{"version":3,"file":"terra-draw.cjs","sources":["../src/geometry/limit-decimal-precision.ts","../src/geometry/measure/pixel-distance.ts","../src/adapters/common/adapter-listener.ts","../src/adapters/common/base.adapter.ts","../src/adapters/google-maps.adapter.ts","../src/adapters/leaflet.adapter.ts","../src/adapters/mapbox-gl.adapter.ts","../src/adapters/maplibre-gl.adapter.ts","../node_modules/ol/util.js","../node_modules/ol/size.js","../node_modules/ol/style/Image.js","../node_modules/ol/AssertionError.js","../node_modules/ol/math.js","../node_modules/ol/color.js","../node_modules/ol/asserts.js","../node_modules/ol/colorlike.js","../node_modules/ol/has.js","../node_modules/ol/dom.js","../node_modules/ol/events/Event.js","../node_modules/ol/Disposable.js","../node_modules/ol/functions.js","../node_modules/ol/obj.js","../node_modules/ol/events/Target.js","../node_modules/ol/events.js","../node_modules/ol/Observable.js","../node_modules/ol/events/EventType.js","../node_modules/ol/Object.js","../node_modules/ol/render/canvas.js","../node_modules/ol/ObjectEventType.js","../node_modules/ol/style/RegularShape.js","../node_modules/ol/ImageState.js","../node_modules/ol/style/Circle.js","../node_modules/ol/style/Fill.js","../node_modules/ol/style/Stroke.js","../node_modules/ol/style/Style.js","../node_modules/ol/proj/Units.js","../node_modules/ol/proj/Projection.js","../node_modules/ol/proj/epsg3857.js","../node_modules/ol/proj/epsg4326.js","../node_modules/ol/proj/projections.js","../node_modules/ol/proj/transforms.js","../node_modules/ol/proj.js","../src/adapters/openlayers.adapter.ts","../src/modes/base.mode.ts","../src/adapters/arcgis-maps-sdk.adapter.ts","../src/common.ts","../src/store/store-feature-validation.ts","../src/geometry/measure/haversine-distance.ts","../src/geometry/helpers.ts","../src/geometry/shape/create-circle.ts","../src/geometry/boolean/self-intersects.ts","../src/geometry/boolean/is-valid-coordinate.ts","../src/geometry/boolean/is-valid-polygon-feature.ts","../src/modes/circle/circle.mode.ts","../src/util/styling.ts","../src/modes/freehand/freehand.mode.ts","../src/geometry/shape/great-circle-line.ts","../src/modes/base.behavior.ts","../src/modes/great-circle-snapping.behavior.ts","../src/modes/pixel-distance.behavior.ts","../src/geometry/shape/create-bbox.ts","../src/modes/click-bounding-box.behavior.ts","../src/modes/greatcircle/great-circle.mode.ts","../src/modes/snapping.behavior.ts","../src/modes/linestring/linestring.mode.ts","../src/geometry/boolean/is-valid-point.ts","../src/modes/point/point.mode.ts","../src/geometry/coordinates-identical.ts","../src/modes/polygon/behaviors/closing-points.behavior.ts","../src/modes/polygon/polygon.mode.ts","../src/util/geoms.ts","../src/modes/rectangle/rectangle.mode.ts","../src/modes/render/render.mode.ts","../src/geometry/boolean/is-valid-linestring-feature.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/get-coordinates-as-points.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/measure/rhumb-bearing.ts","../src/geometry/measure/rhumb-destination.ts","../src/geometry/measure/rhumb-distance.ts","../src/modes/select/behaviors/rotate-feature.behavior.ts","../src/geometry/transform/rotate.ts","../src/modes/select/behaviors/scale-feature.behavior.ts","../src/geometry/transform/scale.ts","../src/geometry/project/web-mercator.ts","../src/geometry/web-mercator-center.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/terra-draw.ts","../src/validations/max-size.validation.ts"],"sourcesContent":["export function limitPrecision(num: number, decimalLimit = 9) {\n\tconst decimals = Math.pow(10, decimalLimit);\n\treturn Math.round(num * decimals) / decimals;\n}\n","export const pixelDistance = (\n\tpointOne: { x: number; y: number },\n\tpointTwo: { x: number; y: number },\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","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} from \"../../common\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\nimport { pixelDistance } 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\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._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\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(): 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\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): 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};\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.\n\t * @returns {number} The coordinate precision.\n\t * @description The coordinate precision is the number of decimal places. Note that the precision will be overriden by the precision of the TerraDraw Adapter.\n\t */\n\tpublic getCoordinatePrecision() {\n\t\treturn this._coordinatePrecision;\n\t}\n\n\tprivate 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\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement().addEventListener(\"pointerdown\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement().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 = pixelDistance(\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// Simiarly 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\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();\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();\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\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement();\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();\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()) {\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\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\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 draggin 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();\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();\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();\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();\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();\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();\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\t\tthis.clear();\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\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { GeoJsonObject } from \"geojson\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\nimport { FeatureId } from \"../store/store\";\n\nexport class TerraDrawGoogleMapsAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tlib: typeof google.maps;\n\t\t\tmap: google.maps.Map;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\t\tthis._lib = config.lib;\n\t\tthis._map = config.map;\n\n\t\t// In order for the internals of the adapter to work we require an ID to\n\t\t// allow query selectors  to work\n\t\tif (!this._map.getDiv().id) {\n\t\t\tthrow new Error(\"Google Map container div requires and id to be set\");\n\t\t}\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 _cursor: string | undefined;\n\tprivate _cursorStyleSheet: HTMLStyleElement | undefined;\n\tprivate _lib: typeof google.maps;\n\tprivate _map: google.maps.Map;\n\tprivate _overlay: google.maps.OverlayView | undefined;\n\tprivate _clickEventListener: google.maps.MapsEventListener | undefined;\n\tprivate _mouseMoveEventListener: google.maps.MapsEventListener | undefined;\n\n\tprivate get _layers(): boolean {\n\t\treturn Boolean(this.renderedFeatureIds?.size > 0);\n\t}\n\n\t/**\n\t * Generates an SVG path string for a circle with the given center coordinates and radius.\n\t * Based off this StackOverflow answer: https://stackoverflow.com/a/27905268/1363484\n\t * @param cx The x-coordinate of the circle's center.\n\t * @param cy The y-coordinate of the circle's center.\n\t * @param r The radius of the circle.\n\t * @returns The SVG path string representing the circle.\n\t */\n\tprivate circlePath(cx: number, cy: number, r: number) {\n\t\tconst d = r * 2;\n\t\treturn `M ${cx} ${cy} m -${r}, 0 a ${r},${r} 0 1,0 ${d},0 a ${r},${r} 0 1,0 -${d},0`;\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\t// The overlay is responsible for allow us to\n\t\t// get the projection, which in turn allows us to\n\t\t// go through lng/lat to pixel space and vice versa\n\t\tthis._overlay = new this._lib.OverlayView();\n\t\tthis._overlay.draw = function () {};\n\n\t\t// Unforunately it is only ready after the onAdd\n\t\t// method is called, which is why we need to use the 'ready'\n\t\t// listener with the Google Maps adapter\n\t\tthis._overlay.onAdd = () => {\n\t\t\tthis._currentModeCallbacks &&\n\t\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\t\tthis._currentModeCallbacks.onReady();\n\t\t};\n\t\tthis._overlay.setMap(this._map);\n\n\t\t// Clicking on data geometries triggers\n\t\t// swallows the map onclick event,\n\t\t// so we need to forward it to the click callback handler\n\t\tthis._clickEventListener = this._map.data.addListener(\n\t\t\t\"click\",\n\t\t\t(\n\t\t\t\tevent: google.maps.MapMouseEvent & {\n\t\t\t\t\tdomEvent: MouseEvent;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst clickListener = this._listeners.find(\n\t\t\t\t\t({ name }) => name === \"click\",\n\t\t\t\t);\n\t\t\t\tif (clickListener) {\n\t\t\t\t\tclickListener.callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tthis._mouseMoveEventListener = this._map.data.addListener(\n\t\t\t\"mousemove\",\n\t\t\t(\n\t\t\t\tevent: google.maps.MapMouseEvent & {\n\t\t\t\t\tdomEvent: MouseEvent;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst mouseMoveListener = this._listeners.find(\n\t\t\t\t\t({ name }) => name === \"mousemove\",\n\t\t\t\t);\n\t\t\t\tif (mouseMoveListener) {\n\t\t\t\t\tmouseMoveListener.callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic unregister(): void {\n\t\tsuper.unregister();\n\t\tthis._clickEventListener?.remove();\n\t\tthis._mouseMoveEventListener?.remove();\n\t\tthis._overlay?.setMap(null);\n\t\tthis._overlay = undefined;\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tgetLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst bounds = this._map.getBounds();\n\n\t\tif (!bounds) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst ne = bounds.getNorthEast();\n\t\tconst sw = bounds.getSouthWest();\n\t\tconst latLngBounds = new this._lib.LatLngBounds(sw, ne);\n\n\t\tconst mapCanvas = this._map.getDiv();\n\t\tconst offsetX = event.clientX - mapCanvas.getBoundingClientRect().left;\n\t\tconst offsetY = event.clientY - mapCanvas.getBoundingClientRect().top;\n\t\tconst screenCoord = new this._lib.Point(offsetX, offsetY);\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (!projection) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst latLng = projection.fromContainerPixelToLatLng(screenCoord);\n\n\t\tif (latLng && latLngBounds.contains(latLng)) {\n\t\t\treturn { lng: latLng.lng(), lat: latLng.lat() };\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the Google Map element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\t// TODO: This is a bit hacky, maybe there is a better solution here\n\t\tconst selector = 'div[style*=\"z-index: 3;\"]';\n\t\treturn this._map.getDiv().querySelector(selector) as HTMLDivElement;\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tproject(lng: number, lat: number) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst bounds = this._map.getBounds();\n\n\t\tif (bounds === undefined) {\n\t\t\tthrow new Error(\"cannot get bounds\");\n\t\t}\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (projection === undefined) {\n\t\t\tthrow new Error(\"cannot get projection\");\n\t\t}\n\n\t\tconst point = projection.fromLatLngToContainerPixel(\n\t\t\tnew this._lib.LatLng(lat, lng),\n\t\t);\n\n\t\tif (point === null) {\n\t\t\tthrow new Error(\"cannot project coordinates\");\n\t\t}\n\n\t\treturn { x: point.x, y: point.y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tunproject(x: number, y: number) {\n\t\tif (!this._overlay) {\n\t\t\tthrow new Error(\"cannot get overlay\");\n\t\t}\n\n\t\tconst projection = this._overlay.getProjection();\n\t\tif (projection === undefined) {\n\t\t\tthrow new Error(\"cannot get projection\");\n\t\t}\n\n\t\tconst latLng = projection.fromContainerPixelToLatLng(\n\t\t\tnew this._lib.Point(x, y),\n\t\t);\n\n\t\tif (latLng === null) {\n\t\t\tthrow new Error(\"cannot unproject coordinates\");\n\t\t}\n\n\t\treturn { lng: latLng.lng(), lat: latLng.lat() };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tsetCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === this._cursor) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._cursorStyleSheet) {\n\t\t\tthis._cursorStyleSheet.remove();\n\t\t\tthis._cursorStyleSheet = undefined;\n\t\t}\n\n\t\tif (cursor !== \"unset\") {\n\t\t\t// TODO: We could cache these individually per cursor\n\n\t\t\tconst div = this._map.getDiv();\n\t\t\tconst styleDivSelector = `#${div.id} .gm-style > div`;\n\t\t\tconst styleDiv = document.querySelector(styleDivSelector);\n\n\t\t\tif (styleDiv) {\n\t\t\t\tstyleDiv.classList.add(\"terra-draw-google-maps\");\n\n\t\t\t\tconst style = document.createElement(\"style\");\n\t\t\t\tstyle.innerHTML = `.terra-draw-google-maps { cursor: ${cursor} !important; }`;\n\t\t\t\tdocument.getElementsByTagName(\"head\")[0].appendChild(style);\n\t\t\t\tthis._cursorStyleSheet = style;\n\t\t\t}\n\t\t}\n\n\t\tthis._cursor = cursor;\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tsetDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.setOptions({ disableDoubleClickZoom: false });\n\t\t} else {\n\t\t\tthis._map.setOptions({ disableDoubleClickZoom: true });\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tsetDraggability(enabled: boolean) {\n\t\tthis._map.setOptions({ draggable: enabled });\n\t}\n\n\tprivate renderedFeatureIds: Set<FeatureId> = new Set();\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\trender(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tif (this._layers) {\n\t\t\tchanges.deletedIds.forEach((deletedId) => {\n\t\t\t\tconst featureToDelete = this._map.data.getFeatureById(deletedId);\n\t\t\t\tif (featureToDelete) {\n\t\t\t\t\tthis._map.data.remove(featureToDelete);\n\t\t\t\t\tthis.renderedFeatureIds.delete(deletedId);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchanges.updated.forEach((updatedFeature) => {\n\t\t\t\tif (!updatedFeature || !updatedFeature.id) {\n\t\t\t\t\tthrow new Error(\"Feature is not valid\");\n\t\t\t\t}\n\n\t\t\t\tconst featureToUpdate = this._map.data.getFeatureById(\n\t\t\t\t\tupdatedFeature.id,\n\t\t\t\t);\n\n\t\t\t\tif (!featureToUpdate) {\n\t\t\t\t\tthrow new Error(\"Feature could not be found by Google Maps API\");\n\t\t\t\t}\n\n\t\t\t\t// Remove all keys\n\t\t\t\tfeatureToUpdate.forEachProperty((property, name) => {\n\t\t\t\t\tfeatureToUpdate.setProperty(name, undefined);\n\t\t\t\t});\n\n\t\t\t\t// Update all keys\n\t\t\t\tObject.keys(updatedFeature.properties).forEach((property) => {\n\t\t\t\t\tfeatureToUpdate.setProperty(\n\t\t\t\t\t\tproperty,\n\t\t\t\t\t\tupdatedFeature.properties[property],\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tswitch (updatedFeature.geometry.type) {\n\t\t\t\t\tcase \"Point\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(\n\t\t\t\t\t\t\t\tnew this._lib.Data.Point(\n\t\t\t\t\t\t\t\t\tnew this._lib.LatLng(coordinates[1], coordinates[0]),\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\tbreak;\n\t\t\t\t\tcase \"LineString\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tconst path = [];\n\t\t\t\t\t\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\t\t\t\t\t\tconst coordinate = coordinates[i];\n\t\t\t\t\t\t\t\tconst latLng = new this._lib.LatLng(\n\t\t\t\t\t\t\t\t\tcoordinate[1],\n\t\t\t\t\t\t\t\t\tcoordinate[0],\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tpath.push(latLng);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(new this._lib.Data.LineString(path));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Polygon\":\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst coordinates = updatedFeature.geometry.coordinates;\n\n\t\t\t\t\t\t\tconst paths = [];\n\t\t\t\t\t\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\t\t\t\t\t\tconst path = [];\n\t\t\t\t\t\t\t\tfor (let j = 0; j < coordinates[i].length; j++) {\n\t\t\t\t\t\t\t\t\tconst latLng = new this._lib.LatLng(\n\t\t\t\t\t\t\t\t\t\tcoordinates[i][j][1],\n\t\t\t\t\t\t\t\t\t\tcoordinates[i][j][0],\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tpath.push(latLng);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpaths.push(path);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfeatureToUpdate.setGeometry(new this._lib.Data.Polygon(paths));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Create new features\n\t\t\tchanges.created.forEach((createdFeature) => {\n\t\t\t\tthis.renderedFeatureIds.add(createdFeature.id as string);\n\t\t\t\tthis._map.data.addGeoJson(createdFeature);\n\t\t\t});\n\t\t}\n\n\t\tchanges.created.forEach((feature) => {\n\t\t\tthis.renderedFeatureIds.add(feature.id as string);\n\t\t});\n\n\t\tconst featureCollection = {\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: [...changes.created],\n\t\t} as GeoJsonObject;\n\n\t\tthis._map.data.addGeoJson(featureCollection);\n\n\t\tthis._map.data.setStyle((feature) => {\n\t\t\tconst mode = feature.getProperty(\"mode\");\n\t\t\tconst gmGeometry = feature.getGeometry();\n\t\t\tif (!gmGeometry) {\n\t\t\t\tthrow new Error(\"Google Maps geometry not found\");\n\t\t\t}\n\t\t\tconst type = gmGeometry.getType();\n\t\t\tconst properties: Record<string, any> = {};\n\n\t\t\tfeature.forEachProperty((value, property) => {\n\t\t\t\tproperties[property] = value;\n\t\t\t});\n\n\t\t\tconst calculatedStyles = styling[mode]({\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: type as \"Point\" | \"LineString\" | \"Polygon\",\n\t\t\t\t\tcoordinates: [],\n\t\t\t\t},\n\t\t\t\tproperties,\n\t\t\t});\n\n\t\t\tswitch (type) {\n\t\t\t\tcase \"Point\":\n\t\t\t\t\tconst path = this.circlePath(0, 0, calculatedStyles.pointWidth);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tclickable: false,\n\t\t\t\t\t\ticon: {\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tfillColor: calculatedStyles.pointColor,\n\t\t\t\t\t\t\tfillOpacity: 1,\n\t\t\t\t\t\t\tstrokeColor: calculatedStyles.pointOutlineColor,\n\t\t\t\t\t\t\tstrokeWeight: calculatedStyles.pointOutlineWidth,\n\t\t\t\t\t\t\trotation: 0,\n\t\t\t\t\t\t\tscale: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\tcase \"LineString\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstrokeColor: calculatedStyles.lineStringColor,\n\t\t\t\t\t\tstrokeWeight: calculatedStyles.lineStringWidth,\n\t\t\t\t\t};\n\t\t\t\tcase \"Polygon\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstrokeColor: calculatedStyles.polygonOutlineColor,\n\t\t\t\t\t\tstrokeWeight: calculatedStyles.polygonOutlineWidth,\n\t\t\t\t\t\tfillOpacity: calculatedStyles.polygonFillOpacity,\n\t\t\t\t\t\tfillColor: calculatedStyles.polygonFillColor,\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\tthrow Error(\"Unknown feature type\");\n\t\t});\n\t}\n\n\tprivate clearLayers() {\n\t\tif (this._layers) {\n\t\t\tthis._map.data.forEach((feature) => {\n\t\t\t\tconst id = feature.getId() as string;\n\t\t\t\tconst hasFeature = this.renderedFeatureIds.has(id);\n\t\t\t\tif (hasFeature) {\n\t\t\t\t\tthis._map.data.remove(feature);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.renderedFeatureIds = new Set();\n\t\t}\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clean up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport L from \"leaflet\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawLeafletAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tlib: typeof L;\n\t\t\tmap: L.Map;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._lib = config.lib;\n\t\tthis._map = config.map;\n\t\tthis._container = this._map.getContainer();\n\t}\n\n\tprivate _lib: typeof L;\n\tprivate _map: L.Map;\n\tprivate _panes: Record<string, HTMLStyleElement | undefined> = {};\n\tprivate _container: HTMLElement;\n\tprivate _layers: Record<string, L.GeoJSON<any>> = {};\n\n\t/**\n\t * Creates a pane and its associated style sheet\n\t * @param pane - The pane name\n\t * @param zIndex - The zIndex value for the pane\n\t * @returns The created style element\n\t */\n\tprivate createPaneStyleSheet(pane: string, zIndex: number) {\n\t\tconst style = document.createElement(\"style\");\n\t\tstyle.innerHTML = `.leaflet-${pane} {z-index: ${zIndex};}`;\n\t\tdocument.getElementsByTagName(\"head\")[0].appendChild(style);\n\t\tthis._map.createPane(pane);\n\t\treturn style;\n\t}\n\n\t/**\n\t * Clears the panes created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearPanes() {\n\t\tObject.values(this._panes).forEach((pane) => {\n\t\t\tif (pane) {\n\t\t\t\tpane.remove();\n\t\t\t}\n\t\t});\n\t\tthis._panes = {};\n\t}\n\n\t/**\n\t * Clears the leaflet layers created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tObject.values(this._layers).forEach((layer) => {\n\t\t\tthis._map.removeLayer(layer);\n\t\t});\n\t\tthis._layers = {};\n\t}\n\n\t/**\n\t * Styles a GeoJSON layer based on the styling function\n\t * @param styling - The styling function\n\t * */\n\tprivate styleGeoJSONLayer(\n\t\tstyling: TerraDrawStylingFunction,\n\t): L.GeoJSONOptions {\n\t\treturn {\n\t\t\t// Style points - convert markers to circle markers\n\t\t\tpointToLayer: (\n\t\t\t\tfeature: GeoJSONStoreFeatures,\n\t\t\t\tlatlng: L.LatLngExpression,\n\t\t\t) => {\n\t\t\t\tif (!feature.properties) {\n\t\t\t\t\tthrow new Error(\"Feature has no properties\");\n\t\t\t\t}\n\t\t\t\tif (typeof feature.properties.mode !== \"string\") {\n\t\t\t\t\tthrow new Error(\"Feature mode is not a string\");\n\t\t\t\t}\n\n\t\t\t\tconst mode = feature.properties.mode;\n\t\t\t\tconst modeStyle = styling[mode];\n\t\t\t\tconst featureStyles = modeStyle(feature);\n\t\t\t\tconst paneId = String(featureStyles.zIndex);\n\t\t\t\tconst pane = this._panes[paneId];\n\n\t\t\t\tif (!pane) {\n\t\t\t\t\tthis._panes[paneId] = this.createPaneStyleSheet(\n\t\t\t\t\t\tpaneId,\n\t\t\t\t\t\tfeatureStyles.zIndex,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst styles = {\n\t\t\t\t\tradius: featureStyles.pointWidth,\n\t\t\t\t\tstroke: featureStyles.pointOutlineWidth || false,\n\t\t\t\t\tcolor: featureStyles.pointOutlineColor,\n\t\t\t\t\tweight: featureStyles.pointOutlineWidth,\n\t\t\t\t\tfillOpacity: 0.8,\n\t\t\t\t\tfillColor: featureStyles.pointColor,\n\t\t\t\t\tpane: paneId,\n\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t} as L.CircleMarkerOptions;\n\n\t\t\t\tconst marker = this._lib.circleMarker(latlng, styles);\n\n\t\t\t\treturn marker;\n\t\t\t},\n\n\t\t\t// Style LineStrings and Polygons\n\t\t\tstyle: (_feature) => {\n\t\t\t\tif (!_feature || !_feature.properties) {\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\n\t\t\t\tconst feature = _feature as GeoJSONStoreFeatures;\n\n\t\t\t\tconst mode = feature.properties.mode as string;\n\t\t\t\tconst modeStyle = styling[mode];\n\t\t\t\tconst featureStyles = modeStyle(feature);\n\t\t\t\tconst paneId = String(featureStyles.zIndex);\n\t\t\t\tconst pane = this._panes[paneId];\n\n\t\t\t\tif (!pane) {\n\t\t\t\t\tthis._panes[paneId] = this.createPaneStyleSheet(\n\t\t\t\t\t\tpaneId,\n\t\t\t\t\t\tfeatureStyles.zIndex,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (feature.geometry.type === \"LineString\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t\t\tcolor: featureStyles.lineStringColor,\n\t\t\t\t\t\tweight: featureStyles.lineStringWidth,\n\t\t\t\t\t\tpane: paneId,\n\t\t\t\t\t};\n\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tinteractive: false, // Removes mouse hover cursor styles\n\t\t\t\t\t\tfillOpacity: featureStyles.polygonFillOpacity,\n\t\t\t\t\t\tfillColor: featureStyles.polygonFillColor,\n\t\t\t\t\t\tweight: featureStyles.polygonOutlineWidth,\n\t\t\t\t\t\tstroke: true,\n\t\t\t\t\t\tcolor: featureStyles.polygonFillColor,\n\t\t\t\t\t\tpane: paneId,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn {};\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\n\t\tconst point = { x, y } as L.Point;\n\n\t\t// If is not valid point we don't want to convert\n\t\tif (isNaN(point.x) || isNaN(point.y)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst latLng = this._map.containerPointToLatLng(point);\n\t\tif (isNaN(latLng.lng) || isNaN(latLng.lat)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn { lng: latLng.lng, lat: latLng.lat };\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the Leaflet element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._container;\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.dragging.enable();\n\t\t} else {\n\t\t\tthis._map.dragging.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst { x, y } = this._map.latLngToContainerPoint({ lng, lat });\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { lng, lat } = this._map.containerPointToLatLng({\n\t\t\tx,\n\t\t\ty,\n\t\t} as L.PointExpression);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.doubleClickZoom.enable();\n\t\t} else {\n\t\t\tthis._map.doubleClickZoom.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tchanges.created.forEach((created) => {\n\t\t\tthis._layers[created.id as string] = this._lib.geoJSON(\n\t\t\t\tcreated,\n\t\t\t\tthis.styleGeoJSONLayer(styling),\n\t\t\t);\n\t\t\tthis._map.addLayer(this._layers[created.id as string]);\n\t\t});\n\n\t\tchanges.deletedIds.forEach((deleted) => {\n\t\t\tthis._map.removeLayer(this._layers[deleted]);\n\t\t});\n\n\t\tchanges.updated.forEach((updated) => {\n\t\t\tthis._map.removeLayer(this._layers[updated.id as string]);\n\t\t\tthis._layers[updated.id as string] = this._lib.geoJSON(\n\t\t\t\tupdated,\n\t\t\t\tthis.styleGeoJSONLayer(styling),\n\t\t\t);\n\t\t\tthis._map.addLayer(this._layers[updated.id as string]);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clear up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t\tthis.clearPanes();\n\t\t}\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { Feature, LineString, Point, Polygon } from \"geojson\";\nimport mapboxgl, {\n\tCircleLayer,\n\tFillLayer,\n\tLineLayer,\n\tPointLike,\n} from \"mapbox-gl\";\nimport { GeoJSONStoreFeatures, GeoJSONStoreGeometries } from \"../store/store\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawMapboxGLAdapter extends TerraDrawBaseAdapter {\n\tconstructor(config: { map: mapboxgl.Map } & BaseAdapterConfig) {\n\t\tsuper(config);\n\n\t\tthis._map = config.map;\n\t\tthis._container = this._map.getContainer();\n\t}\n\n\tprivate _nextRender: any;\n\tprivate _map: mapboxgl.Map;\n\tprivate _container: HTMLElement;\n\tprivate _rendered = false;\n\n\t/**\n\t * Clears the map of rendered layers and sources\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tif (this._rendered) {\n\t\t\tconst geometryTypes = [\"point\", \"linestring\", \"polygon\"] as const;\n\t\t\tgeometryTypes.forEach((geometryKey) => {\n\t\t\t\tconst id = `td-${geometryKey.toLowerCase()}`;\n\t\t\t\tthis._map.removeLayer(id);\n\n\t\t\t\t// Special case for polygons as it has another id for the outline\n\t\t\t\t// that we need to make sure we remove\n\t\t\t\tif (geometryKey === \"polygon\") {\n\t\t\t\t\tthis._map.removeLayer(id + \"-outline\");\n\t\t\t\t}\n\t\t\t\tthis._map.removeSource(id);\n\t\t\t});\n\n\t\t\tthis._rendered = false;\n\n\t\t\t// TODO: This is necessary to prevent render artifacts, perhaps there is a nicer solution?\n\t\t\tif (this._nextRender) {\n\t\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t\t\tthis._nextRender = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _addGeoJSONSource(id: string, features: Feature[]) {\n\t\tthis._map.addSource(id, {\n\t\t\ttype: \"geojson\",\n\t\t\tdata: {\n\t\t\t\ttype: \"FeatureCollection\",\n\t\t\t\tfeatures: features,\n\t\t\t},\n\t\t\ttolerance: 0,\n\t\t});\n\t}\n\n\tprivate _addFillLayer(id: string) {\n\t\treturn this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"fill\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"fill-color\": [\"get\", \"polygonFillColor\"],\n\t\t\t\t\"fill-opacity\": [\"get\", \"polygonFillOpacity\"],\n\t\t\t},\n\t\t} as FillLayer);\n\t}\n\n\tprivate _addFillOutlineLayer(id: string, beneath?: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid: id + \"-outline\",\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"polygonOutlineWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"polygonOutlineColor\"],\n\t\t\t},\n\t\t} as LineLayer);\n\n\t\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\n\t\treturn layer;\n\t}\n\n\tprivate _addLineLayer(id: string, beneath?: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"line\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"line-width\": [\"get\", \"lineStringWidth\"],\n\t\t\t\t\"line-color\": [\"get\", \"lineStringColor\"],\n\t\t\t},\n\t\t} as LineLayer);\n\n\t\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\n\t\treturn layer;\n\t}\n\n\tprivate _addPointLayer(id: string, beneath?: string) {\n\t\tconst layer = this._map.addLayer({\n\t\t\tid,\n\t\t\tsource: id,\n\t\t\ttype: \"circle\",\n\t\t\t// No need for filters as style is driven by properties\n\t\t\tpaint: {\n\t\t\t\t\"circle-stroke-color\": [\"get\", \"pointOutlineColor\"],\n\t\t\t\t\"circle-stroke-width\": [\"get\", \"pointOutlineWidth\"],\n\t\t\t\t\"circle-radius\": [\"get\", \"pointWidth\"],\n\t\t\t\t\"circle-color\": [\"get\", \"pointColor\"],\n\t\t\t},\n\t\t} as CircleLayer);\n\t\tif (beneath) {\n\t\t\tthis._map.moveLayer(id, beneath);\n\t\t}\n\t\treturn layer;\n\t}\n\n\tprivate _addLayer(\n\t\tid: string,\n\t\tfeatureType: \"Point\" | \"LineString\" | \"Polygon\",\n\t\tbeneath?: string,\n\t) {\n\t\tif (featureType === \"Point\") {\n\t\t\tthis._addPointLayer(id, beneath);\n\t\t}\n\t\tif (featureType === \"LineString\") {\n\t\t\tthis._addLineLayer(id, beneath);\n\t\t}\n\t\tif (featureType === \"Polygon\") {\n\t\t\tthis._addFillLayer(id);\n\t\t\tthis._addFillOutlineLayer(id, beneath);\n\t\t}\n\t}\n\n\tprivate _addGeoJSONLayer<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `td-${featureType.toLowerCase()}`;\n\t\tthis._addGeoJSONSource(id, features);\n\t\tthis._addLayer(id, featureType);\n\n\t\treturn id;\n\t}\n\n\tprivate _setGeoJSONLayerData<T extends GeoJSONStoreGeometries>(\n\t\tfeatureType: Feature<T>[\"geometry\"][\"type\"],\n\t\tfeatures: Feature<T>[],\n\t) {\n\t\tconst id = `td-${featureType.toLowerCase()}`;\n\t\t(this._map.getSource(id) as any).setData({\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: features,\n\t\t});\n\t\treturn id;\n\t}\n\n\tprivate getEmptyGeometries(): {\n\t\tpoints: GeoJSONStoreFeatures[];\n\t\tlinestrings: GeoJSONStoreFeatures[];\n\t\tpolygons: GeoJSONStoreFeatures[];\n\t} {\n\t\treturn {\n\t\t\tpoints: [],\n\t\t\tlinestrings: [],\n\t\t\tpolygons: [],\n\t\t};\n\t}\n\n\tprivate changedIds: {\n\t\tdeletion: boolean;\n\t\tpoints: boolean;\n\t\tlinestrings: boolean;\n\t\tpolygons: boolean;\n\t\tstyling: boolean;\n\t} = {\n\t\tdeletion: false,\n\t\tpoints: false,\n\t\tlinestrings: false,\n\t\tpolygons: false,\n\t\tstyling: false,\n\t};\n\n\tprivate updateChangedIds(changes: TerraDrawChanges) {\n\t\t[...changes.updated, ...changes.created].forEach((feature) => {\n\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\tthis.changedIds.points = true;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tthis.changedIds.linestrings = true;\n\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\tthis.changedIds.polygons = true;\n\t\t\t}\n\t\t});\n\n\t\tif (changes.deletedIds.length > 0) {\n\t\t\tthis.changedIds.deletion = true;\n\t\t}\n\n\t\tif (\n\t\t\tchanges.created.length === 0 &&\n\t\t\tchanges.updated.length === 0 &&\n\t\t\tchanges.deletedIds.length === 0\n\t\t) {\n\t\t\tthis.changedIds.styling = true;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { left, top } = this._container.getBoundingClientRect();\n\t\tconst x = event.clientX - left;\n\t\tconst y = event.clientY - top;\n\n\t\treturn this.unproject(x, y);\n\t}\n\n\t/**\n\t *Retrieves the HTML element of the Mapbox element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._map.getCanvas();\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\t// Mapbox GL has both drag rotation and drag panning interactions\n\t\t\t// hence having to enable/disable both\n\t\t\tthis._map.dragRotate.enable();\n\t\t\tthis._map.dragPan.enable();\n\t\t} else {\n\t\t\tthis._map.dragRotate.disable();\n\t\t\tthis._map.dragPan.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst { x, y } = this._map.project({ lng, lat });\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { lng, lat } = this._map.unproject({ x, y } as PointLike);\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tconst canvas = this._map.getCanvas();\n\t\tif (cursor === \"unset\") {\n\t\t\tcanvas.style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tcanvas.style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tif (enabled) {\n\t\t\tthis._map.doubleClickZoom.enable();\n\t\t} else {\n\t\t\tthis._map.doubleClickZoom.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.updateChangedIds(changes);\n\n\t\tif (this._nextRender) {\n\t\t\tcancelAnimationFrame(this._nextRender);\n\t\t}\n\n\t\t// Because Mapbox GL makes us pass in a full re-render of alll the features\n\t\t// we can do debounce rendering to only render the last render in a given\n\t\t// frame bucket (16ms)\n\n\t\tthis._nextRender = requestAnimationFrame(() => {\n\t\t\t// Get a map of the changed feature IDs by geometry type\n\t\t\t// We use this to determine which MB layers need to be updated\n\n\t\t\tconst features = [\n\t\t\t\t...changes.created,\n\t\t\t\t...changes.updated,\n\t\t\t\t...changes.unchanged,\n\t\t\t];\n\n\t\t\tconst geometryFeatures = this.getEmptyGeometries();\n\n\t\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\t\tconst feature = features[i];\n\n\t\t\t\tObject.keys(styling).forEach((mode) => {\n\t\t\t\t\tconst { properties } = feature;\n\n\t\t\t\t\tif (properties.mode !== mode) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst styles = styling[mode](feature);\n\n\t\t\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\t\t\tproperties.pointColor = styles.pointColor;\n\t\t\t\t\t\tproperties.pointOutlineColor = styles.pointOutlineColor;\n\t\t\t\t\t\tproperties.pointOutlineWidth = styles.pointOutlineWidth;\n\t\t\t\t\t\tproperties.pointWidth = styles.pointWidth;\n\t\t\t\t\t\tgeometryFeatures.points.push(feature);\n\t\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\t\tproperties.lineStringColor = styles.lineStringColor;\n\t\t\t\t\t\tproperties.lineStringWidth = styles.lineStringWidth;\n\t\t\t\t\t\tgeometryFeatures.linestrings.push(feature);\n\t\t\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\t\tproperties.polygonFillColor = styles.polygonFillColor;\n\t\t\t\t\t\tproperties.polygonFillOpacity = styles.polygonFillOpacity;\n\t\t\t\t\t\tproperties.polygonOutlineColor = styles.polygonOutlineColor;\n\t\t\t\t\t\tproperties.polygonOutlineWidth = styles.polygonOutlineWidth;\n\t\t\t\t\t\tgeometryFeatures.polygons.push(feature);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst { points, linestrings, polygons } = geometryFeatures;\n\n\t\t\tif (!this._rendered) {\n\t\t\t\tconst pointId = this._addGeoJSONLayer<Point>(\n\t\t\t\t\t\"Point\",\n\t\t\t\t\tpoints as Feature<Point>[],\n\t\t\t\t);\n\t\t\t\tthis._addGeoJSONLayer<LineString>(\n\t\t\t\t\t\"LineString\",\n\t\t\t\t\tlinestrings as Feature<LineString>[],\n\t\t\t\t);\n\t\t\t\tthis._addGeoJSONLayer<Polygon>(\n\t\t\t\t\t\"Polygon\",\n\t\t\t\t\tpolygons as Feature<Polygon>[],\n\t\t\t\t);\n\t\t\t\tthis._rendered = true;\n\n\t\t\t\t// Ensure selection/mid points are rendered on top\n\t\t\t\tpointId && this._map.moveLayer(pointId);\n\t\t\t} else {\n\t\t\t\t// If deletion occured we always have to update all layers\n\t\t\t\t// as we don't know the type (TODO: perhaps we could pass that back?)\n\t\t\t\tconst deletionOccured = this.changedIds.deletion;\n\t\t\t\tconst styleUpdatedOccured = this.changedIds.styling;\n\t\t\t\tconst forceUpdate = deletionOccured || styleUpdatedOccured;\n\n\t\t\t\t// Determine if we need to update each layer by geometry type\n\t\t\t\tconst updatePoints = forceUpdate || this.changedIds.points;\n\t\t\t\tconst updateLineStrings = forceUpdate || this.changedIds.linestrings;\n\t\t\t\tconst updatedPolygon = forceUpdate || this.changedIds.polygons;\n\n\t\t\t\tlet pointId;\n\t\t\t\tif (updatePoints) {\n\t\t\t\t\tpointId = this._setGeoJSONLayerData<Point>(\n\t\t\t\t\t\t\"Point\",\n\t\t\t\t\t\tpoints as Feature<Point>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (updateLineStrings) {\n\t\t\t\t\tthis._setGeoJSONLayerData<LineString>(\n\t\t\t\t\t\t\"LineString\",\n\t\t\t\t\t\tlinestrings as Feature<LineString>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (updatedPolygon) {\n\t\t\t\t\tthis._setGeoJSONLayerData<Polygon>(\n\t\t\t\t\t\t\"Polygon\",\n\t\t\t\t\t\tpolygons as Feature<Polygon>[],\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// TODO: This logic could be better - I think this will render the selection points above user\n\t\t\t\t// defined layers outside of TerraDraw which is perhaps unideal\n\n\t\t\t\t// Ensure selection/mid points are rendered on top\n\t\t\t\tpointId && this._map.moveLayer(pointId);\n\t\t\t}\n\n\t\t\t// Reset changed ids\n\t\t\tthis.changedIds = {\n\t\t\t\tpoints: false,\n\t\t\t\tlinestrings: false,\n\t\t\t\tpolygons: false,\n\t\t\t\tdeletion: false,\n\t\t\t\tstyling: false,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clear up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n}\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { Map } from \"maplibre-gl\";\nimport { TerraDrawMapboxGLAdapter } from \"./mapbox-gl.adapter\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\nexport class TerraDrawMapLibreGLAdapter extends TerraDrawBaseAdapter {\n\tprivate mapboxglAdapter: TerraDrawMapboxGLAdapter;\n\n\tconstructor(config: { map: Map } & BaseAdapterConfig) {\n\t\tsuper(config);\n\n\t\t// At the moment the APIs of MapboxGL and MapLibre are so compatible that\n\t\t// there is not need to bother completely reimplementing the internals of the adapter.\n\t\t// This may change over time and gives us a shell to allow for rewriting the internals\n\t\t// of the adapter should the MapboxGL and MapbLibre APIs diverge in the instances where\n\t\t// we rely on them.\n\t\tthis.mapboxglAdapter = new TerraDrawMapboxGLAdapter(\n\t\t\tconfig as {\n\t\t\t\tmap: any; //\n\t\t\t\tcoordinatePrecision: number;\n\t\t\t},\n\t\t);\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks): void {\n\t\tthis.mapboxglAdapter.register(callbacks);\n\t}\n\n\tpublic unregister(): void {\n\t\tthis.mapboxglAdapter.unregister();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn this.mapboxglAdapter.getCoordinatePrecision();\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\treturn this.mapboxglAdapter.getLngLatFromEvent(event);\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the MapLibre element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this.mapboxglAdapter.getMapEventElement();\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis.mapboxglAdapter.setDraggability(enabled);\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\treturn this.mapboxglAdapter.project(lng, lat);\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\treturn this.mapboxglAdapter.unproject(x, y);\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(style: Parameters<SetCursor>[0]) {\n\t\tthis.mapboxglAdapter.setCursor(style);\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis.mapboxglAdapter.setDoubleClickToZoom(enabled);\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.mapboxglAdapter.render(changes, styling);\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tthis.mapboxglAdapter.clear();\n\t}\n}\n","/**\n * @module ol/util\n */\n\n/**\n * @return {never} Any return.\n */\nexport function abstract() {\n  throw new Error('Unimplemented abstract method.');\n}\n\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\nlet uidCounter_ = 0;\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {string} The unique ID for the object.\n * @api\n */\nexport function getUid(obj) {\n  return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));\n}\n\n/**\n * OpenLayers version.\n * @type {string}\n */\nexport const VERSION = '7.1.0';\n","/**\n * @module ol/size\n */\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The buffered size.\n */\nexport function buffer(size, num, dest) {\n  if (dest === undefined) {\n    dest = [0, 0];\n  }\n  dest[0] = size[0] + 2 * num;\n  dest[1] = size[1] + 2 * num;\n  return dest;\n}\n\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\nexport function hasArea(size) {\n  return size[0] > 0 && size[1] > 0;\n}\n\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The scaled size.\n */\nexport function scale(size, ratio, dest) {\n  if (dest === undefined) {\n    dest = [0, 0];\n  }\n  dest[0] = (size[0] * ratio + 0.5) | 0;\n  dest[1] = (size[1] * ratio + 0.5) | 0;\n  return dest;\n}\n\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\nexport function toSize(size, dest) {\n  if (Array.isArray(size)) {\n    return size;\n  } else {\n    if (dest === undefined) {\n      dest = [size, size];\n    } else {\n      dest[0] = size;\n      dest[1] = size;\n    }\n    return dest;\n  }\n}\n","/**\n * @module ol/style/Image\n */\nimport {abstract} from '../util.js';\nimport {toSize} from '../size.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} opacity Opacity.\n * @property {boolean} rotateWithView If the image should get rotated with the view.\n * @property {number} rotation Rotation.\n * @property {number|import(\"../size.js\").Size} scale Scale.\n * @property {Array<number>} displacement Displacement.\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} declutterMode Declutter mode: `declutter`, `obstacle`, 'none */\n\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @abstract\n * @api\n */\nclass ImageStyle {\n  /**\n   * @param {Options} options Options.\n   */\n  constructor(options) {\n    /**\n     * @private\n     * @type {number}\n     */\n    this.opacity_ = options.opacity;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.rotateWithView_ = options.rotateWithView;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.rotation_ = options.rotation;\n\n    /**\n     * @private\n     * @type {number|import(\"../size.js\").Size}\n     */\n    this.scale_ = options.scale;\n\n    /**\n     * @private\n     * @type {import(\"../size.js\").Size}\n     */\n    this.scaleArray_ = toSize(options.scale);\n\n    /**\n     * @private\n     * @type {Array<number>}\n     */\n    this.displacement_ = options.displacement;\n\n    /**\n     * @private\n     * @type {\"declutter\"|\"obstacle\"|\"none\"|undefined}\n     */\n    this.declutterMode_ = options.declutterMode;\n  }\n\n  /**\n   * Clones the style.\n   * @return {ImageStyle} The cloned style.\n   * @api\n   */\n  clone() {\n    const scale = this.getScale();\n    return new ImageStyle({\n      opacity: this.getOpacity(),\n      scale: Array.isArray(scale) ? scale.slice() : scale,\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView(),\n      displacement: this.getDisplacement().slice(),\n      declutterMode: this.getDeclutterMode(),\n    });\n  }\n\n  /**\n   * Get the symbolizer opacity.\n   * @return {number} Opacity.\n   * @api\n   */\n  getOpacity() {\n    return this.opacity_;\n  }\n\n  /**\n   * Determine whether the symbolizer rotates with the map.\n   * @return {boolean} Rotate with map.\n   * @api\n   */\n  getRotateWithView() {\n    return this.rotateWithView_;\n  }\n\n  /**\n   * Get the symoblizer rotation.\n   * @return {number} Rotation.\n   * @api\n   */\n  getRotation() {\n    return this.rotation_;\n  }\n\n  /**\n   * Get the symbolizer scale.\n   * @return {number|import(\"../size.js\").Size} Scale.\n   * @api\n   */\n  getScale() {\n    return this.scale_;\n  }\n\n  /**\n   * Get the symbolizer scale array.\n   * @return {import(\"../size.js\").Size} Scale array.\n   */\n  getScaleArray() {\n    return this.scaleArray_;\n  }\n\n  /**\n   * Get the displacement of the shape\n   * @return {Array<number>} Shape's center displacement\n   * @api\n   */\n  getDisplacement() {\n    return this.displacement_;\n  }\n\n  /**\n   * Get the declutter mode of the shape\n   * @return {\"declutter\"|\"obstacle\"|\"none\"|undefined} Shape's declutter mode\n   * @api\n   */\n  getDeclutterMode() {\n    return this.declutterMode_;\n  }\n\n  /**\n   * Get the anchor point in pixels. The anchor determines the center point for the\n   * symbolizer.\n   * @abstract\n   * @return {Array<number>} Anchor.\n   */\n  getAnchor() {\n    return abstract();\n  }\n\n  /**\n   * Get the image element for the symbolizer.\n   * @abstract\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n   */\n  getImage(pixelRatio) {\n    return abstract();\n  }\n\n  /**\n   * @abstract\n   * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n   */\n  getHitDetectionImage() {\n    return abstract();\n  }\n\n  /**\n   * Get the image pixel ratio.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {number} Pixel ratio.\n   */\n  getPixelRatio(pixelRatio) {\n    return 1;\n  }\n\n  /**\n   * @abstract\n   * @return {import(\"../ImageState.js\").default} Image state.\n   */\n  getImageState() {\n    return abstract();\n  }\n\n  /**\n   * @abstract\n   * @return {import(\"../size.js\").Size} Image size.\n   */\n  getImageSize() {\n    return abstract();\n  }\n\n  /**\n   * Get the origin of the symbolizer.\n   * @abstract\n   * @return {Array<number>} Origin.\n   */\n  getOrigin() {\n    return abstract();\n  }\n\n  /**\n   * Get the size of the symbolizer (in pixels).\n   * @abstract\n   * @return {import(\"../size.js\").Size} Size.\n   */\n  getSize() {\n    return abstract();\n  }\n\n  /**\n   * Set the displacement.\n   *\n   * @param {Array<number>} displacement Displacement.\n   * @api\n   */\n  setDisplacement(displacement) {\n    this.displacement_ = displacement;\n  }\n\n  /**\n   * Set the opacity.\n   *\n   * @param {number} opacity Opacity.\n   * @api\n   */\n  setOpacity(opacity) {\n    this.opacity_ = opacity;\n  }\n\n  /**\n   * Set whether to rotate the style with the view.\n   *\n   * @param {boolean} rotateWithView Rotate with map.\n   * @api\n   */\n  setRotateWithView(rotateWithView) {\n    this.rotateWithView_ = rotateWithView;\n  }\n\n  /**\n   * Set the rotation.\n   *\n   * @param {number} rotation Rotation.\n   * @api\n   */\n  setRotation(rotation) {\n    this.rotation_ = rotation;\n  }\n  /**\n   * Set the scale.\n   *\n   * @param {number|import(\"../size.js\").Size} scale Scale.\n   * @api\n   */\n  setScale(scale) {\n    this.scale_ = scale;\n    this.scaleArray_ = toSize(scale);\n  }\n\n  /**\n   * @abstract\n   * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n   */\n  listenImageChange(listener) {\n    abstract();\n  }\n\n  /**\n   * Load not yet loaded URI.\n   * @abstract\n   */\n  load() {\n    abstract();\n  }\n\n  /**\n   * @abstract\n   * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n   */\n  unlistenImageChange(listener) {\n    abstract();\n  }\n}\n\nexport default ImageStyle;\n","/**\n * @module ol/AssertionError\n */\n\n/** @type {Object<number, string>} */\nconst messages = {\n  1: 'The view center is not defined',\n  2: 'The view resolution is not defined',\n  3: 'The view rotation is not defined',\n  4: '`image` and `src` cannot be provided at the same time',\n  5: '`imgSize` must be set when `image` is provided',\n  7: '`format` must be set when `url` is set',\n  8: 'Unknown `serverType` configured',\n  9: '`url` must be configured or set using `#setUrl()`',\n  10: 'The default `geometryFunction` can only handle `Point` geometries',\n  11: '`options.featureTypes` must be an Array',\n  12: '`options.geometryName` must also be provided when `options.bbox` is set',\n  13: 'Invalid corner',\n  14: 'Invalid color',\n  15: 'Tried to get a value for a key that does not exist in the cache',\n  16: 'Tried to set a value for a key that is used already',\n  17: '`resolutions` must be sorted in descending order',\n  18: 'Either `origin` or `origins` must be configured, never both',\n  19: 'Number of `tileSizes` and `resolutions` must be equal',\n  20: 'Number of `origins` and `resolutions` must be equal',\n  22: 'Either `tileSize` or `tileSizes` must be configured, never both',\n  24: 'Invalid extent or geometry provided as `geometry`',\n  25: 'Cannot fit empty extent provided as `geometry`',\n  26: 'Features must have an id set',\n  27: 'Features must have an id set',\n  28: '`renderMode` must be `\"hybrid\"` or `\"vector\"`',\n  30: 'The passed `feature` was already added to the source',\n  31: 'Tried to enqueue an `element` that was already added to the queue',\n  32: 'Transformation matrix cannot be inverted',\n  33: 'Invalid units',\n  34: 'Invalid geometry layout',\n  36: 'Unknown SRS type',\n  37: 'Unknown geometry type found',\n  38: '`styleMapValue` has an unknown type',\n  39: 'Unknown geometry type',\n  40: 'Expected `feature` to have a geometry',\n  41: 'Expected an `ol/style/Style` or an array of `ol/style/Style.js`',\n  42: 'Question unknown, the answer is 42',\n  43: 'Expected `layers` to be an array or a `Collection`',\n  47: 'Expected `controls` to be an array or an `ol/Collection`',\n  48: 'Expected `interactions` to be an array or an `ol/Collection`',\n  49: 'Expected `overlays` to be an array or an `ol/Collection`',\n  50: '`options.featureTypes` should be an Array',\n  51: 'Either `url` or `tileJSON` options must be provided',\n  52: 'Unknown `serverType` configured',\n  53: 'Unknown `tierSizeCalculation` configured',\n  55: 'The {-y} placeholder requires a tile grid with extent',\n  56: 'mapBrowserEvent must originate from a pointer event',\n  57: 'At least 2 conditions are required',\n  59: 'Invalid command found in the PBF',\n  60: 'Missing or invalid `size`',\n  61: 'Cannot determine IIIF Image API version from provided image information JSON',\n  62: 'A `WebGLArrayBuffer` must either be of type `ELEMENT_ARRAY_BUFFER` or `ARRAY_BUFFER`',\n  64: 'Layer opacity must be a number',\n  66: '`forEachFeatureAtCoordinate` cannot be used on a WebGL layer if the hit detection logic has not been enabled. This is done by providing adequate shaders using the `hitVertexShader` and `hitFragmentShader` properties of `WebGLPointsLayerRenderer`',\n  67: 'A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both',\n  68: 'A VectorTile source can only be rendered if it has a projection compatible with the view projection',\n};\n\n/**\n * Error object thrown when an assertion failed. This is an ECMA-262 Error,\n * extended with a `code` property.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.\n */\nclass AssertionError extends Error {\n  /**\n   * @param {number} code Error code.\n   */\n  constructor(code) {\n    const message = messages[code];\n\n    super(message);\n\n    /**\n     * Error code. The meaning of the code can be found on\n     * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with\n     * the version found in the OpenLayers script's header comment if a version\n     * other than the latest is used).\n     * @type {number}\n     * @deprecated ol/AssertionError and error codes will be removed in v8.0\n     * @api\n     */\n    this.code = code;\n\n    /**\n     * @type {string}\n     */\n    this.name = 'AssertionError';\n\n    // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40\n    this.message = message;\n  }\n}\n\nexport default AssertionError;\n","/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n *     number within the bounds.\n */\nexport function clamp(value, min, max) {\n  return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  if (dx !== 0 || dy !== 0) {\n    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n    if (t > 1) {\n      x1 = x2;\n      y1 = y2;\n    } else if (t > 0) {\n      x1 += dx * t;\n      y1 += dy * t;\n    }\n  }\n  return squaredDistance(x, y, x1, y1);\n}\n\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredDistance(x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  return dx * dx + dy * dy;\n}\n\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n *                                     in row-major order.\n * @return {Array<number>} The resulting vector.\n */\nexport function solveLinearSystem(mat) {\n  const n = mat.length;\n\n  for (let i = 0; i < n; i++) {\n    // Find max in the i-th column (ignoring i - 1 first rows)\n    let maxRow = i;\n    let maxEl = Math.abs(mat[i][i]);\n    for (let r = i + 1; r < n; r++) {\n      const absValue = Math.abs(mat[r][i]);\n      if (absValue > maxEl) {\n        maxEl = absValue;\n        maxRow = r;\n      }\n    }\n\n    if (maxEl === 0) {\n      return null; // matrix is singular\n    }\n\n    // Swap max row with i-th (current) row\n    const tmp = mat[maxRow];\n    mat[maxRow] = mat[i];\n    mat[i] = tmp;\n\n    // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n    for (let j = i + 1; j < n; j++) {\n      const coef = -mat[j][i] / mat[i][i];\n      for (let k = i; k < n + 1; k++) {\n        if (i == k) {\n          mat[j][k] = 0;\n        } else {\n          mat[j][k] += coef * mat[i][k];\n        }\n      }\n    }\n  }\n\n  // Solve Ax=b for upper triangular matrix A (mat)\n  const x = new Array(n);\n  for (let l = n - 1; l >= 0; l--) {\n    x[l] = mat[l][n] / mat[l][l];\n    for (let m = l - 1; m >= 0; m--) {\n      mat[m][n] -= mat[m][l] * x[l];\n    }\n  }\n  return x;\n}\n\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\nexport function toDegrees(angleInRadians) {\n  return (angleInRadians * 180) / Math.PI;\n}\n\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\nexport function toRadians(angleInDegrees) {\n  return (angleInDegrees * Math.PI) / 180;\n}\n\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\nexport function modulo(a, b) {\n  const r = a % b;\n  return r * b < 0 ? r + b : r;\n}\n\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\nexport function lerp(a, b, x) {\n  return a + x * (b - a);\n}\n\n/**\n * Returns a number with a limited number of decimal digits.\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The input number with a limited number of decimal digits.\n */\nexport function toFixed(n, decimals) {\n  const factor = Math.pow(10, decimals);\n  return Math.round(n * factor) / factor;\n}\n\n/**\n * Rounds a number to the nearest integer value considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The nearest integer.\n */\nexport function round(n, decimals) {\n  return Math.round(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next smaller integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next smaller integer.\n */\nexport function floor(n, decimals) {\n  return Math.floor(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next bigger integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next bigger integer.\n */\nexport function ceil(n, decimals) {\n  return Math.ceil(toFixed(n, decimals));\n}\n","/**\n * @module ol/color\n */\nimport {assert} from './asserts.js';\nimport {clamp} from './math.js';\n\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array<number>} Color\n * @api\n */\n\n/**\n * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.\n * @const\n * @type {RegExp}\n * @private\n */\nconst HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;\n\n/**\n * Regular expression for matching potential named color style strings.\n * @const\n * @type {RegExp}\n * @private\n */\nconst NAMED_COLOR_RE_ = /^([a-z]*)$|^hsla?\\(.*\\)$/i;\n\n/**\n * Return the color as an rgba string.\n * @param {Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\nexport function asString(color) {\n  if (typeof color === 'string') {\n    return color;\n  } else {\n    return toString(color);\n  }\n}\n\n/**\n * Return named color as an rgba string.\n * @param {string} color Named color.\n * @return {string} Rgb string.\n */\nfunction fromNamed(color) {\n  const el = document.createElement('div');\n  el.style.color = color;\n  if (el.style.color !== '') {\n    document.body.appendChild(el);\n    const rgb = getComputedStyle(el).color;\n    document.body.removeChild(el);\n    return rgb;\n  } else {\n    return '';\n  }\n}\n\n/**\n * @param {string} s String.\n * @return {Color} Color.\n */\nexport const fromString = (function () {\n  // We maintain a small cache of parsed strings.  To provide cheap LRU-like\n  // semantics, whenever the cache grows too large we simply delete an\n  // arbitrary 25% of the entries.\n\n  /**\n   * @const\n   * @type {number}\n   */\n  const MAX_CACHE_SIZE = 1024;\n\n  /**\n   * @type {Object<string, Color>}\n   */\n  const cache = {};\n\n  /**\n   * @type {number}\n   */\n  let cacheSize = 0;\n\n  return (\n    /**\n     * @param {string} s String.\n     * @return {Color} Color.\n     */\n    function (s) {\n      let color;\n      if (cache.hasOwnProperty(s)) {\n        color = cache[s];\n      } else {\n        if (cacheSize >= MAX_CACHE_SIZE) {\n          let i = 0;\n          for (const key in cache) {\n            if ((i++ & 3) === 0) {\n              delete cache[key];\n              --cacheSize;\n            }\n          }\n        }\n        color = fromStringInternal_(s);\n        cache[s] = color;\n        ++cacheSize;\n      }\n      return color;\n    }\n  );\n})();\n\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {Color|string} color Color.\n * @return {Color} Color.\n * @api\n */\nexport function asArray(color) {\n  if (Array.isArray(color)) {\n    return color;\n  } else {\n    return fromString(color);\n  }\n}\n\n/**\n * @param {string} s String.\n * @private\n * @return {Color} Color.\n */\nfunction fromStringInternal_(s) {\n  let r, g, b, a, color;\n\n  if (NAMED_COLOR_RE_.exec(s)) {\n    s = fromNamed(s);\n  }\n\n  if (HEX_COLOR_RE_.exec(s)) {\n    // hex\n    const n = s.length - 1; // number of hex digits\n    let d; // number of digits per channel\n    if (n <= 4) {\n      d = 1;\n    } else {\n      d = 2;\n    }\n    const hasAlpha = n === 4 || n === 8;\n    r = parseInt(s.substr(1 + 0 * d, d), 16);\n    g = parseInt(s.substr(1 + 1 * d, d), 16);\n    b = parseInt(s.substr(1 + 2 * d, d), 16);\n    if (hasAlpha) {\n      a = parseInt(s.substr(1 + 3 * d, d), 16);\n    } else {\n      a = 255;\n    }\n    if (d == 1) {\n      r = (r << 4) + r;\n      g = (g << 4) + g;\n      b = (b << 4) + b;\n      if (hasAlpha) {\n        a = (a << 4) + a;\n      }\n    }\n    color = [r, g, b, a / 255];\n  } else if (s.startsWith('rgba(')) {\n    // rgba()\n    color = s.slice(5, -1).split(',').map(Number);\n    normalize(color);\n  } else if (s.startsWith('rgb(')) {\n    // rgb()\n    color = s.slice(4, -1).split(',').map(Number);\n    color.push(1);\n    normalize(color);\n  } else {\n    assert(false, 14); // Invalid color\n  }\n  return color;\n}\n\n/**\n * TODO this function is only used in the test, we probably shouldn't export it\n * @param {Color} color Color.\n * @return {Color} Clamped color.\n */\nexport function normalize(color) {\n  color[0] = clamp((color[0] + 0.5) | 0, 0, 255);\n  color[1] = clamp((color[1] + 0.5) | 0, 0, 255);\n  color[2] = clamp((color[2] + 0.5) | 0, 0, 255);\n  color[3] = clamp(color[3], 0, 1);\n  return color;\n}\n\n/**\n * @param {Color} color Color.\n * @return {string} String.\n */\nexport function toString(color) {\n  let r = color[0];\n  if (r != (r | 0)) {\n    r = (r + 0.5) | 0;\n  }\n  let g = color[1];\n  if (g != (g | 0)) {\n    g = (g + 0.5) | 0;\n  }\n  let b = color[2];\n  if (b != (b | 0)) {\n    b = (b + 0.5) | 0;\n  }\n  const a = color[3] === undefined ? 1 : Math.round(color[3] * 100) / 100;\n  return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n}\n\n/**\n * @param {string} s String.\n * @return {boolean} Whether the string is actually a valid color\n */\nexport function isStringColor(s) {\n  if (NAMED_COLOR_RE_.test(s)) {\n    s = fromNamed(s);\n  }\n  return HEX_COLOR_RE_.test(s) || s.startsWith('rgba(') || s.startsWith('rgb(');\n}\n","/**\n * @module ol/asserts\n */\nimport AssertionError from './AssertionError.js';\n\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {number} errorCode Error code.\n */\nexport function assert(assertion, errorCode) {\n  if (!assertion) {\n    throw new AssertionError(errorCode);\n  }\n}\n","/**\n * @module ol/colorlike\n */\nimport {toString} from './color.js';\n\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, pattern, or gradient. The origin for patterns and\n * gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n\n/**\n * @param {import(\"./color.js\").Color|ColorLike} color Color.\n * @return {ColorLike} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\nexport function asColorLike(color) {\n  if (Array.isArray(color)) {\n    return toString(color);\n  } else {\n    return color;\n  }\n}\n","/**\n * @module ol/has\n */\n\nconst ua =\n  typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined'\n    ? navigator.userAgent.toLowerCase()\n    : '';\n\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\nexport const FIREFOX = ua.includes('firefox');\n\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\nexport const SAFARI = ua.includes('safari') && !ua.includes('chrom');\n\n/**\n * https://bugs.webkit.org/show_bug.cgi?id=237906\n * @type {boolean}\n */\nexport const SAFARI_BUG_237906 =\n  SAFARI &&\n  (ua.includes('version/15.4') ||\n    /cpu (os|iphone os) 15_4 like mac os x/.test(ua));\n\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\nexport const WEBKIT = ua.includes('webkit') && !ua.includes('edge');\n\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\nexport const MAC = ua.includes('macintosh');\n\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\nexport const DEVICE_PIXEL_RATIO =\n  typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n\n/**\n * The execution context is a worker with OffscreenCanvas available.\n * @const\n * @type {boolean}\n */\nexport const WORKER_OFFSCREEN_CANVAS =\n  typeof WorkerGlobalScope !== 'undefined' &&\n  typeof OffscreenCanvas !== 'undefined' &&\n  self instanceof WorkerGlobalScope; //eslint-disable-line\n\n/**\n * Image.prototype.decode() is supported.\n * @type {boolean}\n */\nexport const IMAGE_DECODE =\n  typeof Image !== 'undefined' && Image.prototype.decode;\n\n/**\n * @type {boolean}\n */\nexport const PASSIVE_EVENT_LISTENERS = (function () {\n  let passive = false;\n  try {\n    const options = Object.defineProperty({}, 'passive', {\n      get: function () {\n        passive = true;\n      },\n    });\n\n    window.addEventListener('_', null, options);\n    window.removeEventListener('_', null, options);\n  } catch (error) {\n    // passive not supported\n  }\n  return passive;\n})();\n","import {WORKER_OFFSCREEN_CANVAS} from './has.js';\n\n/**\n * @module ol/dom\n */\n\n//FIXME Move this function to the canvas module\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number} [width] Canvas width.\n * @param {number} [height] Canvas height.\n * @param {Array<HTMLCanvasElement>} [canvasPool] Canvas pool to take existing canvas from.\n * @param {CanvasRenderingContext2DSettings} [settings] CanvasRenderingContext2DSettings\n * @return {CanvasRenderingContext2D} The context.\n */\nexport function createCanvasContext2D(width, height, canvasPool, settings) {\n  /** @type {HTMLCanvasElement|OffscreenCanvas} */\n  let canvas;\n  if (canvasPool && canvasPool.length) {\n    canvas = canvasPool.shift();\n  } else if (WORKER_OFFSCREEN_CANVAS) {\n    canvas = new OffscreenCanvas(width || 300, height || 300);\n  } else {\n    canvas = document.createElement('canvas');\n  }\n  if (width) {\n    canvas.width = width;\n  }\n  if (height) {\n    canvas.height = height;\n  }\n  //FIXME Allow OffscreenCanvasRenderingContext2D as return type\n  return /** @type {CanvasRenderingContext2D} */ (\n    canvas.getContext('2d', settings)\n  );\n}\n\n/**\n * Releases canvas memory to avoid exceeding memory limits in Safari.\n * See https://pqina.nl/blog/total-canvas-memory-use-exceeds-the-maximum-limit/\n * @param {CanvasRenderingContext2D} context Context.\n */\nexport function releaseCanvas(context) {\n  const canvas = context.canvas;\n  canvas.width = 1;\n  canvas.height = 1;\n  context.clearRect(0, 0, 1, 1);\n}\n\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\nexport function outerWidth(element) {\n  let width = element.offsetWidth;\n  const style = getComputedStyle(element);\n  width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n\n  return width;\n}\n\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\nexport function outerHeight(element) {\n  let height = element.offsetHeight;\n  const style = getComputedStyle(element);\n  height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n\n  return height;\n}\n\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\nexport function replaceNode(newNode, oldNode) {\n  const parent = oldNode.parentNode;\n  if (parent) {\n    parent.replaceChild(newNode, oldNode);\n  }\n}\n\n/**\n * @param {Node} node The node to remove.\n * @return {Node|null} The node that was removed or null.\n */\nexport function removeNode(node) {\n  return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n}\n\n/**\n * @param {Node} node The node to remove the children from.\n */\nexport function removeChildren(node) {\n  while (node.lastChild) {\n    node.removeChild(node.lastChild);\n  }\n}\n\n/**\n * Transform the children of a parent node so they match the\n * provided list of children.  This function aims to efficiently\n * remove, add, and reorder child nodes while maintaining a simple\n * implementation (it is not guaranteed to minimize DOM operations).\n * @param {Node} node The parent node whose children need reworking.\n * @param {Array<Node>} children The desired children.\n */\nexport function replaceChildren(node, children) {\n  const oldChildren = node.childNodes;\n\n  for (let i = 0; true; ++i) {\n    const oldChild = oldChildren[i];\n    const newChild = children[i];\n\n    // check if our work is done\n    if (!oldChild && !newChild) {\n      break;\n    }\n\n    // check if children match\n    if (oldChild === newChild) {\n      continue;\n    }\n\n    // check if a new child needs to be added\n    if (!oldChild) {\n      node.appendChild(newChild);\n      continue;\n    }\n\n    // check if an old child needs to be removed\n    if (!newChild) {\n      node.removeChild(oldChild);\n      --i;\n      continue;\n    }\n\n    // reorder\n    node.insertBefore(newChild, oldChild);\n  }\n}\n","/**\n * @module ol/events/Event\n */\n\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/Target~Target}.\n */\nclass BaseEvent {\n  /**\n   * @param {string} type Type.\n   */\n  constructor(type) {\n    /**\n     * @type {boolean}\n     */\n    this.propagationStopped;\n\n    /**\n     * @type {boolean}\n     */\n    this.defaultPrevented;\n\n    /**\n     * The event type.\n     * @type {string}\n     * @api\n     */\n    this.type = type;\n\n    /**\n     * The event target.\n     * @type {Object}\n     * @api\n     */\n    this.target = null;\n  }\n\n  /**\n   * Prevent default. This means that no emulated `click`, `singleclick` or `doubleclick` events\n   * will be fired.\n   * @api\n   */\n  preventDefault() {\n    this.defaultPrevented = true;\n  }\n\n  /**\n   * Stop event propagation.\n   * @api\n   */\n  stopPropagation() {\n    this.propagationStopped = true;\n  }\n}\n\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function stopPropagation(evt) {\n  evt.stopPropagation();\n}\n\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function preventDefault(evt) {\n  evt.preventDefault();\n}\n\nexport default BaseEvent;\n","/**\n * @module ol/Disposable\n */\n\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nclass Disposable {\n  constructor() {\n    /**\n     * The object has already been disposed.\n     * @type {boolean}\n     * @protected\n     */\n    this.disposed = false;\n  }\n\n  /**\n   * Clean up.\n   */\n  dispose() {\n    if (!this.disposed) {\n      this.disposed = true;\n      this.disposeInternal();\n    }\n  }\n\n  /**\n   * Extension point for disposable objects.\n   * @protected\n   */\n  disposeInternal() {}\n}\n\nexport default Disposable;\n","/**\n * @module ol/functions\n */\n\nimport {equals as arrayEquals} from './array.js';\n\n/**\n * Always returns true.\n * @return {boolean} true.\n */\nexport function TRUE() {\n  return true;\n}\n\n/**\n * Always returns false.\n * @return {boolean} false.\n */\nexport function FALSE() {\n  return false;\n}\n\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {void} Nothing.\n */\nexport function VOID() {}\n\n/**\n * Wrap a function in another function that remembers the last return.  If the\n * returned function is called twice in a row with the same arguments and the same\n * this object, it will return the value from the first call in the second call.\n *\n * @param {function(...any): ReturnType} fn The function to memoize.\n * @return {function(...any): ReturnType} The memoized function.\n * @template ReturnType\n */\nexport function memoizeOne(fn) {\n  let called = false;\n\n  /** @type {ReturnType} */\n  let lastResult;\n\n  /** @type {Array<any>} */\n  let lastArgs;\n\n  let lastThis;\n\n  return function () {\n    const nextArgs = Array.prototype.slice.call(arguments);\n    if (!called || this !== lastThis || !arrayEquals(nextArgs, lastArgs)) {\n      called = true;\n      lastThis = this;\n      lastArgs = nextArgs;\n      lastResult = fn.apply(this, arguments);\n    }\n    return lastResult;\n  };\n}\n\n/**\n * @template T\n * @param {function(): (T | Promise<T>)} getter A function that returns a value or a promise for a value.\n * @return {Promise<T>} A promise for the value.\n */\nexport function toPromise(getter) {\n  function promiseGetter() {\n    let value;\n    try {\n      value = getter();\n    } catch (err) {\n      return Promise.reject(err);\n    }\n    if (value instanceof Promise) {\n      return value;\n    }\n    return Promise.resolve(value);\n  }\n  return promiseGetter();\n}\n","/**\n * @module ol/obj\n */\n\n/**\n * Removes all properties from an object.\n * @param {Object} object The object to clear.\n */\nexport function clear(object) {\n  for (const property in object) {\n    delete object[property];\n  }\n}\n\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\nexport function isEmpty(object) {\n  let property;\n  for (property in object) {\n    return false;\n  }\n  return !property;\n}\n","/**\n * @module ol/events/Target\n */\nimport Disposable from '../Disposable.js';\nimport Event from './Event.js';\nimport {VOID} from '../functions.js';\nimport {clear} from '../obj.js';\n\n/**\n * @typedef {EventTarget|Target} EventTargetLike\n */\n\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n *    `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n *    There is no event target hierarchy. When a listener calls\n *    `stopPropagation` or `preventDefault` on an event object, it means that no\n *    more listeners after this one will be called. Same as when the listener\n *    returns false.\n */\nclass Target extends Disposable {\n  /**\n   * @param {*} [target] Default event target for dispatched events.\n   */\n  constructor(target) {\n    super();\n\n    /**\n     * @private\n     * @type {*}\n     */\n    this.eventTarget_ = target;\n\n    /**\n     * @private\n     * @type {Object<string, number>}\n     */\n    this.pendingRemovals_ = null;\n\n    /**\n     * @private\n     * @type {Object<string, number>}\n     */\n    this.dispatching_ = null;\n\n    /**\n     * @private\n     * @type {Object<string, Array<import(\"../events.js\").Listener>>}\n     */\n    this.listeners_ = null;\n  }\n\n  /**\n   * @param {string} type Type.\n   * @param {import(\"../events.js\").Listener} listener Listener.\n   */\n  addEventListener(type, listener) {\n    if (!type || !listener) {\n      return;\n    }\n    const listeners = this.listeners_ || (this.listeners_ = {});\n    const listenersForType = listeners[type] || (listeners[type] = []);\n    if (!listenersForType.includes(listener)) {\n      listenersForType.push(listener);\n    }\n  }\n\n  /**\n   * Dispatches an event and calls all listeners listening for events\n   * of this type. The event parameter can either be a string or an\n   * Object with a `type` property.\n   *\n   * @param {import(\"./Event.js\").default|string} event Event object.\n   * @return {boolean|undefined} `false` if anyone called preventDefault on the\n   *     event object or if any of the listeners returned false.\n   * @api\n   */\n  dispatchEvent(event) {\n    const isString = typeof event === 'string';\n    const type = isString ? event : event.type;\n    const listeners = this.listeners_ && this.listeners_[type];\n    if (!listeners) {\n      return;\n    }\n\n    const evt = isString ? new Event(event) : /** @type {Event} */ (event);\n    if (!evt.target) {\n      evt.target = this.eventTarget_ || this;\n    }\n    const dispatching = this.dispatching_ || (this.dispatching_ = {});\n    const pendingRemovals =\n      this.pendingRemovals_ || (this.pendingRemovals_ = {});\n    if (!(type in dispatching)) {\n      dispatching[type] = 0;\n      pendingRemovals[type] = 0;\n    }\n    ++dispatching[type];\n    let propagate;\n    for (let i = 0, ii = listeners.length; i < ii; ++i) {\n      if ('handleEvent' in listeners[i]) {\n        propagate = /** @type {import(\"../events.js\").ListenerObject} */ (\n          listeners[i]\n        ).handleEvent(evt);\n      } else {\n        propagate = /** @type {import(\"../events.js\").ListenerFunction} */ (\n          listeners[i]\n        ).call(this, evt);\n      }\n      if (propagate === false || evt.propagationStopped) {\n        propagate = false;\n        break;\n      }\n    }\n    if (--dispatching[type] === 0) {\n      let pr = pendingRemovals[type];\n      delete pendingRemovals[type];\n      while (pr--) {\n        this.removeEventListener(type, VOID);\n      }\n      delete dispatching[type];\n    }\n    return propagate;\n  }\n\n  /**\n   * Clean up.\n   */\n  disposeInternal() {\n    this.listeners_ && clear(this.listeners_);\n  }\n\n  /**\n   * Get the listeners for a specified event type. Listeners are returned in the\n   * order that they will be called in.\n   *\n   * @param {string} type Type.\n   * @return {Array<import(\"../events.js\").Listener>|undefined} Listeners.\n   */\n  getListeners(type) {\n    return (this.listeners_ && this.listeners_[type]) || undefined;\n  }\n\n  /**\n   * @param {string} [type] Type. If not provided,\n   *     `true` will be returned if this event target has any listeners.\n   * @return {boolean} Has listeners.\n   */\n  hasListener(type) {\n    if (!this.listeners_) {\n      return false;\n    }\n    return type\n      ? type in this.listeners_\n      : Object.keys(this.listeners_).length > 0;\n  }\n\n  /**\n   * @param {string} type Type.\n   * @param {import(\"../events.js\").Listener} listener Listener.\n   */\n  removeEventListener(type, listener) {\n    const listeners = this.listeners_ && this.listeners_[type];\n    if (listeners) {\n      const index = listeners.indexOf(listener);\n      if (index !== -1) {\n        if (this.pendingRemovals_ && type in this.pendingRemovals_) {\n          // make listener a no-op, and remove later in #dispatchEvent()\n          listeners[index] = VOID;\n          ++this.pendingRemovals_[type];\n        } else {\n          listeners.splice(index, 1);\n          if (listeners.length === 0) {\n            delete this.listeners_[type];\n          }\n        }\n      }\n    }\n  }\n}\n\nexport default Target;\n","/**\n * @module ol/events\n */\nimport {clear} from './obj.js';\n\n/**\n * Key to use with {@link module:ol/Observable.unByKey}.\n * @typedef {Object} EventsKey\n * @property {ListenerFunction} listener Listener.\n * @property {import(\"./events/Target.js\").EventTargetLike} target Target.\n * @property {string} type Type.\n * @api\n */\n\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function((Event|import(\"./events/Event.js\").default)): (void|boolean)} ListenerFunction\n * @api\n */\n\n/**\n * @typedef {Object} ListenerObject\n * @property {ListenerFunction} handleEvent HandleEvent listener function.\n */\n\n/**\n * @typedef {ListenerFunction|ListenerObject} Listener\n */\n\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events.unlistenByKey}.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [thisArg] Object referenced by the `this` keyword in the\n *     listener. Default is the `target`.\n * @param {boolean} [once] If true, add the listener as one-off listener.\n * @return {EventsKey} Unique key for the listener.\n */\nexport function listen(target, type, listener, thisArg, once) {\n  if (thisArg && thisArg !== target) {\n    listener = listener.bind(thisArg);\n  }\n  if (once) {\n    const originalListener = listener;\n    listener = function () {\n      target.removeEventListener(type, listener);\n      originalListener.apply(this, arguments);\n    };\n  }\n  const eventsKey = {\n    target: target,\n    type: type,\n    listener: listener,\n  };\n  target.addEventListener(type, listener);\n  return eventsKey;\n}\n\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events.unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events.listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [thisArg] Object referenced by the `this` keyword in the\n *     listener. Default is the `target`.\n * @return {EventsKey} Key for unlistenByKey.\n */\nexport function listenOnce(target, type, listener, thisArg) {\n  return listen(target, type, listener, thisArg, true);\n}\n\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events.listen} or {@link module:ol/events.listenOnce}.\n *\n * @param {EventsKey} key The key.\n */\nexport function unlistenByKey(key) {\n  if (key && key.target) {\n    key.target.removeEventListener(key.type, key.listener);\n    clear(key);\n  }\n}\n","/**\n * @module ol/Observable\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport {listen, listenOnce, unlistenByKey} from './events.js';\n\n/***\n * @template {string} Type\n * @template {Event|import(\"./events/Event.js\").default} EventClass\n * @template Return\n * @typedef {(type: Type, listener: (event: EventClass) => ?) => Return} OnSignature\n */\n\n/***\n * @template {string} Type\n * @template Return\n * @typedef {(type: Type[], listener: (event: Event|import(\"./events/Event\").default) => ?) => Return extends void ? void : Return[]} CombinedOnSignature\n */\n\n/**\n * @typedef {'change'|'error'} EventTypes\n */\n\n/***\n * @template Return\n * @typedef {OnSignature<EventTypes, import(\"./events/Event.js\").default, Return> & CombinedOnSignature<EventTypes, Return>} ObservableOnSignature\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires import(\"./events/Event.js\").default\n * @api\n */\nclass Observable extends EventTarget {\n  constructor() {\n    super();\n\n    this.on =\n      /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (\n        this.onInternal\n      );\n\n    this.once =\n      /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (\n        this.onceInternal\n      );\n\n    this.un = /** @type {ObservableOnSignature<void>} */ (this.unInternal);\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.revision_ = 0;\n  }\n\n  /**\n   * Increases the revision counter and dispatches a 'change' event.\n   * @api\n   */\n  changed() {\n    ++this.revision_;\n    this.dispatchEvent(EventType.CHANGE);\n  }\n\n  /**\n   * Get the version number for this object.  Each time the object is modified,\n   * its version number will be incremented.\n   * @return {number} Revision.\n   * @api\n   */\n  getRevision() {\n    return this.revision_;\n  }\n\n  /**\n   * @param {string|Array<string>} type Type.\n   * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n   * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n   * @protected\n   */\n  onInternal(type, listener) {\n    if (Array.isArray(type)) {\n      const len = type.length;\n      const keys = new Array(len);\n      for (let i = 0; i < len; ++i) {\n        keys[i] = listen(this, type[i], listener);\n      }\n      return keys;\n    } else {\n      return listen(this, /** @type {string} */ (type), listener);\n    }\n  }\n\n  /**\n   * @param {string|Array<string>} type Type.\n   * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n   * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n   * @protected\n   */\n  onceInternal(type, listener) {\n    let key;\n    if (Array.isArray(type)) {\n      const len = type.length;\n      key = new Array(len);\n      for (let i = 0; i < len; ++i) {\n        key[i] = listenOnce(this, type[i], listener);\n      }\n    } else {\n      key = listenOnce(this, /** @type {string} */ (type), listener);\n    }\n    /** @type {Object} */ (listener).ol_key = key;\n    return key;\n  }\n\n  /**\n   * Unlisten for a certain type of event.\n   * @param {string|Array<string>} type Type.\n   * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n   * @protected\n   */\n  unInternal(type, listener) {\n    const key = /** @type {Object} */ (listener).ol_key;\n    if (key) {\n      unByKey(key);\n    } else if (Array.isArray(type)) {\n      for (let i = 0, ii = type.length; i < ii; ++i) {\n        this.removeEventListener(type[i], listener);\n      }\n    } else {\n      this.removeEventListener(type, listener);\n    }\n  }\n}\n\n/**\n * Listen for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n *     called with an array of event types as the first argument, the return\n *     will be an array of keys.\n * @api\n */\nObservable.prototype.on;\n\n/**\n * Listen once for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n *     called with an array of event types as the first argument, the return\n *     will be an array of keys.\n * @api\n */\nObservable.prototype.once;\n\n/**\n * Unlisten for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @api\n */\nObservable.prototype.un;\n\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} key The key returned by `on()`\n *     or `once()` (or an array of keys).\n * @api\n */\nexport function unByKey(key) {\n  if (Array.isArray(key)) {\n    for (let i = 0, ii = key.length; i < ii; ++i) {\n      unlistenByKey(key[i]);\n    }\n  } else {\n    unlistenByKey(/** @type {import(\"./events.js\").EventsKey} */ (key));\n  }\n}\n\nexport default Observable;\n","/**\n * @module ol/events/EventType\n */\n\n/**\n * @enum {string}\n * @const\n */\nexport default {\n  /**\n   * Generic change event. Triggered when the revision counter is increased.\n   * @event module:ol/events/Event~BaseEvent#change\n   * @api\n   */\n  CHANGE: 'change',\n\n  /**\n   * Generic error event. Triggered when an error occurs.\n   * @event module:ol/events/Event~BaseEvent#error\n   * @api\n   */\n  ERROR: 'error',\n\n  BLUR: 'blur',\n  CLEAR: 'clear',\n  CONTEXTMENU: 'contextmenu',\n  CLICK: 'click',\n  DBLCLICK: 'dblclick',\n  DRAGENTER: 'dragenter',\n  DRAGOVER: 'dragover',\n  DROP: 'drop',\n  FOCUS: 'focus',\n  KEYDOWN: 'keydown',\n  KEYPRESS: 'keypress',\n  LOAD: 'load',\n  RESIZE: 'resize',\n  TOUCHMOVE: 'touchmove',\n  WHEEL: 'wheel',\n};\n","/**\n * @module ol/Object\n */\nimport Event from './events/Event.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport Observable from './Observable.js';\nimport {getUid} from './util.js';\nimport {isEmpty} from './obj.js';\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n */\nexport class ObjectEvent extends Event {\n  /**\n   * @param {string} type The event type.\n   * @param {string} key The property name.\n   * @param {*} oldValue The old value for `key`.\n   */\n  constructor(type, key, oldValue) {\n    super(type);\n\n    /**\n     * The name of the property whose value is changing.\n     * @type {string}\n     * @api\n     */\n    this.key = key;\n\n    /**\n     * The old value. To get the new value use `e.target.get(e.key)` where\n     * `e` is the event object.\n     * @type {*}\n     * @api\n     */\n    this.oldValue = oldValue;\n  }\n}\n\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n *    import(\"./Observable\").OnSignature<import(\"./ObjectEventType\").Types, ObjectEvent, Return> &\n *    import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|import(\"./ObjectEventType\").Types, Return>} ObjectOnSignature\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable~Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * 'Observable Properties', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get('target')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on('change:center', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.\n * You can listen for changes on that property value with\n * `object.on('change:prop', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title='New title'` and with `map.set('title', 'Another title')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset('foo').\n *\n * @fires ObjectEvent\n * @api\n */\nclass BaseObject extends Observable {\n  /**\n   * @param {Object<string, *>} [values] An object with key-value pairs.\n   */\n  constructor(values) {\n    super();\n\n    /***\n     * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n     */\n    this.on;\n\n    /***\n     * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n     */\n    this.once;\n\n    /***\n     * @type {ObjectOnSignature<void>}\n     */\n    this.un;\n\n    // Call {@link module:ol/util.getUid} to ensure that the order of objects' ids is\n    // the same as the order in which they were created.  This also helps to\n    // ensure that object properties are always added in the same order, which\n    // helps many JavaScript engines generate faster code.\n    getUid(this);\n\n    /**\n     * @private\n     * @type {Object<string, *>}\n     */\n    this.values_ = null;\n\n    if (values !== undefined) {\n      this.setProperties(values);\n    }\n  }\n\n  /**\n   * Gets a value.\n   * @param {string} key Key name.\n   * @return {*} Value.\n   * @api\n   */\n  get(key) {\n    let value;\n    if (this.values_ && this.values_.hasOwnProperty(key)) {\n      value = this.values_[key];\n    }\n    return value;\n  }\n\n  /**\n   * Get a list of object property names.\n   * @return {Array<string>} List of property names.\n   * @api\n   */\n  getKeys() {\n    return (this.values_ && Object.keys(this.values_)) || [];\n  }\n\n  /**\n   * Get an object of all property names and values.\n   * @return {Object<string, *>} Object.\n   * @api\n   */\n  getProperties() {\n    return (this.values_ && Object.assign({}, this.values_)) || {};\n  }\n\n  /**\n   * @return {boolean} The object has properties.\n   */\n  hasProperties() {\n    return !!this.values_;\n  }\n\n  /**\n   * @param {string} key Key name.\n   * @param {*} oldValue Old value.\n   */\n  notify(key, oldValue) {\n    let eventType;\n    eventType = `change:${key}`;\n    if (this.hasListener(eventType)) {\n      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n    }\n    eventType = ObjectEventType.PROPERTYCHANGE;\n    if (this.hasListener(eventType)) {\n      this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n    }\n  }\n\n  /**\n   * @param {string} key Key name.\n   * @param {import(\"./events.js\").Listener} listener Listener.\n   */\n  addChangeListener(key, listener) {\n    this.addEventListener(`change:${key}`, listener);\n  }\n\n  /**\n   * @param {string} key Key name.\n   * @param {import(\"./events.js\").Listener} listener Listener.\n   */\n  removeChangeListener(key, listener) {\n    this.removeEventListener(`change:${key}`, listener);\n  }\n\n  /**\n   * Sets a value.\n   * @param {string} key Key name.\n   * @param {*} value Value.\n   * @param {boolean} [silent] Update without triggering an event.\n   * @api\n   */\n  set(key, value, silent) {\n    const values = this.values_ || (this.values_ = {});\n    if (silent) {\n      values[key] = value;\n    } else {\n      const oldValue = values[key];\n      values[key] = value;\n      if (oldValue !== value) {\n        this.notify(key, oldValue);\n      }\n    }\n  }\n\n  /**\n   * Sets a collection of key-value pairs.  Note that this changes any existing\n   * properties and adds new ones (it does not remove any existing properties).\n   * @param {Object<string, *>} values Values.\n   * @param {boolean} [silent] Update without triggering an event.\n   * @api\n   */\n  setProperties(values, silent) {\n    for (const key in values) {\n      this.set(key, values[key], silent);\n    }\n  }\n\n  /**\n   * Apply any properties from another object without triggering events.\n   * @param {BaseObject} source The source object.\n   * @protected\n   */\n  applyProperties(source) {\n    if (!source.values_) {\n      return;\n    }\n    Object.assign(this.values_ || (this.values_ = {}), source.values_);\n  }\n\n  /**\n   * Unsets a property.\n   * @param {string} key Key name.\n   * @param {boolean} [silent] Unset without triggering an event.\n   * @api\n   */\n  unset(key, silent) {\n    if (this.values_ && key in this.values_) {\n      const oldValue = this.values_[key];\n      delete this.values_[key];\n      if (isEmpty(this.values_)) {\n        this.values_ = null;\n      }\n      if (!silent) {\n        this.notify(key, oldValue);\n      }\n    }\n  }\n}\n\nexport default BaseObject;\n","/**\n * @module ol/render/canvas\n */\nimport BaseObject from '../Object.js';\nimport {WORKER_OFFSCREEN_CANVAS} from '../has.js';\nimport {clear} from '../obj.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {getFontParameters} from '../css.js';\n\n/**\n * @typedef {'Circle' | 'Image' | 'LineString' | 'Polygon' | 'Text' | 'Default'} BuilderType\n */\n\n/**\n * @typedef {Object} FillState\n * @property {import(\"../colorlike.js\").ColorLike} fillStyle FillStyle.\n */\n\n/**\n * @typedef Label\n * @property {number} width Width.\n * @property {number} height Height.\n * @property {Array<string|number>} contextInstructions ContextInstructions.\n */\n\n/**\n * @typedef {Object} FillStrokeState\n * @property {import(\"../colorlike.js\").ColorLike} [currentFillStyle] Current FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [currentStrokeStyle] Current StrokeStyle.\n * @property {CanvasLineCap} [currentLineCap] Current LineCap.\n * @property {Array<number>} currentLineDash Current LineDash.\n * @property {number} [currentLineDashOffset] Current LineDashOffset.\n * @property {CanvasLineJoin} [currentLineJoin] Current LineJoin.\n * @property {number} [currentLineWidth] Current LineWidth.\n * @property {number} [currentMiterLimit] Current MiterLimit.\n * @property {number} [lastStroke] Last stroke.\n * @property {import(\"../colorlike.js\").ColorLike} [fillStyle] FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [strokeStyle] StrokeStyle.\n * @property {CanvasLineCap} [lineCap] LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} [lineDashOffset] LineDashOffset.\n * @property {CanvasLineJoin} [lineJoin] LineJoin.\n * @property {number} [lineWidth] LineWidth.\n * @property {number} [miterLimit] MiterLimit.\n */\n\n/**\n * @typedef {Object} StrokeState\n * @property {CanvasLineCap} lineCap LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} lineWidth LineWidth.\n * @property {number} miterLimit MiterLimit.\n * @property {import(\"../colorlike.js\").ColorLike} strokeStyle StrokeStyle.\n */\n\n/**\n * @typedef {Object} TextState\n * @property {string} font Font.\n * @property {CanvasTextAlign} [textAlign] TextAlign.\n * @property {import(\"../style/Text.js\").TextJustify} [justify] Justify.\n * @property {CanvasTextBaseline} textBaseline TextBaseline.\n * @property {import(\"../style/Text.js\").TextPlacement} [placement] Placement.\n * @property {number} [maxAngle] MaxAngle.\n * @property {boolean} [overflow] Overflow.\n * @property {import(\"../style/Fill.js\").default} [backgroundFill] BackgroundFill.\n * @property {import(\"../style/Stroke.js\").default} [backgroundStroke] BackgroundStroke.\n * @property {import(\"../size.js\").Size} [scale] Scale.\n * @property {Array<number>} [padding] Padding.\n */\n\n/**\n * @typedef {Object} SerializableInstructions\n * @property {Array<*>} instructions The rendering instructions.\n * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.\n * @property {Array<number>} coordinates The array of all coordinates.\n * @property {!Object<string, TextState>} [textStates] The text states (decluttering).\n * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).\n * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).\n */\n\n/**\n * @typedef {Object<number, import(\"./canvas/Executor.js\").ReplayImageOrLabelArgs>} DeclutterImageWithText\n */\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultFont = '10px sans-serif';\n\n/**\n * @const\n * @type {import(\"../colorlike.js\").ColorLike}\n */\nexport const defaultFillStyle = '#000';\n\n/**\n * @const\n * @type {CanvasLineCap}\n */\nexport const defaultLineCap = 'round';\n\n/**\n * @const\n * @type {Array<number>}\n */\nexport const defaultLineDash = [];\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineDashOffset = 0;\n\n/**\n * @const\n * @type {CanvasLineJoin}\n */\nexport const defaultLineJoin = 'round';\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultMiterLimit = 10;\n\n/**\n * @const\n * @type {import(\"../colorlike.js\").ColorLike}\n */\nexport const defaultStrokeStyle = '#000';\n\n/**\n * @const\n * @type {CanvasTextAlign}\n */\nexport const defaultTextAlign = 'center';\n\n/**\n * @const\n * @type {CanvasTextBaseline}\n */\nexport const defaultTextBaseline = 'middle';\n\n/**\n * @const\n * @type {Array<number>}\n */\nexport const defaultPadding = [0, 0, 0, 0];\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineWidth = 1;\n\n/**\n * @type {BaseObject}\n */\nexport const checkedFonts = new BaseObject();\n\n/**\n * @type {CanvasRenderingContext2D}\n */\nlet measureContext = null;\n\n/**\n * @type {string}\n */\nlet measureFont;\n\n/**\n * @type {!Object<string, number>}\n */\nexport const textHeights = {};\n\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\nexport const registerFont = (function () {\n  const retries = 100;\n  const size = '32px ';\n  const referenceFonts = ['monospace', 'serif'];\n  const len = referenceFonts.length;\n  const text = 'wmytzilWMYTZIL@#/&?$%10\\uF013';\n  let interval, referenceWidth;\n\n  /**\n   * @param {string} fontStyle Css font-style\n   * @param {string} fontWeight Css font-weight\n   * @param {*} fontFamily Css font-family\n   * @return {boolean} Font with style and weight is available\n   */\n  function isAvailable(fontStyle, fontWeight, fontFamily) {\n    let available = true;\n    for (let i = 0; i < len; ++i) {\n      const referenceFont = referenceFonts[i];\n      referenceWidth = measureTextWidth(\n        fontStyle + ' ' + fontWeight + ' ' + size + referenceFont,\n        text\n      );\n      if (fontFamily != referenceFont) {\n        const width = measureTextWidth(\n          fontStyle +\n            ' ' +\n            fontWeight +\n            ' ' +\n            size +\n            fontFamily +\n            ',' +\n            referenceFont,\n          text\n        );\n        // If width and referenceWidth are the same, then the fallback was used\n        // instead of the font we wanted, so the font is not available.\n        available = available && width != referenceWidth;\n      }\n    }\n    if (available) {\n      return true;\n    }\n    return false;\n  }\n\n  function check() {\n    let done = true;\n    const fonts = checkedFonts.getKeys();\n    for (let i = 0, ii = fonts.length; i < ii; ++i) {\n      const font = fonts[i];\n      if (checkedFonts.get(font) < retries) {\n        if (isAvailable.apply(this, font.split('\\n'))) {\n          clear(textHeights);\n          // Make sure that loaded fonts are picked up by Safari\n          measureContext = null;\n          measureFont = undefined;\n          checkedFonts.set(font, retries);\n        } else {\n          checkedFonts.set(font, checkedFonts.get(font) + 1, true);\n          done = false;\n        }\n      }\n    }\n    if (done) {\n      clearInterval(interval);\n      interval = undefined;\n    }\n  }\n\n  return function (fontSpec) {\n    const font = getFontParameters(fontSpec);\n    if (!font) {\n      return;\n    }\n    const families = font.families;\n    for (let i = 0, ii = families.length; i < ii; ++i) {\n      const family = families[i];\n      const key = font.style + '\\n' + font.weight + '\\n' + family;\n      if (checkedFonts.get(key) === undefined) {\n        checkedFonts.set(key, retries, true);\n        if (!isAvailable(font.style, font.weight, family)) {\n          checkedFonts.set(key, 0, true);\n          if (interval === undefined) {\n            interval = setInterval(check, 32);\n          }\n        }\n      }\n    }\n  };\n})();\n\n/**\n * @param {string} font Font to use for measuring.\n * @return {import(\"../size.js\").Size} Measurement.\n */\nexport const measureTextHeight = (function () {\n  /**\n   * @type {HTMLDivElement}\n   */\n  let measureElement;\n  return function (fontSpec) {\n    let height = textHeights[fontSpec];\n    if (height == undefined) {\n      if (WORKER_OFFSCREEN_CANVAS) {\n        const font = getFontParameters(fontSpec);\n        const metrics = measureText(fontSpec, 'Žg');\n        const lineHeight = isNaN(Number(font.lineHeight))\n          ? 1.2\n          : Number(font.lineHeight);\n        height =\n          lineHeight *\n          (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);\n      } else {\n        if (!measureElement) {\n          measureElement = document.createElement('div');\n          measureElement.innerHTML = 'M';\n          measureElement.style.minHeight = '0';\n          measureElement.style.maxHeight = 'none';\n          measureElement.style.height = 'auto';\n          measureElement.style.padding = '0';\n          measureElement.style.border = 'none';\n          measureElement.style.position = 'absolute';\n          measureElement.style.display = 'block';\n          measureElement.style.left = '-99999px';\n        }\n        measureElement.style.font = fontSpec;\n        document.body.appendChild(measureElement);\n        height = measureElement.offsetHeight;\n        document.body.removeChild(measureElement);\n      }\n      textHeights[fontSpec] = height;\n    }\n    return height;\n  };\n})();\n\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {TextMetrics} Text metrics.\n */\nfunction measureText(font, text) {\n  if (!measureContext) {\n    measureContext = createCanvasContext2D(1, 1);\n  }\n  if (font != measureFont) {\n    measureContext.font = font;\n    measureFont = measureContext.font;\n  }\n  return measureContext.measureText(text);\n}\n\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\nexport function measureTextWidth(font, text) {\n  return measureText(font, text).width;\n}\n\n/**\n * Measure text width using a cache.\n * @param {string} font The font.\n * @param {string} text The text to measure.\n * @param {Object<string, number>} cache A lookup of cached widths by text.\n * @return {number} The text width.\n */\nexport function measureAndCacheTextWidth(font, text, cache) {\n  if (text in cache) {\n    return cache[text];\n  }\n  const width = text\n    .split('\\n')\n    .reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0);\n  cache[text] = width;\n  return width;\n}\n\n/**\n * @param {TextState} baseStyle Base style.\n * @param {Array<string>} chunks Text chunks to measure.\n * @return {{width: number, height: number, widths: Array<number>, heights: Array<number>, lineWidths: Array<number>}}} Text metrics.\n */\nexport function getTextDimensions(baseStyle, chunks) {\n  const widths = [];\n  const heights = [];\n  const lineWidths = [];\n  let width = 0;\n  let lineWidth = 0;\n  let height = 0;\n  let lineHeight = 0;\n  for (let i = 0, ii = chunks.length; i <= ii; i += 2) {\n    const text = chunks[i];\n    if (text === '\\n' || i === ii) {\n      width = Math.max(width, lineWidth);\n      lineWidths.push(lineWidth);\n      lineWidth = 0;\n      height += lineHeight;\n      continue;\n    }\n    const font = chunks[i + 1] || baseStyle.font;\n    const currentWidth = measureTextWidth(font, text);\n    widths.push(currentWidth);\n    lineWidth += currentWidth;\n    const currentHeight = measureTextHeight(font);\n    heights.push(currentHeight);\n    lineHeight = Math.max(lineHeight, currentHeight);\n  }\n  return {width, height, widths, heights, lineWidths};\n}\n\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\nexport function rotateAtOffset(context, rotation, offsetX, offsetY) {\n  if (rotation !== 0) {\n    context.translate(offsetX, offsetY);\n    context.rotate(rotation);\n    context.translate(-offsetX, -offsetY);\n  }\n}\n\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../transform.js\").Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../size.js\").Size} scale Scale.\n */\nexport function drawImageOrLabel(\n  context,\n  transform,\n  opacity,\n  labelOrImage,\n  originX,\n  originY,\n  w,\n  h,\n  x,\n  y,\n  scale\n) {\n  context.save();\n\n  if (opacity !== 1) {\n    context.globalAlpha *= opacity;\n  }\n  if (transform) {\n    context.setTransform.apply(context, transform);\n  }\n\n  if (/** @type {*} */ (labelOrImage).contextInstructions) {\n    // label\n    context.translate(x, y);\n    context.scale(scale[0], scale[1]);\n    executeLabelInstructions(/** @type {Label} */ (labelOrImage), context);\n  } else if (scale[0] < 0 || scale[1] < 0) {\n    // flipped image\n    context.translate(x, y);\n    context.scale(scale[0], scale[1]);\n    context.drawImage(\n      /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (\n        labelOrImage\n      ),\n      originX,\n      originY,\n      w,\n      h,\n      0,\n      0,\n      w,\n      h\n    );\n  } else {\n    // if image not flipped translate and scale can be avoided\n    context.drawImage(\n      /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (\n        labelOrImage\n      ),\n      originX,\n      originY,\n      w,\n      h,\n      x,\n      y,\n      w * scale[0],\n      h * scale[1]\n    );\n  }\n\n  context.restore();\n}\n\n/**\n * @param {Label} label Label.\n * @param {CanvasRenderingContext2D} context Context.\n */\nfunction executeLabelInstructions(label, context) {\n  const contextInstructions = label.contextInstructions;\n  for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {\n    if (Array.isArray(contextInstructions[i + 1])) {\n      context[contextInstructions[i]].apply(\n        context,\n        contextInstructions[i + 1]\n      );\n    } else {\n      context[contextInstructions[i]] = contextInstructions[i + 1];\n    }\n  }\n}\n","/**\n * @module ol/ObjectEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  /**\n   * Triggered when a property is changed.\n   * @event module:ol/Object.ObjectEvent#propertychange\n   * @api\n   */\n  PROPERTYCHANGE: 'propertychange',\n};\n\n/**\n * @typedef {'propertychange'} Types\n */\n","/**\n * @module ol/style/RegularShape\n */\n\nimport ImageState from '../ImageState.js';\nimport ImageStyle from './Image.js';\nimport {asArray} from '../color.js';\nimport {asColorLike} from '../colorlike.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {\n  defaultFillStyle,\n  defaultLineJoin,\n  defaultLineWidth,\n  defaultMiterLimit,\n  defaultStrokeStyle,\n} from '../render/canvas.js';\n\n/**\n * Specify radius for regular polygons, or radius1 and radius2 for stars.\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} [radius] Radius of a regular polygon.\n * @property {number} [radius1] First radius of a star. Ignored if radius is set.\n * @property {number} [radius2] Second radius of a star.\n * @property {number} [angle=0] Shape's angle in radians. A value of 0 will have one of the shape's points facing up.\n * @property {Array<number>} [displacement=[0, 0]] Displacement of the shape in pixels.\n * Positive values will shift the shape right and up.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. Unless two dimensional scaling is required a better\n * result may be obtained with appropriate settings for `radius`, `radius1` and `radius2`.\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} [declutterMode] Declutter mode.\n */\n\n/**\n * @typedef {Object} RenderOptions\n * @property {import(\"../colorlike.js\").ColorLike} [strokeStyle] StrokeStyle.\n * @property {number} strokeWidth StrokeWidth.\n * @property {number} size Size.\n * @property {Array<number>|null} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} miterLimit MiterLimit.\n */\n\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when `radius1` and\n * `radius2` are provided.\n * @api\n */\nclass RegularShape extends ImageStyle {\n  /**\n   * @param {Options} options Options.\n   */\n  constructor(options) {\n    /**\n     * @type {boolean}\n     */\n    const rotateWithView =\n      options.rotateWithView !== undefined ? options.rotateWithView : false;\n\n    super({\n      opacity: 1,\n      rotateWithView: rotateWithView,\n      rotation: options.rotation !== undefined ? options.rotation : 0,\n      scale: options.scale !== undefined ? options.scale : 1,\n      displacement:\n        options.displacement !== undefined ? options.displacement : [0, 0],\n      declutterMode: options.declutterMode,\n    });\n\n    /**\n     * @private\n     * @type {Object<number, HTMLCanvasElement>}\n     */\n    this.canvas_ = undefined;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.hitDetectionCanvas_ = null;\n\n    /**\n     * @private\n     * @type {import(\"./Fill.js\").default}\n     */\n    this.fill_ = options.fill !== undefined ? options.fill : null;\n\n    /**\n     * @private\n     * @type {Array<number>}\n     */\n    this.origin_ = [0, 0];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.points_ = options.points;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.radius_ =\n      options.radius !== undefined ? options.radius : options.radius1;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.radius2_ = options.radius2;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.angle_ = options.angle !== undefined ? options.angle : 0;\n\n    /**\n     * @private\n     * @type {import(\"./Stroke.js\").default}\n     */\n    this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n    /**\n     * @private\n     * @type {import(\"../size.js\").Size}\n     */\n    this.size_ = null;\n\n    /**\n     * @private\n     * @type {RenderOptions}\n     */\n    this.renderOptions_ = null;\n\n    this.render();\n  }\n\n  /**\n   * Clones the style.\n   * @return {RegularShape} The cloned style.\n   * @api\n   */\n  clone() {\n    const scale = this.getScale();\n    const style = new RegularShape({\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      points: this.getPoints(),\n      radius: this.getRadius(),\n      radius2: this.getRadius2(),\n      angle: this.getAngle(),\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView(),\n      scale: Array.isArray(scale) ? scale.slice() : scale,\n      displacement: this.getDisplacement().slice(),\n      declutterMode: this.getDeclutterMode(),\n    });\n    style.setOpacity(this.getOpacity());\n    return style;\n  }\n\n  /**\n   * Get the anchor point in pixels. The anchor determines the center point for the\n   * symbolizer.\n   * @return {Array<number>} Anchor.\n   * @api\n   */\n  getAnchor() {\n    const size = this.size_;\n    if (!size) {\n      return null;\n    }\n    const displacement = this.getDisplacement();\n    const scale = this.getScaleArray();\n    // anchor is scaled by renderer but displacement should not be scaled\n    // so divide by scale here\n    return [\n      size[0] / 2 - displacement[0] / scale[0],\n      size[1] / 2 + displacement[1] / scale[1],\n    ];\n  }\n\n  /**\n   * Get the angle used in generating the shape.\n   * @return {number} Shape's rotation in radians.\n   * @api\n   */\n  getAngle() {\n    return this.angle_;\n  }\n\n  /**\n   * Get the fill style for the shape.\n   * @return {import(\"./Fill.js\").default} Fill style.\n   * @api\n   */\n  getFill() {\n    return this.fill_;\n  }\n\n  /**\n   * Set the fill style.\n   * @param {import(\"./Fill.js\").default} fill Fill style.\n   * @api\n   */\n  setFill(fill) {\n    this.fill_ = fill;\n    this.render();\n  }\n\n  /**\n   * @return {HTMLCanvasElement} Image element.\n   */\n  getHitDetectionImage() {\n    if (!this.hitDetectionCanvas_) {\n      this.createHitDetectionCanvas_(this.renderOptions_);\n    }\n    return this.hitDetectionCanvas_;\n  }\n\n  /**\n   * Get the image icon.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {HTMLCanvasElement} Image or Canvas element.\n   * @api\n   */\n  getImage(pixelRatio) {\n    let image = this.canvas_[pixelRatio];\n    if (!image) {\n      const renderOptions = this.renderOptions_;\n      const context = createCanvasContext2D(\n        renderOptions.size * pixelRatio,\n        renderOptions.size * pixelRatio\n      );\n      this.draw_(renderOptions, context, pixelRatio);\n\n      image = context.canvas;\n      this.canvas_[pixelRatio] = image;\n    }\n    return image;\n  }\n\n  /**\n   * Get the image pixel ratio.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {number} Pixel ratio.\n   */\n  getPixelRatio(pixelRatio) {\n    return pixelRatio;\n  }\n\n  /**\n   * @return {import(\"../size.js\").Size} Image size.\n   */\n  getImageSize() {\n    return this.size_;\n  }\n\n  /**\n   * @return {import(\"../ImageState.js\").default} Image state.\n   */\n  getImageState() {\n    return ImageState.LOADED;\n  }\n\n  /**\n   * Get the origin of the symbolizer.\n   * @return {Array<number>} Origin.\n   * @api\n   */\n  getOrigin() {\n    return this.origin_;\n  }\n\n  /**\n   * Get the number of points for generating the shape.\n   * @return {number} Number of points for stars and regular polygons.\n   * @api\n   */\n  getPoints() {\n    return this.points_;\n  }\n\n  /**\n   * Get the (primary) radius for the shape.\n   * @return {number} Radius.\n   * @api\n   */\n  getRadius() {\n    return this.radius_;\n  }\n\n  /**\n   * Get the secondary radius for the shape.\n   * @return {number|undefined} Radius2.\n   * @api\n   */\n  getRadius2() {\n    return this.radius2_;\n  }\n\n  /**\n   * Get the size of the symbolizer (in pixels).\n   * @return {import(\"../size.js\").Size} Size.\n   * @api\n   */\n  getSize() {\n    return this.size_;\n  }\n\n  /**\n   * Get the stroke style for the shape.\n   * @return {import(\"./Stroke.js\").default} Stroke style.\n   * @api\n   */\n  getStroke() {\n    return this.stroke_;\n  }\n\n  /**\n   * Set the stroke style.\n   * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n   * @api\n   */\n  setStroke(stroke) {\n    this.stroke_ = stroke;\n    this.render();\n  }\n\n  /**\n   * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n   */\n  listenImageChange(listener) {}\n\n  /**\n   * Load not yet loaded URI.\n   */\n  load() {}\n\n  /**\n   * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n   */\n  unlistenImageChange(listener) {}\n\n  /**\n   * Calculate additional canvas size needed for the miter.\n   * @param {string} lineJoin Line join\n   * @param {number} strokeWidth Stroke width\n   * @param {number} miterLimit Miter limit\n   * @return {number} Additional canvas size needed\n   * @private\n   */\n  calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit) {\n    if (\n      strokeWidth === 0 ||\n      this.points_ === Infinity ||\n      (lineJoin !== 'bevel' && lineJoin !== 'miter')\n    ) {\n      return strokeWidth;\n    }\n    // m  | ^\n    // i  | |\\                  .\n    // t >|  #\\\n    // e  | |\\ \\              .\n    // r      \\s\\\n    //      |  \\t\\          .                 .\n    //          \\r\\                      .   .\n    //      |    \\o\\      .          .  . . .\n    //          e \\k\\            .  .    . .\n    //      |      \\e\\  .    .  .       . .\n    //       d      \\ \\  .  .          . .\n    //      | _ _a_ _\\#  .            . .\n    //   r1          / `             . .\n    //      |                       . .\n    //       b     /               . .\n    //      |                     . .\n    //           / r2            . .\n    //      |                        .   .\n    //         /                           .   .\n    //      |α                                   .   .\n    //       /                                         .   .\n    //      ° center\n    let r1 = this.radius_;\n    let r2 = this.radius2_ === undefined ? r1 : this.radius2_;\n    if (r1 < r2) {\n      const tmp = r1;\n      r1 = r2;\n      r2 = tmp;\n    }\n    const points =\n      this.radius2_ === undefined ? this.points_ : this.points_ * 2;\n    const alpha = (2 * Math.PI) / points;\n    const a = r2 * Math.sin(alpha);\n    const b = Math.sqrt(r2 * r2 - a * a);\n    const d = r1 - b;\n    const e = Math.sqrt(a * a + d * d);\n    const miterRatio = e / a;\n    if (lineJoin === 'miter' && miterRatio <= miterLimit) {\n      return miterRatio * strokeWidth;\n    }\n    // Calculate the distnce from center to the stroke corner where\n    // it was cut short because of the miter limit.\n    //              l\n    //        ----+---- <= distance from center to here is maxr\n    //       /####|k ##\\\n    //      /#####^#####\\\n    //     /#### /+\\# s #\\\n    //    /### h/+++\\# t #\\\n    //   /### t/+++++\\# r #\\\n    //  /### a/+++++++\\# o #\\\n    // /### p/++ fill +\\# k #\\\n    ///#### /+++++^+++++\\# e #\\\n    //#####/+++++/+\\+++++\\#####\\\n    const k = strokeWidth / 2 / miterRatio;\n    const l = (strokeWidth / 2) * (d / e);\n    const maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);\n    const bevelAdd = maxr - r1;\n    if (this.radius2_ === undefined || lineJoin === 'bevel') {\n      return bevelAdd * 2;\n    }\n    // If outer miter is over the miter limit the inner miter may reach through the\n    // center and be longer than the bevel, same calculation as above but swap r1 / r2.\n    const aa = r1 * Math.sin(alpha);\n    const bb = Math.sqrt(r1 * r1 - aa * aa);\n    const dd = r2 - bb;\n    const ee = Math.sqrt(aa * aa + dd * dd);\n    const innerMiterRatio = ee / aa;\n    if (innerMiterRatio <= miterLimit) {\n      const innerLength = (innerMiterRatio * strokeWidth) / 2 - r2 - r1;\n      return 2 * Math.max(bevelAdd, innerLength);\n    }\n    return bevelAdd * 2;\n  }\n\n  /**\n   * @return {RenderOptions}  The render options\n   * @protected\n   */\n  createRenderOptions() {\n    let lineJoin = defaultLineJoin;\n    let miterLimit = 0;\n    let lineDash = null;\n    let lineDashOffset = 0;\n    let strokeStyle;\n    let strokeWidth = 0;\n\n    if (this.stroke_) {\n      strokeStyle = this.stroke_.getColor();\n      if (strokeStyle === null) {\n        strokeStyle = defaultStrokeStyle;\n      }\n      strokeStyle = asColorLike(strokeStyle);\n      strokeWidth = this.stroke_.getWidth();\n      if (strokeWidth === undefined) {\n        strokeWidth = defaultLineWidth;\n      }\n      lineDash = this.stroke_.getLineDash();\n      lineDashOffset = this.stroke_.getLineDashOffset();\n      lineJoin = this.stroke_.getLineJoin();\n      if (lineJoin === undefined) {\n        lineJoin = defaultLineJoin;\n      }\n      miterLimit = this.stroke_.getMiterLimit();\n      if (miterLimit === undefined) {\n        miterLimit = defaultMiterLimit;\n      }\n    }\n\n    const add = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);\n    const maxRadius = Math.max(this.radius_, this.radius2_ || 0);\n    const size = Math.ceil(2 * maxRadius + add);\n\n    return {\n      strokeStyle: strokeStyle,\n      strokeWidth: strokeWidth,\n      size: size,\n      lineDash: lineDash,\n      lineDashOffset: lineDashOffset,\n      lineJoin: lineJoin,\n      miterLimit: miterLimit,\n    };\n  }\n\n  /**\n   * @protected\n   */\n  render() {\n    this.renderOptions_ = this.createRenderOptions();\n    const size = this.renderOptions_.size;\n    this.canvas_ = {};\n    this.size_ = [size, size];\n  }\n\n  /**\n   * @private\n   * @param {RenderOptions} renderOptions Render options.\n   * @param {CanvasRenderingContext2D} context The rendering context.\n   * @param {number} pixelRatio The pixel ratio.\n   */\n  draw_(renderOptions, context, pixelRatio) {\n    context.scale(pixelRatio, pixelRatio);\n    // set origin to canvas center\n    context.translate(renderOptions.size / 2, renderOptions.size / 2);\n\n    this.createPath_(context);\n\n    if (this.fill_) {\n      let color = this.fill_.getColor();\n      if (color === null) {\n        color = defaultFillStyle;\n      }\n      context.fillStyle = asColorLike(color);\n      context.fill();\n    }\n    if (this.stroke_) {\n      context.strokeStyle = renderOptions.strokeStyle;\n      context.lineWidth = renderOptions.strokeWidth;\n      if (renderOptions.lineDash) {\n        context.setLineDash(renderOptions.lineDash);\n        context.lineDashOffset = renderOptions.lineDashOffset;\n      }\n      context.lineJoin = renderOptions.lineJoin;\n      context.miterLimit = renderOptions.miterLimit;\n      context.stroke();\n    }\n  }\n\n  /**\n   * @private\n   * @param {RenderOptions} renderOptions Render options.\n   */\n  createHitDetectionCanvas_(renderOptions) {\n    if (this.fill_) {\n      let color = this.fill_.getColor();\n\n      // determine if fill is transparent (or pattern or gradient)\n      let opacity = 0;\n      if (typeof color === 'string') {\n        color = asArray(color);\n      }\n      if (color === null) {\n        opacity = 1;\n      } else if (Array.isArray(color)) {\n        opacity = color.length === 4 ? color[3] : 1;\n      }\n      if (opacity === 0) {\n        // if a transparent fill style is set, create an extra hit-detection image\n        // with a default fill style\n        const context = createCanvasContext2D(\n          renderOptions.size,\n          renderOptions.size\n        );\n        this.hitDetectionCanvas_ = context.canvas;\n\n        this.drawHitDetectionCanvas_(renderOptions, context);\n      }\n    }\n    if (!this.hitDetectionCanvas_) {\n      this.hitDetectionCanvas_ = this.getImage(1);\n    }\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} context The context to draw in.\n   */\n  createPath_(context) {\n    let points = this.points_;\n    const radius = this.radius_;\n    if (points === Infinity) {\n      context.arc(0, 0, radius, 0, 2 * Math.PI);\n    } else {\n      const radius2 = this.radius2_ === undefined ? radius : this.radius2_;\n      if (this.radius2_ !== undefined) {\n        points *= 2;\n      }\n      const startAngle = this.angle_ - Math.PI / 2;\n      const step = (2 * Math.PI) / points;\n      for (let i = 0; i < points; i++) {\n        const angle0 = startAngle + i * step;\n        const radiusC = i % 2 === 0 ? radius : radius2;\n        context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));\n      }\n      context.closePath();\n    }\n  }\n\n  /**\n   * @private\n   * @param {RenderOptions} renderOptions Render options.\n   * @param {CanvasRenderingContext2D} context The context.\n   */\n  drawHitDetectionCanvas_(renderOptions, context) {\n    // set origin to canvas center\n    context.translate(renderOptions.size / 2, renderOptions.size / 2);\n\n    this.createPath_(context);\n\n    context.fillStyle = defaultFillStyle;\n    context.fill();\n    if (this.stroke_) {\n      context.strokeStyle = renderOptions.strokeStyle;\n      context.lineWidth = renderOptions.strokeWidth;\n      if (renderOptions.lineDash) {\n        context.setLineDash(renderOptions.lineDash);\n        context.lineDashOffset = renderOptions.lineDashOffset;\n      }\n      context.lineJoin = renderOptions.lineJoin;\n      context.miterLimit = renderOptions.miterLimit;\n      context.stroke();\n    }\n  }\n}\n\nexport default RegularShape;\n","/**\n * @module ol/ImageState\n */\n\n/**\n * @enum {number}\n */\nexport default {\n  IDLE: 0,\n  LOADING: 1,\n  LOADED: 2,\n  ERROR: 3,\n  EMPTY: 4,\n};\n","/**\n * @module ol/style/Circle\n */\n\nimport RegularShape from './RegularShape.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {Array<number>} [displacement=[0,0]] displacement\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.\n * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.\n * @property {number} [rotation=0] Rotation in radians\n * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view\n * (meaningful only when used in conjunction with a two dimensional scale).\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} [declutterMode] Declutter mode\n */\n\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\nclass CircleStyle extends RegularShape {\n  /**\n   * @param {Options} [options] Options.\n   */\n  constructor(options) {\n    options = options ? options : {radius: 5};\n\n    super({\n      points: Infinity,\n      fill: options.fill,\n      radius: options.radius,\n      stroke: options.stroke,\n      scale: options.scale !== undefined ? options.scale : 1,\n      rotation: options.rotation !== undefined ? options.rotation : 0,\n      rotateWithView:\n        options.rotateWithView !== undefined ? options.rotateWithView : false,\n      displacement:\n        options.displacement !== undefined ? options.displacement : [0, 0],\n      declutterMode: options.declutterMode,\n    });\n  }\n\n  /**\n   * Clones the style.\n   * @return {CircleStyle} The cloned style.\n   * @api\n   */\n  clone() {\n    const scale = this.getScale();\n    const style = new CircleStyle({\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      radius: this.getRadius(),\n      scale: Array.isArray(scale) ? scale.slice() : scale,\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView(),\n      displacement: this.getDisplacement().slice(),\n      declutterMode: this.getDeclutterMode(),\n    });\n    style.setOpacity(this.getOpacity());\n    return style;\n  }\n\n  /**\n   * Set the circle radius.\n   *\n   * @param {number} radius Circle radius.\n   * @api\n   */\n  setRadius(radius) {\n    this.radius_ = radius;\n    this.render();\n  }\n}\n\nexport default CircleStyle;\n","/**\n * @module ol/style/Fill\n */\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} [color=null] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nclass Fill {\n  /**\n   * @param {Options} [options] Options.\n   */\n  constructor(options) {\n    options = options || {};\n\n    /**\n     * @private\n     * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null}\n     */\n    this.color_ = options.color !== undefined ? options.color : null;\n  }\n\n  /**\n   * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.\n   * @return {Fill} The cloned style.\n   * @api\n   */\n  clone() {\n    const color = this.getColor();\n    return new Fill({\n      color: Array.isArray(color) ? color.slice() : color || undefined,\n    });\n  }\n\n  /**\n   * Get the fill color.\n   * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} Color.\n   * @api\n   */\n  getColor() {\n    return this.color_;\n  }\n\n  /**\n   * Set the color.\n   *\n   * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} color Color.\n   * @api\n   */\n  setColor(color) {\n    this.color_ = color;\n  }\n}\n\nexport default Fill;\n","/**\n * @module ol/style/Stroke\n */\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {CanvasLineCap} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.\n * @property {CanvasLineJoin} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nclass Stroke {\n  /**\n   * @param {Options} [options] Options.\n   */\n  constructor(options) {\n    options = options || {};\n\n    /**\n     * @private\n     * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike}\n     */\n    this.color_ = options.color !== undefined ? options.color : null;\n\n    /**\n     * @private\n     * @type {CanvasLineCap|undefined}\n     */\n    this.lineCap_ = options.lineCap;\n\n    /**\n     * @private\n     * @type {Array<number>|null}\n     */\n    this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lineDashOffset_ = options.lineDashOffset;\n\n    /**\n     * @private\n     * @type {CanvasLineJoin|undefined}\n     */\n    this.lineJoin_ = options.lineJoin;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.miterLimit_ = options.miterLimit;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.width_ = options.width;\n  }\n\n  /**\n   * Clones the style.\n   * @return {Stroke} The cloned style.\n   * @api\n   */\n  clone() {\n    const color = this.getColor();\n    return new Stroke({\n      color: Array.isArray(color) ? color.slice() : color || undefined,\n      lineCap: this.getLineCap(),\n      lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n      lineDashOffset: this.getLineDashOffset(),\n      lineJoin: this.getLineJoin(),\n      miterLimit: this.getMiterLimit(),\n      width: this.getWidth(),\n    });\n  }\n\n  /**\n   * Get the stroke color.\n   * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} Color.\n   * @api\n   */\n  getColor() {\n    return this.color_;\n  }\n\n  /**\n   * Get the line cap type for the stroke.\n   * @return {CanvasLineCap|undefined} Line cap.\n   * @api\n   */\n  getLineCap() {\n    return this.lineCap_;\n  }\n\n  /**\n   * Get the line dash style for the stroke.\n   * @return {Array<number>|null} Line dash.\n   * @api\n   */\n  getLineDash() {\n    return this.lineDash_;\n  }\n\n  /**\n   * Get the line dash offset for the stroke.\n   * @return {number|undefined} Line dash offset.\n   * @api\n   */\n  getLineDashOffset() {\n    return this.lineDashOffset_;\n  }\n\n  /**\n   * Get the line join type for the stroke.\n   * @return {CanvasLineJoin|undefined} Line join.\n   * @api\n   */\n  getLineJoin() {\n    return this.lineJoin_;\n  }\n\n  /**\n   * Get the miter limit for the stroke.\n   * @return {number|undefined} Miter limit.\n   * @api\n   */\n  getMiterLimit() {\n    return this.miterLimit_;\n  }\n\n  /**\n   * Get the stroke width.\n   * @return {number|undefined} Width.\n   * @api\n   */\n  getWidth() {\n    return this.width_;\n  }\n\n  /**\n   * Set the color.\n   *\n   * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} color Color.\n   * @api\n   */\n  setColor(color) {\n    this.color_ = color;\n  }\n\n  /**\n   * Set the line cap.\n   *\n   * @param {CanvasLineCap|undefined} lineCap Line cap.\n   * @api\n   */\n  setLineCap(lineCap) {\n    this.lineCap_ = lineCap;\n  }\n\n  /**\n   * Set the line dash.\n   *\n   * @param {Array<number>|null} lineDash Line dash.\n   * @api\n   */\n  setLineDash(lineDash) {\n    this.lineDash_ = lineDash;\n  }\n\n  /**\n   * Set the line dash offset.\n   *\n   * @param {number|undefined} lineDashOffset Line dash offset.\n   * @api\n   */\n  setLineDashOffset(lineDashOffset) {\n    this.lineDashOffset_ = lineDashOffset;\n  }\n\n  /**\n   * Set the line join.\n   *\n   * @param {CanvasLineJoin|undefined} lineJoin Line join.\n   * @api\n   */\n  setLineJoin(lineJoin) {\n    this.lineJoin_ = lineJoin;\n  }\n\n  /**\n   * Set the miter limit.\n   *\n   * @param {number|undefined} miterLimit Miter limit.\n   * @api\n   */\n  setMiterLimit(miterLimit) {\n    this.miterLimit_ = miterLimit;\n  }\n\n  /**\n   * Set the width.\n   *\n   * @param {number|undefined} width Width.\n   * @api\n   */\n  setWidth(width) {\n    this.width_ = width;\n  }\n}\n\nexport default Stroke;\n","/**\n * @module ol/style/Style\n */\n\nimport CircleStyle from './Circle.js';\nimport Fill from './Fill.js';\nimport Stroke from './Stroke.js';\nimport {assert} from '../asserts.js';\n\n/**\n * A function that takes an {@link module:ol/Feature~Feature} and a `{number}`\n * representing the view's resolution. The function should return a\n * {@link module:ol/style/Style~Style} or an array of them. This way e.g. a\n * vector layer can be styled. If the function returns `undefined`, the\n * feature will not be rendered.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction\n */\n\n/**\n * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.\n * @typedef {Style|Array<Style>|StyleFunction} StyleLike\n */\n\n/**\n * A function that takes an {@link module:ol/Feature~Feature} as argument and returns an\n * {@link module:ol/geom/Geometry~Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike):\n *     (import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined)} GeometryFunction\n */\n\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((import(\"../coordinate.js\").Coordinate|Array<import(\"../coordinate.js\").Coordinate>|Array<Array<import(\"../coordinate.js\").Coordinate>>),import(\"../render.js\").State): void} RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string|import(\"../geom/Geometry.js\").default|GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {import(\"./Image.js\").default} [image] Image style.\n * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {RenderFunction} [hitDetectionRenderer] Custom renderer for hit detection. If provided will be used\n * in hit detection rendering.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {import(\"./Text.js\").default} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n *\n * ## Feature styles\n *\n * If no style is defined, the following default style is used:\n * ```js\n *  import {Circle, Fill, Stroke, Style} from 'ol/style';\n *\n *  const fill = new Fill({\n *    color: 'rgba(255,255,255,0.4)',\n *  });\n *  const stroke = new Stroke({\n *    color: '#3399CC',\n *    width: 1.25,\n *  });\n *  const styles = [\n *    new Style({\n *      image: new Circle({\n *        fill: fill,\n *        stroke: stroke,\n *        radius: 5,\n *      }),\n *      fill: fill,\n *      stroke: stroke,\n *    }),\n *  ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n *  import {Circle, Fill, Stroke, Style} from 'ol/style';\n *\n *  const styles = {};\n *  const white = [255, 255, 255, 1];\n *  const blue = [0, 153, 255, 1];\n *  const width = 3;\n *  styles['Polygon'] = [\n *    new Style({\n *      fill: new Fill({\n *        color: [255, 255, 255, 0.5],\n *      }),\n *    }),\n *  ];\n *  styles['MultiPolygon'] =\n *      styles['Polygon'];\n *  styles['LineString'] = [\n *    new Style({\n *      stroke: new Stroke({\n *        color: white,\n *        width: width + 2,\n *      }),\n *    }),\n *    new Style({\n *      stroke: new Stroke({\n *        color: blue,\n *        width: width,\n *      }),\n *    }),\n *  ];\n *  styles['MultiLineString'] = styles['LineString'];\n *\n *  styles['Circle'] = styles['Polygon'].concat(\n *    styles['LineString']\n *  );\n *\n *  styles['Point'] = [\n *    new Style({\n *      image: new Circle({\n *        radius: width * 2,\n *        fill: new Fill({\n *          color: blue,\n *        }),\n *        stroke: new Stroke({\n *          color: white,\n *          width: width / 2,\n *        }),\n *      }),\n *      zIndex: Infinity,\n *    }),\n *  ];\n *  styles['MultiPoint'] =\n *      styles['Point'];\n *  styles['GeometryCollection'] =\n *      styles['Polygon'].concat(\n *          styles['LineString'],\n *          styles['Point']\n *      );\n * ```\n *\n * @api\n */\nclass Style {\n  /**\n   * @param {Options} [options] Style options.\n   */\n  constructor(options) {\n    options = options || {};\n\n    /**\n     * @private\n     * @type {string|import(\"../geom/Geometry.js\").default|GeometryFunction}\n     */\n    this.geometry_ = null;\n\n    /**\n     * @private\n     * @type {!GeometryFunction}\n     */\n    this.geometryFunction_ = defaultGeometryFunction;\n\n    if (options.geometry !== undefined) {\n      this.setGeometry(options.geometry);\n    }\n\n    /**\n     * @private\n     * @type {import(\"./Fill.js\").default}\n     */\n    this.fill_ = options.fill !== undefined ? options.fill : null;\n\n    /**\n     * @private\n     * @type {import(\"./Image.js\").default}\n     */\n    this.image_ = options.image !== undefined ? options.image : null;\n\n    /**\n     * @private\n     * @type {RenderFunction|null}\n     */\n    this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n\n    /**\n     * @private\n     * @type {RenderFunction|null}\n     */\n    this.hitDetectionRenderer_ =\n      options.hitDetectionRenderer !== undefined\n        ? options.hitDetectionRenderer\n        : null;\n\n    /**\n     * @private\n     * @type {import(\"./Stroke.js\").default}\n     */\n    this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n    /**\n     * @private\n     * @type {import(\"./Text.js\").default}\n     */\n    this.text_ = options.text !== undefined ? options.text : null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.zIndex_ = options.zIndex;\n  }\n\n  /**\n   * Clones the style.\n   * @return {Style} The cloned style.\n   * @api\n   */\n  clone() {\n    let geometry = this.getGeometry();\n    if (geometry && typeof geometry === 'object') {\n      geometry = /** @type {import(\"../geom/Geometry.js\").default} */ (\n        geometry\n      ).clone();\n    }\n    return new Style({\n      geometry: geometry,\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      image: this.getImage() ? this.getImage().clone() : undefined,\n      renderer: this.getRenderer(),\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      text: this.getText() ? this.getText().clone() : undefined,\n      zIndex: this.getZIndex(),\n    });\n  }\n\n  /**\n   * Get the custom renderer function that was configured with\n   * {@link #setRenderer} or the `renderer` constructor option.\n   * @return {RenderFunction|null} Custom renderer function.\n   * @api\n   */\n  getRenderer() {\n    return this.renderer_;\n  }\n\n  /**\n   * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n   * and `image` options of the style will be ignored.\n   * @param {RenderFunction|null} renderer Custom renderer function.\n   * @api\n   */\n  setRenderer(renderer) {\n    this.renderer_ = renderer;\n  }\n\n  /**\n   * Sets a custom renderer function for this style used\n   * in hit detection.\n   * @param {RenderFunction|null} renderer Custom renderer function.\n   * @api\n   */\n  setHitDetectionRenderer(renderer) {\n    this.hitDetectionRenderer_ = renderer;\n  }\n\n  /**\n   * Get the custom renderer function that was configured with\n   * {@link #setHitDetectionRenderer} or the `hitDetectionRenderer` constructor option.\n   * @return {RenderFunction|null} Custom renderer function.\n   * @api\n   */\n  getHitDetectionRenderer() {\n    return this.hitDetectionRenderer_;\n  }\n\n  /**\n   * Get the geometry to be rendered.\n   * @return {string|import(\"../geom/Geometry.js\").default|GeometryFunction}\n   * Feature property or geometry or function that returns the geometry that will\n   * be rendered with this style.\n   * @api\n   */\n  getGeometry() {\n    return this.geometry_;\n  }\n\n  /**\n   * Get the function used to generate a geometry for rendering.\n   * @return {!GeometryFunction} Function that is called with a feature\n   * and returns the geometry to render instead of the feature's geometry.\n   * @api\n   */\n  getGeometryFunction() {\n    return this.geometryFunction_;\n  }\n\n  /**\n   * Get the fill style.\n   * @return {import(\"./Fill.js\").default} Fill style.\n   * @api\n   */\n  getFill() {\n    return this.fill_;\n  }\n\n  /**\n   * Set the fill style.\n   * @param {import(\"./Fill.js\").default} fill Fill style.\n   * @api\n   */\n  setFill(fill) {\n    this.fill_ = fill;\n  }\n\n  /**\n   * Get the image style.\n   * @return {import(\"./Image.js\").default} Image style.\n   * @api\n   */\n  getImage() {\n    return this.image_;\n  }\n\n  /**\n   * Set the image style.\n   * @param {import(\"./Image.js\").default} image Image style.\n   * @api\n   */\n  setImage(image) {\n    this.image_ = image;\n  }\n\n  /**\n   * Get the stroke style.\n   * @return {import(\"./Stroke.js\").default} Stroke style.\n   * @api\n   */\n  getStroke() {\n    return this.stroke_;\n  }\n\n  /**\n   * Set the stroke style.\n   * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n   * @api\n   */\n  setStroke(stroke) {\n    this.stroke_ = stroke;\n  }\n\n  /**\n   * Get the text style.\n   * @return {import(\"./Text.js\").default} Text style.\n   * @api\n   */\n  getText() {\n    return this.text_;\n  }\n\n  /**\n   * Set the text style.\n   * @param {import(\"./Text.js\").default} text Text style.\n   * @api\n   */\n  setText(text) {\n    this.text_ = text;\n  }\n\n  /**\n   * Get the z-index for the style.\n   * @return {number|undefined} ZIndex.\n   * @api\n   */\n  getZIndex() {\n    return this.zIndex_;\n  }\n\n  /**\n   * Set a geometry that is rendered instead of the feature's geometry.\n   *\n   * @param {string|import(\"../geom/Geometry.js\").default|GeometryFunction} geometry\n   *     Feature property or geometry or function returning a geometry to render\n   *     for this style.\n   * @api\n   */\n  setGeometry(geometry) {\n    if (typeof geometry === 'function') {\n      this.geometryFunction_ = geometry;\n    } else if (typeof geometry === 'string') {\n      this.geometryFunction_ = function (feature) {\n        return /** @type {import(\"../geom/Geometry.js\").default} */ (\n          feature.get(geometry)\n        );\n      };\n    } else if (!geometry) {\n      this.geometryFunction_ = defaultGeometryFunction;\n    } else if (geometry !== undefined) {\n      this.geometryFunction_ = function () {\n        return /** @type {import(\"../geom/Geometry.js\").default} */ (geometry);\n      };\n    }\n    this.geometry_ = geometry;\n  }\n\n  /**\n   * Set the z-index.\n   *\n   * @param {number|undefined} zIndex ZIndex.\n   * @api\n   */\n  setZIndex(zIndex) {\n    this.zIndex_ = zIndex;\n  }\n}\n\n/**\n * Convert the provided object into a style function.  Functions passed through\n * unchanged.  Arrays of Style or single style objects wrapped in a\n * new style function.\n * @param {StyleFunction|Array<Style>|Style} obj\n *     A style function, a single style, or an array of styles.\n * @return {StyleFunction} A style function.\n */\nexport function toFunction(obj) {\n  let styleFunction;\n\n  if (typeof obj === 'function') {\n    styleFunction = obj;\n  } else {\n    /**\n     * @type {Array<Style>}\n     */\n    let styles;\n    if (Array.isArray(obj)) {\n      styles = obj;\n    } else {\n      assert(typeof (/** @type {?} */ (obj).getZIndex) === 'function', 41); // Expected an `Style` or an array of `Style`\n      const style = /** @type {Style} */ (obj);\n      styles = [style];\n    }\n    styleFunction = function () {\n      return styles;\n    };\n  }\n  return styleFunction;\n}\n\n/**\n * @type {Array<Style>|null}\n */\nlet defaultStyles = null;\n\n/**\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array<Style>} Style.\n */\nexport function createDefaultStyle(feature, resolution) {\n  // We don't use an immediately-invoked function\n  // and a closure so we don't get an error at script evaluation time in\n  // browsers that do not support Canvas. (import(\"./Circle.js\").CircleStyle does\n  // canvas.getContext('2d') at construction time, which will cause an.error\n  // in such browsers.)\n  if (!defaultStyles) {\n    const fill = new Fill({\n      color: 'rgba(255,255,255,0.4)',\n    });\n    const stroke = new Stroke({\n      color: '#3399CC',\n      width: 1.25,\n    });\n    defaultStyles = [\n      new Style({\n        image: new CircleStyle({\n          fill: fill,\n          stroke: stroke,\n          radius: 5,\n        }),\n        fill: fill,\n        stroke: stroke,\n      }),\n    ];\n  }\n  return defaultStyles;\n}\n\n/**\n * Default styles for editing features.\n * @return {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} Styles\n */\nexport function createEditingStyle() {\n  /** @type {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} */\n  const styles = {};\n  const white = [255, 255, 255, 1];\n  const blue = [0, 153, 255, 1];\n  const width = 3;\n  styles['Polygon'] = [\n    new Style({\n      fill: new Fill({\n        color: [255, 255, 255, 0.5],\n      }),\n    }),\n  ];\n  styles['MultiPolygon'] = styles['Polygon'];\n\n  styles['LineString'] = [\n    new Style({\n      stroke: new Stroke({\n        color: white,\n        width: width + 2,\n      }),\n    }),\n    new Style({\n      stroke: new Stroke({\n        color: blue,\n        width: width,\n      }),\n    }),\n  ];\n  styles['MultiLineString'] = styles['LineString'];\n\n  styles['Circle'] = styles['Polygon'].concat(styles['LineString']);\n\n  styles['Point'] = [\n    new Style({\n      image: new CircleStyle({\n        radius: width * 2,\n        fill: new Fill({\n          color: blue,\n        }),\n        stroke: new Stroke({\n          color: white,\n          width: width / 2,\n        }),\n      }),\n      zIndex: Infinity,\n    }),\n  ];\n  styles['MultiPoint'] = styles['Point'];\n\n  styles['GeometryCollection'] = styles['Polygon'].concat(\n    styles['LineString'],\n    styles['Point']\n  );\n\n  return styles;\n}\n\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature to get the geometry for.\n * @return {import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined} Geometry to render.\n */\nfunction defaultGeometryFunction(feature) {\n  return feature.getGeometry();\n}\n\nexport default Style;\n","/**\n * @module ol/proj/Units\n */\n\n/**\n * @typedef {'radians' | 'degrees' | 'ft' | 'm' | 'pixels' | 'tile-pixels' | 'us-ft'} Units\n * Projection units.\n */\n\n/**\n * See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt\n * @type {Object<number, Units>}\n */\nconst unitByCode = {\n  '9001': 'm',\n  '9002': 'ft',\n  '9003': 'us-ft',\n  '9101': 'radians',\n  '9102': 'degrees',\n};\n\n/**\n * @param {number} code Unit code.\n * @return {Units} Units.\n */\nexport function fromCode(code) {\n  return unitByCode[code];\n}\n\n/**\n * @typedef {Object} MetersPerUnitLookup\n * @property {number} radians Radians\n * @property {number} degrees Degrees\n * @property {number} ft  Feet\n * @property {number} m Meters\n * @property {number} us-ft US feet\n */\n\n/**\n * Meters per unit lookup table.\n * @const\n * @type {MetersPerUnitLookup}\n * @api\n */\nexport const METERS_PER_UNIT = {\n  // use the radius of the Normal sphere\n  'radians': 6370997 / (2 * Math.PI),\n  'degrees': (2 * Math.PI * 6370997) / 360,\n  'ft': 0.3048,\n  'm': 1,\n  'us-ft': 1200 / 3937,\n};\n","/**\n * @module ol/proj/Projection\n */\nimport {METERS_PER_UNIT} from './Units.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import(\"./Units.js\").Units} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import(\"../extent.js\").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link METERS_PER_UNIT}\n * lookup table.\n * @property {import(\"../extent.js\").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import(\"../coordinate.js\").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `number` view resolution and a {@link module:ol/coordinate~Coordinate} as arguments, and returns\n * the `number` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj.getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj.get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n *     urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n *     http://www.opengis.net/gml/srs/epsg.xml#4326,\n *     urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n *     urn:ogc:def:crs:EPSG:6.18:3:3857,\n *     http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4.register} function.\n *\n * @api\n */\nclass Projection {\n  /**\n   * @param {Options} options Projection options.\n   */\n  constructor(options) {\n    /**\n     * @private\n     * @type {string}\n     */\n    this.code_ = options.code;\n\n    /**\n     * Units of projected coordinates. When set to `TILE_PIXELS`, a\n     * `this.extent_` and `this.worldExtent_` must be configured properly for each\n     * tile.\n     * @private\n     * @type {import(\"./Units.js\").Units}\n     */\n    this.units_ = /** @type {import(\"./Units.js\").Units} */ (options.units);\n\n    /**\n     * Validity extent of the projection in projected coordinates. For projections\n     * with `TILE_PIXELS` units, this is the extent of the tile in\n     * tile pixel space.\n     * @private\n     * @type {import(\"../extent.js\").Extent}\n     */\n    this.extent_ = options.extent !== undefined ? options.extent : null;\n\n    /**\n     * Extent of the world in EPSG:4326. For projections with\n     * `TILE_PIXELS` units, this is the extent of the tile in\n     * projected coordinate space.\n     * @private\n     * @type {import(\"../extent.js\").Extent}\n     */\n    this.worldExtent_ =\n      options.worldExtent !== undefined ? options.worldExtent : null;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.axisOrientation_ =\n      options.axisOrientation !== undefined ? options.axisOrientation : 'enu';\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.global_ = options.global !== undefined ? options.global : false;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.canWrapX_ = !!(this.global_ && this.extent_);\n\n    /**\n     * @private\n     * @type {function(number, import(\"../coordinate.js\").Coordinate):number|undefined}\n     */\n    this.getPointResolutionFunc_ = options.getPointResolution;\n\n    /**\n     * @private\n     * @type {import(\"../tilegrid/TileGrid.js\").default}\n     */\n    this.defaultTileGrid_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.metersPerUnit_ = options.metersPerUnit;\n  }\n\n  /**\n   * @return {boolean} The projection is suitable for wrapping the x-axis\n   */\n  canWrapX() {\n    return this.canWrapX_;\n  }\n\n  /**\n   * Get the code for this projection, e.g. 'EPSG:4326'.\n   * @return {string} Code.\n   * @api\n   */\n  getCode() {\n    return this.code_;\n  }\n\n  /**\n   * Get the validity extent for this projection.\n   * @return {import(\"../extent.js\").Extent} Extent.\n   * @api\n   */\n  getExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * Get the units of this projection.\n   * @return {import(\"./Units.js\").Units} Units.\n   * @api\n   */\n  getUnits() {\n    return this.units_;\n  }\n\n  /**\n   * Get the amount of meters per unit of this projection.  If the projection is\n   * not configured with `metersPerUnit` or a units identifier, the return is\n   * `undefined`.\n   * @return {number|undefined} Meters.\n   * @api\n   */\n  getMetersPerUnit() {\n    return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n  }\n\n  /**\n   * Get the world extent for this projection.\n   * @return {import(\"../extent.js\").Extent} Extent.\n   * @api\n   */\n  getWorldExtent() {\n    return this.worldExtent_;\n  }\n\n  /**\n   * Get the axis orientation of this projection.\n   * Example values are:\n   * enu - the default easting, northing, elevation.\n   * neu - northing, easting, up - useful for \"lat/long\" geographic coordinates,\n   *     or south orientated transverse mercator.\n   * wnu - westing, northing, up - some planetary coordinate systems have\n   *     \"west positive\" coordinate systems\n   * @return {string} Axis orientation.\n   * @api\n   */\n  getAxisOrientation() {\n    return this.axisOrientation_;\n  }\n\n  /**\n   * Is this projection a global projection which spans the whole world?\n   * @return {boolean} Whether the projection is global.\n   * @api\n   */\n  isGlobal() {\n    return this.global_;\n  }\n\n  /**\n   * Set if the projection is a global projection which spans the whole world\n   * @param {boolean} global Whether the projection is global.\n   * @api\n   */\n  setGlobal(global) {\n    this.global_ = global;\n    this.canWrapX_ = !!(global && this.extent_);\n  }\n\n  /**\n   * @return {import(\"../tilegrid/TileGrid.js\").default} The default tile grid.\n   */\n  getDefaultTileGrid() {\n    return this.defaultTileGrid_;\n  }\n\n  /**\n   * @param {import(\"../tilegrid/TileGrid.js\").default} tileGrid The default tile grid.\n   */\n  setDefaultTileGrid(tileGrid) {\n    this.defaultTileGrid_ = tileGrid;\n  }\n\n  /**\n   * Set the validity extent for this projection.\n   * @param {import(\"../extent.js\").Extent} extent Extent.\n   * @api\n   */\n  setExtent(extent) {\n    this.extent_ = extent;\n    this.canWrapX_ = !!(this.global_ && extent);\n  }\n\n  /**\n   * Set the world extent for this projection.\n   * @param {import(\"../extent.js\").Extent} worldExtent World extent\n   *     [minlon, minlat, maxlon, maxlat].\n   * @api\n   */\n  setWorldExtent(worldExtent) {\n    this.worldExtent_ = worldExtent;\n  }\n\n  /**\n   * Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}\n   * for this projection.\n   * @param {function(number, import(\"../coordinate.js\").Coordinate):number} func Function\n   * @api\n   */\n  setGetPointResolution(func) {\n    this.getPointResolutionFunc_ = func;\n  }\n\n  /**\n   * Get the custom point resolution function for this projection (if set).\n   * @return {function(number, import(\"../coordinate.js\").Coordinate):number|undefined} The custom point\n   * resolution function (if set).\n   */\n  getPointResolutionFunc() {\n    return this.getPointResolutionFunc_;\n  }\n}\n\nexport default Projection;\n","/**\n * @module ol/proj/epsg3857\n */\nimport Projection from './Projection.js';\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * @const\n * @type {number}\n */\nexport const HALF_SIZE = Math.PI * RADIUS;\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const WORLD_EXTENT = [-180, -85, 180, 85];\n\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\nexport const MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\nclass EPSG3857Projection extends Projection {\n  /**\n   * @param {string} code Code.\n   */\n  constructor(code) {\n    super({\n      code: code,\n      units: 'm',\n      extent: EXTENT,\n      global: true,\n      worldExtent: WORLD_EXTENT,\n      getPointResolution: function (resolution, point) {\n        return resolution / Math.cosh(point[1] / RADIUS);\n      },\n    });\n  }\n}\n\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n  new EPSG3857Projection('EPSG:3857'),\n  new EPSG3857Projection('EPSG:102100'),\n  new EPSG3857Projection('EPSG:102113'),\n  new EPSG3857Projection('EPSG:900913'),\n  new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),\n  new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),\n];\n\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function fromEPSG4326(input, output, dimension) {\n  const length = input.length;\n  dimension = dimension > 1 ? dimension : 2;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = (HALF_SIZE * input[i]) / 180;\n    let y = RADIUS * Math.log(Math.tan((Math.PI * (+input[i + 1] + 90)) / 360));\n    if (y > MAX_SAFE_Y) {\n      y = MAX_SAFE_Y;\n    } else if (y < -MAX_SAFE_Y) {\n      y = -MAX_SAFE_Y;\n    }\n    output[i + 1] = y;\n  }\n  return output;\n}\n\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function toEPSG4326(input, output, dimension) {\n  const length = input.length;\n  dimension = dimension > 1 ? dimension : 2;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = (180 * input[i]) / HALF_SIZE;\n    output[i + 1] =\n      (360 * Math.atan(Math.exp(input[i + 1] / RADIUS))) / Math.PI - 90;\n  }\n  return output;\n}\n","/**\n * @module ol/proj/epsg4326\n */\nimport Projection from './Projection.js';\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-180, -90, 180, 90];\n\n/**\n * @const\n * @type {number}\n */\nexport const METERS_PER_UNIT = (Math.PI * RADIUS) / 180;\n\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\nclass EPSG4326Projection extends Projection {\n  /**\n   * @param {string} code Code.\n   * @param {string} [axisOrientation] Axis orientation.\n   */\n  constructor(code, axisOrientation) {\n    super({\n      code: code,\n      units: 'degrees',\n      extent: EXTENT,\n      axisOrientation: axisOrientation,\n      global: true,\n      metersPerUnit: METERS_PER_UNIT,\n      worldExtent: EXTENT,\n    });\n  }\n}\n\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n  new EPSG4326Projection('CRS:84'),\n  new EPSG4326Projection('EPSG:4326', 'neu'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),\n  new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84'),\n  new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),\n  new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),\n];\n","/**\n * @module ol/proj/projections\n */\n\n/**\n * @type {Object<string, import(\"./Projection.js\").default>}\n */\nlet cache = {};\n\n/**\n * Clear the projections cache.\n */\nexport function clear() {\n  cache = {};\n}\n\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import(\"./Projection.js\").default} The projection (if cached).\n */\nexport function get(code) {\n  return (\n    cache[code] ||\n    cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, 'EPSG:$3')] ||\n    null\n  );\n}\n\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import(\"./Projection.js\").default} projection The projection to cache.\n */\nexport function add(code, projection) {\n  cache[code] = projection;\n}\n","/**\n * @module ol/proj/transforms\n */\nimport {isEmpty} from '../obj.js';\n\n/**\n * @private\n * @type {!Object<string, Object<string, import(\"../proj.js\").TransformFunction>>}\n */\nlet transforms = {};\n\n/**\n * Clear the transform cache.\n */\nexport function clear() {\n  transforms = {};\n}\n\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import(\"./Projection.js\").default} source Source.\n * @param {import(\"./Projection.js\").default} destination Destination.\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform.\n */\nexport function add(source, destination, transformFn) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  if (!(sourceCode in transforms)) {\n    transforms[sourceCode] = {};\n  }\n  transforms[sourceCode][destinationCode] = transformFn;\n}\n\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection.  This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import(\"./Projection.js\").default} source Source projection.\n * @param {import(\"./Projection.js\").default} destination Destination projection.\n * @return {import(\"../proj.js\").TransformFunction} transformFn The unregistered transform.\n */\nexport function remove(source, destination) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  const transform = transforms[sourceCode][destinationCode];\n  delete transforms[sourceCode][destinationCode];\n  if (isEmpty(transforms[sourceCode])) {\n    delete transforms[sourceCode];\n  }\n  return transform;\n}\n\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import(\"../proj.js\").TransformFunction|undefined} The transform function (if found).\n */\nexport function get(sourceCode, destinationCode) {\n  let transform;\n  if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n    transform = transforms[sourceCode][destinationCode];\n  }\n  return transform;\n}\n","/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection~Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4's registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get('EPSG:1234').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj.addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection~Projection} object for the new projection and add it with\n * {@link module:ol/proj.addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj.addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection~Projection} with\n * {@link module:ol/proj.addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\nimport Projection from './proj/Projection.js';\nimport {\n  PROJECTIONS as EPSG3857_PROJECTIONS,\n  fromEPSG4326,\n  toEPSG4326,\n} from './proj/epsg3857.js';\nimport {PROJECTIONS as EPSG4326_PROJECTIONS} from './proj/epsg4326.js';\nimport {METERS_PER_UNIT} from './proj/Units.js';\nimport {\n  add as addProj,\n  clear as clearProj,\n  get as getProj,\n} from './proj/projections.js';\nimport {\n  add as addTransformFunc,\n  clear as clearTransformFuncs,\n  get as getTransformFunc,\n} from './proj/transforms.js';\nimport {applyTransform, getWidth} from './extent.js';\nimport {clamp, modulo} from './math.js';\nimport {equals, getWorldsAway} from './coordinate.js';\nimport {getDistance} from './sphere.js';\n\n/**\n * A projection as {@link module:ol/proj/Projection~Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2).  The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\n\nexport {METERS_PER_UNIT};\n\nexport {Projection};\n\nlet showCoordinateWarning = true;\n\n/**\n * @param {boolean} [disable = true] Disable console info about `useGeographic()`\n */\nexport function disableCoordinateWarning(disable) {\n  const hide = disable === undefined ? true : disable;\n  showCoordinateWarning = !hide;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n *     values).\n */\nexport function cloneTransform(input, output, dimension) {\n  if (output !== undefined) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      output[i] = input[i];\n    }\n    output = output;\n  } else {\n    output = input.slice();\n  }\n  return output;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\nexport function identityTransform(input, output, dimension) {\n  if (output !== undefined && input !== output) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      output[i] = input[i];\n    }\n    input = output;\n  }\n  return input;\n}\n\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\nexport function addProjection(projection) {\n  addProj(projection.getCode(), projection);\n  addTransformFunc(projection, projection, cloneTransform);\n}\n\n/**\n * @param {Array<Projection>} projections Projections.\n */\nexport function addProjections(projections) {\n  projections.forEach(addProjection);\n}\n\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n *     a combination of authority and identifier such as \"EPSG:4326\", or an\n *     existing projection object, or undefined.\n * @return {Projection|null} Projection object, or null if not in list.\n * @api\n */\nexport function get(projectionLike) {\n  return typeof projectionLike === 'string'\n    ? getProj(/** @type {string} */ (projectionLike))\n    : /** @type {Projection} */ (projectionLike) || null;\n}\n\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the `point` pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import(\"./coordinate.js\").Coordinate} point Point to find adjusted resolution at.\n * @param {import(\"./proj/Units.js\").Units} [units] Units to get the point resolution in.\n * Default is the projection's units.\n * @return {number} Point resolution.\n * @api\n */\nexport function getPointResolution(projection, resolution, point, units) {\n  projection = get(projection);\n  let pointResolution;\n  const getter = projection.getPointResolutionFunc();\n  if (getter) {\n    pointResolution = getter(resolution, point);\n    if (units && units !== projection.getUnits()) {\n      const metersPerUnit = projection.getMetersPerUnit();\n      if (metersPerUnit) {\n        pointResolution =\n          (pointResolution * metersPerUnit) / METERS_PER_UNIT[units];\n      }\n    }\n  } else {\n    const projUnits = projection.getUnits();\n    if ((projUnits == 'degrees' && !units) || units == 'degrees') {\n      pointResolution = resolution;\n    } else {\n      // Estimate point resolution by transforming the center pixel to EPSG:4326,\n      // measuring its width and height on the normal sphere, and taking the\n      // average of the width and height.\n      const toEPSG4326 = getTransformFromProjections(\n        projection,\n        get('EPSG:4326')\n      );\n      if (toEPSG4326 === identityTransform && projUnits !== 'degrees') {\n        // no transform is available\n        pointResolution = resolution * projection.getMetersPerUnit();\n      } else {\n        let vertices = [\n          point[0] - resolution / 2,\n          point[1],\n          point[0] + resolution / 2,\n          point[1],\n          point[0],\n          point[1] - resolution / 2,\n          point[0],\n          point[1] + resolution / 2,\n        ];\n        vertices = toEPSG4326(vertices, vertices, 2);\n        const width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n        const height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n        pointResolution = (width + height) / 2;\n      }\n      const metersPerUnit = units\n        ? METERS_PER_UNIT[units]\n        : projection.getMetersPerUnit();\n      if (metersPerUnit !== undefined) {\n        pointResolution /= metersPerUnit;\n      }\n    }\n  }\n  return pointResolution;\n}\n\n/**\n * Registers transformation functions that don't alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\nexport function addEquivalentProjections(projections) {\n  addProjections(projections);\n  projections.forEach(function (source) {\n    projections.forEach(function (destination) {\n      if (source !== destination) {\n        addTransformFunc(source, destination, cloneTransform);\n      }\n    });\n  });\n}\n\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n *     meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n *     meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n *   projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n *   in projection2 to any projection in projection1..\n */\nexport function addEquivalentTransforms(\n  projections1,\n  projections2,\n  forwardTransform,\n  inverseTransform\n) {\n  projections1.forEach(function (projection1) {\n    projections2.forEach(function (projection2) {\n      addTransformFunc(projection1, projection2, forwardTransform);\n      addTransformFunc(projection2, projection1, inverseTransform);\n    });\n  });\n}\n\n/**\n * Clear all cached projections and transforms.\n */\nexport function clearAllProjections() {\n  clearProj();\n  clearTransformFuncs();\n}\n\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\nexport function createProjection(projection, defaultCode) {\n  if (!projection) {\n    return get(defaultCode);\n  } else if (typeof projection === 'string') {\n    return get(projection);\n  } else {\n    return /** @type {Projection} */ (projection);\n  }\n}\n\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} coordTransform Coordinate\n *     transform.\n * @return {TransformFunction} Transform function.\n */\nexport function createTransformFromCoordinateTransform(coordTransform) {\n  return (\n    /**\n     * @param {Array<number>} input Input.\n     * @param {Array<number>} [output] Output.\n     * @param {number} [dimension] Dimension.\n     * @return {Array<number>} Output.\n     */\n    function (input, output, dimension) {\n      const length = input.length;\n      dimension = dimension !== undefined ? dimension : 2;\n      output = output !== undefined ? output : new Array(length);\n      for (let i = 0; i < length; i += dimension) {\n        const point = coordTransform(input.slice(i, i + dimension));\n        const pointLength = point.length;\n        for (let j = 0, jj = dimension; j < jj; ++j) {\n          output[i + j] = j >= pointLength ? input[i + j] : point[j];\n        }\n      }\n      return output;\n    }\n  );\n}\n\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} forward The forward transform\n *     function (that is, from the source projection to the destination\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} inverse The inverse transform\n *     function (that is, from the destination projection to the source\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only\n *     transform less dimensions than the input coordinate, it is supposeed to return a coordinate\n *     with only the length it can transform. The other dimensions will be taken unchanged from the\n *     source.\n * @api\n */\nexport function addCoordinateTransforms(source, destination, forward, inverse) {\n  const sourceProj = get(source);\n  const destProj = get(destination);\n  addTransformFunc(\n    sourceProj,\n    destProj,\n    createTransformFromCoordinateTransform(forward)\n  );\n  addTransformFunc(\n    destProj,\n    sourceProj,\n    createTransformFromCoordinateTransform(inverse)\n  );\n}\n\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n *     an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike} [projection] Target projection. The\n *     default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate projected to the target projection.\n * @api\n */\nexport function fromLonLat(coordinate, projection) {\n  disableCoordinateWarning();\n  return transform(\n    coordinate,\n    'EPSG:4326',\n    projection !== undefined ? projection : 'EPSG:3857'\n  );\n}\n\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike} [projection] Projection of the coordinate.\n *     The default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate as longitude and latitude, i.e. an array\n *     with longitude as 1st and latitude as 2nd element.\n * @api\n */\nexport function toLonLat(coordinate, projection) {\n  const lonLat = transform(\n    coordinate,\n    projection !== undefined ? projection : 'EPSG:3857',\n    'EPSG:4326'\n  );\n  const lon = lonLat[0];\n  if (lon < -180 || lon > 180) {\n    lonLat[0] = modulo(lon + 180, 360) - 180;\n  }\n  return lonLat;\n}\n\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\nexport function equivalent(projection1, projection2) {\n  if (projection1 === projection2) {\n    return true;\n  }\n  const equalUnits = projection1.getUnits() === projection2.getUnits();\n  if (projection1.getCode() === projection2.getCode()) {\n    return equalUnits;\n  } else {\n    const transformFunc = getTransformFromProjections(projection1, projection2);\n    return transformFunc === cloneTransform && equalUnits;\n  }\n}\n\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n *     object.\n * @return {TransformFunction} Transform function.\n */\nexport function getTransformFromProjections(\n  sourceProjection,\n  destinationProjection\n) {\n  const sourceCode = sourceProjection.getCode();\n  const destinationCode = destinationProjection.getCode();\n  let transformFunc = getTransformFunc(sourceCode, destinationCode);\n  if (!transformFunc) {\n    transformFunc = identityTransform;\n  }\n  return transformFunc;\n}\n\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\nexport function getTransform(source, destination) {\n  const sourceProjection = get(source);\n  const destinationProjection = get(destination);\n  return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj.transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n * @api\n */\nexport function transform(coordinate, source, destination) {\n  const transformFunc = getTransform(source, destination);\n  return transformFunc(coordinate, undefined, coordinate.length);\n}\n\n/**\n * Transforms an extent from source projection to destination projection.  This\n * returns a new extent (and does not modify the original).\n *\n * @param {import(\"./extent.js\").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number} [stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import(\"./extent.js\").Extent} The transformed extent.\n * @api\n */\nexport function transformExtent(extent, source, destination, stops) {\n  const transformFunc = getTransform(source, destination);\n  return applyTransform(extent, transformFunc, undefined, stops);\n}\n\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import(\"./coordinate.js\").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import(\"./coordinate.js\").Coordinate} Point.\n */\nexport function transformWithProjections(\n  point,\n  sourceProjection,\n  destinationProjection\n) {\n  const transformFunc = getTransformFromProjections(\n    sourceProjection,\n    destinationProjection\n  );\n  return transformFunc(point);\n}\n\n/**\n * @type {Projection|null}\n */\nlet userProjection = null;\n\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * This includes all API methods except for those interacting with tile grids.\n * @param {ProjectionLike} projection The user projection.\n * @api\n */\nexport function setUserProjection(projection) {\n  userProjection = get(projection);\n}\n\n/**\n * Clear the user projection if set.\n * @api\n */\nexport function clearUserProjection() {\n  userProjection = null;\n}\n\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API.  Support for user\n * projections is not yet complete and should be considered experimental.\n * @return {Projection|null} The user projection (or null if not set).\n * @api\n */\nexport function getUserProjection() {\n  return userProjection;\n}\n\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods.  This includes all API\n * methods except for those interacting with tile grids.\n * @api\n */\nexport function useGeographic() {\n  setUserProjection('EPSG:4326');\n}\n\n/**\n * Return a coordinate transformed into the user projection.  If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @return {Array<number>} The input coordinate in the user projection.\n */\nexport function toUserCoordinate(coordinate, sourceProjection) {\n  if (!userProjection) {\n    return coordinate;\n  }\n  return transform(coordinate, sourceProjection, userProjection);\n}\n\n/**\n * Return a coordinate transformed from the user projection.  If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {Array<number>} The input coordinate transformed.\n */\nexport function fromUserCoordinate(coordinate, destProjection) {\n  if (!userProjection) {\n    if (\n      showCoordinateWarning &&\n      !equals(coordinate, [0, 0]) &&\n      coordinate[0] >= -180 &&\n      coordinate[0] <= 180 &&\n      coordinate[1] >= -90 &&\n      coordinate[1] <= 90\n    ) {\n      showCoordinateWarning = false;\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.'\n      );\n    }\n    return coordinate;\n  }\n  return transform(coordinate, userProjection, destProjection);\n}\n\n/**\n * Return an extent transformed into the user projection.  If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @return {import(\"./extent.js\").Extent} The input extent in the user projection.\n */\nexport function toUserExtent(extent, sourceProjection) {\n  if (!userProjection) {\n    return extent;\n  }\n  return transformExtent(extent, sourceProjection, userProjection);\n}\n\n/**\n * Return an extent transformed from the user projection.  If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {import(\"./extent.js\").Extent} The input extent transformed.\n */\nexport function fromUserExtent(extent, destProjection) {\n  if (!userProjection) {\n    return extent;\n  }\n  return transformExtent(extent, userProjection, destProjection);\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in input projection units per pixel.\n * @param {ProjectionLike} sourceProjection The input projection.\n * @return {number} Resolution in user projection units per pixel.\n */\nexport function toUserResolution(resolution, sourceProjection) {\n  if (!userProjection) {\n    return resolution;\n  }\n  const sourceUnits = get(sourceProjection).getUnits();\n  const userUnits = userProjection.getUnits();\n  return sourceUnits && userUnits\n    ? (resolution * METERS_PER_UNIT[sourceUnits]) / METERS_PER_UNIT[userUnits]\n    : resolution;\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in user projection units per pixel.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {number} Resolution in destination projection units per pixel.\n */\nexport function fromUserResolution(resolution, destProjection) {\n  if (!userProjection) {\n    return resolution;\n  }\n  const sourceUnits = get(destProjection).getUnits();\n  const userUnits = userProjection.getUnits();\n  return sourceUnits && userUnits\n    ? (resolution * METERS_PER_UNIT[userUnits]) / METERS_PER_UNIT[sourceUnits]\n    : resolution;\n}\n\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * \"Safe\" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent's range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} transform Transform function (source to destiation).\n * @return {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} Safe transform function (source to destiation).\n */\nexport function createSafeCoordinateTransform(sourceProj, destProj, transform) {\n  return function (coord) {\n    let transformed, worldsAway;\n    if (sourceProj.canWrapX()) {\n      const sourceExtent = sourceProj.getExtent();\n      const sourceExtentWidth = getWidth(sourceExtent);\n      coord = coord.slice(0);\n      worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n      if (worldsAway) {\n        // Move x to the real world\n        coord[0] = coord[0] - worldsAway * sourceExtentWidth;\n      }\n      coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);\n      coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);\n      transformed = transform(coord);\n    } else {\n      transformed = transform(coord);\n    }\n    if (worldsAway && destProj.canWrapX()) {\n      // Move transformed coordinate back to the offset world\n      transformed[0] += worldsAway * getWidth(destProj.getExtent());\n    }\n    return transformed;\n  };\n}\n\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857.  This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\nexport function addCommon() {\n  // Add transformations that don't alter coordinates to convert within set of\n  // projections with equal meaning.\n  addEquivalentProjections(EPSG3857_PROJECTIONS);\n  addEquivalentProjections(EPSG4326_PROJECTIONS);\n  // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n  // coordinates and back.\n  addEquivalentTransforms(\n    EPSG4326_PROJECTIONS,\n    EPSG3857_PROJECTIONS,\n    fromEPSG4326,\n    toEPSG4326\n  );\n}\n\naddCommon();\n","import {\n\tTerraDrawChanges,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tTerraDrawCallbacks,\n} from \"../common\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../store/store\";\nimport CircleGeom from \"ol/geom/Circle\";\nimport Feature, { FeatureLike } from \"ol/Feature\";\nimport GeoJSON from \"ol/format/GeoJSON\";\nimport Map from \"ol/Map\";\nimport Circle from \"ol/style/Circle\";\nimport Fill from \"ol/style/Fill\";\nimport Stroke from \"ol/style/Stroke\";\nimport Style from \"ol/style/Style\";\nimport VectorSource from \"ol/source/Vector\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport { fromLonLat, toLonLat } from \"ol/proj\";\nimport Geometry from \"ol/geom/Geometry\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\n\ntype InjectableOL = {\n\tCircle: typeof CircleGeom;\n\tFeature: typeof Feature;\n\tGeoJSON: typeof GeoJSON;\n\tStyle: typeof Style;\n\tCircleStyle: typeof Circle;\n\tVectorLayer: typeof VectorLayer;\n\tVectorSource: typeof VectorSource;\n\tStroke: typeof Stroke;\n\ttoLonLat: typeof toLonLat;\n};\n\nexport class TerraDrawOpenLayersAdapter extends TerraDrawBaseAdapter {\n\tconstructor(\n\t\tconfig: {\n\t\t\tmap: Map;\n\t\t\tlib: InjectableOL;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._map = config.map;\n\t\tthis._lib = config.lib;\n\n\t\tthis._geoJSONReader = new this._lib.GeoJSON();\n\n\t\tthis._container = this._map.getViewport();\n\n\t\t// TODO: Is this the best way to recieve keyboard events\n\t\tthis._container.setAttribute(\"tabindex\", \"0\");\n\n\t\tconst vectorSource = new this._lib.VectorSource({\n\t\t\tfeatures: [],\n\t\t});\n\n\t\tthis._vectorSource = vectorSource;\n\n\t\tconst vectorLayer = new this._lib.VectorLayer({\n\t\t\tsource: vectorSource,\n\t\t\tstyle: (feature) => this.getStyles(feature, this.stylingFunction()),\n\t\t});\n\n\t\tthis._map.addLayer(vectorLayer);\n\t}\n\n\tprivate stylingFunction = () => ({});\n\n\tprivate _lib: InjectableOL;\n\tprivate _map: Map;\n\tprivate _container: HTMLElement;\n\tprivate _projection = \"EPSG:3857\" as const;\n\tprivate _vectorSource: undefined | VectorSource<Geometry>;\n\tprivate _geoJSONReader: undefined | GeoJSON;\n\n\t/**\n\t * Converts a hexideciaml color to RGB\n\t * @param hex a string of the hexidecimal string\n\t * @returns an object to red green and blue (RGB) color\n\t */\n\tprivate hexToRGB(hex: string): { r: number; g: number; b: number } {\n\t\treturn {\n\t\t\tr: parseInt(hex.slice(1, 3), 16),\n\t\t\tg: parseInt(hex.slice(3, 5), 16),\n\t\t\tb: parseInt(hex.slice(5, 7), 16),\n\t\t};\n\t}\n\n\t/**\n\t * Converts a hexideciaml color to RGB\n\t * @param feature\n\t * @param styling\n\t * @returns an object to red green and blue (RGB) color\n\t */\n\tprivate getStyles(feature: FeatureLike, styling: TerraDrawStylingFunction) {\n\t\tconst geometry = feature.getGeometry();\n\t\tif (!geometry) {\n\t\t\treturn;\n\t\t}\n\t\tconst key = geometry.getType() as \"Point\" | \"LineString\" | \"Polygon\";\n\n\t\treturn {\n\t\t\tPoint: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"Point\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\treturn new this._lib.Style({\n\t\t\t\t\timage: new Circle({\n\t\t\t\t\t\tradius: style.pointWidth,\n\t\t\t\t\t\tfill: new Fill({\n\t\t\t\t\t\t\tcolor: style.pointColor,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tstroke: new Stroke({\n\t\t\t\t\t\t\tcolor: style.pointOutlineColor,\n\t\t\t\t\t\t\twidth: style.pointOutlineWidth,\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t\tLineString: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"LineString\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\treturn new this._lib.Style({\n\t\t\t\t\tstroke: new this._lib.Stroke({\n\t\t\t\t\t\tcolor: style.lineStringColor,\n\t\t\t\t\t\twidth: style.lineStringWidth,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t\tPolygon: (feature: FeatureLike) => {\n\t\t\t\tconst properties = feature.getProperties();\n\t\t\t\tconst style = styling[properties.mode]({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: { type: \"LineString\", coordinates: [] },\n\t\t\t\t\tproperties,\n\t\t\t\t});\n\t\t\t\tconst { r, g, b } = this.hexToRGB(style.polygonFillColor);\n\n\t\t\t\treturn new Style({\n\t\t\t\t\tstroke: new Stroke({\n\t\t\t\t\t\tcolor: style.polygonOutlineColor,\n\t\t\t\t\t\twidth: style.polygonOutlineWidth,\n\t\t\t\t\t}),\n\t\t\t\t\tfill: new Fill({\n\t\t\t\t\t\tcolor: `rgba(${r},${g},${b},${style.polygonFillOpacity})`,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t},\n\t\t}[key](feature);\n\t}\n\n\t/**\n\t * Clears the layers created by the adapter\n\t * @returns void\n\t * */\n\tprivate clearLayers() {\n\t\tif (this._vectorSource) {\n\t\t\tthis._vectorSource.clear();\n\t\t}\n\t}\n\n\tprivate addFeature(feature: GeoJSONStoreFeatures) {\n\t\tif (this._vectorSource && this._geoJSONReader) {\n\t\t\tconst olFeature = this._geoJSONReader.readFeature(feature, {\n\t\t\t\tfeatureProjection: this._projection,\n\t\t\t});\n\t\t\tthis._vectorSource.addFeature(olFeature);\n\t\t} else {\n\t\t\tthrow new Error(\"Vector Source not initalised\");\n\t\t}\n\t}\n\n\tprivate removeFeature(id: FeatureId) {\n\t\tif (this._vectorSource) {\n\t\t\tconst deleted = this._vectorSource.getFeatureById(id);\n\t\t\tif (!deleted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._vectorSource.removeFeature(deleted);\n\t\t} else {\n\t\t\tthrow new Error(\"Vector Source not initalised\");\n\t\t}\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\t\ttry {\n\t\t\treturn this.unproject(x, y);\n\t\t} catch (_) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the OpenLayers element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\tconst canvases = this._container.querySelectorAll(\"canvas\");\n\n\t\tif (canvases.length > 1) {\n\t\t\tthrow Error(\n\t\t\t\t\"Terra Draw currently only supports 1 canvas with OpenLayers\",\n\t\t\t);\n\t\t}\n\n\t\treturn canvases[0];\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis._map.getInteractions().forEach((interaction) => {\n\t\t\tif (interaction.constructor.name === \"DragPan\") {\n\t\t\t\tinteraction.setActive(enabled);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst [x, y] = this._map.getPixelFromCoordinate(fromLonLat([lng, lat]));\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst [lng, lat] = toLonLat(this._map.getCoordinateFromPixel([x, y]));\n\t\treturn { lng, lat };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis._map.getInteractions().forEach(function (interaction) {\n\t\t\tif (interaction.constructor.name === \"DoubleClickZoom\") {\n\t\t\t\tinteraction.setActive(enabled);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tthis.stylingFunction = () => styling;\n\n\t\tconst source = this._vectorSource;\n\n\t\tif (!source) {\n\t\t\tthrow new Error(\"Vector Layer source has disappeared\");\n\t\t}\n\n\t\tchanges.deletedIds.forEach((id) => {\n\t\t\tthis.removeFeature(id);\n\t\t});\n\n\t\tchanges.updated.forEach((feature) => {\n\t\t\tthis.removeFeature(feature.id as string);\n\t\t\tthis.addFeature(feature);\n\t\t});\n\n\t\tchanges.created.forEach((feature) => {\n\t\t\tthis.addFeature(feature);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tif (this._currentModeCallbacks) {\n\t\t\t// Clean up state first\n\t\t\tthis._currentModeCallbacks.onClear();\n\n\t\t\t// Then clean up rendering\n\t\t\tthis.clearLayers();\n\t\t}\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\tpublic unregister(): void {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.unregister();\n\t}\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport {\n\tHexColor,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawModeRegisterConfig,\n\tTerraDrawModeState,\n\tTerraDrawMouseEvent,\n} from \"../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tStoreChangeHandler,\n} from \"../store/store\";\nimport { isValidStoreFeature } from \"../store/store-feature-validation\";\n\nexport type CustomStyling = Record<\n\tstring,\n\t| string\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => HexColor)\n\t| ((feature: GeoJSONStoreFeatures) => number)\n>;\n\nexport enum ModeTypes {\n\tDrawing = \"drawing\",\n\tSelect = \"select\",\n\tStatic = \"static\",\n\tRender = \"render\",\n}\n\nexport type BaseModeOptions<T extends CustomStyling> = {\n\tstyles?: Partial<T>;\n\tpointerDistance?: number;\n};\n\nexport abstract class TerraDrawBaseDrawMode<T extends CustomStyling> {\n\tprotected _state: TerraDrawModeState;\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\tprotected _styles: Partial<T>;\n\n\tget styles(): Partial<T> {\n\t\treturn this._styles;\n\t}\n\tset styles(styling: Partial<T>) {\n\t\tif (typeof styling !== \"object\") {\n\t\t\tthrow new Error(\"Styling must be an object\");\n\t\t}\n\t\tthis.onStyleChange([], \"styling\");\n\t\tthis._styles = styling;\n\t}\n\n\tprotected behaviors: TerraDrawModeBehavior[] = [];\n\tprotected pointerDistance: number;\n\tprotected coordinatePrecision!: number;\n\tprotected onStyleChange!: StoreChangeHandler;\n\tprotected store!: GeoJSONStore;\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\tconstructor(options?: BaseModeOptions<T>) {\n\t\tthis._state = \"unregistered\";\n\t\tthis._styles =\n\t\t\toptions && options.styles ? { ...options.styles } : ({} as Partial<T>);\n\t\tthis.pointerDistance = (options && options.pointerDistance) || 40;\n\t}\n\n\ttype = ModeTypes.Drawing;\n\tmode = \"base\";\n\n\tprotected setDrawing() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"drawing\";\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStarted() {\n\t\tif (\n\t\t\tthis._state === \"stopped\" ||\n\t\t\tthis._state === \"registered\" ||\n\t\t\tthis._state === \"drawing\" ||\n\t\t\tthis._state === \"selecting\"\n\t\t) {\n\t\t\tthis._state = \"started\";\n\t\t\tthis.setDoubleClickToZoom(false);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStopped() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"stopped\";\n\t\t\tthis.setDoubleClickToZoom(true);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be started to be stopped\");\n\t\t}\n\t}\n\n\tregister(config: TerraDrawModeRegisterConfig) {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthis._state = \"registered\";\n\t\t\tthis.store = config.store;\n\t\t\tthis.store.registerOnChange(config.onChange);\n\t\t\tthis.setDoubleClickToZoom = config.setDoubleClickToZoom;\n\t\t\tthis.project = config.project;\n\t\t\tthis.unproject = config.unproject;\n\t\t\tthis.onSelect = config.onSelect;\n\t\t\tthis.onDeselect = config.onDeselect;\n\t\t\tthis.setCursor = config.setCursor;\n\t\t\tthis.onStyleChange = config.onChange;\n\t\t\tthis.onFinish = config.onFinish;\n\t\t\tthis.coordinatePrecision = config.coordinatePrecision;\n\n\t\t\tthis.registerBehaviors({\n\t\t\t\tmode: config.mode,\n\t\t\t\tstore: this.store,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tpointerDistance: this.pointerDistance,\n\t\t\t\tcoordinatePrecision: config.coordinatePrecision,\n\t\t\t});\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): feature is GeoJSONStoreFeatures {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthrow new Error(\"Mode must be registered\");\n\t\t}\n\n\t\treturn isValidStoreFeature(feature, this.store.idStrategy.isValidId);\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) {}\n\tonDeselect(deselectedId: FeatureId) {}\n\tonSelect(selectedId: FeatureId) {}\n\tonKeyDown(event: TerraDrawKeyboardEvent) {}\n\tonKeyUp(event: TerraDrawKeyboardEvent) {}\n\tonMouseMove(event: TerraDrawMouseEvent) {}\n\tonClick(event: TerraDrawMouseEvent) {}\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\n\tprotected getHexColorStylingValue(\n\t\tvalue: HexColor | ((feature: GeoJSONStoreFeatures) => HexColor) | undefined,\n\t\tdefaultValue: HexColor,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): HexColor {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprotected getNumericStylingValue(\n\t\tvalue: number | ((feature: GeoJSONStoreFeatures) => number) | undefined,\n\t\tdefaultValue: number,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): number {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprivate getStylingValue<T extends string | number>(\n\t\tvalue: T | ((feature: GeoJSONStoreFeatures) => T) | undefined,\n\t\tdefaultValue: T,\n\t\tfeature: GeoJSONStoreFeatures,\n\t) {\n\t\tconst visible4Index = [0, 16, 32, 48];\n\t\tif (\n\t\t\tfeature.properties.type == \"circle\" &&\n\t\t\t!visible4Index.includes(feature.properties.index as number)\n\t\t) {\n\t\t\treturn 0 as T;\n\t\t}\n\n\t\tif (value === undefined) {\n\t\t\treturn defaultValue;\n\t\t} else if (typeof value === \"function\") {\n\t\t\treturn value(feature);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t}\n}\n\nexport abstract class TerraDrawBaseSelectMode<\n\tT extends CustomStyling,\n> extends TerraDrawBaseDrawMode<T> {\n\tpublic type = ModeTypes.Select;\n\n\tpublic abstract selectFeature(featureId: FeatureId): void;\n\tpublic abstract deselectFeature(featureId: FeatureId): void;\n}\n","import {\n\tSetCursor,\n\tTerraDrawCallbacks,\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n} from \"../common\";\nimport { BaseAdapterConfig, TerraDrawBaseAdapter } from \"./common/base.adapter\";\nimport MapView from \"@arcgis/core/views/MapView\";\nimport Point from \"@arcgis/core/geometry/Point\";\nimport Polyline from \"@arcgis/core/geometry/Polyline\";\nimport Polygon from \"@arcgis/core/geometry/Polygon\";\nimport GraphicsLayer from \"@arcgis/core/layers/GraphicsLayer\";\nimport Graphic from \"@arcgis/core/Graphic\";\nimport SimpleMarkerSymbol from \"@arcgis/core/symbols/SimpleMarkerSymbol\";\nimport { GeoJSONStoreFeatures } from \"../store/store\";\nimport Symbol from \"@arcgis/core/symbols/Symbol\";\nimport SimpleLineSymbol from \"@arcgis/core/symbols/SimpleLineSymbol\";\nimport SimpleFillSymbol from \"@arcgis/core/symbols/SimpleFillSymbol\";\nimport Color from \"@arcgis/core/Color\";\nimport Geometry from \"@arcgis/core/geometry/Geometry\";\n\ntype InjectableArcGISMapsSDK = {\n\tGraphicsLayer: typeof GraphicsLayer;\n\tPoint: typeof Point;\n\tPolyline: typeof Polyline;\n\tPolygon: typeof Polygon;\n\tSimpleLineSymbol: typeof SimpleLineSymbol;\n\tSimpleMarkerSymbol: typeof SimpleMarkerSymbol;\n\tSimpleFillSymbol: typeof SimpleFillSymbol;\n\tGraphic: typeof Graphic;\n\tColor: typeof Color;\n};\n\nexport class TerraDrawArcGISMapsSDKAdapter extends TerraDrawBaseAdapter {\n\tprivate readonly _lib: InjectableArcGISMapsSDK;\n\tprivate readonly _mapView: MapView;\n\tprivate readonly _container: HTMLElement;\n\tprivate readonly _featureIdAttributeName = \"__tdId\";\n\tprivate readonly _featureLayerName = \"__terraDrawFeatures\";\n\tprivate readonly _featureLayer: GraphicsLayer;\n\n\tprivate _dragEnabled = true;\n\tprivate _zoomEnabled = true;\n\tprivate _dragHandler: undefined | IHandle;\n\tprivate _doubleClickHandler: undefined | IHandle;\n\n\tconstructor(\n\t\tconfig: {\n\t\t\tmap: MapView;\n\t\t\tlib: InjectableArcGISMapsSDK;\n\t\t} & BaseAdapterConfig,\n\t) {\n\t\tsuper(config);\n\n\t\tthis._mapView = config.map;\n\t\tthis._lib = config.lib;\n\t\tthis._container = this._mapView.container;\n\t\tthis._featureLayer = new this._lib.GraphicsLayer({\n\t\t\tid: this._featureLayerName,\n\t\t});\n\n\t\tthis._mapView.map.add(this._featureLayer);\n\t}\n\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tsuper.register(callbacks);\n\n\t\tthis._dragHandler = this._mapView.on(\"drag\", (event) => {\n\t\t\tif (!this._dragEnabled) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t});\n\t\tthis._doubleClickHandler = this._mapView.on(\"double-click\", (event) => {\n\t\t\tif (!this._zoomEnabled) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t});\n\n\t\tthis._currentModeCallbacks &&\n\t\t\tthis._currentModeCallbacks.onReady &&\n\t\t\tthis._currentModeCallbacks.onReady();\n\t}\n\n\tpublic unregister() {\n\t\tsuper.unregister();\n\n\t\tif (this._dragHandler) {\n\t\t\tthis._dragHandler.remove();\n\t\t}\n\n\t\tif (this._doubleClickHandler) {\n\t\t\tthis._doubleClickHandler.remove();\n\t\t}\n\t}\n\n\tpublic getCoordinatePrecision(): number {\n\t\t// TODO: It seems this shouldn't be necessary as extends BaseAdapter which as this method\n\t\treturn super.getCoordinatePrecision();\n\t}\n\n\t/**\n\t * Returns the longitude and latitude coordinates from a given PointerEvent on the map.\n\t * @param event The PointerEvent or MouseEvent  containing the screen coordinates of the pointer.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude, or null if the conversion is not possible.\n\t */\n\tpublic getLngLatFromEvent(event: PointerEvent | MouseEvent) {\n\t\tconst { containerX: x, containerY: y } =\n\t\t\tthis.getMapElementXYPosition(event);\n\t\treturn this.unproject(x, y);\n\t}\n\n\t/**\n\t * Retrieves the HTML element of the ArcGIS element that handles interaction events\n\t * @returns The HTMLElement representing the map container.\n\t */\n\tpublic getMapEventElement() {\n\t\treturn this._container.querySelector(\".esri-view-surface\") as HTMLElement;\n\t}\n\n\t/**\n\t * Enables or disables the draggable functionality of the map.\n\t * @param enabled Set to true to enable map dragging, or false to disable it.\n\t */\n\tpublic setDraggability(enabled: boolean) {\n\t\tthis._dragEnabled = enabled;\n\t}\n\n\t/**\n\t * Converts longitude and latitude coordinates to pixel coordinates in the map container.\n\t * @param lng The longitude coordinate to project.\n\t * @param lat The latitude coordinate to project.\n\t * @returns An object with 'x' and 'y' properties representing the pixel coordinates within the map container.\n\t */\n\tpublic project(lng: number, lat: number) {\n\t\tconst point = new this._lib.Point({ longitude: lng, latitude: lat });\n\t\tconst { x, y } = this._mapView.toScreen(point);\n\t\treturn { x, y };\n\t}\n\n\t/**\n\t * Converts pixel coordinates in the map container to longitude and latitude coordinates.\n\t * @param x The x-coordinate in the map container to unproject.\n\t * @param y The y-coordinate in the map container to unproject.\n\t * @returns An object with 'lng' and 'lat' properties representing the longitude and latitude coordinates.\n\t */\n\tpublic unproject(x: number, y: number) {\n\t\tconst { latitude, longitude } = this._mapView.toMap({ x, y });\n\t\treturn { lng: longitude, lat: latitude };\n\t}\n\n\t/**\n\t * Sets the cursor style for the map container.\n\t * @param cursor The CSS cursor style to apply, or 'unset' to remove any previously applied cursor style.\n\t */\n\tpublic setCursor(cursor: Parameters<SetCursor>[0]) {\n\t\tif (cursor === \"unset\") {\n\t\t\tthis.getMapEventElement().style.removeProperty(\"cursor\");\n\t\t} else {\n\t\t\tthis.getMapEventElement().style.cursor = cursor;\n\t\t}\n\t}\n\n\t/**\n\t * Enables or disables the double-click to zoom functionality on the map.\n\t * @param enabled Set to true to enable double-click to zoom, or false to disable it.\n\t */\n\tpublic setDoubleClickToZoom(enabled: boolean) {\n\t\tthis._zoomEnabled = enabled;\n\t}\n\n\t/**\n\t * Renders GeoJSON features on the map using the provided styling configuration.\n\t * @param changes An object containing arrays of created, updated, and unchanged features to render.\n\t * @param styling An object mapping draw modes to feature styling functions\n\t */\n\tpublic render(changes: TerraDrawChanges, styling: TerraDrawStylingFunction) {\n\t\tchanges.created.forEach((createdFeature) => {\n\t\t\tthis.addFeature(createdFeature, styling);\n\t\t});\n\n\t\tchanges.updated.forEach((updatedFeature) => {\n\t\t\tthis.removeFeatureById(updatedFeature.id);\n\t\t\tthis.addFeature(updatedFeature, styling);\n\t\t});\n\n\t\tchanges.deletedIds.forEach((deletedId) => {\n\t\t\tthis.removeFeatureById(deletedId);\n\t\t});\n\t}\n\n\t/**\n\t * Clears the map and store of all rendered data layers\n\t * @returns void\n\t * */\n\tpublic clear() {\n\t\tthis._featureLayer.graphics.removeAll();\n\t}\n\n\tprivate removeFeatureById(id: string | number | undefined) {\n\t\tconst feature = this._featureLayer.graphics.find(\n\t\t\t(g) => g.attributes[this._featureIdAttributeName] === id,\n\t\t);\n\t\tthis._featureLayer.remove(feature);\n\t}\n\n\tprivate addFeature(\n\t\tfeature: GeoJSONStoreFeatures,\n\t\tstyling: TerraDrawStylingFunction,\n\t) {\n\t\tconst { coordinates, type } = feature.geometry;\n\t\tconst style = styling[feature.properties.mode as string](feature);\n\n\t\tlet symbol: Symbol | undefined = undefined; // eslint-disable-line @typescript-eslint/ban-types\n\t\tlet geometry: Geometry | undefined = undefined;\n\n\t\tswitch (type) {\n\t\t\tcase \"Point\":\n\t\t\t\tgeometry = new this._lib.Point({\n\t\t\t\t\tlatitude: coordinates[1],\n\t\t\t\t\tlongitude: coordinates[0],\n\t\t\t\t});\n\t\t\t\tsymbol = new this._lib.SimpleMarkerSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(style.pointColor),\n\t\t\t\t\tsize: style.pointWidth * 2 + \"px\",\n\t\t\t\t\toutline: {\n\t\t\t\t\t\tcolor: this.getColorFromHex(style.pointOutlineColor),\n\t\t\t\t\t\twidth: style.pointOutlineWidth + \"px\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"LineString\":\n\t\t\t\tgeometry = new this._lib.Polyline({ paths: [coordinates] });\n\t\t\t\tsymbol = new this._lib.SimpleLineSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(style.lineStringColor),\n\t\t\t\t\twidth: style.lineStringWidth + \"px\",\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"Polygon\":\n\t\t\t\tgeometry = new this._lib.Polygon({ rings: coordinates });\n\t\t\t\tsymbol = new this._lib.SimpleFillSymbol({\n\t\t\t\t\tcolor: this.getColorFromHex(\n\t\t\t\t\t\tstyle.polygonFillColor,\n\t\t\t\t\t\tstyle.polygonFillOpacity,\n\t\t\t\t\t),\n\t\t\t\t\toutline: {\n\t\t\t\t\t\tcolor: this.getColorFromHex(style.polygonOutlineColor),\n\t\t\t\t\t\twidth: style.polygonOutlineWidth + \"px\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst graphic = new this._lib.Graphic({\n\t\t\tgeometry,\n\t\t\tsymbol,\n\t\t\tattributes: { [this._featureIdAttributeName]: feature.id },\n\t\t});\n\n\t\t// ensure we add points at the topmost position by adding other geometries at index 0\n\t\tif (type === \"Point\") {\n\t\t\tthis._featureLayer.graphics.add(graphic);\n\t\t} else {\n\t\t\tthis._featureLayer.graphics.add(graphic, 0);\n\t\t}\n\t}\n\n\tprivate getColorFromHex(hexColor: string, opacity?: number): Color {\n\t\tconst color = this._lib.Color.fromHex(hexColor);\n\t\tif (opacity) {\n\t\t\tcolor.a = opacity;\n\t\t}\n\t\treturn color;\n\t}\n}\n","import {\n\tStoreChangeHandler,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tFeatureId,\n} from \"./store/store\";\n\nexport type HexColor = `#${string}`;\n\nexport type HexColorStyling =\n\t| HexColor\n\t| ((feature: GeoJSONStoreFeatures) => HexColor);\n\nexport type NumericStyling =\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => number);\n\nexport interface TerraDrawAdapterStyling {\n\tpointColor: HexColor;\n\tpointWidth: number;\n\tpointOutlineColor: HexColor;\n\tpointOutlineWidth: number;\n\tpolygonFillColor: HexColor;\n\tpolygonFillOpacity: number;\n\tpolygonOutlineColor: HexColor;\n\tpolygonOutlineWidth: number;\n\tlineStringWidth: number;\n\tlineStringColor: HexColor;\n\tzIndex: number;\n}\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}\n\nexport interface TerraDrawKeyboardEvent {\n\tkey: string;\n\theldKeys: string[];\n\tpreventDefault: () => void;\n}\n\nexport type Required<T> = {\n\t[P in keyof T]-?: T[P];\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) => { x: number; y: number };\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 interface TerraDrawModeRegisterConfig {\n\tmode: string;\n\tstore: GeoJSONStore;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tsetCursor: SetCursor;\n\tonChange: StoreChangeHandler;\n\tonSelect: (selectedId: string) => void;\n\tonDeselect: (deselectedId: string) => void;\n\tonFinish: (finishedId: string) => void;\n\tproject: Project;\n\tunproject: Unproject;\n\tcoordinatePrecision: number;\n}\n\ntype ValidationContext = Pick<\n\tTerraDrawModeRegisterConfig,\n\t\"project\" | \"unproject\" | \"coordinatePrecision\"\n>;\nexport type Validation = (\n\tfeature: GeoJSONStoreFeatures,\n\tcontext: ValidationContext,\n) => boolean;\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 interface TerraDrawAdapter {\n\tproject: Project;\n\tunproject: Unproject;\n\tsetCursor: SetCursor;\n\tgetLngLatFromEvent: GetLngLatFromEvent;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tgetMapEventElement: () => HTMLElement;\n\tregister(callbacks: TerraDrawCallbacks): void;\n\tunregister(): void;\n\trender(changes: TerraDrawChanges, styling: TerraDrawStylingFunction): void;\n\tclear(): void;\n\tgetCoordinatePrecision(): number;\n}\n\nexport const SELECT_PROPERTIES = {\n\tSELECTED: \"selected\",\n\tMID_POINT: \"midPoint\",\n\tSELECTION_POINT: \"selectionPoint\",\n} as const;\n\nexport const POLYGON_PROPERTIES = {\n\tCLOSING_POINT: \"closingPoint\",\n};\n","import { FeatureId, GeoJSONStoreFeatures, 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\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\tthrow new Error(StoreValidationErrors.InvalidTrackedProperties);\n\t}\n\n\treturn true;\n}\n\nexport function isValidStoreFeature(\n\tfeature: unknown,\n\tisValidId: IdStrategy<FeatureId>[\"isValidId\"],\n): feature is GeoJSONStoreFeatures {\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\tthrow new Error(StoreValidationErrors.InvalidModeProperty);\n\t}\n\n\tif (error) {\n\t\tthrow new Error(error);\n\t}\n\n\treturn true;\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","import { Feature, Polygon, Position } from \"geojson\";\nimport {\n\tdegreesToRadians,\n\tlengthToRadians,\n\tradiansToDegrees,\n} from \"../helpers\";\nimport { limitPrecision } from \"../limit-decimal-precision\";\n\n// Based on Turf.js Circle module\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","// 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","export 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 coordinateIsValid(\n\tcoordinate: unknown[],\n\tcoordinatePrecision: number,\n) {\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\tgetDecimalPlaces(coordinate[0]) <= coordinatePrecision &&\n\t\tgetDecimalPlaces(coordinate[1]) <= coordinatePrecision\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 \"./self-intersects\";\nimport { coordinateIsValid } from \"./is-valid-coordinate\";\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\nexport function isValidPolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"Polygon\" &&\n\t\tfeature.geometry.coordinates.length === 1 && // No hole support\n\t\tfeature.geometry.coordinates[0].length >= 4 &&\n\t\tfeature.geometry.coordinates[0].every((coordinate) =>\n\t\t\tcoordinateIsValid(coordinate, coordinatePrecision),\n\t\t) &&\n\t\tcoordinatesMatch(\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}\n\nexport function isValidNonIntersectingPolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tisValidPolygonFeature(feature, coordinatePrecision) &&\n\t\t!selfIntersects(feature as Feature<Polygon>)\n\t);\n}\n","import { Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { circle } from \"../../geometry/shape/create-circle\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { isValidNonIntersectingPolygonFeature } from \"../../geometry/boolean/is-valid-polygon-feature\";\n\ntype TerraDrawCircleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype CirclePolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\ninterface TerraDrawCircleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawCircleModeKeyEvents | null;\n\tcursors?: Cursors;\n\tminimumRadiusKilometers?: number;\n}\n\nexport class TerraDrawCircleMode extends TerraDrawBaseDrawMode<CirclePolygonStyling> {\n\tmode = \"circle\";\n\tprivate center: Position | undefined;\n\tprivate clickCount = 0;\n\tprivate currentCircleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawCircleModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\tprivate minimumRadiusKilometers: number;\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.minimumRadiusKilometers - Minimum radius for the circle\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 */\n\tconstructor(options?: TerraDrawCircleModeOptions<CirclePolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.minimumRadiusKilometers = options?.minimumRadiusKilometers ?? 0.00001;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentCircleId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedId = this.currentCircleId;\n\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.clickCount = 0;\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\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId);\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 (this.clickCount === 0) {\n\t\t\tthis.center = [event.lng, event.lat];\n\t\t\tconst startingCircle = circle({\n\t\t\t\tcenter: this.center,\n\t\t\t\tradiusKilometers: this.minimumRadiusKilometers,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t});\n\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: startingCircle.geometry,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\tradiusKilometers: this.minimumRadiusKilometers,\n\t\t\t\t\t\tcenter: this.center,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentCircleId = createdId;\n\t\t\tthis.clickCount++;\n\t\t\tthis.setDrawing();\n\t\t} else {\n\t\t\tif (\n\t\t\t\tthis.clickCount === 1 &&\n\t\t\t\tthis.center &&\n\t\t\t\tthis.currentCircleId !== undefined\n\t\t\t) {\n\t\t\t\tthis.createCircle(event);\n\t\t\t}\n\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.createCircle(event);\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\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentCircleId !== undefined) {\n\t\t\t\tthis.store.delete([this.currentCircleId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.clickCount = 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 (\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.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\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tisValidNonIntersectingPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate createCircle(event: TerraDrawMouseEvent) {\n\t\tif (this.clickCount === 1 && this.center && this.currentCircleId) {\n\t\t\tconst distanceKm = haversineDistanceKilometers(this.center, [\n\t\t\t\tevent.lng,\n\t\t\t\tevent.lat,\n\t\t\t]);\n\n\t\t\tconst newRadius =\n\t\t\t\tdistanceKm > this.minimumRadiusKilometers\n\t\t\t\t\t? distanceKm\n\t\t\t\t\t: this.minimumRadiusKilometers;\n\n\t\t\tconst updatedCircle = circle({\n\t\t\t\tcenter: this.center,\n\t\t\t\tradiusKilometers: newRadius,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t});\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{ id: this.currentCircleId, geometry: updatedCircle.geometry },\n\t\t\t]);\n\t\t\tthis.store.updateProperty([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentCircleId,\n\t\t\t\t\tproperty: \"radiusKilometers\",\n\t\t\t\t\tvalue: newRadius,\n\t\t\t\t},\n\t\t\t]);\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\tpolygonFillOpacity: 0.3,\n\t\tpointColor: \"#3f97e0\",\n\t\tpointOutlineColor: \"#ffffff\",\n\t\tpointOutlineWidth: 0,\n\t\tpointWidth: 6,\n\t\tlineStringColor: \"#3f97e0\",\n\t\tlineStringWidth: 4,\n\t\tzIndex: 0,\n\t};\n};\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\n\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { pixelDistance } from \"../../geometry/measure/pixel-distance\";\nimport { isValidPolygonFeature } from \"../../geometry/boolean/is-valid-polygon-feature\";\n\ntype TerraDrawFreehandModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype FreehandPolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawFreehandModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tminDistance?: number;\n\tpreventPointsNearClose?: boolean;\n\tkeyEvents?: TerraDrawFreehandModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n\tmode = \"freehand\";\n\n\tprivate startingClick = false;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate minDistance: number;\n\tprivate keyEvents: TerraDrawFreehandModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\tprivate preventPointsNearClose: boolean;\n\n\tconstructor(options?: TerraDrawFreehandModeOptions<FreehandPolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.preventPointsNearClose =\n\t\t\t(options && options.preventPointsNearClose) || true;\n\n\t\tthis.minDistance = (options && options.minDistance) || 20;\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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\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 finishedId = this.currentId;\n\n\t\tthis.closingPointId && this.store.delete([this.closingPointId]);\n\t\tthis.startingClick = false;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = 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\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId);\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.startingClick === false) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentLineGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\tconst [previousLng, previousLat] =\n\t\t\tcurrentLineGeometry.coordinates[0][\n\t\t\t\tcurrentLineGeometry.coordinates[0].length - 2\n\t\t\t];\n\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\tconst distance = pixelDistance(\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] = currentLineGeometry.coordinates[0][0];\n\t\tconst { x: closingX, y: closingY } = this.project(closingLng, closingLat);\n\t\tconst closingDistance = pixelDistance(\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\n\t\t\t// We want to prohibit drawing new points at or around the closing\n\t\t\t// point as it can be non user friendly\n\t\t\tif (this.preventPointsNearClose) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t}\n\n\t\t// The cusor 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\tcurrentLineGeometry.coordinates[0].pop();\n\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...currentLineGeometry.coordinates[0],\n\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\tcurrentLineGeometry.coordinates[0][0],\n\t\t\t\t\t\t],\n\t\t\t\t\t],\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 (this.startingClick === false) {\n\t\t\tconst [createdId, closingPointId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: [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]);\n\n\t\t\tthis.currentId = createdId;\n\t\t\tthis.closingPointId = closingPointId;\n\t\t\tthis.startingClick = true;\n\t\t\tthis.setDrawing();\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.close();\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\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t\tif (this.closingPointId) {\n\t\t\t\tthis.store.delete([this.closingPointId]);\n\t\t\t}\n\t\t} catch (error) {}\n\t\tthis.closingPointId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.startingClick = false;\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 (\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.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\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.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\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tisValidPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { Feature, LineString, Position } from \"geojson\";\nimport { JSONObject } from \"../../store/store\";\nimport { limitPrecision } from \"../limit-decimal-precision\";\n\n// Based on - https://github.com/springmeyer/arc.js\n// MIT License - Copyright (c) 2019, Dane Springmeyer\n\nconst D2R = Math.PI / 180;\nconst R2D = 180 / Math.PI;\n\ninterface Coord {\n\treadonly lng: number;\n\treadonly lat: number;\n\treadonly x: number;\n\treadonly y: number;\n}\n\nclass ArcLineString {\n\tconstructor(coordinatePrecision: number) {\n\t\tthis.coordinatePrecision = coordinatePrecision;\n\t\tthis.coords = [];\n\t\tthis.length = 0;\n\t}\n\n\tprivate coordinatePrecision: number;\n\tpublic coords: [number, number][];\n\tpublic length: number;\n\n\tmoveTo(coord: [number, number]) {\n\t\tthis.length++;\n\t\tthis.coords.push([\n\t\t\tlimitPrecision(coord[0], this.coordinatePrecision),\n\t\t\tlimitPrecision(coord[1], this.coordinatePrecision),\n\t\t]);\n\t}\n}\n\nclass Arc<Properties extends JSONObject> {\n\tconstructor({ properties }: { properties: Properties }) {\n\t\tthis.properties = properties || {};\n\t\tthis.geometries = [];\n\t}\n\n\tpublic geometries: ArcLineString[];\n\tpublic properties: Properties;\n\n\ttoJSON(): Feature<LineString> | null {\n\t\tif (this.geometries.length === 1) {\n\t\t\tconst coords = this.geometries[0].coords;\n\n\t\t\t// TODO: Sometimes coords are NaN?\n\t\t\tif (\n\t\t\t\tcoords[0][0] &&\n\t\t\t\t!isNaN(coords[0][0]) &&\n\t\t\t\tcoords[0][1] &&\n\t\t\t\t!isNaN(coords[0][1])\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tgeometry: { type: \"LineString\", coordinates: coords },\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tproperties: this.properties,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// TODO: this.geometries.length can return 0 and also > 1. Do we need to handle this?\n\t\treturn null;\n\t}\n}\n\nclass GreatCircleLine<Properties extends JSONObject> {\n\tconstructor(start: Position, end: Position, properties?: Properties) {\n\t\tif (!start || start[0] === undefined || start[1] === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"GreatCircle constructor expects two args: start and end objects with x and y properties\",\n\t\t\t);\n\t\t}\n\t\tif (!end || end[0] === undefined || end[1] === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"GreatCircle constructor expects two args: start and end objects with x and y properties\",\n\t\t\t);\n\t\t}\n\t\tthis.start = {\n\t\t\tlng: start[0],\n\t\t\tlat: start[1],\n\t\t\tx: D2R * start[0],\n\t\t\ty: D2R * start[1],\n\t\t};\n\n\t\tthis.end = {\n\t\t\tlng: end[0],\n\t\t\tlat: end[1],\n\t\t\tx: D2R * end[0],\n\t\t\ty: D2R * end[1],\n\t\t};\n\n\t\tthis.properties = properties || ({} as Properties);\n\n\t\tconst w = this.start.x - this.end.x;\n\t\tconst h = this.start.y - this.end.y;\n\t\tconst z =\n\t\t\tMath.pow(Math.sin(h / 2.0), 2) +\n\t\t\tMath.cos(this.start.y) *\n\t\t\t\tMath.cos(this.end.y) *\n\t\t\t\tMath.pow(Math.sin(w / 2.0), 2);\n\t\tthis.g = 2.0 * Math.asin(Math.sqrt(z));\n\n\t\tif (this.g === Math.PI) {\n\t\t\tthrow new Error(\n\t\t\t\t`it appears ${start} and ${end} are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite`,\n\t\t\t);\n\t\t} else if (isNaN(this.g)) {\n\t\t\tthrow new Error(\n\t\t\t\t`could not calculate great circle between ${start} and ${end}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate g: number;\n\tprivate start: Coord;\n\tprivate end: Coord;\n\tprivate properties: Properties;\n\n\t/*\n\t * http://williams.best.vwh.net/avform.htm#Intermediate\n\t */\n\tinterpolate(f: number) {\n\t\tconst A = Math.sin((1 - f) * this.g) / Math.sin(this.g);\n\t\tconst B = Math.sin(f * this.g) / Math.sin(this.g);\n\t\tconst x =\n\t\t\tA * Math.cos(this.start.y) * Math.cos(this.start.x) +\n\t\t\tB * Math.cos(this.end.y) * Math.cos(this.end.x);\n\t\tconst y =\n\t\t\tA * Math.cos(this.start.y) * Math.sin(this.start.x) +\n\t\t\tB * Math.cos(this.end.y) * Math.sin(this.end.x);\n\t\tconst z = A * Math.sin(this.start.y) + B * Math.sin(this.end.y);\n\t\tconst lat = R2D * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));\n\t\tconst lon = R2D * Math.atan2(y, x);\n\t\treturn [lon, lat];\n\t}\n\n\t/*\n\t * Generate points along the great circle\n\t */\n\tarc(\n\t\tnumberOfPoints: number,\n\t\toptions: { offset: number; coordinatePrecision: number },\n\t) {\n\t\tconst firstPass = [];\n\t\tif (!numberOfPoints || numberOfPoints <= 2) {\n\t\t\tfirstPass.push([this.start.lng, this.start.lat]);\n\t\t\tfirstPass.push([this.end.lng, this.end.lat]);\n\t\t} else {\n\t\t\tconst delta = 1.0 / (numberOfPoints - 1);\n\t\t\tfor (let i = 0; i < numberOfPoints; ++i) {\n\t\t\t\tconst step = delta * i;\n\t\t\t\tconst pair = this.interpolate(step);\n\t\t\t\tfirstPass.push(pair);\n\t\t\t}\n\t\t}\n\t\t/* partial port of dateline handling from:\n            gdal/ogr/ogrgeometryfactory.cpp\n    \n            TODO - does not handle all wrapping scenarios yet\n        */\n\t\tlet bHasBigDiff = false;\n\t\tlet dfMaxSmallDiffLong = 0;\n\t\t// from http://www.gdal.org/ogr2ogr.html\n\t\t// -datelineoffset:\n\t\t// (starting with GDAL 1.10) offset from dateline in degrees (default long. = +/- 10deg, geometries within 170deg to -170deg will be splited)\n\t\tconst dfDateLineOffset = options && options.offset ? options.offset : 10;\n\t\tconst dfLeftBorderX = 180 - dfDateLineOffset;\n\t\tconst dfRightBorderX = -180 + dfDateLineOffset;\n\t\tconst dfDiffSpace = 360 - dfDateLineOffset;\n\n\t\t// https://github.com/OSGeo/gdal/blob/7bfb9c452a59aac958bff0c8386b891edf8154ca/gdal/ogr/ogrgeometryfactory.cpp#L2342\n\t\tfor (let j = 1; j < firstPass.length; ++j) {\n\t\t\tconst dfPrevX = firstPass[j - 1][0];\n\t\t\tconst dfX = firstPass[j][0];\n\t\t\tconst dfDiffLong = Math.abs(dfX - dfPrevX);\n\t\t\tif (\n\t\t\t\tdfDiffLong > dfDiffSpace &&\n\t\t\t\t((dfX > dfLeftBorderX && dfPrevX < dfRightBorderX) ||\n\t\t\t\t\t(dfPrevX > dfLeftBorderX && dfX < dfRightBorderX))\n\t\t\t) {\n\t\t\t\tbHasBigDiff = true;\n\t\t\t} else if (dfDiffLong > dfMaxSmallDiffLong) {\n\t\t\t\tdfMaxSmallDiffLong = dfDiffLong;\n\t\t\t}\n\t\t}\n\n\t\tconst poMulti = [];\n\t\tif (bHasBigDiff && dfMaxSmallDiffLong < dfDateLineOffset) {\n\t\t\tlet poNewLS: [number, number][] = [];\n\t\t\tpoMulti.push(poNewLS);\n\n\t\t\tfor (let k = 0; k < firstPass.length; ++k) {\n\t\t\t\tconst dfX0 = firstPass[k][0];\n\t\t\t\tif (k > 0 && Math.abs(dfX0 - firstPass[k - 1][0]) > dfDiffSpace) {\n\t\t\t\t\tlet dfX1 = firstPass[k - 1][0];\n\t\t\t\t\tlet dfY1 = firstPass[k - 1][1];\n\t\t\t\t\tlet dfX2 = firstPass[k][0];\n\t\t\t\t\tlet dfY2 = firstPass[k][1];\n\t\t\t\t\tif (\n\t\t\t\t\t\tdfX1 > -180 &&\n\t\t\t\t\t\tdfX1 < dfRightBorderX &&\n\t\t\t\t\t\tdfX2 === 180 &&\n\t\t\t\t\t\tk + 1 < firstPass.length &&\n\t\t\t\t\t\tfirstPass[k - 1][0] > -180 &&\n\t\t\t\t\t\tfirstPass[k - 1][0] < dfRightBorderX\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoNewLS.push([-180, firstPass[k][1]]);\n\t\t\t\t\t\tk++;\n\t\t\t\t\t\tpoNewLS.push([firstPass[k][0], firstPass[k][1]]);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tdfX1 > dfLeftBorderX &&\n\t\t\t\t\t\tdfX1 < 180 &&\n\t\t\t\t\t\tdfX2 === -180 &&\n\t\t\t\t\t\tk + 1 < firstPass.length &&\n\t\t\t\t\t\tfirstPass[k - 1][0] > dfLeftBorderX &&\n\t\t\t\t\t\tfirstPass[k - 1][0] < 180\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoNewLS.push([180, firstPass[k][1]]);\n\t\t\t\t\t\tk++;\n\t\t\t\t\t\tpoNewLS.push([firstPass[k][0], firstPass[k][1]]);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (dfX1 < dfRightBorderX && dfX2 > dfLeftBorderX) {\n\t\t\t\t\t\t// swap dfX1, dfX2\n\t\t\t\t\t\tconst tmpX = dfX1;\n\t\t\t\t\t\tdfX1 = dfX2;\n\t\t\t\t\t\tdfX2 = tmpX;\n\n\t\t\t\t\t\t// swap dfY1, dfY2\n\t\t\t\t\t\tconst tmpY = dfY1;\n\t\t\t\t\t\tdfY1 = dfY2;\n\t\t\t\t\t\tdfY2 = tmpY;\n\t\t\t\t\t}\n\t\t\t\t\tif (dfX1 > dfLeftBorderX && dfX2 < dfRightBorderX) {\n\t\t\t\t\t\tdfX2 += 360;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (dfX1 <= 180 && dfX2 >= 180 && dfX1 < dfX2) {\n\t\t\t\t\t\tconst dfRatio = (180 - dfX1) / (dfX2 - dfX1);\n\t\t\t\t\t\tconst dfY = dfRatio * dfY2 + (1 - dfRatio) * dfY1;\n\t\t\t\t\t\tpoNewLS.push([\n\t\t\t\t\t\t\tfirstPass[k - 1][0] > dfLeftBorderX ? 180 : -180,\n\t\t\t\t\t\t\tdfY,\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tpoNewLS = [];\n\t\t\t\t\t\tpoNewLS.push([\n\t\t\t\t\t\t\tfirstPass[k - 1][0] > dfLeftBorderX ? -180 : 180,\n\t\t\t\t\t\t\tdfY,\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tpoMulti.push(poNewLS);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpoNewLS = [];\n\t\t\t\t\t\tpoMulti.push(poNewLS);\n\t\t\t\t\t}\n\t\t\t\t\tpoNewLS.push([dfX0, firstPass[k][1]]);\n\t\t\t\t} else {\n\t\t\t\t\tpoNewLS.push([firstPass[k][0], firstPass[k][1]]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// add normally\n\t\t\tconst poNewLS0: [number, number][] = [];\n\t\t\tpoMulti.push(poNewLS0);\n\t\t\tfor (let l = 0; l < firstPass.length; ++l) {\n\t\t\t\tpoNewLS0.push([firstPass[l][0], firstPass[l][1]]);\n\t\t\t}\n\t\t}\n\n\t\tconst arc = new Arc({ properties: this.properties });\n\t\tfor (let m = 0; m < poMulti.length; ++m) {\n\t\t\tconst line = new ArcLineString(options.coordinatePrecision);\n\t\t\tarc.geometries.push(line);\n\t\t\tconst points = poMulti[m];\n\t\t\tfor (let j0 = 0; j0 < points.length; ++j0) {\n\t\t\t\tline.moveTo(points[j0]);\n\t\t\t}\n\t\t}\n\t\treturn arc;\n\t}\n}\n\nexport function greatCircleLine<Properties extends JSONObject>({\n\tstart,\n\tend,\n\toptions,\n}: {\n\tstart: Position;\n\tend: Position;\n\toptions?: {\n\t\tnumberOfPoints?: number;\n\t\toffset?: number;\n\t\tproperties?: Properties;\n\t\tcoordinatePrecision?: number;\n\t};\n}) {\n\tconst opts = options || {};\n\tif (typeof opts !== \"object\") {\n\t\tthrow new Error(\"options argument is invalid, must be of type object\");\n\t}\n\n\tconst {\n\t\tproperties = {},\n\t\tnumberOfPoints = 100,\n\t\toffset = 10,\n\t\tcoordinatePrecision = 9,\n\t} = opts;\n\tconst circle = new GreatCircleLine(start, end, properties);\n\tconst line = circle.arc(numberOfPoints, {\n\t\toffset: offset,\n\t\tcoordinatePrecision,\n\t});\n\n\treturn line.toJSON();\n}\n","import { Project, Unproject } from \"../common\";\nimport { GeoJSONStore } from \"../store/store\";\n\nexport type BehaviorConfig = {\n\tstore: GeoJSONStore;\n\tmode: string;\n\tproject: Project;\n\tunproject: Unproject;\n\tpointerDistance: number;\n\tcoordinatePrecision: number;\n};\n\nexport class TerraDrawModeBehavior {\n\tprotected store: GeoJSONStore;\n\tprotected mode: string;\n\tprotected project: Project;\n\tprotected unproject: Unproject;\n\tprotected pointerDistance: number;\n\tprotected coordinatePrecision: number;\n\n\tconstructor({\n\t\tstore,\n\t\tmode,\n\t\tproject,\n\t\tunproject,\n\t\tpointerDistance,\n\t\tcoordinatePrecision,\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}\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 GreatCircleSnappingBehavior 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\tpublic getSnappableCoordinate = (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcurrentFeatureId?: FeatureId,\n\t) => {\n\t\treturn this.getSnappableEnds(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\tcurrentFeatureId\n\t\t\t\t\t? feature.id !== currentFeatureId\n\t\t\t\t\t: true,\n\t\t\t);\n\t\t});\n\t};\n\n\tprivate getSnappableEnds(\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: { coord: undefined | Position; minDist: number } = {\n\t\t\tcoord: 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 === \"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\t// Get the start coordinate\n\t\t\tconst start = coordinates[0];\n\t\t\tconst dist = this.pixelDistance.measure(event, start);\n\t\t\tif (dist < closest.minDist && dist < this.pointerDistance) {\n\t\t\t\tclosest.coord = start;\n\t\t\t}\n\n\t\t\t// Get the final coordinate\n\t\t\tconst end = coordinates[coordinates.length - 1];\n\t\t\tconst endDist = this.pixelDistance.measure(event, end);\n\t\t\tif (endDist < closest.minDist && endDist < this.pointerDistance) {\n\t\t\t\tclosest.coord = end;\n\t\t\t}\n\t\t});\n\n\t\treturn closest.coord;\n\t}\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\n\nimport { Position } from \"geojson\";\nimport { pixelDistance } 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 = pixelDistance(\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 { 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 {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { LineString } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { greatCircleLine } from \"../../geometry/shape/great-circle-line\";\nimport { GreatCircleSnappingBehavior } from \"../great-circle-snapping.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\n\ntype TerraDrawGreateCircleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype GreateCircleStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawGreatCircleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawGreateCircleModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawGreatCircleMode extends TerraDrawBaseDrawMode<GreateCircleStyling> {\n\tmode = \"greatcircle\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawGreateCircleModeKeyEvents;\n\tprivate snappingEnabled: boolean;\n\tprivate cursors: Required<Cursors>;\n\n\t// Behaviors\n\tprivate snapping!: GreatCircleSnappingBehavior;\n\n\tconstructor(options?: TerraDrawGreatCircleModeOptions<GreateCircleStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.snappingEnabled =\n\t\t\toptions && options.snapping !== undefined ? options.snapping : false;\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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\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 finishedId = this.currentId;\n\n\t\t// Reset the state back to starting state\n\t\tthis.closingPointId && this.store.delete([this.closingPointId]);\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = 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\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId);\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.snapping = new GreatCircleSnappingBehavior(\n\t\t\tconfig,\n\t\t\tnew PixelDistanceBehavior(config),\n\t\t\tnew ClickBoundingBoxBehavior(config),\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.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined && this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t} else if (\n\t\t\tthis.currentId &&\n\t\t\tthis.currentCoordinate === 1 &&\n\t\t\tthis.closingPointId\n\t\t) {\n\t\t\tconst snappedCoord =\n\t\t\t\tthis.currentId &&\n\t\t\t\tthis.snappingEnabled &&\n\t\t\t\tthis.snapping.getSnappableCoordinate(event, this.currentId);\n\n\t\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.closingPointId,\n\t\t\t\t\tgeometry: { type: \"Point\", coordinates: updatedCoord },\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\t// Remove the 'live' point that changes on mouse move\n\t\t\tcurrentLineGeometry.coordinates.pop();\n\n\t\t\t// Update the 'live' point\n\t\t\tconst greatCircle = greatCircleLine({\n\t\t\t\tstart: currentLineGeometry.coordinates[0],\n\t\t\t\tend: updatedCoord,\n\t\t\t\toptions: { coordinatePrecision: this.coordinatePrecision },\n\t\t\t});\n\n\t\t\tif (greatCircle) {\n\t\t\t\tthis.store.updateGeometry([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: this.currentId,\n\t\t\t\t\t\tgeometry: greatCircle.geometry,\n\t\t\t\t\t},\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 (this.currentCoordinate === 0) {\n\t\t\tconst snappedCoord =\n\t\t\t\tthis.snappingEnabled && this.snapping.getSnappableCoordinate(event);\n\n\t\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\tupdatedCoord,\n\t\t\t\t\t\t\tupdatedCoord, // This is the 'live' point that changes on mouse move\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = createdId;\n\n\t\t\tconst [pointId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: updatedCoord,\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.closingPointId = pointId;\n\n\t\t\tthis.currentCoordinate++;\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\t// We are creating the point so we immediately want\n\t\t\t// to set the point cursor to show it can be closed\n\t\t\tthis.setCursor(\"pointer\");\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}\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\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t\tif (this.closingPointId) {\n\t\t\t\tthis.store.delete([this.closingPointId]);\n\t\t\t}\n\t\t} catch (error) {}\n\n\t\tthis.closingPointId = 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 (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tstyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.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\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.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.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.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\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\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\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): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tfeature.geometry.coordinates.length >= 2\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\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 SnappingBehavior 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\treturn 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\t};\n\n\tpublic getSnappableCoordinate = (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcurrentFeatureId: FeatureId,\n\t) => {\n\t\treturn 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\t};\n\n\tprivate 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: { coord: undefined | Position; minDist: number } = {\n\t\t\tcoord: 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) => {\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.coord = coord;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn closest.coord;\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { LineString } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { pixelDistance } from \"../../geometry/measure/pixel-distance\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype LineStringStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawLineStringModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: boolean;\n\tallowSelfIntersections?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawLineStringModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringStyling> {\n\tmode = \"linestring\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate allowSelfIntersections;\n\tprivate keyEvents: TerraDrawLineStringModeKeyEvents;\n\tprivate snappingEnabled: boolean;\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\t// Behaviors\n\tprivate snapping!: SnappingBehavior;\n\n\tconstructor(options?: TerraDrawLineStringModeOptions<LineStringStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.snappingEnabled =\n\t\t\toptions && options.snapping !== undefined ? options.snapping : false;\n\n\t\tthis.allowSelfIntersections =\n\t\t\toptions && options.allowSelfIntersections !== undefined\n\t\t\t\t? options.allowSelfIntersections\n\t\t\t\t: true;\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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\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 currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\t// Finish off the drawing\n\t\tcurrentLineGeometry.coordinates.pop();\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\tcoordinates: [...currentLineGeometry.coordinates],\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconst finishedId = this.currentId;\n\n\t\t// Reset the state back to starting state\n\t\tthis.closingPointId && this.store.delete([this.closingPointId]);\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = 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\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(finishedId);\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.snapping = new SnappingBehavior(\n\t\t\tconfig,\n\t\t\tnew PixelDistanceBehavior(config),\n\t\t\tnew ClickBoundingBoxBehavior(config),\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\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\t// Remove the 'live' point that changes on mouse move\n\t\tcurrentLineGeometry.coordinates.pop();\n\n\t\tconst snappedCoord =\n\t\t\tthis.snappingEnabled &&\n\t\t\tthis.snapping.getSnappableCoordinate(event, this.currentId);\n\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\t// We want to ensure that when we are hovering over\n\t\t// the losign point that the pointer cursor is shown\n\t\tif (this.closingPointId) {\n\t\t\tconst [previousLng, previousLat] =\n\t\t\t\tcurrentLineGeometry.coordinates[\n\t\t\t\t\tcurrentLineGeometry.coordinates.length - 1\n\t\t\t\t];\n\t\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\t\tconst distance = pixelDistance(\n\t\t\t\t{ x, y },\n\t\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t\t);\n\n\t\t\tconst isClosingClick = distance < this.pointerDistance;\n\n\t\t\tif (isClosingClick) {\n\t\t\t\tthis.setCursor(this.cursors.close);\n\t\t\t}\n\t\t}\n\n\t\t// Update the 'live' point\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\tcoordinates: [...currentLineGeometry.coordinates, updatedCoord],\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\tconst snappedCoord =\n\t\t\tthis.currentId &&\n\t\t\tthis.snappingEnabled &&\n\t\t\tthis.snapping.getSnappableCoordinate(event, this.currentId);\n\t\tconst updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\tupdatedCoord,\n\t\t\t\t\t\t\tupdatedCoord, // This is the 'live' point that changes on mouse move\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = createdId;\n\t\t\tthis.currentCoordinate++;\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst [pointId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: [...updatedCoord],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.closingPointId = pointId;\n\n\t\t\t// We are creating the point so we immediately want\n\t\t\t// to set the point cursor to show it can be closed\n\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\tcurrentLineGeometry.coordinates[0],\n\t\t\t\t\t\t\tupdatedCoord,\n\t\t\t\t\t\t\tupdatedCoord,\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentId) {\n\t\t\tconst currentLineGeometry = this.store.getGeometryCopy<LineString>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst [previousLng, previousLat] =\n\t\t\t\tcurrentLineGeometry.coordinates[\n\t\t\t\t\tcurrentLineGeometry.coordinates.length - 2\n\t\t\t\t];\n\t\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\t\tconst distance = pixelDistance(\n\t\t\t\t{ x, y },\n\t\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t\t);\n\n\t\t\tconst isClosingClick = distance < this.pointerDistance;\n\n\t\t\tif (isClosingClick) {\n\t\t\t\tthis.close();\n\t\t\t} else {\n\t\t\t\t// If not close to the final point, keep adding points\n\t\t\t\tconst newLineString = {\n\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\tcoordinates: [...currentLineGeometry.coordinates, updatedCoord],\n\t\t\t\t} as LineString;\n\n\t\t\t\tif (!this.allowSelfIntersections) {\n\t\t\t\t\tconst hasSelfIntersections = selfIntersects({\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tgeometry: newLineString,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t});\n\n\t\t\t\t\tif (hasSelfIntersections) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.closingPointId) {\n\t\t\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\t\t\tthis.store.updateGeometry([\n\t\t\t\t\t\t{ id: this.currentId, geometry: newLineString },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: this.closingPointId,\n\t\t\t\t\t\t\tgeometry: {\n\t\t\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\t\t\tcoordinates:\n\t\t\t\t\t\t\t\t\tcurrentLineGeometry.coordinates[\n\t\t\t\t\t\t\t\t\t\tcurrentLineGeometry.coordinates.length - 1\n\t\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\t\t\t\t\tthis.currentCoordinate++;\n\t\t\t\t}\n\t\t\t}\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}\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\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t\tif (this.closingPointId) {\n\t\t\t\tthis.store.delete([this.closingPointId]);\n\t\t\t}\n\t\t} catch (error) {}\n\n\t\tthis.closingPointId = 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 (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tstyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.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\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.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.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.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\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\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\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): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tfeature.geometry.coordinates.length >= 2\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { GeoJSONStoreFeatures } from \"../../terra-draw\";\nimport { coordinateIsValid } from \"./is-valid-coordinate\";\n\nexport function isValidPoint(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"Point\" &&\n\t\tcoordinateIsValid(feature.geometry.coordinates, coordinatePrecision)\n\t);\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tNumericStyling,\n\tHexColorStyling,\n\tCursor,\n} from \"../../common\";\nimport { GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { isValidPoint } from \"../../geometry/boolean/is-valid-point\";\n\ntype PointModeStyling = {\n\tpointWidth: NumericStyling;\n\tpointColor: HexColorStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tcreate?: Cursor;\n}\n\ninterface TerraDrawPointModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawPointMode extends TerraDrawBaseDrawMode<PointModeStyling> {\n\tmode = \"point\";\n\n\tprivate cursors: Required<Cursors>;\n\n\tconstructor(options?: TerraDrawPointModeOptions<PointModeStyling>) {\n\t\tsuper(options);\n\t\tconst defaultCursors = {\n\t\t\tcreate: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\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 (!this.store) {\n\t\t\tthrow new Error(\"Mode must be registered first\");\n\t\t}\n\n\t\tconst [pointId] = this.store.create([\n\t\t\t{\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\t\t},\n\t\t\t\tproperties: { mode: this.mode },\n\t\t\t},\n\t\t]);\n\n\t\t// Ensure that any listerers are triggered with the main created geometry\n\t\tthis.onFinish(pointId);\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\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\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.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointWidth,\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.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\tthis.styles.pointOutlineColor,\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.pointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tisValidPoint(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\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 { Point, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { POLYGON_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\n\nexport class ClosingPointsBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _startEndPoints: string[] = [];\n\n\tget ids() {\n\t\treturn this._startEndPoints.concat();\n\t}\n\n\tset ids(_: string[]) {}\n\n\tpublic create(selectedCoords: Position[], mode: string) {\n\t\tif (this.ids.length) {\n\t\t\tthrow new Error(\"Opening and closing points already creating\");\n\t\t}\n\n\t\tif (selectedCoords.length <= 3) {\n\t\t\tthrow new Error(\"Requires at least 4 cooridnates\");\n\t\t}\n\n\t\tthis._startEndPoints = this.store.create(\n\t\t\t// Opening coordinate\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: selectedCoords[0],\n\t\t\t\t\t} as Point,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\t[POLYGON_PROPERTIES.CLOSING_POINT]: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t// Final coordinate\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: selectedCoords[selectedCoords.length - 2],\n\t\t\t\t\t} as Point,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\t[POLYGON_PROPERTIES.CLOSING_POINT]: true,\n\t\t\t\t\t},\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\tthis.store.delete(this.ids);\n\t\t\tthis._startEndPoints = [];\n\t\t}\n\t}\n\n\tpublic update(updatedCoordinates: Position[]) {\n\t\tif (this.ids.length !== 2) {\n\t\t\tthrow new Error(\"No closing points to update\");\n\t\t}\n\n\t\tthis.store.updateGeometry(\n\t\t\t// Opening coordinate\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tid: this.ids[0],\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: updatedCoordinates[0],\n\t\t\t\t\t} as Point,\n\t\t\t\t},\n\t\t\t\t// Final coordinate\n\t\t\t\t{\n\t\t\t\t\tid: this.ids[1],\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: updatedCoordinates[updatedCoordinates.length - 3],\n\t\t\t\t\t} as Point,\n\t\t\t\t},\n\t\t\t],\n\t\t);\n\t}\n\n\tpublic isClosingPoint(event: TerraDrawMouseEvent) {\n\t\tconst opening = this.store.getGeometryCopy(this.ids[0]);\n\t\tconst closing = this.store.getGeometryCopy(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 {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { Polygon } from \"geojson\";\nimport { selfIntersects } from \"../../geometry/boolean/self-intersects\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n} from \"../base.mode\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { createPolygon } from \"../../util/geoms\";\nimport { SnappingBehavior } from \"../snapping.behavior\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { ClosingPointsBehavior } from \"./behaviors/closing-points.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { isValidPolygonFeature } from \"../../geometry/boolean/is-valid-polygon-feature\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\ntype PolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\ninterface TerraDrawPolygonModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tallowSelfIntersections?: boolean;\n\tsnapping?: boolean;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawPolygonModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawPolygonMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n\tmode = \"polygon\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate allowSelfIntersections: boolean;\n\tprivate keyEvents: TerraDrawPolygonModeKeyEvents;\n\tprivate snappingEnabled: boolean;\n\n\t// Behaviors\n\tprivate snapping!: SnappingBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\tprivate cursors: Required<Cursors>;\n\tprivate mouseMove = false;\n\n\tconstructor(options?: TerraDrawPolygonModeOptions<PolygonStyling>) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t\tclose: \"pointer\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\tthis.snappingEnabled =\n\t\t\toptions && options.snapping !== undefined ? options.snapping : false;\n\n\t\tthis.allowSelfIntersections =\n\t\t\toptions && options.allowSelfIntersections !== undefined\n\t\t\t\t? options.allowSelfIntersections\n\t\t\t\t: true;\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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\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.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\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\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...currentPolygonCoordinates.slice(0, -2),\n\t\t\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconst finishedId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPoints.delete();\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(finishedId);\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.snapping = new SnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tnew ClickBoundingBoxBehavior(config),\n\t\t);\n\t\tthis.closingPoints = new ClosingPointsBehavior(config, this.pixelDistance);\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\tconst closestCoord = this.snappingEnabled\n\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t: undefined;\n\n\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\tthis.currentId,\n\t\t).coordinates[0];\n\n\t\tif (closestCoord) {\n\t\t\tevent.lng = closestCoord[0];\n\t\t\tevent.lat = closestCoord[1];\n\t\t}\n\n\t\tlet updatedCoordinates;\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t\t// renders the polygon - There might be a cleaner solution?\n\t\t\tconst epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n\t\t\tconst offset = Math.max(0.000001, epsilon);\n\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat - offset],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tupdatedCoordinates = [\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\tcurrentPolygonCoordinates[1],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t];\n\t\t} else {\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isClosingPoint(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\t\tupdatedCoordinates = [\n\t\t\t\t\t...currentPolygonCoordinates.slice(0, -2),\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\tupdatedCoordinates = [\n\t\t\t\t\t...currentPolygonCoordinates.slice(0, -2),\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.currentId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\tcoordinates: [updatedCoordinates],\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 (this.currentCoordinate === 0) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinateFirstClick(event)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst [newId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentId = newId;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst currentPolygonGeometry = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t);\n\n\t\t\tconst previousCoordinate = currentPolygonGeometry.coordinates[0][0];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\tcurrentPolygonGeometry.coordinates[0][0],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tif (closestCoord) {\n\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t}\n\n\t\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t).coordinates[0];\n\n\t\t\tconst previousCoordinate = currentPolygonCoordinates[1];\n\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\tpreviousCoordinate,\n\t\t\t);\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.currentCoordinate === 2) {\n\t\t\t\tthis.closingPoints.create(currentPolygonCoordinates, \"polygon\");\n\t\t\t}\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\t\t\t\tcurrentPolygonCoordinates[1],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentId) {\n\t\t\tconst closestCoord = this.snappingEnabled\n\t\t\t\t? this.snapping.getSnappableCoordinate(event, this.currentId)\n\t\t\t\t: undefined;\n\n\t\t\tconst currentPolygonCoordinates = this.store.getGeometryCopy<Polygon>(\n\t\t\t\tthis.currentId,\n\t\t\t).coordinates[0];\n\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isClosingPoint(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tthis.close();\n\t\t\t} else {\n\t\t\t\tif (closestCoord) {\n\t\t\t\t\tevent.lng = closestCoord[0];\n\t\t\t\t\tevent.lat = closestCoord[1];\n\t\t\t\t}\n\n\t\t\t\tconst previousCoordinate =\n\t\t\t\t\tcurrentPolygonCoordinates[this.currentCoordinate - 1];\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 updatedPolygon = createPolygon([\n\t\t\t\t\t[\n\t\t\t\t\t\t...currentPolygonCoordinates.slice(0, -1),\n\t\t\t\t\t\t[event.lng, event.lat], // New point that onMouseMove can manipulate\n\t\t\t\t\t\tcurrentPolygonCoordinates[0],\n\t\t\t\t\t],\n\t\t\t\t]);\n\n\t\t\t\tif (this.currentCoordinate > 2 && !this.allowSelfIntersections) {\n\t\t\t\t\tconst hasSelfIntersections = selfIntersects(updatedPolygon);\n\n\t\t\t\t\tif (hasSelfIntersections) {\n\t\t\t\t\t\t// Don't update the geometry!\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\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\tthis.store.updateGeometry([\n\t\t\t\t\t{ id: this.currentId, geometry: updatedPolygon.geometry },\n\t\t\t\t]);\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Update closing points straight away\n\t\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\t\tthis.closingPoints.update(updatedPolygon.geometry.coordinates[0]);\n\t\t\t\t}\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\n\t/** @internal */\n\tonDragStart() {\n\t\t// We want to allow the default drag\n\t\t// cursor to exist\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {\n\t\t// Set it back to crosshair\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\ttry {\n\t\t\tif (this.currentId) {\n\t\t\t\tthis.store.delete([this.currentId]);\n\t\t\t}\n\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\tthis.closingPoints.delete();\n\t\t\t}\n\t\t} catch (error) {}\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.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 = 10;\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.closingPointWidth,\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.closingPointColor,\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\tthis.styles.closingPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\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.closingPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\t\t\t\tstyles.zIndex = 30;\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tisValidPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\nexport function createPolygon(\n\tcoordinates: Position[][] = [\n\t\t[\n\t\t\t[0, 0],\n\t\t\t[0, 1],\n\t\t\t[1, 1],\n\t\t\t[1, 0],\n\t\t\t[0, 0],\n\t\t],\n\t],\n): Feature<Polygon> {\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates,\n\t\t},\n\t\tproperties: {},\n\t};\n}\n\nexport function createLineString(coordinates: Position[]): Feature<LineString> {\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: {\n\t\t\ttype: \"LineString\",\n\t\t\tcoordinates,\n\t\t},\n\t\tproperties: {},\n\t};\n}\n","import { Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n} from \"../../common\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { isValidNonIntersectingPolygonFeature } from \"../../geometry/boolean/is-valid-polygon-feature\";\n\ntype TerraDrawRectangleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\ntype RectanglePolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\ninterface TerraDrawRectangleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawRectangleModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawRectangleMode extends TerraDrawBaseDrawMode<RectanglePolygonStyling> {\n\tmode = \"rectangle\";\n\tprivate center: Position | undefined;\n\tprivate clickCount = 0;\n\tprivate currentRectangleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawRectangleModeKeyEvents;\n\tprivate cursors: Required<Cursors>;\n\n\tconstructor(\n\t\toptions?: TerraDrawRectangleModeOptions<RectanglePolygonStyling>,\n\t) {\n\t\tsuper(options);\n\n\t\tconst defaultCursors = {\n\t\t\tstart: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...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 = { cancel: null, finish: null };\n\t\t} else {\n\t\t\tconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\t}\n\n\tprivate updateRectangle(event: TerraDrawMouseEvent) {\n\t\tif (this.clickCount === 1 && this.center && this.currentRectangleId) {\n\t\t\tconst geometry = this.store.getGeometryCopy(this.currentRectangleId);\n\n\t\t\tconst firstCoord = (geometry.coordinates as Position[][])[0][0];\n\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.currentRectangleId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\tfirstCoord,\n\t\t\t\t\t\t\t\t[event.lng, firstCoord[1]],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[firstCoord[0], event.lat],\n\t\t\t\t\t\t\t\tfirstCoord,\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tconst finishedId = this.currentRectangleId;\n\t\tthis.center = undefined;\n\t\tthis.currentRectangleId = undefined;\n\t\tthis.clickCount = 0;\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\tfinishedId && this.onFinish(finishedId);\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 (this.clickCount === 0) {\n\t\t\tthis.center = [event.lng, event.lat];\n\t\t\tconst [createdId] = this.store.create([\n\t\t\t\t{\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Polygon\",\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\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},\n\t\t\t\t},\n\t\t\t]);\n\t\t\tthis.currentRectangleId = createdId;\n\t\t\tthis.clickCount++;\n\t\t\tthis.setDrawing();\n\t\t} else {\n\t\t\tthis.updateRectangle(event);\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.updateRectangle(event);\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\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tif (this.currentRectangleId) {\n\t\t\tthis.store.delete([this.currentRectangleId]);\n\t\t}\n\n\t\tthis.center = undefined;\n\t\tthis.currentRectangleId = undefined;\n\t\tthis.clickCount = 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 (\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.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\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\tif (super.validateFeature(feature)) {\n\t\t\treturn (\n\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\tisValidNonIntersectingPolygonFeature(feature, this.coordinatePrecision)\n\t\t\t);\n\t\t} else {\n\t\t\treturn false;\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\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../terra-draw\";\nimport { isValidPoint } from \"../../geometry/boolean/is-valid-point\";\nimport { isValidPolygonFeature } from \"../../geometry/boolean/is-valid-polygon-feature\";\nimport { isValidLineStringFeature } from \"../../geometry/boolean/is-valid-linestring-feature\";\n\ntype RenderModeStyling = {\n\tpointColor: HexColorStyling;\n\tpointWidth: NumericStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineWidth: NumericStyling;\n\tpolygonFillColor: HexColorStyling;\n\tpolygonFillOpacity: NumericStyling;\n\tpolygonOutlineColor: HexColorStyling;\n\tpolygonOutlineWidth: NumericStyling;\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tzIndex: NumericStyling;\n};\n\ninterface TerraDrawRenderModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tmodeName: string;\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\tsuper({ styles: options.styles });\n\t\tthis.mode = options.modeName;\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\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\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\tzIndex: this.getNumericStylingValue(\n\t\t\t\tthis.styles.zIndex,\n\t\t\t\tdefaultStyles.zIndex,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t};\n\t}\n\n\tvalidateFeature(feature: unknown): feature is GeoJSONStoreFeatures {\n\t\treturn (\n\t\t\tsuper.validateFeature(feature) &&\n\t\t\t(isValidPoint(feature, this.coordinatePrecision) ||\n\t\t\t\tisValidPolygonFeature(feature, this.coordinatePrecision) ||\n\t\t\t\tisValidLineStringFeature(feature, this.coordinatePrecision))\n\t\t);\n\t}\n}\n","import { GeoJSONStoreFeatures } from \"../../terra-draw\";\nimport { coordinateIsValid } from \"./is-valid-coordinate\";\n\nexport function isValidLineStringFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): boolean {\n\treturn (\n\t\tfeature.geometry.type === \"LineString\" &&\n\t\tfeature.geometry.coordinates.length >= 2 &&\n\t\tfeature.geometry.coordinates.every((coordinate) =>\n\t\t\tcoordinateIsValid(coordinate, coordinatePrecision),\n\t\t)\n\t);\n}\n","import { Position } from \"geojson\";\nimport { limitPrecision } from \"./limit-decimal-precision\";\nimport { Project, Unproject } from \"../common\";\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","import { Point, Position } from \"geojson\";\nimport { Project, Unproject } from \"../common\";\nimport { JSONObject } from \"../store/store\";\nimport { midpointCoordinate } from \"./midpoint-coordinate\";\n\nexport function getMidPointCoordinates(\n\tfeatureCoords: Position[],\n\tprecision: number,\n\tproject: Project,\n\tunproject: Unproject,\n) {\n\tconst midPointCoords: Position[] = [];\n\tfor (let i = 0; i < featureCoords.length - 1; i++) {\n\t\tconst mid = midpointCoordinate(\n\t\t\tfeatureCoords[i],\n\t\t\tfeatureCoords[i + 1],\n\t\t\tprecision,\n\t\t\tproject,\n\t\t\tunproject,\n\t\t);\n\t\tmidPointCoords.push(mid);\n\t}\n\treturn midPointCoords;\n}\n\nexport function getMidPoints(\n\tselectedCoords: Position[],\n\tproperties: (index: number) => JSONObject,\n\tprecision: number,\n\tproject: Project,\n\tunproject: Unproject,\n) {\n\treturn getMidPointCoordinates(\n\t\tselectedCoords,\n\t\tprecision,\n\t\tproject,\n\t\tunproject,\n\t).map((coord, i) => ({\n\t\tgeometry: { type: \"Point\", coordinates: coord } as Point,\n\t\tproperties: properties(i),\n\t}));\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport {\n\tgetMidPointCoordinates,\n\tgetMidPoints,\n} from \"../../../geometry/get-midpoints\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { SELECT_PROPERTIES } from \"../../../common\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class MidPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPointBehavior: SelectionPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _midPoints: string[] = [];\n\n\tget ids() {\n\t\treturn this._midPoints.concat();\n\t}\n\n\tset ids(_: string[]) {}\n\n\tpublic insert(midPointId: string, coordinatePrecision: number) {\n\t\tconst midPoint = this.store.getGeometryCopy(midPointId);\n\t\tconst { midPointFeatureId, midPointSegment } =\n\t\t\tthis.store.getPropertiesCopy(midPointId);\n\t\tconst geometry = this.store.getGeometryCopy<Polygon | LineString>(\n\t\t\tmidPointFeatureId as string,\n\t\t);\n\n\t\t// Update the coordinates to include inserted midpoint\n\t\tconst updatedCoordinates =\n\t\t\tgeometry.type === \"Polygon\"\n\t\t\t\t? geometry.coordinates[0]\n\t\t\t\t: geometry.coordinates;\n\n\t\tupdatedCoordinates.splice(\n\t\t\t(midPointSegment as number) + 1,\n\t\t\t0,\n\t\t\tmidPoint.coordinates as Position,\n\t\t);\n\n\t\t// Update geometry coordinates depending\n\t\t// on if a polygon or linestring\n\t\tgeometry.coordinates =\n\t\t\tgeometry.type === \"Polygon\" ? [updatedCoordinates] : updatedCoordinates;\n\n\t\t// Update the selected features geometry to insert\n\t\t// the new midpoint\n\t\tthis.store.updateGeometry([{ id: midPointFeatureId as string, geometry }]);\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\n\t\tthis.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]);\n\n\t\t// We don't need to check if flags are correct\n\t\t// because selection points are prerequiste for midpoints\n\t\tthis.create(\n\t\t\tupdatedCoordinates,\n\t\t\tmidPointFeatureId as string,\n\t\t\tcoordinatePrecision,\n\t\t);\n\t\tthis.selectionPointBehavior.create(\n\t\t\tupdatedCoordinates,\n\t\t\tgeometry.type,\n\t\t\tmidPointFeatureId as string,\n\t\t);\n\t}\n\n\tpublic create(\n\t\tselectedCoords: Position[],\n\t\tfeatureId: FeatureId,\n\t\tcoordinatePrecision: number,\n\t) {\n\t\tif (!this.store.has(featureId)) {\n\t\t\tthrow new Error(\"Store does not have feature with this id\");\n\t\t}\n\n\t\tthis._midPoints = this.store.create(\n\t\t\tgetMidPoints(\n\t\t\t\tselectedCoords,\n\t\t\t\t(i) => ({\n\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t[SELECT_PROPERTIES.MID_POINT]: true,\n\t\t\t\t\tmidPointSegment: i,\n\t\t\t\t\tmidPointFeatureId: featureId,\n\t\t\t\t}),\n\t\t\t\tcoordinatePrecision,\n\t\t\t\tthis.config.project,\n\t\t\t\tthis.config.unproject,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic delete() {\n\t\tif (this._midPoints.length) {\n\t\t\tthis.store.delete(this._midPoints);\n\t\t\tthis._midPoints = [];\n\t\t}\n\t}\n\n\tpublic getUpdated(updatedCoordinates: Position[]) {\n\t\tif (this._midPoints.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn getMidPointCoordinates(\n\t\t\tupdatedCoordinates,\n\t\t\tthis.coordinatePrecision,\n\t\t\tthis.config.project,\n\t\t\tthis.config.unproject,\n\t\t).map((updatedMidPointCoord, i) => ({\n\t\t\tid: this._midPoints[i] as string,\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: updatedMidPointCoord,\n\t\t\t} as Point,\n\t\t}));\n\t}\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { getCoordinatesAsPoints } from \"../../../geometry/get-coordinates-as-points\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class SelectionPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\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\tselectedCoords: Position[],\n\t\ttype: Polygon[\"type\"] | LineString[\"type\"],\n\t\tfeatureId: FeatureId,\n\t) {\n\t\tconst featureMode = this.store.getPropertiesCopy(featureId);\n\t\tthis._selectionPoints = this.store.create(\n\t\t\tgetCoordinatesAsPoints(selectedCoords, type, (i) => ({\n\t\t\t\tmode: this.mode,\n\t\t\t\tselectionPoint: true,\n\t\t\t\ttype: featureMode.mode === \"circle\" ? \"circle\" : \"other\",\n\t\t\t\tselectionPointFeatureId: featureId,\n\t\t\t\tindex: i,\n\t\t\t})),\n\t\t);\n\t}\n\n\tpublic delete() {\n\t\tif (this.ids.length) {\n\t\t\tthis.store.delete(this.ids);\n\t\t\tthis._selectionPoints = [];\n\t\t}\n\t}\n\n\tpublic getUpdated(updatedCoordinates: Position[]) {\n\t\tif (this._selectionPoints.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this._selectionPoints.map((id, i) => {\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: updatedCoordinates[i],\n\t\t\t\t} as Point,\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic getOneUpdated(index: number, updatedCoordinate: Position) {\n\t\tif (this._selectionPoints[index] === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tid: this._selectionPoints[index] as string,\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: updatedCoordinate,\n\t\t\t} as Point,\n\t\t};\n\t}\n}\n","import { Point, Position } from \"geojson\";\nimport { JSONObject } from \"../store/store\";\n\nexport function getCoordinatesAsPoints(\n\tselectedCoords: Position[],\n\tgeometryType: \"Polygon\" | \"LineString\",\n\tproperties: (index: number) => JSONObject,\n) {\n\tconst selectionPoints = [];\n\n\t// We can skip the last point for polygons\n\t// as it's a duplicate of the first\n\tconst length =\n\t\tgeometryType === \"Polygon\"\n\t\t\t? selectedCoords.length - 1\n\t\t\t: selectedCoords.length;\n\n\tfor (let i = 0; i < length; i++) {\n\t\tselectionPoints.push({\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Point\",\n\t\t\t\tcoordinates: selectedCoords[i],\n\t\t\t} as Point,\n\t\t\tproperties: properties(i),\n\t\t});\n\t}\n\n\treturn selectionPoints;\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","export const pixelDistanceToLine = (\n\tpoint: { x: number; y: number },\n\tlinePointOne: { x: number; y: number },\n\tlinePointTwo: { x: number; y: number },\n) => {\n\tconst square = (x: number) => {\n\t\treturn x * x;\n\t};\n\tconst dist2 = (v: { x: number; y: number }, w: { x: number; y: number }) => {\n\t\treturn square(v.x - w.x) + square(v.y - w.y);\n\t};\n\tconst distToSegmentSquared = (\n\t\tp: { x: number; y: number },\n\t\tv: { x: number; y: number },\n\t\tw: { x: number; y: number },\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 clickedFeature: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedFeatureDistance = Infinity;\n\t\tlet clickedMidPoint: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedMidPointDistance = Infinity;\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 isNonSelectedMidPoint =\n\t\t\t\t\t!hasSelection && feature.properties[SELECT_PROPERTIES.MID_POINT];\n\n\t\t\t\tif (isSelectionPoint || 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\t// We want to catch both clicked\n\t\t\t\t// features but also any midpoints\n\t\t\t\t// in the clicked area\n\t\t\t\tif (\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.MID_POINT] &&\n\t\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\t\tdistance < clickedMidPointDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedMidPointDistance = distance;\n\t\t\t\t\tclickedMidPoint = feature;\n\t\t\t\t} else if (\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 < clickedFeatureDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedFeatureDistance = distance;\n\t\t\t\t\tclickedFeature = feature;\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"LineString\") {\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 < clickedFeatureDistance\n\t\t\t\t\t) {\n\t\t\t\t\t\tclickedFeatureDistance = distanceToLine;\n\t\t\t\t\t\tclickedFeature = 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\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\tclickedFeatureDistance = 0;\n\t\t\t\t\tclickedFeature = feature;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { clickedFeature, clickedMidPoint };\n\t}\n}\n","import { TerraDrawMouseEvent, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureAtPointerEventBehavior } from \"./feature-at-pointer-event.behavior\";\nimport { Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class DragFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly featuresAtMouseEvent: FeatureAtPointerEventBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\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.featuresAtMouseEvent.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, validateFeature?: Validation) {\n\t\tif (!this.draggedFeatureId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.store.getGeometryCopy(this.draggedFeatureId);\n\t\tconst mouseCoord = [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\t\t\t\tconst delta = [\n\t\t\t\t\tthis.dragPosition[0] - mouseCoord[0],\n\t\t\t\t\tthis.dragPosition[1] - mouseCoord[1],\n\t\t\t\t];\n\n\t\t\t\t// Keep precision limited when calculating new coordinates\n\t\t\t\tconst updatedLng = limitPrecision(\n\t\t\t\t\tcoordinate[0] - delta[0],\n\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t);\n\n\t\t\t\tconst updatedLat = limitPrecision(\n\t\t\t\t\tcoordinate[1] - delta[1],\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 updatedSelectionPoints =\n\t\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\t\tif (validateFeature) {\n\t\t\t\tconst valid = validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tid: this.draggedFeatureId,\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!valid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Issue the update to the selected feature\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{ id: this.draggedFeatureId, geometry },\n\t\t\t\t...updatedSelectionPoints,\n\t\t\t\t...updatedMidPoints,\n\t\t\t]);\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 mouse points we can simply move it\n\t\t\t// to the dragged position\n\t\t\tthis.store.updateGeometry([\n\t\t\t\t{\n\t\t\t\t\tid: this.draggedFeatureId,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\t\tcoordinates: mouseCoord,\n\t\t\t\t\t},\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 { TerraDrawMouseEvent, Validation } 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 } from \"../../../store/store\";\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) {\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 getDraggableIndex(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t): number {\n\t\tconst geometry = this.store.getGeometryCopy(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\tpublic drag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tallowSelfIntersection: boolean,\n\t\tvalidateFeature?: Validation,\n\t): boolean {\n\t\tif (!this.draggedCoordinate.id) {\n\t\t\treturn false;\n\t\t}\n\t\tconst index = this.draggedCoordinate.index;\n\t\tconst geometry = this.store.getGeometryCopy(this.draggedCoordinate.id);\n\n\t\tconst geomCoordinates = (\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 === geomCoordinates.length - 1 || index === 0);\n\n\t\t// Store the updated coord\n\t\tconst updatedCoordinate = [event.lng, event.lat];\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 = geomCoordinates.length - 1;\n\t\t\tgeomCoordinates[0] = updatedCoordinate;\n\t\t\tgeomCoordinates[lastCoordIndex] = updatedCoordinate;\n\t\t} else {\n\t\t\tgeomCoordinates[index] = updatedCoordinate;\n\t\t}\n\n\t\tconst updatedSelectionPoint = this.selectionPoints.getOneUpdated(\n\t\t\tindex,\n\t\t\tupdatedCoordinate,\n\t\t);\n\n\t\tconst updatedSelectionPoints = updatedSelectionPoint\n\t\t\t? [updatedSelectionPoint]\n\t\t\t: [];\n\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(geomCoordinates) || [];\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\tif (validateFeature) {\n\t\t\tconst valid = validateFeature(\n\t\t\t\t{\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\t\tgeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Apply all the updates\n\t\tthis.store.updateGeometry([\n\t\t\t// Update feature\n\t\t\t{\n\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\tgeometry: geometry,\n\t\t\t},\n\t\t\t// Update selection and mid points\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\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// Based on turf-bearing: 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 { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\n// Based on Turf.js Rhumb Bearing module\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.js Rhumb Destination module\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? 360\n\t\t\t: 0;\n\treturn destination;\n}\n","import { Position } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Based on Turf.js 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? 360\n\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 { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { transformRotate } 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 } from \"../../../store/store\";\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) {\n\t\tsuper(config);\n\t}\n\n\tprivate lastBearing: number | undefined;\n\n\treset() {\n\t\tthis.lastBearing = undefined;\n\t}\n\n\trotate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t\tvalidateFeature?: Validation,\n\t) {\n\t\tconst geometry = this.store.getGeometryCopy<LineString | Polygon>(\n\t\t\tselectedId,\n\t\t);\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\tconst bearing = rhumbBearing(\n\t\t\tcentroid({ type: \"Feature\", geometry, properties: {} }),\n\t\t\tmouseCoord,\n\t\t);\n\n\t\t// We need an original bearing to compare against\n\t\tif (!this.lastBearing) {\n\t\t\tthis.lastBearing = bearing + 180;\n\t\t\treturn;\n\t\t}\n\n\t\tconst angle = this.lastBearing - (bearing + 180);\n\n\t\ttransformRotate({ type: \"Feature\", geometry, properties: {} }, -angle);\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 updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tif (validateFeature) {\n\t\t\tif (\n\t\t\t\t!validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: selectedId,\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{ id: selectedId, geometry },\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\tthis.lastBearing = bearing + 180;\n\t}\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\";\n\n// Based on turf-transform-rotate: https://github.com/Turfjs/turf/tree/master/packages/turf-transform-rotate\n\nexport function transformRotate(\n\tgeojson: Feature<Polygon | LineString>,\n\tangle: number,\n) {\n\t// Shortcut no-rotation\n\tif (angle === 0) {\n\t\treturn geojson;\n\t}\n\n\t// Use centroid of GeoJSON if pivot is not provided\n\tconst pivot = centroid(geojson);\n\n\tconst cooordinates =\n\t\tgeojson.geometry.type === \"Polygon\"\n\t\t\t? geojson.geometry.coordinates[0]\n\t\t\t: geojson.geometry.coordinates;\n\n\tcooordinates.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 geojson;\n}\n","import { TerraDrawMouseEvent, Validation } 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 { centroid } from \"../../../geometry/centroid\";\nimport { haversineDistanceKilometers } from \"../../../geometry/measure/haversine-distance\";\nimport { transformScale } from \"../../../geometry/transform/scale\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId } from \"../../../store/store\";\n\nexport class ScaleFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate lastDistance: number | undefined;\n\n\treset() {\n\t\tthis.lastDistance = undefined;\n\t}\n\n\tscale(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t\tvalidateFeature?: Validation,\n\t) {\n\t\tconst geometry = this.store.getGeometryCopy<LineString | Polygon>(\n\t\t\tselectedId,\n\t\t);\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\tconst distance = haversineDistanceKilometers(\n\t\t\tcentroid({ type: \"Feature\", geometry, properties: {} }),\n\t\t\tmouseCoord,\n\t\t);\n\n\t\t// We need an original bearing to compare against\n\t\tif (!this.lastDistance) {\n\t\t\tthis.lastDistance = distance;\n\t\t\treturn;\n\t\t}\n\n\t\tconst scale = 1 - (this.lastDistance - distance) / distance;\n\n\t\tconst feature = { type: \"Feature\", geometry, properties: {} } as Feature<\n\t\t\tPolygon | LineString\n\t\t>;\n\t\tconst origin = centroid(feature);\n\t\ttransformScale(feature, scale, origin);\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 updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tif (validateFeature) {\n\t\t\tif (\n\t\t\t\t!validateFeature(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: selectedId,\n\t\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\t\tgeometry,\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{ id: selectedId, geometry },\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\n\n\t\tthis.lastDistance = distance;\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n// import { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\n\n// Based on turf-transform-scale: https://github.com/Turfjs/turf/tree/master/packages/turf-transform-scale\n\nexport function transformScale(\n\tfeature: Feature<Polygon | LineString>,\n\tfactor: number,\n\torigin: Position,\n\taxis: \"x\" | \"y\" | \"xy\" = \"xy\",\n) {\n\t// Shortcut no-scaling\n\tif (factor === 1) {\n\t\treturn feature;\n\t}\n\n\tconst cooordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tcooordinates.forEach((pointCoords: Position) => {\n\t\tconst originalDistance = rhumbDistance(origin, pointCoords);\n\t\tconst bearing = rhumbBearing(origin, pointCoords);\n\t\tconst newDistance = originalDistance * factor;\n\t\tconst newCoord = rhumbDestination(origin, newDistance, bearing);\n\n\t\tif (axis === \"x\" || axis === \"xy\") {\n\t\t\tpointCoords[0] = newCoord[0];\n\t\t}\n\n\t\tif (axis === \"y\" || axis === \"xy\") {\n\t\t\tpointCoords[1] = newCoord[1];\n\t\t}\n\t});\n\n\treturn feature;\n}\n","const 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): { x: number; y: number } => ({\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, LineString, Polygon, Position } from \"geojson\";\nimport { lngLatToWebMercatorXY } from \"./project/web-mercator\";\n\nfunction bbox(coords: Position[]) {\n\tconst result = [Infinity, Infinity, -Infinity, -Infinity];\n\tfor (let i = 0; i < coords.length; i++) {\n\t\tconst coord = coords[i];\n\t\tif (result[0] > coord[0]) {\n\t\t\tresult[0] = coord[0];\n\t\t}\n\t\tif (result[1] > coord[1]) {\n\t\t\tresult[1] = coord[1];\n\t\t}\n\t\tif (result[2] < coord[0]) {\n\t\t\tresult[2] = coord[0];\n\t\t}\n\t\tif (result[3] < coord[1]) {\n\t\t\tresult[3] = coord[1];\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function webMercatorCenter(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\tconst ext = bbox(webMercatorCoordinates);\n\tconst x = (ext[0] + ext[2]) / 2;\n\tconst y = (ext[1] + ext[3]) / 2;\n\treturn { x, y };\n}\n","import { TerraDrawMouseEvent, Validation } 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 { FeatureId, GeoJSONStoreGeometries } from \"../../../store/store\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { pixelDistance } from \"../../../geometry/measure/pixel-distance\";\nimport { coordinateIsValid } from \"../../../geometry/boolean/is-valid-coordinate\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../../geometry/project/web-mercator\";\nimport { webMercatorCenter } from \"../../../geometry/web-mercator-center\";\n\nexport type ResizeOptions =\n\t| \"center-web-mercator\"\n\t| \"opposite-web-mercator\"\n\t| \"center-fixed-web-mercator\"\n\t| \"opposite-fixed-web-mercator\";\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) {\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 = webMercatorCenter(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 = webMercatorCenter(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: { x: number; y: number };\n\t\twebMercatorSelected: { x: number; y: number };\n\t\twebMercatorOrigin: { x: number; y: number };\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\tpixelDistance(webMercatorOrigin, webMercatorCursor) /\n\t\t\tpixelDistance(webMercatorOrigin, webMercatorSelected);\n\n\t\tif (scale < 0) {\n\t\t\tscale = 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\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: { x: number; y: number };\n\t\twebMercatorSelected: { x: number; y: number };\n\t\twebMercatorOrigin: { x: number; y: number };\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.store.getGeometryCopy(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 = { type: \"Feature\", geometry, properties: {} } as Feature<\n\t\t\tPolygon | LineString\n\t\t>;\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 represnted 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: { x: number; y: number },\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 = pixelDistance(\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.store.getGeometryCopy(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-web-mercator\" or \"opposite-web-mercator\"\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\tvalidateFeature?: Validation,\n\t): boolean {\n\t\tif (!this.draggedCoordinate.id) {\n\t\t\treturn false;\n\t\t}\n\t\tconst feature = this.getFeature(this.draggedCoordinate.id);\n\t\tif (!feature) {\n\t\t\treturn false;\n\t\t}\n\t\tlet updatedCoords: Position[] | null = null;\n\n\t\tif (resizeOption === \"center-web-mercator\") {\n\t\t\tupdatedCoords = this.centerWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite-web-mercator\") {\n\t\t\tupdatedCoords = this.oppositeWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"center-fixed-web-mercator\") {\n\t\t\tupdatedCoords = this.centerFixedWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite-fixed-web-mercator\") {\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 (!coordinateIsValid(coordinate, this.coordinatePrecision)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Perform the update to the midpoints and selection points\n\t\tconst updatedMidPoints = this.midPoints.getUpdated(updatedCoords) || [];\n\t\tconst updatedSelectionPoints =\n\t\t\tthis.selectionPoints.getUpdated(updatedCoords) || [];\n\n\t\tconst updatedGeometry = {\n\t\t\ttype: feature.geometry.type as \"Polygon\" | \"LineString\",\n\t\t\tcoordinates:\n\t\t\t\tfeature.geometry.type === \"Polygon\" ? [updatedCoords] : updatedCoords,\n\t\t} as GeoJSONStoreGeometries;\n\n\t\tif (validateFeature) {\n\t\t\tconst valid = validateFeature(\n\t\t\t\t{\n\t\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tproject: this.config.project,\n\t\t\t\t\tunproject: this.config.unproject,\n\t\t\t\t\tcoordinatePrecision: this.config.coordinatePrecision,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!valid) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Issue the update to the selected feature\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: this.draggedCoordinate.id,\n\t\t\t\tgeometry: updatedGeometry,\n\t\t\t},\n\t\t\t...updatedSelectionPoints,\n\t\t\t...updatedMidPoints,\n\t\t]);\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} from \"../../common\";\nimport { Point, Position } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tTerraDrawBaseSelectMode,\n} from \"../base.mode\";\nimport { MidPointBehavior } from \"./behaviors/midpoint.behavior\";\nimport { SelectionPointBehavior } 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\";\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\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\n\t\tcoordinates?: {\n\t\t\tmidpoints?:\n\t\t\t\t| {\n\t\t\t\t\t\tshow: boolean;\n\t\t\t\t\t\tdraggableMod: \"free\" | \"afterClick\";\n\t\t\t\t  }\n\t\t\t\t| boolean;\n\t\t\tdraggable?: boolean;\n\t\t\tresizable?: ResizeOptions;\n\t\t\tdeletable?: boolean;\n\t\t\tselfdraggable?: boolean;\n\t\t};\n\t};\n};\n\ntype SelectionStyling = {\n\t// Point\n\tselectedPointColor: HexColorStyling;\n\tselectedPointWidth: NumericStyling;\n\tselectedPointOutlineColor: HexColorStyling;\n\tselectedPointOutlineWidth: NumericStyling;\n\n\t// LineString\n\tselectedLineStringColor: HexColorStyling;\n\tselectedLineStringWidth: NumericStyling;\n\n\t// Polygon\n\tselectedPolygonColor: HexColorStyling;\n\tselectedPolygonFillOpacity: NumericStyling;\n\tselectedPolygonOutlineColor: HexColorStyling;\n\tselectedPolygonOutlineWidth: NumericStyling;\n\n\t// Selection Points (points at vertices of a polygon/linestring feature)\n\tselectionPointWidth: NumericStyling;\n\tselectionPointColor: HexColorStyling;\n\tselectionPointOutlineColor: HexColorStyling;\n\tselectionPointOutlineWidth: NumericStyling;\n\n\t// Mid points (points at mid point of a polygon/linestring feature)\n\tmidPointColor: HexColorStyling;\n\tmidPointOutlineColor: HexColorStyling;\n\tmidPointWidth: NumericStyling;\n\tmidPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tpointerOver?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n\tinsertMidpoint?: Cursor;\n}\n\ninterface TerraDrawSelectModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tpointerDistance?: number;\n\tflags?: { [mode: string]: ModeFlags };\n\tkeyEvents?: TerraDrawSelectModeKeyEvents | null;\n\tdragEventThrottle?: number;\n\tcursors?: Cursors;\n\tallowManualDeselection?: boolean;\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseSelectMode<SelectionStyling> {\n\tpublic mode = \"select\";\n\n\tprivate allowManualDeselection = true;\n\tprivate dragEventThrottle = 5;\n\tprivate dragEventCount = 0;\n\tprivate selected: FeatureId[] = [];\n\n\tprivate flags: { [mode: string]: ModeFlags };\n\tprivate keyEvents: TerraDrawSelectModeKeyEvents;\n\n\t// Behaviors\n\tprivate selectionPoints!: SelectionPointBehavior;\n\tprivate midPoints!: MidPointBehavior;\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 cursors: Required<Cursors>;\n\tprivate validations: {\n\t\t[mode: string]: (feature: GeoJSONStoreFeatures) => boolean;\n\t} = {};\n\n\tconstructor(options?: TerraDrawSelectModeOptions<SelectionStyling>) {\n\t\tsuper(options);\n\n\t\tthis.flags = options && options.flags ? options.flags : {};\n\n\t\tconst defaultCursors = {\n\t\t\tpointerOver: \"move\",\n\t\t\tdragStart: \"move\",\n\t\t\tdragEnd: \"move\",\n\t\t\tinsertMidpoint: \"crosshair\",\n\t\t} as Required<Cursors>;\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...defaultCursors, ...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 {\n\t\t\tconst defaultKeyEvents = {\n\t\t\t\tdeselect: \"Escape\",\n\t\t\t\tdelete: \"Delete\",\n\t\t\t\trotate: [\"Control\", \"r\"],\n\t\t\t\tscale: [\"Control\", \"s\"],\n\t\t\t};\n\t\t\tthis.keyEvents =\n\t\t\t\toptions && options.keyEvents\n\t\t\t\t\t? { ...defaultKeyEvents, ...options.keyEvents }\n\t\t\t\t\t: defaultKeyEvents;\n\t\t}\n\n\t\tthis.dragEventThrottle =\n\t\t\t(options &&\n\t\t\t\toptions.dragEventThrottle !== undefined &&\n\t\t\t\toptions.dragEventThrottle) ||\n\t\t\t5;\n\n\t\tthis.allowManualDeselection = options?.allowManualDeselection ?? true;\n\n\t\t// Validations\n\t\tif (options && options.flags && options.flags) {\n\t\t\tfor (const mode in options.flags) {\n\t\t\t\tconst feature = options.flags[mode].feature;\n\t\t\t\tif (feature && feature.validation) {\n\t\t\t\t\tthis.validations[mode] = feature.validation as (\n\t\t\t\t\t\tfeature: GeoJSONStoreFeatures,\n\t\t\t\t\t) => boolean;\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.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(config);\n\t\tthis.midPoints = new MidPointBehavior(config, this.selectionPoints);\n\n\t\tthis.rotateFeature = new RotateFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t);\n\n\t\tthis.scaleFeature = new ScaleFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\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);\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);\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);\n\t}\n\n\tpublic deselectFeature() {\n\t\tthis.deselect();\n\t}\n\n\tprivate deselect() {\n\t\tconst updateSelectedFeatures = this.selected\n\t\t\t.filter((id) => this.store.has(id))\n\t\t\t.map((id) => ({\n\t\t\t\tid,\n\t\t\t\tproperty: SELECT_PROPERTIES.SELECTED,\n\t\t\t\tvalue: false,\n\t\t\t}));\n\n\t\tthis.store.updateProperty(updateSelectedFeatures);\n\n\t\tthis.onDeselect(this.selected[0]);\n\t\tthis.selected = [];\n\t\tthis.selectionPoints.delete();\n\t\tthis.midPoints.delete();\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\tthis.store.delete(this.selected);\n\t\tthis.selected = [];\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:\n\t\t\t| {\n\t\t\t\t\tselectionPointFeatureId: string;\n\t\t\t\t\tindex: number;\n\t\t\t  }\n\t\t\t| undefined;\n\n\t\tlet clickedFeatureDistance = Infinity;\n\n\t\tthis.selectionPoints.ids.forEach((id) => {\n\t\t\tconst geometry = this.store.getGeometryCopy<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.store.getPropertiesCopy(id) as {\n\t\t\t\t\tselectionPointFeatureId: string;\n\t\t\t\t\tindex: number;\n\t\t\t\t};\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.store.getPropertiesCopy(featureId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst validation = this.validations[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.store.getGeometryCopy(featureId);\n\n\t\tlet coordinates;\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 <= 3) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Geometry is not Polygon or LineString\n\t\tif (!coordinates) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\t(geometry.type === \"Polygon\" && coordinateIndex === 0) ||\n\t\t\tcoordinateIndex === coordinates.length - 1\n\t\t) {\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\t// Validate the new geometry\n\t\tif (validation) {\n\t\t\tconst valid = validation({\n\t\t\t\tid: featureId,\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry,\n\t\t\t\tproperties,\n\t\t\t});\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.store.delete([...this.midPoints.ids, ...this.selectionPoints.ids]);\n\t\tthis.store.updateGeometry([\n\t\t\t{\n\t\t\t\tid: featureId,\n\t\t\t\tgeometry,\n\t\t\t},\n\t\t]);\n\n\t\tthis.selectionPoints.create(\n\t\t\tcoordinates,\n\t\t\tgeometry.type as \"Polygon\" | \"LineString\",\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(coordinates, featureId, this.coordinatePrecision);\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.store.getPropertiesCopy(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();\n\t\t\t}\n\t\t}\n\n\t\tif (fromCursor) {\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t}\n\n\t\t// Select feature\n\t\tthis.selected = [featureId];\n\n\t\tthis.store.updateProperty([\n\t\t\t{ id: featureId, property: \"selected\", value: true },\n\t\t]);\n\t\tthis.onSelect(featureId);\n\n\t\t// Get the clicked feature\n\t\tconst { type, coordinates } = this.store.getGeometryCopy(featureId);\n\n\t\tif (type !== \"LineString\" && type !== \"Polygon\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// LineString does not have nesting so we can just take 'coordinates'\n\t\t// directly. Polygon is nested so we need to take [0] item in the array\n\t\tconst selectedCoords: Position[] =\n\t\t\ttype === \"LineString\" ? coordinates : coordinates[0];\n\n\t\tif (selectedCoords && modeFlags && modeFlags.feature.coordinates) {\n\t\t\tthis.selectionPoints.create(selectedCoords, type, featureId);\n\n\t\t\tif (modeFlags.feature.coordinates.midpoints) {\n\t\t\t\tthis.midPoints.create(\n\t\t\t\t\tselectedCoords,\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tthis.coordinatePrecision,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tconst { clickedFeature, clickedMidPoint } = this.featuresAtMouseEvent.find(\n\t\t\tevent,\n\t\t\tthis.selected.length > 0,\n\t\t);\n\n\t\tif (this.selected.length && clickedMidPoint) {\n\t\t\t// TODO: We probably want to make sure the midpoint\n\t\t\t// is visible?\n\n\t\t\tthis.midPoints.insert(\n\t\t\t\tclickedMidPoint.id as string,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (clickedFeature && clickedFeature.id) {\n\t\t\tthis.select(clickedFeature.id, true);\n\t\t} else if (this.selected.length && this.allowManualDeselection) {\n\t\t\tthis.deselect();\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 (this.selected.length) {\n\t\t\tthis.setCursor(this.cursors.dragEnd);\n\t\t\t// If we have finished dragging a coordinate or a feature\n\t\t\t// lets fire an onFinish event which can be listened to\n\t\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t} else if (this.dragFeature.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t} else if (this.dragCoordinateResizeFeature.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t}\n\n\t\t\tthis.dragCoordinate.stopDragging();\n\t\t\tthis.dragFeature.stopDragging();\n\t\t\tthis.dragCoordinateResizeFeature.stopDragging();\n\t\t\tthis.rotateFeature.reset();\n\t\t\tthis.scaleFeature.reset();\n\t\t\t// this.deselect();\n\t\t}\n\n\t\tif (event.button === \"right\") {\n\t\t\tthis.onRightClick(event);\n\t\t\treturn;\n\t\t} else if (event.button === \"left\") {\n\t\t\tthis.onLeftClick(event);\n\t\t} else if (event.button === \"neither\") {\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\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 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.setCursor(this.cursors.dragEnd);\n\t\t\t// If we have finished dragging a coordinate or a feature\n\t\t\t// lets fire an onFinish event which can be listened to\n\t\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t} else if (this.dragFeature.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t} else if (this.dragCoordinateResizeFeature.isDragging()) {\n\t\t\t\tthis.onFinish(this.selected[0]);\n\t\t\t}\n\n\t\t\tthis.dragCoordinate.stopDragging();\n\t\t\tthis.dragFeature.stopDragging();\n\t\t\tthis.dragCoordinateResizeFeature.stopDragging();\n\t\t\tthis.rotateFeature.reset();\n\t\t\tthis.scaleFeature.reset();\n\t\t\tthis.deselect();\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\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tthis.selected.length > 0 && this.onClick(event);\n\t\tif (!this.selected.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst midpoints =\n\t\t\tthis.flags[this.store.getPropertiesCopy(this.selected[0]).mode as string]\n\t\t\t\t.feature?.coordinates?.midpoints;\n\n\t\tif (\n\t\t\tthis.selected.length > 0 &&\n\t\t\ttypeof midpoints === \"object\" &&\n\t\t\tmidpoints.draggableMod === \"free\"\n\t\t) {\n\t\t\tthis.onClick(event);\n\t\t}\n\n\t\t// If the selected feature is not draggable\n\t\t// don't do anything\n\n\t\tconst properties = this.store.getPropertiesCopy(this.selected[0]);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst draggable =\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\t(modeFlags.feature.draggable ||\n\t\t\t\t(modeFlags.feature.coordinates &&\n\t\t\t\t\tmodeFlags.feature.coordinates.draggable) ||\n\t\t\t\t(modeFlags.feature.coordinates &&\n\t\t\t\t\tmodeFlags.feature.coordinates.resizable));\n\n\t\tif (!draggable) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.dragEventCount = 0;\n\n\t\tconst selectedId = this.selected[0];\n\t\tconst draggableCoordinateIndex = this.dragCoordinate.getDraggableIndex(\n\t\t\tevent,\n\t\t\tselectedId,\n\t\t);\n\n\t\t// Drag Coordinate\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\t(modeFlags.feature.coordinates.draggable ||\n\t\t\t\tmodeFlags.feature.coordinates.resizable) &&\n\t\t\tdraggableCoordinateIndex !== -1\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\t\t// With resizeable\n\t\t\tif (modeFlags.feature.coordinates.resizable) {\n\t\t\t\tthis.dragCoordinateResizeFeature.startDragging(\n\t\t\t\t\tselectedId,\n\t\t\t\t\tdraggableCoordinateIndex,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Without with resizable being set\n\t\t\t\tthis.dragCoordinate.startDragging(selectedId, draggableCoordinateIndex);\n\t\t\t}\n\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Drag Feature\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.draggable &&\n\t\t\tthis.dragFeature.canDrag(event, selectedId)\n\t\t) {\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\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\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.store.getPropertiesCopy(selectedId);\n\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\tconst validation = this.validations[properties.mode as string];\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, validation);\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\t\t\tthis.scaleFeature.scale(event, selectedId, validation);\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\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\tvalidation,\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\tthis.dragCoordinate.drag(event, canSelfIntersect, validation);\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, validation);\n\t\t\treturn;\n\t\t}\n\n\t\tsetMapDraggability(true);\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\t_: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tthis.setCursor(this.cursors.dragEnd);\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 (\n\t\t\tthis.dragCoordinate.isDragging() ||\n\t\t\tthis.dragCoordinateResizeFeature.isDragging()\n\t\t) {\n\t\t\tthis.onFinish(this.selected[0]);\n\t\t} else if (this.dragFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0]);\n\t\t} else if (this.dragCoordinateResizeFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0]);\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\tif (!this.selected.length) {\n\t\t\tthis.setCursor(\"unset\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.dragFeature.isDragging()) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet nearbyMidPoint = false;\n\t\tthis.midPoints.ids.forEach((id: string) => {\n\t\t\tif (nearbyMidPoint) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst geometry = this.store.getGeometryCopy<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n\t\t\tif (distance < this.pointerDistance) {\n\t\t\t\tnearbyMidPoint = true;\n\t\t\t}\n\t\t});\n\n\t\tlet nearbySelectionPoint = false;\n\t\t// TODO: Is there a cleaner way to handle prioritising\n\t\t// dragging selection points?\n\t\tthis.selectionPoints.ids.forEach((id: FeatureId) => {\n\t\t\tconst geometry = this.store.getGeometryCopy<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\t\t\tif (distance < this.pointerDistance) {\n\t\t\t\tnearbyMidPoint = false;\n\t\t\t\tnearbySelectionPoint = true;\n\t\t\t}\n\t\t});\n\n\t\tif (nearbyMidPoint) {\n\t\t\tthis.setCursor(this.cursors.insertMidpoint);\n\t\t\treturn;\n\t\t}\n\n\t\t// If we have a feature under the pointer then show the pointer over cursor\n\t\tconst { clickedFeature: featureUnderPointer } =\n\t\t\tthis.featuresAtMouseEvent.find(event, true);\n\n\t\tif (\n\t\t\tthis.selected.length > 0 &&\n\t\t\t((featureUnderPointer && featureUnderPointer.id === this.selected[0]) ||\n\t\t\t\tnearbySelectionPoint)\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t} else {\n\t\t\t// Set it back to whatever the default cursor is\n\t\t\tthis.setCursor(\"unset\");\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.selectionPoint) {\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.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.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 = 30;\n\n\t\t\t\treturn styles;\n\t\t\t}\n\n\t\t\tif (feature.properties.midPoint) {\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.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.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 = 40;\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 (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.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 = 10;\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 = 10;\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.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.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 = 10;\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { ModeTypes, TerraDrawBaseDrawMode } from \"../base.mode\";\n\n// TODO: Is there a better way to handle the following line?\n// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-types\ntype StaticModeStylingExt<T extends TerraDrawAdapterStyling> = {};\ntype StaticModeStyling = StaticModeStylingExt<TerraDrawAdapterStyling>;\n\nexport class TerraDrawStaticMode extends TerraDrawBaseDrawMode<StaticModeStyling> {\n\ttype = ModeTypes.Static;\n\tmode = \"static\";\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\";\n\ntype 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 = Feature<\n\tGeoJSONStoreGeometries,\n\tDefinedProperties\n>;\n\nexport type StoreChangeEvents = \"delete\" | \"create\" | \"update\" | \"styling\";\n\nexport type StoreChangeHandler = (\n\tids: FeatureId[],\n\tchange: StoreChangeEvents,\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\nexport type 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\nexport class GeoJSONStore<Id extends FeatureId = FeatureId> {\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 = () => {};\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?: (feature: unknown, tracked?: boolean) => boolean,\n\t) {\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\tconst clonedData = this.clone(data);\n\n\t\t// We try to be a bit forgiving here as many users\n\t\t// may not set a feature id as UUID or createdAt/updatedAt\n\t\tclonedData.forEach((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\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\tisValidTimestamp(feature.properties.createdAt);\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\tisValidTimestamp(feature.properties.updatedAt);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst changes: FeatureId[] = [];\n\t\tclonedData.forEach((feature) => {\n\t\t\tconst id = feature.id as FeatureId;\n\t\t\tif (featureValidation) {\n\t\t\t\tconst isValid = 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 (!isValid) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Feature is not ${id} valid: ${JSON.stringify(feature)}`,\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\tthrow new Error(`Feature already exists with this id: ${id}`);\n\t\t\t}\n\n\t\t\tthis.store[id] = feature;\n\t\t\tchanges.push(id);\n\t\t});\n\t\tthis.spatialIndex.load(clonedData);\n\t\tthis._onChange(changes, \"create\");\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) {\n\t\tthis._onChange = (ids, change) => {\n\t\t\tonChange(ids, change);\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: { id: FeatureId; property: string; value: JSON }[],\n\t): void {\n\t\tconst ids: FeatureId[] = [];\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\tids.push(id);\n\n\t\t\tfeature.properties[property] = value;\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) {\n\t\t\tthis._onChange(ids, \"update\");\n\t\t}\n\t}\n\n\tupdateGeometry(\n\t\tgeometriesToUpdate: { id: FeatureId; geometry: GeoJSONStoreGeometries }[],\n\t): void {\n\t\tconst ids: FeatureId[] = [];\n\t\tgeometriesToUpdate.forEach(({ id, geometry }) => {\n\t\t\tids.push(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) {\n\t\t\tthis._onChange(ids, \"update\");\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): 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\");\n\t\t}\n\n\t\treturn ids as Id[];\n\t}\n\n\tdelete(ids: FeatureId[]): 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 this id, can not delete\");\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange([...ids], \"delete\");\n\t\t}\n\t}\n\n\tcopyAll(): GeoJSONStoreFeatures[] {\n\t\treturn this.clone(Object.keys(this.store).map((id) => this.store[id]));\n\t}\n\n\tclear(): void {\n\t\tthis.store = {};\n\t\tthis.spatialIndex.clear();\n\t}\n\n\tsize(): number {\n\t\treturn Object.keys(this.store).length;\n\t}\n}\n","export const uuid4 = function (): string {\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n\t\tconst r = (Math.random() * 16) | 0,\n\t\t\tv = c == \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n};\n","import { Polygon } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Adapted from Turf.js 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 { Polygon } from \"geojson\";\nimport { polygonAreaSquareMeters } from \"../geometry/measure/area\";\n\nexport const ValidateMinSizeSquareMeters = (\n\tpolygon: Polygon,\n\tminSize: number,\n): boolean => {\n\treturn polygonAreaSquareMeters(polygon) > minSize;\n};\n","import { TerraDrawGoogleMapsAdapter } from \"./adapters/google-maps.adapter\";\nimport { TerraDrawLeafletAdapter } from \"./adapters/leaflet.adapter\";\nimport { TerraDrawMapboxGLAdapter } from \"./adapters/mapbox-gl.adapter\";\nimport { TerraDrawMapLibreGLAdapter } from \"./adapters/maplibre-gl.adapter\";\nimport { TerraDrawOpenLayersAdapter } from \"./adapters/openlayers.adapter\";\nimport { TerraDrawArcGISMapsSDKAdapter } from \"./adapters/arcgis-maps-sdk.adapter\";\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} from \"./common\";\nimport { TerraDrawBaseAdapter } from \"./adapters/common/base.adapter\";\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 { TerraDrawGreatCircleMode } from \"./modes/greatcircle/great-circle.mode\";\nimport { TerraDrawLineStringMode } from \"./modes/linestring/linestring.mode\";\nimport { TerraDrawPointMode } from \"./modes/point/point.mode\";\nimport { TerraDrawPolygonMode } from \"./modes/polygon/polygon.mode\";\nimport { TerraDrawRectangleMode } from \"./modes/rectangle/rectangle.mode\";\nimport { TerraDrawRenderMode } from \"./modes/render/render.mode\";\nimport { TerraDrawSelectMode } from \"./modes/select/select.mode\";\nimport { TerraDrawStaticMode } from \"./modes/static/static.mode\";\nimport {\n\tBBoxPolygon,\n\tFeatureId,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tIdStrategy,\n\tStoreChangeHandler,\n} from \"./store/store\";\nimport { BehaviorConfig } from \"./modes/base.behavior\";\nimport { pixelDistance } from \"./geometry/measure/pixel-distance\";\nimport { pixelDistanceToLine } from \"./geometry/measure/pixel-distance-to-line\";\nimport { Position } from \"geojson\";\nimport { pointInPolygon } from \"./geometry/boolean/point-in-polygon\";\nimport { createBBoxFromPoint } from \"./geometry/shape/create-bbox\";\nimport { ValidateMinSizeSquareMeters } from \"./validations/min-size.validation\";\nimport { ValidateMaxSizeSquareMeters } from \"./validations/max-size.validation\";\n\ntype FinishListener = (ids: FeatureId) => void;\ntype ChangeListener = (ids: FeatureId[], type: string) => void;\ntype SelectListener = (id: FeatureId) => void;\ntype DeselectListener = () => void;\n\ninterface TerraDrawEventListeners {\n\tready: () => void;\n\tfinish: FinishListener;\n\tchange: ChangeListener;\n\tselect: SelectListener;\n\tdeselect: DeselectListener;\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: GeoJSONStore;\n\tprivate _eventListeners: {\n\t\tready: (() => void)[];\n\t\tchange: ChangeListener[];\n\t\tfinish: FinishListener[];\n\t\tselect: SelectListener[];\n\t\tdeselect: DeselectListener[];\n\t};\n\t// This is the select mode that is assigned in the instance.\n\t// There can only be 1 select mode active per instance\n\tprivate _instanceSelectMode: undefined | string;\n\n\tconstructor(options: {\n\t\tadapter: TerraDrawAdapter;\n\t\tmodes: TerraDrawBaseDrawMode<any>[];\n\t\tidStrategy?: IdStrategy<FeatureId>;\n\t\ttracked?: boolean;\n\t}) {\n\t\tthis._adapter = options.adapter;\n\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// Ensure only one select mode can be present\n\t\tmodeKeys.forEach((mode) => {\n\t\t\tif (modesMap[mode].type !== ModeTypes.Select) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this._instanceSelectMode) {\n\t\t\t\tthrow new Error(\"only one type of select mode can be provided\");\n\t\t\t} else {\n\t\t\t\tthis._instanceSelectMode = mode;\n\t\t\t}\n\t\t});\n\n\t\tthis._modes = { ...modesMap, static: this._mode };\n\t\tthis._eventListeners = {\n\t\t\tchange: [],\n\t\t\tselect: [],\n\t\t\tdeselect: [],\n\t\t\tfinish: [],\n\t\t\tready: [],\n\t\t};\n\t\tthis._store = new GeoJSONStore<FeatureId>({\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) => {\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);\n\t\t\t});\n\t\t};\n\n\t\tconst onChange: StoreChangeHandler = (ids, event) => {\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);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged(ids);\n\n\t\t\tif (event === \"create\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: changed,\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: [],\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"update\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"delete\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: ids, unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"styling\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onSelect = (selectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.select.forEach((listener) => {\n\t\t\t\tlistener(selectedId);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([selectedId]);\n\n\t\t\tthis._adapter.render(\n\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: changed },\n\t\t\t\tthis.getModeStyles(),\n\t\t\t);\n\t\t};\n\n\t\tconst onDeselect = (deselectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.deselect.forEach((listener) => {\n\t\t\t\tlistener();\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([deselectedId]);\n\n\t\t\t// onDeselect can be called after a delete call which means that\n\t\t\t// you are deselecting a feature that has been deleted. We\n\t\t\t// double check here to ensure that the feature still exists.\n\t\t\tif (changed) {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\t// Register stores and callbacks\n\t\tObject.keys(this._modes).forEach((modeId) => {\n\t\t\tthis._modes[modeId].register({\n\t\t\t\tmode: modeId,\n\t\t\t\tstore: this._store,\n\t\t\t\tsetCursor: this._adapter.setCursor.bind(this._adapter),\n\t\t\t\tproject: this._adapter.project.bind(this._adapter),\n\t\t\t\tunproject: this._adapter.unproject.bind(this._adapter),\n\t\t\t\tsetDoubleClickToZoom: this._adapter.setDoubleClickToZoom.bind(\n\t\t\t\t\tthis._adapter,\n\t\t\t\t),\n\t\t\t\tonChange: onChange,\n\t\t\t\tonSelect: onSelect,\n\t\t\t\tonDeselect: onDeselect,\n\t\t\t\tonFinish: onFinish,\n\t\t\t\tcoordinatePrecision: this._adapter.getCoordinatePrecision(),\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate checkEnabled() {\n\t\tif (!this._enabled) {\n\t\t\tthrow new Error(\"Terra Draw is not enabled\");\n\t\t}\n\t}\n\n\tprivate getModeStyles() {\n\t\tconst modeStyles: {\n\t\t\t[key: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n\t\t} = {};\n\n\t\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\tthis._instanceSelectMode &&\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTED]\n\t\t\t\t) {\n\t\t\t\t\treturn this._modes[this._instanceSelectMode].styleFeature.bind(\n\t\t\t\t\t\tthis._modes[this._instanceSelectMode],\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?: { pointerDistance: number; ignoreSelectFeatures: boolean },\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 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\t// TODO: This is designed to work in a similar way as FeatureAtPointerEvent\n\t\t// perhaps at some point we could figure out how to unify them\n\t\treturn features.filter((feature) => {\n\t\t\tif (\n\t\t\t\tignoreSelectFeatures &&\n\t\t\t\t(feature.properties[SELECT_PROPERTIES.MID_POINT] ||\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTION_POINT])\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\tconst pointCoordinates = feature.geometry.coordinates;\n\t\t\t\tconst pointXY = project(pointCoordinates[0], pointCoordinates[1]);\n\t\t\t\tconst distance = pixelDistance(inputPoint, pointXY);\n\t\t\t\treturn distance < pointerDistance;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tconst coordinates: Position[] = feature.geometry.coordinates;\n\n\t\t\t\tfor (let i = 0; i < coordinates.length - 1; i++) {\n\t\t\t\t\tconst coord = coordinates[i];\n\t\t\t\t\tconst nextCoord = coordinates[i + 1];\n\t\t\t\t\tconst distanceToLine = pixelDistanceToLine(\n\t\t\t\t\t\tinputPoint,\n\t\t\t\t\t\tproject(coord[0], coord[1]),\n\t\t\t\t\t\tproject(nextCoord[0], nextCoord[1]),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (distanceToLine < pointerDistance) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tconst lngLatInsidePolygon = pointInPolygon(\n\t\t\t\t\t[lng, lat],\n\t\t\t\t\tfeature.geometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\tif (lngLatInsidePolygon) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate getSelectMode() {\n\t\tthis.checkEnabled();\n\n\t\tif (!this._instanceSelectMode) {\n\t\t\tthrow new Error(\"No select mode defined in instance\");\n\t\t}\n\n\t\tconst currentMode = this.getMode();\n\n\t\t// If we're not already in the select mode, we switch to it\n\t\tif (currentMode !== this._instanceSelectMode) {\n\t\t\tthis.setMode(this._instanceSelectMode);\n\t\t}\n\n\t\tconst selectMode = this._modes[\n\t\t\tthis._instanceSelectMode\n\t\t] as TerraDrawBaseSelectMode<any>;\n\n\t\treturn selectMode;\n\t}\n\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\t * @alpha\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 * Allows the user to get a snapshot (copy) of all given features\n\t *\n\t * @returns An array of all given Feature Geometries in the instances store\n\t *\n\t * @alpha\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 * Removes all data from the current store and removes any rendered layers\n\t * via the registering the adapter.\n\t *\n\t * @alpha\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 * @alpha\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\t * @alpha\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 *\n\t * @return the current mode name\n\t *\n\t * @alpha\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 * 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\t * @alpha\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\t * @alpha\n\t */\n\tremoveFeatures(ids: FeatureId[]) {\n\t\tthis.checkEnabled();\n\t\tthis._store.delete(ids);\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 the select mode, it will switch to it.\n\t * @param id - the id of the feature to select\n\t * @alpha\n\t */\n\tselectFeature(id: FeatureId) {\n\t\tconst selectMdode = this.getSelectMode();\n\t\tselectMdode.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 the select mode, it will switch to it.\n\t * @param id  - the id of the feature to deselect\n\t * @alpha\n\t */\n\tdeselectFeature(id: FeatureId) {\n\t\tconst selectMode = this.getSelectMode();\n\t\tselectMode.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 * @alpha\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\t * @alpha\n\t */\n\thasFeature(id: FeatureId): boolean {\n\t\treturn this._store.has(id);\n\t}\n\n\t/**\n\t * A method for adding features to the store. This method will validate the features.\n\t * Features must match one of the modes enabled in the instance.\n\t * @param mode\n\t * @param features\n\t * @returns\n\t *\n\t * @alpha\n\t */\n\taddFeatures(features: GeoJSONStoreFeatures[]) {\n\t\tthis.checkEnabled();\n\n\t\tif (features.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._store.load(features, (feature) => {\n\t\t\tconst hasModeProperty = Boolean(\n\t\t\t\tfeature &&\n\t\t\t\t\ttypeof feature === \"object\" &&\n\t\t\t\t\t\"properties\" in feature &&\n\t\t\t\t\ttypeof feature.properties === \"object\" &&\n\t\t\t\t\tfeature.properties !== null &&\n\t\t\t\t\t\"mode\" in feature.properties,\n\t\t\t);\n\n\t\t\tif (hasModeProperty) {\n\t\t\t\tconst modeToAddTo =\n\t\t\t\t\tthis._modes[\n\t\t\t\t\t\t(feature as { properties: { mode: string } }).properties.mode\n\t\t\t\t\t];\n\n\t\t\t\t// if the mode does not exist, we return false\n\t\t\t\tif (!modeToAddTo) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// use the inbuilt validation of the mode\n\t\t\t\tconst validation = modeToAddTo.validateFeature.bind(modeToAddTo);\n\t\t\t\treturn validation(feature);\n\t\t\t}\n\n\t\t\t// If the feature does not have a mode property, we return false\n\t\t\treturn false;\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\t * @alpha\n\t */\n\tstart() {\n\t\tthis._enabled = true;\n\t\tthis._adapter.register({\n\t\t\tonReady: () => {\n\t\t\t\tthis._eventListeners.ready.forEach((listener) => {\n\t\t\t\t\tlistener();\n\t\t\t\t});\n\t\t\t},\n\t\t\tgetState: () => {\n\t\t\t\treturn this._mode.state;\n\t\t\t},\n\t\t\tonClick: (event) => {\n\t\t\t\tthis._mode.onClick(event);\n\t\t\t},\n\t\t\tonMouseMove: (event) => {\n\t\t\t\tthis._mode.onMouseMove(event);\n\t\t\t},\n\t\t\tonKeyDown: (event) => {\n\t\t\t\tthis._mode.onKeyDown(event);\n\t\t\t},\n\t\t\tonKeyUp: (event) => {\n\t\t\t\tthis._mode.onKeyUp(event);\n\t\t\t},\n\t\t\tonDragStart: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragStart(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDrag: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDrag(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDragEnd: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragEnd(event, setMapDraggability);\n\t\t\t},\n\t\t\tonClear: () => {\n\t\t\t\t// Ensure that the mode resets its state\n\t\t\t\t// as it may be storing feature ids internally in it's instance\n\t\t\t\tthis._mode.cleanUp();\n\n\t\t\t\t// Remove all features from the store\n\t\t\t\tthis._store.clear();\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Gets the features at a given longitude and latitude.\n\t * Will return point and linestrings that are a given pixel distance\n\t * away from the lng/lat and any polygons which contain it.\n\t *\n\t * @alpha\n\t */\n\tgetFeaturesAtLngLat(\n\t\tlngLat: { lng: number; lat: number },\n\t\toptions?: { pointerDistance: number; ignoreSelectFeatures: boolean },\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\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\t * @alpha\n\t */\n\tgetFeaturesAtPointerEvent(\n\t\tevent: PointerEvent | MouseEvent,\n\t\toptions?: { pointerDistance: number; ignoreSelectFeatures: boolean },\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\t * @alpha\n\t */\n\tstop() {\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 * @alpha\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 * @alpha\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\n// This object allows 3rd party developers to\n// extend these abstract classes and create there\n// own modes and adapters\nconst TerraDrawExtend = {\n\tTerraDrawBaseDrawMode,\n\tTerraDrawBaseAdapter,\n};\n\nexport {\n\tTerraDraw,\n\tTerraDrawSelectMode,\n\tTerraDrawPointMode,\n\tTerraDrawLineStringMode,\n\tTerraDrawGreatCircleMode,\n\tTerraDrawPolygonMode,\n\tTerraDrawCircleMode,\n\tTerraDrawFreehandMode,\n\tTerraDrawRenderMode,\n\tTerraDrawRectangleMode,\n\tTerraDrawGoogleMapsAdapter,\n\tTerraDrawMapboxGLAdapter,\n\tTerraDrawLeafletAdapter,\n\tTerraDrawMapLibreGLAdapter,\n\tTerraDrawOpenLayersAdapter,\n\tTerraDrawArcGISMapsSDKAdapter,\n\tTerraDrawExtend,\n\n\t// Types that are required for 3rd party developers to extend\n\n\t// TerraDrawBaseMode\n\tBehaviorConfig,\n\tGeoJSONStoreFeatures,\n\tHexColor,\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\n\t// TerraDrawBaseAdapter\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n\tProject,\n\tUnproject,\n\tSetCursor,\n\tGetLngLatFromEvent,\n\n\t// Validations\n\tValidateMinSizeSquareMeters,\n\tValidateMaxSizeSquareMeters,\n};\n","import { Polygon } from \"geojson\";\nimport { polygonAreaSquareMeters } from \"../geometry/measure/area\";\n\nexport const ValidateMaxSizeSquareMeters = (\n\tpolygon: Polygon,\n\tminSize: number,\n): boolean => {\n\treturn polygonAreaSquareMeters(polygon) < minSize;\n};\n"],"names":["limitPrecision","num","decimalLimit","decimals","Math","pow","round","pixelDistance","pointOne","pointTwo","y","x","sqrt","AdapterListener","_ref","_this","this","name","callback","unregister","register","registered","TerraDrawBaseAdapter","config","_minPixelDragDistance","_minPixelDragDistanceDrawing","_minPixelDragDistanceSelecting","_lastDrawEvent","_coordinatePrecision","_heldKeys","Set","_listeners","_dragState","_currentModeCallbacks","minPixelDragDistance","minPixelDragDistanceSelecting","minPixelDragDistanceDrawing","coordinatePrecision","_proto","prototype","getButton","event","button","getMapElementXYPosition","_mapElement$getBoundi","getMapEventElement","getBoundingClientRect","containerX","clientX","left","containerY","clientY","top","getDrawEventFromEvent","latLng","getLngLatFromEvent","lng","lat","_this$getMapElementXY","heldKeys","Array","from","callbacks","getAdapterListeners","forEach","listener","getCoordinatePrecision","isPrimary","drawEvent","addEventListener","removeEventListener","preventDefault","onMouseMove","lastEventXY","currentEventXY","modeState","getState","pixelDistanceToCheck","onDragStart","enabled","setDraggability","bind","onDrag","target","onDragEnd","onClick","key","onKeyUp","add","onKeyDown","clear","TerraDrawGoogleMapsAdapter","_TerraDrawBaseAdapter","call","_cursor","_cursorStyleSheet","_lib","_map","_overlay","_clickEventListener","_mouseMoveEventListener","renderedFeatureIds","lib","map","getDiv","id","Error","_inheritsLoose","circlePath","cx","cy","r","d","_this2","OverlayView","draw","onAdd","onReady","setMap","data","addListener","clickListener","find","mouseMoveListener","_ref2","_this$_clickEventList","_this$_mouseMoveEvent","_this$_overlay","remove","undefined","bounds","getBounds","ne","getNorthEast","sw","getSouthWest","latLngBounds","LatLngBounds","mapCanvas","offsetX","offsetY","screenCoord","Point","projection","getProjection","fromContainerPixelToLatLng","contains","querySelector","project","point","fromLatLngToContainerPixel","LatLng","unproject","setCursor","cursor","div","styleDiv","document","classList","style","createElement","innerHTML","getElementsByTagName","appendChild","setDoubleClickToZoom","setOptions","disableDoubleClickZoom","draggable","render","changes","styling","_this3","_layers","deletedIds","deletedId","featureToDelete","getFeatureById","updated","updatedFeature","featureToUpdate","forEachProperty","property","setProperty","Object","keys","properties","geometry","type","coordinates","setGeometry","Data","path","i","length","coordinate","push","LineString","paths","j","Polygon","created","createdFeature","addGeoJson","feature","featureCollection","features","concat","setStyle","mode","getProperty","gmGeometry","getGeometry","getType","value","calculatedStyles","clickable","icon","pointWidth","fillColor","pointColor","fillOpacity","strokeColor","pointOutlineColor","strokeWeight","pointOutlineWidth","rotation","scale","lineStringColor","lineStringWidth","polygonOutlineColor","polygonOutlineWidth","polygonFillOpacity","polygonFillColor","clearLayers","_this4","getId","has","onClear","_createClass","get","_this$renderedFeature","Boolean","size","TerraDrawLeafletAdapter","_panes","_container","getContainer","createPaneStyleSheet","pane","zIndex","createPane","clearPanes","values","layer","removeLayer","styleGeoJSONLayer","pointToLayer","latlng","featureStyles","modeStyle","paneId","String","circleMarker","radius","stroke","color","weight","interactive","_feature","isNaN","containerPointToLatLng","dragging","enable","disable","_this$_map$latLngToCo","latLngToContainerPoint","_this$_map$containerP","removeProperty","doubleClickZoom","geoJSON","addLayer","deleted","TerraDrawMapboxGLAdapter","_nextRender","_rendered","changedIds","deletion","points","linestrings","polygons","geometryKey","toLowerCase","removeSource","cancelAnimationFrame","_addGeoJSONSource","addSource","tolerance","_addFillLayer","source","paint","_addFillOutlineLayer","beneath","moveLayer","_addLineLayer","_addPointLayer","_addLayer","featureType","_addGeoJSONLayer","_setGeoJSONLayerData","getSource","setData","getEmptyGeometries","updateChangedIds","_this$_container$getB","getCanvas","dragRotate","dragPan","_this$_map$project","_this$_map$unproject","canvas","requestAnimationFrame","unchanged","geometryFeatures","_loop","styles","pointId","forceUpdate","updateLineStrings","updatedPolygon","TerraDrawMapLibreGLAdapter","mapboxglAdapter","abstract","uidCounter_","toSize","dest","isArray","ImageStyle","constructor","options","opacity_","opacity","rotateWithView_","rotateWithView","rotation_","scale_","scaleArray_","displacement_","displacement","declutterMode_","declutterMode","clone","getScale","getOpacity","slice","getRotation","getRotateWithView","getDisplacement","getDeclutterMode","getScaleArray","getAnchor","getImage","pixelRatio","getHitDetectionImage","getPixelRatio","getImageState","getImageSize","getOrigin","getSize","setDisplacement","setOpacity","setRotateWithView","setRotation","setScale","listenImageChange","load","unlistenImageChange","ImageStyle$1","messages","AssertionError","code","message","super","AssertionError$1","clamp","min","max","HEX_COLOR_RE_","NAMED_COLOR_RE_","fromString","cache","cacheSize","s","hasOwnProperty","g","b","a","exec","el","body","rgb","getComputedStyle","removeChild","fromNamed","n","hasAlpha","parseInt","substr","startsWith","split","Number","normalize","assertion","errorCode","assert","fromStringInternal_","asColorLike","toString","ua","navigator","userAgent","includes","test","WORKER_OFFSCREEN_CANVAS","WorkerGlobalScope","OffscreenCanvas","self","createCanvasContext2D","width","height","canvasPool","settings","shift","getContext","passive","defineProperty","window","error","Event","defaultPrevented","stopPropagation","propagationStopped","Disposable$1","disposed","dispose","disposeInternal","VOID","object","EventTarget","Disposable","eventTarget_","pendingRemovals_","dispatching_","listeners_","listeners","listenersForType","dispatchEvent","isString","evt","dispatching","pendingRemovals","propagate","ii","handleEvent","pr","getListeners","hasListener","index","indexOf","splice","listen","thisArg","once","originalListener","apply","arguments","eventsKey","listenOnce","unlistenByKey","Observable$1","on","un","revision_","changed","getRevision","onInternal","len","onceInternal","ol_key","unInternal","unByKey","ObjectEvent","oldValue","defaultFillStyle","defaultLineJoin","Observable","ol_uid","values_","setProperties","getKeys","getProperties","assign","hasProperties","notify","eventType","addChangeListener","removeChangeListener","set","silent","applyProperties","unset","isEmpty","RegularShape","canvas_","hitDetectionCanvas_","fill_","fill","origin_","points_","radius_","radius1","radius2_","radius2","angle_","angle","stroke_","size_","renderOptions_","getFill","getPoints","getRadius","getRadius2","getAngle","getStroke","setFill","createHitDetectionCanvas_","image","renderOptions","context","draw_","setStroke","calculateLineJoinSize_","lineJoin","strokeWidth","miterLimit","Infinity","r1","r2","tmp","alpha","PI","sin","e","miterRatio","k","l","bevelAdd","aa","dd","innerMiterRatio","createRenderOptions","strokeStyle","lineDash","lineDashOffset","getColor","getWidth","getLineDash","getLineDashOffset","getLineJoin","getMiterLimit","maxRadius","ceil","translate","createPath_","fillStyle","lineWidth","setLineDash","asArray","drawHitDetectionCanvas_","arc","startAngle","step","angle0","radiusC","lineTo","cos","closePath","RegularShape$1","CircleStyle","setRadius","Circle","Fill","color_","setColor","Fill$1","Stroke","lineCap_","lineCap","lineDash_","lineDashOffset_","lineJoin_","miterLimit_","width_","getLineCap","setLineCap","setLineDashOffset","setLineJoin","setMiterLimit","setWidth","Stroke$1","Style","geometry_","geometryFunction_","defaultGeometryFunction","image_","renderer_","renderer","hitDetectionRenderer_","hitDetectionRenderer","text_","text","zIndex_","getRenderer","getText","getZIndex","setRenderer","setHitDetectionRenderer","getHitDetectionRenderer","getGeometryFunction","setImage","setText","setZIndex","Style$1","METERS_PER_UNIT","radians","degrees","ft","m","Projection$1","code_","units_","extent_","extent","worldExtent_","worldExtent","axisOrientation_","axisOrientation","global_","global","canWrapX_","getPointResolutionFunc_","getPointResolution","defaultTileGrid_","metersPerUnit_","metersPerUnit","canWrapX","getCode","getExtent","getUnits","getMetersPerUnit","getWorldExtent","getAxisOrientation","isGlobal","setGlobal","getDefaultTileGrid","setDefaultTileGrid","tileGrid","setExtent","setWorldExtent","setGetPointResolution","func","getPointResolutionFunc","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","MAX_SAFE_Y","log","tan","EPSG3857Projection","Projection","units","resolution","cosh","PROJECTIONS","EPSG4326Projection","transforms","destination","transformFn","sourceCode","destinationCode","cloneTransform","input","output","dimension","identityTransform","addProjection","addProj","addTransformFunc","projectionLike","replace","addEquivalentProjections","projections","addProjections","transform","transformFunc","sourceProjection","destinationProjection","getTransformFunc","getTransformFromProjections","getTransform","projections2","forwardTransform","inverseTransform","EPSG3857_PROJECTIONS","EPSG4326_PROJECTIONS","atan","exp","projection1","projection2","ModeTypes","TerraDrawOpenLayersAdapter","stylingFunction","_projection","_vectorSource","_geoJSONReader","GeoJSON","getViewport","setAttribute","vectorSource","VectorSource","vectorLayer","VectorLayer","getStyles","hexToRGB","hex","_this2$hexToRGB","addFeature","olFeature","readFeature","featureProjection","removeFeature","_","canvases","querySelectorAll","getInteractions","interaction","setActive","_this$_map$getPixelFr","getPixelFromCoordinate","_toLonLat","lonLat","lon","modulo","toLonLat","getCoordinateFromPixel","TerraDrawArcGISMapsSDKAdapter","_mapView","_featureIdAttributeName","_featureLayerName","_featureLayer","_dragEnabled","_zoomEnabled","_dragHandler","_doubleClickHandler","container","GraphicsLayer","longitude","latitude","_this$_mapView$toScre","toScreen","_this$_mapView$toMap","toMap","removeFeatureById","graphics","removeAll","attributes","_attributes","_feature$geometry","symbol","SimpleMarkerSymbol","getColorFromHex","outline","Polyline","SimpleLineSymbol","rings","SimpleFillSymbol","graphic","Graphic","hexColor","Color","fromHex","SELECT_PROPERTIES","POLYGON_PROPERTIES","isObject","isValidTimestamp","timestamp","Date","valueOf","dateIsValid","TerraDrawBaseDrawMode","_state","_styles","behaviors","pointerDistance","onStyleChange","store","Drawing","_extends","registerBehaviors","behaviorConfig","setDrawing","setStarted","setStopped","registerOnChange","onChange","onSelect","onDeselect","onFinish","validateFeature","isValidId","isValidStoreFeature","idStrategy","finishedId","deselectedId","selectedId","setMapDraggability","getHexColorStylingValue","defaultValue","getStylingValue","getNumericStylingValue","TerraDrawBaseSelectMode","_TerraDrawBaseDrawMod","_len","args","_key","Select","haversineDistanceKilometers","toRadians","latOrLng","phiOne","lambdaOne","phiTwo","deltaPhi","deltalambda","atan2","earthRadius","degreesToRadians","radiansToDegrees","circle","center","radiusKilometers","steps","circleCoordinate","distance","bearing","longitude1","origin","latitude1","bearingRad","lengthToRadians","latitude2","asin","selfIntersects","coord","epsilon","ring0","edge0","ring1","edge1","ifInteresctionAddToOutput","isOutside","frac","frac1","start0","end0","start1","end1","intersection","equalArrays","x0","y0","x1","y1","x2","y2","x3","y3","denom","intersect","array1","array2","coordinateIsValid","getDecimalPlaces","current","precision","isValidPolygonFeature","every","coordinateOne","coordinateTwo","isValidNonIntersectingPolygonFeature","TerraDrawCircleMode","_options$minimumRadiu","clickCount","currentCircleId","keyEvents","cursors","minimumRadiusKilometers","defaultCursors","start","cancel","finish","defaultKeyEvents","close","state","stop","cleanUp","startingCircle","_this$store$create","create","createCircle","styleFeature","getDefaultStyling","outlineColor","outlineWidth","distanceKm","newRadius","updatedCircle","updateGeometry","updateProperty","TerraDrawFreehandMode","startingClick","currentId","closingPointId","minDistance","preventPointsNearClose","currentLineGeometry","getGeometryCopy","_currentLineGeometry$","_this$project","_currentLineGeometry$2","_this$project2","pop","closingPointWidth","closingPointColor","closingPointOutlineColor","closingPointOutlineWidth","D2R","R2D","ArcLineString","coords","moveTo","Arc","geometries","toJSON","GreatCircleLine","end","w","z","_proto3","interpolate","f","A","B","numberOfPoints","firstPass","delta","pair","bHasBigDiff","dfMaxSmallDiffLong","dfDateLineOffset","offset","dfLeftBorderX","dfRightBorderX","dfDiffSpace","dfPrevX","dfX","dfDiffLong","abs","poMulti","poNewLS","dfX0","dfX1","dfY1","dfX2","dfY2","tmpX","tmpY","dfRatio","dfY","poNewLS0","line","j0","TerraDrawModeBehavior","GreatCircleSnappingBehavior","_TerraDrawModeBehavio","clickBoundingBox","getSnappableCoordinate","currentFeatureId","getSnappableEnds","filter","bbox","search","closest","minDist","dist","measure","endDist","PixelDistanceBehavior","clickEvent","secondCoordinate","createBBoxFromPoint","halfDist","c","ClickBoundingBoxBehavior","TerraDrawGreatCircleMode","currentCoordinate","snappingEnabled","snapping","updatedCoord","greatCircle","opts","_opts$properties","_opts$numberOfPoints","_opts$offset","_opts$coordinatePreci","greatCircleLine","_this$store$create2","SnappingBehavior","getSnappableCoordinateFirstClick","getSnappable","TerraDrawLineStringMode","allowSelfIntersections","mouseMove","newLineString","isValidPoint","TerraDrawPointMode","coordinatesIdentical","ClosingPointsBehavior","_startEndPoints","selectedCoords","_properties","_properties2","ids","update","updatedCoordinates","isClosingPoint","opening","closing","distancePrevious","isClosing","isPreviousClosing","TerraDrawPolygonMode","closingPoints","currentPolygonCoordinates","closestCoord","_this$closingPoints$i","currentPolygonGeometry","_this$closingPoints$i2","TerraDrawRectangleMode","currentRectangleId","updateRectangle","firstCoord","TerraDrawRenderMode","Render","modeName","isValidLineStringFeature","midpointCoordinate","coordinates1","coordinates2","projectedCoordinateOne","projectedCoordinateTwo","_unproject","getMidPointCoordinates","featureCoords","midPointCoords","mid","MidPointBehavior","selectionPointBehavior","_midPoints","insert","midPointId","midPoint","_this$store$getProper","getPropertiesCopy","midPointFeatureId","midPointSegment","featureId","getMidPoints","getUpdated","updatedMidPointCoord","SelectionPointBehavior","_selectionPoints","featureMode","geometryType","selectionPoints","getCoordinatesAsPoints","selectionPoint","selectionPointFeatureId","getOneUpdated","updatedCoordinate","pointInPolygon","p","p1","p2","inside","ring","len2","pixelDistanceToLine","linePointOne","linePointTwo","square","dist2","v","l2","t","distToSegmentSquared","FeatureAtPointerEventBehavior","createClickBoundingBox","hasSelection","clickedFeature","clickedFeatureDistance","clickedMidPoint","clickedMidPointDistance","nextCoord","distanceToLine","DragFeatureBehavior","featuresAtMouseEvent","midPoints","draggedFeatureId","dragPosition","startDragging","stopDragging","isDragging","canDrag","drag","mouseCoord","updatedCoords","upToCoord","updatedLng","updatedLat","updatedSelectionPoints","updatedMidPoints","DragCoordinateBehavior","draggedCoordinate","getClosestCoordinate","geomCoordinates","closestCoordinate","isFirstOrLastPolygonCoord","getDraggableIndex","allowSelfIntersection","lastCoordIndex","updatedSelectionPoint","centroid","geojson","xSum","ySum","rhumbBearing","to","phi1","phi2","deltaLambda","deltaPsi","bear360","rhumbDestination","distanceMeters","distanceInMeters","lambda1","theta","DeltaPhi","DeltaPsi","q","rhumbDistance","R","DeltaLambda","RotateFeatureBehavior","lastBearing","reset","rotate","pivot","pointCoords","finalAngle","newCoords","transformRotate","ScaleFeatureBehavior","lastDistance","factor","axis","originalDistance","newCoord","transformScale","RADIANS_TO_DEGREES","DEGREES_TO_RADIANS","lngLatToWebMercatorXY","webMercatorCenter","ext","result","_lngLatToWebMercatorX","DragCoordinateResizeBehavior","minimumScale","boundingBoxMaps","opposite","isValidDragWebMercator","distanceX","distanceY","getSelectedFeatureDataWebMercator","getFeature","getNormalisedCoordinates","boundingBox","getBBoxWebMercator","selectedCoordinate","centerWebMercatorDrag","featureData","webMercatorOrigin","webMercatorSelected","closestBBoxIndex","getIndexesWebMercator","webMercatorCursor","scaleWebMercator","centerFixedWebMercatorDrag","scaleFixedWebMercator","performWebMercatorScale","oppositeFixedWebMercatorDrag","_this$getIndexesWebMe3","oppositeBboxIndex","oppositeWebMercatorDrag","_this$getIndexesWebMe4","cursorDistanceX","cursorDistanceY","xScale","yScale","validateScale","validX","MAX_SAFE_INTEGER","validY","originX","originY","_webMercatorXYToLngLa","_lngLatToWebMercatorX2","_ref3","west","south","east","north","selectedXY","closestIndex","closestDistance","resizeOption","updatedGeometry","TerraDrawSelectMode","_TerraDrawBaseSelectM","_options$allowManualD","allowManualDeselection","dragEventThrottle","dragEventCount","selected","flags","dragFeature","dragCoordinate","rotateFeature","scaleFeature","dragCoordinateResizeFeature","validations","pointerOver","dragStart","dragEnd","insertMidpoint","deselect","delete","validation","selectFeature","select","setSelecting","deselectFeature","updateSelectedFeatures","deleteSelected","onRightClick","clickedSelectionPointProps","coordinateIndex","modeFlags","deletable","midpoints","fromCursor","previouslySelectedId","_this$store$getGeomet","onLeftClick","_this$featuresAtMouse","canScale","canRotate","preventDefaultKeyEvent","isRotationKeys","isScaleKeys","_this$flags$this$stor","_this$flags$this$stor2","draggableMod","resizable","draggableCoordinateIndex","canSelfIntersect","selfIntersectable","rotateable","scaleable","nearbyMidPoint","nearbySelectionPoint","featureUnderPointer","selectionPointColor","selectionPointOutlineColor","selectionPointWidth","selectionPointOutlineWidth","midPointColor","midPointOutlineColor","midPointWidth","midPointOutlineWidth","selectedPolygonColor","selectedPolygonOutlineWidth","selectedPolygonOutlineColor","selectedPolygonFillOpacity","selectedLineStringColor","selectedLineStringWidth","selectedPointWidth","selectedPointColor","selectedPointOutlineColor","selectedPointOutlineWidth","TerraDrawStaticMode","Static","quickselect","arr","right","compare","sd","floor","swap","calcBBox","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","child","extend","leaf","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","intersects","multiSelect","stack","RBush","maxEntries","_maxEntries","_minEntries","nodesToSearch","childBBox","_all","collides","_build","_splitRoot","tmpNode","_insert","item","parent","indexes","goingUp","_condense","compareMinX","compareMinY","items","N","M","N2","N1","right2","right3","_chooseSubtree","level","minArea","minEnlargement","targetNode","area","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","seenIds","defaultIdStrategy","random","GeoJSONStore","tracked","spatialIndex","_onChange","obj","JSON","parse","stringify","featureValidation","clonedData","createdAt","updatedAt","change","propertiesToUpdate","geometriesToUpdate","_this5","createdProperties","_this6","copyAll","_this7","polygonAreaSquareMeters","polygon","total","ringArea","FACTOR","PI_OVER_180","coordsLength","TerraDrawExtend","TerraDraw","_modes","_mode","_adapter","_enabled","_store","_eventListeners","_instanceSelectMode","adapter","duplicateModeTracker","modesMap","modes","reduce","modeMap","currentMode","modeKeys","static","ready","getChanged","_getChanged","getModeStyles","_getChanged2","_getChanged3","modeId","checkEnabled","modeStyles","featuresAtLocation","ignoreSelectFeatures","inputPoint","pointCoordinates","pointXY","getSelectMode","getMode","setMode","setModeStyles","getSnapshot","removeFeatures","getFeatureId","hasFeature","addFeatures","modeToAddTo","getFeaturesAtLngLat","lngLat","getFeaturesAtPointerEvent","off","minSize"],"mappings":"o/BAAgBA,EAAeC,EAAaC,YAAAA,IAAAA,EAAe,GAC1D,IAAMC,EAAWC,KAAKC,IAAI,GAAIH,GAC9B,OAAOE,KAAKE,MAAML,EAAME,GAAYA,CACrC,CCHa,IAAAI,EAAgB,SAC5BC,EACAC,GAEA,IAEMC,EADmBD,EAAjBE,EADiBH,EAAjBG,EAGFA,EAFmBF,EAAVC,EADUF,EAAVE,EAIf,OAAON,KAAKQ,KAAKD,EAAIA,EAAID,EAAIA,EAC9B,ECTaG,EAgBZ,SAAAC,GAUC,IAAAC,EAAAC,KATAC,EAAIH,EAAJG,KACAC,EAAQJ,EAARI,SACAC,EAAUL,EAAVK,WACAC,EAAQN,EAARM,SAnBMH,KAAAA,UACAC,EAAAA,KAAAA,cACAG,EAAAA,KAAAA,YAAa,EAAKL,KAClBI,cAAQ,EAAAJ,KACRG,gBAAU,EAsBhBH,KAAKC,KAAOA,EAGZD,KAAKI,SAAW,WACVL,EAAKM,aACTN,EAAKM,YAAa,EAClBD,EAASF,GAEX,EAGAF,KAAKG,WAAa,WACbJ,EAAKK,WACRL,EAAKM,YAAa,EAClBF,EAAWD,GAEb,EAEAF,KAAKE,SAAWA,CACjB,ECpBqBI,eAAoB,WACzC,SAAAA,EAAYC,GAAyBP,KAsB3BQ,2BACAC,EAAAA,KAAAA,yCACAC,oCAA8B,EAAAV,KAC9BW,oBACAC,EAAAA,KAAAA,iCACAC,UAAyB,IAAIC,SAC7BC,WAEJ,GACIC,KAAAA,WACT,oBACSC,2BAAqB,EAhC9BjB,KAAKQ,sBACmC,iBAAhCD,EAAOW,qBACXX,EAAOW,qBACP,EAEJlB,KAAKU,+BAC4C,iBAAzCH,EAAOY,8BACXZ,EAAOY,8BACP,EAEJnB,KAAKS,6BAC0C,iBAAvCF,EAAOa,4BACXb,EAAOa,4BACP,EAEJpB,KAAKY,qBACkC,iBAA/BL,EAAOc,oBACXd,EAAOc,oBACP,CACL,CAAC,IAAAC,EAAAhB,EAAAiB,iBAAAD,EAiBSE,UAAA,SAAUC,GACnB,OAAsB,IAAlBA,EAAMC,OACF,UACoB,IAAjBD,EAAMC,OACT,OACoB,IAAjBD,EAAMC,OACT,SACoB,IAAjBD,EAAMC,OACT,QAID,SACR,EAACJ,EAESK,wBAAA,SAAwBF,GACjC,IACAG,EADmB5B,KAAK6B,qBACSC,wBAEjC,MAAO,CACNC,WAAYN,EAAMO,QAHPJ,EAAJK,KAIPC,WAAYT,EAAMU,QAJFP,EAAHQ,IAMf,EAACd,EAESe,sBAAA,SACTZ,GAEA,IAAMa,EAAStC,KAAKuC,mBAAmBd,GAEvC,IAAKa,EACJ,OAAO,KAGR,IAAQE,EAAaF,EAAbE,IAAKC,EAAQH,EAARG,IACbC,EAAmC1C,KAAK2B,wBAAwBF,GAAxDM,EAAUW,EAAVX,WAAYG,EAAUQ,EAAVR,WACdR,EAAS1B,KAAKwB,UAAUC,GACxBkB,EAAWC,MAAMC,KAAK7C,KAAKa,WAEjC,MAAO,CACN2B,IAAKxD,EAAewD,EAAKxC,KAAKY,sBAC9B6B,IAAKzD,EAAeyD,EAAKzC,KAAKY,sBAC9BmB,WAAAA,EACAG,WAAAA,EACAR,OAAAA,EACAiB,SAAAA,EAEF,EAACrB,EAQMlB,SAAA,SAAS0C,GACf9C,KAAKiB,sBAAwB6B,EAE7B9C,KAAKe,WAAaf,KAAK+C,sBAEvB/C,KAAKe,WAAWiC,QAAQ,SAACC,GACxBA,EAAS7C,UACV,EACD,EAACkB,EAOM4B,uBAAA,WACN,YAAYtC,oBACb,EAACU,EAEOyB,oBAAA,WAAmBhD,IAAAA,OAC1B,MAAO,CACN,IAAIF,EAAqC,CACxCI,KAAM,cACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAKLQ,EAAM0B,UAAX,CAIA,IAAMC,EAAYrD,EAAKsC,sBAAsBZ,GACxC2B,IAILrD,EAAKiB,WAAa,eAKlBjB,EAAKY,eAAiByC,EAZtB,CAaD,EACAhD,SAAU,SAACF,GACVH,EAAK8B,qBAAqBwB,iBAAiB,cAAenD,EAC3D,EACAC,WAAY,SAACD,GACZH,EAAK8B,qBAAqByB,oBACzB,cACApD,EAEF,IAED,IAAIL,EAAqC,CACxCI,KAAM,cACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAGLQ,EAAM0B,UAAX,CAIA1B,EAAM8B,iBAEN,IAAMH,EAAYrD,EAAKsC,sBAAsBZ,GAC7C,GAAK2B,EAIL,GAAwB,iBAApBrD,EAAKiB,WAERjB,EAAKkB,sBAAsBuC,YAAYJ,GACvCrD,EAAKY,eAAiByC,OAChB,GAAwB,iBAApBrD,EAAKiB,WAA+B,CAE9C,IAAKjB,EAAKY,eACT,OAGD,IAAM8C,EAAc,CACnB9D,EAAGI,EAAKY,eAAeoB,WACvBrC,EAAGK,EAAKY,eAAeuB,YAElBwB,EAAiB,CACtB/D,EAAGyD,EAAUrB,WACbrC,EAAG0D,EAAUlB,YAMRyB,EAAY5D,EAAKkB,sBAAsB2C,WAEvCC,EAAuBtE,EAC5BkE,EACAC,GAwBD,GAlBkB,YAAdC,EAKFE,EAAuB9D,EAAKU,6BACL,cAAdkD,EAKTE,EAAuB9D,EAAKW,+BAGfmD,EAAuB9D,EAAKS,sBAK1C,OAGDT,EAAKiB,WAAa,WAClBjB,EAAKkB,sBAAsB6C,YAC1BV,EACA,SAACW,GACAhE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,EAEF,KAA+B,aAApBhE,EAAKiB,YACfjB,EAAKkB,sBAAsBiD,OAAOd,EAAW,SAACW,GAC7ChE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,EAzED,CA2ED,EACA3D,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,cAAenD,EAC5C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,cAAepD,EAC/C,IAED,IAAIL,EAAmC,CACtCI,KAAM,cACNC,SAAU,SAACuB,GACL1B,EAAKkB,uBAGVQ,EAAM8B,gBACP,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,cAAenD,EAC5C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,cAAepD,EAC/C,IAED,IAAIL,EAAqC,CACxCI,KAAM,YACNC,SAAU,SAACuB,GACV,GAAK1B,EAAKkB,uBAINQ,EAAM0C,SAAWpE,EAAK8B,sBAKrBJ,EAAM0B,UAAX,CAIA,IAAMC,EAAYrD,EAAKsC,sBAAsBZ,GAExC2B,IAImB,aAApBrD,EAAKiB,WACRjB,EAAKkB,sBAAsBmD,UAAUhB,EAAW,SAACW,GAChDhE,EAAKiE,gBAAgBC,KAAKlE,EAA1BA,CAAgCgE,EACjC,GAEoB,iBAApBhE,EAAKiB,YACe,iBAApBjB,EAAKiB,YAILjB,EAAKkB,sBAAsBoD,QAAQjB,GAKpCrD,EAAKiB,WAAa,eAClBjB,EAAKiE,iBAAgB,GAxBrB,CAyBD,EACA5D,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,YAAanD,EAC1C,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,YAAapD,EAC7C,IAED,IAAIL,EAAgB,CACnBI,KAAM,QACNC,SAAU,SAACuB,GAGL1B,EAAKkB,wBAEVlB,EAAKc,iBAAiBY,EAAM6C,KAE5BvE,EAAKkB,sBAAsBsD,QAAQ,CAClCD,IAAK7C,EAAM6C,IACX3B,SAAUC,MAAMC,KAAK9C,EAAKc,WAC1B0C,eAAgB,kBAAM9B,EAAM8B,gBAAgB,IAE9C,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,QAASnD,EACtC,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,QAASpD,EACzC,IAED,IAAIL,EAAgB,CACnBI,KAAM,UACNC,SAAU,SAACuB,GACL1B,EAAKkB,wBAIVlB,EAAKc,UAAU2D,IAAI/C,EAAM6C,KAEzBvE,EAAKkB,sBAAsBwD,UAAU,CACpCH,IAAK7C,EAAM6C,IACX3B,SAAUC,MAAMC,KAAK9C,EAAKc,WAC1B0C,eAAgB,kBAAM9B,EAAM8B,gBAAgB,IAE9C,EACAnD,SAAU,SAACF,GACSH,EAAK8B,qBACbwB,iBAAiB,UAAWnD,EACxC,EACAC,WAAY,SAACD,GACOH,EAAK8B,qBACbyB,oBAAoB,UAAWpD,EAC3C,IAGH,EAACoB,EAOMnB,WAAA,WACNH,KAAKe,WAAWiC,QAAQ,SAACC,GACxBA,EAAS9C,YACV,GACAH,KAAK0E,OACN,EAACpE,CAAA,CAhXwC,GChB7BqE,eAA2B,SAAAC,GACvC,SAAAD,EACCpE,GAGqBR,IAAAA,EAQrB,IANAA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAOP,MAgBN8E,aAAO,EAAA/E,EACPgF,uBAAiB,EAAAhF,EACjBiF,UAAI,EAAAjF,EACJkF,UAAI,EAAAlF,EACJmF,cAAQ,EAAAnF,EACRoF,yBAAmB,EAAApF,EACnBqF,6BAAuB,EAAArF,EAqPvBsF,mBAAqC,IAAIvE,IA1QhDf,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKkF,KAAO1E,EAAOgF,KAIdxF,EAAKkF,KAAKO,SAASC,GACvB,MAAU,IAAAC,MAAM,sDAMX,OAHN3F,EAAKa,qBACkC,iBAA/BL,EAAOc,oBACXd,EAAOc,oBACP,EAAEtB,CACP,CArBuC4F,EAAAhB,EAAAC,GAqBtC,IAAAtD,EAAAqD,EAAApD,UAYAoD,OAZArD,EAsBOsE,WAAA,SAAWC,EAAYC,EAAYC,GAC1C,IAAMC,EAAQ,EAAJD,EACV,MAAA,KAAYF,EAAE,IAAIC,EAAE,OAAOC,EAAC,SAASA,EAAC,IAAIA,EAAC,UAAUC,EAAC,QAAQD,EAAC,IAAIA,EAAC,WAAWC,EAAC,IACjF,EAAC1E,EAEMlB,SAAA,SAAS0C,GAA6BmD,IAAAA,EAC5CrB,KAAAA,EAAArD,UAAMnB,SAAQyE,KAAA7E,KAAC8C,GAKf9C,KAAKkF,SAAW,IAAIlF,KAAKgF,KAAKkB,YAC9BlG,KAAKkF,SAASiB,KAAO,WAAc,EAKnCnG,KAAKkF,SAASkB,MAAQ,WACrBH,EAAKhF,uBACJgF,EAAKhF,sBAAsBoF,SAC3BJ,EAAKhF,sBAAsBoF,SAC7B,EACArG,KAAKkF,SAASoB,OAAOtG,KAAKiF,MAK1BjF,KAAKmF,oBAAsBnF,KAAKiF,KAAKsB,KAAKC,YACzC,QACA,SACC/E,GAIA,IAAMgF,EAAgBR,EAAKlF,WAAW2F,KACrC,SAAA5G,GAAO,MAAgB,UAAhBA,EAAJG,IAA2B,GAE3BwG,GACHA,EAAcvG,SAASuB,EAEzB,GAGDzB,KAAKoF,wBAA0BpF,KAAKiF,KAAKsB,KAAKC,YAC7C,YACA,SACC/E,GAIA,IAAMkF,EAAoBV,EAAKlF,WAAW2F,KACzC,SAAAE,GAAO,MAAgB,cAAhBA,EAAJ3G,IAA+B,GAE/B0G,GACHA,EAAkBzG,SAASuB,EAE7B,EAEF,EAACH,EAEMnB,WAAA,WAAU0G,IAAAA,EAAAC,EAAAC,EAChBnC,EAAArD,UAAMpB,WAAU0E,KAAA7E,MACQ,OAAxB6G,EAAI7G,KAACmF,sBAAL0B,EAA0BG,SACE,OAA5BF,EAAI9G,KAACoF,0BAAL0B,EAA8BE,SACjB,OAAbD,EAAI/G,KAACkF,WAAL6B,EAAeT,OAAO,MACtBtG,KAAKkF,cAAW+B,CACjB,EAAC3F,EAODiB,mBAAA,SAAmBd,GAClB,IAAKzB,KAAKkF,SACT,MAAU,IAAAQ,MAAM,sBAGjB,IAAMwB,EAASlH,KAAKiF,KAAKkC,YAEzB,IAAKD,EACJ,OAAO,KAGR,IAAME,EAAKF,EAAOG,eACZC,EAAKJ,EAAOK,eACZC,EAAe,IAAQxH,KAACgF,KAAKyC,aAAaH,EAAIF,GAE9CM,EAAY1H,KAAKiF,KAAKO,SACtBmC,EAAUlG,EAAMO,QAAU0F,EAAU5F,wBAAwBG,KAC5D2F,EAAUnG,EAAMU,QAAUuF,EAAU5F,wBAAwBM,IAC5DyF,EAAc,IAAI7H,KAAKgF,KAAK8C,MAAMH,EAASC,GAE3CG,EAAa/H,KAAKkF,SAAS8C,gBACjC,IAAKD,EACJ,OACD,KAEA,IAAMzF,EAASyF,EAAWE,2BAA2BJ,GAErD,OAAIvF,GAAUkF,EAAaU,SAAS5F,GAC5B,CAAEE,IAAKF,EAAOE,MAAOC,IAAKH,EAAOG,WAI1C,EAACnB,EAMMO,mBAAA,WAGN,OAAW7B,KAACiF,KAAKO,SAAS2C,cADT,4BAElB,EAAC7G,EAQD8G,QAAA,SAAQ5F,EAAaC,GACpB,IAAKzC,KAAKkF,SACT,MAAM,IAAIQ,MAAM,sBAKjB,QAAeuB,IAFAjH,KAAKiF,KAAKkC,YAGxB,MAAU,IAAAzB,MAAM,qBAGjB,IAAMqC,EAAa/H,KAAKkF,SAAS8C,gBACjC,QAAmBf,IAAfc,EACH,MAAU,IAAArC,MAAM,yBAGjB,IAAM2C,EAAQN,EAAWO,2BACxB,IAAQtI,KAACgF,KAAKuD,OAAO9F,EAAKD,IAG3B,GAAc,OAAV6F,EACH,MAAU,IAAA3C,MAAM,8BAGjB,MAAO,CAAE/F,EAAG0I,EAAM1I,EAAGD,EAAG2I,EAAM3I,EAC/B,EAAC4B,EAQDkH,UAAA,SAAU7I,EAAWD,GACpB,IAAKM,KAAKkF,SACT,MAAU,IAAAQ,MAAM,sBAGjB,IAAMqC,EAAa/H,KAAKkF,SAAS8C,gBACjC,QAAmBf,IAAfc,EACH,MAAM,IAAIrC,MAAM,yBAGjB,IAAMpD,EAASyF,EAAWE,2BACzB,IAAIjI,KAAKgF,KAAK8C,MAAMnI,EAAGD,IAGxB,GAAe,OAAX4C,EACH,MAAU,IAAAoD,MAAM,gCAGjB,MAAO,CAAElD,IAAKF,EAAOE,MAAOC,IAAKH,EAAOG,MACzC,EAACnB,EAMDmH,UAAA,SAAUC,GACT,GAAIA,IAAW1I,KAAK8E,QAApB,CASA,GALI9E,KAAK+E,oBACR/E,KAAK+E,kBAAkBiC,SACvBhH,KAAK+E,uBAAoBkC,GAGX,UAAXyB,EAAoB,CAGvB,IAAMC,EAAM3I,KAAKiF,KAAKO,SAEhBoD,EAAWC,SAASV,cADJ,IAAOQ,EAAIlD,GAAE,oBAGnC,GAAImD,EAAU,CACbA,EAASE,UAAUtE,IAAI,0BAEvB,IAAMuE,EAAQF,SAASG,cAAc,SACrCD,EAAME,UAAS,qCAAwCP,EAAM,iBAC7DG,SAASK,qBAAqB,QAAQ,GAAGC,YAAYJ,GACrD/I,KAAK+E,kBAAoBgE,CAC1B,CACD,CAEA/I,KAAK8E,QAAU4D,CAxBf,CAyBD,EAACpH,EAMD8H,qBAAA,SAAqBrF,GAEnB/D,KAAKiF,KAAKoE,WADPtF,EACkB,CAAEuF,wBAAwB,GAE1B,CAAEA,wBAAwB,GAEjD,EAAChI,EAMD0C,gBAAA,SAAgBD,GACf/D,KAAKiF,KAAKoE,WAAW,CAAEE,UAAWxF,GACnC,EAACzC,EASDkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAC,EAAA3J,KAC9DA,KAAK4J,UACRH,EAAQI,WAAW7G,QAAQ,SAAC8G,GAC3B,IAAMC,EAAkBJ,EAAK1E,KAAKsB,KAAKyD,eAAeF,GAClDC,IACHJ,EAAK1E,KAAKsB,KAAKS,OAAO+C,GACtBJ,EAAKtE,mBAAyB,OAACyE,GAEjC,GAEAL,EAAQQ,QAAQjH,QAAQ,SAACkH,GACxB,IAAKA,IAAmBA,EAAezE,GACtC,MAAM,IAAIC,MAAM,wBAGjB,IAAMyE,EAAkBR,EAAK1E,KAAKsB,KAAKyD,eACtCE,EAAezE,IAGhB,IAAK0E,EACJ,MAAU,IAAAzE,MAAM,iDAgBjB,OAZAyE,EAAgBC,gBAAgB,SAACC,EAAUpK,GAC1CkK,EAAgBG,YAAYrK,OAAMgH,EACnC,GAGAsD,OAAOC,KAAKN,EAAeO,YAAYzH,QAAQ,SAACqH,GAC/CF,EAAgBG,YACfD,EACAH,EAAeO,WAAWJ,GAE5B,GAEQH,EAAeQ,SAASC,MAC/B,IAAK,QAEH,IAAMC,EAAcV,EAAeQ,SAASE,YAE5CT,EAAgBU,YACf,IAAIlB,EAAK3E,KAAK8F,KAAKhD,MAClB,IAAI6B,EAAK3E,KAAKuD,OAAOqC,EAAY,GAAIA,EAAY,MAIpD,MACD,IAAK,aAKH,IAHA,IAAMA,EAAcV,EAAeQ,SAASE,YAEtCG,EAAO,GACJC,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IAAK,CAC5C,IAAME,EAAaN,EAAYI,GACzB1I,EAAS,IAAIqH,EAAK3E,KAAKuD,OAC5B2C,EAAW,GACXA,EAAW,IAEZH,EAAKI,KAAK7I,EACX,CAEA6H,EAAgBU,YAAY,IAAIlB,EAAK3E,KAAK8F,KAAKM,WAAWL,IAE3D,MACD,IAAK,UAKH,IAHA,IAAMH,EAAcV,EAAeQ,SAASE,YAEtCS,EAAQ,GACLL,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IAAK,CAE5C,IADA,IAAMD,EAAO,GACJO,EAAI,EAAGA,EAAIV,EAAYI,GAAGC,OAAQK,IAAK,CAC/C,IAAMhJ,EAAS,IAAIqH,EAAK3E,KAAKuD,OAC5BqC,EAAYI,GAAGM,GAAG,GAClBV,EAAYI,GAAGM,GAAG,IAEnBP,EAAKI,KAAK7I,EACX,CACA+I,EAAMF,KAAKJ,EACZ,CAEAZ,EAAgBU,YAAY,IAAIlB,EAAK3E,KAAK8F,KAAKS,QAAQF,IAK3D,GAGA5B,EAAQ+B,QAAQxI,QAAQ,SAACyI,GACxB9B,EAAKtE,mBAAmBb,IAAIiH,EAAehG,IAC3CkE,EAAK1E,KAAKsB,KAAKmF,WAAWD,EAC3B,IAGDhC,EAAQ+B,QAAQxI,QAAQ,SAAC2I,GACxBhC,EAAKtE,mBAAmBb,IAAImH,EAAQlG,GACrC,GAEA,IAAMmG,EAAoB,CACzBjB,KAAM,oBACNkB,SAAQ,GAAAC,OAAMrC,EAAQ+B,UAGvBxL,KAAKiF,KAAKsB,KAAKmF,WAAWE,GAE1B5L,KAAKiF,KAAKsB,KAAKwF,SAAS,SAACJ,GACxB,IAAMK,EAAOL,EAAQM,YAAY,QAC3BC,EAAaP,EAAQQ,cAC3B,IAAKD,EACJ,MAAM,IAAIxG,MAAM,kCAEjB,IAAMiF,EAAOuB,EAAWE,UAClB3B,EAAkC,CAAE,EAE1CkB,EAAQvB,gBAAgB,SAACiC,EAAOhC,GAC/BI,EAAWJ,GAAYgC,CACxB,GAEA,IAAMC,EAAmB5C,EAAQsC,GAAM,CACtCrB,KAAM,UACND,SAAU,CACTC,KAAMA,EACNC,YAAa,IAEdH,WAAAA,IAGD,OAAQE,GACP,IAAK,QAGJ,MAAO,CACN4B,WAAW,EACXC,KAAM,CACLzB,KALWpB,EAAK/D,WAAW,EAAG,EAAG0G,EAAiBG,YAMlDC,UAAWJ,EAAiBK,WAC5BC,YAAa,EACbC,YAAaP,EAAiBQ,kBAC9BC,aAAcT,EAAiBU,kBAC/BC,SAAU,EACVC,MAAO,IAIV,IAAK,aACJ,MAAO,CACNL,YAAaP,EAAiBa,gBAC9BJ,aAAcT,EAAiBc,iBAEjC,IAAK,UACJ,MAAO,CACNP,YAAaP,EAAiBe,oBAC9BN,aAAcT,EAAiBgB,oBAC/BV,YAAaN,EAAiBiB,mBAC9Bb,UAAWJ,EAAiBkB,kBAI/B,MAAM9H,MAAM,uBACb,EACD,EAACpE,EAEOmM,YAAA,WAAWC,IAAAA,EAClB1N,KAAIA,KAAK4J,UACR5J,KAAKiF,KAAKsB,KAAKvD,QAAQ,SAAC2I,GACvB,IAAMlG,EAAKkG,EAAQgC,QACAD,EAAKrI,mBAAmBuI,IAAInI,IAE9CiI,EAAKzI,KAAKsB,KAAKS,OAAO2E,EAExB,GACA3L,KAAKqF,mBAAqB,IAAIvE,IAEhC,EAACQ,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KACpC7E,KAAA,EAAC8N,EAAAnJ,EAAAL,CAAAA,CAAAA,IAAAyJ,UAAAA,IA5bD,WAAmBC,IAAAA,EAClB,OAAOC,SAAQD,OAAAA,EAAAhO,KAAKqF,yBAAL2I,EAAAA,EAAyBE,MAAO,EAChD,KAACvJ,CAAA,CAjCsC,CAAQrE,GCAnC6N,eAAwBvJ,SAAAA,GACpC,SAAAuJ,EACC5N,GAGqBR,IAAAA,EAMsB,OAJ3CA,EAAA6E,EAAAC,KAAA7E,KAAMO,IAAOP,MAONgF,UAAIjF,EAAAA,EACJkF,YAAIlF,EACJqO,OAAuD,CAAA,EAAErO,EACzDsO,gBAAUtO,EAAAA,EACV6J,QAA0C,CAAA,EATjD7J,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKsO,WAAatO,EAAKkF,KAAKqJ,eAAevO,CAC5C,CAZoC4F,EAAAwI,EAAAvJ,GAYnC,IAAAtD,EAAA6M,EAAA5M,UAoSA4M,OApSA7M,EAcOiN,qBAAA,SAAqBC,EAAcC,GAC1C,IAAM1F,EAAQF,SAASG,cAAc,SAIrC,OAHAD,EAAME,UAAwBuF,YAAAA,gBAAkBC,EAAM,KACtD5F,SAASK,qBAAqB,QAAQ,GAAGC,YAAYJ,GACrD/I,KAAKiF,KAAKyJ,WAAWF,GACdzF,CACR,EAACzH,EAMOqN,WAAA,WACPpE,OAAOqE,OAAO5O,KAAKoO,QAAQpL,QAAQ,SAACwL,GAC/BA,GACHA,EAAKxH,QAEP,GACAhH,KAAKoO,OAAS,CAAA,CACf,EAAC9M,EAMOmM,YAAA,eAAWxH,EAAAjG,KAClBuK,OAAOqE,OAAO5O,KAAK4J,SAAS5G,QAAQ,SAAC6L,GACpC5I,EAAKhB,KAAK6J,YAAYD,EACvB,GACA7O,KAAK4J,QAAU,EAChB,EAACtI,EAMOyN,kBAAA,SACPrF,OAAiCC,EAAA3J,KAEjC,MAAO,CAENgP,aAAc,SACbrD,EACAsD,GAEA,IAAKtD,EAAQlB,WACZ,MAAM,IAAI/E,MAAM,6BAEjB,GAAuC,iBAA5BiG,EAAQlB,WAAWuB,KAC7B,MAAM,IAAItG,MAAM,gCAGjB,IAEMwJ,GAAgBC,EADJzF,EADLiC,EAAQlB,WAAWuB,OAEAL,GAC1ByD,EAASC,OAAOH,EAAcT,QAuBpC,OAtBa9E,EAAKyE,OAAOgB,KAGxBzF,EAAKyE,OAAOgB,GAAUzF,EAAK4E,qBAC1Ba,EACAF,EAAcT,SAeD9E,EAAK3E,KAAKsK,aAAaL,EAXvB,CACdM,OAAQL,EAAczC,WACtB+C,OAAQN,EAAclC,oBAAqB,EAC3CyC,MAAOP,EAAcpC,kBACrB4C,OAAQR,EAAclC,kBACtBJ,YAAa,GACbF,UAAWwC,EAAcvC,WACzB6B,KAAMY,EACNO,aAAa,GAMf,EAGA5G,MAAO,SAAC6G,GACP,IAAKA,IAAaA,EAASnF,WAC1B,MAAO,CAAA,EAGR,IAAMkB,EAAUiE,EAIVV,GAAgBC,EADJzF,EADLiC,EAAQlB,WAAWuB,OAEAL,GAC1ByD,EAASC,OAAOH,EAAcT,QAUpC,OATa9E,EAAKyE,OAAOgB,KAGxBzF,EAAKyE,OAAOgB,GAAUzF,EAAK4E,qBAC1Ba,EACAF,EAAcT,SAIc,eAA1B9C,EAAQjB,SAASC,KACb,CACNgF,aAAa,EACbF,MAAOP,EAAc/B,gBACrBuC,OAAQR,EAAc9B,gBACtBoB,KAAMY,GAE6B,YAA1BzD,EAAQjB,SAASC,KACpB,CACNgF,aAAa,EACb/C,YAAasC,EAAc3B,mBAC3Bb,UAAWwC,EAAc1B,iBACzBkC,OAAQR,EAAc5B,oBACtBkC,QAAQ,EACRC,MAAOP,EAAc1B,iBACrBgB,KAAMY,GAID,CACR,CAAA,EAEF,EAAC9N,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GAExB4G,EAAQ,CAAE1I,EAHK+C,EAAbX,WAGWrC,EAHiBgD,EAAbR,YAMvB,GAAI2N,MAAMxH,EAAM1I,IAAMkQ,MAAMxH,EAAM3I,GACjC,OACD,KAEA,IAAM4C,EAAStC,KAAKiF,KAAK6K,uBAAuBzH,GAChD,OAAIwH,MAAMvN,EAAOE,MAAQqN,MAAMvN,EAAOG,KAEtC,KAEO,CAAED,IAAKF,EAAOE,IAAKC,IAAKH,EAAOG,IACvC,EAACnB,EAMMO,mBAAA,WACN,OAAW7B,KAACqO,UACb,EAAC/M,EAMM0C,gBAAA,SAAgBD,GAClBA,EACH/D,KAAKiF,KAAK8K,SAASC,SAEnBhQ,KAAKiF,KAAK8K,SAASE,SAErB,EAAC3O,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAAyN,EAAiBlQ,KAAKiF,KAAKkL,uBAAuB,CAAE3N,IAAAA,EAAKC,IAAAA,IACzD,MAAO,CAAE9C,EADAuQ,EAADvQ,EACID,EADAwQ,EAADxQ,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAA0Q,EAAqBpQ,KAAKiF,KAAK6K,uBAAuB,CACrDnQ,EAAAA,EACAD,EAAAA,IAED,MAAO,CAAE8C,IAJE4N,EAAH5N,IAIMC,IAJE2N,EAAH3N,IAKd,EAACnB,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMsH,eAAe,UAE/CrQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GACvBA,EACH/D,KAAKiF,KAAKqL,gBAAgBN,SAE1BhQ,KAAKiF,KAAKqL,gBAAgBL,SAE5B,EAAC3O,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiCgE,IAAAA,OACzEjE,EAAQ+B,QAAQxI,QAAQ,SAACwI,GACxBkC,EAAK9D,QAAQ4B,EAAQ/F,IAAgBiI,EAAK1I,KAAKuL,QAC9C/E,EACAkC,EAAKqB,kBAAkBrF,IAExBgE,EAAKzI,KAAKuL,SAAS9C,EAAK9D,QAAQ4B,EAAQ/F,IACzC,GAEAgE,EAAQI,WAAW7G,QAAQ,SAACyN,GAC3B/C,EAAKzI,KAAK6J,YAAYpB,EAAK9D,QAAQ6G,GACpC,GAEAhH,EAAQQ,QAAQjH,QAAQ,SAACiH,GACxByD,EAAKzI,KAAK6J,YAAYpB,EAAK9D,QAAQK,EAAQxE,KAC3CiI,EAAK9D,QAAQK,EAAQxE,IAAgBiI,EAAK1I,KAAKuL,QAC9CtG,EACAyD,EAAKqB,kBAAkBrF,IAExBgE,EAAKzI,KAAKuL,SAAS9C,EAAK9D,QAAQK,EAAQxE,IACzC,EACD,EAACnE,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cACLzN,KAAK2O,aAEP,EAACrN,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAA7E,KAAC8C,GAEf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KAAA7E,KACpC,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KACxB7E,KAAA,EAACmO,CAAA,CAhTmCvJ,CAAQtE,GCMhCoQ,eAAyB,SAAA9L,GACrC,SAAA8L,EAAYnQ,GAAiDR,IAAAA,EAIjB,OAH3CA,EAAA6E,EAAAC,KAAA7E,KAAMO,IAAQR,MAMP4Q,iBAAW,EAAA5Q,EACXkF,UAAI,EAAAlF,EACJsO,gBAAUtO,EAAAA,EACV6Q,WAAY,EAAK7Q,EAoKjB8Q,WAMJ,CACHC,UAAU,EACVC,QAAQ,EACRC,aAAa,EACbC,UAAU,EACVvH,SAAS,GAtLT3J,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKsO,WAAatO,EAAKkF,KAAKqJ,eAAevO,CAC5C,CANqC4F,EAAA+K,EAAA9L,GAMpC,IAAAtD,EAAAoP,EAAAnP,UAkcA,OAlcAD,EAWOmM,YAAA,eAAWxH,EAAAjG,KACdA,KAAK4Q,YACc,CAAC,QAAS,aAAc,WAChC5N,QAAQ,SAACkO,GACtB,IAAMzL,EAAE,MAASyL,EAAYC,cAC7BlL,EAAKhB,KAAK6J,YAAYrJ,GAIF,YAAhByL,GACHjL,EAAKhB,KAAK6J,YAAYrJ,EAAK,YAE5BQ,EAAKhB,KAAKmM,aAAa3L,EACxB,GAEAzF,KAAK4Q,WAAY,EAGb5Q,KAAK2Q,cACRU,qBAAqBrR,KAAK2Q,aAC1B3Q,KAAK2Q,iBAAc1J,GAGtB,EAAC3F,EAEOgQ,kBAAA,SAAkB7L,EAAYoG,GACrC7L,KAAKiF,KAAKsM,UAAU9L,EAAI,CACvBkF,KAAM,UACNpE,KAAM,CACLoE,KAAM,oBACNkB,SAAUA,GAEX2F,UAAW,GAEb,EAAClQ,EAEOmQ,cAAA,SAAchM,GACrB,YAAYR,KAAKuL,SAAS,CACzB/K,GAAAA,EACAiM,OAAQjM,EACRkF,KAAM,OAENgH,MAAO,CACN,aAAc,CAAC,MAAO,oBACtB,eAAgB,CAAC,MAAO,wBAG3B,EAACrQ,EAEOsQ,qBAAA,SAAqBnM,EAAYoM,GACxC,IAAMhD,EAAQ7O,KAAKiF,KAAKuL,SAAS,CAChC/K,GAAIA,EAAK,WACTiM,OAAQjM,EACRkF,KAAM,OAENgH,MAAO,CACN,aAAc,CAAC,MAAO,uBACtB,aAAc,CAAC,MAAO,0BAQxB,OAJIE,GACH7R,KAAKiF,KAAK6M,UAAUrM,EAAIoM,GAGlBhD,CACR,EAACvN,EAEOyQ,cAAA,SAActM,EAAYoM,GACjC,IAAMhD,EAAQ7O,KAAKiF,KAAKuL,SAAS,CAChC/K,GAAAA,EACAiM,OAAQjM,EACRkF,KAAM,OAENgH,MAAO,CACN,aAAc,CAAC,MAAO,mBACtB,aAAc,CAAC,MAAO,sBAQxB,OAJIE,GACH7R,KAAKiF,KAAK6M,UAAUrM,EAAIoM,GAGlBhD,CACR,EAACvN,EAEO0Q,eAAA,SAAevM,EAAYoM,GAClC,IAAMhD,EAAQ7O,KAAKiF,KAAKuL,SAAS,CAChC/K,GAAAA,EACAiM,OAAQjM,EACRkF,KAAM,SAENgH,MAAO,CACN,sBAAuB,CAAC,MAAO,qBAC/B,sBAAuB,CAAC,MAAO,qBAC/B,gBAAiB,CAAC,MAAO,cACzB,eAAgB,CAAC,MAAO,iBAM1B,OAHIE,GACH7R,KAAKiF,KAAK6M,UAAUrM,EAAIoM,GAElBhD,CACR,EAACvN,EAEO2Q,UAAA,SACPxM,EACAyM,EACAL,GAEoB,UAAhBK,GACHlS,KAAKgS,eAAevM,EAAIoM,GAEL,eAAhBK,GACHlS,KAAK+R,cAActM,EAAIoM,GAEJ,YAAhBK,IACHlS,KAAKyR,cAAchM,GACnBzF,KAAK4R,qBAAqBnM,EAAIoM,GAEhC,EAACvQ,EAEO6Q,iBAAA,SACPD,EACArG,GAEA,IAAMpG,EAAWyM,MAAAA,EAAYf,cAI7B,OAHAnR,KAAKsR,kBAAkB7L,EAAIoG,GAC3B7L,KAAKiS,UAAUxM,EAAIyM,GAEZzM,CACR,EAACnE,EAEO8Q,qBAAA,SACPF,EACArG,GAEA,IAAMpG,EAAWyM,MAAAA,EAAYf,cAK7B,OAJCnR,KAAKiF,KAAKoN,UAAU5M,GAAY6M,QAAQ,CACxC3H,KAAM,oBACNkB,SAAUA,IAEJpG,CACR,EAACnE,EAEOiR,mBAAA,WAKP,MAAO,CACNxB,OAAQ,GACRC,YAAa,GACbC,SAAU,GAEZ,EAAC3P,EAgBOkR,iBAAA,SAAiB/I,GAAyBE,IAAAA,EACjD3J,KAAA,GAAA8L,OAAIrC,EAAQQ,QAAYR,EAAQ+B,SAASxI,QAAQ,SAAC2I,GACnB,UAA1BA,EAAQjB,SAASC,KACpBhB,EAAKkH,WAAWE,QAAS,EACW,eAA1BpF,EAAQjB,SAASC,KAC3BhB,EAAKkH,WAAWG,aAAc,EACM,YAA1BrF,EAAQjB,SAASC,OAC3BhB,EAAKkH,WAAWI,UAAW,EAE7B,GAEIxH,EAAQI,WAAWoB,OAAS,IAC/BjL,KAAK6Q,WAAWC,UAAW,GAIA,IAA3BrH,EAAQ+B,QAAQP,QACW,IAA3BxB,EAAQQ,QAAQgB,QACc,IAA9BxB,EAAQI,WAAWoB,SAEnBjL,KAAK6Q,WAAWnH,SAAU,EAE5B,EAACpI,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAgR,EAAsBzS,KAAKqO,WAAWvM,wBAItC,OAAW9B,KAACwI,UAHF/G,EAAMO,QADJyQ,EAAJxQ,KAEER,EAAMU,QAFCsQ,EAAHrQ,IAKf,EAACd,EAMMO,mBAAA,WACN,OAAO7B,KAAKiF,KAAKyN,WAClB,EAACpR,EAMM0C,gBAAA,SAAgBD,GAClBA,GAGH/D,KAAKiF,KAAK0N,WAAW3C,SACrBhQ,KAAKiF,KAAK2N,QAAQ5C,WAElBhQ,KAAKiF,KAAK0N,WAAW1C,UACrBjQ,KAAKiF,KAAK2N,QAAQ3C,UAEpB,EAAC3O,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAAoQ,EAAiB7S,KAAKiF,KAAKmD,QAAQ,CAAE5F,IAAAA,EAAKC,IAAAA,IAC1C,MAAO,CAAE9C,EADAkT,EAADlT,EACID,EADAmT,EAADnT,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAoT,EAAqB9S,KAAKiF,KAAKuD,UAAU,CAAE7I,EAAAA,EAAGD,EAAAA,IAC9C,MAAO,CAAE8C,IADEsQ,EAAHtQ,IACMC,IADEqQ,EAAHrQ,IAEd,EAACnB,EAMMmH,UAAA,SAAUC,GAChB,IAAMqK,EAAS/S,KAAKiF,KAAKyN,YACV,UAAXhK,EACHqK,EAAOhK,MAAMsH,eAAe,UAE5B0C,EAAOhK,MAAML,OAASA,CAExB,EAACpH,EAMM8H,qBAAA,SAAqBrF,GACvBA,EACH/D,KAAKiF,KAAKqL,gBAAgBN,SAE1BhQ,KAAKiF,KAAKqL,gBAAgBL,SAE5B,EAAC3O,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAgE,EAAA1N,KACzEA,KAAKwS,iBAAiB/I,GAElBzJ,KAAK2Q,aACRU,qBAAqBrR,KAAK2Q,aAO3B3Q,KAAK2Q,YAAcqC,sBAAsB,WAYxC,IARA,IAAMnH,EAAQC,GAAAA,OACVrC,EAAQ+B,QACR/B,EAAQQ,QACRR,EAAQwJ,WAGNC,EAAmBxF,EAAK6E,qBAAqBY,EAAA,SAE1CnI,GACR,IAAMW,EAAUE,EAASb,GAEzBT,OAAOC,KAAKd,GAAS1G,QAAQ,SAACgJ,GAC7B,IAAQvB,EAAekB,EAAflB,WAER,GAAIA,EAAWuB,OAASA,EAAxB,CAIA,IAAMoH,EAAS1J,EAAQsC,GAAML,GAEC,UAA1BA,EAAQjB,SAASC,MACpBF,EAAWkC,WAAayG,EAAOzG,WAC/BlC,EAAWqC,kBAAoBsG,EAAOtG,kBACtCrC,EAAWuC,kBAAoBoG,EAAOpG,kBACtCvC,EAAWgC,WAAa2G,EAAO3G,WAC/ByG,EAAiBnC,OAAO5F,KAAKQ,IACO,eAA1BA,EAAQjB,SAASC,MAC3BF,EAAW0C,gBAAkBiG,EAAOjG,gBACpC1C,EAAW2C,gBAAkBgG,EAAOhG,gBACpC8F,EAAiBlC,YAAY7F,KAAKQ,IACE,YAA1BA,EAAQjB,SAASC,OAC3BF,EAAW+C,iBAAmB4F,EAAO5F,iBACrC/C,EAAW8C,mBAAqB6F,EAAO7F,mBACvC9C,EAAW4C,oBAAsB+F,EAAO/F,oBACxC5C,EAAW6C,oBAAsB8F,EAAO9F,oBACxC4F,EAAiBjC,SAAS9F,KAAKQ,GAnBhC,CAqBD,EAAG,EA7BKX,EAAI,EAAGA,EAAIa,EAASZ,OAAQD,IAAKmI,EAAjCnI,GAgCT,IAAQ+F,EAAkCmC,EAAlCnC,OAAQC,EAA0BkC,EAA1BlC,YAAaC,EAAaiC,EAAbjC,SAE7B,GAAKvD,EAAKkD,UAiBH,CAGN,IASIyC,EAPEC,EAFkB5F,EAAKmD,WAAWC,UACZpD,EAAKmD,WAAWnH,QAKtC6J,EAAoBD,GAAe5F,EAAKmD,WAAWG,YACnDwC,EAAiBF,GAAe5F,EAAKmD,WAAWI,UAFjCqC,GAAe5F,EAAKmD,WAAWE,UAMnDsC,EAAU3F,EAAK0E,qBACd,QACArB,IAIEwC,GACH7F,EAAK0E,qBACJ,aACApB,GAIEwC,GACH9F,EAAK0E,qBACJ,UACAnB,GAQFoC,GAAW3F,EAAKzI,KAAK6M,UAAUuB,EAChC,KAxDqB,CACpB,IAAMA,EAAU3F,EAAKyE,iBACpB,QACApB,GAEDrD,EAAKyE,iBACJ,aACAnB,GAEDtD,EAAKyE,iBACJ,UACAlB,GAEDvD,EAAKkD,WAAY,EAGjByC,GAAW3F,EAAKzI,KAAK6M,UAAUuB,EAChC,CA0CA3F,EAAKmD,WAAa,CACjBE,QAAQ,EACRC,aAAa,EACbC,UAAU,EACVH,UAAU,EACVpH,SAAS,EAEX,EACD,EAACpI,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEM4B,uBAAA,WACN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KACpC7E,KAAA,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KAAA7E,KACxB,EAACsB,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAC/B,KAAAA,GACf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAACqK,CAAA,CAxcoC,CAAQpQ,GCNjCmT,eAA2B7O,SAAAA,GAGvC,SAAA6O,EAAYlT,GAAwC,IAAAR,EAajD,OAZFA,EAAA6E,EAAAC,UAAMtE,IAAQR,MAHP2T,qBAUP3T,EAAAA,EAAK2T,gBAAkB,IAAIhD,EAC1BnQ,GAICR,CACH,CAjBuC4F,EAAA8N,EAAA7O,GAiBtC,IAAAtD,EAAAmS,EAAAlS,UA0FAkS,OA1FAnS,EAEMlB,SAAA,SAAS0C,GACf9C,KAAK0T,gBAAgBtT,SAAS0C,EAC/B,EAACxB,EAEMnB,WAAA,WACNH,KAAK0T,gBAAgBvT,YACtB,EAACmB,EAEM4B,uBAAA,WACN,OAAWlD,KAAC0T,gBAAgBxQ,wBAC7B,EAAC5B,EAOMiB,mBAAA,SAAmBd,GACzB,OAAWzB,KAAC0T,gBAAgBnR,mBAAmBd,EAChD,EAACH,EAMMO,mBAAA,WACN,OAAW7B,KAAC0T,gBAAgB7R,oBAC7B,EAACP,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAK0T,gBAAgB1P,gBAAgBD,EACtC,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,YAAYiR,gBAAgBtL,QAAQ5F,EAAKC,EAC1C,EAACnB,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,OAAWM,KAAC0T,gBAAgBlL,UAAU7I,EAAGD,EAC1C,EAAC4B,EAMMmH,UAAA,SAAUM,GAChB/I,KAAK0T,gBAAgBjL,UAAUM,EAChC,EAACzH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAK0T,gBAAgBtK,qBAAqBrF,EAC3C,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GACxC1J,KAAK0T,gBAAgBlK,OAAOC,EAASC,EACtC,EAACpI,EAMMoD,MAAA,WACN1E,KAAK0T,gBAAgBhP,OACtB,EAAC+O,CAAA,CA3GsC7O,CAAQtE,GCHzC,SAASqT,IACd,MAAM,IAAIjO,MAAM,iCAClB,CAOA,IAAIkO,EAAc,EC4CX,SAASC,EAAO3F,EAAM4F,GAC3B,OAAIlR,MAAMmR,QAAQ7F,GACTA,QAEMjH,IAAT6M,EACFA,EAAO,CAAC5F,EAAMA,IAEd4F,EAAK,GAAK5F,EACV4F,EAAK,GAAK5F,GAEL4F,EAEX,CCjDA,MAAME,EAIJ,WAAAC,CAAYC,GAKVlU,KAAKmU,SAAWD,EAAQE,QAMxBpU,KAAKqU,gBAAkBH,EAAQI,eAM/BtU,KAAKuU,UAAYL,EAAQjH,SAMzBjN,KAAKwU,OAASN,EAAQhH,MAMtBlN,KAAKyU,YAAcZ,EAAOK,EAAQhH,OAMlClN,KAAK0U,cAAgBR,EAAQS,aAM7B3U,KAAK4U,eAAiBV,EAAQW,aAC/B,CAOD,KAAAC,GACE,MAAM5H,EAAQlN,KAAK+U,WACnB,OAAO,IAAIf,EAAW,CACpBI,QAASpU,KAAKgV,aACd9H,MAAOtK,MAAMmR,QAAQ7G,GAASA,EAAM+H,QAAU/H,EAC9CD,SAAUjN,KAAKkV,cACfZ,eAAgBtU,KAAKmV,oBACrBR,aAAc3U,KAAKoV,kBAAkBH,QACrCJ,cAAe7U,KAAKqV,oBAEvB,CAOD,UAAAL,GACE,OAAOhV,KAAKmU,QACb,CAOD,iBAAAgB,GACE,OAAOnV,KAAKqU,eACb,CAOD,WAAAa,GACE,OAAOlV,KAAKuU,SACb,CAOD,QAAAQ,GACE,OAAO/U,KAAKwU,MACb,CAMD,aAAAc,GACE,OAAOtV,KAAKyU,WACb,CAOD,eAAAW,GACE,OAAOpV,KAAK0U,aACb,CAOD,gBAAAW,GACE,OAAOrV,KAAK4U,cACb,CAQD,SAAAW,GACE,OAAO5B,GACR,CAQD,QAAA6B,CAASC,GACP,OAAO9B,GACR,CAMD,oBAAA+B,GACE,OAAO/B,GACR,CAOD,aAAAgC,CAAcF,GACZ,OAAO,CACR,CAMD,aAAAG,GACE,OAAOjC,GACR,CAMD,YAAAkC,GACE,OAAOlC,GACR,CAOD,SAAAmC,GACE,OAAOnC,GACR,CAOD,OAAAoC,GACE,OAAOpC,GACR,CAQD,eAAAqC,CAAgBrB,GACd3U,KAAK0U,cAAgBC,CACtB,CAQD,UAAAsB,CAAW7B,GACTpU,KAAKmU,SAAWC,CACjB,CAQD,iBAAA8B,CAAkB5B,GAChBtU,KAAKqU,gBAAkBC,CACxB,CAQD,WAAA6B,CAAYlJ,GACVjN,KAAKuU,UAAYtH,CAClB,CAOD,QAAAmJ,CAASlJ,GACPlN,KAAKwU,OAAStH,EACdlN,KAAKyU,YAAcZ,EAAO3G,EAC3B,CAMD,iBAAAmJ,CAAkBpT,GAChB0Q,GACD,CAMD,IAAA2C,GACE3C,GACD,CAMD,mBAAA4C,CAAoBtT,GAClB0Q,GACD,EAGH,IAAA6C,EAAexC,ECnSf,MAAMyC,EAAW,CACf,EAAG,iCACH,EAAG,qCACH,EAAG,mCACH,EAAG,wDACH,EAAG,iDACH,EAAG,yCACH,EAAG,kCACH,EAAG,oDACH,GAAI,oEACJ,GAAI,0CACJ,GAAI,0EACJ,GAAI,iBACJ,GAAI,gBACJ,GAAI,kEACJ,GAAI,sDACJ,GAAI,mDACJ,GAAI,8DACJ,GAAI,wDACJ,GAAI,sDACJ,GAAI,kEACJ,GAAI,oDACJ,GAAI,iDACJ,GAAI,+BACJ,GAAI,+BACJ,GAAI,gDACJ,GAAI,uDACJ,GAAI,oEACJ,GAAI,2CACJ,GAAI,gBACJ,GAAI,0BACJ,GAAI,mBACJ,GAAI,8BACJ,GAAI,sCACJ,GAAI,wBACJ,GAAI,wCACJ,GAAI,kEACJ,GAAI,qCACJ,GAAI,qDACJ,GAAI,2DACJ,GAAI,+DACJ,GAAI,2DACJ,GAAI,4CACJ,GAAI,sDACJ,GAAI,kCACJ,GAAI,2CACJ,GAAI,wDACJ,GAAI,sDACJ,GAAI,qCACJ,GAAI,mCACJ,GAAI,4BACJ,GAAI,+EACJ,GAAI,uFACJ,GAAI,iCACJ,GAAI,wPACJ,GAAI,uGACJ,GAAI,uGAQN,MAAMC,UAAuBhR,MAI3B,WAAAuO,CAAY0C,GACV,MAAMC,EAAUH,EAASE,GAEzBE,MAAMD,GAWN5W,KAAK2W,KAAOA,EAKZ3W,KAAKC,KAAO,iBAGZD,KAAK4W,QAAUA,CAChB,EAGH,IAAAE,EAAeJ,ECvFR,SAASK,EAAM1K,EAAO2K,EAAKC,GAChC,OAAO7X,KAAK4X,IAAI5X,KAAK6X,IAAI5K,EAAO2K,GAAMC,EACxC,CCOA,MAAMC,EAAgB,oDAQhBC,EAAkB,4BAsCXC,EAAa,WASxB,MAKMC,EAAQ,CAAA,EAKd,IAAIC,EAAY,EAEhB,OAAA,SAKYC,GACR,IAAI9H,EACJ,GAAI4H,EAAMG,eAAeD,GACvB9H,EAAQ4H,EAAME,OACT,CACL,GAAID,GAtBa,KAsBgB,CAC/B,IAAItM,EAAI,EACR,IAAK,MAAM1G,KAAO+S,EACL,EAANrM,aACIqM,EAAM/S,KACXgT,EAGP,CACD7H,EA6BR,SAA6B8H,GAC3B,IAAIxR,EAAG0R,EAAGC,EAAGC,EAAGlI,EAMhB,GAJI0H,EAAgBS,KAAKL,KACvBA,EA1FJ,SAAmB9H,GACjB,MAAMoI,EAAKhP,SAASG,cAAc,OAElC,GADA6O,EAAG9O,MAAM0G,MAAQA,EACM,KAAnBoI,EAAG9O,MAAM0G,MAAc,CACzB5G,SAASiP,KAAK3O,YAAY0O,GAC1B,MAAME,EAAMC,iBAAiBH,GAAIpI,MAEjC,OADA5G,SAASiP,KAAKG,YAAYJ,GACnBE,CACX,CACI,MAAO,EAEX,CA+EQG,CAAUX,IAGZL,EAAcU,KAAKL,GAAI,CAEzB,MAAMY,EAAIZ,EAAEtM,OAAS,EACrB,IAAIjF,EAEFA,EADEmS,GAAK,EACH,EAEA,EAEN,MAAMC,EAAiB,IAAND,GAAiB,IAANA,EAC5BpS,EAAIsS,SAASd,EAAEe,OAAO,EAAI,EAAItS,EAAGA,GAAI,IACrCyR,EAAIY,SAASd,EAAEe,OAAO,EAAI,EAAItS,EAAGA,GAAI,IACrC0R,EAAIW,SAASd,EAAEe,OAAO,EAAI,EAAItS,EAAGA,GAAI,IAEnC2R,EADES,EACEC,SAASd,EAAEe,OAAO,EAAI,EAAItS,EAAGA,GAAI,IAEjC,IAEG,GAALA,IACFD,GAAKA,GAAK,GAAKA,EACf0R,GAAKA,GAAK,GAAKA,EACfC,GAAKA,GAAK,GAAKA,EACXU,IACFT,GAAKA,GAAK,GAAKA,IAGnBlI,EAAQ,CAAC1J,EAAG0R,EAAGC,EAAGC,EAAI,IACvB,MAAUJ,EAAEgB,WAAW,UAEtB9I,EAAQ8H,EAAEtC,MAAM,GAAI,GAAGuD,MAAM,KAAKjT,IAAIkT,QACtCC,EAAUjJ,IACD8H,EAAEgB,WAAW,SAEtB9I,EAAQ8H,EAAEtC,MAAM,GAAI,GAAGuD,MAAM,KAAKjT,IAAIkT,QACtChJ,EAAMtE,KAAK,GACXuN,EAAUjJ,ICzKP,SAAgBkJ,EAAWC,GAE9B,MAAM,IAAIlC,EDyKI,GCvKlB,CDuKImC,GAEF,OAAOpJ,CACT,CA5EgBqJ,CAAoBvB,GAC5BF,EAAME,GAAK9H,IACT6H,CACH,CACD,OAAO7H,CAET,CACH,CA/CyB,GA2HnB,SAASiJ,EAAUjJ,GAKxB,OAJAA,EAAM,GAAKsH,EAAOtH,EAAM,GAAK,GAAO,EAAG,EAAG,KAC1CA,EAAM,GAAKsH,EAAOtH,EAAM,GAAK,GAAO,EAAG,EAAG,KAC1CA,EAAM,GAAKsH,EAAOtH,EAAM,GAAK,GAAO,EAAG,EAAG,KAC1CA,EAAM,GAAKsH,EAAMtH,EAAM,GAAI,EAAG,GACvBA,CACT,CE9KO,SAASsJ,EAAYtJ,GAC1B,OAAI7M,MAAMmR,QAAQtE,GFmLb,SAAkBA,GACvB,IAAI1J,EAAI0J,EAAM,GACV1J,IAAU,EAAJA,KACRA,EAAKA,EAAI,GAAO,GAElB,IAAI0R,EAAIhI,EAAM,GACVgI,IAAU,EAAJA,KACRA,EAAKA,EAAI,GAAO,GAElB,IAAIC,EAAIjI,EAAM,GAKd,OAJIiI,IAAU,EAAJA,KACRA,EAAKA,EAAI,GAAO,GAGX,QAAU3R,EAAI,IAAM0R,EAAI,IAAMC,EAAI,UADlBzQ,IAAbwI,EAAM,GAAmB,EAAIrQ,KAAKE,MAAiB,IAAXmQ,EAAM,IAAY,KACjB,GACrD,CEjMWuJ,CAASvJ,GAETA,CAEX,CCxBA,MAAMwJ,EACiB,oBAAdC,gBAA4D,IAAxBA,UAAUC,UACjDD,UAAUC,UAAUhI,cACpB,GAMiB8H,EAAGG,SAAS,WAMbH,EAAGG,SAAS,YAAcH,EAAGG,SAAS,WAQzDH,EAAGG,SAAS,iBACX,wCAAwCC,KAAKJ,IAM3BA,EAAGG,SAAS,WAAcH,EAAGG,SAAS,QAMzCH,EAAGG,SAAS,aAiBxB,MAAME,EACkB,oBAAtBC,mBACoB,oBAApBC,iBACPC,gBAAgBF,kBC7CX,SAASG,EAAsBC,EAAOC,EAAQC,EAAYC,GAE/D,IAAI/G,EAeJ,OAbEA,EADE8G,GAAcA,EAAW5O,OAClB4O,EAAWE,QACXT,EACA,IAAIE,gBAAgBG,GAAS,IAAKC,GAAU,KAE5C/Q,SAASG,cAAc,UAE9B2Q,IACF5G,EAAO4G,MAAQA,GAEbC,IACF7G,EAAO6G,OAASA,GAIhB7G,EAAOiH,WAAW,KAAMF,EAE5B,EDqCuC,WACrC,IAAIG,GAAU,EACd,IACE,MAAM/F,EAAU3J,OAAO2P,eAAe,CAAA,EAAI,UAAW,CACnDnM,IAAK,WACHkM,GAAU,CACX,IAGHE,OAAO9W,iBAAiB,IAAK,KAAM6Q,GACnCiG,OAAO7W,oBAAoB,IAAK,KAAM4Q,EACvC,CAAC,MAAOkG,GAER,CAEF,CAfsC,GEIvC,IAAAC,EA9DA,MAIE,WAAApG,CAAYtJ,GAgBV3K,KAAK2K,KAAOA,EAOZ3K,KAAKmE,OAAS,IACf,CAOD,cAAAZ,GACEvD,KAAKsa,kBAAmB,CACzB,CAMD,eAAAC,GACEva,KAAKwa,oBAAqB,CAC3B,GCxBHC,EA3BA,MACE,WAAAxG,GAMEjU,KAAK0a,UAAW,CACjB,CAKD,OAAAC,GACO3a,KAAK0a,WACR1a,KAAK0a,UAAW,EAChB1a,KAAK4a,kBAER,CAMD,eAAAA,GAAoB,GCLf,SAASC,IAAO,CCnBhB,SAASnW,EAAMoW,GACpB,IAAK,MAAMzQ,KAAYyQ,SACdA,EAAOzQ,EAElB,CC+KA,IAAA0Q,EAhKA,cAAqBC,EAInB,WAAA/G,CAAY9P,GACV0S,QAMA7W,KAAKib,aAAe9W,EAMpBnE,KAAKkb,iBAAmB,KAMxBlb,KAAKmb,aAAe,KAMpBnb,KAAKob,WAAa,IACnB,CAMD,gBAAA/X,CAAiBsH,EAAM1H,GACrB,IAAK0H,IAAS1H,EACZ,OAEF,MAAMoY,EAAYrb,KAAKob,aAAepb,KAAKob,WAAa,CAAA,GAClDE,EAAmBD,EAAU1Q,KAAU0Q,EAAU1Q,GAAQ,IAC1D2Q,EAAiBlC,SAASnW,IAC7BqY,EAAiBnQ,KAAKlI,EAEzB,CAYD,aAAAsY,CAAc9Z,GACZ,MAAM+Z,EAA4B,iBAAV/Z,EAClBkJ,EAAO6Q,EAAW/Z,EAAQA,EAAMkJ,KAChC0Q,EAAYrb,KAAKob,YAAcpb,KAAKob,WAAWzQ,GACrD,IAAK0Q,EACH,OAGF,MAAMI,EAAMD,EAAW,IAAInB,EAAM5Y,GAA+B,EAC3Dga,EAAItX,SACPsX,EAAItX,OAASnE,KAAKib,cAAgBjb,MAEpC,MAAM0b,EAAc1b,KAAKmb,eAAiBnb,KAAKmb,aAAe,CAAA,GACxDQ,EACJ3b,KAAKkb,mBAAqBlb,KAAKkb,iBAAmB,CAAE,GAMtD,IAAIU,EALEjR,KAAQ+Q,IACZA,EAAY/Q,GAAQ,EACpBgR,EAAgBhR,GAAQ,KAExB+Q,EAAY/Q,GAEd,IAAK,IAAIK,EAAI,EAAG6Q,EAAKR,EAAUpQ,OAAQD,EAAI6Q,IAAM7Q,EAU/C,GARE4Q,EADE,gBAAiBP,EAAUrQ,GAE3BqQ,EAAUrQ,GACV8Q,YAAYL,GAGZJ,EAAUrQ,GACVnG,KAAK7E,KAAMyb,IAEG,IAAdG,GAAuBH,EAAIjB,mBAAoB,CACjDoB,GAAY,EACZ,KACD,CAEH,GAA4B,KAAtBF,EAAY/Q,GAAa,CAC7B,IAAIoR,EAAKJ,EAAgBhR,GAEzB,WADOgR,EAAgBhR,GAChBoR,KACL/b,KAAKsD,oBAAoBqH,EAAMkQ,UAE1Ba,EAAY/Q,EACpB,CACD,OAAOiR,CACR,CAKD,eAAAhB,GACE5a,KAAKob,YAAc1W,EAAM1E,KAAKob,WAC/B,CASD,YAAAY,CAAarR,GACX,OAAQ3K,KAAKob,YAAcpb,KAAKob,WAAWzQ,SAAU1D,CACtD,CAOD,WAAAgV,CAAYtR,GACV,QAAK3K,KAAKob,aAGHzQ,EACHA,KAAQ3K,KAAKob,WACb7Q,OAAOC,KAAKxK,KAAKob,YAAYnQ,OAAS,EAC3C,CAMD,mBAAA3H,CAAoBqH,EAAM1H,GACxB,MAAMoY,EAAYrb,KAAKob,YAAcpb,KAAKob,WAAWzQ,GACrD,GAAI0Q,EAAW,CACb,MAAMa,EAAQb,EAAUc,QAAQlZ,IACjB,IAAXiZ,IACElc,KAAKkb,kBAAoBvQ,KAAQ3K,KAAKkb,kBAExCG,EAAUa,GAASrB,IACjB7a,KAAKkb,iBAAiBvQ,KAExB0Q,EAAUe,OAAOF,EAAO,GACC,IAArBb,EAAUpQ,eACLjL,KAAKob,WAAWzQ,IAI9B,CACF,GC1II,SAAS0R,EAAOlY,EAAQwG,EAAM1H,EAAUqZ,EAASC,GAItD,GAHID,GAAWA,IAAYnY,IACzBlB,EAAWA,EAASgB,KAAKqY,IAEvBC,EAAM,CACR,MAAMC,EAAmBvZ,EACzBA,EAAW,WACTkB,EAAOb,oBAAoBqH,EAAM1H,GACjCuZ,EAAiBC,MAAMzc,KAAM0c,UACnC,CACG,CACD,MAAMC,EAAY,CAChBxY,OAAQA,EACRwG,KAAMA,EACN1H,SAAUA,GAGZ,OADAkB,EAAOd,iBAAiBsH,EAAM1H,GACvB0Z,CACT,CAsBO,SAASC,EAAWzY,EAAQwG,EAAM1H,EAAUqZ,GACjD,OAAOD,EAAOlY,EAAQwG,EAAM1H,EAAUqZ,GAAS,EACjD,CAWO,SAASO,EAAcvY,GACxBA,GAAOA,EAAIH,SACbG,EAAIH,OAAOb,oBAAoBgB,EAAIqG,KAAMrG,EAAIrB,UAC7CyB,EAAMJ,GAEV,CCuFA,IAAAwY,EAvJA,cAAyB/B,EACvB,WAAA9G,GACE4C,QAEA7W,KAAK+c,GAED/c,KACR,WAEIA,KAAKuc,KAEDvc,KACR,aAEIA,KAAKgd,GAAiDhd,KAAe,WAMrEA,KAAKid,UAAY,CAClB,CAMD,OAAAC,KACIld,KAAKid,UACPjd,KAAKub,cCvDC,SDwDP,CAQD,WAAA4B,GACE,OAAOnd,KAAKid,SACb,CAQD,UAAAG,CAAWzS,EAAM1H,GACf,GAAIL,MAAMmR,QAAQpJ,GAAO,CACvB,MAAM0S,EAAM1S,EAAKM,OACXT,EAAO,IAAI5H,MAAMya,GACvB,IAAK,IAAIrS,EAAI,EAAGA,EAAIqS,IAAOrS,EACzBR,EAAKQ,GAAKqR,EAAOrc,KAAM2K,EAAKK,GAAI/H,GAElC,OAAOuH,CACb,CACM,OAAO6R,EAAOrc,OAAoCiD,EAErD,CAQD,YAAAqa,CAAa3S,EAAM1H,GACjB,IAAIqB,EACJ,GAAI1B,MAAMmR,QAAQpJ,GAAO,CACvB,MAAM0S,EAAM1S,EAAKM,OACjB3G,EAAM,IAAI1B,MAAMya,GAChB,IAAK,IAAIrS,EAAI,EAAGA,EAAIqS,IAAOrS,EACzB1G,EAAI0G,GAAK4R,EAAW5c,KAAM2K,EAAKK,GAAI/H,EAE3C,MACMqB,EAAMsY,EAAW5c,OAAoCiD,GAGvD,OADsB,EAAWsa,OAASjZ,EACnCA,CACR,CAQD,UAAAkZ,CAAW7S,EAAM1H,GACf,MAAMqB,EAA4B,EAAWiZ,OAC7C,GAAIjZ,GAmDD,SAAiBA,GACtB,GAAI1B,MAAMmR,QAAQzP,GAChB,IAAK,IAAI0G,EAAI,EAAG6Q,EAAKvX,EAAI2G,OAAQD,EAAI6Q,IAAM7Q,EACzC6R,EAAcvY,EAAI0G,SAGpB6R,EAAa,EAEjB,CA1DMY,CAAQnZ,QACH,GAAI1B,MAAMmR,QAAQpJ,GACvB,IAAK,IAAIK,EAAI,EAAG6Q,EAAKlR,EAAKM,OAAQD,EAAI6Q,IAAM7Q,EAC1ChL,KAAKsD,oBAAoBqH,EAAKK,GAAI/H,QAGpCjD,KAAKsD,oBAAoBqH,EAAM1H,EAElC,GE9HI,MAAMya,UAAoBrD,EAM/B,WAAApG,CAAYtJ,EAAMrG,EAAKqZ,GACrB9G,MAAMlM,GAON3K,KAAKsE,IAAMA,EAQXtE,KAAK2d,SAAWA,CACjB,EC4DI,MAAMC,EAAmB,OAwBnBC,EAAkB,QAyCH,IDxE5B,cAAyBC,EAIvB,WAAA7J,CAAYrF,GACViI,QAqBO7W,KlBvFE+d,SkBuFF/d,KlBvFiB+d,OAAS1O,SAASuE,IkB6F1C5T,KAAKge,QAAU,UAEA/W,IAAX2H,GACF5O,KAAKie,cAAcrP,EAEtB,CAQD,GAAAb,CAAIzJ,GACF,IAAI+H,EAIJ,OAHIrM,KAAKge,SAAWhe,KAAKge,QAAQxG,eAAelT,KAC9C+H,EAAQrM,KAAKge,QAAQ1Z,IAEhB+H,CACR,CAOD,OAAA6R,GACE,OAAQle,KAAKge,SAAWzT,OAAOC,KAAKxK,KAAKge,UAAa,EACvD,CAOD,aAAAG,GACE,OAAQne,KAAKge,SAAWzT,OAAO6T,OAAO,CAAA,EAAIpe,KAAKge,UAAa,EAC7D,CAKD,aAAAK,GACE,QAASre,KAAKge,OACf,CAMD,MAAAM,CAAOha,EAAKqZ,GACV,IAAIY,EACJA,EAAY,UAAUja,IAClBtE,KAAKic,YAAYsC,IACnBve,KAAKub,cAAc,IAAImC,EAAYa,EAAWja,EAAKqZ,IAErDY,EEpKc,iBFqKVve,KAAKic,YAAYsC,IACnBve,KAAKub,cAAc,IAAImC,EAAYa,EAAWja,EAAKqZ,GAEtD,CAMD,iBAAAa,CAAkBla,EAAKrB,GACrBjD,KAAKqD,iBAAiB,UAAUiB,IAAOrB,EACxC,CAMD,oBAAAwb,CAAqBna,EAAKrB,GACxBjD,KAAKsD,oBAAoB,UAAUgB,IAAOrB,EAC3C,CASD,GAAAyb,CAAIpa,EAAK+H,EAAOsS,GACd,MAAM/P,EAAS5O,KAAKge,UAAYhe,KAAKge,QAAU,CAAA,GAC/C,GAAIW,EACF/P,EAAOtK,GAAO+H,MACT,CACL,MAAMsR,EAAW/O,EAAOtK,GACxBsK,EAAOtK,GAAO+H,EACVsR,IAAatR,GACfrM,KAAKse,OAAOha,EAAKqZ,EAEpB,CACF,CASD,aAAAM,CAAcrP,EAAQ+P,GACpB,IAAK,MAAMra,KAAOsK,EAChB5O,KAAK0e,IAAIpa,EAAKsK,EAAOtK,GAAMqa,EAE9B,CAOD,eAAAC,CAAgBlN,GACTA,EAAOsM,SAGZzT,OAAO6T,OAAOpe,KAAKge,UAAYhe,KAAKge,QAAU,IAAKtM,EAAOsM,QAC3D,CAQD,KAAAa,CAAMva,EAAKqa,GACT,GAAI3e,KAAKge,SAAW1Z,KAAOtE,KAAKge,QAAS,CACvC,MAAML,EAAW3d,KAAKge,QAAQ1Z,UACvBtE,KAAKge,QAAQ1Z,GL1OnB,SAAiBwW,GACtB,IAAIzQ,EACJ,IAAKA,KAAYyQ,EACf,OAAO,EAET,OAAQzQ,CACV,CKqOUyU,CAAQ9e,KAAKge,WACfhe,KAAKge,QAAU,MAEZW,GACH3e,KAAKse,OAAOha,EAAKqZ,EAEpB,CACF,GG9MH,MAAMoB,UAAqB/K,EAIzB,WAAAC,CAAYC,GAOV2C,MAAM,CACJzC,QAAS,EACTE,oBAJ2BrN,IAA3BiN,EAAQI,gBAA+BJ,EAAQI,eAK/CrH,cAA+BhG,IAArBiN,EAAQjH,SAAyBiH,EAAQjH,SAAW,EAC9DC,WAAyBjG,IAAlBiN,EAAQhH,MAAsBgH,EAAQhH,MAAQ,EACrDyH,kBAC2B1N,IAAzBiN,EAAQS,aAA6BT,EAAQS,aAAe,CAAC,EAAG,GAClEE,cAAeX,EAAQW,gBAOzB7U,KAAKgf,aAAU/X,EAMfjH,KAAKif,oBAAsB,KAM3Bjf,KAAKkf,WAAyBjY,IAAjBiN,EAAQiL,KAAqBjL,EAAQiL,KAAO,KAMzDnf,KAAKof,QAAU,CAAC,EAAG,GAMnBpf,KAAKqf,QAAUnL,EAAQnD,OAMvB/Q,KAAKsf,aACgBrY,IAAnBiN,EAAQ3E,OAAuB2E,EAAQ3E,OAAS2E,EAAQqL,QAM1Dvf,KAAKwf,SAAWtL,EAAQuL,QAMxBzf,KAAK0f,YAA2BzY,IAAlBiN,EAAQyL,MAAsBzL,EAAQyL,MAAQ,EAM5D3f,KAAK4f,aAA6B3Y,IAAnBiN,EAAQ1E,OAAuB0E,EAAQ1E,OAAS,KAM/DxP,KAAK6f,MAAQ,KAMb7f,KAAK8f,eAAiB,KAEtB9f,KAAKwJ,QACN,CAOD,KAAAsL,GACE,MAAM5H,EAAQlN,KAAK+U,WACbhM,EAAQ,IAAIgW,EAAa,CAC7BI,KAAMnf,KAAK+f,UAAY/f,KAAK+f,UAAUjL,aAAU7N,EAChD8J,OAAQ/Q,KAAKggB,YACbzQ,OAAQvP,KAAKigB,YACbR,QAASzf,KAAKkgB,aACdP,MAAO3f,KAAKmgB,WACZ3Q,OAAQxP,KAAKogB,YAAcpgB,KAAKogB,YAAYtL,aAAU7N,EACtDgG,SAAUjN,KAAKkV,cACfZ,eAAgBtU,KAAKmV,oBACrBjI,MAAOtK,MAAMmR,QAAQ7G,GAASA,EAAM+H,QAAU/H,EAC9CyH,aAAc3U,KAAKoV,kBAAkBH,QACrCJ,cAAe7U,KAAKqV,qBAGtB,OADAtM,EAAMkN,WAAWjW,KAAKgV,cACfjM,CACR,CAQD,SAAAwM,GACE,MAAMrH,EAAOlO,KAAK6f,MAClB,IAAK3R,EACH,OAAO,KAET,MAAMyG,EAAe3U,KAAKoV,kBACpBlI,EAAQlN,KAAKsV,gBAGnB,MAAO,CACLpH,EAAK,GAAK,EAAIyG,EAAa,GAAKzH,EAAM,GACtCgB,EAAK,GAAK,EAAIyG,EAAa,GAAKzH,EAAM,GAEzC,CAOD,QAAAiT,GACE,OAAOngB,KAAK0f,MACb,CAOD,OAAAK,GACE,OAAO/f,KAAKkf,KACb,CAOD,OAAAmB,CAAQlB,GACNnf,KAAKkf,MAAQC,EACbnf,KAAKwJ,QACN,CAKD,oBAAAkM,GAIE,OAHK1V,KAAKif,qBACRjf,KAAKsgB,0BAA0BtgB,KAAK8f,gBAE/B9f,KAAKif,mBACb,CAQD,QAAAzJ,CAASC,GACP,IAAI8K,EAAQvgB,KAAKgf,QAAQvJ,GACzB,IAAK8K,EAAO,CACV,MAAMC,EAAgBxgB,KAAK8f,eACrBW,EAAU/G,EACd8G,EAActS,KAAOuH,EACrB+K,EAActS,KAAOuH,GAEvBzV,KAAK0gB,MAAMF,EAAeC,EAAShL,GAEnC8K,EAAQE,EAAQ1N,OAChB/S,KAAKgf,QAAQvJ,GAAc8K,CAC5B,CACD,OAAOA,CACR,CAOD,aAAA5K,CAAcF,GACZ,OAAOA,CACR,CAKD,YAAAI,GACE,OAAO7V,KAAK6f,KACb,CAKD,aAAAjK,GACE,OCrQM,CDsQP,CAOD,SAAAE,GACE,OAAO9V,KAAKof,OACb,CAOD,SAAAY,GACE,OAAOhgB,KAAKqf,OACb,CAOD,SAAAY,GACE,OAAOjgB,KAAKsf,OACb,CAOD,UAAAY,GACE,OAAOlgB,KAAKwf,QACb,CAOD,OAAAzJ,GACE,OAAO/V,KAAK6f,KACb,CAOD,SAAAO,GACE,OAAOpgB,KAAK4f,OACb,CAOD,SAAAe,CAAUnR,GACRxP,KAAK4f,QAAUpQ,EACfxP,KAAKwJ,QACN,CAKD,iBAAA6M,CAAkBpT,GAAY,CAK9B,IAAAqT,GAAS,CAKT,mBAAAC,CAAoBtT,GAAY,CAUhC,sBAAA2d,CAAuBC,EAAUC,EAAaC,GAC5C,GACkB,IAAhBD,GACiBE,WAAjBhhB,KAAKqf,SACS,UAAbwB,GAAqC,UAAbA,EAEzB,OAAOC,EAwBT,IAAIG,EAAKjhB,KAAKsf,QACV4B,OAAuBja,IAAlBjH,KAAKwf,SAAyByB,EAAKjhB,KAAKwf,SACjD,GAAIyB,EAAKC,EAAI,CACX,MAAMC,EAAMF,EACZA,EAAKC,EACLA,EAAKC,CACN,CACD,MAEMC,EAAS,EAAIhiB,KAAKiiB,SADJpa,IAAlBjH,KAAKwf,SAAyBxf,KAAKqf,QAAyB,EAAfrf,KAAKqf,SAE9C1H,EAAIuJ,EAAK9hB,KAAKkiB,IAAIF,GAElBpb,EAAIib,EADA7hB,KAAKQ,KAAKshB,EAAKA,EAAKvJ,EAAIA,GAE5B4J,EAAIniB,KAAKQ,KAAK+X,EAAIA,EAAI3R,EAAIA,GAC1Bwb,EAAaD,EAAI5J,EACvB,GAAiB,UAAbkJ,GAAwBW,GAAcT,EACxC,OAAOS,EAAaV,EAetB,MAAMW,EAAIX,EAAc,EAAIU,EACtBE,EAAKZ,EAAc,GAAM9a,EAAIub,GAE7BI,EADOviB,KAAKQ,MAAMqhB,EAAKQ,IAAMR,EAAKQ,GAAKC,EAAIA,GACzBT,EACxB,QAAsBha,IAAlBjH,KAAKwf,UAAuC,UAAbqB,EACjC,OAAkB,EAAXc,EAIT,MAAMC,EAAKX,EAAK7hB,KAAKkiB,IAAIF,GAEnBS,EAAKX,EADA9hB,KAAKQ,KAAKqhB,EAAKA,EAAKW,EAAKA,GAG9BE,EADK1iB,KAAKQ,KAAKgiB,EAAKA,EAAKC,EAAKA,GACPD,EAC7B,OAAIE,GAAmBf,EAEd,EAAI3hB,KAAK6X,IAAI0K,EADCG,EAAkBhB,EAAe,EAAII,EAAKD,GAG/C,EAAXU,CACR,CAMD,mBAAAI,GACE,IAIIC,EAJAnB,EAAWhD,EACXkD,EAAa,EACbkB,EAAW,KACXC,EAAiB,EAEjBpB,EAAc,EAEd9gB,KAAK4f,UACPoC,EAAchiB,KAAK4f,QAAQuC,WACP,OAAhBH,IACFA,EFtU0B,QEwU5BA,EAAcjJ,EAAYiJ,GAC1BlB,EAAc9gB,KAAK4f,QAAQwC,gBACPnb,IAAhB6Z,IACFA,EFnTwB,GEqT1BmB,EAAWjiB,KAAK4f,QAAQyC,cACxBH,EAAiBliB,KAAK4f,QAAQ0C,oBAC9BzB,EAAW7gB,KAAK4f,QAAQ2C,mBACPtb,IAAb4Z,IACFA,EAAWhD,GAEbkD,EAAa/gB,KAAK4f,QAAQ4C,qBACPvb,IAAf8Z,IACFA,EF3VyB,KE+V7B,MAAMvc,EAAMxE,KAAK4gB,uBAAuBC,EAAUC,EAAaC,GACzD0B,EAAYrjB,KAAK6X,IAAIjX,KAAKsf,QAAStf,KAAKwf,UAAY,GAG1D,MAAO,CACLwC,YAAaA,EACblB,YAAaA,EACb5S,KALW9O,KAAKsjB,KAAK,EAAID,EAAYje,GAMrCyd,SAAUA,EACVC,eAAgBA,EAChBrB,SAAUA,EACVE,WAAYA,EAEf,CAKD,MAAAvX,GACExJ,KAAK8f,eAAiB9f,KAAK+hB,sBAC3B,MAAM7T,EAAOlO,KAAK8f,eAAe5R,KACjClO,KAAKgf,QAAU,GACfhf,KAAK6f,MAAQ,CAAC3R,EAAMA,EACrB,CAQD,KAAAwS,CAAMF,EAAeC,EAAShL,GAO5B,GANAgL,EAAQvT,MAAMuI,EAAYA,GAE1BgL,EAAQkC,UAAUnC,EAActS,KAAO,EAAGsS,EAActS,KAAO,GAE/DlO,KAAK4iB,YAAYnC,GAEbzgB,KAAKkf,MAAO,CACd,IAAIzP,EAAQzP,KAAKkf,MAAMiD,WACT,OAAV1S,IACFA,EAAQmO,GAEV6C,EAAQoC,UAAY9J,EAAYtJ,GAChCgR,EAAQtB,MACT,CACGnf,KAAK4f,UACPa,EAAQuB,YAAcxB,EAAcwB,YACpCvB,EAAQqC,UAAYtC,EAAcM,YAC9BN,EAAcyB,WAChBxB,EAAQsC,YAAYvC,EAAcyB,UAClCxB,EAAQyB,eAAiB1B,EAAc0B,gBAEzCzB,EAAQI,SAAWL,EAAcK,SACjCJ,EAAQM,WAAaP,EAAcO,WACnCN,EAAQjR,SAEX,CAMD,yBAAA8Q,CAA0BE,GACxB,GAAIxgB,KAAKkf,MAAO,CACd,IAAIzP,EAAQzP,KAAKkf,MAAMiD,WAGnB/N,EAAU,EASd,GARqB,iBAAV3E,IACTA,EhBxaD,SAAiBA,GACtB,OAAI7M,MAAMmR,QAAQtE,GACTA,EAEA2H,EAAW3H,EAEtB,CgBkagBuT,CAAQvT,IAEJ,OAAVA,EACF2E,EAAU,EACDxR,MAAMmR,QAAQtE,KACvB2E,EAA2B,IAAjB3E,EAAMxE,OAAewE,EAAM,GAAK,GAE5B,IAAZ2E,EAAe,CAGjB,MAAMqM,EAAU/G,EACd8G,EAActS,KACdsS,EAActS,MAEhBlO,KAAKif,oBAAsBwB,EAAQ1N,OAEnC/S,KAAKijB,wBAAwBzC,EAAeC,EAC7C,CACF,CACIzgB,KAAKif,sBACRjf,KAAKif,oBAAsBjf,KAAKwV,SAAS,GAE5C,CAMD,WAAAoN,CAAYnC,GACV,IAAI1P,EAAS/Q,KAAKqf,QAClB,MAAM9P,EAASvP,KAAKsf,QACpB,GAAe0B,WAAXjQ,EACF0P,EAAQyC,IAAI,EAAG,EAAG3T,EAAQ,EAAG,EAAInQ,KAAKiiB,QACjC,CACL,MAAM5B,OAA4BxY,IAAlBjH,KAAKwf,SAAyBjQ,EAASvP,KAAKwf,cACtCvY,IAAlBjH,KAAKwf,WACPzO,GAAU,GAEZ,MAAMoS,EAAanjB,KAAK0f,OAAStgB,KAAKiiB,GAAK,EACrC+B,EAAQ,EAAIhkB,KAAKiiB,GAAMtQ,EAC7B,IAAK,IAAI/F,EAAI,EAAGA,EAAI+F,EAAQ/F,IAAK,CAC/B,MAAMqY,EAASF,EAAanY,EAAIoY,EAC1BE,EAAUtY,EAAI,GAAM,EAAIuE,EAASkQ,EACvCgB,EAAQ8C,OAAOD,EAAUlkB,KAAKokB,IAAIH,GAASC,EAAUlkB,KAAKkiB,IAAI+B,GAC/D,CACD5C,EAAQgD,WACT,CACF,CAOD,uBAAAR,CAAwBzC,EAAeC,GAErCA,EAAQkC,UAAUnC,EAActS,KAAO,EAAGsS,EAActS,KAAO,GAE/DlO,KAAK4iB,YAAYnC,GAEjBA,EAAQoC,UAAYjF,EACpB6C,EAAQtB,OACJnf,KAAK4f,UACPa,EAAQuB,YAAcxB,EAAcwB,YACpCvB,EAAQqC,UAAYtC,EAAcM,YAC9BN,EAAcyB,WAChBxB,EAAQsC,YAAYvC,EAAcyB,UAClCxB,EAAQyB,eAAiB1B,EAAc0B,gBAEzCzB,EAAQI,SAAWL,EAAcK,SACjCJ,EAAQM,WAAaP,EAAcO,WACnCN,EAAQjR,SAEX,EAGH,IAAAkU,EAAe3E,EErlBf,MAAM4E,UAAoB5E,EAIxB,WAAA9K,CAAYC,GAGV2C,MAAM,CACJ9F,OAAQiQ,SACR7B,MAJFjL,EAAUA,GAAoB,CAAC3E,OAAQ,IAIvB4P,KACd5P,OAAQ2E,EAAQ3E,OAChBC,OAAQ0E,EAAQ1E,OAChBtC,WAAyBjG,IAAlBiN,EAAQhH,MAAsBgH,EAAQhH,MAAQ,EACrDD,cAA+BhG,IAArBiN,EAAQjH,SAAyBiH,EAAQjH,SAAW,EAC9DqH,oBAC6BrN,IAA3BiN,EAAQI,gBAA+BJ,EAAQI,eACjDK,kBAC2B1N,IAAzBiN,EAAQS,aAA6BT,EAAQS,aAAe,CAAC,EAAG,GAClEE,cAAeX,EAAQW,eAE1B,CAOD,KAAAC,GACE,MAAM5H,EAAQlN,KAAK+U,WACbhM,EAAQ,IAAI4a,EAAY,CAC5BxE,KAAMnf,KAAK+f,UAAY/f,KAAK+f,UAAUjL,aAAU7N,EAChDuI,OAAQxP,KAAKogB,YAAcpgB,KAAKogB,YAAYtL,aAAU7N,EACtDsI,OAAQvP,KAAKigB,YACb/S,MAAOtK,MAAMmR,QAAQ7G,GAASA,EAAM+H,QAAU/H,EAC9CD,SAAUjN,KAAKkV,cACfZ,eAAgBtU,KAAKmV,oBACrBR,aAAc3U,KAAKoV,kBAAkBH,QACrCJ,cAAe7U,KAAKqV,qBAGtB,OADAtM,EAAMkN,WAAWjW,KAAKgV,cACfjM,CACR,CAQD,SAAA6a,CAAUrU,GACRvP,KAAKsf,QAAU/P,EACfvP,KAAKwJ,QACN,EAGH,IAAAqa,EAAeF,ECjEf,MAAMG,EAIJ,WAAA7P,CAAYC,GAOVlU,KAAK+jB,YAA2B9c,KANhCiN,EAAUA,GAAW,IAMCzE,MAAsByE,EAAQzE,MAAQ,IAC7D,CAOD,KAAAqF,GACE,MAAMrF,EAAQzP,KAAKmiB,WACnB,OAAO,IAAI2B,EAAK,CACdrU,MAAO7M,MAAMmR,QAAQtE,GAASA,EAAMwF,QAAUxF,QAASxI,GAE1D,CAOD,QAAAkb,GACE,OAAOniB,KAAK+jB,MACb,CAQD,QAAAC,CAASvU,GACPzP,KAAK+jB,OAAStU,CACf,EAGH,IAAAwU,EAAeH,ECrCf,MAAMI,EAIJ,WAAAjQ,CAAYC,GAOVlU,KAAK+jB,YAA2B9c,KANhCiN,EAAUA,GAAW,IAMCzE,MAAsByE,EAAQzE,MAAQ,KAM5DzP,KAAKmkB,SAAWjQ,EAAQkQ,QAMxBpkB,KAAKqkB,eAAiCpd,IAArBiN,EAAQ+N,SAAyB/N,EAAQ+N,SAAW,KAMrEjiB,KAAKskB,gBAAkBpQ,EAAQgO,eAM/BliB,KAAKukB,UAAYrQ,EAAQ2M,SAMzB7gB,KAAKwkB,YAActQ,EAAQ6M,WAM3B/gB,KAAKykB,OAASvQ,EAAQyF,KACvB,CAOD,KAAA7E,GACE,MAAMrF,EAAQzP,KAAKmiB,WACnB,OAAO,IAAI+B,EAAO,CAChBzU,MAAO7M,MAAMmR,QAAQtE,GAASA,EAAMwF,QAAUxF,QAASxI,EACvDmd,QAASpkB,KAAK0kB,aACdzC,SAAUjiB,KAAKqiB,cAAgBriB,KAAKqiB,cAAcpN,aAAUhO,EAC5Dib,eAAgBliB,KAAKsiB,oBACrBzB,SAAU7gB,KAAKuiB,cACfxB,WAAY/gB,KAAKwiB,gBACjB7I,MAAO3Z,KAAKoiB,YAEf,CAOD,QAAAD,GACE,OAAOniB,KAAK+jB,MACb,CAOD,UAAAW,GACE,OAAO1kB,KAAKmkB,QACb,CAOD,WAAA9B,GACE,OAAOriB,KAAKqkB,SACb,CAOD,iBAAA/B,GACE,OAAOtiB,KAAKskB,eACb,CAOD,WAAA/B,GACE,OAAOviB,KAAKukB,SACb,CAOD,aAAA/B,GACE,OAAOxiB,KAAKwkB,WACb,CAOD,QAAApC,GACE,OAAOpiB,KAAKykB,MACb,CAQD,QAAAT,CAASvU,GACPzP,KAAK+jB,OAAStU,CACf,CAQD,UAAAkV,CAAWP,GACTpkB,KAAKmkB,SAAWC,CACjB,CAQD,WAAArB,CAAYd,GACVjiB,KAAKqkB,UAAYpC,CAClB,CAQD,iBAAA2C,CAAkB1C,GAChBliB,KAAKskB,gBAAkBpC,CACxB,CAQD,WAAA2C,CAAYhE,GACV7gB,KAAKukB,UAAY1D,CAClB,CAQD,aAAAiE,CAAc/D,GACZ/gB,KAAKwkB,YAAczD,CACpB,CAQD,QAAAgE,CAASpL,GACP3Z,KAAKykB,OAAS9K,CACf,EAGH,IAAAqL,EAAed,EC5Ef,MAAMe,EAIJ,WAAAhR,CAAYC,GACVA,EAAUA,GAAW,GAMrBlU,KAAKklB,UAAY,KAMjBllB,KAAKmlB,kBAAoBC,OAEAne,IAArBiN,EAAQxJ,UACV1K,KAAK6K,YAAYqJ,EAAQxJ,UAO3B1K,KAAKkf,WAAyBjY,IAAjBiN,EAAQiL,KAAqBjL,EAAQiL,KAAO,KAMzDnf,KAAKqlB,YAA2Bpe,IAAlBiN,EAAQqM,MAAsBrM,EAAQqM,MAAQ,KAM5DvgB,KAAKslB,eAAiCre,IAArBiN,EAAQqR,SAAyBrR,EAAQqR,SAAW,KAMrEvlB,KAAKwlB,2BAC8Bve,IAAjCiN,EAAQuR,qBACJvR,EAAQuR,qBACR,KAMNzlB,KAAK4f,aAA6B3Y,IAAnBiN,EAAQ1E,OAAuB0E,EAAQ1E,OAAS,KAM/DxP,KAAK0lB,WAAyBze,IAAjBiN,EAAQyR,KAAqBzR,EAAQyR,KAAO,KAMzD3lB,KAAK4lB,QAAU1R,EAAQzF,MACxB,CAOD,KAAAqG,GACE,IAAIpK,EAAW1K,KAAKmM,cAMpB,OALIzB,GAAgC,iBAAbA,IACrBA,EAAgE,EAE9DoK,SAEG,IAAImQ,EAAM,CACfva,SAAUA,EACVyU,KAAMnf,KAAK+f,UAAY/f,KAAK+f,UAAUjL,aAAU7N,EAChDsZ,MAAOvgB,KAAKwV,WAAaxV,KAAKwV,WAAWV,aAAU7N,EACnDse,SAAUvlB,KAAK6lB,cACfrW,OAAQxP,KAAKogB,YAAcpgB,KAAKogB,YAAYtL,aAAU7N,EACtD0e,KAAM3lB,KAAK8lB,UAAY9lB,KAAK8lB,UAAUhR,aAAU7N,EAChDwH,OAAQzO,KAAK+lB,aAEhB,CAQD,WAAAF,GACE,OAAO7lB,KAAKslB,SACb,CAQD,WAAAU,CAAYT,GACVvlB,KAAKslB,UAAYC,CAClB,CAQD,uBAAAU,CAAwBV,GACtBvlB,KAAKwlB,sBAAwBD,CAC9B,CAQD,uBAAAW,GACE,OAAOlmB,KAAKwlB,qBACb,CASD,WAAArZ,GACE,OAAOnM,KAAKklB,SACb,CAQD,mBAAAiB,GACE,OAAOnmB,KAAKmlB,iBACb,CAOD,OAAApF,GACE,OAAO/f,KAAKkf,KACb,CAOD,OAAAmB,CAAQlB,GACNnf,KAAKkf,MAAQC,CACd,CAOD,QAAA3J,GACE,OAAOxV,KAAKqlB,MACb,CAOD,QAAAe,CAAS7F,GACPvgB,KAAKqlB,OAAS9E,CACf,CAOD,SAAAH,GACE,OAAOpgB,KAAK4f,OACb,CAOD,SAAAe,CAAUnR,GACRxP,KAAK4f,QAAUpQ,CAChB,CAOD,OAAAsW,GACE,OAAO9lB,KAAK0lB,KACb,CAOD,OAAAW,CAAQV,GACN3lB,KAAK0lB,MAAQC,CACd,CAOD,SAAAI,GACE,OAAO/lB,KAAK4lB,OACb,CAUD,WAAA/a,CAAYH,GACc,mBAAbA,EACT1K,KAAKmlB,kBAAoBza,EACI,iBAAbA,EAChB1K,KAAKmlB,kBAAoB,SAAUxZ,GACjC,OACEA,EAAQoC,IAAIrD,EAEtB,EACgBA,OAEYzD,IAAbyD,IACT1K,KAAKmlB,kBAAoB,WACvB,OAAA,CACR,GAJMnlB,KAAKmlB,kBAAoBC,EAM3BplB,KAAKklB,UAAYxa,CAClB,CAQD,SAAA4b,CAAU7X,GACRzO,KAAK4lB,QAAUnX,CAChB,EA6IH,SAAS2W,EAAwBzZ,GAC/B,OAAOA,EAAQQ,aACjB,CAEA,IAAAoa,EAAetB,ECzgBR,MAAMuB,GAAkB,CAE7BC,QAAW,SAAW,EAAIrnB,KAAKiiB,IAC/BqF,QAAY,EAAItnB,KAAKiiB,GAAK,QAAW,IACrCsF,GAAM,MACNC,EAAK,EACL,QAAS,KAAO,MC4NlB,IAAAC,GA3NA,MAIE,WAAA5S,CAAYC,GAKVlU,KAAK8mB,MAAQ5S,EAAQyC,KASrB3W,KAAK+mB,OAAoD7S,EAAa,MAStElU,KAAKgnB,aAA6B/f,IAAnBiN,EAAQ+S,OAAuB/S,EAAQ+S,OAAS,KAS/DjnB,KAAKknB,kBACqBjgB,IAAxBiN,EAAQiT,YAA4BjT,EAAQiT,YAAc,KAM5DnnB,KAAKonB,sBACyBngB,IAA5BiN,EAAQmT,gBAAgCnT,EAAQmT,gBAAkB,MAMpErnB,KAAKsnB,aAA6BrgB,IAAnBiN,EAAQqT,QAAuBrT,EAAQqT,OAMtDvnB,KAAKwnB,aAAexnB,KAAKsnB,UAAWtnB,KAAKgnB,SAMzChnB,KAAKynB,wBAA0BvT,EAAQwT,mBAMvC1nB,KAAK2nB,iBAAmB,KAMxB3nB,KAAK4nB,eAAiB1T,EAAQ2T,aAC/B,CAKD,QAAAC,GACE,OAAO9nB,KAAKwnB,SACb,CAOD,OAAAO,GACE,OAAO/nB,KAAK8mB,KACb,CAOD,SAAAkB,GACE,OAAOhoB,KAAKgnB,OACb,CAOD,QAAAiB,GACE,OAAOjoB,KAAK+mB,MACb,CASD,gBAAAmB,GACE,OAAOloB,KAAK4nB,gBAAkBpB,GAAgBxmB,KAAK+mB,OACpD,CAOD,cAAAoB,GACE,OAAOnoB,KAAKknB,YACb,CAaD,kBAAAkB,GACE,OAAOpoB,KAAKonB,gBACb,CAOD,QAAAiB,GACE,OAAOroB,KAAKsnB,OACb,CAOD,SAAAgB,CAAUf,GACRvnB,KAAKsnB,QAAUC,EACfvnB,KAAKwnB,aAAeD,IAAUvnB,KAAKgnB,QACpC,CAKD,kBAAAuB,GACE,OAAOvoB,KAAK2nB,gBACb,CAKD,kBAAAa,CAAmBC,GACjBzoB,KAAK2nB,iBAAmBc,CACzB,CAOD,SAAAC,CAAUzB,GACRjnB,KAAKgnB,QAAUC,EACfjnB,KAAKwnB,aAAexnB,KAAKsnB,UAAWL,EACrC,CAQD,cAAA0B,CAAexB,GACbnnB,KAAKknB,aAAeC,CACrB,CAQD,qBAAAyB,CAAsBC,GACpB7oB,KAAKynB,wBAA0BoB,CAChC,CAOD,sBAAAC,GACE,OAAO9oB,KAAKynB,uBACb,GChQI,MAAMsB,GAAS,QAMTC,GAAY5pB,KAAKiiB,GAAK0H,GAMtBE,GAAS,EAAED,IAAYA,GAAWA,GAAWA,IAM7CE,GAAe,EAAE,KAAM,GAAI,IAAK,IAOhCC,GAAaJ,GAAS3pB,KAAKgqB,IAAIhqB,KAAKiqB,IAAIjqB,KAAKiiB,GAAK,IAM/D,MAAMiI,WAA2BC,GAI/B,WAAAtV,CAAY0C,GACVE,MAAM,CACJF,KAAMA,EACN6S,MAAO,IACPvC,OAAQgC,GACR1B,QAAQ,EACRJ,YAAa+B,GACbxB,mBAAoB,SAAU+B,EAAYphB,GACxC,OAAOohB,EAAarqB,KAAKsqB,KAAKrhB,EAAM,GAAK0gB,GAC1C,GAEJ,EASI,MAAMY,GAAc,CACzB,IAAIL,GAAmB,aACvB,IAAIA,GAAmB,eACvB,IAAIA,GAAmB,eACvB,IAAIA,GAAmB,eACvB,IAAIA,GAAmB,8CACvB,IAAIA,GAAmB,iDCrDZL,GAAS,EAAE,KAAM,GAAI,IAAK,IAM1BzC,GAdS,QAcUpnB,KAAKiiB,GAAe,IAUpD,MAAMuI,WAA2BL,GAK/B,WAAAtV,CAAY0C,EAAM0Q,GAChBxQ,MAAM,CACJF,KAAMA,EACN6S,MAAO,UACPvC,OAAQgC,GACR5B,gBAAiBA,EACjBE,QAAQ,EACRM,cAAerB,GACfW,YAAa8B,IAEhB,EASI,MAAMU,GAAc,CACzB,IAAIC,GAAmB,UACvB,IAAIA,GAAmB,YAAa,OACpC,IAAIA,GAAmB,iCACvB,IAAIA,GAAmB,4BACvB,IAAIA,GAAmB,gDACvB,IAAIA,GAAmB,+CAAgD,OACvE,IAAIA,GAAmB,6CAA8C,QC3DvE,IAAIvS,GAAQ,CAAA,ECERwS,GAAa,CAAA,EAiBV,SAASrlB,GAAIkN,EAAQoY,EAAaC,GACvC,MAAMC,EAAatY,EAAOqW,UACpBkC,EAAkBH,EAAY/B,UAC9BiC,KAAcH,KAClBA,GAAWG,GAAc,IAE3BH,GAAWG,GAAYC,GAAmBF,CAC5C,CCmFO,SAASG,GAAeC,EAAOC,EAAQC,GAC5C,QAAepjB,IAAXmjB,EACF,IAAK,IAAIpf,EAAI,EAAG6Q,EAAKsO,EAAMlf,OAAQD,EAAI6Q,IAAM7Q,EAC3Cof,EAAOpf,GAAKmf,EAAMnf,QAIpBof,EAASD,EAAMlV,QAEjB,OAAOmV,CACT,CAQO,SAASE,GAAkBH,EAAOC,EAAQC,GAC/C,QAAepjB,IAAXmjB,GAAwBD,IAAUC,EAAQ,CAC5C,IAAK,IAAIpf,EAAI,EAAG6Q,EAAKsO,EAAMlf,OAAQD,EAAI6Q,IAAM7Q,EAC3Cof,EAAOpf,GAAKmf,EAAMnf,GAEpBmf,EAAQC,CACT,CACD,OAAOD,CACT,CASO,SAASI,GAAcxiB,IFrHvB,SAAa4O,EAAM5O,GACxBsP,GAAMV,GAAQ5O,CAChB,CEoHEyiB,CAAQziB,EAAWggB,UAAWhgB,GAC9B0iB,GAAiB1iB,EAAYA,EAAYmiB,GAC3C,CAkBO,SAASnc,GAAI2c,GAClB,MAAiC,iBAAnBA,EFtJZrT,GAFgBV,EEyJiB,IFtJjCU,GAAMV,EAAKgU,QAAQ,yCAA0C,aAC7D,KEsJ4B,GAAoB,KF1J7C,IAAahU,CE2JpB,CAoFO,SAASiU,GAAyBC,IArGlC,SAAwBA,GAC7BA,EAAY7nB,QAAQunB,GACtB,CAoGEO,CAAeD,GACfA,EAAY7nB,QAAQ,SAAU0O,GAC5BmZ,EAAY7nB,QAAQ,SAAU8mB,GACxBpY,IAAWoY,GACbW,GAAiB/Y,EAAQoY,EAAaI,GAE9C,EACA,EACA,CA2OO,SAASa,GAAU7f,EAAYwG,EAAQoY,GAC5C,MAAMkB,EArBD,SAAsBtZ,EAAQoY,GAGnC,OA1BK,SACLmB,EACAC,GAIA,IAAIF,EDtZC,SAAahB,EAAYC,GAC9B,IAAIc,EAIJ,OAHIf,KAAcH,IAAcI,KAAmBJ,GAAWG,KAC5De,EAAYlB,GAAWG,GAAYC,IAE9Bc,CACT,CCgZsBI,CAFDF,EAAiBlD,UACZmD,EAAsBnD,WAK9C,OAHKiD,IACHA,EAAgBV,IAEXU,CACT,CAeSI,CAFkBrd,GAAI2D,GACC3D,GAAI+b,GAEpC,CAiBwBuB,CAAa3Z,EAAQoY,GAC3C,OAAOkB,EAAc9f,OAAYjE,EAAWiE,EAAWD,OACzD,CAuOO,IApcLqgB,GACAC,GACAC,GAqcAZ,GAAyBa,IACzBb,GAAyBc,IAxczBJ,GA6cEG,GA5cFF,GJ5MK,SAAsBpB,EAAOC,EAAQC,GAC1C,MAAMpf,EAASkf,EAAMlf,OACrBof,EAAYA,EAAY,EAAIA,EAAY,OACzBpjB,IAAXmjB,IAGAA,EAFEC,EAAY,EAELF,EAAMlV,QAEN,IAAIrS,MAAMqI,IAGvB,IAAK,IAAID,EAAI,EAAGA,EAAIC,EAAQD,GAAKqf,EAAW,CAC1CD,EAAOpf,GAAMge,GAAYmB,EAAMnf,GAAM,IACrC,IAAItL,EAAIqpB,GAAS3pB,KAAKgqB,IAAIhqB,KAAKiqB,IAAKjqB,KAAKiiB,KAAO8I,EAAMnf,EAAI,GAAK,IAAO,MAClEtL,EAAIypB,GACNzpB,EAAIypB,GACKzpB,GAAKypB,KACdzpB,GAAKypB,IAEPiB,EAAOpf,EAAI,GAAKtL,CACjB,CACD,OAAO0qB,CACT,EIuLEoB,GJ7KK,SAAoBrB,EAAOC,EAAQC,GACxC,MAAMpf,EAASkf,EAAMlf,OACrBof,EAAYA,EAAY,EAAIA,EAAY,OACzBpjB,IAAXmjB,IAGAA,EAFEC,EAAY,EAELF,EAAMlV,QAEN,IAAIrS,MAAMqI,IAGvB,IAAK,IAAID,EAAI,EAAGA,EAAIC,EAAQD,GAAKqf,EAC/BD,EAAOpf,GAAM,IAAMmf,EAAMnf,GAAMge,GAC/BoB,EAAOpf,EAAI,GACR,IAAM5L,KAAKusB,KAAKvsB,KAAKwsB,IAAIzB,EAAMnf,EAAI,GAAK+d,KAAY3pB,KAAKiiB,GAAK,GAEnE,OAAO+I,CACT,EIsmBIsB,GAxcW1oB,QAAQ,SAAU6oB,GAC7BP,GAAatoB,QAAQ,SAAU8oB,GAC7BrB,GAAiBoB,EAAaC,EAAaP,IAC3Cd,GAAiBqB,EAAaD,EAAaL,GACjD,EACA,GCtQa,ICNDO,GDMCC,gBAA2BpnB,SAAAA,GACvC,SAAAonB,EACCzrB,GAGqB,IAAAR,GAErBA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAOP,MA0BNisB,gBAAkB,WAAO,MAAA,EAAE,EAAClsB,EAE5BiF,UAAIjF,EAAAA,EACJkF,UAAI,EAAAlF,EACJsO,gBAAUtO,EAAAA,EACVmsB,YAAc,YAAoBnsB,EAClCosB,mBAAapsB,EAAAA,EACbqsB,oBAAc,EA/BrBrsB,EAAKkF,KAAO1E,EAAOgF,IACnBxF,EAAKiF,KAAOzE,EAAO+E,IAEnBvF,EAAKqsB,eAAiB,IAAIrsB,EAAKiF,KAAKqnB,QAEpCtsB,EAAKsO,WAAatO,EAAKkF,KAAKqnB,cAG5BvsB,EAAKsO,WAAWke,aAAa,WAAY,KAEzC,IAAMC,EAAe,IAAIzsB,EAAKiF,KAAKynB,aAAa,CAC/C5gB,SAAU,KAGX9L,EAAKosB,cAAgBK,EAErB,IAAME,EAAc,IAAI3sB,EAAKiF,KAAK2nB,YAAY,CAC7Cjb,OAAQ8a,EACRzjB,MAAO,SAAC4C,GAAO,OAAK5L,EAAK6sB,UAAUjhB,EAAS5L,EAAKksB,kBAAkB,IAGpC,OAAhClsB,EAAKkF,KAAKuL,SAASkc,GAAa3sB,CACjC,CA/BuC4F,EAAAqmB,EAAApnB,GA+BtC,IAAAtD,EAAA0qB,EAAAzqB,UAgRAyqB,OAhRA1qB,EAgBOurB,SAAA,SAASC,GAChB,MAAO,CACN/mB,EAAGsS,SAASyU,EAAI7X,MAAM,EAAG,GAAI,IAC7BwC,EAAGY,SAASyU,EAAI7X,MAAM,EAAG,GAAI,IAC7ByC,EAAGW,SAASyU,EAAI7X,MAAM,EAAG,GAAI,IAE/B,EAAC3T,EAQOsrB,UAAA,SAAUjhB,EAAsBjC,OAAiCzD,EAAAjG,KAClE0K,EAAWiB,EAAQQ,cACzB,GAAKzB,EAKL,MAAO,CACN5C,MAAO,SAAC6D,GACP,IAAMlB,EAAakB,EAAQwS,gBACrBpV,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,QAASC,YAAa,IACxCH,WAAAA,IAED,OAAO,IAAIxE,EAAKjB,KAAKigB,MAAM,CAC1B1E,MAAO,IAAIsD,EAAO,CACjBtU,OAAQxG,EAAM0D,WACd0S,KAAM,IAAI2E,EAAK,CACdrU,MAAO1G,EAAM4D,aAEd6C,OAAQ,IAAI0U,EAAO,CAClBzU,MAAO1G,EAAM+D,kBACb6M,MAAO5Q,EAAMiE,uBAIjB,EACA5B,WAAY,SAACO,GACZ,IAAMlB,EAAakB,EAAQwS,gBACrBpV,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,aAAcC,YAAa,IAC7CH,WAAAA,IAED,OAAW,IAAAxE,EAAKjB,KAAKigB,MAAM,CAC1BzV,OAAQ,IAAIvJ,EAAKjB,KAAKkf,OAAO,CAC5BzU,MAAO1G,EAAMoE,gBACbwM,MAAO5Q,EAAMqE,mBAGhB,EACA7B,QAAS,SAACI,GACT,IAAMlB,EAAakB,EAAQwS,gBACrBpV,EAAQW,EAAQe,EAAWuB,MAAM,CACtCrB,KAAM,UACND,SAAU,CAAEC,KAAM,aAAcC,YAAa,IAC7CH,WAAAA,IAEDsiB,EAAoB9mB,EAAK4mB,SAAS9jB,EAAMyE,kBAAhCzH,EAACgnB,EAADhnB,EAAG0R,EAACsV,EAADtV,EAAGC,EAACqV,EAADrV,EAEd,OAAO,IAAIuN,EAAM,CAChBzV,OAAQ,IAAI0U,EAAO,CAClBzU,MAAO1G,EAAMsE,oBACbsM,MAAO5Q,EAAMuE,sBAEd6R,KAAM,IAAI2E,EAAK,CACdrU,MAAe1J,QAAAA,MAAK0R,EAAC,IAAIC,EAAC,IAAI3O,EAAMwE,0BAGvC,GAvDW7C,EAAS0B,WAwDdT,EACR,EAACrK,EAMOmM,YAAA,WACHzN,KAAKmsB,eACRnsB,KAAKmsB,cAAcznB,OAErB,EAACpD,EAEO0rB,WAAA,SAAWrhB,GAClB,IAAI3L,KAAKmsB,gBAAiBnsB,KAAKosB,eAM9B,MAAU,IAAA1mB,MAAM,gCALhB,IAAMunB,EAAYjtB,KAAKosB,eAAec,YAAYvhB,EAAS,CAC1DwhB,kBAAmBntB,KAAKksB,cAEzBlsB,KAAKmsB,cAAca,WAAWC,EAIhC,EAAC3rB,EAEO8rB,cAAA,SAAc3nB,GACrB,IAAIzF,KAAKmsB,cAOR,UAAUzmB,MAAM,gCANhB,IAAM+K,EAAUzQ,KAAKmsB,cAAcniB,eAAevE,GAC7CgL,GAGLzQ,KAAKmsB,cAAciB,cAAc3c,EAInC,EAACnP,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GADV9B,EAAC+C,EAAbX,WAA2BrC,EAACgD,EAAbR,WAEvB,IACC,YAAYsG,UAAU7I,EAAGD,EAC1B,CAAE,MAAO2tB,GACR,OACD,IAAA,CACD,EAAC/rB,EAMMO,mBAAA,WACN,IAAMyrB,EAAWttB,KAAKqO,WAAWkf,iBAAiB,UAElD,GAAID,EAASriB,OAAS,EACrB,MAAMvF,MACL,+DAIF,OAAO4nB,EAAS,EACjB,EAAChsB,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAKiF,KAAKuoB,kBAAkBxqB,QAAQ,SAACyqB,GACC,YAAjCA,EAAYxZ,YAAYhU,MAC3BwtB,EAAYC,UAAU3pB,EAExB,EACD,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAAkrB,EAAe3tB,KAAKiF,KAAK2oB,uBD+JlB7C,GC/JoD,CAACvoB,EAAKC,GDiK/D,YACwC,cCjK1C,MAAO,CAAE9C,EADDguB,KACIjuB,EADDiuB,EACX,GACD,EAACrsB,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAmuB,EDoKK,SAAkB3iB,EAAYnD,GACnC,MAAM+lB,EAAS/C,GACb7f,EACwC,YACxC,aAEI6iB,EAAMD,EAAO,GAInB,OAHIC,GAAO,KAAOA,EAAM,OACtBD,EAAO,G7B7RJ,SAAgBnW,EAAGD,GACxB,MAAM3R,EAAI4R,E6B4RsB,I7B3RhC,O6B2RgC,I7B3RzB5R,EAAQ,EAAIA,E6B2Ra,I7B3RLA,CAC7B,C6B0RgBioB,CAAOD,EAAM,KAAY,KAEhCD,CACT,CC/KqBG,CAASjuB,KAAKiF,KAAKipB,uBAAuB,CAACvuB,EAAGD,KACjE,MAAO,CAAE8C,IADCqrB,EAAEprB,GACEA,IADCorB,KAEhB,EAACvsB,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMsH,eAAe,UAE/CrQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAKiF,KAAKuoB,kBAAkBxqB,QAAQ,SAAUyqB,GACR,oBAAjCA,EAAYxZ,YAAYhU,MAC3BwtB,EAAYC,UAAU3pB,EAExB,EACD,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiC,IAAAC,EACzE3J,KAIA,GAJAA,KAAKisB,gBAAkB,WAAM,OAAAviB,CAAO,GAErB1J,KAAKmsB,cAGnB,MAAM,IAAIzmB,MAAM,uCAGjB+D,EAAQI,WAAW7G,QAAQ,SAACyC,GAC3BkE,EAAKyjB,cAAc3nB,EACpB,GAEAgE,EAAQQ,QAAQjH,QAAQ,SAAC2I,GACxBhC,EAAKyjB,cAAczhB,EAAQlG,IAC3BkE,EAAKqjB,WAAWrhB,EACjB,GAEAlC,EAAQ+B,QAAQxI,QAAQ,SAAC2I,GACxBhC,EAAKqjB,WAAWrhB,EACjB,EACD,EAACrK,EAMMoD,MAAA,WACF1E,KAAKiB,wBAERjB,KAAKiB,sBAAsB4M,UAG3B7N,KAAKyN,cAEP,EAACnM,EAEMlB,SAAA,SAAS0C,GACf8B,EAAArD,UAAMnB,SAAQyE,KAAA7E,KAAC8C,GACf9C,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEM4B,uBAAA,WACN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KAAA7E,KACpC,EAACsB,EAEMnB,WAAA,WAEN,OAAAyE,EAAArD,UAAapB,WAAU0E,KAAA7E,KACxB,EAACgsB,CAAA,CA/SsCpnB,CAAQtE,GEAnC6tB,gBAA8B,SAAAvpB,GAa1C,SAAAupB,EACC5tB,GAGqB,IAAAR,EAWqB,OAT1CA,EAAA6E,EAAAC,KAAMtE,KAAAA,IAAQR,MAlBEiF,UAAIjF,EAAAA,EACJquB,cAAQruB,EAAAA,EACRsO,gBAAUtO,EAAAA,EACVsuB,wBAA0B,SAAQtuB,EAClCuuB,kBAAoB,sBAAqBvuB,EACzCwuB,mBAAaxuB,EAAAA,EAEtByuB,cAAe,EAAIzuB,EACnB0uB,cAAe,EAAI1uB,EACnB2uB,kBAAY,EAAA3uB,EACZ4uB,yBAAmB,EAU1B5uB,EAAKquB,SAAW7tB,EAAOgF,IACvBxF,EAAKiF,KAAOzE,EAAO+E,IACnBvF,EAAKsO,WAAatO,EAAKquB,SAASQ,UAChC7uB,EAAKwuB,cAAgB,IAAIxuB,EAAKiF,KAAK6pB,cAAc,CAChDppB,GAAI1F,EAAKuuB,oBAGVvuB,EAAKquB,SAAS7oB,IAAIf,IAAIzE,EAAKwuB,eAAexuB,CAC3C,CA7B0C4F,EAAAwoB,EAAAvpB,GA6BzC,IAAAtD,EAAA6sB,EAAA5sB,UAkNA4sB,OAlNA7sB,EAEMlB,SAAA,SAAS0C,GAA6B,IAAAmD,EAAAjG,KAC5C4E,EAAArD,UAAMnB,SAAQyE,KAAC/B,KAAAA,GAEf9C,KAAK0uB,aAAe1uB,KAAKouB,SAASrR,GAAG,OAAQ,SAACtb,GACxCwE,EAAKuoB,cACT/sB,EAAM8Y,iBAER,GACAva,KAAK2uB,oBAAsB3uB,KAAKouB,SAASrR,GAAG,eAAgB,SAACtb,GACvDwE,EAAKwoB,cACThtB,EAAM8Y,iBAER,GAEAva,KAAKiB,uBACJjB,KAAKiB,sBAAsBoF,SAC3BrG,KAAKiB,sBAAsBoF,SAC7B,EAAC/E,EAEMnB,WAAA,WACNyE,EAAArD,UAAMpB,WAAU0E,KAAA7E,MAEZA,KAAK0uB,cACR1uB,KAAK0uB,aAAa1nB,SAGfhH,KAAK2uB,qBACR3uB,KAAK2uB,oBAAoB3nB,QAE3B,EAAC1F,EAEM4B,uBAAA,WAEN,OAAA0B,EAAArD,UAAa2B,uBAAsB2B,KACpC7E,KAAA,EAACsB,EAOMiB,mBAAA,SAAmBd,GACzB,IAAAiB,EACC1C,KAAK2B,wBAAwBF,GAC9B,OAAWzB,KAACwI,UAFS9F,EAAbX,WAA4BW,EAAbR,WAGxB,EAACZ,EAMMO,mBAAA,WACN,OAAW7B,KAACqO,WAAWlG,cAAc,qBACtC,EAAC7G,EAMM0C,gBAAA,SAAgBD,GACtB/D,KAAKwuB,aAAezqB,CACrB,EAACzC,EAQM8G,QAAA,SAAQ5F,EAAaC,GAC3B,IAAM4F,EAAQ,IAAQrI,KAACgF,KAAK8C,MAAM,CAAEgnB,UAAWtsB,EAAKusB,SAAUtsB,IAC9DusB,EAAiBhvB,KAAKouB,SAASa,SAAS5mB,GACxC,MAAO,CAAE1I,EADAqvB,EAADrvB,EACID,EADAsvB,EAADtvB,EAEZ,EAAC4B,EAQMkH,UAAA,SAAU7I,EAAWD,GAC3B,IAAAwvB,EAAgClvB,KAAKouB,SAASe,MAAM,CAAExvB,EAAAA,EAAGD,EAAAA,IACzD,MAAO,CAAE8C,IADkB0sB,EAATJ,UACOrsB,IADTysB,EAARH,SAET,EAACztB,EAMMmH,UAAA,SAAUC,GACD,UAAXA,EACH1I,KAAK6B,qBAAqBkH,MAAMsH,eAAe,UAE/CrQ,KAAK6B,qBAAqBkH,MAAML,OAASA,CAE3C,EAACpH,EAMM8H,qBAAA,SAAqBrF,GAC3B/D,KAAKyuB,aAAe1qB,CACrB,EAACzC,EAOMkI,OAAA,SAAOC,EAA2BC,GAAiCC,IAAAA,OACzEF,EAAQ+B,QAAQxI,QAAQ,SAACyI,GACxB9B,EAAKqjB,WAAWvhB,EAAgB/B,EACjC,GAEAD,EAAQQ,QAAQjH,QAAQ,SAACkH,GACxBP,EAAKylB,kBAAkBllB,EAAezE,IACtCkE,EAAKqjB,WAAW9iB,EAAgBR,EACjC,GAEAD,EAAQI,WAAW7G,QAAQ,SAAC8G,GAC3BH,EAAKylB,kBAAkBtlB,EACxB,EACD,EAACxI,EAMMoD,MAAA,WACN1E,KAAKuuB,cAAcc,SAASC,WAC7B,EAAChuB,EAEO8tB,kBAAA,SAAkB3pB,GAA+BiI,IAAAA,EACxD1N,KAAM2L,EAAU3L,KAAKuuB,cAAcc,SAAS3oB,KAC3C,SAAC+Q,GAAM,OAAAA,EAAE8X,WAAW7hB,EAAK2gB,2BAA6B5oB,CAAE,GAEzDzF,KAAKuuB,cAAcvnB,OAAO2E,EAC3B,EAACrK,EAEO0rB,WAAA,SACPrhB,EACAjC,GAAiC,IAAA8lB,EAEjCC,EAA8B9jB,EAAQjB,SAA9BE,EAAW6kB,EAAX7kB,YAAaD,EAAI8kB,EAAJ9kB,KACf5B,EAAQW,EAAQiC,EAAQlB,WAAWuB,MAAgBL,GAErD+jB,OAA6BzoB,EAC7ByD,OAAiCzD,EAErC,OAAQ0D,GACP,IAAK,QACJD,EAAW,IAAI1K,KAAKgF,KAAK8C,MAAM,CAC9BinB,SAAUnkB,EAAY,GACtBkkB,UAAWlkB,EAAY,KAExB8kB,EAAS,IAAQ1vB,KAACgF,KAAK2qB,mBAAmB,CACzClgB,MAAOzP,KAAK4vB,gBAAgB7mB,EAAM4D,YAClCuB,KAAyB,EAAnBnF,EAAM0D,WAAiB,KAC7BojB,QAAS,CACRpgB,MAAOzP,KAAK4vB,gBAAgB7mB,EAAM+D,mBAClC6M,MAAO5Q,EAAMiE,kBAAoB,QAGnC,MACD,IAAK,aACJtC,EAAW,IAAI1K,KAAKgF,KAAK8qB,SAAS,CAAEzkB,MAAO,CAACT,KAC5C8kB,EAAS,IAAI1vB,KAAKgF,KAAK+qB,iBAAiB,CACvCtgB,MAAOzP,KAAK4vB,gBAAgB7mB,EAAMoE,iBAClCwM,MAAO5Q,EAAMqE,gBAAkB,OAEhC,MACD,IAAK,UACJ1C,EAAW,IAAI1K,KAAKgF,KAAKuG,QAAQ,CAAEykB,MAAOplB,IAC1C8kB,EAAS,IAAI1vB,KAAKgF,KAAKirB,iBAAiB,CACvCxgB,MAAOzP,KAAK4vB,gBACX7mB,EAAMyE,iBACNzE,EAAMwE,oBAEPsiB,QAAS,CACRpgB,MAAOzP,KAAK4vB,gBAAgB7mB,EAAMsE,qBAClCsM,MAAO5Q,EAAMuE,oBAAsB,QAMvC,IAAM4iB,EAAU,IAAQlwB,KAACgF,KAAKmrB,QAAQ,CACrCzlB,SAAAA,EACAglB,OAAAA,EACAH,YAAUC,EAAA,CAAA,EAAAA,EAAKxvB,KAAKquB,yBAA0B1iB,EAAQlG,GAAE+pB,KAI5C,UAAT7kB,EACH3K,KAAKuuB,cAAcc,SAAS7qB,IAAI0rB,GAEhClwB,KAAKuuB,cAAcc,SAAS7qB,IAAI0rB,EAAS,EAE3C,EAAC5uB,EAEOsuB,gBAAA,SAAgBQ,EAAkBhc,GACzC,IAAM3E,EAAQzP,KAAKgF,KAAKqrB,MAAMC,QAAQF,GAItC,OAHIhc,IACH3E,EAAMkI,EAAIvD,GAEJ3E,CACR,EAAC0e,CAAA,CA/OyC,CAAQ7tB,GCwHtCiwB,GACF,WADEA,GAED,WAICC,GACG,eChJhB,SAASC,GACR9kB,GAEA,OAAOsC,QACNtC,GACoB,iBAAZA,GACK,OAAZA,IACC/I,MAAMmR,QAAQpI,GAElB,UASgB+kB,GAAiBC,GAChC,IARD,SAAqBA,GACpB,MACsB,iBAAdA,IACN9gB,MAAM,IAAI+gB,KAAKD,GAAqBE,UAEvC,CAGMC,CAAYH,GAChB,MAAM,IAAIjrB,MA/Be,oDAkC1B,OACD,CAAA,EHbA,SAAYqmB,GACXA,EAAA,QAAA,UACAA,EAAA,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,OAAA,QACA,CALD,CAAYA,KAAAA,GAKX,CAAA,IAOqB,IAAAgF,gBAAqBzvB,WAAAA,IAAAA,EAAAyvB,EAAAxvB,UAiC1C,SAAAwvB,EAAY7c,GAA4BlU,KAhC9BgxB,YAAM,EAAAhxB,KAQNixB,aAAO,EAAAjxB,KAaPkxB,UAAqC,GACrCC,KAAAA,qBACA9vB,EAAAA,KAAAA,gCACA+vB,mBAAa,EAAApxB,KACbqxB,WAAK,EAAArxB,KACLoJ,0BAAoB,EAAApJ,KACpBwI,eACAJ,EAAAA,KAAAA,aACAK,EAAAA,KAAAA,eAUVkC,EAAAA,KAAAA,KAAOohB,GAAUuF,QACjBtlB,KAAAA,KAAO,OAPNhM,KAAKgxB,OAAS,eACdhxB,KAAKixB,QACJ/c,GAAWA,EAAQd,OAAMme,EAAA,CAAA,EAAQrd,EAAQd,QAAY,CAAA,EACtDpT,KAAKmxB,gBAAmBjd,GAAWA,EAAQid,iBAAoB,EAChE,CAlBC,OApByC7vB,EA+BhCkwB,kBAAA,SAAkBC,GAAwC,EAOnEnwB,EAKSowB,WAAA,WACT,GAAoB,YAAhB1xB,KAAKgxB,OAGR,MAAM,IAAItrB,MAAM,iDAFhB1F,KAAKgxB,OAAS,SAIhB,EAAC1vB,EAESqwB,WAAA,WACT,GACiB,YAAhB3xB,KAAKgxB,QACW,eAAhBhxB,KAAKgxB,QACW,YAAhBhxB,KAAKgxB,QACW,cAAhBhxB,KAAKgxB,OAKL,MAAU,IAAAtrB,MAAM,iDAHhB1F,KAAKgxB,OAAS,UACdhxB,KAAKoJ,sBAAqB,EAI5B,EAAC9H,EAESswB,WAAA,WACT,GAAoB,YAAhB5xB,KAAKgxB,OAIR,MAAU,IAAAtrB,MAAM,sCAHhB1F,KAAKgxB,OAAS,UACdhxB,KAAKoJ,sBAAqB,EAI5B,EAAC9H,EAEDlB,SAAA,SAASG,GACR,GAAoB,iBAAhBP,KAAKgxB,OAuBR,MAAU,IAAAtrB,MAAM,gDAtBhB1F,KAAKgxB,OAAS,aACdhxB,KAAKqxB,MAAQ9wB,EAAO8wB,MACpBrxB,KAAKqxB,MAAMQ,iBAAiBtxB,EAAOuxB,UACnC9xB,KAAKoJ,qBAAuB7I,EAAO6I,qBACnCpJ,KAAKoI,QAAU7H,EAAO6H,QACtBpI,KAAKwI,UAAYjI,EAAOiI,UACxBxI,KAAK+xB,SAAWxxB,EAAOwxB,SACvB/xB,KAAKgyB,WAAazxB,EAAOyxB,WACzBhyB,KAAKyI,UAAYlI,EAAOkI,UACxBzI,KAAKoxB,cAAgB7wB,EAAOuxB,SAC5B9xB,KAAKiyB,SAAW1xB,EAAO0xB,SACvBjyB,KAAKqB,oBAAsBd,EAAOc,oBAElCrB,KAAKwxB,kBAAkB,CACtBxlB,KAAMzL,EAAOyL,KACbqlB,MAAOrxB,KAAKqxB,MACZjpB,QAASpI,KAAKoI,QACdI,UAAWxI,KAAKwI,UAChB2oB,gBAAiBnxB,KAAKmxB,gBACtB9vB,oBAAqBd,EAAOc,qBAK/B,EAACC,EAED4wB,gBAAA,SAAgBvmB,GACf,GAAoB,iBAAhB3L,KAAKgxB,OACR,MAAU,IAAAtrB,MAAM,2BAGjB,OGxGc,SACfiG,EACAwmB,GAEA,IAAI/X,EACJ,GAAKqW,GAAS9kB,MAEHA,QAAQlG,GAClB2U,EA/Ce,yBAgDL,GAAsB,iBAAfzO,EAAQlG,IAAyC,iBAAfkG,EAAQlG,GAC3D2U,EA7CyB,+DA8Cd+X,EAAUxmB,EAAQlG,OAElBgrB,GAAS9kB,EAAQjB,UAEtB,GAAK+lB,GAAS9kB,EAAQlB,YAEtB,GAC2B,iBAA1BkB,EAAQjB,SAASC,MACvB,CAAC,UAAW,aAAc,SAASyO,SAASzN,EAAQjB,SAASC,MAGxD,GAAK/H,MAAMmR,QAAQpI,EAAQjB,SAASE,kBAGzCe,EAAQlB,WAAWuB,MACe,iBAA5BL,EAAQlB,WAAWuB,KAE1B,MAAM,IAAItG,MAzDU,oDAoDpB0U,EArD6B,2CAmD7BA,EApD4B,mDA+C5BA,EAhDuB,iCA8CvBA,EA/CqB,+BA6CrBA,EA9CkB,6DAwClBA,EA5CmB,wBAqEpB,GAAIA,EACH,MAAM,IAAI1U,MAAM0U,GAGjB,OACD,CAAA,CHoESgY,CAAoBzmB,EAAS3L,KAAKqxB,MAAMgB,WAAWF,UAC3D,EAAC7wB,EAOD2wB,SAAA,SAASK,GAAqB,EAAIhxB,EAClC0wB,WAAA,SAAWO,GAAuB,EAAIjxB,EACtCywB,SAAA,SAASS,GAAyB,EAAAlxB,EAClCmD,UAAA,SAAUhD,GAA6B,EAAIH,EAC3CiD,QAAA,SAAQ9C,GAA6B,EAAIH,EACzCkC,YAAA,SAAY/B,GAA8B,EAAAH,EAC1C+C,QAAA,SAAQ5C,GAA0B,EAAIH,EACtCwC,YAAA,SACCrC,EACAgxB,KACGnxB,EACJ4C,OAAA,SACCzC,EACAgxB,GACG,EAAAnxB,EACJ8C,UAAA,SACC3C,EACAgxB,GACG,EAAAnxB,EAEMoxB,wBAAA,SACTrmB,EACAsmB,EACAhnB,GAEA,YAAYinB,gBAAgBvmB,EAAOsmB,EAAchnB,EAClD,EAACrK,EAESuxB,uBAAA,SACTxmB,EACAsmB,EACAhnB,GAEA,OAAW3L,KAAC4yB,gBAAgBvmB,EAAOsmB,EAAchnB,EAClD,EAACrK,EAEOsxB,gBAAA,SACPvmB,EACAsmB,EACAhnB,GAGA,MAC4B,UAA3BA,EAAQlB,WAAWE,MAFE,CAAC,EAAG,GAAI,GAAI,IAGlByO,SAASzN,EAAQlB,WAAWyR,YAK9BjV,IAAVoF,EACIsmB,EACoB,mBAAVtmB,EACVA,EAAMV,GAENU,EAPR,CASD,EAACyB,EAAAijB,EAAA,CAAA,CAAAzsB,IAAAyJ,QAAAA,IAzKD,WACC,OAAO/N,KAAKgxB,MACb,EAACtS,IACD,SAAU2O,GACT,MAAU,IAAA3nB,MAAM,yCACjB,GAACpB,CAAAA,IAAAyJ,SAAAA,IAID,WACC,OAAW/N,KAACixB,OACb,EAACvS,IACD,SAAWhV,GACV,GAAuB,iBAAZA,EACV,MAAU,IAAAhE,MAAM,6BAEjB1F,KAAKoxB,cAAc,GAAI,WACvBpxB,KAAKixB,QAAUvnB,CAChB,KAACqnB,CAAA,CApByCzvB,GA8KrBwxB,gBAEpBC,SAAAA,GAAAD,SAAAA,QAAA/yB,IAAAA,EAAAizB,EAAAtW,UAAAzR,OAAAgoB,EAAArwB,IAAAA,MAAAowB,GAAAE,IAAAA,EAAAF,EAAAE,IAAAD,EAAAC,GAAAxW,UAAAwW,GAC6B,OAD7BnzB,EAAAgzB,EAAAluB,KAAA4X,MAAAsW,EAAAjnB,CAAAA,MAAAA,OAAAmnB,WACMtoB,KAAOohB,GAAUoH,OAAMpzB,CAAA,CAAA,OAD7B4F,EAAAmtB,EAAAC,GAC6BD,CAAA,CAD7BC,CAAQhC,IIrNM,SAAAqC,GACf5zB,EACAC,GAEA,IAAM4zB,EAAY,SAACC,GAAgB,OAAMA,EAAWl0B,KAAKiiB,GAAM,GAAG,EAE5DkS,EAASF,EAAU7zB,EAAS,IAC5Bg0B,EAAYH,EAAU7zB,EAAS,IAC/Bi0B,EAASJ,EAAU5zB,EAAS,IAE5Bi0B,EAAWD,EAASF,EACpBI,EAFYN,EAAU5zB,EAAS,IAEL+zB,EAE1B7b,EACLvY,KAAKkiB,IAAIoS,EAAW,GAAKt0B,KAAKkiB,IAAIoS,EAAW,GAC7Ct0B,KAAKokB,IAAI+P,GACRn0B,KAAKokB,IAAIiQ,GACTr0B,KAAKkiB,IAAIqS,EAAc,GACvBv0B,KAAKkiB,IAAIqS,EAAc,GAMzB,OALU,EAAIv0B,KAAKw0B,MAAMx0B,KAAKQ,KAAK+X,GAAIvY,KAAKQ,KAAK,EAAI+X,IAEtC,OAGG,GACnB,KC3Bakc,GAAc,UAErB,SAAUC,GAAiBpN,GAEhC,OADgBA,EAAU,IACRtnB,KAAKiiB,GAAM,GAC9B,CAOgB,SAAA0S,GAAiBtN,GAEhC,OADgBA,GAAW,EAAIrnB,KAAKiiB,IAClB,IAAOjiB,KAAKiiB,EAC/B,CCuBM,SAAU2S,GAAO9f,GAUtB,IAJA,IAAQ+f,EAAkD/f,EAAlD+f,OAAQC,EAA0ChgB,EAA1CggB,iBAAkB7yB,EAAwB6S,EAAxB7S,oBAC5B8yB,EAAQjgB,EAAQigB,MAAQjgB,EAAQigB,MAAQ,GAExCvpB,EAA0B,GACvBI,EAAI,EAAGA,EAAImpB,EAAOnpB,IAAK,CAC/B,IAAMopB,GApCPC,EAsCEH,EArCFI,GAsCQ,IAALtpB,EAAYmpB,EApCTI,EAAaT,IAJnBU,EAsCEP,GAlCyC,IACrCQ,EAAYX,GAAiBU,EAAO,IACpCE,EAAaZ,GAAiBQ,GAC9B7N,EDZS,SAAgB4N,GAE/B,OAAOA,EADQR,SAEhB,CCSiBc,CAAgBN,GAG1BO,EAAYx1B,KAAKy1B,KACtBz1B,KAAKkiB,IAAImT,GAAar1B,KAAKokB,IAAIiD,GAC9BrnB,KAAKokB,IAAIiR,GAAar1B,KAAKkiB,IAAImF,GAAWrnB,KAAKokB,IAAIkR,IAW9C,CAHKX,GALXQ,EACAn1B,KAAKw0B,MACJx0B,KAAKkiB,IAAIoT,GAAct1B,KAAKkiB,IAAImF,GAAWrnB,KAAKokB,IAAIiR,GACpDr1B,KAAKokB,IAAIiD,GAAWrnB,KAAKkiB,IAAImT,GAAar1B,KAAKkiB,IAAIsT,KAGzCb,GAAiBa,KAsB5BhqB,EAAYO,KAAK,CAChBnM,EAAeo1B,EAAiB,GAAI/yB,GACpCrC,EAAeo1B,EAAiB,GAAI/yB,IAEtC,CAhDD,IACCmzB,EACAH,EACAC,EAEMC,EACAE,EACAC,EACAjO,EAGAmO,EAwCN,OAFAhqB,EAAYO,KAAKP,EAAY,IAEtB,CACND,KAAM,UACND,SAAU,CAAEC,KAAM,UAAWC,YAAa,CAACA,IAC3CH,WAAY,GAEd,UCvDgBqqB,GACfnpB,GAEA,IAMIopB,EANE7gB,EAAiC,CACtC8gB,QAAS,GAOV,GAA8B,YAA1BrpB,EAAQjB,SAASC,KACpBoqB,EAAQppB,EAAQjB,SAASE,oBACW,eAA1Be,EAAQjB,SAASC,KAG3B,UAAUjF,MAAM,yDAFhBqvB,EAAQ,CAACppB,EAAQjB,SAASE,YAG3B,CAKA,IAHA,IAAMwf,EAAqB,GAGlB6K,EAAQ,EAAGA,EAAQF,EAAM9pB,OAAQgqB,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQH,EAAME,GAAOhqB,OAAS,EAAGiqB,IACpD,IAAK,IAAIC,EAAQ,EAAGA,EAAQJ,EAAM9pB,OAAQkqB,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQL,EAAMI,GAAOlqB,OAAS,EAAGmqB,IAEpDC,EAA0BJ,EAAOC,EAAOC,EAAOC,GAMnD,OAAOhL,EAAOnf,OAAS,EAQvB,SAASqqB,EAAUC,GAClB,OAAOA,EAAO,EAAIrhB,EAAQ8gB,SAAWO,EAAO,EAAIrhB,EAAQ8gB,OACzD,CAEA,SAASK,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,GAAYL,EAAQE,IACpBG,GAAYL,EAAQG,IACpBE,GAAYJ,EAAMC,IAClBG,GAAYF,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,EACI,KASD,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,EAAa7c,WAMzBoR,EAAOjf,KAAK0qB,IACb,CACD,CAEA,SAASC,GAAYW,EAAkBC,GACtC,OAAOD,EAAO,KAAOC,EAAO,IAAMD,EAAO,KAAOC,EAAO,EACxD,CClHgB,SAAAC,GACfzrB,EACA7J,GAEA,OACuB,IAAtB6J,EAAWD,QACc,iBAAlBC,EAAW,IACO,iBAAlBA,EAAW,IACA8V,WAAlB9V,EAAW,IACO8V,WAAlB9V,EAAW,KAbkB1I,EAcd0I,EAAW,MAbZ,KAAO1I,GAAO,MALAC,EAmBdyI,EAAW,MAlBX,IAAMzI,GAAO,IAmB3Bm0B,GAAiB1rB,EAAW,KAAO7J,GACnCu1B,GAAiB1rB,EAAW,KAAO7J,MArBPoB,EAICD,CAmB/B,CAEgB,SAAAo0B,GAAiBvqB,GAGhC,IAFA,IAAIwqB,EAAU,EACVC,EAAY,EACT13B,KAAKE,MAAM+M,EAAQwqB,GAAWA,IAAYxqB,GAChDwqB,GAAW,GACXC,IAGD,OAAOA,CACR,CCtBgB,SAAAC,GACfprB,EACAtK,GAEA,MAC2B,YAA1BsK,EAAQjB,SAASC,MACuB,IAAxCgB,EAAQjB,SAASE,YAAYK,QAC7BU,EAAQjB,SAASE,YAAY,GAAGK,QAAU,GAC1CU,EAAQjB,SAASE,YAAY,GAAGosB,MAAM,SAAC9rB,GACtC,OAAAyrB,GAAkBzrB,EAAY7J,EAAoB,KAhB3B41B,EAmBvBtrB,EAAQjB,SAASE,YAAY,GAAG,IAjBnB,MAFmCssB,EAoBhDvrB,EAAQjB,SAASE,YAAY,GAC5Be,EAAQjB,SAASE,YAAY,GAAGK,OAAS,IAnBR,IACnCgsB,EAAc,KAAOC,EAAc,GAHrC,IAA0BD,EAAyBC,CAyBnD,CAEgB,SAAAC,GACfxrB,EACAtK,GAEA,OACC01B,GAAsBprB,EAAStK,KAC9ByzB,GAAenpB,EAElB,CCGa,IAAAyrB,gBAAoBrE,SAAAA,GAkBhC,SAAAqE,EAAYljB,GAA0DmjB,IAAAA,EAAAt3B,GACrEA,EAAAgzB,EAAAluB,KAAMqP,KAAAA,IAAQlU,MAlBfgM,KAAO,SAAQjM,EACPk0B,YAAMl0B,EAAAA,EACNu3B,WAAa,EAACv3B,EACdw3B,qBAAex3B,EAAAA,EACfy3B,eAASz3B,EAAAA,EACT03B,aAAO13B,EAAAA,EACP23B,6BAcP,EAAA,IAAMC,EAAiB,CACtBC,MAAO,aAWR,GAPC73B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAA,CAAA,EAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EAKW,QAAhB,MAAPzjB,OAAO,EAAPA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,EAAA,CAAA,EACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAE2E,OAA3Eh4B,EAAK23B,wBAA0DL,OAAnCA,EAAGnjB,MAAAA,OAAAA,EAAAA,EAASwjB,yBAAuBL,EAAI,KAAQt3B,CAC5E,CA5CgC4F,EAAAyxB,EAAArE,GA4C/B,IAAAzxB,EAAA81B,EAAA71B,UA+LA,OA/LAD,EAEO02B,MAAA,WACP,QAA6B/wB,IAAzBjH,KAAKu3B,gBAAT,CAIA,IAAMjF,EAAatyB,KAAKu3B,gBAExBv3B,KAAKi0B,YAAShtB,EACdjH,KAAKu3B,qBAAkBtwB,EACvBjH,KAAKs3B,WAAa,EAEC,YAAft3B,KAAKi4B,OACRj4B,KAAK2xB,aAIN3xB,KAAKiyB,SAASK,EAbd,CAcD,EAAChxB,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,GAAwB,IAApBzB,KAAKs3B,WAAkB,CAC1Bt3B,KAAKi0B,OAAS,CAACxyB,EAAMe,IAAKf,EAAMgB,KAChC,IAAM21B,EAAiBpE,GAAO,CAC7BC,OAAQj0B,KAAKi0B,OACbC,iBAAkBl0B,KAAK03B,wBACvBr2B,oBAAqBrB,KAAKqB,sBAG3Bg3B,EAAoBr4B,KAAKqxB,MAAMiH,OAAO,CACrC,CACC5tB,SAAU0tB,EAAe1tB,SACzBD,WAAY,CACXuB,KAAMhM,KAAKgM,KACXkoB,iBAAkBl0B,KAAK03B,wBACvBzD,OAAQj0B,KAAKi0B,WAIhBj0B,KAAKu3B,gBAVWc,EAUhB,GACAr4B,KAAKs3B,aACLt3B,KAAK0xB,YACN,MAEsB,IAApB1xB,KAAKs3B,YACLt3B,KAAKi0B,aACoBhtB,IAAzBjH,KAAKu3B,iBAELv3B,KAAKu4B,aAAa92B,GAInBzB,KAAKg4B,OAEP,EAAC12B,EAGDkC,YAAA,SAAY/B,GACXzB,KAAKu4B,aAAa92B,EACnB,EAACH,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,OAChC73B,KAAKm4B,UACK12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QACvC93B,KAAKg4B,OAEP,EAAC12B,EAGDwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGd62B,QAAA,WACC,SAC8BlxB,IAAzBjH,KAAKu3B,iBACRv3B,KAAKqxB,MAAK,OAAQ,CAACrxB,KAAKu3B,iBAE1B,CAAE,MAAOnd,GAAO,CAChBpa,KAAKi0B,YAAShtB,EACdjH,KAAKu3B,qBAAkBtwB,EACvBjH,KAAKs3B,WAAa,EACC,YAAft3B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAQkH,CAAAA,ECtMd,CACNjrB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,ID6LR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAO5F,iBAAmBxN,KAAK0yB,wBAC9B1yB,KAAKoT,OAAO1G,UACZ0G,EAAO5F,iBACP7B,GAGDyH,EAAO/F,oBAAsBrN,KAAK0yB,wBACjC1yB,KAAKoT,OAAOslB,aACZtlB,EAAO/F,oBACP1B,GAGDyH,EAAO9F,oBAAsBtN,KAAK6yB,uBACjC7yB,KAAKoT,OAAOulB,aACZvlB,EAAO9F,oBACP3B,GAGDyH,EAAO7F,mBAAqBvN,KAAK6yB,uBAChC7yB,KAAKoT,OAAOxG,YACZwG,EAAO7F,mBACP5B,GAGMyH,GAGDA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCmrB,GAAqCxrB,EAAS3L,KAAKqB,oBAKtD,EAACC,EAEOi3B,aAAA,SAAa92B,GACpB,GAAwB,IAApBzB,KAAKs3B,YAAoBt3B,KAAKi0B,QAAUj0B,KAAKu3B,gBAAiB,CACjE,IAAMqB,EAAaxF,GAA4BpzB,KAAKi0B,OAAQ,CAC3DxyB,EAAMe,IACNf,EAAMgB,MAGDo2B,EACLD,EAAa54B,KAAK03B,wBACfkB,EACA54B,KAAK03B,wBAEHoB,EAAgB9E,GAAO,CAC5BC,OAAQj0B,KAAKi0B,OACbC,iBAAkB2E,EAClBx3B,oBAAqBrB,KAAKqB,sBAG3BrB,KAAKqxB,MAAM0H,eAAe,CACzB,CAAEtzB,GAAIzF,KAAKu3B,gBAAiB7sB,SAAUouB,EAAcpuB,YAErD1K,KAAKqxB,MAAM2H,eAAe,CACzB,CACCvzB,GAAIzF,KAAKu3B,gBACTltB,SAAU,mBACVgC,MAAOwsB,IAGV,CACD,EAACzB,CAAA,CA3O+BrE,CAAQhC,IEM5BkI,gBAAsB,SAAAlG,GAWlC,SAAAkG,EAAY/kB,GAA8D,IAAAnU,GACzEA,EAAAgzB,EAAAluB,KAAA7E,KAAMkU,UAXPlI,KAAO,WAAUjM,EAETm5B,eAAgB,EAAKn5B,EACrBo5B,iBAASp5B,EACTq5B,oBAAc,EAAAr5B,EACds5B,iBAAWt5B,EAAAA,EACXy3B,eAAS,EAAAz3B,EACT03B,eAAO13B,EACPu5B,4BAAsB,EAK7B,IAAM3B,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAgBR,GAZCj4B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAA,CAAA,EAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EAGhB53B,EAAKu5B,uBACHplB,GAAWA,EAAQolB,yBAA2B,EAEhDv5B,EAAKs5B,YAAenlB,GAAWA,EAAQmlB,aAAgB,GAI5B,QAAvBnlB,MAAAA,OAAAA,EAAAA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,KACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAAC,OAAAh4B,CACF,CAzCkC4F,EAAAszB,EAAAlG,GAyCjC,IAAAzxB,EAAA23B,EAAA13B,UA8PA03B,OA9PA33B,EAEO02B,MAAA,WACP,QAAuB/wB,IAAnBjH,KAAKm5B,UAAT,CAIA,IAAM7G,EAAatyB,KAAKm5B,UAExBn5B,KAAKo5B,gBAAkBp5B,KAAKqxB,aAAa,CAACrxB,KAAKo5B,iBAC/Cp5B,KAAKk5B,eAAgB,EACrBl5B,KAAKm5B,eAAYlyB,EACjBjH,KAAKo5B,oBAAiBnyB,EAEH,YAAfjH,KAAKi4B,OACRj4B,KAAK2xB,aAIN3xB,KAAKiyB,SAASK,EAdd,CAeD,EAAChxB,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GACX,QAAuBwF,IAAnBjH,KAAKm5B,YAAkD,IAAvBn5B,KAAKk5B,cAAzC,CAIA,IAAMK,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAGNM,EACCF,EAAoB3uB,YAAY,GAC/B2uB,EAAoB3uB,YAAY,GAAGK,OAAS,GAE9CyuB,EAAiB15B,KAAKoI,QAJJqxB,EAAA,GAAaA,EAI/B,IACMpF,EAAW90B,EAChB,CAAEI,EAFM+5B,EAAD/5B,EAEFD,EAFMg6B,EAADh6B,GAGV,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGjCy3B,EAAiCJ,EAAoB3uB,YAAY,GAAG,GACpEgvB,EAAqC55B,KAAKoI,QADzBuxB,KAAYA,EAAA,IAO7B,GALwBp6B,EACvB,CAAEI,EAFgBi6B,EAAXj6B,EAEQD,EAFgBk6B,EAAXl6B,GAGpB,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGXlC,KAAKmxB,iBAK1B,GAJAnxB,KAAKyI,UAAUzI,KAAKy3B,QAAQO,OAIxBh4B,KAAKs5B,uBACR,YAGDt5B,KAAKyI,UAAUzI,KAAKy3B,QAAQG,OAKzBvD,EAAWr0B,KAAKq5B,cAIpBE,EAAoB3uB,YAAY,GAAGivB,MAEnC75B,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,UACNC,YAAa,IAAAkB,OAERytB,EAAoB3uB,YAAY,GAAE,CACrC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB82B,EAAoB3uB,YAAY,GAAG,UApDxC,CA0DD,EAACtJ,EAGD+C,QAAA,SAAQ5C,GACP,IAA2B,IAAvBzB,KAAKk5B,cAAyB,CACjC,IAAAb,EAAoCr4B,KAAKqxB,MAAMiH,OAAO,CACrD,CACC5tB,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,OAE1B,CACCtB,SAAU,CACTC,KAAM,QACNC,YAAa,CAACnJ,EAAMe,IAAKf,EAAMgB,MAEhCgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SApBTotB,EAAcf,EAAA,GA6BhC,OALAr4B,KAAKm5B,UAxBWd,KAyBhBr4B,KAAKo5B,eAAiBA,EACtBp5B,KAAKk5B,eAAgB,OACrBl5B,KAAK0xB,YAGN,CAEA1xB,KAAKg4B,OACN,EAAC12B,EAGDmD,UAAA,aAAcnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,OAChC73B,KAAKm4B,UACK12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QACvC93B,KAAKg4B,OAEP,EAAC12B,EAGDwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGd62B,QAAA,WACC,IACKn4B,KAAKm5B,WACRn5B,KAAKqxB,aAAa,CAACrxB,KAAKm5B,YAErBn5B,KAAKo5B,gBACRp5B,KAAKqxB,MAAK,OAAQ,CAACrxB,KAAKo5B,gBAE1B,CAAE,MAAOhf,GACT,CAAApa,KAAKo5B,oBAAiBnyB,EACtBjH,KAAKm5B,eAAYlyB,EACjBjH,KAAKk5B,eAAgB,EACF,YAAfl5B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAQkH,CAAAA,EDzQd,CACNjrB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,ICgQR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAO5F,iBAAmBxN,KAAK0yB,wBAC9B1yB,KAAKoT,OAAO1G,UACZ0G,EAAO5F,iBACP7B,GAGDyH,EAAO/F,oBAAsBrN,KAAK0yB,wBACjC1yB,KAAKoT,OAAOslB,aACZtlB,EAAO/F,oBACP1B,GAGDyH,EAAO9F,oBAAsBtN,KAAK6yB,uBACjC7yB,KAAKoT,OAAOulB,aACZvlB,EAAO9F,oBACP3B,GAGDyH,EAAO7F,mBAAqBvN,KAAK6yB,uBAChC7yB,KAAKoT,OAAOxG,YACZwG,EAAO7F,mBACP5B,GAGMyH,GAEU,YAAjBzH,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAO0mB,kBACZ1mB,EAAO3G,WACPd,GAGDyH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAO2mB,kBACZ3mB,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAO4mB,yBACZ5mB,EAAOtG,kBACPnB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAO6mB,yBACZ,EACAtuB,GAGMyH,GAGDA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+qB,GAAsBprB,EAAS3L,KAAKqB,oBAKvC,EAAC43B,CAAA,CAvSiC,CAAQlI,IC1CrCmJ,GAAM96B,KAAKiiB,GAAK,IAChB8Y,GAAM,IAAM/6B,KAAKiiB,GASjB+Y,gBAAa,WAClB,SAAAA,EAAY/4B,GAA2BrB,KAM/BqB,yBAAmB,EAAArB,KACpBq6B,YAAM,EAAAr6B,KACNiL,YAAM,EAPZjL,KAAKqB,oBAAsBA,EAC3BrB,KAAKq6B,OAAS,GACdr6B,KAAKiL,OAAS,CACf,CAYCmvB,OAZAA,EAAA74B,UAMD+4B,OAAA,SAAOvF,GACN/0B,KAAKiL,SACLjL,KAAKq6B,OAAOlvB,KAAK,CAChBnM,EAAe+1B,EAAM,GAAI/0B,KAAKqB,qBAC9BrC,EAAe+1B,EAAM,GAAI/0B,KAAKqB,sBAEhC,EAAC+4B,CAAA,CAjBiB,GAoBbG,gBAAG,WACR,SAAAA,EAAAz6B,GAAsD,IAAxC2K,EAAU3K,EAAV2K,WAKP+vB,KAAAA,gBACA/vB,EAAAA,KAAAA,gBALN,EAAAzK,KAAKyK,WAAaA,GAAc,CAAA,EAChCzK,KAAKw6B,WAAa,EACnB,CA0BC,OA1BAD,EAAAh5B,UAKDk5B,OAAA,WACC,GAA+B,IAA3Bz6B,KAAKw6B,WAAWvvB,OAAc,CACjC,IAAMovB,EAASr6B,KAAKw6B,WAAW,GAAGH,OAGlC,GACCA,EAAO,GAAG,KACTxqB,MAAMwqB,EAAO,GAAG,KACjBA,EAAO,GAAG,KACTxqB,MAAMwqB,EAAO,GAAG,IAEjB,MAAO,CACN3vB,SAAU,CAAEC,KAAM,aAAcC,YAAayvB,GAC7C1vB,KAAM,UACNF,WAAYzK,KAAKyK,WAGpB,CAGA,WACD,EAAC8vB,CAAA,CA9BO,GAiCHG,gBACL,WAAA,SAAAA,EAAY9C,EAAiB+C,EAAelwB,GAC3C,GA8COgN,KAAAA,OACAmgB,EAAAA,KAAAA,WACA+C,EAAAA,KAAAA,SACAlwB,EAAAA,KAAAA,gBAjDP,GAAKmtB,QAAsB3wB,IAAb2wB,EAAM,SAAiC3wB,IAAb2wB,EAAM,GAC7C,UAAUlyB,MACT,2FAGF,IAAKi1B,QAAkB1zB,IAAX0zB,EAAI,SAA+B1zB,IAAX0zB,EAAI,GACvC,MAAM,IAAIj1B,MACT,2FAGF1F,KAAK43B,MAAQ,CACZp1B,IAAKo1B,EAAM,GACXn1B,IAAKm1B,EAAM,GACXj4B,EAAGu6B,GAAMtC,EAAM,GACfl4B,EAAGw6B,GAAMtC,EAAM,IAGhB53B,KAAK26B,IAAM,CACVn4B,IAAKm4B,EAAI,GACTl4B,IAAKk4B,EAAI,GACTh7B,EAAGu6B,GAAMS,EAAI,GACbj7B,EAAGw6B,GAAMS,EAAI,IAGd36B,KAAKyK,WAAaA,GAAe,CAAiB,EAElD,IAAMmwB,EAAI56B,KAAK43B,MAAMj4B,EAAIK,KAAK26B,IAAIh7B,EAE5Bk7B,EACLz7B,KAAKC,IAAID,KAAKkiB,KAFLthB,KAAK43B,MAAMl4B,EAAIM,KAAK26B,IAAIj7B,GAEX,GAAM,GAC5BN,KAAKokB,IAAIxjB,KAAK43B,MAAMl4B,GACnBN,KAAKokB,IAAIxjB,KAAK26B,IAAIj7B,GAClBN,KAAKC,IAAID,KAAKkiB,IAAIsZ,EAAI,GAAM,GAG9B,GAFA56B,KAAKyX,EAAI,EAAMrY,KAAKy1B,KAAKz1B,KAAKQ,KAAKi7B,IAE/B76B,KAAKyX,IAAMrY,KAAKiiB,GACnB,MAAM,IAAI3b,MACKkyB,cAAAA,UAAa+C,EAAG,mGAEzB,GAAI9qB,MAAM7P,KAAKyX,GACrB,MAAU,IAAA/R,MAAK,4CAC8BkyB,EAAK,QAAQ+C,EAG5D,CAAC,IAAAG,EAAAJ,EAAAn5B,UAyKAm5B,OAzKAI,EAUDC,YAAA,SAAYC,GACX,IAAMC,EAAI77B,KAAKkiB,KAAK,EAAI0Z,GAAKh7B,KAAKyX,GAAKrY,KAAKkiB,IAAIthB,KAAKyX,GAC/CyjB,EAAI97B,KAAKkiB,IAAI0Z,EAAIh7B,KAAKyX,GAAKrY,KAAKkiB,IAAIthB,KAAKyX,GACzC9X,EACLs7B,EAAI77B,KAAKokB,IAAIxjB,KAAK43B,MAAMl4B,GAAKN,KAAKokB,IAAIxjB,KAAK43B,MAAMj4B,GACjDu7B,EAAI97B,KAAKokB,IAAIxjB,KAAK26B,IAAIj7B,GAAKN,KAAKokB,IAAIxjB,KAAK26B,IAAIh7B,GACxCD,EACLu7B,EAAI77B,KAAKokB,IAAIxjB,KAAK43B,MAAMl4B,GAAKN,KAAKkiB,IAAIthB,KAAK43B,MAAMj4B,GACjDu7B,EAAI97B,KAAKokB,IAAIxjB,KAAK26B,IAAIj7B,GAAKN,KAAKkiB,IAAIthB,KAAK26B,IAAIh7B,GACxCk7B,EAAII,EAAI77B,KAAKkiB,IAAIthB,KAAK43B,MAAMl4B,GAAKw7B,EAAI97B,KAAKkiB,IAAIthB,KAAK26B,IAAIj7B,GACvD+C,EAAM03B,GAAM/6B,KAAKw0B,MAAMiH,EAAGz7B,KAAKQ,KAAKR,KAAKC,IAAIM,EAAG,GAAKP,KAAKC,IAAIK,EAAG,KAEvE,MAAO,CADKy6B,GAAM/6B,KAAKw0B,MAAMl0B,EAAGC,GACnB8C,EACd,EAACq4B,EAKD5X,IAAA,SACCiY,EACAjnB,GAEA,IAAMknB,EAAY,GAClB,IAAKD,GAAkBA,GAAkB,EACxCC,EAAUjwB,KAAK,CAACnL,KAAK43B,MAAMp1B,IAAKxC,KAAK43B,MAAMn1B,MAC3C24B,EAAUjwB,KAAK,CAACnL,KAAK26B,IAAIn4B,IAAKxC,KAAK26B,IAAIl4B,WAGvC,IADA,IAAM44B,EAAQ,GAAOF,EAAiB,GAC7BnwB,EAAI,EAAGA,EAAImwB,IAAkBnwB,EAAG,CACxC,IACMswB,EAAOt7B,KAAK+6B,YADLM,EAAQrwB,GAErBowB,EAAUjwB,KAAKmwB,EAChB,CAkBD,IAXA,IAAIC,GAAc,EACdC,EAAqB,EAInBC,EAAmBvnB,GAAWA,EAAQwnB,OAASxnB,EAAQwnB,OAAS,GAChEC,EAAgB,IAAMF,EACtBG,GAAkB,IAAMH,EACxBI,EAAc,IAAMJ,EAGjBnwB,EAAI,EAAGA,EAAI8vB,EAAUnwB,SAAUK,EAAG,CAC1C,IAAMwwB,EAAUV,EAAU9vB,EAAI,GAAG,GAC3BywB,EAAMX,EAAU9vB,GAAG,GACnB0wB,EAAa58B,KAAK68B,IAAIF,EAAMD,GAEjCE,EAAaH,IACXE,EAAMJ,GAAiBG,EAAUF,GACjCE,EAAUH,GAAiBI,EAAMH,GAEnCL,GAAc,EACJS,EAAaR,IACvBA,EAAqBQ,EAEvB,CAEA,IAAME,EAAU,GAChB,GAAIX,GAAeC,EAAqBC,EAAkB,CACzD,IAAIU,EAA8B,GAClCD,EAAQ/wB,KAAKgxB,GAEb,IAAK,IAAI1a,EAAI,EAAGA,EAAI2Z,EAAUnwB,SAAUwW,EAAG,CAC1C,IAAM2a,EAAOhB,EAAU3Z,GAAG,GAC1B,GAAIA,EAAI,GAAKriB,KAAK68B,IAAIG,EAAOhB,EAAU3Z,EAAI,GAAG,IAAMoa,EAAa,CAChE,IAAIQ,EAAOjB,EAAU3Z,EAAI,GAAG,GACxB6a,EAAOlB,EAAU3Z,EAAI,GAAG,GACxB8a,EAAOnB,EAAU3Z,GAAG,GACpB+a,EAAOpB,EAAU3Z,GAAG,GACxB,GACC4a,GAAQ,KACRA,EAAOT,GACE,MAATW,GACA9a,EAAI,EAAI2Z,EAAUnwB,QAClBmwB,EAAU3Z,EAAI,GAAG,IAAM,KACvB2Z,EAAU3Z,EAAI,GAAG,GAAKma,EACrB,CACDO,EAAQhxB,KAAK,EAAE,IAAKiwB,EAAU3Z,GAAG,KACjCA,IACA0a,EAAQhxB,KAAK,CAACiwB,EAAU3Z,GAAG,GAAI2Z,EAAU3Z,GAAG,KAC5C,QACD,CAAO,GACN4a,EAAOV,GACPU,EAAO,MACG,MAAVE,GACA9a,EAAI,EAAI2Z,EAAUnwB,QAClBmwB,EAAU3Z,EAAI,GAAG,GAAKka,GACtBP,EAAU3Z,EAAI,GAAG,GAAK,IACrB,CACD0a,EAAQhxB,KAAK,CAAC,IAAKiwB,EAAU3Z,GAAG,KAChCA,IACA0a,EAAQhxB,KAAK,CAACiwB,EAAU3Z,GAAG,GAAI2Z,EAAU3Z,GAAG,KAC5C,QACD,CAEA,GAAI4a,EAAOT,GAAkBW,EAAOZ,EAAe,CAElD,IAAMc,EAAOJ,EACbA,EAAOE,EACPA,EAAOE,EAGP,IAAMC,EAAOJ,EACbA,EAAOE,EACPA,EAAOE,CACR,CAKA,GAJIL,EAAOV,GAAiBY,EAAOX,IAClCW,GAAQ,KAGLF,GAAQ,KAAOE,GAAQ,KAAOF,EAAOE,EAAM,CAC9C,IAAMI,GAAW,IAAMN,IAASE,EAAOF,GACjCO,EAAMD,EAAUH,GAAQ,EAAIG,GAAWL,EAC7CH,EAAQhxB,KAAK,CACZiwB,EAAU3Z,EAAI,GAAG,GAAKka,EAAgB,KAAO,IAC7CiB,KAEDT,EAAU,IACFhxB,KAAK,CACZiwB,EAAU3Z,EAAI,GAAG,GAAKka,GAAiB,IAAM,IAC7CiB,IAEDV,EAAQ/wB,KAAKgxB,EACd,MAECD,EAAQ/wB,KADRgxB,EAAU,IAGXA,EAAQhxB,KAAK,CAACixB,EAAMhB,EAAU3Z,GAAG,IAClC,MACC0a,EAAQhxB,KAAK,CAACiwB,EAAU3Z,GAAG,GAAI2Z,EAAU3Z,GAAG,IAE9C,CACD,KAAO,CAEN,IAAMob,EAA+B,GACrCX,EAAQ/wB,KAAK0xB,GACb,IAAK,IAAInb,EAAI,EAAGA,EAAI0Z,EAAUnwB,SAAUyW,EACvCmb,EAAS1xB,KAAK,CAACiwB,EAAU1Z,GAAG,GAAI0Z,EAAU1Z,GAAG,IAE/C,CAGA,IADA,IAAMwB,EAAM,IAAIqX,GAAI,CAAE9vB,WAAYzK,KAAKyK,aAC9Bmc,EAAI,EAAGA,EAAIsV,EAAQjxB,SAAU2b,EAAG,CACxC,IAAMkW,EAAO,IAAI1C,GAAclmB,EAAQ7S,qBACvC6hB,EAAIsX,WAAWrvB,KAAK2xB,GAEpB,IADA,IAAM/rB,EAASmrB,EAAQtV,GACdmW,EAAK,EAAGA,EAAKhsB,EAAO9F,SAAU8xB,EACtCD,EAAKxC,OAAOvpB,EAAOgsB,GAErB,CACA,OAAO7Z,CACR,EAACwX,CAAA,CAtND,GC3DYsC,GAQZ,SAAAl9B,OACCuxB,EAAKvxB,EAALuxB,MACArlB,EAAIlM,EAAJkM,KACA5D,EAAOtI,EAAPsI,QACAI,EAAS1I,EAAT0I,UACA2oB,EAAerxB,EAAfqxB,gBACA9vB,EAAmBvB,EAAnBuB,oBAbSgwB,KAAAA,kBACArlB,UAAI,EAAAhM,KACJoI,aACAI,EAAAA,KAAAA,sBACA2oB,qBAAe,EAAAnxB,KACfqB,yBAUT,EAAArB,KAAKqxB,MAAQA,EACbrxB,KAAKgM,KAAOA,EACZhM,KAAKoI,QAAUA,EACfpI,KAAKwI,UAAYA,EACjBxI,KAAKmxB,gBAAkBA,EACvBnxB,KAAKqB,oBAAsBA,CAC5B,EC3BY47B,gBAA4B,SAAAC,GACxC,SAAAD,EACU18B,EACQhB,EACA49B,GAA0C,IAAAp9B,EAAA,OAE3DA,EAAAm9B,EAAAr4B,KAAA7E,KAAMO,UAJGA,YAAA,EAAAR,EACQR,mBAAAQ,EAAAA,EACAo9B,sBAAA,EAAAp9B,EAKXq9B,uBAAyB,SAC/B37B,EACA47B,GAEA,OAAOt9B,EAAKu9B,iBAAiB77B,EAAO,SAACkK,GACpC,OAAOsC,SACNtC,EAAQlB,YACPkB,EAAQlB,WAAWuB,OAASjM,EAAKiM,OACjCqxB,GACE1xB,EAAQlG,KAAO43B,EAGpB,EACD,EApBUt9B,EAAMQ,OAANA,EACQR,EAAaR,cAAbA,EACAQ,EAAgBo9B,iBAAhBA,EAA0Cp9B,CAG5D,CAsDCk9B,OA7DuCt3B,EAAAs3B,EAAAC,GAOvCD,EAAA17B,UAiBO+7B,iBAAA,SACP77B,EACA87B,GAAqCt3B,IAAAA,OAE/Bu3B,EAAOx9B,KAAKm9B,iBAAiB7E,OAAO72B,GAEpCoK,EAAW7L,KAAKqxB,MAAMoM,OAAOD,EAAMD,GAEnCG,EAA4D,CACjE3I,WAAO9tB,EACP02B,QAAS3c,UA0BV,OAvBAnV,EAAS7I,QAAQ,SAAC2I,GACjB,IAAIf,EACJ,GAA8B,eAA1Be,EAAQjB,SAASC,KAArB,CAOA,IAAMitB,GANLhtB,EAAce,EAAQjB,SAASE,aAMN,GACpBgzB,EAAO33B,EAAK1G,cAAcs+B,QAAQp8B,EAAOm2B,GAC3CgG,EAAOF,EAAQC,SAAWC,EAAO33B,EAAKkrB,kBACzCuM,EAAQ3I,MAAQ6C,GAIjB,IAAM+C,EAAM/vB,EAAYA,EAAYK,OAAS,GACvC6yB,EAAU73B,EAAK1G,cAAcs+B,QAAQp8B,EAAOk5B,GAC9CmD,EAAUJ,EAAQC,SAAWG,EAAU73B,EAAKkrB,kBAC/CuM,EAAQ3I,MAAQ4F,EAbjB,CAeD,GAEO+C,EAAQ3I,KAChB,EAACkI,CAAA,CA7DuC,CAAQD,ICDpCe,gBAAsB,SAAAb,GAClC,SAAAa,EAAYx9B,GACX,OAAA28B,EAAAr4B,KAAMtE,KAAAA,IAAOP,IACd,CAUC,OAbiC2F,EAAAo4B,EAAAb,GAGjCa,EAAAx8B,UACMs8B,QAAA,SAAQG,EAAiCC,GAC/C,IAAAvE,EAAiB15B,KAAKoI,QAAQ61B,EAAiB,GAAIA,EAAiB,IAOpE,OALiB1+B,EAChB,CAAEI,EAHM+5B,EAAD/5B,EAGFD,EAHMg6B,EAADh6B,GAIV,CAAEC,EAAGq+B,EAAWj8B,WAAYrC,EAAGs+B,EAAW97B,YAI5C,EAAC67B,CAAA,CAbiC,CAAQf,ICH3B,SAAAkB,GAAmBp+B,GAWlC,IAVA0I,EAAS1I,EAAT0I,UACAH,EAAKvI,EAALuI,MAUM81B,EATSr+B,EAAfqxB,gBASmC,EAC3BxxB,EAAS0I,EAAT1I,EAAGD,EAAM2I,EAAN3I,EAEX,MAAO,CACNiL,KAAM,UACNF,WAAY,CAAE,EACdC,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACCpC,EAAU7I,EAAIw+B,EAAUz+B,EAAIy+B,GAC5B31B,EAAU7I,EAAIw+B,EAAUz+B,EAAIy+B,GAC5B31B,EAAU7I,EAAIw+B,EAAUz+B,EAAIy+B,GAC5B31B,EAAU7I,EAAIw+B,EAAUz+B,EAAIy+B,GAC5B31B,EAAU7I,EAAIw+B,EAAUz+B,EAAIy+B,IAC3B54B,IAAI,SAAC64B,GAAM,MAAA,CAACA,EAAE57B,IAAK47B,EAAE37B,IAAI,KAI/B,CC9BA,IAAa47B,gBAAyB,SAAAnB,GACrC,SAAAmB,EAAY99B,GAAsB,OACjC28B,EAAAr4B,KAAMtE,KAAAA,IAAOP,IACd,CASC,OAZoC2F,EAAA04B,EAAAnB,GAGpCmB,EAAA98B,UAEM+2B,OAAA,SAAO72B,GAEb,OAAOy8B,GAAoB,CAC1B11B,UAAWxI,KAAKwI,UAChBH,MAAO,CAAE1I,EAH+B8B,EAAjCM,WAGKrC,EAH4B+B,EAAlBS,YAItBivB,gBAAiBnxB,KAAKmxB,iBAExB,EAACkN,CAAA,CAZoC,CAAQrB,IC6CjCsB,gBAAyB,SAAAvL,GAarC,SAAAuL,EAAYpqB,GAA8DnU,IAAAA,GACzEA,EAAAgzB,EAAAluB,KAAMqP,KAAAA,IAAQlU,MAbfgM,KAAO,cAAajM,EAEZw+B,kBAAoB,EAACx+B,EACrBo5B,iBAASp5B,EACTq5B,oBAAc,EAAAr5B,EACdy3B,eAAS,EAAAz3B,EACTy+B,qBAAez+B,EAAAA,EACf03B,aAAO,EAAA13B,EAGP0+B,cAKP,EAAA,IAAM9G,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAcR,GAVCj4B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAQoG,CAAAA,EAAAA,EAAmBzjB,EAAQujB,SAEhCE,EAGhB53B,EAAKy+B,mBACJtqB,QAAgCjN,IAArBiN,EAAQuqB,WAAyBvqB,EAAQuqB,SAI1B,QAAhB,MAAPvqB,OAAO,EAAPA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,KACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAAC,OAAAh4B,CACF,CAzCqC4F,EAAA24B,EAAAvL,GAyCpC,IAAAzxB,EAAAg9B,EAAA/8B,UAuPA+8B,OAvPAh9B,EAEO02B,MAAA,WACP,QAAuB/wB,IAAnBjH,KAAKm5B,UAAT,CAIA,IAAM7G,EAAatyB,KAAKm5B,UAGxBn5B,KAAKo5B,gBAAkBp5B,KAAKqxB,MAAY,OAAC,CAACrxB,KAAKo5B,iBAC/Cp5B,KAAKu+B,kBAAoB,EACzBv+B,KAAKm5B,eAAYlyB,EACjBjH,KAAKo5B,oBAAiBnyB,EAEH,YAAfjH,KAAKi4B,OACRj4B,KAAK2xB,aAIN3xB,KAAKiyB,SAASK,EAfd,CAgBD,EAAChxB,EAGDkwB,kBAAA,SAAkBjxB,GACjBP,KAAKy+B,SAAW,IAAIxB,GACnB18B,EACA,IAAIw9B,GAAsBx9B,GAC1B,IAAI89B,GAAyB99B,GAE/B,EAACe,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAGX,GAFAzB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,aAEL3wB,IAAnBjH,KAAKm5B,WAAsD,IAA3Bn5B,KAAKu+B,oBAGxCv+B,KAAKm5B,WACsB,IAA3Bn5B,KAAKu+B,mBACLv+B,KAAKo5B,eACJ,CACD,IAKMsF,EAJL1+B,KAAKm5B,WACLn5B,KAAKw+B,iBACLx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,YAEC,CAAC13B,EAAMe,IAAKf,EAAMgB,KAErEzC,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKo5B,eACT1uB,SAAU,CAAEC,KAAM,QAASC,YAAa8zB,MAI1C,IAAMnF,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAINI,EAAoB3uB,YAAYivB,MAGhC,IAAM8E,WNwHsB/3B,GAa9B,IAZAgxB,EAAKhxB,EAALgxB,MACA+C,EAAG/zB,EAAH+zB,IAYMiE,EAXCh4B,EAAPsN,SAWwB,CAAA,EACxB,GAAoB,iBAAT0qB,EACV,MAAU,IAAAl5B,MAAM,uDAGjB,IAAAm5B,EAKID,EAJHn0B,WAAeq0B,EAIZF,EAHHzD,eAAAA,OAAiB,IAAH2D,EAAG,IAAGA,EAAAC,EAGjBH,EAFHlD,OAAAA,OAAS,IAAHqD,EAAG,GAAEA,EAAAC,EAERJ,EADHv9B,oBAAAA,OAAmB,IAAA29B,EAAG,EAACA,EAQxB,OANe,IAAItE,GAAgB9C,EAAO+C,WAL/BkE,EAAG,CAAA,EAAEA,GAMI3b,IAAIiY,EAAgB,CACvCO,OAAQA,EACRr6B,oBAAAA,IAGWo5B,QACb,CMxJuBwE,CAAgB,CACnCrH,MAAO2B,EAAoB3uB,YAAY,GACvC+vB,IAAK+D,EACLxqB,QAAS,CAAE7S,oBAAqBrB,KAAKqB,uBAGlCs9B,GACH3+B,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAUi0B,EAAYj0B,WAI1B,CACD,EAACpJ,EAGD+C,QAAA,SAAQ5C,GACP,GAA+B,IAA3BzB,KAAKu+B,kBAAyB,CACjC,IAGMG,EAFL1+B,KAAKw+B,iBAAmBx+B,KAAKy+B,SAASrB,uBAAuB37B,IAEX,CAACA,EAAMe,IAAKf,EAAMgB,KAErE41B,EAAoBr4B,KAAKqxB,MAAMiH,OAAO,CACrC,CACC5tB,SAAU,CACTC,KAAM,aACNC,YAAa,CACZ8zB,EACAA,IAGFj0B,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKm5B,UAZWd,EAYhB,GAEA,IAAA6G,EAAkBl/B,KAAKqxB,MAAMiH,OAAO,CACnC,CACC5tB,SAAU,CACTC,KAAM,QACNC,YAAa8zB,GAEdj0B,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKo5B,eATS8F,EAAA,GAWdl/B,KAAKu+B,oBACLv+B,KAAK0xB,YACN,MAAsC,IAA3B1xB,KAAKu+B,mBAA2Bv+B,KAAKm5B,YAG/Cn5B,KAAKyI,UAAU,WACfzI,KAAKg4B,QAEP,EAAC12B,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,QAChC73B,KAAKm4B,UAGF12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QAChC93B,KAAKg4B,OAEP,EAAC12B,EAGDwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGd62B,QAAA,WACC,IACKn4B,KAAKm5B,WACRn5B,KAAKqxB,MAAY,OAAC,CAACrxB,KAAKm5B,YAErBn5B,KAAKo5B,gBACRp5B,KAAKqxB,MAAK,OAAQ,CAACrxB,KAAKo5B,gBAE1B,CAAE,MAAOhf,GAET,CAAApa,KAAKo5B,oBAAiBnyB,EACtBjH,KAAKm5B,eAAYlyB,EACjBjH,KAAKu+B,kBAAoB,EACN,YAAfv+B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,KR7QN,CACN/jB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IQoQR,MACkB,YAAjB9C,EAAQhB,MACkB,eAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAOjG,gBAAkBnN,KAAK0yB,wBAC7B1yB,KAAKoT,OAAOjG,gBACZiG,EAAOjG,gBACPxB,GAGDyH,EAAOhG,gBAAkBpN,KAAK6yB,uBAC7B7yB,KAAKoT,OAAOhG,gBACZgG,EAAOhG,gBACPzB,GAGMyH,GAEU,YAAjBzH,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAO2mB,kBACZ3mB,EAAOzG,WACPhB,GAGDyH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAO0mB,kBACZ1mB,EAAO3G,WACPd,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAO4mB,yBACZ,UACAruB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAO6mB,yBACZ,EACAtuB,GAGMyH,GAGDA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAEE,eAA1BA,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCL,EAAQjB,SAASE,YAAYK,QAAU,CAK1C,EAACqzB,CAAA,CAhSoC,CAAQvN,IC1CjCoO,gBAAiB,SAAAjC,GAC7B,SAAAiC,EACU5+B,EACQhB,EACA49B,GAA0Cp9B,IAAAA,EAAA,OAE3DA,EAAAm9B,EAAAr4B,KAAMtE,KAAAA,IAAQR,MAJLQ,YAAA,EAAAR,EACQR,mBAAAQ,EAAAA,EACAo9B,wBAAAp9B,EAMXq/B,iCAAmC,SAAC39B,GAC1C,OAAO1B,EAAKs/B,aAAa59B,EAAO,SAACkK,GAChC,OAAOsC,QACNtC,EAAQlB,YAAckB,EAAQlB,WAAWuB,OAASjM,EAAKiM,KAEzD,EACD,EAACjM,EAEMq9B,uBAAyB,SAC/B37B,EACA47B,GAEA,OAAOt9B,EAAKs/B,aAAa59B,EAAO,SAACkK,GAChC,OAAOsC,QACNtC,EAAQlB,YACPkB,EAAQlB,WAAWuB,OAASjM,EAAKiM,MACjCL,EAAQlG,KAAO43B,EAElB,EACD,EA3BUt9B,EAAMQ,OAANA,EACQR,EAAaR,cAAbA,EACAQ,EAAgBo9B,iBAAhBA,EAA0Cp9B,CAG5D,CAwDCo/B,OA/D4Bx5B,EAAAw5B,EAAAjC,GAO5BiC,EAAA59B,UAwBO89B,aAAA,SACP59B,EACA87B,GAAqCt3B,IAAAA,OAE/Bu3B,EAAOx9B,KAAKm9B,iBAAiB7E,OAAO72B,GAEpCoK,EAAW7L,KAAKqxB,MAAMoM,OAAOD,EAAMD,GAEnCG,EAA4D,CACjE3I,WAAO9tB,EACP02B,QAAS3c,UAqBV,OAlBAnV,EAAS7I,QAAQ,SAAC2I,GACjB,IAAIf,EACJ,GAA8B,YAA1Be,EAAQjB,SAASC,KACpBC,EAAce,EAAQjB,SAASE,YAAY,OACrC,IAA8B,eAA1Be,EAAQjB,SAASC,KAG3B,OAFAC,EAAce,EAAQjB,SAASE,WAGhC,CAEAA,EAAY5H,QAAQ,SAAC+xB,GACpB,IAAM6I,EAAO33B,EAAK1G,cAAcs+B,QAAQp8B,EAAOszB,GAC3C6I,EAAOF,EAAQC,SAAWC,EAAO33B,EAAKkrB,kBACzCuM,EAAQ3I,MAAQA,EAElB,EACD,GAEO2I,EAAQ3I,KAChB,EAACoK,CAAA,CA/D4B,CAAQnC,IC4CzBsC,yBAAwBvM,GAepC,SAAAuM,EAAYprB,GAA2D,IAAAnU,GACtEA,EAAAgzB,EAAAluB,KAAMqP,KAAAA,IAAQlU,MAffgM,KAAO,aAAYjM,EAEXw+B,kBAAoB,EAACx+B,EACrBo5B,eAAS,EAAAp5B,EACTq5B,sBAAcr5B,EACdw/B,4BAAsBx/B,EAAAA,EACtBy3B,eAASz3B,EAAAA,EACTy+B,qBAAe,EAAAz+B,EACf03B,aAAO,EAAA13B,EACPy/B,WAAY,EAAKz/B,EAGjB0+B,cAAQ,EAKf,IAAM9G,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAmBR,GAfCj4B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,KAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EAGhB53B,EAAKy+B,mBACJtqB,QAAgCjN,IAArBiN,EAAQuqB,WAAyBvqB,EAAQuqB,SAErD1+B,EAAKw/B,wBACJrrB,QAA8CjN,IAAnCiN,EAAQqrB,wBAChBrrB,EAAQqrB,uBAKe,QAAvBrrB,MAAAA,OAAAA,EAAAA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,KACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAAC,OAAAh4B,CACF,CAhDoC4F,EAAA25B,EAAAvM,GAgDnC,IAAAzxB,EAAAg+B,EAAA/9B,UA+VA,OA/VAD,EAEO02B,MAAA,WACP,QAAuB/wB,IAAnBjH,KAAKm5B,UAAT,CAIA,IAAMI,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAINI,EAAoB3uB,YAAYivB,MAChC75B,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,aACNC,YAAWkB,GAAAA,OAAMytB,EAAoB3uB,iBAKxC,IAAM0nB,EAAatyB,KAAKm5B,UAGxBn5B,KAAKo5B,gBAAkBp5B,KAAKqxB,MAAY,OAAC,CAACrxB,KAAKo5B,iBAC/Cp5B,KAAKu+B,kBAAoB,EACzBv+B,KAAKm5B,eAAYlyB,EACjBjH,KAAKo5B,oBAAiBnyB,EAGH,YAAfjH,KAAKi4B,OACRj4B,KAAK2xB,aAIN3xB,KAAKiyB,SAASK,EAhCd,CAiCD,EAAChxB,EAGDkwB,kBAAA,SAAkBjxB,GACjBP,KAAKy+B,SAAW,IAAIU,GACnB5+B,EACA,IAAIw9B,GAAsBx9B,GAC1B,IAAI89B,GAAyB99B,GAE/B,EAACe,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKw/B,WAAY,EACjBx/B,KAAKyI,UAAUzI,KAAKy3B,QAAQG,YAEL3wB,IAAnBjH,KAAKm5B,WAAsD,IAA3Bn5B,KAAKu+B,kBAAzC,CAGA,IAAMhF,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAINI,EAAoB3uB,YAAYivB,MAEhC,IAGM6E,EAFL1+B,KAAKw+B,iBACLx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,YACC,CAAC13B,EAAMe,IAAKf,EAAMgB,KAIrE,GAAIzC,KAAKo5B,eAAgB,CACxB,IAAAK,EACCF,EAAoB3uB,YACnB2uB,EAAoB3uB,YAAYK,OAAS,GAE3CyuB,EAAiB15B,KAAKoI,QAJJqxB,EAAA,GAAaA,MAKdl6B,EAChB,CAAEI,EAFM+5B,EAAD/5B,EAEFD,EAFMg6B,EAADh6B,GAGV,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGClC,KAAKmxB,iBAGtCnxB,KAAKyI,UAAUzI,KAAKy3B,QAAQO,MAE9B,CAGAh4B,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,aACNC,eAAWkB,OAAMytB,EAAoB3uB,aAAa8zB,OAvCrD,CA2CD,EAACp9B,EAGD+C,QAAA,SAAQ5C,GAKHzB,KAAKu+B,kBAAoB,IAAMv+B,KAAKw/B,WACvCx/B,KAAKwD,YAAY/B,GAElBzB,KAAKw/B,WAAY,EAEjB,IAIMd,EAHL1+B,KAAKm5B,WACLn5B,KAAKw+B,iBACLx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,YACC,CAAC13B,EAAMe,IAAKf,EAAMgB,KAErE,GAA+B,IAA3BzC,KAAKu+B,kBAAyB,CACjC,IAAAlG,EAAoBr4B,KAAKqxB,MAAMiH,OAAO,CACrC,CACC5tB,SAAU,CACTC,KAAM,aACNC,YAAa,CACZ8zB,EACAA,IAGFj0B,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKm5B,UAZWd,EAYhB,GACAr4B,KAAKu+B,oBACLv+B,KAAK0xB,YACN,MAAO,GAA+B,IAA3B1xB,KAAKu+B,mBAA2Bv+B,KAAKm5B,UAAW,CAC1D,IAAMI,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAGN+F,EAAkBl/B,KAAKqxB,MAAMiH,OAAO,CACnC,CACC5tB,SAAU,CACTC,KAAM,QACNC,YAAWkB,GAAAA,OAAM4yB,IAElBj0B,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKo5B,eATS8F,EAAA,GAadl/B,KAAKyI,UAAUzI,KAAKy3B,QAAQO,OAE5Bh4B,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,aACNC,YAAa,CACZ2uB,EAAoB3uB,YAAY,GAChC8zB,EACAA,OAMJ1+B,KAAKu+B,mBACN,SAAWv+B,KAAKm5B,UAAW,CAC1B,IAAMI,EAAsBv5B,KAAKqxB,MAAMmI,gBACtCx5B,KAAKm5B,WAGNQ,EACCJ,EAAoB3uB,YACnB2uB,EAAoB3uB,YAAYK,OAAS,GAE3C2uB,EAAiB55B,KAAKoI,QAJJuxB,KAAaA,EAAA,IAY/B,GAPiBp6B,EAChB,CAAEI,EAFMi6B,EAADj6B,EAEFD,EAFMk6B,EAADl6B,GAGV,CAAEC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,aAGClC,KAAKmxB,gBAGtCnxB,KAAKg4B,YACC,CAEN,IAAMyH,EAAgB,CACrB90B,KAAM,aACNC,YAAWkB,GAAAA,OAAMytB,EAAoB3uB,YAAa8zB,CAAAA,KAGnD,IAAK1+B,KAAKu/B,wBACoBzK,GAAe,CAC3CnqB,KAAM,UACND,SAAU+0B,EACVh1B,WAAY,CAAA,IAIZ,OAIEzK,KAAKo5B,iBACRp5B,KAAKyI,UAAUzI,KAAKy3B,QAAQO,OAE5Bh4B,KAAKqxB,MAAM0H,eAAe,CACzB,CAAEtzB,GAAIzF,KAAKm5B,UAAWzuB,SAAU+0B,GAChC,CACCh6B,GAAIzF,KAAKo5B,eACT1uB,SAAU,CACTC,KAAM,QACNC,YACC2uB,EAAoB3uB,YACnB2uB,EAAoB3uB,YAAYK,OAAS,OAK9CjL,KAAKu+B,oBAEP,CACD,CACD,EAACj9B,EAGDmD,UAAA,aAAcnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,QAChC73B,KAAKm4B,UAGF12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QAChC93B,KAAKg4B,OAEP,EAAC12B,EAGDwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,WAAW,EAAA5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGd62B,QAAA,WACC,IACKn4B,KAAKm5B,WACRn5B,KAAKqxB,MAAY,OAAC,CAACrxB,KAAKm5B,YAErBn5B,KAAKo5B,gBACRp5B,KAAKqxB,MAAK,OAAQ,CAACrxB,KAAKo5B,gBAE1B,CAAE,MAAOhf,GAET,CAAApa,KAAKo5B,oBAAiBnyB,EACtBjH,KAAKm5B,eAAYlyB,EACjBjH,KAAKu+B,kBAAoB,EACN,YAAfv+B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAQkH,GV9Xd,CACNjrB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IUqXR,MACkB,YAAjB9C,EAAQhB,MACkB,eAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAOjG,gBAAkBnN,KAAK0yB,wBAC7B1yB,KAAKoT,OAAOjG,gBACZiG,EAAOjG,gBACPxB,GAGDyH,EAAOhG,gBAAkBpN,KAAK6yB,uBAC7B7yB,KAAKoT,OAAOhG,gBACZgG,EAAOhG,gBACPzB,GAGMyH,GAEU,YAAjBzH,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAO2mB,kBACZ3mB,EAAOzG,WACPhB,GAGDyH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAO0mB,kBACZ1mB,EAAO3G,WACPd,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAO4mB,yBACZ,UACAruB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAO6mB,yBACZ,EACAtuB,GAGMyH,GAGDA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAC8G,KAAAA,IAEE,eAA1BA,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCL,EAAQjB,SAASE,YAAYK,QAAU,CAK1C,EAACq0B,CAAA,EA/Y2CvO,IChD7B,SAAA2O,GACf/zB,EACAtK,GAEA,MAC2B,UAA1BsK,EAAQjB,SAASC,MACjBgsB,GAAkBhrB,EAAQjB,SAASE,YAAavJ,EAElD,CCqBa,IAAAs+B,gBAAmB,SAAA5M,GAK/B,SAAA4M,EAAYzrB,GAAqD,IAAAnU,GAChEA,EAAAgzB,EAAAluB,KAAA7E,KAAMkU,IAASnU,MALhBiM,KAAO,QAAOjM,EAEN03B,aAIP,EAAA,IAAME,EAAiB,CACtBW,OAAQ,aAOR,OAHAv4B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAA,CAAA,EAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EACf53B,CACF,CAhB+B4F,EAAAg6B,EAAA5M,GAgB9B,IAAAzxB,EAAAq+B,EAAAp+B,UAsGA,OAtGAD,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQa,OAC7B,EAACh3B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,IAAKzB,KAAKqxB,MACT,MAAU,IAAA3rB,MAAM,iCAGjB,IAAA2yB,EAAkBr4B,KAAKqxB,MAAMiH,OAAO,CACnC,CACC5tB,SAAU,CACTC,KAAM,QACNC,YAAa,CAACnJ,EAAMe,IAAKf,EAAMgB,MAEhCgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SAK3BhM,KAAKiyB,SAXSoG,EAWd,GACD,EAAC/2B,EAGDkC,YAAA,aAAgBlC,EAGhBmD,UAAA,aAAcnD,EAGdiD,QAAA,aAAYjD,EAGZ62B,QAAA,WAAY,EAAA72B,EAGZwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAA,CAAA,EZvGN,CACN/jB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IY4HR,MA7BkB,YAAjB9C,EAAQhB,MACkB,UAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,OAEjCoH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAO3G,WACZ2G,EAAO3G,WACPd,GAGDyH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAOzG,WACZyG,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAOtG,kBACZsG,EAAOtG,kBACPnB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAOpG,kBACZ,EACArB,IAIKyH,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC0zB,GAAa/zB,EAAS3L,KAAKqB,oBAK9B,EAACs+B,CAAA,CAtH8B,CAAQ5O,IC9BxB,SAAA6O,GACf10B,EACAgsB,GAEA,OACChsB,EAAW,KAAOgsB,EAAc,IAAMhsB,EAAW,KAAOgsB,EAAc,EAExE,CCJa,IAAA2I,gBAAsB,SAAA3C,GAClC,SAAA2C,EACUt/B,EACQhB,GAAoC,IAAAQ,EAAA,OAErDA,EAAAm9B,EAAAr4B,KAAMtE,KAAAA,IAAOP,MAHJO,YAAA,EAAAR,EACQR,mBAAAQ,EAAAA,EAKV+/B,gBAA4B,GAN1B//B,EAAMQ,OAANA,EACQR,EAAaR,cAAbA,EAAoCQ,CAGtD,CANkC4F,EAAAk6B,EAAA3C,GAMjC,IAAA57B,EAAAu+B,EAAAt+B,UAQsB,OARtBD,EAUMg3B,OAAA,SAAOyH,EAA4B/zB,GAAY,IAAAg0B,EAAAC,EACrD,GAAIjgC,KAAKkgC,IAAIj1B,OACZ,MAAU,IAAAvF,MAAM,+CAGjB,GAAIq6B,EAAe90B,QAAU,EAC5B,MAAU,IAAAvF,MAAM,mCAGjB1F,KAAK8/B,gBAAkB9/B,KAAKqxB,MAAMiH,OAEjC,CACC,CACC5tB,SAAU,CACTC,KAAM,QACNC,YAAam1B,EAAe,IAE7Bt1B,YAAUu1B,EACTh0B,CAAAA,KAAAA,GAAIg0B,EACHxP,KAAmC,EAAIwP,IAI1C,CACCt1B,SAAU,CACTC,KAAM,QACNC,YAAam1B,EAAeA,EAAe90B,OAAS,IAErDR,YAAUw1B,EACTj0B,CAAAA,KAAAA,GAAIi0B,EACHzP,KAAmC,EAAIyP,KAK7C,EAAC3+B,EAAA,OAEM,WACFtB,KAAKkgC,IAAIj1B,SACZjL,KAAKqxB,MAAK,OAAQrxB,KAAKkgC,KACvBlgC,KAAK8/B,gBAAkB,GAEzB,EAACx+B,EAEM6+B,OAAA,SAAOC,GACb,GAAwB,IAApBpgC,KAAKkgC,IAAIj1B,OACZ,MAAU,IAAAvF,MAAM,+BAGjB1F,KAAKqxB,MAAM0H,eAEV,CACC,CACCtzB,GAAIzF,KAAKkgC,IAAI,GACbx1B,SAAU,CACTC,KAAM,QACNC,YAAaw1B,EAAmB,KAIlC,CACC36B,GAAIzF,KAAKkgC,IAAI,GACbx1B,SAAU,CACTC,KAAM,QACNC,YAAaw1B,EAAmBA,EAAmBn1B,OAAS,MAKjE,EAAC3J,EAEM++B,eAAA,SAAe5+B,GACrB,IAAM6+B,EAAUtgC,KAAKqxB,MAAMmI,gBAAgBx5B,KAAKkgC,IAAI,IAC9CK,EAAUvgC,KAAKqxB,MAAMmI,gBAAgBx5B,KAAKkgC,IAAI,IAE9C7L,EAAWr0B,KAAKT,cAAcs+B,QACnCp8B,EACA6+B,EAAQ11B,aAGH41B,EAAmBxgC,KAAKT,cAAcs+B,QAC3Cp8B,EACA8+B,EAAQ31B,aAMT,MAAO,CAAE61B,UAHSpM,EAAWr0B,KAAKmxB,gBAGduP,kBAFMF,EAAmBxgC,KAAKmxB,gBAGnD,EAACrjB,EAAA+xB,EAAA,CAAA,CAAAv7B,IAAAyJ,MAAAA,IA/FD,WACC,OAAW/N,KAAC8/B,gBAAgBh0B,QAC7B,EAAC4S,IAED,SAAQ2O,GAAe,KAAAwS,CAAA,CAdW,CAAQ7C,ICmD9B2D,gBAAqB,SAAA5N,GAgBjC,SAAA4N,EAAYzsB,GAAqDnU,IAAAA,GAChEA,EAAAgzB,EAAAluB,KAAMqP,KAAAA,IAAQlU,MAhBfgM,KAAO,UAASjM,EAERw+B,kBAAoB,EAACx+B,EACrBo5B,eAASp5B,EAAAA,EACTw/B,4BAAsBx/B,EAAAA,EACtBy3B,eAAS,EAAAz3B,EACTy+B,qBAAe,EAAAz+B,EAGf0+B,cAAQ,EAAA1+B,EACRR,mBAAa,EAAAQ,EACb6gC,mBAAa7gC,EAAAA,EACb03B,aAAO13B,EAAAA,EACPy/B,WAAY,EAKnB,IAAM7H,EAAiB,CACtBC,MAAO,YACPI,MAAO,WAmBR,GAfCj4B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAA,CAAA,EAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EAGhB53B,EAAKy+B,mBACJtqB,QAAgCjN,IAArBiN,EAAQuqB,WAAyBvqB,EAAQuqB,SAErD1+B,EAAKw/B,wBACJrrB,QAA8CjN,IAAnCiN,EAAQqrB,wBAChBrrB,EAAQqrB,uBAKe,QAAvBrrB,MAAAA,OAAAA,EAAAA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,EAAA,CAAA,EACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAAC,OAAAh4B,CACF,CAjDiC4F,EAAAg7B,EAAA5N,GAiDhC,IAAAzxB,EAAAq/B,EAAAp/B,UAycAo/B,OAzcAr/B,EAEO02B,MAAA,WACP,QAAuB/wB,IAAnBjH,KAAKm5B,UAAT,CAIA,IAAM0H,EAA4B7gC,KAAKqxB,MAAMmI,gBAC5Cx5B,KAAKm5B,WACJvuB,YAAY,GAKd,KAAIi2B,EAA0B51B,OAAS,GAAvC,CAIAjL,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,UACNC,YAAa,CAAAkB,GAAAA,OAER+0B,EAA0B5rB,MAAM,GAAI,GAAE,CACzC4rB,EAA0B,UAO/B,IAAMvO,EAAatyB,KAAKm5B,UAExBn5B,KAAKu+B,kBAAoB,EACzBv+B,KAAKm5B,eAAYlyB,EACjBjH,KAAK4gC,cAAa,SAGC,YAAf5gC,KAAKi4B,OACRj4B,KAAK2xB,aAGN3xB,KAAKiyB,SAASK,EA5Bd,CAXA,CAwCD,EAAChxB,EAGDkwB,kBAAA,SAAkBjxB,GACjBP,KAAKT,cAAgB,IAAIw+B,GAAsBx9B,GAC/CP,KAAKy+B,SAAW,IAAIU,GACnB5+B,EACAP,KAAKT,cACL,IAAI8+B,GAAyB99B,IAE9BP,KAAK4gC,cAAgB,IAAIf,GAAsBt/B,EAAQP,KAAKT,cAC7D,EAAC+B,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGDkC,YAAA,SAAY/B,GAIX,GAHAzB,KAAKw/B,WAAY,EACjBx/B,KAAKyI,UAAUzI,KAAKy3B,QAAQG,YAEL3wB,IAAnBjH,KAAKm5B,WAAsD,IAA3Bn5B,KAAKu+B,kBAAzC,CAIA,IAaI6B,EAbEU,EAAe9gC,KAAKw+B,gBACvBx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,gBACjDlyB,EAEG45B,EAA4B7gC,KAAKqxB,MAAMmI,gBAC5Cx5B,KAAKm5B,WACJvuB,YAAY,GASd,GAPIk2B,IACHr/B,EAAMe,IAAMs+B,EAAa,GACzBr/B,EAAMgB,IAAMq+B,EAAa,IAKK,IAA3B9gC,KAAKu+B,kBAAyB,CAGjC,IAAMvJ,EAAU,EAAI51B,KAAKC,IAAI,GAAIW,KAAKqB,oBAAsB,GACtDq6B,EAASt8B,KAAK6X,IAAI,KAAU+d,GAElCoL,EAAqB,CACpBS,EAA0B,GAC1B,CAACp/B,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,IAAMi5B,GACxBmF,EAA0B,GAE5B,MAAO,GAA+B,IAA3B7gC,KAAKu+B,kBACf6B,EAAqB,CACpBS,EAA0B,GAC1BA,EAA0B,GAC1B,CAACp/B,EAAMe,IAAKf,EAAMgB,KAClBo+B,EAA0B,QAErB,CACN,IAAAE,EACC/gC,KAAK4gC,cAAcP,eAAe5+B,GADCs/B,EAAjBL,mBAAFK,EAATN,WAIPzgC,KAAKyI,UAAUzI,KAAKy3B,QAAQO,OAE5BoI,EAAkB,GAAAt0B,OACd+0B,EAA0B5rB,MAAM,GAAI,GACvC4rB,CAAAA,EAA0B,GAC1BA,EAA0B,MAG3BT,EAAkB,GAAAt0B,OACd+0B,EAA0B5rB,MAAM,GAAI,GAAE,CACzC,CAACxT,EAAMe,IAAKf,EAAMgB,KAClBo+B,EAA0B,IAG7B,CAEA7gC,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,UACNC,YAAa,CAACw1B,MA9DjB,CAkED,EAAC9+B,EAGD+C,QAAA,SAAQ5C,GAUP,GALIzB,KAAKu+B,kBAAoB,IAAMv+B,KAAKw/B,WACvCx/B,KAAKwD,YAAY/B,GAElBzB,KAAKw/B,WAAY,EAEc,IAA3Bx/B,KAAKu+B,kBAAyB,CACjC,IAAMuC,EAAe9gC,KAAKw+B,gBACvBx+B,KAAKy+B,SAASW,iCAAiC39B,QAC/CwF,EAEC65B,IACHr/B,EAAMe,IAAMs+B,EAAa,GACzBr/B,EAAMgB,IAAMq+B,EAAa,IAG1B,IAAAzI,EAAgBr4B,KAAKqxB,MAAMiH,OAAO,CACjC,CACC5tB,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CAAEuB,KAAMhM,KAAKgM,SAG3BhM,KAAKm5B,UAhBOd,EAgBZ,GACAr4B,KAAKu+B,oBAGLv+B,KAAK0xB,YACN,MAAO,GAA+B,IAA3B1xB,KAAKu+B,mBAA2Bv+B,KAAKm5B,UAAW,CAC1D,IAAM2H,EAAe9gC,KAAKw+B,gBACvBx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,gBACjDlyB,EAEC65B,IACHr/B,EAAMe,IAAMs+B,EAAa,GACzBr/B,EAAMgB,IAAMq+B,EAAa,IAG1B,IAAME,EAAyBhhC,KAAKqxB,MAAMmI,gBACzCx5B,KAAKm5B,WASN,GALoByG,GACnB,CAACn+B,EAAMe,IAAKf,EAAMgB,KAFQu+B,EAAuBp2B,YAAY,GAAG,IAOhE,OAGD5K,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACCo2B,EAAuBp2B,YAAY,GAAG,GACtC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClBu+B,EAAuBp2B,YAAY,GAAG,SAO3C5K,KAAKu+B,mBACN,MAAO,GAA+B,IAA3Bv+B,KAAKu+B,mBAA2Bv+B,KAAKm5B,UAAW,CAC1D,IAAM2H,EAAe9gC,KAAKw+B,gBACvBx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,gBACjDlyB,EAEC65B,IACHr/B,EAAMe,IAAMs+B,EAAa,GACzBr/B,EAAMgB,IAAMq+B,EAAa,IAG1B,IAAMD,EAA4B7gC,KAAKqxB,MAAMmI,gBAC5Cx5B,KAAKm5B,WACJvuB,YAAY,GAQd,GALoBg1B,GACnB,CAACn+B,EAAMe,IAAKf,EAAMgB,KAFQo+B,EAA0B,IAOpD,OAG8B,IAA3B7gC,KAAKu+B,mBACRv+B,KAAK4gC,cAActI,OAAOuI,EAA2B,WAGtD7gC,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKm5B,UACTzuB,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACCi2B,EAA0B,GAC1BA,EAA0B,GAC1B,CAACp/B,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClBo+B,EAA0B,SAO/B7gC,KAAKu+B,mBACN,MAAW,GAAAv+B,KAAKm5B,UAAW,CAC1B,IAAM2H,EAAe9gC,KAAKw+B,gBACvBx+B,KAAKy+B,SAASrB,uBAAuB37B,EAAOzB,KAAKm5B,gBACjDlyB,EAEG45B,EAA4B7gC,KAAKqxB,MAAMmI,gBAC5Cx5B,KAAKm5B,WACJvuB,YAAY,GAEdq2B,EACCjhC,KAAK4gC,cAAcP,eAAe5+B,GAEnC,GAHoCw/B,EAAjBP,mBAAFO,EAATR,UAIPzgC,KAAKg4B,YACC,CAaN,GAZI8I,IACHr/B,EAAMe,IAAMs+B,EAAa,GACzBr/B,EAAMgB,IAAMq+B,EAAa,IAKNlB,GACnB,CAACn+B,EAAMe,IAAKf,EAAMgB,KAFlBo+B,EAA0B7gC,KAAKu+B,kBAAoB,IAOnD,OAGD,IAAM/qB,QC1ZT5I,KAAAA,ED0ZwC,CAAA,GAAAkB,OAEhC+0B,EAA0B5rB,MAAM,GAAI,GACvC,CAAA,CAACxT,EAAMe,IAAKf,EAAMgB,KAClBo+B,EAA0B,SC9Z/Bj2B,EAA4B,CAC3B,CACC,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,GACJ,CAAC,EAAG,MAIC,CACND,KAAM,UACND,SAAU,CACTC,KAAM,UACNC,YAAAA,GAEDH,WAAY,KDkZV,GAAIzK,KAAKu+B,kBAAoB,IAAMv+B,KAAKu/B,wBACVzK,GAAethB,GAI3C,OAKFxT,KAAKqxB,MAAM0H,eAAe,CACzB,CAAEtzB,GAAIzF,KAAKm5B,UAAWzuB,SAAU8I,EAAe9I,YAEhD1K,KAAKu+B,oBAGDv+B,KAAK4gC,cAAcV,IAAIj1B,QAC1BjL,KAAK4gC,cAAcT,OAAO3sB,EAAe9I,SAASE,YAAY,GAEhE,CACD,CCvbI,IACLA,CDubA,EAACtJ,EAGDiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,OAChC73B,KAAKm4B,UACK12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QACvC93B,KAAKg4B,OAEP,EAAC12B,EAGDmD,UAAA,WAAc,EAAAnD,EAGdwC,YAAA,WAGC9D,KAAKyI,UAAU,QAChB,EAACnH,EAGD4C,OAAA,aAAW5C,EAGX8C,UAAA,WAECpE,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD62B,QAAA,WACC,IACKn4B,KAAKm5B,WACRn5B,KAAKqxB,MAAK,OAAQ,CAACrxB,KAAKm5B,YAErBn5B,KAAK4gC,cAAcV,IAAIj1B,QAC1BjL,KAAK4gC,cAAoB,QAE3B,CAAE,MAAOxmB,GAAO,CAChBpa,KAAKm5B,eAAYlyB,EACjBjH,KAAKu+B,kBAAoB,EACN,YAAfv+B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAA,CAAA,EfxeN,CACN/jB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,Ie+dR,GAAI9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,KAAM,CAC1C,GAA8B,YAA1BL,EAAQjB,SAASC,KA0BpB,OAzBAyI,EAAO5F,iBAAmBxN,KAAK0yB,wBAC9B1yB,KAAKoT,OAAO1G,UACZ0G,EAAO5F,iBACP7B,GAGDyH,EAAO/F,oBAAsBrN,KAAK0yB,wBACjC1yB,KAAKoT,OAAOslB,aACZtlB,EAAO/F,oBACP1B,GAGDyH,EAAO9F,oBAAsBtN,KAAK6yB,uBACjC7yB,KAAKoT,OAAOulB,aACZvlB,EAAO9F,oBACP3B,GAGDyH,EAAO7F,mBAAqBvN,KAAK6yB,uBAChC7yB,KAAKoT,OAAOxG,YACZwG,EAAO7F,mBACP5B,GAGDyH,EAAO3E,OAAS,GACT2E,EACD,GAA8B,UAA1BzH,EAAQjB,SAASC,KAyB3B,OAxBAyI,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAO0mB,kBACZ1mB,EAAO3G,WACPd,GAGDyH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAO2mB,kBACZ3mB,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAO4mB,yBACZ5mB,EAAOtG,kBACPnB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAO6mB,yBACZ,EACAtuB,GAEDyH,EAAO3E,OAAS,GACT2E,CAET,CAEA,OAAOA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjC+qB,GAAsBprB,EAAS3L,KAAKqB,oBAKvC,EAACs/B,CAAA,CA1fgC,CAAQ5P,IEhB7BmQ,gBAAuBnO,SAAAA,GAQnC,SAAAmO,EACChtB,GAAgE,IAAAnU,GAEhEA,EAAAgzB,EAAAluB,KAAMqP,KAAAA,IAASnU,MAVhBiM,KAAO,YAAWjM,EACVk0B,YAAMl0B,EAAAA,EACNu3B,WAAa,EAACv3B,EACdohC,wBAAkB,EAAAphC,EAClBy3B,eAASz3B,EAAAA,EACT03B,eAOP,IAAME,EAAiB,CACtBC,MAAO,aAWR,GAPC73B,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAA,CAAA,EAAQoG,EAAmBzjB,EAAQujB,SAEhCE,EAKW,QAAhB,MAAPzjB,OAAO,EAAPA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAAEK,OAAQ,KAAMC,OAAQ,UACnC,CACN,IAAMC,EAAmB,CAAEF,OAAQ,SAAUC,OAAQ,SACrD/3B,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,EAAA,GACpBwG,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAAC,OAAAh4B,CACF,CAlCmC4F,EAAAu7B,EAAAnO,GAkClC,IAAAzxB,EAAA4/B,EAAA3/B,UA8KA,OA9KAD,EAEO8/B,gBAAA,SAAgB3/B,GACvB,GAAwB,IAApBzB,KAAKs3B,YAAoBt3B,KAAKi0B,QAAUj0B,KAAKmhC,mBAAoB,CACpE,IAEME,EAFWrhC,KAAKqxB,MAAMmI,gBAAgBx5B,KAAKmhC,oBAEpBv2B,YAA6B,GAAG,GAE7D5K,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKmhC,mBACTz2B,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACCy2B,EACA,CAAC5/B,EAAMe,IAAK6+B,EAAW,IACvB,CAAC5/B,EAAMe,IAAKf,EAAMgB,KAClB,CAAC4+B,EAAW,GAAI5/B,EAAMgB,KACtB4+B,OAMN,CACD,EAAC//B,EAEO02B,MAAA,WACP,IAAM1F,EAAatyB,KAAKmhC,mBACxBnhC,KAAKi0B,YAAShtB,EACdjH,KAAKmhC,wBAAqBl6B,EAC1BjH,KAAKs3B,WAAa,EAEC,YAAft3B,KAAKi4B,OACRj4B,KAAK2xB,aAGNW,GAActyB,KAAKiyB,SAASK,EAC7B,EAAChxB,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKyI,UAAUzI,KAAKy3B,QAAQG,MAC7B,EAACt2B,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK4xB,aACL5xB,KAAKyI,UAAU,QAChB,EAACnH,EAGD+C,QAAA,SAAQ5C,GACP,GAAwB,IAApBzB,KAAKs3B,WAAkB,CAC1Bt3B,KAAKi0B,OAAS,CAACxyB,EAAMe,IAAKf,EAAMgB,KAChC,IAAA41B,EAAoBr4B,KAAKqxB,MAAMiH,OAAO,CACrC,CACC5tB,SAAU,CACTC,KAAM,UACNC,YAAa,CACZ,CACC,CAACnJ,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,KAClB,CAAChB,EAAMe,IAAKf,EAAMgB,QAIrBgI,WAAY,CACXuB,KAAMhM,KAAKgM,SAIdhM,KAAKmhC,mBAlBW9I,EAkBhB,GACAr4B,KAAKs3B,aACLt3B,KAAK0xB,YACN,MACC1xB,KAAKohC,gBAAgB3/B,GAErBzB,KAAKg4B,OAEP,EAAC12B,EAGDkC,YAAA,SAAY/B,GACXzB,KAAKohC,gBAAgB3/B,EACtB,EAACH,EAGDmD,UAAA,WAAc,EAAAnD,EAGdiD,QAAA,SAAQ9C,GACHA,EAAM6C,MAAQtE,KAAKw3B,UAAUK,OAChC73B,KAAKm4B,UACK12B,EAAM6C,MAAQtE,KAAKw3B,UAAUM,QACvC93B,KAAKg4B,OAEP,EAAC12B,EAGDwC,YAAA,WAAgB,EAAAxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,aAAc9C,EAGd62B,QAAA,WACKn4B,KAAKmhC,oBACRnhC,KAAKqxB,MAAY,OAAC,CAACrxB,KAAKmhC,qBAGzBnhC,KAAKi0B,YAAShtB,EACdjH,KAAKmhC,wBAAqBl6B,EAC1BjH,KAAKs3B,WAAa,EACC,YAAft3B,KAAKi4B,OACRj4B,KAAK2xB,YAEP,EAACrwB,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAQkH,CAAAA,EjBvMd,CACNjrB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IiB8LR,MACkB,YAAjB9C,EAAQhB,MACkB,YAA1BgB,EAAQjB,SAASC,MACjBgB,EAAQlB,WAAWuB,OAAShM,KAAKgM,MAEjCoH,EAAO5F,iBAAmBxN,KAAK0yB,wBAC9B1yB,KAAKoT,OAAO1G,UACZ0G,EAAO5F,iBACP7B,GAGDyH,EAAO/F,oBAAsBrN,KAAK0yB,wBACjC1yB,KAAKoT,OAAOslB,aACZtlB,EAAO/F,oBACP1B,GAGDyH,EAAO9F,oBAAsBtN,KAAK6yB,uBACjC7yB,KAAKoT,OAAOulB,aACZvlB,EAAO9F,oBACP3B,GAGDyH,EAAO7F,mBAAqBvN,KAAK6yB,uBAChC7yB,KAAKoT,OAAOxG,YACZwG,EAAO7F,mBACP5B,GAGMyH,GAGDA,CACR,EAAC9R,EAED4wB,gBAAA,SAAgBvmB,GACf,QAAAonB,EAAAxxB,UAAU2wB,gBAAertB,KAAA7E,KAAC2L,IAExBA,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACjCmrB,GAAqCxrB,EAAS3L,KAAKqB,oBAKtD,EAAC6/B,CAAA,CAhNkCnO,CAAQhC,ICD/BuQ,gBAAoBvO,SAAAA,GAIhC,SAAAuO,EAAYptB,GAAsD,IAAAnU,EAEpC,OAD7BA,EAAAgzB,EAAAluB,KAAA7E,KAAM,CAAEoT,OAAQc,EAAQd,UAAUrT,MAJ5B4K,KAAOohB,GAAUwV,OAAMxhC,EACvBiM,KAAO,SAIbjM,EAAKiM,KAAOkI,EAAQstB,SAASzhC,CAC9B,CAPgC4F,EAAA27B,EAAAvO,GAO/B,IAAAzxB,EAAAggC,EAAA//B,UAmHA,OAnHAD,EAGDkwB,kBAAA,SAAkBC,GAKjBzxB,KAAKgM,KAAOylB,EAAezlB,IAC5B,EAAC1K,EAGDs2B,MAAA,WACC53B,KAAK2xB,YACN,EAACrwB,EAGD42B,KAAA,WACCl4B,KAAK4xB,YACN,EAACtwB,EAGDiD,QAAA,WAAY,EAAAjD,EAGZmD,UAAA,WAAc,EAAAnD,EAGd+C,QAAA,aAAY/C,EAGZwC,YAAA,aAAgBxC,EAGhB4C,OAAA,aAAW5C,EAGX8C,UAAA,WAAc,EAAA9C,EAGdkC,YAAA,WAAgB,EAAAlC,EAGhB62B,QAAA,aAAY72B,EAGZk3B,aAAA,SAAa7sB,GAGZ,MAAO,CACNgB,WAAY3M,KAAK0yB,wBAChB1yB,KAAKoT,OAAOzG,WlBzFF,UkB2FVhB,GAEDc,WAAYzM,KAAK6yB,uBAChB7yB,KAAKoT,OAAO3G,WlB3FF,EkB6FVd,GAEDmB,kBAAmB9M,KAAK0yB,wBACvB1yB,KAAKoT,OAAOtG,kBlBlGK,UkBoGjBnB,GAEDqB,kBAAmBhN,KAAK6yB,uBACvB7yB,KAAKoT,OAAOpG,kBlBtGK,EkBwGjBrB,GAED6B,iBAAkBxN,KAAK0yB,wBACtB1yB,KAAKoT,OAAO5F,iBlBjHI,UkBmHhB7B,GAED4B,mBAAoBvN,KAAK6yB,uBACxB7yB,KAAKoT,OAAO7F,mBlBnHM,GkBqHlB5B,GAED0B,oBAAqBrN,KAAK0yB,wBACzB1yB,KAAKoT,OAAO/F,oBlB1HO,UkB4HnB1B,GAED2B,oBAAqBtN,KAAK6yB,uBACzB7yB,KAAKoT,OAAO9F,oBlB9HO,EkBgInB3B,GAEDyB,gBAAiBpN,KAAK6yB,uBACrB7yB,KAAKoT,OAAOhG,gBlB5HG,EkB8HfzB,GAEDwB,gBAAiBnN,KAAK0yB,wBACrB1yB,KAAKoT,OAAOjG,gBlBlIG,UkBoIfxB,GAED8C,OAAQzO,KAAK6yB,uBACZ7yB,KAAKoT,OAAO3E,OlBrIN,EkBuIN9C,GAGH,EAACrK,EAED4wB,gBAAA,SAAgBvmB,GACf,OACConB,EAAAxxB,UAAM2wB,gBAAertB,KAAC8G,KAAAA,KACrB+zB,GAAa/zB,EAAS3L,KAAKqB,sBAC3B01B,GAAsBprB,EAAS3L,KAAKqB,+BC1JvCsK,EACAtK,GAEA,MAC2B,eAA1BsK,EAAQjB,SAASC,MACjBgB,EAAQjB,SAASE,YAAYK,QAAU,GACvCU,EAAQjB,SAASE,YAAYosB,MAAM,SAAC9rB,GAAU,OAC7CyrB,GAAkBzrB,EAAY7J,EAAoB,EAGrD,CDiJIogC,CAAyB91B,EAAS3L,KAAKqB,qBAE1C,EAACigC,CAAA,CA1H+BvO,CAAQhC,aEnCzB2Q,GACfC,EACAC,EACA9K,EACA1uB,EACAI,GAEA,IAAMq5B,EAAyBz5B,EAAQu5B,EAAa,GAAIA,EAAa,IAC/DG,EAAyB15B,EAAQw5B,EAAa,GAAIA,EAAa,IAErEG,EAAqBv5B,GACnBq5B,EAAuBliC,EAAImiC,EAAuBniC,GAAK,GACvDkiC,EAAuBniC,EAAIoiC,EAAuBpiC,GAAK,GAF5C+C,EAAGs/B,EAAHt/B,IAKb,MAAO,CAACzD,EALG+iC,EAAHv/B,IAKoBs0B,GAAY93B,EAAeyD,EAAKq0B,GAC7D,CCfM,SAAUkL,GACfC,EACAnL,EACA1uB,EACAI,GAGA,IADA,IAAM05B,EAA6B,GAC1Bl3B,EAAI,EAAGA,EAAIi3B,EAAch3B,OAAS,EAAGD,IAAK,CAClD,IAAMm3B,EAAMT,GACXO,EAAcj3B,GACdi3B,EAAcj3B,EAAI,GAClB8rB,EACA1uB,EACAI,GAED05B,EAAe/2B,KAAKg3B,EACrB,CACA,OAAOD,CACR,CCba,IAAAE,gBAAiB,SAAAlF,GAC7B,SAAAkF,EACU7hC,EACQ8hC,GAA8CtiC,IAAAA,EAAA,OAE/DA,EAAAm9B,EAAAr4B,KAAMtE,KAAAA,IAAOP,MAHJO,YAAA,EAAAR,EACQsiC,4BAAA,EAAAtiC,EAKVuiC,WAAuB,GANrBviC,EAAMQ,OAANA,EACQR,EAAsBsiC,uBAAtBA,EAA8CtiC,CAGhE,CAN6B4F,EAAAy8B,EAAAlF,GAM5B,IAAA57B,EAAA8gC,EAAA7gC,UAQsB,OARtBD,EAUMihC,OAAA,SAAOC,EAAoBnhC,GACjC,IAAMohC,EAAWziC,KAAKqxB,MAAMmI,gBAAgBgJ,GAC5CE,EACC1iC,KAAKqxB,MAAMsR,kBAAkBH,GADtBI,EAAiBF,EAAjBE,kBAAmBC,EAAeH,EAAfG,gBAErBn4B,EAAW1K,KAAKqxB,MAAMmI,gBAC3BoJ,GAIKxC,EACa,YAAlB11B,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAEbw1B,EAAmBhkB,OACjBymB,EAA6B,EAC9B,EACAJ,EAAS73B,aAKVF,EAASE,YACU,YAAlBF,EAASC,KAAqB,CAACy1B,GAAsBA,EAItDpgC,KAAKqxB,MAAM0H,eAAe,CAAC,CAAEtzB,GAAIm9B,EAA6Bl4B,SAAAA,KAM9D1K,KAAKqxB,MAAK,OAAOvlB,GAAAA,OAAK9L,KAAKsiC,WAAetiC,KAAKqiC,uBAAuBnC,MAItElgC,KAAKs4B,OACJ8H,EACAwC,EACAvhC,GAEDrB,KAAKqiC,uBAAuB/J,OAC3B8H,EACA11B,EAASC,KACTi4B,EAEF,EAACthC,EAEMg3B,OAAA,SACNyH,EACA+C,EACAzhC,GAA2B4E,IAAAA,EAE3BjG,KAAA,IAAKA,KAAKqxB,MAAMzjB,IAAIk1B,GACnB,MAAU,IAAAp9B,MAAM,4CAGjB1F,KAAKsiC,WAAatiC,KAAKqxB,MAAMiH,OD3Df,SACfyH,EACAt1B,EACAqsB,EACA1uB,EACAI,GAEA,OAAOw5B,GACNjC,EACAjJ,EACA1uB,EACAI,GACCjD,IAAI,SAACwvB,EAAO/pB,GAAC,MAAM,CACpBN,SAAU,CAAEC,KAAM,QAASC,YAAamqB,GACxCtqB,WAAYA,EAAWO,GACvB,EACF,CC4CG+3B,CACChD,EACA,SAAC/0B,GAAC,IAAAlL,EAAA,OAAAA,EAAA,CACDkM,KAAM/F,EAAK+F,OACVukB,KAA8B,EAAIzwB,EACnC+iC,gBAAiB73B,EAAClL,EAClB8iC,kBAAmBE,EAAShjC,CAAA,EAE7BuB,EACArB,KAAKO,OAAO6H,QACZpI,KAAKO,OAAOiI,WAGf,EAAClH,EAAA,OAEM,WACFtB,KAAKsiC,WAAWr3B,SACnBjL,KAAKqxB,MAAK,OAAQrxB,KAAKsiC,YACvBtiC,KAAKsiC,WAAa,GAEpB,EAAChhC,EAEM0hC,WAAA,SAAW5C,GAA8Bz2B,IAAAA,EAC/C3J,KAAA,GAA+B,IAA3BA,KAAKsiC,WAAWr3B,OAIpB,OAAO+2B,GACN5B,EACApgC,KAAKqB,oBACLrB,KAAKO,OAAO6H,QACZpI,KAAKO,OAAOiI,WACXjD,IAAI,SAAC09B,EAAsBj4B,GAAO,MAAA,CACnCvF,GAAIkE,EAAK24B,WAAWt3B,GACpBN,SAAU,CACTC,KAAM,QACNC,YAAaq4B,GAEd,EACF,EAACn1B,EAAAs0B,EAAA99B,CAAAA,CAAAA,IAAAyJ,MAAAA,IAxGD,WACC,OAAW/N,KAACsiC,WAAWx2B,QACxB,EAAC4S,IAED,SAAQ2O,GAAW,KAAI+U,CAAA,CAdM,CAAQpF,ICLzBkG,gBAAuBhG,SAAAA,GACnC,SAAAgG,EAAY3iC,GAAsBR,IAAAA,EAIQA,OAHzCA,EAAAm9B,EAAAr4B,KAAA7E,KAAMO,IAAOP,MAGNmjC,iBAAgC,GAAEpjC,CAF1C,CAHmC4F,EAAAu9B,EAAAhG,GAGlC,IAAA57B,EAAA4hC,EAAA3hC,UAQyB2hC,OARzB5hC,EAUMg3B,OAAA,SACNyH,EACAp1B,EACAm4B,OAAoB78B,EAAAjG,KAEdojC,EAAcpjC,KAAKqxB,MAAMsR,kBAAkBG,GACjD9iC,KAAKmjC,iBAAmBnjC,KAAKqxB,MAAMiH,gBCpBpCyH,EACAsD,EACA54B,GAWA,IATA,IAAM64B,EAAkB,GAIlBr4B,EACY,YAAjBo4B,EACGtD,EAAe90B,OAAS,EACxB80B,EAAe90B,OAEVD,EAAI,EAAGA,EAAIC,EAAQD,IAC3Bs4B,EAAgBn4B,KAAK,CACpBT,SAAU,CACTC,KAAM,QACNC,YAAam1B,EAAe/0B,IAE7BP,WAAYA,EAAWO,KAIzB,OAAOs4B,CACR,CDHGC,CAAuBxD,EAAgBp1B,EAAM,SAACK,SAAO,CACpDgB,KAAM/F,EAAK+F,KACXw3B,gBAAgB,EAChB74B,KAA2B,WAArBy4B,EAAYp3B,KAAoB,SAAW,QACjDy3B,wBAAyBX,EACzB5mB,MAAOlR,EACP,GAEH,EAAC1J,EAEM,OAAA,WACFtB,KAAKkgC,IAAIj1B,SACZjL,KAAKqxB,MAAK,OAAQrxB,KAAKkgC,KACvBlgC,KAAKmjC,iBAAmB,GAE1B,EAAC7hC,EAEM0hC,WAAA,SAAW5C,GACjB,GAAqC,IAAjCpgC,KAAKmjC,iBAAiBl4B,OAI1B,OAAOjL,KAAKmjC,iBAAiB59B,IAAI,SAACE,EAAIuF,GACrC,MAAO,CACNvF,GAAAA,EACAiF,SAAU,CACTC,KAAM,QACNC,YAAaw1B,EAAmBp1B,IAGnC,EACD,EAAC1J,EAEMoiC,cAAA,SAAcxnB,EAAeynB,GACnC,QAAqC18B,IAAjCjH,KAAKmjC,iBAAiBjnB,GAI1B,MAAO,CACNzW,GAAIzF,KAAKmjC,iBAAiBjnB,GAC1BxR,SAAU,CACTC,KAAM,QACNC,YAAa+4B,GAGhB,EAAC71B,EAAAo1B,EAAA5+B,CAAAA,CAAAA,IAAAyJ,MAAAA,IA1DD,WACC,OAAW/N,KAACmjC,iBAAiBr3B,QAC9B,EAAC4S,IAED,SAAQ2O,GAAc,KAAI6V,CAAA,CAXShG,CAAQF,aEC5B4G,GAAev7B,EAAiB2nB,GAE/C,IADA,IAYqB6T,EAAaC,EAAcC,EAZ5CC,GAAS,EACJh5B,EAAI,EAAGqS,EAAM2S,EAAM/kB,OAAQD,EAAIqS,EAAKrS,IAE5C,IADA,IAAMi5B,EAAOjU,EAAMhlB,GACVM,EAAI,EAAG44B,EAAOD,EAAKh5B,OAAQwW,EAAIyiB,EAAO,EAAG54B,EAAI44B,EAAMziB,EAAInW,KAS/Bw4B,EARRG,EAAK34B,IAU3B,IAFiBu4B,EARFx7B,GAUR,KAFqC07B,EARbE,EAAKxiB,IAUnB,GAAKoiB,EAAE,IAC3BA,EAAE,IAAOE,EAAG,GAAKD,EAAG,KAAOD,EAAE,GAAKC,EAAG,KAAQC,EAAG,GAAKD,EAAG,IAAMA,EAAG,KAV/DE,GAAUA,GAIb,OAAOA,CACR,CCjBO,IAAMG,GAAsB,SAClC97B,EACA+7B,EACAC,GAEA,IAAMC,EAAS,SAAC3kC,GACf,OAAOA,EAAIA,CACZ,EACM4kC,EAAQ,SAACC,EAA6B5J,GAC3C,OAAO0J,EAAOE,EAAE7kC,EAAIi7B,EAAEj7B,GAAK2kC,EAAOE,EAAE9kC,EAAIk7B,EAAEl7B,EAC3C,EAkBA,OAAON,KAAKQ,KAjBiB,SAC5BikC,EACAW,EACA5J,GAEA,IAAM6J,EAAKF,EAAMC,EAAG5J,GAEpB,GAAW,IAAP6J,EACH,OAAOF,EAAMV,EAAGW,GAGjB,IAAIE,IAAMb,EAAElkC,EAAI6kC,EAAE7kC,IAAMi7B,EAAEj7B,EAAI6kC,EAAE7kC,IAAMkkC,EAAEnkC,EAAI8kC,EAAE9kC,IAAMk7B,EAAEl7B,EAAI8kC,EAAE9kC,IAAM+kC,EAGlE,OAFAC,EAAItlC,KAAK6X,IAAI,EAAG7X,KAAK4X,IAAI,EAAG0tB,IAErBH,EAAMV,EAAG,CAAElkC,EAAG6kC,EAAE7kC,EAAI+kC,GAAK9J,EAAEj7B,EAAI6kC,EAAE7kC,GAAID,EAAG8kC,EAAE9kC,EAAIglC,GAAK9J,EAAEl7B,EAAI8kC,EAAE9kC,IACnE,CAEiBilC,CAAqBt8B,EAAO+7B,EAAcC,GAC5D,ECnBaO,gBAA8B1H,SAAAA,GAC1C,SAAA0H,EACUrkC,EACQskC,EACAtlC,GAAoCQ,IAAAA,EAAA,OAErDA,EAAAm9B,EAAAr4B,KAAMtE,KAAAA,IAAOP,MAJJO,YAAA,EAAAR,EACQ8kC,4BAAA,EAAA9kC,EACAR,mBAFRQ,EAAAA,EAAMQ,OAANA,EACQR,EAAsB8kC,uBAAtBA,EACA9kC,EAAaR,cAAbA,EAAoCQ,CAGtD,CAiFC,OAxFyC4F,EAAAi/B,EAAA1H,GAOzC0H,EAAArjC,UAEMmF,KAAA,SAAKjF,EAA4BqjC,GASvC,IARA,IAAIC,OAAmD99B,EACnD+9B,EAAyBhkB,SACzBikB,OAAoDh+B,EACpDi+B,EAA0BlkB,SAExBwc,EAAOx9B,KAAK6kC,uBAAuBvM,OAAO72B,GAC1CoK,EAAW7L,KAAKqxB,MAAMoM,OAAOD,GAE1BxyB,EAAI,EAAGA,EAAIa,EAASZ,OAAQD,IAAK,CACzC,IAAMW,EAAUE,EAASb,GACnBN,EAAWiB,EAAQjB,SAEzB,GAAsB,UAAlBA,EAASC,KAAkB,CAO9B,GAJyBgB,EAAQlB,WAAW+4B,iBAE1CsB,GAAgBn5B,EAAQlB,WAAW8lB,IAGpC,SAGD,IAAM8D,EAAWr0B,KAAKT,cAAcs+B,QACnCp8B,EACAiJ,EAASE,aAOTe,EAAQlB,WAAW8lB,KACnB8D,EAAWr0B,KAAKmxB,iBAChBkD,EAAW6Q,GAEXA,EAA0B7Q,EAC1B4Q,EAAkBt5B,IAEjBA,EAAQlB,WAAW8lB,KACpB8D,EAAWr0B,KAAKmxB,iBAChBkD,EAAW2Q,IAEXA,EAAyB3Q,EACzB0Q,EAAiBp5B,EAEnB,SAA6B,eAAlBjB,EAASC,KACnB,IAAK,IAAIK,EAAI,EAAGA,EAAIN,EAASE,YAAYK,OAAS,EAAGD,IAAK,CACzD,IAAM+pB,EAAQrqB,EAASE,YAAYI,GAC7Bm6B,EAAYz6B,EAASE,YAAYI,EAAI,GACrCo6B,EAAiBjB,GACtB,CAAExkC,EAAG8B,EAAMM,WAAYrC,EAAG+B,EAAMS,YAChClC,KAAKoI,QAAQ2sB,EAAM,GAAIA,EAAM,IAC7B/0B,KAAKoI,QAAQ+8B,EAAU,GAAIA,EAAU,KAIrCC,EAAiBplC,KAAKmxB,iBACtBiU,EAAiBJ,IAEjBA,EAAyBI,EACzBL,EAAiBp5B,EAEnB,KAC4B,YAAlBjB,EAASC,MACQi5B,GAC1B,CAACniC,EAAMe,IAAKf,EAAMgB,KAClBiI,EAASE,eAITo6B,EAAyB,EACzBD,EAAiBp5B,EAGpB,CAEA,MAAO,CAAEo5B,eAAAA,EAAgBE,gBAAAA,EAC1B,EAACL,CAAA,CAxFyC1H,CAAQF,ICDtCqI,gBAAoBnI,SAAAA,GAChC,SAAAmI,EACU9kC,EACQ+kC,EACAhC,EACAiC,GAA2BxlC,IAAAA,EAAA,OAE5CA,EAAAm9B,EAAAr4B,UAAMtE,IAAQR,MALLQ,YAAA,EAAAR,EACQulC,4BAAAvlC,EACAujC,qBAAA,EAAAvjC,EACAwlC,iBAAAxlC,EAKVylC,iBAAqC,KAAIzlC,EAEzC0lC,kBAAY,EAVV1lC,EAAMQ,OAANA,EACQR,EAAoBulC,qBAApBA,EACAvlC,EAAeujC,gBAAfA,EACAvjC,EAASwlC,UAATA,EAA2BxlC,CAG7C,CARgC4F,EAAA0/B,EAAAnI,GAQ/B,IAAA57B,EAAA+jC,EAAA9jC,UAsJA8jC,OAtJA/jC,EAMDokC,cAAA,SAAcjkC,EAA4BgE,GACzCzF,KAAKwlC,iBAAmB//B,EACxBzF,KAAKylC,aAAe,CAAChkC,EAAMe,IAAKf,EAAMgB,IACvC,EAACnB,EAEDqkC,aAAA,WACC3lC,KAAKwlC,iBAAmB,KACxBxlC,KAAKylC,kBAAex+B,CACrB,EAAC3F,EAEDskC,WAAA,WACC,OAAiC,YAArBJ,gBACb,EAAClkC,EAEDukC,QAAA,SAAQpkC,EAA4B+wB,GACnC,IAAQuS,EAAmB/kC,KAAKslC,qBAAqB5+B,KAAKjF,GAAO,GAAzDsjC,eAIR,SAAKA,GAAkBA,EAAet/B,KAAO+sB,EAK9C,EAAClxB,EAEDwkC,KAAA,SAAKrkC,EAA4BywB,GAChC,GAAKlyB,KAAKwlC,iBAAV,CAIA,IAAM96B,EAAW1K,KAAKqxB,MAAMmI,gBAAgBx5B,KAAKwlC,kBAC3CO,EAAa,CAACtkC,EAAMe,IAAKf,EAAMgB,KAGrC,GAAsB,YAAlBiI,EAASC,MAAwC,eAAlBD,EAASC,KAAuB,CAClE,IAAIq7B,EACAC,EAWJ,GAPCA,EAFqB,YAAlBv7B,EAASC,MACZq7B,EAAgBt7B,EAASE,YAAY,IACXK,OAAS,GAGnC+6B,EAAgBt7B,EAASE,aACCK,QAGtBjL,KAAKylC,aACT,SAGD,IAAK,IAAIz6B,EAAI,EAAGA,EAAIi7B,EAAWj7B,IAAK,CACnC,IAAME,EAAa86B,EAAch7B,GAC3BqwB,EAAQ,CACbr7B,KAAKylC,aAAa,GAAKM,EAAW,GAClC/lC,KAAKylC,aAAa,GAAKM,EAAW,IAI7BG,EAAalnC,EAClBkM,EAAW,GAAKmwB,EAAM,GACtBr7B,KAAKO,OAAOc,qBAGP8kC,EAAannC,EAClBkM,EAAW,GAAKmwB,EAAM,GACtBr7B,KAAKO,OAAOc,qBAMb,GACC6kC,EAAa,KACbA,GAAc,KACdC,EAAa,IACbA,GAAc,GAEd,OAAO,EAGRH,EAAch7B,GAAK,CAACk7B,EAAYC,EACjC,CAIsB,YAAlBz7B,EAASC,OACZq7B,EAAcA,EAAc/6B,OAAS,GAAK,CACzC+6B,EAAc,GAAG,GACjBA,EAAc,GAAG,KAInB,IAAMI,EACLpmC,KAAKsjC,gBAAgBN,WAAWgD,IAAkB,GAE7CK,EAAmBrmC,KAAKulC,UAAUvC,WAAWgD,IAAkB,GAErE,GAAI9T,IACWA,EACb,CACCvnB,KAAM,UACNlF,GAAIzF,KAAKwlC,iBACT96B,SAAAA,EACAD,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,sBAKlC,OAAO,EAKTrB,KAAKqxB,MAAM0H,eAAc,CACxB,CAAEtzB,GAAIzF,KAAKwlC,iBAAkB96B,SAAAA,IAAUoB,OACpCs6B,EACAC,IAGJrmC,KAAKylC,aAAe,CAAChkC,EAAMe,IAAKf,EAAMgB,IAGvC,KAA6B,UAAlBiI,EAASC,OAGnB3K,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIzF,KAAKwlC,iBACT96B,SAAU,CACTC,KAAM,QACNC,YAAam7B,MAKhB/lC,KAAKylC,aAAe,CAAChkC,EAAMe,IAAKf,EAAMgB,KAjHvC,CAmHD,EAAC4iC,CAAA,CA9J+BnI,CAAQF,ICC5BsJ,gBAAuB,SAAApJ,GACnC,SAAAoJ,EACU/lC,EACQhB,EACA+jC,EACAiC,OAA2BxlC,EAAA,OAE5CA,EAAAm9B,EAAAr4B,KAAA7E,KAAMO,IAAOP,MALJO,cAAAR,EACQR,mBAAAQ,EAAAA,EACAujC,qBAAA,EAAAvjC,EACAwlC,iBAAAxlC,EAKVwmC,kBAA6D,CACpE9gC,GAAI,KACJyW,OAAQ,GAVCnc,EAAMQ,OAANA,EACQR,EAAaR,cAAbA,EACAQ,EAAeujC,gBAAfA,EACAvjC,EAASwlC,UAATA,EAA2BxlC,CAG7C,CARmC4F,EAAA2gC,EAAApJ,GAQlC,IAAA57B,EAAAglC,EAAA/kC,UA6LA,OA7LAD,EAOOklC,qBAAA,SACP/kC,EACAiJ,GAEA,IAMI+7B,EANEC,EAAoB,CACzB9I,KAAM5c,SACN9E,OAAQ,EACRyqB,2BAA2B,GAK5B,GAAsB,eAAlBj8B,EAASC,KACZ87B,EAAkB/7B,EAASE,oBACC,YAAlBF,EAASC,KAKnB,OAAO+7B,EAJPD,EAAkB/7B,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAII,EAAI,EAAGA,EAAIy7B,EAAgBx7B,OAAQD,IAAK,CAChD,IACMqpB,EAAWr0B,KAAKT,cAAcs+B,QAAQp8B,EAD9BglC,EAAgBz7B,IAG9B,GACCqpB,EAAWr0B,KAAKmxB,iBAChBkD,EAAWqS,EAAkB9I,KAC5B,CAID,IAAM+I,EACa,YAAlBj8B,EAASC,OACRK,IAAMy7B,EAAgBx7B,OAAS,GAAW,IAAND,GAEtC07B,EAAkB9I,KAAOvJ,EACzBqS,EAAkBxqB,MAAQyqB,EAA4B,EAAI37B,EAC1D07B,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACplC,EAEMslC,kBAAA,SACNnlC,EACA+wB,GAEA,IAAM9nB,EAAW1K,KAAKqxB,MAAMmI,gBAAgBhH,GACtCkU,EAAoB1mC,KAAKwmC,qBAAqB/kC,EAAOiJ,GAG3D,OAAiC,IAA7Bg8B,EAAkBxqB,OACb,EAEFwqB,EAAkBxqB,KAC1B,EAAC5a,EAEMwkC,KAAA,SACNrkC,EACAolC,EACA3U,GAEA,IAAKlyB,KAAKumC,kBAAkB9gC,GAC3B,OAAO,EAER,IAAMyW,EAAQlc,KAAKumC,kBAAkBrqB,MAC/BxR,EAAW1K,KAAKqxB,MAAMmI,gBAAgBx5B,KAAKumC,kBAAkB9gC,IAE7DghC,EACa,eAAlB/7B,EAASC,KACND,EAASE,YACTF,EAASE,YAAY,GAQnB+4B,EAAoB,CAACliC,EAAMe,IAAKf,EAAMgB,KAK5C,GACChB,EAAMe,IAAM,KACZf,EAAMe,KAAO,KACbf,EAAMgB,IAAM,IACZhB,EAAMgB,KAAO,GAEb,SAKD,GApBmB,YAAlBiI,EAASC,MACRuR,IAAUuqB,EAAgBx7B,OAAS,GAAe,IAAViR,EAwBzCuqB,EAAgBvqB,GAASynB,MALK,CAC9B,IAAMmD,EAAiBL,EAAgBx7B,OAAS,EAChDw7B,EAAgB,GAAK9C,EACrB8C,EAAgBK,GAAkBnD,CACnC,CAIA,IAAMoD,EAAwB/mC,KAAKsjC,gBAAgBI,cAClDxnB,EACAynB,GAGKyC,EAAyBW,EAC5B,CAACA,GACD,GAEGV,EAAmBrmC,KAAKulC,UAAUvC,WAAWyD,IAAoB,GAEvE,QACmB,UAAlB/7B,EAASC,OACRk8B,GACD/R,GAAe,CACdnqB,KAAM,UACND,SAAUA,EACVD,WAAY,CACQ,KAKlBynB,IACWA,EACb,CACCvnB,KAAM,UACNlF,GAAIzF,KAAKumC,kBAAkB9gC,GAC3BiF,SAAAA,EACAD,WAAY,IAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,wBAUpCrB,KAAKqxB,MAAM0H,eAEV,CAAA,CACCtzB,GAAIzF,KAAKumC,kBAAkB9gC,GAC3BiF,SAAUA,IACVoB,OAEEs6B,EACAC,IAIL,GAAA,EAAC/kC,EAEDskC,WAAA,WACC,OAAqC,OAA1B5lC,KAACumC,kBAAkB9gC,EAC/B,EAACnE,EAEDokC,cAAA,SAAcjgC,EAAeyW,GAC5Blc,KAAKumC,kBAAoB,CACxB9gC,GAAAA,EACAyW,MAAAA,EAEF,EAAC5a,EAEDqkC,aAAA,WACC3lC,KAAKumC,kBAAoB,CACxB9gC,GAAI,KACJyW,OAAQ,EAEV,EAACoqB,CAAA,CArMkC,CAAQtJ,ICNtC,SAAUgK,GAASC,GACxB,IAAIC,EAAO,EACPC,EAAO,EACP9pB,EAAM,EAaV,OAV2B,YAA1B4pB,EAAQv8B,SAASC,KACds8B,EAAQv8B,SAASE,YAAY,GAAGqK,MAAM,GAAI,GAC1CgyB,EAAQv8B,SAASE,aAET5H,QAAQ,SAAC+xB,GACpBmS,GAAQnS,EAAM,GACdoS,GAAQpS,EAAM,GACd1X,GACD,GAAG,GAEI,CAAC6pB,EAAO7pB,EAAK8pB,EAAO9pB,EAC5B,CCfgB,SAAA+pB,GAAaxP,EAAiB+C,GAC7C,IAAM93B,EAAO+0B,EACPyP,EAAK1M,EAML2M,EAAOxT,GAAiBjxB,EAAK,IAC7B0kC,EAAOzT,GAAiBuT,EAAG,IAC7BG,EAAc1T,GAAiBuT,EAAG,GAAKxkC,EAAK,IAG5C2kC,EAAcpoC,KAAKiiB,KACtBmmB,GAAe,EAAIpoC,KAAKiiB,IAErBmmB,GAAepoC,KAAKiiB,KACvBmmB,GAAe,EAAIpoC,KAAKiiB,IAGzB,IAAMomB,EAAWroC,KAAKgqB,IACrBhqB,KAAKiqB,IAAIke,EAAO,EAAInoC,KAAKiiB,GAAK,GAAKjiB,KAAKiqB,IAAIie,EAAO,EAAIloC,KAAKiiB,GAAK,IAK5DqmB,GAAW3T,GAFH30B,KAAKw0B,MAAM4T,EAAaC,IAEK,KAAO,IAIlD,OAFgBC,EAAU,MAAQ,IAAMA,GAAWA,CAGpD,CC/BgB,SAAAC,GACfnT,EACAoT,EACAtT,GAEA,IACIuT,EAAmBD,EADKA,EAAiB,IAI5CC,GAAoBzoC,KAAK68B,IAAI4L,IAG9B,IAAMxM,EAAQwM,EAAmBhU,GAC3BiU,EAAWtT,EAAO,GAAKp1B,KAAKiiB,GAAM,IAClCimB,EAAOxT,GAAiBU,EAAO,IAC/BuT,EAAQjU,GAAiBQ,GAEzB0T,EAAW3M,EAAQj8B,KAAKokB,IAAIukB,GAC9BR,EAAOD,EAAOU,EAGd5oC,KAAK68B,IAAIsL,GAAQnoC,KAAKiiB,GAAK,IAC9BkmB,EAAOA,EAAO,EAAInoC,KAAKiiB,GAAKkmB,GAAQnoC,KAAKiiB,GAAKkmB,GAG/C,IAAMU,EAAW7oC,KAAKgqB,IACrBhqB,KAAKiqB,IAAIke,EAAO,EAAInoC,KAAKiiB,GAAK,GAAKjiB,KAAKiqB,IAAIie,EAAO,EAAIloC,KAAKiiB,GAAK,IAG5D6mB,EAAI9oC,KAAK68B,IAAIgM,GAAY,MAASD,EAAWC,EAAW7oC,KAAKokB,IAAI8jB,GAMjExd,EAAc,EACN,KAJEge,EADKzM,EAAQj8B,KAAKkiB,IAAIymB,GAAUG,GAK3B9oC,KAAKiiB,GAAK,KAAO,IAAO,IACpC,IAAPkmB,EAAcnoC,KAAKiiB,IAWrB,OANAyI,EAAY,IACXA,EAAY,GAAK0K,EAAO,GAAK,KACzB,IACDA,EAAO,GAAK1K,EAAY,GAAK,IAC7B,IACA,EACGA,CACR,UCjDgBqe,GAAcre,EAAuB0K,GAGpD1K,EAAY,IACXA,EAAY,GAAK0K,EAAO,GAAK,KACzB,IACDA,EAAO,GAAK1K,EAAY,GAAK,IAC7B,IACA,EAIJ,IAAMse,EAAIvU,GACJyT,EAAQ9S,EAAO,GAAKp1B,KAAKiiB,GAAM,IAC/BkmB,EAAQzd,EAAY,GAAK1qB,KAAKiiB,GAAM,IACpC2mB,EAAWT,EAAOD,EACpBe,EAAejpC,KAAK68B,IAAInS,EAAY,GAAK0K,EAAO,IAAMp1B,KAAKiiB,GAAM,IAGjEgnB,EAAcjpC,KAAKiiB,KACtBgnB,GAAe,EAAIjpC,KAAKiiB,IAKzB,IAAM4mB,EAAW7oC,KAAKgqB,IACrBhqB,KAAKiqB,IAAIke,EAAO,EAAInoC,KAAKiiB,GAAK,GAAKjiB,KAAKiqB,IAAIie,EAAO,EAAIloC,KAAKiiB,GAAK,IAE5D6mB,EAAI9oC,KAAK68B,IAAIgM,GAAY,MAASD,EAAWC,EAAW7oC,KAAKokB,IAAI8jB,GASvE,OANcloC,KAAKQ,KAClBooC,EAAWA,EAAWE,EAAIA,EAAIG,EAAcA,GAGdD,CAGhC,CCjCA,IAAaE,gBAAsB,SAAApL,GAClC,SAAAoL,EACU/nC,EACQ+iC,EACAiC,GAA2BxlC,IAAAA,EAAA,OAE5CA,EAAAm9B,EAAAr4B,KAAA7E,KAAMO,IAAOP,MAJJO,YAAA,EAAAR,EACQujC,qBAAAvjC,EAAAA,EACAwlC,iBAAAxlC,EAKVwoC,iBAAW,EAPTxoC,EAAMQ,OAANA,EACQR,EAAeujC,gBAAfA,EACAvjC,EAASwlC,UAATA,EAA2BxlC,CAG7C,CAPkC4F,EAAA2iC,EAAApL,GAOjC,IAAA57B,EAAAgnC,EAAA/mC,UAoFA,OApFAD,EAIDknC,MAAA,WACCxoC,KAAKuoC,iBAActhC,CACpB,EAAC3F,EAEDmnC,OAAA,SACChnC,EACA+wB,EACAN,GAA4BjsB,IAAAA,OAEtByE,EAAW1K,KAAKqxB,MAAMmI,gBAC3BhH,GAID,GAAsB,YAAlB9nB,EAASC,MAAwC,eAAlBD,EAASC,KAA5C,CAIA,IAAMo7B,EAAa,CAACtkC,EAAMe,IAAKf,EAAMgB,KAE/B6xB,EAAU8S,GACfJ,GAAS,CAAEr8B,KAAM,UAAWD,SAAAA,EAAUD,WAAY,CAAA,IAClDs7B,GAID,GAAK/lC,KAAKuoC,YAAV,ECxCc,SACftB,EACAtnB,GAGA,GAAc,IAAVA,EACH,OAAOsnB,EAIR,IAAMyB,EAAQ1B,GAASC,IAGI,YAA1BA,EAAQv8B,SAASC,KACds8B,EAAQv8B,SAASE,YAAY,GAC7Bq8B,EAAQv8B,SAASE,aAER5H,QAAQ,SAAC2lC,GACrB,IACMC,EADexB,GAAasB,EAAOC,GACPhpB,EAC5B0U,EAAW8T,GAAcO,EAAOC,GAChCE,EAAYlB,GAAiBe,EAAOrU,EAAUuU,GACpDD,EAAY,GAAKE,EAAU,GAC3BF,EAAY,GAAKE,EAAU,EAC5B,EAGD,CDoBEC,CAAgB,CAAEn+B,KAAM,UAAWD,SAAAA,EAAUD,WAAY,MAF3CzK,KAAKuoC,aAAejU,EAAU,OAK5C,IAAM0R,EACa,YAAlBt7B,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAGbo7B,EAAchjC,QAAQ,SAACkI,GACtBA,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,oBACpD,GAEA,IAAMglC,EAAmBrmC,KAAKulC,UAAUvC,WAAWgD,IAAkB,GAE/DI,EACLpmC,KAAKsjC,gBAAgBN,WAAWgD,IAAkB,GAEnD,GAAI9T,IAEDA,EACA,CACCzsB,GAAI+sB,EACJ7nB,KAAM,UACND,SAAAA,EACAD,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,sBAInC,OAAO,EAKTrB,KAAKqxB,MAAM0H,eACV,CAAA,CAAEtzB,GAAI+sB,EAAY9nB,SAAAA,IAAUoB,OACzBs6B,EACAC,IAGJrmC,KAAKuoC,YAAcjU,EAAU,GAlD7B,MAFCt0B,KAAKuoC,YAAcjU,EAAU,GAX9B,CAgED,EAACgU,CAAA,CA3FiC,CAAQtL,IEA9B+L,gBAAqB7L,SAAAA,GACjC,SAAA6L,EACUxoC,EACQ+iC,EACAiC,GAA2B,IAAAxlC,EAAA,OAE5CA,EAAAm9B,EAAAr4B,KAAA7E,KAAMO,UAJGA,YAAA,EAAAR,EACQujC,qBAAAvjC,EAAAA,EACAwlC,eAAAxlC,EAAAA,EAKVipC,kBAAY,EAPVjpC,EAAMQ,OAANA,EACQR,EAAeujC,gBAAfA,EACAvjC,EAASwlC,UAATA,EAA2BxlC,CAG7C,CAPiC4F,EAAAojC,EAAA7L,GAOhC,IAAA57B,EAAAynC,EAAAxnC,UAwFA,OAxFAD,EAIDknC,MAAA,WACCxoC,KAAKgpC,kBAAe/hC,CACrB,EAAC3F,EAED4L,MAAA,SACCzL,EACA+wB,EACAN,GAA4BjsB,IAAAA,EAE5BjG,KAAM0K,EAAW1K,KAAKqxB,MAAMmI,gBAC3BhH,GAID,GAAsB,YAAlB9nB,EAASC,MAAwC,eAAlBD,EAASC,KAA5C,CAIA,IAAMo7B,EAAa,CAACtkC,EAAMe,IAAKf,EAAMgB,KAE/B4xB,EAAWjB,GAChB4T,GAAS,CAAEr8B,KAAM,UAAWD,SAAAA,EAAUD,WAAY,KAClDs7B,GAID,GAAK/lC,KAAKgpC,aAAV,CAKA,IAEMr9B,EAAU,CAAEhB,KAAM,UAAWD,SAAAA,EAAUD,WAAY,KC/CrD,SACLkB,EACAs9B,EACAzU,EACA0U,QAAAA,IAAAA,IAAAA,EAAyB,MAGV,IAAXD,IAKuB,YAA1Bt9B,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAER5H,QAAQ,SAAC2lC,GACrB,IAAMQ,EAAmBhB,GAAc3T,EAAQmU,GACzCrU,EAAU8S,GAAa5S,EAAQmU,GAE/BS,EAAWzB,GAAiBnT,EADd2U,EAAmBF,EACgB3U,GAE1C,MAAT4U,GAAyB,OAATA,IACnBP,EAAY,GAAKS,EAAS,IAGd,MAATF,GAAyB,OAATA,IACnBP,EAAY,GAAKS,EAAS,GAE5B,EAGD,CDmBEC,CAAe19B,EAND,GAAK3L,KAAKgpC,aAAe3U,GAAYA,EAKpC2S,GAASr7B,IAIxB,IAAMq6B,EACa,YAAlBt7B,EAASC,KACND,EAASE,YAAY,GACrBF,EAASE,YAGbo7B,EAAchjC,QAAQ,SAACkI,GACtBA,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIjF,EAAK5E,oBACpD,GAEA,IAAMglC,EAAmBrmC,KAAKulC,UAAUvC,WAAWgD,IAAkB,GAE/DI,EACLpmC,KAAKsjC,gBAAgBN,WAAWgD,IAAkB,GAEnD,GAAI9T,IAEDA,EACA,CACCzsB,GAAI+sB,EACJ7nB,KAAM,UACND,SAAAA,EACAD,WAAY,IAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,sBAInC,OAAO,EAKTrB,KAAKqxB,MAAM0H,eAAc,CACxB,CAAEtzB,GAAI+sB,EAAY9nB,SAAAA,IAAUoB,OACzBs6B,EACAC,IAGJrmC,KAAKgpC,aAAe3U,CAtDpB,MAFCr0B,KAAKgpC,aAAe3U,CAXrB,CAoED,EAAC0U,CAAA,CA/FgC7L,CAAQF,IEXpCsM,GAAqB,kBACrBC,GAAqB,oBACrBnB,GAAI,QAQGoB,GAAwB,SACpChnC,EACAC,GAC+B,MAAA,CAC/B9C,EAAW,IAAR6C,EAAY,EAAIA,EAAM+mC,GAAqBnB,GAC9C1oC,EACS,IAAR+C,EACG,EACArD,KAAKgqB,IAAIhqB,KAAKiqB,IAAIjqB,KAAKiiB,GAAK,EAAK5e,EAAM8mC,GAAsB,IAAMnB,GACvE,ECIe,SAAAqB,GAAkB99B,GACjC,IAUM+9B,EA/BP,SAAcrP,GAEb,IADA,IAAMsP,EAAS,CAAC3oB,SAAUA,UAAWA,UAAWA,UACvChW,EAAI,EAAGA,EAAIqvB,EAAOpvB,OAAQD,IAAK,CACvC,IAAM+pB,EAAQsF,EAAOrvB,GACjB2+B,EAAO,GAAK5U,EAAM,KACrB4U,EAAO,GAAK5U,EAAM,IAEf4U,EAAO,GAAK5U,EAAM,KACrB4U,EAAO,GAAK5U,EAAM,IAEf4U,EAAO,GAAK5U,EAAM,KACrB4U,EAAO,GAAK5U,EAAM,IAEf4U,EAAO,GAAK5U,EAAM,KACrB4U,EAAO,GAAK5U,EAAM,GAEpB,CACA,OAAO4U,CACR,CAaanM,EATe,YAA1B7xB,EAAQjB,SAASC,KACdgB,EAAQjB,SAASE,YAAY,GAC7Be,EAAQjB,SAASE,aAEsBrF,IAAI,SAACwvB,GAC/C,IAAA6U,EAAiBJ,GAAsBzU,EAAM,GAAIA,EAAM,IACvD,MAAO,CADE6U,EAADjqC,EAAIiqC,EAADlqC,EAEZ,IAKA,MAAO,CAAEC,GAFE+pC,EAAI,GAAKA,EAAI,IAAM,EAElBhqC,GADDgqC,EAAI,GAAKA,EAAI,IAAM,EAE/B,CCHA,IAAaG,gBAA6B,SAAA3M,GACzC,SAAA2M,EACUtpC,EACQhB,EACA+jC,EACAiC,GAA2B,IAAAxlC,EAAA,OAE5CA,EAAAm9B,EAAAr4B,KAAMtE,KAAAA,IAAOP,MALJO,cAAAR,EACQR,mBAAAQ,EAAAA,EACAujC,uBAAAvjC,EACAwlC,eAAAxlC,EAAAA,EAKV+pC,aAAe,KAAM/pC,EAErBwmC,kBAA6D,CACpE9gC,GAAI,KACJyW,OAAQ,GACRnc,EAYOgqC,gBAAkB,CACzBC,SAAU,CACT,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,IAlCKjqC,EAAMQ,OAANA,EACQR,EAAaR,cAAbA,EACAQ,EAAeujC,gBAAfA,EACAvjC,EAASwlC,UAATA,EAA2BxlC,CAG7C,CARyC4F,EAAAkkC,EAAA3M,GAQxC,IAAA57B,EAAAuoC,EAAAtoC,UAgsBAsoC,OAhsBAvoC,EAgCOklC,qBAAA,SACP/kC,EACAiJ,GAEA,IAMI+7B,EANEC,EAAoB,CACzB9I,KAAM5c,SACN9E,OAAQ,EACRyqB,2BAA2B,GAK5B,GAAsB,eAAlBj8B,EAASC,KACZ87B,EAAkB/7B,EAASE,gBACjBF,IAAkB,YAAlBA,EAASC,KAKnB,OAAO+7B,EAJPD,EAAkB/7B,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAII,EAAI,EAAGA,EAAIy7B,EAAgBx7B,OAAQD,IAAK,CAChD,IACMqpB,EAAWr0B,KAAKT,cAAcs+B,QAAQp8B,EAD9BglC,EAAgBz7B,IAG9B,GACCqpB,EAAWr0B,KAAKmxB,iBAChBkD,EAAWqS,EAAkB9I,KAC5B,CAID,IAAM+I,EACa,YAAlBj8B,EAASC,OACRK,IAAMy7B,EAAgBx7B,OAAS,GAAW,IAAND,GAEtC07B,EAAkB9I,KAAOvJ,EACzBqS,EAAkBxqB,MAAQyqB,EAA4B,EAAI37B,EAC1D07B,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACplC,EAEO2oC,uBAAA,SACP/tB,EACAguB,EACAC,GAEA,OAAQjuB,GACP,KAAK,EACJ,GAAIguB,GAAa,GAAKC,GAAa,EAClC,OACD,EACA,MACD,KAAK,EACJ,GAAIA,GAAa,EAChB,SAED,MACD,KAAK,EACJ,GAAID,GAAa,GAAKC,GAAa,EAClC,OACD,EACA,MACD,KAAK,EACJ,GAAID,GAAa,EAChB,SAED,MACD,KAAM,EACL,GAAIA,GAAa,GAAKC,GAAa,EAClC,OACD,EACA,MACD,KAAK,EACJ,GAAIA,GAAa,EAChB,SAED,MACD,KAAM,EACL,GAAID,GAAa,GAAKC,GAAa,EAClC,SAED,MACD,KAAK,EACJ,GAAID,GAAa,EAChB,OAAO,EAOV,OACD,CAAA,EAAC5oC,EAEO8oC,kCAAA,WACP,IAAKpqC,KAAKumC,kBAAkB9gC,KAAwC,IAAlCzF,KAAKumC,kBAAkBrqB,MACxD,OACD,KAEA,IAAMvQ,EAAU3L,KAAKqqC,WAAWrqC,KAAKumC,kBAAkB9gC,IACvD,IAAKkG,EACJ,OAAO,KAGR,IAAMq6B,EAAgBhmC,KAAKsqC,yBAAyB3+B,EAAQjB,UAG5D,MAAO,CACN6/B,YAHmBvqC,KAAKwqC,mBAAmBxE,GAI3Cr6B,QAAAA,EACAq6B,cAAAA,EACAyE,mBAAoBzE,EAAchmC,KAAKumC,kBAAkBrqB,OAE3D,EAAC5a,EAEOopC,sBAAA,SAAsBjpC,GAC7B,IAAMkpC,EAAc3qC,KAAKoqC,oCACzB,IAAKO,EACJ,YAED,IAAiBJ,EAChBI,EADgBJ,YAAavE,EAC7B2E,EAD6B3E,cAAeyE,EAC5CE,EAD4CF,mBAGvCG,EAAoBnB,GAFzBkB,EADOh/B,SAKR,IAAKi/B,EACJ,OAAO,KAGR,IAAMC,EAAsBrB,GAC3BiB,EAAmB,GACnBA,EAAmB,IAGZK,EAAqB9qC,KAAK+qC,sBACjCR,EACAM,GAFOC,iBAKFE,EAAoBxB,GAAsB/nC,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKirC,iBAAiB,CACrBH,iBAAAA,EACA9E,cAAAA,EACAgF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM5E,CACR,EAAC1kC,EAEO4pC,2BAAA,SAA2BzpC,GAClC,IAAMkpC,EAAc3qC,KAAKoqC,oCACzB,IAAKO,EACJ,OAAO,KAER,IAAiBJ,EAChBI,EADgBJ,YAAavE,EAC7B2E,EAD6B3E,cAAeyE,EAC5CE,EAD4CF,mBAGvCG,EAAoBnB,GAFzBkB,EADOh/B,SAKR,IAAKi/B,EACJ,OACD,KAEA,IAAMC,EAAsBrB,GAC3BiB,EAAmB,GACnBA,EAAmB,IAGZK,EAAqB9qC,KAAK+qC,sBACjCR,EACAM,GAFOC,iBAKFE,EAAoBxB,GAAsB/nC,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKmrC,sBAAsB,CAC1BL,iBAAAA,EACA9E,cAAAA,EACAgF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM5E,CACR,EAAC1kC,EAEO6pC,sBAAA,SAAArrC,OAEP8qC,EAAiB9qC,EAAjB8qC,kBACAC,EAAmB/qC,EAAnB+qC,oBACAG,EAAiBlrC,EAAjBkrC,kBACAhF,EAAalmC,EAAbkmC,cAiBA,IANchmC,KAAKiqC,uBAfHnqC,EAAhBgrC,iBAYwBF,EAAkBjrC,EAAIqrC,EAAkBrrC,EACxCirC,EAAkBlrC,EAAIsrC,EAAkBtrC,GAS/D,YAGD,IAAIwN,EACH3N,EAAcqrC,EAAmBI,GACjCzrC,EAAcqrC,EAAmBC,GAclC,OAZI39B,EAAQ,IACXA,EAAQlN,KAAK8pC,cAGd9pC,KAAKorC,wBACJpF,EACA4E,EAAkBjrC,EAClBirC,EAAkBlrC,EAClBwN,EACAA,GAGM84B,CACR,EAAC1kC,EAEO+pC,6BAAA,SAA6B5pC,GACpC,IAAMkpC,EAAc3qC,KAAKoqC,oCACzB,IAAKO,EACJ,YAGD,IAAQJ,EAAmDI,EAAnDJ,YAAavE,EAAsC2E,EAAtC3E,cAAeyE,EAAuBE,EAAvBF,mBAE9BI,EAAsBrB,GAC3BiB,EAAmB,GACnBA,EAAmB,IAGpBa,EAAgDtrC,KAAK+qC,sBACpDR,EACAM,GAFOU,EAAiBD,EAAjBC,kBAAmBT,EAAgBQ,EAAhBR,iBAKrBF,EAAoB,CACzBjrC,EAAG4qC,EAAYgB,GAAmB,GAClC7rC,EAAG6qC,EAAYgB,GAAmB,IAE7BP,EAAoBxB,GAAsB/nC,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKmrC,sBAAsB,CAC1BL,iBAAAA,EACA9E,cAAAA,EACAgF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM5E,CACR,EAAC1kC,EAEOkqC,wBAAA,SAAwB/pC,GAC/B,IAAMkpC,EAAc3qC,KAAKoqC,oCACzB,IAAKO,EACJ,OACD,KAEA,IAAQJ,EAAmDI,EAAnDJ,YAAavE,EAAsC2E,EAAtC3E,cAAeyE,EAAuBE,EAAvBF,mBAE9BI,EAAsBrB,GAC3BiB,EAAmB,GACnBA,EAAmB,IAGpBgB,EAAgDzrC,KAAK+qC,sBACpDR,EACAM,GAFOU,EAAiBE,EAAjBF,kBAAmBT,EAAgBW,EAAhBX,iBAKrBF,EAAoB,CACzBjrC,EAAG4qC,EAAYgB,GAAmB,GAClC7rC,EAAG6qC,EAAYgB,GAAmB,IAE7BP,EAAoBxB,GAAsB/nC,EAAMe,IAAKf,EAAMgB,KAUjE,OARAzC,KAAKirC,iBAAiB,CACrBH,iBAAAA,EACA9E,cAAAA,EACAgF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGM5E,CACR,EAAC1kC,EAEO2pC,iBAAA,SAAArkC,GAYP,IAXAkkC,EAAgBlkC,EAAhBkkC,iBACAF,EAAiBhkC,EAAjBgkC,kBACAC,EAAmBjkC,EAAnBikC,oBACAG,EAAiBpkC,EAAjBokC,kBACAhF,EAAap/B,EAAbo/B,cAQM0F,EAAkBd,EAAkBjrC,EAAIqrC,EAAkBrrC,EAC1DgsC,EAAkBf,EAAkBlrC,EAAIsrC,EAAkBtrC,EAQhE,IANcM,KAAKiqC,uBAClBa,EACAY,EACAC,GAIA,OACD,KAEA,IAAIC,EAAS,EAEQ,IAApBF,GACqB,IAArBZ,GACqB,IAArBA,IAGAc,EAAS,GADgBhB,EAAkBjrC,EAAIkrC,EAAoBlrC,EAClC+rC,GAAmBA,GAGrD,IAAIG,EAAS,EAUb,OARqB,IAApBF,GACqB,IAArBb,GACqB,IAArBA,IAGAe,EAAS,GADgBjB,EAAkBlrC,EAAImrC,EAAoBnrC,EAClCisC,GAAmBA,GAGhD3rC,KAAK8rC,cAAcF,EAAQC,IAI5BD,EAAS,IACZA,EAAS5rC,KAAK8pC,cAGX+B,EAAS,IACZA,EAAS7rC,KAAK8pC,cAGf9pC,KAAKorC,wBACJpF,EACA4E,EAAkBjrC,EAClBirC,EAAkBlrC,EAClBksC,EACAC,GAGM7F,OACR,EAAC1kC,EAEO+oC,WAAA,SAAW5kC,GAClB,GAAkC,OAA9BzF,KAAKumC,kBAAkB9gC,GAC1B,OAAO,KAGR,IAAMiF,EAAW1K,KAAKqxB,MAAMmI,gBAAgB/zB,GAG5C,MAAsB,YAAlBiF,EAASC,MAAwC,eAAlBD,EAASC,KACpC,KAGQ,CAAEA,KAAM,UAAWD,SAAAA,EAAUD,WAAY,GAK1D,EAACnJ,EAEOgpC,yBAAA,SAAyB5/B,GAEhC,MAAyB,YAAlBA,EAASC,KACbD,EAASE,YAAY,GACrBF,EAASE,WACb,EAACtJ,EAEOwqC,cAAA,SAAcF,EAAgBC,GACrC,IAAME,GAAUl8B,MAAM+7B,IAAWC,EAASpzB,OAAOuzB,iBAC3CC,GAAUp8B,MAAMg8B,IAAWA,EAASpzB,OAAOuzB,iBAEjD,OAAOD,GAAUE,CAClB,EAAC3qC,EAEO8pC,wBAAA,SACPxgC,EACAshC,EACAC,EACAP,EACAC,GAEAjhC,EAAY5H,QAAQ,SAACkI,GACpB,IFpdFvL,EACAD,EEmdEkqC,EAAiBJ,GAAsBt+B,EAAW,GAAIA,EAAW,IAKjEkhC,EFvdiC,CACnC5pC,IAAW,KAHX7C,EEsdmBusC,GAFRtC,EAADjqC,EAEwBusC,GAAWN,GFnd9B,EAAItC,IAAsB3pC,EAAIyoC,IAC7C3lC,IACO,KAJP/C,EEsdmBysC,GAHLvC,EAADlqC,EAGqBysC,GAAWN,GFjdzC,GACC,EAAIzsC,KAAKusB,KAAKvsB,KAAKwsB,IAAIlsB,EAAI0oC,KAAMhpC,KAAKiiB,GAAK,GAAKioB,IEkdtC7mC,EAAG2pC,EAAH3pC,IAEbyI,EAAW,GAFAkhC,EAAH5pC,IAGR0I,EAAW,GAAKzI,CACjB,EACD,EAACnB,EAEOkpC,mBAAA,SAAmB5/B,GAC1B,IAAM4yB,EAAyC,CAC9Cxc,SACAA,UACCA,UACAA,WAIFpW,EAAcA,EAAYrF,IAAI,SAACwvB,GAC9B,IAAAsX,EAAiB7C,GAAsBzU,EAAM,GAAIA,EAAM,IACvD,MAAO,CADEsX,EAAD1sC,EAAI0sC,EAAD3sC,EAEZ,IAEYsD,QAAQ,SAAAspC,GAAW,IAAT3sC,EAAC2sC,EAAA,GAAE5sC,EAAC4sC,KACrB3sC,EAAI69B,EAAK,KACZA,EAAK,GAAK79B,GAGPD,EAAI89B,EAAK,KACZA,EAAK,GAAK99B,GAGPC,EAAI69B,EAAK,KACZA,EAAK,GAAK79B,GAGPD,EAAI89B,EAAK,KACZA,EAAK,GAAK99B,EAEZ,GAEA,IAAO6sC,EAA4B/O,EAAI,GAA1BgP,EAAsBhP,KAAfiP,EAAejP,EAAI,GAAbkP,EAASlP,KAsBnC,MAAO,CAVS,CAAC+O,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,EAACprC,EAEOypC,sBAAA,SACPR,EACAoC,GAKA,IAHA,IAAIC,EACAC,EAAkB7rB,SAEbhW,EAAI,EAAGA,EAAIu/B,EAAYt/B,OAAQD,IAAK,CAC5C,IAAMqpB,EAAW90B,EAChB,CAAEI,EAAGgtC,EAAWhtC,EAAGD,EAAGitC,EAAWjtC,GACjC,CAAEC,EAAG4qC,EAAYv/B,GAAG,GAAItL,EAAG6qC,EAAYv/B,GAAG,KAGvCqpB,EAAWwY,IACdD,EAAe5hC,EACf6hC,EAAkBxY,EAEpB,CAEA,QAAqBptB,IAAjB2lC,EACH,MAAU,IAAAlnC,MAAM,+BASjB,MAAO,CACN6lC,kBALqBvrC,KAAK+pC,gBAA0B,SACpD6C,GAKA9B,iBAAkB8B,EAEpB,EAACtrC,EAKMskC,WAAA,WACN,OAAqC,OAA9B5lC,KAAKumC,kBAAkB9gC,EAC/B,EAACnE,EAQMokC,cAAA,SAAcjgC,EAAeyW,GACnClc,KAAKumC,kBAAoB,CACxB9gC,GAAAA,EACAyW,MAAAA,EAEF,EAAC5a,EAMMqkC,aAAA,WACN3lC,KAAKumC,kBAAoB,CACxB9gC,GAAI,KACJyW,OAAQ,EAEV,EAAC5a,EAQMslC,kBAAA,SACNnlC,EACA+wB,GAEA,IAAM9nB,EAAW1K,KAAKqxB,MAAMmI,gBAAgBhH,GACtCkU,EAAoB1mC,KAAKwmC,qBAAqB/kC,EAAOiJ,GAG3D,OAAiC,IAA7Bg8B,EAAkBxqB,OACb,EAEFwqB,EAAkBxqB,KAC1B,EAAC5a,EAQMwkC,KAAA,SACNrkC,EACAqrC,EACA5a,GAEA,IAAKlyB,KAAKumC,kBAAkB9gC,GAC3B,OACD,EACA,IAAMkG,EAAU3L,KAAKqqC,WAAWrqC,KAAKumC,kBAAkB9gC,IACvD,IAAKkG,EACJ,OAAO,EAER,IAAIq6B,EAAmC,KAYvC,GAVqB,wBAAjB8G,EACH9G,EAAgBhmC,KAAK0qC,sBAAsBjpC,GAChB,0BAAjBqrC,EACV9G,EAAgBhmC,KAAKwrC,wBAAwB/pC,GAClB,8BAAjBqrC,EACV9G,EAAgBhmC,KAAKkrC,2BAA2BzpC,GACrB,gCAAjBqrC,IACV9G,EAAgBhmC,KAAKqrC,6BAA6B5pC,KAG9CukC,EACJ,OAAO,EAIR,IAAK,IAAIh7B,EAAI,EAAGA,EAAIg7B,EAAc/6B,OAAQD,IAAK,CAC9C,IAAME,EAAa86B,EAAch7B,GAKjC,GAJAE,EAAW,GAAKlM,EAAekM,EAAW,GAAIlL,KAAKqB,qBACnD6J,EAAW,GAAKlM,EAAekM,EAAW,GAAIlL,KAAKqB,sBAG9Cs1B,GAAkBzrB,EAAYlL,KAAKqB,qBACvC,QAEF,CAGA,IAAMglC,EAAmBrmC,KAAKulC,UAAUvC,WAAWgD,IAAkB,GAC/DI,EACLpmC,KAAKsjC,gBAAgBN,WAAWgD,IAAkB,GAE7C+G,EAAkB,CACvBpiC,KAAMgB,EAAQjB,SAASC,KACvBC,YAC2B,YAA1Be,EAAQjB,SAASC,KAAqB,CAACq7B,GAAiBA,GAG1D,QAAI9T,IACWA,EACb,CACCzsB,GAAIzF,KAAKumC,kBAAkB9gC,GAC3BkF,KAAM,UACND,SAAUqiC,EACVtiC,WAAY,CAAA,GAEb,CACCrC,QAASpI,KAAKO,OAAO6H,QACrBI,UAAWxI,KAAKO,OAAOiI,UACvBnH,oBAAqBrB,KAAKO,OAAOc,wBASpCrB,KAAKqxB,MAAM0H,gBACV,CACCtzB,GAAIzF,KAAKumC,kBAAkB9gC,GAC3BiF,SAAUqiC,IACVjhC,OACEs6B,EACAC,IAGG,GACR,EAACwD,CAAA,CAxsBwC,CAAQ7M,IC2ErCgQ,gBAAoBC,SAAAA,GA2BhC,SAAAD,EAAY94B,GAAsDg5B,IAAAA,EAAAntC,GACjEA,EAAAktC,EAAApoC,KAAA7E,KAAMkU,IAASnU,MA3BTiM,KAAO,SAAQjM,EAEdotC,wBAAyB,EAAIptC,EAC7BqtC,kBAAoB,EAACrtC,EACrBstC,eAAiB,EAACttC,EAClButC,SAAwB,GAAEvtC,EAE1BwtC,WAAK,EAAAxtC,EACLy3B,eAAS,EAAAz3B,EAGTujC,qBAAevjC,EAAAA,EACfwlC,eAASxlC,EAAAA,EACTulC,0BAAoBvlC,EAAAA,EACpBR,mBAAaQ,EAAAA,EACbo9B,sBAAgB,EAAAp9B,EAChBytC,iBAAW,EAAAztC,EACX0tC,oBAAc,EAAA1tC,EACd2tC,mBAAa,EAAA3tC,EACb4tC,kBAAY,EAAA5tC,EACZ6tC,iCAA2B,EAAA7tC,EAC3B03B,aAAO,EAAA13B,EACP8tC,YAEJ,GAKH9tC,EAAKwtC,MAAQr5B,GAAWA,EAAQq5B,MAAQr5B,EAAQq5B,MAAQ,CAAE,EAE1D,IAAM5V,EAAiB,CACtBmW,YAAa,OACbC,UAAW,OACXC,QAAS,OACTC,eAAgB,aAWjB,GAPCluC,EAAK03B,QADFvjB,GAAWA,EAAQujB,QACVlG,EAAQoG,CAAAA,EAAAA,EAAmBzjB,EAAQujB,SAEhCE,EAKW,QAAvBzjB,MAAAA,OAAAA,EAAAA,EAASsjB,WACZz3B,EAAKy3B,UAAY,CAChB0W,SAAU,KACVC,OAAQ,KACR1F,OAAQ,KACRv7B,MAAO,UAEF,CACN,IAAM6qB,EAAmB,CACxBmW,SAAU,SACVC,OAAQ,SACR1F,OAAQ,CAAC,UAAW,KACpBv7B,MAAO,CAAC,UAAW,MAEpBnN,EAAKy3B,UACJtjB,GAAWA,EAAQsjB,UAASjG,EACpBwG,CAAAA,EAAAA,EAAqB7jB,EAAQsjB,WAClCO,CACL,CAWA,GATAh4B,EAAKqtC,kBACHl5B,QAC8BjN,IAA9BiN,EAAQk5B,mBACRl5B,EAAQk5B,mBACT,EAEDrtC,EAAKotC,uBAAwDD,OAAlCA,EAAU,MAAPh5B,OAAO,EAAPA,EAASi5B,yBAAsBD,EAGzDh5B,GAAWA,EAAQq5B,OAASr5B,EAAQq5B,MACvC,IAAK,IAAMvhC,KAAQkI,EAAQq5B,MAAO,CACjC,IAAM5hC,EAAUuI,EAAQq5B,MAAMvhC,GAAML,QAChCA,GAAWA,EAAQyiC,aACtBruC,EAAK8tC,YAAY7hC,GAAQL,EAAQyiC,WAInC,CACA,OAAAruC,CACF,CAtFgC4F,EAAAqnC,EAAAC,GAsF/B,IAAA3rC,EAAA0rC,EAAAzrC,UAs0BA,OAt0BAD,EAED+sC,cAAA,SAAcvL,GACb9iC,KAAKsuC,OAAOxL,GAAW,EACxB,EAACxhC,EAEDitC,aAAA,WACC,GAAoB,YAAhBvuC,KAAKgxB,OAGR,MAAM,IAAItrB,MAAM,mDAFhB1F,KAAKgxB,OAAS,WAIhB,EAAC1vB,EAEDkwB,kBAAA,SAAkBjxB,GACjBP,KAAKT,cAAgB,IAAIw+B,GAAsBx9B,GAC/CP,KAAKm9B,iBAAmB,IAAIkB,GAAyB99B,GACrDP,KAAKslC,qBAAuB,IAAIV,GAC/BrkC,EACAP,KAAKm9B,iBACLn9B,KAAKT,eAGNS,KAAKsjC,gBAAkB,IAAIJ,GAAuB3iC,GAClDP,KAAKulC,UAAY,IAAInD,GAAiB7hC,EAAQP,KAAKsjC,iBAEnDtjC,KAAK0tC,cAAgB,IAAIpF,GACxB/nC,EACAP,KAAKsjC,gBACLtjC,KAAKulC,WAGNvlC,KAAK2tC,aAAe,IAAI5E,GACvBxoC,EACAP,KAAKsjC,gBACLtjC,KAAKulC,WAGNvlC,KAAKwtC,YAAc,IAAInI,GACtB9kC,EACAP,KAAKslC,qBACLtlC,KAAKsjC,gBACLtjC,KAAKulC,WAENvlC,KAAKytC,eAAiB,IAAInH,GACzB/lC,EACAP,KAAKT,cACLS,KAAKsjC,gBACLtjC,KAAKulC,WAENvlC,KAAK4tC,4BAA8B,IAAI/D,GACtCtpC,EACAP,KAAKT,cACLS,KAAKsjC,gBACLtjC,KAAKulC,UAEP,EAACjkC,EAEMktC,gBAAA,WACNxuC,KAAKkuC,UACN,EAAC5sC,EAEO4sC,SAAA,WAAQjoC,IAAAA,OACTwoC,EAAyBzuC,KAAKstC,SAClC/P,OAAO,SAAC93B,GAAO,OAAAQ,EAAKorB,MAAMzjB,IAAInI,EAAG,GACjCF,IAAI,SAACE,GAAQ,MAAA,CACbA,GAAAA,EACA4E,SAAUkmB,GACVlkB,OAAO,EACP,GAEFrM,KAAKqxB,MAAM2H,eAAeyV,GAE1BzuC,KAAKgyB,WAAWhyB,KAAKstC,SAAS,IAC9BttC,KAAKstC,SAAW,GAChBttC,KAAKsjC,gBAAe,SACpBtjC,KAAKulC,UAAgB,QACtB,EAACjkC,EAEOotC,eAAA,WAMP1uC,KAAKqxB,MAAK,OAAQrxB,KAAKstC,UACvBttC,KAAKstC,SAAW,EACjB,EAAChsC,EAEOqtC,aAAA,SAAaltC,GAA0B,IAAAkI,EAAA3J,KAC9C,GAAKA,KAAKsjC,gBAAgBpD,IAAIj1B,OAA9B,CAIA,IAAI2jC,EAOA5J,EAAyBhkB,SAkB7B,GAhBAhhB,KAAKsjC,gBAAgBpD,IAAIl9B,QAAQ,SAACyC,GACjC,IAAMiF,EAAWf,EAAK0nB,MAAMmI,gBAAuB/zB,GAC7C4uB,EAAW1qB,EAAKpK,cAAcs+B,QAAQp8B,EAAOiJ,EAASE,aAG3DypB,EAAW1qB,EAAKwnB,iBAChBkD,EAAW2Q,IAEXA,EAAyB3Q,EACzBua,EAA6BjlC,EAAK0nB,MAAMsR,kBAAkBl9B,GAK5D,GAEKmpC,EAAL,CAIA,IAAM9L,EAAY8L,EAA2BnL,wBACvCoL,EAAkBD,EAA2B1yB,MAG7CzR,EAAazK,KAAKqxB,MAAMsR,kBAAkBG,GAC1CgM,EAAY9uC,KAAKutC,MAAM9iC,EAAWuB,MAClCoiC,EAAapuC,KAAK6tC,YAAYpjC,EAAWuB,MAS/C,GALE8iC,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQf,aAClBkkC,EAAUnjC,QAAQf,YAAYmkC,UAEhC,CAIA,IAEInkC,EAFEF,EAAW1K,KAAKqxB,MAAMmI,gBAAgBsJ,GAG5C,GAAsB,YAAlBp4B,EAASC,MAIZ,IAHAC,EAAcF,EAASE,YAAY,IAGnBK,QAAU,EACzB,YAEK,GAAsB,eAAlBP,EAASC,OACnBC,EAAcF,EAASE,aAGPK,QAAU,EACzB,OAKF,GAAKL,EAAL,CAoBA,GAfoB,YAAlBF,EAASC,MAA0C,IAApBkkC,GAChCA,IAAoBjkC,EAAYK,OAAS,GAKzCL,EAAYmP,QACZnP,EAAYivB,MACZjvB,EAAYO,KAAK,CAACP,EAAY,GAAG,GAAIA,EAAY,GAAG,MAGpDA,EAAYwR,OAAOyyB,EAAiB,GAIjCT,IACWA,EAAW,CACxB3oC,GAAIq9B,EACJn4B,KAAM,UACND,SAAAA,EACAD,WAAAA,IAGA,OAIFzK,KAAKqxB,MAAY,OAAA,GAAAvlB,OAAK9L,KAAKulC,UAAUrF,IAAQlgC,KAAKsjC,gBAAgBpD,MAClElgC,KAAKqxB,MAAM0H,eAAe,CACzB,CACCtzB,GAAIq9B,EACJp4B,SAAAA,KAIF1K,KAAKsjC,gBAAgBhL,OACpB1tB,EACAF,EAASC,KACTm4B,GAIAgM,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQf,aAClBkkC,EAAUnjC,QAAQf,YAAYokC,WAE9BhvC,KAAKulC,UAAUjN,OAAO1tB,EAAak4B,EAAW9iC,KAAKqB,oBAlDpD,CAxBA,CAnBA,CA7BA,CA4HD,EAACC,EAEOgtC,OAAA,SAAOxL,EAAsBmM,GACpC,QAD8C,IAAVA,IAAAA,GAAa,GAC7CjvC,KAAKstC,SAAS,KAAOxK,EAAzB,CAIA,IAAAJ,EAAiB1iC,KAAKqxB,MAAMsR,kBAAkBG,GAGxCgM,EAAY9uC,KAAKutC,MAHX7K,EAAJ12B,MAMR,GAAK8iC,GAAcA,EAAUnjC,QAA7B,CAIA,IAAMujC,EAAuBlvC,KAAKstC,SAAS,GAG3C,GAAI4B,EAAsB,CAEzB,GAAIA,IAAyBpM,EAC5B,OAIA9iC,KAAKkuC,UAEP,CAEIe,GACHjvC,KAAKyI,UAAUzI,KAAKy3B,QAAQqW,aAI7B9tC,KAAKstC,SAAW,CAACxK,GAEjB9iC,KAAKqxB,MAAM2H,eAAe,CACzB,CAAEvzB,GAAIq9B,EAAWz4B,SAAU,WAAYgC,OAAO,KAE/CrM,KAAK+xB,SAAS+Q,GAGd,IAAAqM,EAA8BnvC,KAAKqxB,MAAMmI,gBAAgBsJ,GAAjDn4B,EAAIwkC,EAAJxkC,KAAMC,EAAWukC,EAAXvkC,YAEd,GAAa,eAATD,GAAkC,YAATA,EAA7B,CAMA,IAAMo1B,EACI,eAATp1B,EAAwBC,EAAcA,EAAY,GAE/Cm1B,GAAkB+O,GAAaA,EAAUnjC,QAAQf,cACpD5K,KAAKsjC,gBAAgBhL,OAAOyH,EAAgBp1B,EAAMm4B,GAE9CgM,EAAUnjC,QAAQf,YAAYokC,WACjChvC,KAAKulC,UAAUjN,OACdyH,EACA+C,EACA9iC,KAAKqB,qBAdR,CAjCA,CAVA,CA6DD,EAACC,EAEO8tC,YAAA,SAAY3tC,GACnB,IAAA4tC,EAA4CrvC,KAAKslC,qBAAqB5+B,KACrEjF,EACAzB,KAAKstC,SAASriC,OAAS,GAFhB85B,EAAcsK,EAAdtK,eAAgBE,EAAeoK,EAAfpK,gBAKxB,GAAIjlC,KAAKstC,SAASriC,QAAUg6B,EAI3BjlC,KAAKulC,UAAUhD,OACd0C,EAAgBx/B,GAChBzF,KAAKqB,0BAMP,GAAI0jC,GAAkBA,EAAet/B,GACpCzF,KAAKsuC,OAAOvJ,EAAet/B,IAAI,QACrB,GAAAzF,KAAKstC,SAASriC,QAAUjL,KAAKmtC,uBAEvC,YADAntC,KAAKkuC,UAGP,EAAC5sC,EAGDs2B,MAAA,WACC53B,KAAK2xB,aACL3xB,KAAKuuC,cACN,EAACjtC,EAGD42B,KAAA,WACCl4B,KAAKm4B,UACLn4B,KAAK2xB,aACL3xB,KAAK4xB,YACN,EAACtwB,EAGD+C,QAAA,SAAQ5C,GACHzB,KAAKstC,SAASriC,SACjBjL,KAAKyI,UAAUzI,KAAKy3B,QAAQuW,UAGxBhuC,KAAKytC,eAAe7H,cAEb5lC,KAAKwtC,YAAY5H,cAEjB5lC,KAAK4tC,4BAA4BhI,eAH3C5lC,KAAKiyB,SAASjyB,KAAKstC,SAAS,IAO7BttC,KAAKytC,eAAe9H,eACpB3lC,KAAKwtC,YAAY7H,eACjB3lC,KAAK4tC,4BAA4BjI,eACjC3lC,KAAK0tC,cAAclF,QACnBxoC,KAAK2tC,aAAanF,SAIE,UAAjB/mC,EAAMC,QAGkB,SAAjBD,EAAMC,QAEW,YAAjBD,EAAMC,SADhB1B,KAAKovC,YAAY3tC,GAHjBzB,KAAK2uC,aAAaltC,EAOpB,EAACH,EAEOguC,SAAA,SAAS7tC,GAChB,OACKzB,KAACw3B,UAAUtqB,OACflN,KAAKw3B,UAAUtqB,MAAM8pB,MAAM,SAAC1yB,GAAG,OAAK7C,EAAMkB,SAASyW,SAAS9U,EAAI,EAElE,EAAChD,EAEOiuC,UAAA,SAAU9tC,GACjB,YACM+1B,UAAUiR,QACfzoC,KAAKw3B,UAAUiR,OAAOzR,MAAM,SAAC1yB,GAAQ,OAAA7C,EAAMkB,SAASyW,SAAS9U,EAAI,EAEnE,EAAChD,EAEOkuC,uBAAA,SAAuB/tC,GAC9B,IAAMguC,EAAiBzvC,KAAKuvC,UAAU9tC,GAChCiuC,EAAc1vC,KAAKsvC,SAAS7tC,IAG9BguC,GAAkBC,IACrBjuC,EAAM8B,gBAER,EAACjC,EAGDmD,UAAA,SAAUhD,GACTzB,KAAKwvC,uBAAuB/tC,EAC7B,EAACH,EAGDiD,QAAA,SAAQ9C,GAGP,GAFAzB,KAAKwvC,uBAAuB/tC,GAExBzB,KAAKw3B,UAAgB,QAAI/1B,EAAM6C,MAAQtE,KAAKw3B,UAAS,OAAS,CACjE,IAAKx3B,KAAKstC,SAASriC,OAClB,OAODjL,KAAKgyB,WADsBhyB,KAAKstC,SAAS,IAIzCttC,KAAK0uC,iBAGL1uC,KAAKsjC,gBAAe,SACpBtjC,KAAKulC,UAAgB,QACtB,MACCvlC,KAAKw3B,UAAU0W,UACfzsC,EAAM6C,MAAQtE,KAAKw3B,UAAU0W,UAE7BluC,KAAKm4B,SAEP,EAAC72B,EAGD62B,QAAA,WACKn4B,KAAKstC,SAASriC,SACjBjL,KAAKyI,UAAUzI,KAAKy3B,QAAQuW,UAGxBhuC,KAAKytC,eAAe7H,cAEb5lC,KAAKwtC,YAAY5H,cAEjB5lC,KAAK4tC,4BAA4BhI,eAH3C5lC,KAAKiyB,SAASjyB,KAAKstC,SAAS,IAO7BttC,KAAKytC,eAAe9H,eACpB3lC,KAAKwtC,YAAY7H,eACjB3lC,KAAK4tC,4BAA4BjI,eACjC3lC,KAAK0tC,cAAclF,QACnBxoC,KAAK2tC,aAAanF,QAClBxoC,KAAKkuC,WAEP,EAAC5sC,EAGDwC,YAAA,SACCrC,EACAgxB,GAA8Ckd,IAAAA,EAAAC,EAK9C,GADA5vC,KAAKstC,SAASriC,OAAS,GAAKjL,KAAKqE,QAAQ5C,GACpCzB,KAAKstC,SAASriC,OAAnB,CAGA,IAAM+jC,EAEIY,OAFKD,EACd3vC,KAAKutC,MAAMvtC,KAAKqxB,MAAMsR,kBAAkB3iC,KAAKstC,SAAS,IAAIthC,MACxDL,UADFikC,OACSA,EADTD,EACW/kC,kBAAFglC,EADTA,EACwBZ,UAGxBhvC,KAAKstC,SAASriC,OAAS,GACF,iBAAd+jC,GACoB,SAA3BA,EAAUa,cAEV7vC,KAAKqE,QAAQ5C,GAMd,IAAMgJ,EAAazK,KAAKqxB,MAAMsR,kBAAkB3iC,KAAKstC,SAAS,IACxDwB,EAAY9uC,KAAKutC,MAAM9iC,EAAWuB,MAUxC,GARC8iC,GACAA,EAAUnjC,UACTmjC,EAAUnjC,QAAQpC,WACjBulC,EAAUnjC,QAAQf,aAClBkkC,EAAUnjC,QAAQf,YAAYrB,WAC9BulC,EAAUnjC,QAAQf,aAClBkkC,EAAUnjC,QAAQf,YAAYklC,WAEjC,CAIA9vC,KAAKqtC,eAAiB,EAEtB,IAAM7a,EAAaxyB,KAAKstC,SAAS,GAC3ByC,EAA2B/vC,KAAKytC,eAAe7G,kBACpDnlC,EACA+wB,GAID,OACCsc,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQf,cACjBkkC,EAAUnjC,QAAQf,YAAYrB,WAC9BulC,EAAUnjC,QAAQf,YAAYklC,aACD,IAA9BC,GAEA/vC,KAAKyI,UAAUzI,KAAKy3B,QAAQsW,WAGxBe,EAAUnjC,QAAQf,YAAYklC,UACjC9vC,KAAK4tC,4BAA4BlI,cAChClT,EACAud,GAID/vC,KAAKytC,eAAe/H,cAAclT,EAAYud,QAG/Ctd,GAAmB,IAMnBqc,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQpC,WAClBvJ,KAAKwtC,YAAY3H,QAAQpkC,EAAO+wB,IAEhCxyB,KAAKyI,UAAUzI,KAAKy3B,QAAQsW,WAC5B/tC,KAAKwtC,YAAY9H,cAAcjkC,EAAO+wB,QACtCC,GAAmB,SARpB,CArCA,CA7BA,CA6ED,EAACnxB,EAGD4C,OAAA,SACCzC,EACAgxB,GAEA,IAAMD,EAAaxyB,KAAKstC,SAAS,GAGjC,GAAK9a,EAAL,CAIA,IAAM/nB,EAAazK,KAAKqxB,MAAMsR,kBAAkBnQ,GAE1Csc,EAAY9uC,KAAKutC,MAAM9iC,EAAWuB,MAClCgkC,GAGqC,KAFzClB,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQskC,mBAOpB,GAJAjwC,KAAKqtC,iBAIDrtC,KAAKqtC,eAAiBrtC,KAAKotC,mBAAsB,EAArD,CAIA,IAAMgB,EAAapuC,KAAK6tC,YAAYpjC,EAAWuB,MAG/C,OACC8iC,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQukC,YAClBlwC,KAAKuvC,UAAU9tC,IAEfgxB,GAAmB,QACnBzyB,KAAK0tC,cAAcjF,OAAOhnC,EAAO+wB,EAAY4b,IAM7CU,GACAA,EAAUnjC,SACVmjC,EAAUnjC,QAAQwkC,WAClBnwC,KAAKsvC,SAAS7tC,IAEdgxB,GAAmB,QACnBzyB,KAAK2tC,aAAazgC,MAAMzL,EAAO+wB,EAAY4b,IAK3CpuC,KAAK4tC,4BAA4BhI,cACjCkJ,EAAUnjC,SACVmjC,EAAUnjC,QAAQf,aAClBkkC,EAAUnjC,QAAQf,YAAYklC,WAE9Brd,GAAmB,QACnBzyB,KAAK4tC,4BAA4B9H,KAChCrkC,EACAqtC,EAAUnjC,QAAQf,YAAYklC,UAC9B1B,SAMEpuC,KAAKytC,eAAe7H,aACvB5lC,KAAKytC,eAAe3H,KAAKrkC,EAAOuuC,EAAkB5B,GAK/CpuC,KAAKwtC,YAAY5H,aACpB5lC,KAAKwtC,YAAY1H,KAAKrkC,EAAO2sC,GAI9B3b,GAAmB,GAvDnB,CAjBA,CAyED,EAACnxB,EAGD8C,UAAA,SACCipB,EACAoF,GAEAzyB,KAAKyI,UAAUzI,KAAKy3B,QAAQuW,UAI3BhuC,KAAKytC,eAAe7H,cACpB5lC,KAAK4tC,4BAA4BhI,cAGvB5lC,KAAKwtC,YAAY5H,cAEjB5lC,KAAK4tC,4BAA4BhI,eAH3C5lC,KAAKiyB,SAASjyB,KAAKstC,SAAS,IAO7BttC,KAAKytC,eAAe9H,eACpB3lC,KAAKwtC,YAAY7H,eACjB3lC,KAAK4tC,4BAA4BjI,eACjC3lC,KAAK0tC,cAAclF,QACnBxoC,KAAK2tC,aAAanF,QAClB/V,GAAmB,EACpB,EAACnxB,EAGDkC,YAAA,SAAY/B,GAA0B,IAAAiM,EAAA1N,KACrC,GAAKA,KAAKstC,SAASriC,QAKnB,IAAIjL,KAAKwtC,YAAY5H,aAArB,CAIA,IAAIwK,GAAiB,EACrBpwC,KAAKulC,UAAUrF,IAAIl9B,QAAQ,SAACyC,GAC3B,IAAI2qC,EAAJ,CAGA,IAAM1lC,EAAWgD,EAAK2jB,MAAMmI,gBAAuB/zB,GAClCiI,EAAKnO,cAAcs+B,QAAQp8B,EAAOiJ,EAASE,aAE7C8C,EAAKyjB,kBACnBif,GAAiB,EALlB,CAOD,GAEA,IAAIC,GAAuB,EAY3B,GATArwC,KAAKsjC,gBAAgBpD,IAAIl9B,QAAQ,SAACyC,GACjC,IAAMiF,EAAWgD,EAAK2jB,MAAMmI,gBAAuB/zB,GAClCiI,EAAKnO,cAAcs+B,QAAQp8B,EAAOiJ,EAASE,aAC7C8C,EAAKyjB,kBACnBif,GAAiB,EACjBC,GAAuB,EAEzB,GAEID,EACHpwC,KAAKyI,UAAUzI,KAAKy3B,QAAQwW,oBAD7B,CAMA,IAAwBqC,EACvBtwC,KAAKslC,qBAAqB5+B,KAAKjF,GAAO,GAD/BsjC,eAQP/kC,KAAKyI,UAJLzI,KAAKstC,SAASriC,OAAS,IACrBqlC,GAAuBA,EAAoB7qC,KAAOzF,KAAKstC,SAAS,IACjE+C,GAEcrwC,KAAKy3B,QAAQqW,YAGb,QAdhB,CA9BA,OANC9tC,KAAKyI,UAAU,QAoDjB,EAACnH,EAGDk3B,aAAA,SAAa7sB,GACZ,IAAMyH,EAAMme,EAAA,CAAA,EzCz3BN,CACN/jB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,IyCg3BR,GACC9C,EAAQlB,WAAWuB,OAAShM,KAAKgM,MACP,UAA1BL,EAAQjB,SAASC,KAChB,CACD,GAAIgB,EAAQlB,WAAW+4B,eA2BtB,OA1BApwB,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAOm9B,oBACZn9B,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAOo9B,2BACZp9B,EAAOtG,kBACPnB,GAGDyH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAOq9B,oBACZr9B,EAAO3G,WACPd,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAOs9B,2BACZ,EACA/kC,GAGDyH,EAAO3E,OAAS,GAET2E,EAGR,GAAIzH,EAAQlB,WAAWg4B,SA2BtB,OA1BArvB,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAOu9B,cACZv9B,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAOw9B,qBACZx9B,EAAOtG,kBACPnB,GAGDyH,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAOy9B,cACZ,EACAllC,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAO09B,qBACZ,EACAnlC,GAGDyH,EAAO3E,OAAS,GAET2E,CAET,MAAO,GAAIzH,EAAQlB,WAAW8lB,IAA6B,CAI1D,GAA8B,YAA1B5kB,EAAQjB,SAASC,KA0BpB,OAzBAyI,EAAO5F,iBAAmBxN,KAAK0yB,wBAC9B1yB,KAAKoT,OAAO29B,qBACZ39B,EAAO5F,iBACP7B,GAGDyH,EAAO9F,oBAAsBtN,KAAK6yB,uBACjC7yB,KAAKoT,OAAO49B,4BACZ59B,EAAO9F,oBACP3B,GAGDyH,EAAO/F,oBAAsBrN,KAAK0yB,wBACjC1yB,KAAKoT,OAAO69B,4BACZ79B,EAAO/F,oBACP1B,GAGDyH,EAAO7F,mBAAqBvN,KAAK6yB,uBAChC7yB,KAAKoT,OAAO89B,2BACZ99B,EAAO7F,mBACP5B,GAGDyH,EAAO3E,OAAS,GACT2E,EACD,GAA8B,eAA1BzH,EAAQjB,SAASC,KAc3B,OAbAyI,EAAOjG,gBAAkBnN,KAAK0yB,wBAC7B1yB,KAAKoT,OAAO+9B,wBACZ/9B,EAAOjG,gBACPxB,GAGDyH,EAAOhG,gBAAkBpN,KAAK6yB,uBAC7B7yB,KAAKoT,OAAOg+B,wBACZh+B,EAAOhG,gBACPzB,GAGDyH,EAAO3E,OAAS,GACT2E,EACD,GAA8B,UAA1BzH,EAAQjB,SAASC,KA0B3B,OAzBAyI,EAAO3G,WAAazM,KAAK6yB,uBACxB7yB,KAAKoT,OAAOi+B,mBACZj+B,EAAO3G,WACPd,GAGDyH,EAAOzG,WAAa3M,KAAK0yB,wBACxB1yB,KAAKoT,OAAOk+B,mBACZl+B,EAAOzG,WACPhB,GAGDyH,EAAOtG,kBAAoB9M,KAAK0yB,wBAC/B1yB,KAAKoT,OAAOm+B,0BACZn+B,EAAOtG,kBACPnB,GAGDyH,EAAOpG,kBAAoBhN,KAAK6yB,uBAC/B7yB,KAAKoT,OAAOo+B,0BACZp+B,EAAOpG,kBACPrB,GAGDyH,EAAO3E,OAAS,GACT2E,CAET,CAEA,OAAOA,CACR,EAAC45B,CAAA,CA55B+BC,CAAQna,ICrG5B2e,yBAAoB1e,GAAA0e,SAAAA,IAAA,QAAA1xC,EAAAizB,EAAAtW,UAAAzR,OAAAgoB,EAAA,IAAArwB,MAAAowB,GAAAE,EAAAA,EAAAA,EAAAF,EAAAE,IAAAD,EAAAC,GAAAxW,UAAAwW,GAEjBnzB,OAFiBA,EAAAgzB,EAAAluB,KAAA4X,MAAAsW,SAAAjnB,OAAAmnB,KAAAjzB,MAChC2K,KAAOohB,GAAU2lB,OAAM3xC,EACvBiM,KAAO,SAAQjM,CAAA,CAFiB4F,EAAA8rC,EAAA1e,OAEjBzxB,EAAAmwC,EAAAlwC,UAad,OAbcD,EACfs2B,MAAA,aAAUt2B,EACV42B,KAAA,aAAS52B,EACTiD,QAAA,WAAY,EAAAjD,EACZmD,UAAA,WAAc,EAAAnD,EACd+C,QAAA,WAAY,EAAA/C,EACZwC,YAAA,aAAgBxC,EAChB4C,OAAA,aAAW5C,EACX8C,UAAA,aAAc9C,EACdkC,YAAA,aAAgBlC,EAChB62B,QAAA,WAAY,EAAA72B,EACZk3B,aAAA,WACC,OAAAjH,EAAYkH,G1CpBN,CACNjrB,iBAAkB,UAClBH,oBAAqB,UACrBC,oBAAqB,EACrBC,mBAAoB,GACpBZ,WAAY,UACZG,kBAAmB,UACnBE,kBAAmB,EACnBP,WAAY,EACZU,gBAAiB,UACjBC,gBAAiB,EACjBqB,OAAQ,G0CUT,EAACgjC,CAAA,EAfuC1gB,ICJnC,SAAU4gB,GACfC,EACAnwB,EACAxf,EACA4vC,EACAC,GAEA,KAAOD,EAAQ5vC,GAAM,CACpB,GAAI4vC,EAAQ5vC,EAAO,IAAK,CACvB,IAAMkW,EAAI05B,EAAQ5vC,EAAO,EACnB2kB,EAAInF,EAAIxf,EAAO,EACf44B,EAAIz7B,KAAKgqB,IAAIjR,GACbZ,EAAI,GAAMnY,KAAKwsB,IAAK,EAAIiP,EAAK,GAC7BkX,EACL,GAAM3yC,KAAKQ,KAAMi7B,EAAItjB,GAAKY,EAAIZ,GAAMY,IAAMyO,EAAIzO,EAAI,EAAI,GAAK,EAAI,GAGhEw5B,GAAYC,EAAKnwB,EAFDriB,KAAK6X,IAAIhV,EAAM7C,KAAK4yC,MAAMvwB,EAAKmF,EAAIrP,EAAKY,EAAI45B,IAC3C3yC,KAAK4X,IAAI66B,EAAOzyC,KAAK4yC,MAAMvwB,GAAMtJ,EAAIyO,GAAKrP,EAAKY,EAAI45B,IAC7BD,EACxC,CAEA,IAAMpN,EAAIkN,EAAInwB,GACVzW,EAAI/I,EACJqJ,EAAIumC,EAKR,IAHAI,GAAKL,EAAK3vC,EAAMwf,GACZqwB,EAAQF,EAAIC,GAAQnN,GAAK,GAAGuN,GAAKL,EAAK3vC,EAAM4vC,GAEzC7mC,EAAIM,GAAG,CAIb,IAHA2mC,GAAKL,EAAK5mC,EAAGM,GACbN,IACAM,IACOwmC,EAAQF,EAAI5mC,GAAI05B,GAAK,GAAG15B,IAC/B,KAAO8mC,EAAQF,EAAItmC,GAAIo5B,GAAK,GAAGp5B,GAChC,CAE8B,IAA1BwmC,EAAQF,EAAI3vC,GAAOyiC,GACtBuN,GAAKL,EAAK3vC,EAAMqJ,GAGhB2mC,GAAKL,IADLtmC,EACaumC,GAGVvmC,GAAKmW,IAAGxf,EAAOqJ,EAAI,GACnBmW,GAAKnW,IAAGumC,EAAQvmC,EAAI,EACzB,CACD,CAEA,SAAS2mC,GAAQL,EAAU5mC,EAAWM,GACrC,IAAM6V,EAAMywB,EAAI5mC,GAChB4mC,EAAI5mC,GAAK4mC,EAAItmC,GACbsmC,EAAItmC,GAAK6V,CACV,CCvCA,SAAS+wB,GAASC,EAAYC,GAC7BC,GAASF,EAAM,EAAGA,EAAKG,SAASrnC,OAAQmnC,EAAQD,EACjD,CAGA,SAASE,GACRF,EACA1wB,EACAoiB,EACAuO,EACAG,GAEKA,IAAUA,EAAWC,GAAW,KACrCD,EAASE,KAAOzxB,SAChBuxB,EAASG,KAAO1xB,SAChBuxB,EAASI,MAAQ3xB,SACjBuxB,EAASK,MAAQ5xB,SAEjB,IAAK,IAAIhW,EAAIyW,EAAGzW,EAAI64B,EAAG74B,IAAK,CAC3B,IAAM6nC,EAAQV,EAAKG,SAAStnC,GAC5B8nC,GAAOP,EAAUJ,EAAKY,KAAOX,EAAOS,GAASA,EAC9C,CAEA,OAAON,CACR,CAEA,SAASO,GAAOn7B,EAASD,GAKxB,OAJAC,EAAE86B,KAAOrzC,KAAK4X,IAAIW,EAAE86B,KAAM/6B,EAAE+6B,MAC5B96B,EAAE+6B,KAAOtzC,KAAK4X,IAAIW,EAAE+6B,KAAMh7B,EAAEg7B,MAC5B/6B,EAAEg7B,KAAOvzC,KAAK6X,IAAIU,EAAEg7B,KAAMj7B,EAAEi7B,MAC5Bh7B,EAAEi7B,KAAOxzC,KAAK6X,IAAIU,EAAEi7B,KAAMl7B,EAAEk7B,MACrBj7B,CACR,CAEA,SAASq7B,GAAgBr7B,EAASD,GACjC,OAAOC,EAAE86B,KAAO/6B,EAAE+6B,IACnB,CACA,SAASQ,GAAgBt7B,EAASD,GACjC,OAAOC,EAAE+6B,KAAOh7B,EAAEg7B,IACnB,CAEA,SAASQ,GAASv7B,GACjB,OAAQA,EAAEg7B,KAAOh7B,EAAE86B,OAAS96B,EAAEi7B,KAAOj7B,EAAE+6B,KACxC,CACA,SAASS,GAAWx7B,GAMnB,OAAOA,EAAEg7B,KAAOh7B,EAAE86B,MAAQ96B,EAAEi7B,KAAOj7B,EAAE+6B,KACtC,CAkBA,SAASxqC,GAASyP,EAASD,GAC1B,OACCC,EAAE86B,MAAQ/6B,EAAE+6B,MAAQ96B,EAAE+6B,MAAQh7B,EAAEg7B,MAAQh7B,EAAEi7B,MAAQh7B,EAAEg7B,MAAQj7B,EAAEk7B,MAAQj7B,EAAEi7B,IAE1E,CAEA,SAASQ,GAAWz7B,EAASD,GAC5B,OACCA,EAAE+6B,MAAQ96B,EAAEg7B,MAAQj7B,EAAEg7B,MAAQ/6B,EAAEi7B,MAAQl7B,EAAEi7B,MAAQh7B,EAAE86B,MAAQ/6B,EAAEk7B,MAAQj7B,EAAE+6B,IAE1E,CAEA,SAASF,GAAWF,GACnB,MAAO,CACNA,SAAAA,EACA14B,OAAQ,EACRm5B,MAAM,EACNN,KAAMzxB,SACN0xB,KAAM1xB,SACN2xB,MAAO3xB,SACP4xB,MAAO5xB,SAET,CAKA,SAASqyB,GACRzB,EACA3vC,EACA4vC,EACA15B,EACA25B,GAIA,IAFA,IAAMwB,EAAQ,CAACrxC,EAAM4vC,GAEdyB,EAAMroC,QAIZ,MAHA4mC,EAAQyB,EAAMzZ,QACd53B,EAAOqxC,EAAMzZ,QAEO1hB,GAApB,CAEA,IAAMgqB,EAAMlgC,EAAO7C,KAAKsjB,MAAMmvB,EAAQ5vC,GAAQkW,EAAI,GAAKA,EACvDw5B,GAAYC,EAAKzP,EAAKlgC,EAAM4vC,EAAOC,GAEnCwB,EAAMnoC,KAAKlJ,EAAMkgC,EAAKA,EAAK0P,GAE7B,CAEA,IAAa0B,gBAAK,WAKjB,SAAAA,EAAYC,GAAkBxzC,KAJtByzC,iBACAC,EAAAA,KAAAA,wBACAntC,UAAI,EAIXvG,KAAKyzC,YAAcr0C,KAAK6X,IAAI,EAAGu8B,GAC/BxzC,KAAK0zC,YAAct0C,KAAK6X,IAAI,EAAG7X,KAAKsjB,KAAwB,GAAnB1iB,KAAKyzC,cAC9CzzC,KAAK0E,OACN,CAAC,IAAApD,EAAAiyC,EAAAhyC,iBAAAD,EAEDm8B,OAAA,SAAOD,GACN,IAAI2U,EAAOnyC,KAAKuG,KACVojC,EAAiB,GAEvB,IAAKyJ,GAAW5V,EAAM2U,GACrB,OAAOxI,EAMR,IAHA,IAAMyI,EAASpyC,KAAKoyC,OACduB,EAAgB,GAEfxB,GAAM,CACZ,IAAK,IAAInnC,EAAI,EAAGA,EAAImnC,EAAKG,SAASrnC,OAAQD,IAAK,CAC9C,IAAM6nC,EAAQV,EAAKG,SAAStnC,GACtB4oC,EAAYzB,EAAKY,KAAOX,EAAOS,GAASA,EAE1CO,GAAW5V,EAAMoW,KAChBzB,EAAKY,KAAMpJ,EAAOx+B,KAAK0nC,GAClB3qC,GAASs1B,EAAMoW,GAAY5zC,KAAK6zC,KAAKhB,EAAOlJ,GAChDgK,EAAcxoC,KAAK0nC,GAE1B,CACAV,EAAOwB,EAAc9Z,KACtB,CAEA,OAAO8P,CACR,EAACroC,EAEDwyC,SAAA,SAAStW,GACR,IAAI2U,EAAOnyC,KAAKuG,KAGhB,GADkB6sC,GAAW5V,EAAM2U,GAGlC,IADA,IAAMwB,EAAgB,GACfxB,GAAM,CACZ,IAAK,IAAInnC,EAAI,EAAGA,EAAImnC,EAAKG,SAASrnC,OAAQD,IAAK,CAC9C,IAAM6nC,EAAQV,EAAKG,SAAStnC,GACtB4oC,EAAYzB,EAAKY,KAAO/yC,KAAKoyC,OAAOS,GAASA,EAEnD,GAAIO,GAAW5V,EAAMoW,GAAY,CAChC,GAAIzB,EAAKY,MAAQ7qC,GAASs1B,EAAMoW,GAC/B,SAEDD,EAAcxoC,KAAK0nC,EACpB,CACD,CACAV,EAAOwB,EAAc9Z,KACtB,CAGD,OAAO,CACR,EAACv4B,EAEDgV,KAAA,SAAK/P,GACJ,GAAIA,EAAK0E,OAASjL,KAAK0zC,YACtB,IAAK,IAAI1oC,EAAI,EAAGA,EAAIzE,EAAK0E,OAAQD,IAChChL,KAAKuiC,OAAOh8B,EAAKyE,QAFnB,CAQA,IAAImnC,EAAOnyC,KAAK+zC,OAAOxtC,EAAK0O,QAAS,EAAG1O,EAAK0E,OAAS,EAAG,GAEzD,GAAKjL,KAAKuG,KAAK+rC,SAASrnC,OAGjB,GAAIjL,KAAKuG,KAAKqT,SAAWu4B,EAAKv4B,OAEpC5Z,KAAKg0C,WAAWh0C,KAAKuG,KAAM4rC,OACrB,CACN,GAAInyC,KAAKuG,KAAKqT,OAASu4B,EAAKv4B,OAAQ,CAEnC,IAAMq6B,EAAUj0C,KAAKuG,KACrBvG,KAAKuG,KAAO4rC,EACZA,EAAO8B,CACR,CAGAj0C,KAAKk0C,QAAQ/B,EAAMnyC,KAAKuG,KAAKqT,OAASu4B,EAAKv4B,OAAS,GAAG,EACxD,MAdC5Z,KAAKuG,KAAO4rC,CAPb,CAsBD,EAAC7wC,EAEDihC,OAAA,SAAO4R,GACNn0C,KAAKk0C,QAAQC,EAAMn0C,KAAKuG,KAAKqT,OAAS,EACvC,EAACtY,EAEDoD,MAAA,WACC1E,KAAKuG,KAAOisC,GAAW,GACxB,EAAClxC,EAED0F,OAAA,SAAOmtC,GAUN,IATA,IAIInpC,EACAopC,EALAjC,EAAoBnyC,KAAKuG,KACvBi3B,EAAOx9B,KAAKoyC,OAAO+B,GACnBppC,EAAO,GACPspC,EAAoB,GAGtBC,GAAU,EAGPnC,GAAQpnC,EAAKE,QAAQ,CAS3B,GARKknC,IAEJA,EAAOpnC,EAAK8uB,MACZua,EAASrpC,EAAKA,EAAKE,OAAS,GAC5BD,EAAIqpC,EAAQxa,MACZya,GAAU,GAGPnC,EAAKY,KAAM,CAGd,IAAM72B,EAAQi2B,EAAKG,SAASn2B,QAAQg4B,IAErB,IAAXj4B,IAEHi2B,EAAKG,SAASl2B,OAAOF,EAAO,GAC5BnR,EAAKI,KAAKgnC,GACVnyC,KAAKu0C,UAAUxpC,GAEjB,CAEKupC,GAAYnC,EAAKY,OAAQ7qC,GAASiqC,EAAM3U,GAOlC4W,GAETppC,IACDmnC,EAAOiC,EAAO9B,SAAStnC,GACvBspC,GAAU,GAEVnC,EAAO,MAXPpnC,EAAKI,KAAKgnC,GACVkC,EAAQlpC,KAAKH,GACbA,EAAI,EACJopC,EAASjC,EACTA,EAAOA,EAAKG,SAAS,GASvB,CACD,EAAChxC,EAEO8wC,OAAA,SAAU+B,GACjB,OAAOA,CACR,EAAC7yC,EAEOkzC,YAAA,SAAY78B,EAASD,GAC5B,OAAOC,EAAE86B,KAAO/6B,EAAE+6B,IACnB,EAACnxC,EACOmzC,YAAA,SAAY98B,EAASD,GAC5B,OAAOC,EAAE+6B,KAAOh7B,EAAEg7B,IACnB,EAACpxC,EAEOuyC,KAAA,SAAK1B,EAAYxI,GAExB,IADA,IAAMgK,EAAgB,GACfxB,GACFA,EAAKY,KAAMpJ,EAAOx+B,KAAIsR,MAAXktB,EAAewI,EAAKG,UAC9BqB,EAAcxoC,KAAIsR,MAAlBk3B,EAAsBxB,EAAKG,UAEhCH,EAAOwB,EAAc9Z,MAEtB,OAAO8P,CACR,EAACroC,EAEOyyC,OAAA,SAAOW,EAAezyC,EAAc4vC,EAAej4B,GAC1D,IAEIu4B,EAFEwC,EAAI9C,EAAQ5vC,EAAO,EACrB2yC,EAAI50C,KAAKyzC,YAGb,GAAIkB,GAAKC,EAIR,OADA1C,GADAC,EAAOK,GAAWkC,EAAMz/B,MAAMhT,EAAM4vC,EAAQ,IAC7B7xC,KAAKoyC,QACbD,EAGHv4B,IAEJA,EAASxa,KAAKsjB,KAAKtjB,KAAKgqB,IAAIurB,GAAKv1C,KAAKgqB,IAAIwrB,IAG1CA,EAAIx1C,KAAKsjB,KAAKiyB,EAAIv1C,KAAKC,IAAIu1C,EAAGh7B,EAAS,MAGxCu4B,EAAOK,GAAW,KACbO,MAAO,EACZZ,EAAKv4B,OAASA,EAId,IAAMi7B,EAAKz1C,KAAKsjB,KAAKiyB,EAAIC,GACnBE,EAAKD,EAAKz1C,KAAKsjB,KAAKtjB,KAAKQ,KAAKg1C,IAEpCvB,GAAYqB,EAAOzyC,EAAM4vC,EAAOiD,EAAI90C,KAAKw0C,aAEzC,IAAK,IAAIxpC,EAAI/I,EAAM+I,GAAK6mC,EAAO7mC,GAAK8pC,EAAI,CACvC,IAAMC,EAAS31C,KAAK4X,IAAIhM,EAAI8pC,EAAK,EAAGjD,GAEpCwB,GAAYqB,EAAO1pC,EAAG+pC,EAAQF,EAAI70C,KAAKy0C,aAEvC,IAAK,IAAInpC,EAAIN,EAAGM,GAAKypC,EAAQzpC,GAAKupC,EAAI,CACrC,IAAMG,EAAS51C,KAAK4X,IAAI1L,EAAIupC,EAAK,EAAGE,GAGpC5C,EAAKG,SAASnnC,KAAKnL,KAAK+zC,OAAOW,EAAOppC,EAAG0pC,EAAQp7B,EAAS,GAC3D,CACD,CAIA,OAFAs4B,GAASC,EAAMnyC,KAAKoyC,QAEbD,CACR,EAAC7wC,EAEO2zC,eAAA,SAAezX,EAAY2U,EAAY+C,EAAenqC,GAC7D,KACCA,EAAKI,KAAKgnC,IAENA,EAAKY,MAAQhoC,EAAKE,OAAS,IAAMiqC,GAHzB,CAWZ,IAJA,IAAIC,EAAUn0B,SACVo0B,EAAiBp0B,SACjBq0B,SAEKrqC,EAAI,EAAGA,EAAImnC,EAAKG,SAASrnC,OAAQD,IAAK,CAC9C,IAAM6nC,EAAQV,EAAKG,SAAStnC,GAEtBsqC,EAAOpC,GAASL,GAChB0C,GAjTY59B,EAiTe6lB,EAjTN9lB,EAiTYm7B,GA/SxCzzC,KAAK6X,IAAIS,EAAEi7B,KAAMh7B,EAAEg7B,MAAQvzC,KAAK4X,IAAIU,EAAE+6B,KAAM96B,EAAE86B,QAC9CrzC,KAAK6X,IAAIS,EAAEk7B,KAAMj7B,EAAEi7B,MAAQxzC,KAAK4X,IAAIU,EAAEg7B,KAAM/6B,EAAE+6B,OA8SG4C,GAI5CC,EAAcH,GACjBA,EAAiBG,EACjBJ,EAAUG,EAAOH,EAAUG,EAAOH,EAClCE,EAAaxC,GACH0C,IAAgBH,GAEtBE,EAAOH,IACVA,EAAUG,EACVD,EAAaxC,EAGhB,CAEAV,EAAOkD,GAAclD,EAAKG,SAAS,EACpC,CAnUF,IAAsB36B,EAASD,EAqU7B,OAAOy6B,CACR,EAAC7wC,EAEO4yC,QAAA,SAAQC,EAAYe,EAAeM,GAC1C,IAAMhY,EAAOgY,EAASrB,EAAOn0C,KAAKoyC,OAAO+B,GACnCsB,EAAqB,GAGrBtD,EAAOnyC,KAAKi1C,eAAezX,EAAMx9B,KAAKuG,KAAM2uC,EAAOO,GAOzD,IAJAtD,EAAKG,SAASnnC,KAAKgpC,GACnBrB,GAAOX,EAAM3U,GAGN0X,GAAS,GACXO,EAAWP,GAAO5C,SAASrnC,OAASjL,KAAKyzC,aAC5CzzC,KAAK01C,OAAOD,EAAYP,GACxBA,IAKFl1C,KAAK21C,oBAAoBnY,EAAMiY,EAAYP,EAC5C,EAAC5zC,EAGOo0C,OAAA,SAAOD,EAAoBP,GAClC,IAAM/C,EAAOsD,EAAWP,GAClBN,EAAIzC,EAAKG,SAASrnC,OAClB2b,EAAI5mB,KAAK0zC,YAEf1zC,KAAK41C,iBAAiBzD,EAAMvrB,EAAGguB,GAE/B,IAAMiB,EAAa71C,KAAK81C,kBAAkB3D,EAAMvrB,EAAGguB,GAE7CmB,EAAUvD,GACfL,EAAKG,SAASl2B,OAAOy5B,EAAY1D,EAAKG,SAASrnC,OAAS4qC,IAEzDE,EAAQn8B,OAASu4B,EAAKv4B,OACtBm8B,EAAQhD,KAAOZ,EAAKY,KAEpBb,GAASC,EAAMnyC,KAAKoyC,QACpBF,GAAS6D,EAAS/1C,KAAKoyC,QAEnB8C,EAAOO,EAAWP,EAAQ,GAAG5C,SAASnnC,KAAK4qC,GACtC/1C,KAACg0C,WAAW7B,EAAM4D,EAC5B,EAACz0C,EAEO0yC,WAAA,SAAW7B,EAAY4D,GAE9B/1C,KAAKuG,KAAOisC,GAAW,CAACL,EAAM4D,IAC9B/1C,KAAKuG,KAAKqT,OAASu4B,EAAKv4B,OAAS,EACjC5Z,KAAKuG,KAAKwsC,MAAO,EACjBb,GAASlyC,KAAKuG,KAAMvG,KAAKoyC,OAC1B,EAAC9wC,EAEOw0C,kBAAA,SAAkB3D,EAAYvrB,EAAWguB,GAKhD,IAJA,IAAI14B,EAxXoBvE,EAASD,EAC5B+6B,EACAC,EACAC,EACAC,EAqXDoD,EAAah1B,SACbm0B,EAAUn0B,SAELhW,EAAI4b,EAAG5b,GAAK4pC,EAAIhuB,EAAG5b,IAAK,CAChC,IAAMirC,EAAQ5D,GAASF,EAAM,EAAGnnC,EAAGhL,KAAKoyC,QAClC8D,EAAQ7D,GAASF,EAAMnnC,EAAG4pC,EAAG50C,KAAKoyC,QAElC+D,GAhYiBx+B,EAgYUs+B,EAhYDv+B,EAgYQw+B,EA/XpCzD,EAAOrzC,KAAK6X,IAAIU,EAAE86B,KAAM/6B,EAAE+6B,MAC1BC,EAAOtzC,KAAK6X,IAAIU,EAAE+6B,KAAMh7B,EAAEg7B,MAC1BC,EAAOvzC,KAAK4X,IAAIW,EAAEg7B,KAAMj7B,EAAEi7B,MAC1BC,EAAOxzC,KAAK4X,IAAIW,EAAEi7B,KAAMl7B,EAAEk7B,MAEzBxzC,KAAK6X,IAAI,EAAG07B,EAAOF,GAAQrzC,KAAK6X,IAAI,EAAG27B,EAAOF,IA2X7C4C,EAAOpC,GAAS+C,GAAS/C,GAASgD,GAGpCC,EAAUH,GACbA,EAAaG,EACbj6B,EAAQlR,EAERmqC,EAAUG,EAAOH,EAAUG,EAAOH,GACxBgB,IAAYH,GAElBV,EAAOH,IACVA,EAAUG,EACVp5B,EAAQlR,EAGX,CAEA,OAAOkR,GAAS04B,EAAIhuB,CACrB,EAACtlB,EAGOs0C,iBAAA,SAAiBzD,EAAYvrB,EAAWguB,GAC/C,IAAMJ,EAAcrC,EAAKY,KAAO/yC,KAAKw0C,YAAcxB,GAC7CyB,EAActC,EAAKY,KAAO/yC,KAAKy0C,YAAcxB,GACnCjzC,KAAKo2C,eAAejE,EAAMvrB,EAAGguB,EAAGJ,GAChCx0C,KAAKo2C,eAAejE,EAAMvrB,EAAGguB,EAAGH,IAK/CtC,EAAKG,SAAS+D,KAAK7B,EAErB,EAAClzC,EAGO80C,eAAA,SACPjE,EACAvrB,EACAguB,EACA9C,GAEAK,EAAKG,SAAS+D,KAAKvE,GAOnB,IALA,IAAMM,EAASpyC,KAAKoyC,OACdkE,EAAWjE,GAASF,EAAM,EAAGvrB,EAAGwrB,GAChCmE,EAAYlE,GAASF,EAAMyC,EAAIhuB,EAAGguB,EAAGxC,GACvCoE,EAASrD,GAAWmD,GAAYnD,GAAWoD,GAEtCvrC,EAAI4b,EAAG5b,EAAI4pC,EAAIhuB,EAAG5b,IAAK,CAC/B,IAAM6nC,EAAQV,EAAKG,SAAStnC,GAC5B8nC,GAAOwD,EAAUnE,EAAKY,KAAOX,EAAOS,GAASA,GAC7C2D,GAAUrD,GAAWmD,EACtB,CAEA,IAAK,IAAItrC,EAAI4pC,EAAIhuB,EAAI,EAAG5b,GAAK4b,EAAG5b,IAAK,CACpC,IAAM6nC,EAAQV,EAAKG,SAAStnC,GAC5B8nC,GAAOyD,EAAWpE,EAAKY,KAAOX,EAAOS,GAASA,GAC9C2D,GAAUrD,GAAWoD,EACtB,CAEA,OAAOC,CACR,EAACl1C,EAEOq0C,oBAAA,SAAoBnY,EAAYzyB,EAAcmqC,GAErD,IAAK,IAAIlqC,EAAIkqC,EAAOlqC,GAAK,EAAGA,IAC3B8nC,GAAO/nC,EAAKC,GAAIwyB,EAElB,EAACl8B,EAEOizC,UAAA,SAAUxpC,GAEjB,IAAK,IAAyB0rC,EAArBzrC,EAAID,EAAKE,OAAS,EAAaD,GAAK,EAAGA,IACf,IAA5BD,EAAKC,GAAGsnC,SAASrnC,OAChBD,EAAI,GACPyrC,EAAW1rC,EAAKC,EAAI,GAAGsnC,UACdl2B,OAAOq6B,EAASt6B,QAAQpR,EAAKC,IAAK,GACrChL,KAAK0E,QAEZwtC,GAASnnC,EAAKC,GAAIhL,KAAKoyC,OAG1B,EAACmB,CAAA,CAzZgB,GCnILmD,gBAAY,WAKxB,SAAAA,EAAYxiC,GAAgClU,KAJpC22C,UACAC,EAAAA,KAAAA,qBACAC,cAAQ,EAGf72C,KAAK22C,KAAO,IAAIpD,GACfr/B,GAAWA,EAAQs/B,WAAat/B,EAAQs/B,WAAa,GAEtDxzC,KAAK42C,SAAW,IAAIE,IACpB92C,KAAK62C,SAAW,IAAIC,GACrB,CAAC,IAAAx1C,EAAAo1C,EAAAn1C,iBAAAD,EAEOy1C,QAAA,SAAQprC,EAA+B6xB,GAC9Cx9B,KAAK42C,SAASl4B,IAAI/S,EAAQlG,GAAiB+3B,GAC3Cx9B,KAAK62C,SAASn4B,IAAI8e,EAAM7xB,EAAQlG,GACjC,EAACnE,EAEO8wC,OAAA,SAAOzmC,GACd,IAGIf,EAHEosC,EAAuB,GACvBC,EAAsB,GAG5B,GAA8B,YAA1BtrC,EAAQjB,SAASC,KACpBC,EAAce,EAAQjB,SAASE,YAAY,QACrC,GAA8B,eAA1Be,EAAQjB,SAASC,KAC3BC,EAAce,EAAQjB,SAASE,gBACrBe,IAA0B,UAA1BA,EAAQjB,SAASC,KAG3B,MAAU,IAAAjF,MAAM,mDAFhBkF,EAAc,CAACe,EAAQjB,SAASE,YAGjC,CAEA,IAAK,IAAII,EAAI,EAAGA,EAAIJ,EAAYK,OAAQD,IACvCisC,EAAU9rC,KAAKP,EAAYI,GAAG,IAC9BgsC,EAAW7rC,KAAKP,EAAYI,GAAG,IAGhC,IAAMksC,EAAS93C,KAAK4X,IAAGyF,MAARrd,KAAY63C,GACrBE,EAAS/3C,KAAK6X,IAAGwF,MAARrd,KAAY63C,GAI3B,MAAO,CACNxE,KAJcrzC,KAAK4X,IAAGyF,MAARrd,KAAY43C,GAK1BtE,KAAMwE,EACNvE,KALcvzC,KAAK6X,IAAGwF,MAARrd,KAAY43C,GAM1BpE,KAAMuE,EAER,EAAC71C,EAEDihC,OAAA,SAAO52B,GACN,GAAI3L,KAAK42C,SAAS7oC,IAAIsB,OAAO1D,EAAQlG,KACpC,MAAM,IAAIC,MAAM,0BAEjB,IAAM83B,EAAOx9B,KAAKoyC,OAAOzmC,GACzB3L,KAAK+2C,QAAQprC,EAAS6xB,GACtBx9B,KAAK22C,KAAKpU,OAAO/E,EAClB,EAACl8B,EAEDgV,KAAA,SAAKzK,GAAgC,IAAA9L,EAAAC,KAC9BsW,EAAe,GACf8gC,EAAuB,IAAIt2C,IACjC+K,EAAS7I,QAAQ,SAAC2I,GACjB,IAAM6xB,EAAOz9B,EAAKqyC,OAAOzmC,GAEzB,GADA5L,EAAKg3C,QAAQprC,EAAS6xB,GAClB4Z,EAAQxpC,IAAIyB,OAAO1D,EAAQlG,KAC9B,UAAUC,oCAAoCiG,EAAQlG,IAEvD2xC,EAAQ5yC,IAAI6K,OAAO1D,EAAQlG,KAC3B6Q,EAAKnL,KAAKqyB,EACX,GACAx9B,KAAK22C,KAAKrgC,KAAKA,EAChB,EAAChV,EAED6+B,OAAA,SAAOx0B,GACN3L,KAAKgH,OAAO2E,EAAQlG,IACpB,IAAM+3B,EAAOx9B,KAAKoyC,OAAOzmC,GACzB3L,KAAK+2C,QAAQprC,EAAS6xB,GACtBx9B,KAAK22C,KAAKpU,OAAO/E,EAClB,EAACl8B,EAED0F,OAAA,SAAO87B,GACN,IAAMqP,EAAOnyC,KAAK42C,SAAS7oC,IAAI+0B,GAC/B,IAAKqP,EACJ,MAAM,IAAIzsC,MAASo9B,EAA+C,wCAGnE9iC,KAAK22C,KAAK3vC,OAAOmrC,EAClB,EAAC7wC,EAEDoD,MAAA,WACC1E,KAAK22C,KAAKjyC,OACX,EAACpD,EAEDm8B,OAAA,SAAO9xB,GAA6B,IAAA1F,EACnCjG,KACA,OADcA,KAAK22C,KAAKlZ,OAAOz9B,KAAKoyC,OAAOzmC,IAC9BpG,IAAI,SAAC4sC,GACjB,OAAOlsC,EAAK4wC,SAAS9oC,IAAIokC,EAC1B,EACD,EAAC7wC,EAEDwyC,SAAA,SAASnoC,GACR,YAAYgrC,KAAK7C,SAAS9zC,KAAKoyC,OAAOzmC,GACvC,EAAC+qC,CAAA,CAxGuB,GCsCZW,GAAoB,CAChC1pC,MAAO,WAAiB,MC1CjB,uCAAuCgd,QAAQ,QAAS,SAAUyT,GACxE,IAAMr4B,EAAqB,GAAhB3G,KAAKk4C,SAAiB,EAEjC,OADU,KAALlZ,EAAWr4B,EAAS,EAAJA,EAAW,GACvBiT,SAAS,GACnB,EDsC4C,EAC5CmZ,UAAW,SAAC1sB,GAAa,MAAmB,iBAAPA,GAAiC,KAAdA,EAAGwF,MAAa,GAG5DssC,gBACZ,WAAA,SAAAA,EAAYh3C,GAWL8xB,KAAAA,gBAECmlB,EAAAA,KAAAA,oBAEAC,kBAAY,EAAAz3C,KAEZqxB,WAAK,EAAArxB,KAKL03C,UAAgC,WAAQ,EArB/C13C,KAAKqxB,MAAQ,CAAA,EACbrxB,KAAKy3C,aAAe,IAAIf,GAIxB12C,KAAKw3C,SAAUj3C,IAA6B,IAAnBA,EAAOi3C,QAChCx3C,KAAKqyB,WACJ9xB,GAAUA,EAAO8xB,WAAa9xB,EAAO8xB,WAAaglB,EACpD,CAAC,IAAA/1C,EAAAi2C,EAAAh2C,iBAAAD,EAeOwT,MAAA,SAAS6iC,GAChB,OAAOC,KAAKC,MAAMD,KAAKE,UAAUH,GAClC,EAACr2C,EAEDqM,MAAA,WACC,OAAW3N,KAACqyB,WAAW1kB,OACxB,EAACrM,EAEDsM,IAAA,SAAInI,GACH,OAAOwI,QAAQjO,KAAKqxB,MAAM5rB,GAC3B,EAACnE,EAEDgV,KAAA,SACC/P,EACAwxC,GAAoE,IAAAh4C,EAEpEC,KAAA,GAAoB,IAAhBuG,EAAK0E,OAAT,CAKA,IAAM+sC,EAAah4C,KAAK8U,MAAMvO,GAI9ByxC,EAAWh1C,QAAQ,SAAC2I,GACfA,QAAQlG,KACXkG,EAAQlG,GAAK1F,EAAKsyB,WAAW1kB,SAG1B5N,EAAKy3C,UACH7rC,EAAQlB,WAAWwtC,UAGvBvnB,GAAiB/kB,EAAQlB,WAAWwtC,WAFpCtsC,EAAQlB,WAAWwtC,WAAa,IAAIrnB,KAKhCjlB,EAAQlB,WAAWytC,UAGvBxnB,GAAiB/kB,EAAQlB,WAAWytC,WAFpCvsC,EAAQlB,WAAWytC,WAAa,IAAItnB,KAKvC,GAEA,IAAMnnB,EAAuB,GAC7BuuC,EAAWh1C,QAAQ,SAAC2I,GACnB,IAAMlG,EAAKkG,EAAQlG,GACnB,GAAIsyC,IACaA,EAAkBpsC,GAKjC,UAAUjG,MACSD,kBAAAA,aAAamyC,KAAKE,UAAUnsC,IAMjD,GAAI5L,EAAK6N,IAAInI,GACZ,MAAU,IAAAC,MAAK,wCAAyCD,GAGzD1F,EAAKsxB,MAAM5rB,GAAMkG,EACjBlC,EAAQ0B,KAAK1F,EACd,GACAzF,KAAKy3C,aAAanhC,KAAK0hC,GACvBh4C,KAAK03C,UAAUjuC,EAAS,SAnDxB,CAoDD,EAACnI,EAEDm8B,OAAA,SACCD,EACAD,GAAmDt3B,IAAAA,EAEnDjG,KAAM6L,EAAW7L,KAAKy3C,aAAaha,OAAOD,GAAMj4B,IAAI,SAACE,GAAE,OAAKQ,EAAKorB,MAAM5rB,EAAG,GAC1E,OACQzF,KAAK8U,MADTyoB,EACe1xB,EAAS0xB,OAAOA,GAEhB1xB,EAEpB,EAACvK,EAEDuwB,iBAAA,SAAiBC,GAChB9xB,KAAK03C,UAAY,SAACxX,EAAKiY,GACtBrmB,EAASoO,EAAKiY,EACf,CACD,EAAC72C,EAEDk4B,gBAAA,SAAkD/zB,GACjD,IAAMkG,EAAU3L,KAAKqxB,MAAM5rB,GAC3B,IAAKkG,EACJ,MAAM,IAAIjG,kCACmBD,EAAE,gCAGhC,OAAWzF,KAAC8U,MAAMnJ,EAAQjB,SAC3B,EAACpJ,EAEDqhC,kBAAA,SAAkBl9B,GACjB,IAAMkG,EAAU3L,KAAKqxB,MAAM5rB,GAC3B,IAAKkG,EACJ,MAAU,IAAAjG,MACmBD,4BAAAA,EAAkC,kCAGhE,OAAOzF,KAAK8U,MAAMnJ,EAAQlB,WAC3B,EAACnJ,EAED03B,eAAA,SACCof,GAAsEzuC,IAAAA,EAEtE3J,KAAMkgC,EAAmB,GACzBkY,EAAmBp1C,QAAQ,SAAAlD,GAAG,IAAA2F,EAAE3F,EAAF2F,GAAI4E,EAAQvK,EAARuK,SAAUgC,EAAKvM,EAALuM,MACrCV,EAAUhC,EAAK0nB,MAAM5rB,GAE3B,IAAKkG,EACJ,MAAU,IAAAjG,MAAK,yBACWD,EAA8B,8BAIzDy6B,EAAI/0B,KAAK1F,GAETkG,EAAQlB,WAAWJ,GAAYgC,EAG3B1C,EAAK6tC,UACR7rC,EAAQlB,WAAWytC,WAAa,IAAItnB,KAEtC,GAEI5wB,KAAK03C,WACR13C,KAAK03C,UAAUxX,EAAK,SAEtB,EAAC5+B,EAEDy3B,eAAA,SACCsf,GAAyE,IAAA3qC,EAAA1N,KAEnEkgC,EAAmB,GACzBmY,EAAmBr1C,QAAQ,SAAA4D,GAAG,IAAAnB,EAAEmB,EAAFnB,GAAIiF,EAAQ9D,EAAR8D,SACjCw1B,EAAI/0B,KAAK1F,GAET,IAAMkG,EAAU+B,EAAK2jB,MAAM5rB,GAE3B,IAAKkG,EACJ,MAAM,IAAIjG,MACgBD,yBAAAA,EAA8B,8BAIzDkG,EAAQjB,SAAWgD,EAAKoH,MAAMpK,GAE9BgD,EAAK+pC,aAAatX,OAAOx0B,GAGrB+B,EAAK8pC,UACR7rC,EAAQlB,WAAWytC,WAAa,IAAItnB,KAEtC,GAEI5wB,KAAK03C,WACR13C,KAAK03C,UAAUxX,EAAK,SAEtB,EAAC5+B,EAEDg3B,OAAA,SACCzsB,GAGG,IAAAysC,EAAAt4C,KAEGkgC,EAAmB,GAwCzB,OAvCAr0B,EAAS7I,QAAQ,SAAAspC,GAA6B,IACzC2L,EADevtC,EAAQ4hC,EAAR5hC,SAAUD,EAAU6hC,EAAV7hC,WAEzB8tC,EAAiBhnB,EAAA,CAAA,EAAQ9mB,GAEzB6tC,EAAKd,UACRS,GAAa,IAAIrnB,KAEbnmB,GACH8tC,EAAkBN,UACe,iBAAzBxtC,EAAWwtC,UACfxtC,EAAWwtC,UACXA,EACJM,EAAkBL,UACe,iBAAzBztC,EAAWytC,UACfztC,EAAWytC,UACXD,GAEJM,EAAoB,CAAEN,UAAAA,EAAWC,UAAWD,IAI9C,IAAMxyC,EAAK6yC,EAAK3qC,QACVhC,EAAU,CACflG,GAAAA,EACAkF,KAAM,UACND,SAAAA,EACAD,WAAY8tC,GAGbD,EAAKjnB,MAAM5rB,GAAMkG,EACjB2sC,EAAKb,aAAalV,OAAO52B,GAEzBu0B,EAAI/0B,KAAK1F,EACV,GAEIzF,KAAK03C,WACR13C,KAAK03C,UAAS,GAAA5rC,OAAKo0B,GAAM,UAGnBA,CACR,EAAC5+B,EAED,OAAA,SAAO4+B,GAAgBsY,IAAAA,EACtBtY,KAAAA,EAAIl9B,QAAQ,SAACyC,GACZ,IAAI+yC,EAAKnnB,MAAM5rB,GAId,MAAU,IAAAC,MAAM,kDAHT8yC,EAAKnnB,MAAM5rB,GAClB+yC,EAAKf,aAAazwC,OAAOvB,EAI3B,GAEIzF,KAAK03C,WACR13C,KAAK03C,UAAS5rC,GAAAA,OAAKo0B,GAAM,SAE3B,EAAC5+B,EAEDm3C,QAAA,eAAOC,EAAA14C,KACN,OAAOA,KAAK8U,MAAMvK,OAAOC,KAAKxK,KAAKqxB,OAAO9rB,IAAI,SAACE,GAAE,OAAKizC,EAAKrnB,MAAM5rB,EAAG,GACrE,EAACnE,EAEDoD,MAAA,WACC1E,KAAKqxB,MAAQ,CAAA,EACbrxB,KAAKy3C,aAAa/yC,OACnB,EAACpD,EAED4M,KAAA,WACC,OAAO3D,OAAOC,KAAKxK,KAAKqxB,OAAOpmB,MAChC,EAACssC,CAAA,CA3QD,GE1CK,SAAUoB,GAAwBC,GACvC,IAAMve,EAASue,EAAQhuC,YACnBiuC,EAAQ,EACZ,GAAIxe,GAAUA,EAAOpvB,OAAS,EAAG,CAChC4tC,GAASz5C,KAAK68B,IAAI6c,GAASze,EAAO,KAClC,IAAK,IAAIrvB,EAAI,EAAGA,EAAIqvB,EAAOpvB,OAAQD,IAClC6tC,GAASz5C,KAAK68B,IAAI6c,GAASze,EAAOrvB,IAEpC,CACA,OAAO6tC,CACR,CAEA,IAAME,GAAUllB,kBACVmlB,GAAc55C,KAAKiiB,GAAK,IAE9B,SAASy3B,GAASze,GACjB,IAAM4e,EAAe5e,EAAOpvB,OAE5B,GAAIguC,GAAgB,EACnB,OACD,EAKA,IAHA,IAAIJ,EAAQ,EAER7tC,EAAI,EACDA,EAAIiuC,GAUVJ,IANCxe,EAAOrvB,EAAI,GAAKiuC,GAAgBjuC,EAAI,GAAKiuC,EAAejuC,EAAI,GAIxC,GAAKguC,GAPZ3e,EAAOrvB,GAKA,GAAKguC,IAIG55C,KAAKkiB,IARnB+Y,EAAOrvB,EAAI,IAAMiuC,EAAe,EAAIjuC,EAAI,GAKhC,GAAKguC,IAK5BhuC,IAGD,OAAO6tC,EAAQE,EAChB,CC5Ca,ICswBPG,GAAkB,CACvBnoB,sBAAAA,GACAzwB,qBAAAA,kCAvsBc,WAmBd,SAAA64C,EAAYjlC,GAKX,IAAAnU,EAvBOq5C,KAAAA,KAAAA,YAGAC,EAAAA,KAAAA,kBACAC,cAAQ,EAAAt5C,KACRu5C,UAAW,EACXC,KAAAA,YACAC,EAAAA,KAAAA,4BASAC,yBAAmB,EAQ1B15C,KAAKs5C,SAAWplC,EAAQylC,QAExB35C,KAAKq5C,MAAQ,IAAI5H,GAGjB,IAAMmI,EAAuB,IAAI94C,IAG3B+4C,EAAW3lC,EAAQ4lC,MAAMC,OAE5B,SAACC,EAASC,GACZ,GAAIL,EAAqBhsC,IAAIqsC,EAAYjuC,MACxC,UAAUtG,MAA4Bu0C,sBAAAA,EAAYjuC,KAAI,kBAIvD,OAFA4tC,EAAqBp1C,IAAIy1C,EAAYjuC,MACrCguC,EAAQC,EAAYjuC,MAAQiuC,EACrBD,CACR,EAAG,CAAE,GAGCE,EAAW3vC,OAAOC,KAAKqvC,GAG7B,GAAwB,IAApBK,EAASjvC,OACZ,MAAM,IAAIvF,MAAM,qBAIjBw0C,EAASl3C,QAAQ,SAACgJ,GACjB,GAAI6tC,EAAS7tC,GAAMrB,OAASohB,GAAUoH,OAAtC,CAGA,GAAIpzB,EAAK25C,oBACR,MAAM,IAAIh0C,MAAM,gDAEhB3F,EAAK25C,oBAAsB1tC,CAJ5B,CAMD,GAEAhM,KAAKo5C,OAAM7nB,EAAQsoB,CAAAA,EAAAA,EAAU,CAAAM,OAAQn6C,KAAKq5C,QAC1Cr5C,KAAKy5C,gBAAkB,CACtBtB,OAAQ,GACR7J,OAAQ,GACRJ,SAAU,GACVpW,OAAQ,GACRsiB,MAAO,IAERp6C,KAAKw5C,OAAS,IAAIjC,GAAwB,CACzCC,UAAStjC,EAAQsjC,QACjBnlB,WAAYne,EAAQme,WAAane,EAAQme,gBAAaprB,IAGvD,IAAMozC,EAAa,SAClBna,GAKA,IAAMhjB,EAAkC,GAElCjK,EAAYlT,EAAKy5C,OAAOf,UAAUlb,OAAO,SAACvC,GAC/C,OAAIkF,EAAI9mB,SAAS4hB,EAAEv1B,MAClByX,EAAQ/R,KAAK6vB,IAEd,EAGD,GAEA,MAAO,CAAE9d,QAAAA,EAASjK,UAAAA,EACnB,EAEMgf,EAAW,SAACK,GACZvyB,EAAKw5C,UAIVx5C,EAAK05C,gBAAgB3hB,OAAO90B,QAAQ,SAACC,GACpCA,EAASqvB,EACV,EACD,EAEMR,EAA+B,SAACoO,EAAKz+B,GAC1C,GAAK1B,EAAKw5C,SAAV,CAIAx5C,EAAK05C,gBAAgBtB,OAAOn1C,QAAQ,SAACC,GACpCA,EAASi9B,EAAKz+B,EACf,GAEA,IAAA64C,EAA+BD,EAAWna,GAAlChjB,EAAOo9B,EAAPp9B,QAASjK,EAASqnC,EAATrnC,UAEH,WAAVxR,EACH1B,EAAKu5C,SAAS9vC,OACb,CACCgC,QAAS0R,EACTrT,WAAY,GACZoJ,UAAAA,EACAhJ,QAAS,IAEVlK,EAAKw6C,iBAEc,WAAV94C,EACV1B,EAAKu5C,SAAS9vC,OACb,CACCgC,QAAS,GACT3B,WAAY,GACZoJ,UAAAA,EACAhJ,QAASiT,GAEVnd,EAAKw6C,iBAEc,WAAV94C,EACV1B,EAAKu5C,SAAS9vC,OACb,CAAEgC,QAAS,GAAI3B,WAAYq2B,EAAKjtB,UAAAA,EAAWhJ,QAAS,IACpDlK,EAAKw6C,iBAEc,YAAV94C,GACV1B,EAAKu5C,SAAS9vC,OACb,CAAEgC,QAAS,GAAI3B,WAAY,GAAIoJ,UAAAA,EAAWhJ,QAAS,IACnDlK,EAAKw6C,gBApCP,CAuCD,EAEMxoB,EAAW,SAACS,GACjB,GAAKzyB,EAAKw5C,SAAV,CAIAx5C,EAAK05C,gBAAgBnL,OAAOtrC,QAAQ,SAACC,GACpCA,EAASuvB,EACV,GAEA,IAAAgoB,EAA+BH,EAAW,CAAC7nB,IAE3CzyB,EAAKu5C,SAAS9vC,OACb,CAAEgC,QAAS,GAAI3B,WAAY,GAAIoJ,UAHNunC,EAATvnC,UAG0BhJ,QAH5BuwC,EAAPt9B,SAIPnd,EAAKw6C,gBAVN,CAYD,EAEMvoB,EAAa,SAACO,GACnB,GAAKxyB,EAAKw5C,SAAV,CAIAx5C,EAAK05C,gBAAgBvL,SAASlrC,QAAQ,SAACC,GACtCA,GACD,GAEA,IAAAw3C,EAA+BJ,EAAW,CAAC9nB,IAAnCrV,EAAOu9B,EAAPv9B,QAKJA,GACHnd,EAAKu5C,SAAS9vC,OACb,CACCgC,QAAS,GACT3B,WAAY,GACZoJ,UAVuBwnC,EAATxnC,UAWdhJ,QAASiT,GAEVnd,EAAKw6C,gBAnBP,CAsBD,EAGAhwC,OAAOC,KAAKxK,KAAKo5C,QAAQp2C,QAAQ,SAAC03C,GACjC36C,EAAKq5C,OAAOsB,GAAQt6C,SAAS,CAC5B4L,KAAM0uC,EACNrpB,MAAOtxB,EAAKy5C,OACZ/wC,UAAW1I,EAAKu5C,SAAS7wC,UAAUxE,KAAKlE,EAAKu5C,UAC7ClxC,QAASrI,EAAKu5C,SAASlxC,QAAQnE,KAAKlE,EAAKu5C,UACzC9wC,UAAWzI,EAAKu5C,SAAS9wC,UAAUvE,KAAKlE,EAAKu5C,UAC7ClwC,qBAAsBrJ,EAAKu5C,SAASlwC,qBAAqBnF,KACxDlE,EAAKu5C,UAENxnB,SAAUA,EACVC,SAAUA,EACVC,WAAYA,EACZC,SAAUA,EACV5wB,oBAAqBtB,EAAKu5C,SAASp2C,0BAErC,EACD,CAAC,IAAA5B,EAAA63C,EAAA53C,UAqMA43C,OArMA73C,EAEOq5C,aAAA,WACP,IAAK36C,KAAKu5C,SACT,MAAM,IAAI7zC,MAAM,4BAElB,EAACpE,EAEOi5C,cAAA,eAAat0C,EAAAjG,KACd46C,EAEF,CAAA,EAkBJ,OAhBArwC,OAAOC,KAAKxK,KAAKo5C,QAAQp2C,QAAQ,SAACgJ,GACjC4uC,EAAW5uC,GAAQ,SAACL,GAEnB,OACC1F,EAAKyzC,qBACL/tC,EAAQlB,WAAW8lB,IAEZtqB,EAAKmzC,OAAOnzC,EAAKyzC,qBAAqBlhB,aAAav0B,KACzDgC,EAAKmzC,OAAOnzC,EAAKyzC,qBADXzzC,CAEL0F,GAII1F,EAAKmzC,OAAOptC,GAAMwsB,aAAav0B,KAAKgC,EAAKmzC,OAAOptC,GAAhD/F,CAAuD0F,EAC/D,CACD,GACOivC,CACR,EAACt5C,EAEOu5C,mBAAA,SAAA/6C,EAQPoU,GANC,IAAA1R,EAAG1C,EAAH0C,IACAC,EAAG3C,EAAH2C,IAOK0uB,EACLjd,QAAuCjN,IAA5BiN,EAAQid,gBAChBjd,EAAQid,gBACR,GAEE2pB,GACL5mC,QAA4CjN,IAAjCiN,EAAQ4mC,sBAChB5mC,EAAQ4mC,qBAGNtyC,EAAYxI,KAAKs5C,SAAS9wC,UAAUvE,KAAKjE,KAAKs5C,UAC9ClxC,EAAUpI,KAAKs5C,SAASlxC,QAAQnE,KAAKjE,KAAKs5C,UAE1CyB,EAAa3yC,EAAQ5F,EAAKC,GAE1B+6B,EAAOU,GAAoB,CAChC11B,UAAAA,EACAH,MAAO0yC,EACP5pB,gBAAAA,IAOD,OAJiBnxB,KAAKw5C,OAAO/b,OAAOD,GAIpBD,OAAO,SAAC5xB,GACvB,GACCmvC,IACCnvC,EAAQlB,WAAW8lB,KACnB5kB,EAAQlB,WAA4C,gBAErD,SAGD,GAA8B,UAA1BkB,EAAQjB,SAASC,KAAkB,CACtC,IAAMqwC,EAAmBrvC,EAAQjB,SAASE,YACpCqwC,EAAU7yC,EAAQ4yC,EAAiB,GAAIA,EAAiB,IAE9D,OADiBz7C,EAAcw7C,EAAYE,GACzB9pB,CACnB,CAAO,GAA8B,eAA1BxlB,EAAQjB,SAASC,KAAuB,CAGlD,IAFA,IAAMC,EAA0Be,EAAQjB,SAASE,YAExCI,EAAI,EAAGA,EAAIJ,EAAYK,OAAS,EAAGD,IAAK,CAChD,IAAM+pB,EAAQnqB,EAAYI,GACpBm6B,EAAYv6B,EAAYI,EAAI,GAOlC,GANuBm5B,GACtB4W,EACA3yC,EAAQ2sB,EAAM,GAAIA,EAAM,IACxB3sB,EAAQ+8B,EAAU,GAAIA,EAAU,KAGZhU,EACpB,OACD,CACD,CACA,OAAO,CACR,CAMC,QAL4ByS,GAC3B,CAACphC,EAAKC,GACNkJ,EAAQjB,SAASE,mBAGlB,CAIF,EACD,EAACtJ,EAEO45C,cAAA,WAGP,GAFAl7C,KAAK26C,gBAEA36C,KAAK05C,oBACT,MAAM,IAAIh0C,MAAM,sCAcjB,OAXoB1F,KAAKm7C,YAGLn7C,KAAK05C,qBACxB15C,KAAKo7C,QAAQp7C,KAAK05C,qBAGA15C,KAAKo5C,OACvBp5C,KAAK05C,oBAIP,EAACp4C,EAWD+5C,cAAA,SACCrvC,EACAoH,GAGA,GADApT,KAAK26C,gBACA36C,KAAKo5C,OAAOptC,GAChB,MAAU,IAAAtG,MAAM,kCAIhB1F,KAAKo5C,OAAOptC,GAAqCoH,OAASA,CAC5D,EAAC9R,EASDg6C,YAAA,WAEC,OAAWt7C,KAACw5C,OAAOf,SACpB,EAACn3C,EAQDoD,MAAA,WACC1E,KAAK26C,eACL36C,KAAKs5C,SAAS50C,OACf,EAACpD,EA+BD65C,QAAA,WAEC,OAAOn7C,KAAKq5C,MAAMrtC,IACnB,EAAC1K,EASD85C,QAAA,SAAQpvC,GAGP,GAFAhM,KAAK26C,gBAED36C,KAAKo5C,OAAOptC,GAcf,MAAU,IAAAtG,MAAM,kCAThB1F,KAAKq5C,MAAMnhB,OAGXl4B,KAAKq5C,MAAQr5C,KAAKo5C,OAAOptC,GAGzBhM,KAAKq5C,MAAMzhB,OAKb,EAACt2B,EASDi6C,eAAA,SAAerb,GACdlgC,KAAK26C,eACL36C,KAAKw5C,cAActZ,EACpB,EAAC5+B,EASD+sC,cAAA,SAAc5oC,GACOzF,KAAKk7C,gBACb7M,cAAc5oC,EAC3B,EAACnE,EASDktC,gBAAA,SAAgB/oC,GACIzF,KAAKk7C,gBACb1M,gBAAgB/oC,EAC5B,EAACnE,EAUDk6C,aAAA,WACC,OAAOx7C,KAAKw5C,OAAO7rC,OACpB,EAACrM,EAQDm6C,WAAA,SAAWh2C,GACV,OAAWzF,KAACw5C,OAAO5rC,IAAInI,EACxB,EAACnE,EAWDo6C,YAAA,SAAY7vC,OAAgClC,EAAA3J,KAC3CA,KAAK26C,eAEmB,IAApB9uC,EAASZ,QAIbjL,KAAKw5C,OAAOljC,KAAKzK,EAAU,SAACF,GAU3B,GATwBsC,QACvBtC,GACoB,iBAAZA,GACP,eAAgBA,GACc,iBAAvBA,EAAQlB,YACQ,OAAvBkB,EAAQlB,YACR,SAAUkB,EAAQlB,YAGC,CACpB,IAAMkxC,EACLhyC,EAAKyvC,OACHztC,EAA6ClB,WAAWuB,MAI3D,QAAK2vC,GAKcA,EAAYzpB,gBAAgBjuB,KAAK03C,EAC7CvN,CAAWziC,EACnB,CAGA,QACD,EACD,EAACrK,EAQDs2B,MAAA,WAAK,IAAAlqB,EAAA1N,KACJA,KAAKu5C,UAAW,EAChBv5C,KAAKs5C,SAASl5C,SAAS,CACtBiG,QAAS,WACRqH,EAAK+rC,gBAAgBW,MAAMp3C,QAAQ,SAACC,GACnCA,GACD,EACD,EACAW,SAAU,WACT,OAAO8J,EAAK2rC,MAAMphB,KACnB,EACA5zB,QAAS,SAAC5C,GACTiM,EAAK2rC,MAAMh1C,QAAQ5C,EACpB,EACA+B,YAAa,SAAC/B,GACbiM,EAAK2rC,MAAM71C,YAAY/B,EACxB,EACAgD,UAAW,SAAChD,GACXiM,EAAK2rC,MAAM50C,UAAUhD,EACtB,EACA8C,QAAS,SAAC9C,GACTiM,EAAK2rC,MAAM90C,QAAQ9C,EACpB,EACAqC,YAAa,SAACrC,EAAOgxB,GACpB/kB,EAAK2rC,MAAMv1C,YAAYrC,EAAOgxB,EAC/B,EACAvuB,OAAQ,SAACzC,EAAOgxB,GACf/kB,EAAK2rC,MAAMn1C,OAAOzC,EAAOgxB,EAC1B,EACAruB,UAAW,SAAC3C,EAAOgxB,GAClB/kB,EAAK2rC,MAAMj1C,UAAU3C,EAAOgxB,EAC7B,EACA5kB,QAAS,WAGRH,EAAK2rC,MAAMlhB,UAGXzqB,EAAK8rC,OAAO90C,OACb,GAEF,EAACpD,EASDs6C,oBAAA,SACCC,EACA3nC,GAIA,YAAY2mC,mBACX,CACCr4C,IAJmBq5C,EAAbr5C,IAKNC,IALmBo5C,EAARp5C,KAOZyR,EAEF,EAAC5S,EASDw6C,0BAAA,SACCr6C,EACAyS,GAEA,IAIM2nC,EAJqB77C,KAAKs5C,SAAS/2C,mBAAmB0B,KAC3DjE,KAAKs5C,SAGS/2C,CAAmBd,GAIlC,OAAe,OAAXo6C,EACI,QAGIhB,mBAAmBgB,EAAQ3nC,EACxC,EAAC5S,EAQD42B,KAAA,WACCl4B,KAAKu5C,UAAW,EAChBv5C,KAAKs5C,SAASn5C,YACf,EAACmB,EAUDyb,GAAA,SACCtb,EACAvB,GAEA,IAAMmb,EAAYrb,KAAKy5C,gBACtBh4C,GAEI4Z,EAAUjC,SAASlZ,IACvBmb,EAAUlQ,KAAKjL,EAEjB,EAACoB,EAUDy6C,IAAA,SACCt6C,EACAvB,GAEA,IAAMmb,EAAYrb,KAAKy5C,gBACtBh4C,GAEG4Z,EAAUjC,SAASlZ,IACtBmb,EAAUe,OAAOf,EAAUc,QAAQjc,GAAW,EAEhD,EAAC4N,EAAAqrC,EAAA70C,CAAAA,CAAAA,cAAAyJ,IAhTD,WACC,OAAW/N,KAACu5C,QACb,EAAC76B,IAOD,SAAY2O,GACX,MAAU,IAAA3nB,MAAM,uBACjB,KAACyzC,CAAA,CA1Za,qkBCjE4B,SAC1CP,EACAoD,GAEA,OAAOrD,GAAwBC,GAAWoD,CAC3C,sCFL2C,SAC1CpD,EACAoD,GAEA,OAAOrD,GAAwBC,GAAWoD,CAC3C"}