UNPKG

terra-draw

Version:

Frictionless map drawing across mapping provider

1 lines 220 kB
function t(){return t=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var o in i)({}).hasOwnProperty.call(i,o)&&(t[o]=i[o])}return t},t.apply(null,arguments)}const e="draw",i="edit",o="deleteCoordinate",n="insertMidpoint";var r;!function(t){t.Commit="commit",t.Provisional="provisional",t.Finish="finish"}(r||(r={}));const s="https://raw.githubusercontent.com/JamesLMilner/terra-draw/refs/heads/main/assets/markers/marker-blue.png",a={SELECTED:"selected",MID_POINT:"midPoint",SELECTION_POINT_FEATURE_ID:"selectionPointFeatureId",SELECTION_POINT:"selectionPoint"},d={MODE:"mode",CURRENTLY_DRAWING:"currentlyDrawing",EDITED:"edited",CLOSING_POINT:"closingPoint",SNAPPING_POINT:"snappingPoint",COORDINATE_POINT:"coordinatePoint",COORDINATE_POINT_FEATURE_ID:"coordinatePointFeatureId",COORDINATE_POINT_IDS:"coordinatePointIds",PROVISIONAL_COORDINATE_COUNT:"provisionalCoordinateCount",COMMITTED_COORDINATE_COUNT:"committedCoordinateCount",MARKER:"marker"},h=10;function l(t){return Boolean(t&&"object"==typeof t&&null!==t&&!Array.isArray(t))}function u(t){return Boolean(t&&"object"==typeof t&&"properties"in t&&"object"==typeof t.properties&&null!==t.properties&&"mode"in t.properties)}function c(t){return!!function(t){return"number"==typeof t&&!isNaN(new Date(t).valueOf())}(t)}const p="Feature is not a Polygon",g="Feature mode property does not match the mode being added to";var y;!function(t){t.Drawing="drawing",t.Select="select",t.Static="static",t.Render="render"}(y||(y={}));const m={rightClick:!0,contextMenu:!1,leftClick:!0,onDragStart:!0,onDrag:!0,onDragEnd:!0};class f{get state(){return this._state}set state(t){throw new Error("Please use the modes lifecycle methods")}get styles(){return this._styles}set styles(t){if("object"!=typeof t)throw new Error("Styling must be an object");this.onStyleChange&&this.onStyleChange([],"styling"),this._styles=t}registerBehaviors(t){}constructor(e,i=!1){this._state="unregistered",this._styles={},this.pointerEvents=m,this.behaviors=[],this.validate=void 0,this.pointerDistance=40,this.coordinatePrecision=void 0,this.undoRedoMaxStackSize=void 0,this.onStyleChange=void 0,this.store=void 0,this.projection="web-mercator",this.setDoubleClickToZoom=void 0,this.unproject=void 0,this.project=void 0,this.setCursor=void 0,this.isInitialUpdate=!1,this.type=y.Drawing,this.mode="base",i?this.isInitialUpdate=!0:this.updateOptions(t({},e))}updateOptions(e){null!=e&&e.styles&&(this.styles=t({},this._styles,e.styles)),null!=e&&e.pointerDistance&&(this.pointerDistance=e.pointerDistance),null!=e&&e.validation&&(this.validate=e&&e.validation),null!=e&&e.projection&&(this.projection=e.projection),void 0!==(null==e?void 0:e.pointerEvents)&&(this.pointerEvents=e.pointerEvents),null!=e&&e.modeName&&!0===this.isInitialUpdate&&(this.mode=e.modeName),this.isInitialUpdate=!1}allowPointerEvent(t,e){return"boolean"==typeof t?t:"function"!=typeof t||t(e)}setDrawing(){if("started"!==this._state)throw new Error("Mode must be unregistered or stopped to start");this._state="drawing"}setStarted(){if("stopped"!==this._state&&"registered"!==this._state&&"drawing"!==this._state&&"selecting"!==this._state)throw new Error("Mode must be unregistered or stopped to start");this._state="started",this.setDoubleClickToZoom(!1)}setStopped(){if("started"!==this._state)throw new Error("Mode must be started to be stopped");this._state="stopped",this.setDoubleClickToZoom(!0)}register(t){if("unregistered"!==this._state)throw new Error("Can not register unless mode is unregistered");this._state="registered",this.store=t.store,this.store.registerOnChange(t.onChange),this.setDoubleClickToZoom=t.setDoubleClickToZoom,this.project=t.project,this.unproject=t.unproject,this.onSelect=t.onSelect,this.onDeselect=t.onDeselect,this.setCursor=t.setCursor,this.onStyleChange=t.onChange,this.onFinish=t.onFinish,this.coordinatePrecision=t.coordinatePrecision,this.undoRedoMaxStackSize=t.undoRedoMaxStackSize,this.registerBehaviors({mode:t.mode,store:this.store,project:this.project,unproject:this.unproject,pointerDistance:this.pointerDistance,coordinatePrecision:t.coordinatePrecision,projection:this.projection,undoRedoMaxStackSize:t.undoRedoMaxStackSize})}validateFeature(t){return this.performFeatureValidation(t)}afterFeatureAdded(t){}afterFeatureUpdated(t){}performFeatureValidation(t){if("unregistered"===this._state)throw new Error("Mode must be registered");const e=function(t,e){let i;if(l(t))if(null==t.id)i="Feature has no id";else if("string"!=typeof t.id&&"number"!=typeof t.id)i="Feature must be string or number as per GeoJSON spec";else if(e(t.id))if(l(t.geometry))if(l(t.properties))if("string"==typeof t.geometry.type&&["Polygon","LineString","Point"].includes(t.geometry.type))if(Array.isArray(t.geometry.coordinates)){if(!t.properties.mode||"string"!=typeof t.properties.mode)return{valid:!1,reason:"Feature does not have a valid mode property"}}else i="Feature coordinates is not an array";else i="Feature is not Point, LineString or Polygon";else i="Feature has no properties";else i="Feature has no geometry";else i="Feature must match the id strategy (default is UUID4)";else i="Feature is not object";return i?{valid:!1,reason:i}:{valid:!0}}(t,this.store.idStrategy.isValidId);if(!e.valid)return e;if(this.validate){const i=this.validate(t,{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:r.Provisional});return{valid:e.valid&&i.valid,reason:i.reason}}return{valid:e.valid,reason:e.reason}}validateModeFeature(t,e){const i=this.performFeatureValidation(t);return i.valid?t.properties.mode!==this.mode?{valid:!1,reason:g}:e(t):{valid:!1,reason:i.reason}}onFinish(t,e){}onDeselect(t){}onSelect(t){}onKeyDown(t){}onKeyUp(t){}undo(){}clearHistory(){}undoSize(){return 0}redoSize(){return 0}redo(){}onMouseMove(t){}onClick(t){}onDragStart(t,e){}onDrag(t,e){}onDragEnd(t,e){}getHexColorStylingValue(t,e,i){return this.getStylingValue(t,e,i)}getNumericStylingValue(t,e,i){return this.getStylingValue(t,e,i)}getUrlStylingValue(t,e,i){return this.getStylingValue(t,e,i)}getStylingValue(t,e,i){return void 0===t?e:"function"==typeof t?null!=(o=t(i))?o:e:t;var o}}class v extends f{constructor(...t){super(...t),this.type=y.Select}}function C(t,e){const i=t=>t*Math.PI/180,o=i(t[1]),n=i(t[0]),r=i(e[1]),s=r-o,a=i(e[0])-n,d=Math.sin(s/2)*Math.sin(s/2)+Math.cos(o)*Math.cos(r)*Math.sin(a/2)*Math.sin(a/2);return 2*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))*6371e3/1e3}const P=6371008.8;function I(t){return t%360*Math.PI/180}function S(t){return t/6371.0088}function F(t){return t%(2*Math.PI)*180/Math.PI}function x(t,e=9){const i=Math.pow(10,e);return Math.round(t*i)/i}const O=57.29577951308232,M=.017453292519943295,w=6378137,E=(t,e)=>({x:0===t?0:t*M*w,y:0===e?0:Math.log(Math.tan(Math.PI/4+e*M/2))*w}),D=(t,e)=>({lng:0===t?0:O*(t/w),lat:0===e?0:(2*Math.atan(Math.exp(e/w))-Math.PI/2)*O});function k(t,e,i){const o=I(t[0]),n=I(t[1]),r=I(i),s=S(e),a=Math.asin(Math.sin(n)*Math.cos(s)+Math.cos(n)*Math.sin(s)*Math.cos(r));return[F(o+Math.atan2(Math.sin(r)*Math.sin(s)*Math.cos(n),Math.cos(s)-Math.sin(n)*Math.sin(a))),F(a)]}function _(t){const{center:e,radiusKilometers:i,coordinatePrecision:o}=t,n=t.steps?t.steps:64,r=[];for(let t=0;t<n;t++){const s=k(e,i,-360*t/n);r.push([x(s[0],o),x(s[1],o)])}return r.push(r[0]),{type:"Feature",geometry:{type:"Polygon",coordinates:[r]},properties:{}}}function b(t){let e;if("Polygon"===t.geometry.type)e=t.geometry.coordinates;else{if("LineString"!==t.geometry.type)throw new Error("Self intersects only accepts Polygons and LineStrings");e=[t.geometry.coordinates]}const i=[];for(let t=0;t<e.length;t++)for(let i=0;i<e[t].length-1;i++)for(let o=0;o<e.length;o++)for(let r=0;r<e[o].length-1;r++)n(t,i,o,r);return i.length>0;function o(t){return t<0||t>1}function n(t,n,r,s){const a=e[t][n],d=e[t][n+1],h=e[r][s],l=e[r][s+1],u=function(t,e,i,o){if(N(t,i)||N(t,o)||N(e,i)||N(o,i))return null;const n=t[0],r=t[1],s=e[0],a=e[1],d=i[0],h=i[1],l=o[0],u=o[1],c=(n-s)*(h-u)-(r-a)*(d-l);return 0===c?null:[((n*a-r*s)*(d-l)-(n-s)*(d*u-h*l))/c,((n*a-r*s)*(h-u)-(r-a)*(d*u-h*l))/c]}(a,d,h,l);if(null===u)return;let c,p;c=d[0]!==a[0]?(u[0]-a[0])/(d[0]-a[0]):(u[1]-a[1])/(d[1]-a[1]),p=l[0]!==h[0]?(u[0]-h[0])/(l[0]-h[0]):(u[1]-h[1])/(l[1]-h[1]),o(c)||o(p)||(u.toString(),i.push(u))}}function N(t,e){return t[0]===e[0]&&t[1]===e[1]}function T(t,e){return W(t[0])<=e&&W(t[1])<=e}function R(t){return 2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]&&Infinity!==t[0]&&Infinity!==t[1]&&(i=t[0])>=-180&&i<=180&&(e=t[1])>=-90&&e<=90;var e,i}function W(t){let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}const U="Feature has holes",L="Feature has less than 4 coordinates",B="Feature has invalid coordinates",A="Feature coordinates are not closed";function z(t,e){if("Polygon"!==t.geometry.type)return{valid:!1,reason:"Feature is not a Polygon"};if(1!==t.geometry.coordinates.length)return{valid:!1,reason:U};if(t.geometry.coordinates[0].length<4)return{valid:!1,reason:L};for(let i=0;i<t.geometry.coordinates[0].length;i++){if(!R(t.geometry.coordinates[0][i]))return{valid:!1,reason:B};if(!T(t.geometry.coordinates[0][i],e))return{valid:!1,reason:"Feature has coordinates with excessive precision"}}return(i=t.geometry.coordinates[0][0])[0]!==(o=t.geometry.coordinates[0][t.geometry.coordinates[0].length-1])[0]||i[1]!==o[1]?{valid:!1,reason:A}:{valid:!0};var i,o}function H(t,e){const i=z(t,e);return i.valid?b(t)?{valid:!1,reason:"Feature intersects itself"}:{valid:!0}:i}class G{constructor({store:t,mode:e,project:i,unproject:o,pointerDistance:n,coordinatePrecision:r,projection:s,undoRedoMaxStackSize:a}){this.store=void 0,this.mode=void 0,this.project=void 0,this.unproject=void 0,this.pointerDistance=void 0,this.coordinatePrecision=void 0,this.projection=void 0,this.undoRedoMaxStackSize=void 0,this.store=t,this.mode=e,this.project=i,this.unproject=o,this.pointerDistance=n,this.coordinatePrecision=r,this.projection=s,this.undoRedoMaxStackSize=a}}function V(t){const e=function(t){const e=t.coordinates[0];let i=0;for(let t=0;t<e.length-1;t++){const[o,n]=e[t],[r,s]=e[t+1];i+=(r-o)*(s+n)}return i<0}(t);if(!e)return{type:"Polygon",coordinates:[t.coordinates[0].reverse()]}}const j="insert-before",K="insert-after",Y="update",X="delete",$="replace";class q extends G{constructor(t,e){super(t),this.options=void 0,this.options=e}createPoint({coordinates:t,properties:e,context:i}){if((null==i?void 0:i.updateType)!==r.Finish||this.validateGeometryWithUpdateType({geometry:{type:"Point",coordinates:t},properties:e,updateType:r.Finish}))return this.handleCreateFeature({geometry:{type:"Point",coordinates:t},properties:e})}createLineString({coordinates:t,properties:e}){return this.handleCreateFeature({geometry:{type:"LineString",coordinates:t},properties:e})}createPolygon({coordinates:t,properties:e,context:i}){const o=V({type:"Polygon",coordinates:[t]}),n={type:"Polygon",coordinates:o?o.coordinates:[t]};if((null==i?void 0:i.updateType)!==r.Finish||this.validateGeometryWithUpdateType({geometry:n,properties:e,updateType:r.Finish}))return this.handleCreateFeature({geometry:n,properties:e})}createGuidancePoint({coordinate:t,type:e}){return this.createGuidancePoints({coordinates:[t],type:e})[0]}createGuidancePoints({coordinates:e,type:i,additionalProperties:o}){const n=e.map((e,n)=>({type:"Feature",geometry:{type:"Point",coordinates:e},properties:t({mode:this.mode,[i]:!0},o?o(n):{})}));return this.createFeatures(n)}updatePoint({featureId:t,coordinateMutations:e,propertyMutations:i,context:o}){return this.handleMutateFeature({type:"Point",featureId:t,coordinateMutations:e,propertyMutations:i,context:o})}updatePolygon({featureId:t,coordinateMutations:e,context:i,propertyMutations:o}){return this.handleMutateFeature({type:"Polygon",featureId:t,coordinateMutations:e,propertyMutations:o,context:i})}updateLineString({featureId:t,coordinateMutations:e,context:i,propertyMutations:o}){return this.handleMutateFeature({type:"LineString",featureId:t,coordinateMutations:e,propertyMutations:o,context:i})}deleteFeatureIfPresent(t){t&&this.store.has(t)&&this.store.delete([t])}deleteFeaturesIfPresent(t){if(0===t.length)return;const e=t.filter(t=>this.store.has(t));e.length&&this.store.delete(e)}setDeselected(t){const e=t.filter(t=>this.store.has(t)).map(t=>({featureId:t,properties:{[a.SELECTED]:!1}}));this.updateFeatureProperties(e)}setSelected(t){const{type:e}=this.store.getGeometryCopy(t),i={featureId:t,propertyMutations:{[a.SELECTED]:!0},context:{updateType:r.Commit}};"Polygon"===e?this.updatePolygon(i):"LineString"===e?this.updateLineString(i):"Point"===e&&this.updatePoint(i)}updateGuidancePoints(t){this.updateFeatureGeometries(t.map(({featureId:t,coordinate:e})=>({id:t,geometry:{type:"Point",coordinates:e}})))}handleCreateFeature({geometry:t,properties:e}){return this.createFeatureWithGeometry({geometry:t,properties:e})}handleMutateFeature({type:e,featureId:i,coordinateMutations:o,propertyMutations:n,context:s}){if(!this.mutateFeature({type:e,featureId:i,coordinateMutations:o,propertyMutations:n,context:s.updateType===r.Finish?t({},s,{correctRightHandRule:!0}):t({},s)}))return null;const a=this.buildFeatureWithGeometry(i);return s.updateType!==r.Finish||o||this.validateGeometryWithUpdateType({geometry:a.geometry,properties:a.properties,updateType:s.updateType})?a:null}mutateFeature({type:t,featureId:e,coordinateMutations:i,propertyMutations:o,context:n}){if(!e)return!1;const r=this.store.getGeometryCopy(e),s=this.store.getPropertiesCopy(e);if(r.type!==t)throw new Error(`${t} geometries cannot be updated on features with ${r.type} geometries`);if(i){let t=this.applyCoordinateMutations(r,i);if(n.correctRightHandRule&&"Polygon"===t.type){const e=V(t);e&&(t=e)}if(!this.validateGeometryWithUpdateType({geometry:t,properties:s,updateType:n.updateType}))return!1;this.updateFeatureGeometries([{id:e,geometry:t}])}return o&&this.updateFeatureProperties([{featureId:e,properties:o}]),!0}applyCoordinateMutations(e,i){if(this.isReplaceMutation(i))return t({},e,{coordinates:i.coordinates});if("Point"===e.type)throw new Error("Coordinate mutations are not supported for Point geometries");const o="Polygon"===e.type,n=o?e.coordinates[0].slice():e.coordinates.slice(),r=n.length,s=t=>{const e=t<0?r+t:t;if(e<0||e>=r)throw new RangeError(`Index ${t} (normalized to ${e}) is out of bounds`);return e},a=new Array(r).fill(void 0),d=Array.from({length:r},()=>[]),h=Array.from({length:r},()=>[]),l=[];for(const e of i){if(e.type===j||e.type===K){const t=e.index,i=t<0?r+t:t;if(i<0||i>r)throw new RangeError(`Index ${e.index} (normalized to ${i}) is out of bounds`);if(e.type===j){if(i>=r)throw new RangeError(`INSERT_BEFORE index ${e.index} (normalized to ${i}) is out of bounds for length ${r}`);d[i].push(e)}else i===r?l.push(e):h[i].push(e);continue}const i=s(e.index);a[i]=t({},e,{index:i})}const u=[];for(let t=0;t<r;t++){const e=d[t];for(const t of e)u.push(t.coordinate);const i=a[t];i?i.type===X||u.push(i.coordinate):u.push(n[t]);const o=h[t];for(const t of o)u.push(t.coordinate)}for(const t of l)u.push(t.coordinate);return t({},e,o?{coordinates:[u,...e.coordinates.slice(1)]}:{coordinates:u})}isReplaceMutation(t){return t.type===$}createFeatureWithGeometry({geometry:t,properties:e}){const[i]=this.createFeatures([{type:"Feature",geometry:t,properties:e}]);return{id:i,type:"Feature",properties:this.store.getPropertiesCopy(i),geometry:this.store.getGeometryCopy(i)}}validateGeometryWithUpdateType({geometry:t,properties:e,updateType:i}){return!this.options.validate||this.options.validate({type:"Feature",geometry:t,properties:e||{}},{project:this.project,unproject:this.unproject,coordinatePrecision:this.coordinatePrecision,updateType:i}).valid}buildFeatureWithGeometry(t){return{id:t,type:"Feature",properties:this.store.getPropertiesCopy(t),geometry:this.store.getGeometryCopy(t)}}createFeatures(t){return this.store.create(t)}updateFeatureGeometries(t){this.store.updateGeometry(t)}updateFeatureProperties(t){const e=t.map(({featureId:t,properties:e})=>Object.entries(e).map(([e,i])=>({id:t,property:e,value:i}))).flat();this.store.updateProperty(e)}}const Z={cancel:"Escape",finish:"Enter"},J={start:"crosshair"};class Q extends f{constructor(t){super(t,!0),this.mode="circle",this.center=void 0,this.endPosition=void 0,this.segments=64,this.currentCircleId=void 0,this.keyEvents=Z,this.cursors=J,this.startingRadiusKilometers=1e-5,this.cursorMovedAfterInitialCursorDown=!1,this.drawInteraction="click-move",this.drawType=void 0,this.mutateFeature=void 0,this.updateOptions(t)}updateOptions(e){super.updateOptions(e),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.startingRadiusKilometers&&(this.startingRadiusKilometers=e.startingRadiusKilometers),null!=e&&e.drawInteraction&&(this.drawInteraction=e.drawInteraction),null!=e&&e.segments&&(this.segments=e.segments<3?3:e.segments)}close(){if(void 0===this.currentCircleId||void 0===this.endPosition)return;if(!this.updateCircle(this.endPosition,r.Finish))return;const t=this.currentCircleId;this.cursorMovedAfterInitialCursorDown=!1,this.center=void 0,this.currentCircleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(t,{mode:this.mode,action:e})}beginDrawing(t,e="click"){this.center=[t.lng,t.lat],this.endPosition=[t.lng,t.lat];const i=_({center:this.center,radiusKilometers:this.startingRadiusKilometers,coordinatePrecision:this.coordinatePrecision}),o=this.mutateFeature.createPolygon({coordinates:i.geometry.coordinates[0],properties:{mode:this.mode,radiusKilometers:this.startingRadiusKilometers,[d.CURRENTLY_DRAWING]:!0}});o&&(this.currentCircleId=o.id,this.cursorMovedAfterInitialCursorDown=!1,this.drawType=e,this.setDrawing())}dragDrawAllowed(){return"click-drag"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction}moveDrawAllowed(){return"click-move"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onClick(t){this.moveDrawAllowed()&&("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))&&(this.center?this.center&&void 0!==this.currentCircleId&&(this.endPosition=[t.lng,t.lat],this.close()):this.beginDrawing(t))}onMouseMove(t){this.cursorMovedAfterInitialCursorDown=!0,this.endPosition=[t.lng,t.lat],this.updateCircle(this.endPosition,r.Provisional)}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()}onDragStart(t,e){"drawing"!==this.state&&this.allowPointerEvent(this.pointerEvents.onDragStart,t)&&this.dragDrawAllowed()&&(this.beginDrawing(t,"drag"),e(!1))}onDrag(t,e){this.allowPointerEvent(this.pointerEvents.onDrag,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&(this.cursorMovedAfterInitialCursorDown=!0,this.endPosition=[t.lng,t.lat],this.updateCircle(this.endPosition,r.Provisional))}onDragEnd(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&(this.endPosition=[t.lng,t.lat],this.close(),e(!0))}cleanUp(){const t=this.currentCircleId;this.center=void 0,this.currentCircleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t)}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return"Feature"===e.type&&"Polygon"===e.geometry.type&&e.properties.mode===this.mode?(i.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,i.polygonFillColor,e),i.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,i.polygonOutlineColor,e),i.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,i.polygonOutlineWidth,e),i.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,e),i.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,i.polygonFillOpacity,e),i.zIndex=h,i):i}validateFeature(t){return this.validateModeFeature(t,t=>H(t,this.coordinatePrecision))}updateCircle(t,i){if(void 0===this.currentCircleId||void 0===this.center)return;const o=i===r.Finish;let n,s;if(this.cursorMovedAfterInitialCursorDown)if(s=C(this.center,t),"web-mercator"===this.projection){const e=function(t,e){const i=1e3*C(t,e);if(0===i)return 1;const{x:o,y:n}=E(t[0],t[1]),{x:r,y:s}=E(e[0],e[1]);return Math.sqrt(Math.pow(r-o,2)+Math.pow(s-n,2))/i}(this.center,t);n=function(t){const{center:e,radiusKilometers:i,coordinatePrecision:o}=t,n=t.steps?t.steps:64,r=1e3*i,[s,a]=e,{x:d,y:h}=E(s,a),l=[];for(let t=0;t<n;t++){const e=360*t/n*Math.PI/180,i=r*Math.cos(e),s=r*Math.sin(e),[a,u]=[d+i,h+s],{lng:c,lat:p}=D(a,u);l.push([x(c,o),x(p,o)])}return l.push(l[0]),{type:"Feature",geometry:{type:"Polygon",coordinates:[l]},properties:{}}}({center:this.center,radiusKilometers:s*e,coordinatePrecision:this.coordinatePrecision,steps:this.segments})}else{if("globe"!==this.projection)throw new Error("Invalid projection");n=_({center:this.center,radiusKilometers:s,coordinatePrecision:this.coordinatePrecision,steps:this.segments})}const a={};return n&&s&&(a.radiusKilometers=s),o&&(a[d.CURRENTLY_DRAWING]=void 0),this.mutateFeature.updatePolygon({featureId:this.currentCircleId,coordinateMutations:n?{type:$,coordinates:n.geometry.coordinates}:void 0,propertyMutations:a,context:o?{updateType:i,action:e}:{updateType:i}})}afterFeatureUpdated(t){this.currentCircleId===t.id&&(this.cursorMovedAfterInitialCursorDown=!1,this.center=void 0,this.currentCircleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted())}registerBehaviors(t){this.mutateFeature=new q(t,{validate:this.validate})}}const tt=(t,e)=>{const{x:i,y:o}=t,{x:n,y:r}=e,s=n-i,a=r-o;return Math.sqrt(a*a+s*s)};function et(t,e){return t[0]===e[0]&&t[1]===e[1]}class it extends G{constructor(t){super(t)}getGeometryType(t){return this.store.getGeometryCopy(t).type}coordinateAtIndexIsIdentical({featureId:t,newCoordinate:e,index:i}){const o=this.store.getGeometryCopy(t);let n;if("Polygon"===o.type)n=o.coordinates[0][i];else if("LineString"===o.type)n=o.coordinates[i];else{if(0!==i)throw new Error("Point geometries only have one coordinate at index 0");n=o.coordinates}return et(e,n)}getGeometry(t){return this.store.getGeometryCopy(t)}getCoordinates(t){const{type:e,coordinates:i}=this.store.getGeometryCopy(t);return"Polygon"===e?i[0]:i}getCoordinate(t,e){const i=this.getCoordinates(t),o=e<0?i.length+e:e;if(o<0||o>=i.length)throw new RangeError(`Index ${e} (normalized to ${o}) is out of bounds`);return i[o]}getProperties(t){return this.store.getPropertiesCopy(t)}hasFeature(t){return this.store.has(t)}getAllFeatureIdsWhere(t){return this.store.copyAllWhere(t).map(({id:t})=>t)}}const ot={cancel:"Escape",finish:"Enter"},nt={start:"crosshair",close:"pointer"};class rt extends f{constructor(t){super(t,!0),this.mode="freehand",this.canClose=!1,this.currentId=void 0,this.closingPointId=void 0,this.minDistance=20,this.keyEvents=ot,this.cursors=nt,this.preventPointsNearClose=!0,this.autoClose=!1,this.autoCloseTimeout=500,this.hasLeftStartingPoint=!1,this.preventNewFeature=!1,this.drawInteraction="click-move",this.drawType=void 0,this.smoothing=0,this.mutateFeature=void 0,this.readFeature=void 0,this.updateOptions(t)}updateOptions(e){if(super.updateOptions(e),null!=e&&e.minDistance&&(this.minDistance=e.minDistance),void 0!==(null==e?void 0:e.smoothing)){const t=.999;this.smoothing=Math.min(Math.max(e.smoothing,0),t)}void 0!==(null==e?void 0:e.preventPointsNearClose)&&(this.preventPointsNearClose=e.preventPointsNearClose),void 0!==(null==e?void 0:e.autoClose)&&(this.autoClose=e.autoClose),null!=e&&e.autoCloseTimeout&&(this.autoCloseTimeout=e.autoCloseTimeout),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null!=e&&e.drawInteraction&&(this.drawInteraction=e.drawInteraction)}moveDrawAllowed(){return"click-move"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction}dragDrawAllowed(){return"click-drag"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction}beginDrawing(t,e="click"){const{id:i}=this.mutateFeature.createPolygon({coordinates:[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]],properties:{mode:this.mode,[d.CURRENTLY_DRAWING]:!0}});this.currentId=i,this.drawType=e,this.closingPointId=this.mutateFeature.createGuidancePoint({coordinate:[t.lng,t.lat],type:d.CLOSING_POINT}),this.canClose=!0,"drawing"!==this.state&&this.setDrawing()}addCoordinate(t){if(void 0===this.currentId||!1===this.canClose)return void this.setCursor(this.cursors.start);const[e,i]=this.readFeature.getCoordinate(this.currentId,-2),{x:o,y:n}=this.project(e,i),s=tt({x:o,y:n},{x:t.containerX,y:t.containerY}),[a,d]=this.readFeature.getCoordinate(this.currentId,0),{x:h,y:l}=this.project(a,d);if(tt({x:h,y:l},{x:t.containerX,y:t.containerY})<this.pointerDistance){if(this.autoClose&&this.hasLeftStartingPoint&&(this.preventNewFeature=!0,setTimeout(()=>{this.preventNewFeature=!1},this.autoCloseTimeout),this.close()),this.setCursor(this.cursors.close),this.preventPointsNearClose)return}else this.hasLeftStartingPoint=!0,this.setCursor(this.cursors.start);if(s<this.minDistance)return;const u=this.getSmoothedCoordinate([e,i],[t.lng,t.lat]);this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:j,index:-1,coordinate:u}],context:{updateType:r.Provisional}})}getSmoothedCoordinate(t,e){if(0===this.smoothing)return e;const[i,o]=t,[n,r]=e;return[i*this.smoothing+n*(1-this.smoothing),o*this.smoothing+r*(1-this.smoothing)]}close(){if(void 0===this.currentId)return;if(!this.mutateFeature.updatePolygon({featureId:this.currentId,propertyMutations:{[d.CURRENTLY_DRAWING]:void 0},context:{updateType:r.Finish,action:e}}))return;const t=this.currentId;this.mutateFeature.deleteFeatureIfPresent(this.closingPointId),this.canClose=!1,this.currentId=void 0,this.closingPointId=void 0,this.hasLeftStartingPoint=!1,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(t,{mode:this.mode,action:e})}start(){this.setStarted(),this.setCursor(this.cursors.start)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){this.moveDrawAllowed()&&"click"===this.drawType&&this.addCoordinate(t)}onClick(t){if(this.moveDrawAllowed()&&("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))){if(this.preventNewFeature)return;if(!1===this.canClose)return void this.beginDrawing(t);this.close()}}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&!0===this.canClose&&this.close()}onDragStart(t,e){"drawing"!==this.state&&(this.preventNewFeature||this.allowPointerEvent(this.pointerEvents.onDragStart,t)&&this.dragDrawAllowed()&&(this.beginDrawing(t,"drag"),e(!1)))}onDrag(t,e){this.allowPointerEvent(this.pointerEvents.onDrag,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&this.addCoordinate(t)}onDragEnd(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&(this.preventNewFeature=!0,setTimeout(()=>{this.preventNewFeature=!1},this.autoCloseTimeout),this.close(),e(!0))}cleanUp(){const t=this.currentId,e=this.closingPointId;this.closingPointId=void 0,this.currentId=void 0,this.canClose=!1,this.hasLeftStartingPoint=!1,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t),this.mutateFeature.deleteFeatureIfPresent(e)}styleFeature(e){const i=t({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return"Feature"===e.type&&"Polygon"===e.geometry.type&&e.properties.mode===this.mode?(i.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,i.polygonFillColor,e),i.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,i.polygonOutlineColor,e),i.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,e),i.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,i.polygonOutlineWidth,e),i.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,i.polygonFillOpacity,e),i.zIndex=h,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointWidth=this.getNumericStylingValue(this.styles.closingPointWidth,i.pointWidth,e),i.pointColor=this.getHexColorStylingValue(this.styles.closingPointColor,i.pointColor,e),i.pointOpacity=this.getNumericStylingValue(this.styles.closingPointOpacity,void 0===i.pointOpacity?1:i.pointOpacity,e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.closingPointOutlineColor,i.pointOutlineColor,e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.closingPointOutlineWidth,2,e),i.pointOutlineOpacity=this.getNumericStylingValue(this.styles.closingPointOutlineOpacity,void 0===i.pointOutlineOpacity?1:i.pointOutlineOpacity,e),i.zIndex=50,i):i}validateFeature(t){return this.validateModeFeature(t,t=>z(t,this.coordinatePrecision))}afterFeatureUpdated(t){this.currentId===t.id&&(this.mutateFeature.deleteFeatureIfPresent(this.closingPointId),this.canClose=!1,this.currentId=void 0,this.closingPointId=void 0,this.hasLeftStartingPoint=!1)}registerBehaviors(t){this.readFeature=new it(t),this.mutateFeature=new q(t,{validate:this.validate})}}function st({unproject:t,point:e,pointerDistance:i}){const o=i/2,{x:n,y:r}=e;return{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[[t(n-o,r-o),t(n+o,r-o),t(n+o,r+o),t(n-o,r+o),t(n-o,r-o)].map(t=>[t.lng,t.lat])]}}}class at extends G{constructor(t){super(t)}create(t){const{containerX:e,containerY:i}=t;return st({unproject:this.unproject,point:{x:e,y:i},pointerDistance:this.pointerDistance})}}class dt extends G{constructor(t){super(t)}measure(t,e){const{x:i,y:o}=this.project(e[0],e[1]);return tt({x:i,y:o},{x:t.containerX,y:t.containerY})}}class ht extends G{constructor(t,e,i){super(t),this.config=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.getSnappableCoordinateFirstClick=t=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode)).coordinate,this.getSnappableCoordinate=(t,e)=>this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode&&t.id!==e)).coordinate,this.config=t,this.pixelDistance=e,this.clickBoundingBox=i}getSnappable(t,e){const i=this.clickBoundingBox.create(t),o=this.store.search(i,e),n={featureId:void 0,featureCoordinateIndex:void 0,coordinate:void 0,minDist:Infinity};return o.forEach(e=>{let i;if("Polygon"===e.geometry.type)i=e.geometry.coordinates[0];else{if("LineString"!==e.geometry.type)return;i=e.geometry.coordinates}i.forEach((i,o)=>{const r=this.pixelDistance.measure(t,i);r<n.minDist&&r<this.pointerDistance&&(n.coordinate=i,n.minDist=r,n.featureId=e.id,n.featureCoordinateIndex=o)})}),n}}function lt(t,e,i){const o=I(t[0]),n=I(t[1]),r=I(i),s=S(e),a=Math.asin(Math.sin(n)*Math.cos(s)+Math.cos(n)*Math.sin(s)*Math.cos(r));return[F(o+Math.atan2(Math.sin(r)*Math.sin(s)*Math.cos(n),Math.cos(s)-Math.sin(n)*Math.sin(a))),F(a)]}function ut({x:t,y:e},i,o){const n=I(o);return{x:t+i*Math.cos(n),y:e+i*Math.sin(n)}}function ct(t,e){const i=I(t[0]),o=I(e[0]),n=I(t[1]),r=I(e[1]),s=Math.sin(o-i)*Math.cos(r),a=Math.cos(n)*Math.sin(r)-Math.sin(n)*Math.cos(r)*Math.cos(o-i);return F(Math.atan2(s,a))}function pt({x:t,y:e},{x:i,y:o}){const n=i-t,r=o-e;if(0===n&&0===r)return 0;let s=Math.atan2(r,n);return s*=180/Math.PI,s>180?s-=360:s<-180&&(s+=360),s}function gt(t){return(t+360)%360}function yt(t,e,i){const o=[],n=t.length;let r,s,a,d=0;for(let n=0;n<t.length&&!(e>=d&&n===t.length-1);n++){if(d>e&&0===o.length){if(r=e-d,!r)return o.push(t[n]),o;s=ct(t[n],t[n-1])-180,a=lt(t[n],r,s),o.push(a)}if(d>=i)return r=i-d,r?(s=ct(t[n],t[n-1])-180,a=lt(t[n],r,s),o.push(a),o):(o.push(t[n]),o);if(d>=e&&o.push(t[n]),n===t.length-1)return o;d+=C(t[n],t[n+1])}if(d<e&&t.length===n)throw new Error("Start position is beyond line");const h=t[t.length-1];return[h,h]}function mt(t){return t*(Math.PI/180)}function ft(t){return t*(180/Math.PI)}class vt extends G{constructor(t){super(t),this.config=void 0,this.config=t}generateInsertionCoordinates(t,e,i){const o=[t,e];let n=0;for(let t=0;t<o.length-1;t++)n+=C(o[0],o[1]);if(n<=i)return o;let r=n/i-1;Number.isInteger(r)||(r=Math.floor(r)+1);const s=[];for(let t=0;t<r;t++){const e=yt(o,i*t,i*(t+1));s.push(e)}const a=[];for(let t=0;t<s.length;t++)a.push(s[t][1]);return this.limitCoordinates(a)}generateInsertionGeodesicCoordinates(t,e,i){const o=C(t,e),n=function(t,e,i){const o=[],n=mt(t[1]),r=mt(t[0]),s=mt(e[1]),a=mt(e[0]);i+=1;const d=2*Math.asin(Math.sqrt(Math.sin((s-n)/2)**2+Math.cos(n)*Math.cos(s)*Math.sin((a-r)/2)**2));if(0===d||isNaN(d))return o;for(let t=0;t<=i;t++){const e=t/i,h=Math.sin((1-e)*d)/Math.sin(d),l=Math.sin(e*d)/Math.sin(d),u=h*Math.cos(n)*Math.cos(r)+l*Math.cos(s)*Math.cos(a),c=h*Math.cos(n)*Math.sin(r)+l*Math.cos(s)*Math.sin(a),p=h*Math.sin(n)+l*Math.sin(s);if(isNaN(u)||isNaN(c)||isNaN(p))continue;const g=Math.atan2(p,Math.sqrt(u**2+c**2)),y=Math.atan2(c,u);isNaN(g)||isNaN(y)||o.push([ft(y),ft(g)])}return o.slice(1,-1)}(t,e,Math.floor(o/i));return this.limitCoordinates(n)}limitCoordinates(t){return t.map(t=>[x(t[0],this.config.coordinatePrecision),x(t[1],this.config.coordinatePrecision)])}}function Ct(t,e){if("LineString"!==t.geometry.type)return{valid:!1,reason:"Feature is not a LineString"};if(t.geometry.coordinates.length<2)return{valid:!1,reason:"Feature has less than 2 coordinates"};for(let i=0;i<t.geometry.coordinates.length;i++){if(!R(t.geometry.coordinates[i]))return{valid:!1,reason:"Feature has invalid coordinates"};if(!T(t.geometry.coordinates[i],e))return{valid:!1,reason:"Feature has coordinates with excessive precision"}}return{valid:!0}}function Pt(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2))}function It(t,e){const i=function(t,e){const[i,o,n]=t,[r,s,a]=e;return i*r+o*s+n*a}(t,e)/(Pt(t)*Pt(e));return Math.acos(Math.min(Math.max(i,-1),1))}function St(t){const e=I(t[1]),i=I(t[0]);return[Math.cos(e)*Math.cos(i),Math.cos(e)*Math.sin(i),Math.sin(e)]}function Ft(t){const[e,i,o]=t,n=F(Math.asin(o));return[F(Math.atan2(i,e)),n]}function xt(t,e,i){const o=St(t),n=St(e),r=St(i),[s,a,d]=r,[h,l,u]=function(t,e){const[i,o,n]=t,[r,s,a]=e;return[o*a-n*s,n*r-i*a,i*s-o*r]}(o,n),c=l*d-u*a,p=u*s-h*d,g=h*a-l*s,y=g*l-p*u,m=c*u-g*h,f=p*h-c*l,v=1/Math.sqrt(Math.pow(y,2)+Math.pow(m,2)+Math.pow(f,2)),P=[y*v,m*v,f*v],I=[-1*y*v,-1*m*v,-1*f*v],S=It(o,n),F=It(o,P),x=It(n,P),O=It(o,I),M=It(n,I);let w;return w=F<O&&F<M||x<O&&x<M?P:I,It(o,w)>S||It(n,w)>S?C(Ft(w),Ft(o))<=C(Ft(w),Ft(n))?[Ft(o),!0,!1]:[Ft(n),!1,!0]:[Ft(w),!1,!1]}function Ot(t,e,i){const o=e.x-t.x,n=e.y-t.y,r=Math.max(0,Math.min(1,((i.x-t.x)*o+(i.y-t.y)*n)/(o*o+n*n)));return{x:t.x+r*o,y:t.y+r*n}}class Mt extends G{constructor(t,e,i){super(t),this.config=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.getSnappableCoordinateFirstClick=t=>{const e=this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode));return e.coordinate?[x(e.coordinate[0],this.config.coordinatePrecision),x(e.coordinate[1],this.config.coordinatePrecision)]:void 0},this.getSnappableCoordinate=(t,e)=>{const i=this.getSnappable(t,t=>Boolean(t.properties&&t.properties.mode===this.mode&&t.id!==e));return i.coordinate?[x(i.coordinate[0],this.config.coordinatePrecision),x(i.coordinate[1],this.config.coordinatePrecision)]:void 0},this.config=t,this.pixelDistance=e,this.clickBoundingBox=i}getSnappable(t,e){const i=this.clickBoundingBox.create(t),o=this.store.search(i,e),n={featureId:void 0,featureCoordinateIndex:void 0,coordinate:void 0,minDistance:Infinity};return o.forEach(e=>{let i;if("Polygon"===e.geometry.type)i=e.geometry.coordinates[0];else{if("LineString"!==e.geometry.type)return;i=e.geometry.coordinates}const o=[];for(let t=0;t<i.length-1;t++)o.push([i[t],i[t+1]]);let r;const s=[t.lng,t.lat];if("web-mercator"===this.config.projection?r=function(t,e){let i=[Infinity,Infinity],o=Infinity,n=0;for(let r of e){const s=r[0],a=r[1];let d,h=Infinity;const l=E(s[0],s[1]),u=E(a[0],a[1]),c=E(t[0],t[1]);if(s[0]===t[0]&&s[1]===t[1])d=s;else if(a[0]===t[0]&&a[1]===t[1])d=a;else{const{x:t,y:e}=Ot(l,u,c),{lng:i,lat:o}=D(t,e);d=[i,o]}d&&(h=tt(c,E(d[0],d[1])),h<o&&(i=d,o=h,n=e.indexOf(r)))}return Infinity===o?void 0:{coordinate:i,lineIndex:n,distance:o}}(s,o):"globe"===this.config.projection&&(r=function(t,e){let i=[Infinity,Infinity],o=Infinity,n=0;for(let r of e){const s=r[0],a=r[1];let d,h=Infinity;s[0]===t[0]&&s[1]===t[1]?d=s:a[0]===t[0]&&a[1]===t[1]?d=a:[d]=xt(s,a,t),d&&(h=C(t,d),h<o&&(i=d,o=h,n=e.indexOf(r)))}return Infinity===o?void 0:{coordinate:i,distance:o,lineIndex:n}}(s,o)),!r)return;const a=this.pixelDistance.measure(t,r.coordinate);a<n.minDistance&&a<this.pointerDistance&&(n.featureId=e.id,n.coordinate=[x(r.coordinate[0],this.config.coordinatePrecision),x(r.coordinate[1],this.config.coordinatePrecision)],n.featureCoordinateIndex=r.lineIndex,n.minDistance=a)}),n}}function wt(t){return Array.isArray(t)&&t.length>0&&Array.isArray(t[0])&&Array.isArray(t[0][0])}const Et=t=>wt(t)?t[0].slice(0,-1):t,Dt=t=>wt(t)?t[0]:t;class kt extends G{constructor(t,e,i,o){super(t),this.config=void 0,this.pixelDistance=void 0,this.mutateFeatureBehavior=void 0,this.readFeatureBehavior=void 0,this._startEndPoints=[],this.config=t,this.pixelDistance=e,this.mutateFeatureBehavior=i,this.readFeatureBehavior=o}get ids(){return this._startEndPoints.concat()}set ids(t){}create(t){if(this.ids.length)throw new Error("Opening and closing points already created");const e=wt(t),i=Dt(t);if(e){if(i.length<=3)throw new Error("Requires at least 4 coordinates");this._startEndPoints=this.mutateFeatureBehavior.createGuidancePoints({coordinates:[i[0],i[i.length-2]],type:d.CLOSING_POINT})}else this._startEndPoints=[this.mutateFeatureBehavior.createGuidancePoint({coordinate:i[i.length-2],type:d.CLOSING_POINT})]}delete(){this.ids.length&&(this.mutateFeatureBehavior.deleteFeaturesIfPresent(this.ids),this._startEndPoints=[])}updateOne(t,e){this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[t],coordinate:e}])}update(t){const e=Dt(t);1!==this.ids.length?2===this.ids.length&&this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[0],coordinate:e[0]},{featureId:this.ids[1],coordinate:e[e.length-3]}]):this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[0],coordinate:e[e.length-2]}])}isLineStringClosingPoint(t){if(1!==this.ids.length)return{isClosing:!1};const e=this.readFeatureBehavior.getGeometry(this.ids[0]);return{isClosing:this.pixelDistance.measure(t,e.coordinates)<this.pointerDistance}}isPolygonClosingPoints(t){if(2!==this.ids.length)return{isClosing:!1,isPreviousClosing:!1};const e=this.readFeatureBehavior.getGeometry(this.ids[0]),i=this.readFeatureBehavior.getGeometry(this.ids[1]),o=this.pixelDistance.measure(t,e.coordinates),n=this.pixelDistance.measure(t,i.coordinates);return{isClosing:o<this.pointerDistance,isPreviousClosing:n<this.pointerDistance}}}class _t extends G{constructor(t,e,i){super(t),this.readFeature=void 0,this.mutateFeature=void 0,this.readFeature=e,this.mutateFeature=i}createOrUpdate({featureId:t,featureCoordinates:e}){if(!this.readFeature.hasFeature(t))return void this.deleteOrphanedPoints(t);const i=Et(e),o=this.readFeature.getProperties(t),n=o.coordinatePointIds;if(n)if(n&&n.every(t=>this.readFeature.hasFeature(t))){const e=o.coordinatePointIds,n=e.map(t=>this.readFeature.getGeometry(t).coordinates);if(e.length!==i.length){this.deleteCoordinatePoints(e);const n=this.createPoints(i,o.mode,t);this.setFeatureCoordinatePoints(t,n)}else{const t=[];i.forEach((i,o)=>{i[0]===n[o][0]&&i[1]===n[o][1]||t.push({featureId:e[o],coordinate:i})}),this.mutateFeature.updateGuidancePoints(t)}}else{const e=n.filter(t=>this.readFeature.hasFeature(t));e.length&&this.deleteCoordinatePoints(e);const r=this.createPoints(i,o.mode,t);this.setFeatureCoordinatePoints(t,r)}else{const e=this.createPoints(i,o.mode,t);this.setFeatureCoordinatePoints(t,e)}}deletePointsByFeatureIds(t){for(const e of t)this.deleteIfPresent(e)}updateOneAtIndex(t,e,i){const o=this.readFeature.getProperties(t).coordinatePointIds;o&&0!==o.length&&void 0!==o[e]&&this.mutateFeature.updateGuidancePoints([{featureId:o[e],coordinate:i}])}updateAllInPlace({featureId:t,featureCoordinates:e}){const i=this.readFeature.getProperties(t);if(!i.coordinatePointIds)return;const o=Et(e);o.length===i.coordinatePointIds.length&&this.mutateFeature.updateGuidancePoints(i.coordinatePointIds.map((t,e)=>({featureId:t,coordinate:o[e]})))}createPoints(t,e,i){return this.mutateFeature.createGuidancePoints({coordinates:t,type:d.COORDINATE_POINT,additionalProperties:t=>({mode:e,[d.COORDINATE_POINT]:!0,[d.COORDINATE_POINT_FEATURE_ID]:i,index:t})})}setFeatureCoordinatePoints(t,e,i=r.Commit){const o=this.readFeature.getGeometryType(t),n={featureId:t,propertyMutations:{[d.COORDINATE_POINT_IDS]:e},context:{updateType:i}};if("Polygon"===o)this.mutateFeature.updatePolygon(n);else{if("LineString"!==o)throw new Error("Unsupported geometry type for coordinate points");this.mutateFeature.updateLineString(n)}}deleteCoordinatePoints(t){this.mutateFeature.deleteFeaturesIfPresent(t)}deleteIfPresent(t){if(!this.readFeature.hasFeature(t))return;const e=this.readFeature.getProperties(t).coordinatePointIds;e&&(this.deleteCoordinatePoints(e),this.setFeatureCoordinatePoints(t,null))}deleteOrphanedPoints(t){const e=this.readFeature.getAllFeatureIdsWhere(e=>e[d.COORDINATE_POINT_FEATURE_ID]===t);this.mutateFeature.deleteFeaturesIfPresent(e)}}class bt{constructor(t){this.undoHistory=[],this.redoHistory=[],this.cloneCoordinatesFunction=void 0,this.maxStackSize=void 0,this.cloneCoordinatesFunction=t=>this.cloneRecursively(t);const e=null==t?void 0:t.maxStackSize;this.maxStackSize=void 0!==e&&Number.isFinite(e)?Math.max(0,Math.floor(e)):Number.POSITIVE_INFINITY}setMaxStackSize(t){Number.isFinite(t)?(this.maxStackSize=Math.max(0,Math.floor(t)),this.trimHistoryToMax(this.undoHistory),this.trimHistoryToMax(this.redoHistory)):this.maxStackSize=Number.POSITIVE_INFINITY}trimHistoryToMax(t){if(Number.isFinite(this.maxStackSize))for(;t.length>this.maxStackSize;)t.shift()}pushUndoEntry(t){0!==this.maxStackSize&&(this.undoHistory.push(t),this.trimHistoryToMax(this.undoHistory))}pushRedoEntry(t){0!==this.maxStackSize&&(this.redoHistory.push(t),this.trimHistoryToMax(this.redoHistory))}cloneRecursively(e){return Array.isArray(e)?e.map(t=>this.cloneRecursively(t)):null!==e&&"object"==typeof e?t({},e):e}cloneCoordinates(t){return this.cloneCoordinatesFunction(t)}cloneEntry(t){return{featureCoordinates:this.cloneCoordinates(t.featureCoordinates),currentCoordinate:t.currentCoordinate}}clear(){this.undoHistory=[],this.redoHistory=[]}undoSize(){return this.undoHistory.length}redoSize(){return this.redoHistory.length}recordSnapshot(t){this.pushUndoEntry(this.cloneEntry(t)),this.redoHistory=[]}beginUndo(){const t=this.undoHistory.pop();if(!t)return;const e=this.cloneEntry(t);this.pushRedoEntry(e);const i=this.undoHistory[this.undoHistory.length-1];return{undoneEntry:e,previousEntry:i?this.cloneEntry(i):void 0}}takeRedo(){const t=this.redoHistory.pop();if(t)return this.cloneEntry(t)}commitRedo(t){this.pushUndoEntry(this.cloneEntry(t))}}const Nt={cancel:"Escape",finish:"Enter"},Tt={start:"crosshair",close:"pointer",dragStart:"grabbing",dragEnd:"crosshair"};class Rt extends f{constructor(t){super(t,!0),this.mode="linestring",this.currentCoordinate=0,this.currentId=void 0,this.keyEvents=Nt,this.snapping=void 0,this.cursors=Tt,this.mouseMove=!1,this.insertCoordinates=void 0,this.lastCommittedCoordinates=void 0,this.snappedPointId=void 0,this.lastMouseMoveEvent=void 0,this.showCoordinatePoints=!1,this.finishOnNthCoordinate=void 0,this.editable=!1,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedSnapType=void 0,this.editedInsertIndex=void 0,this.editedPointId=void 0,this.coordinateSnapping=void 0,this.insertPoint=void 0,this.lineSnapping=void 0,this.pixelDistance=void 0,this.clickBoundingBox=void 0,this.mutateFeature=void 0,this.readFeature=void 0,this.closingPoints=void 0,this.coordinatePoints=void 0,this.undoRedo=void 0,this.updateOptions(t)}updateOptions(e){if(super.updateOptions(e),void 0!==(null==e?void 0:e.finishOnNthCoordinate)&&Number.isInteger(e.finishOnNthCoordinate)&&e.finishOnNthCoordinate>1&&(this.finishOnNthCoordinate=Math.floor(e.finishOnNthCoordinate)),null!=e&&e.cursors&&(this.cursors=t({},this.cursors,e.cursors)),null!=e&&e.snapping&&(this.snapping=e.snapping),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=t({},this.keyEvents,e.keyEvents)),null!=e&&e.insertCoordinates&&(this.insertCoordinates=e.insertCoordinates),e&&e.editable&&(this.editable=e.editable),void 0!==(null==e?void 0:e.showCoordinatePoints))if(this.showCoordinatePoints=e.showCoordinatePoints,this.coordinatePoints&&!0===e.showCoordinatePoints)this.store.copyAllWhere(t=>t.mode===this.mode).forEach(t=>{this.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates})});else if(this.coordinatePoints&&!1===this.showCoordinatePoints){const t=this.store.copyAllWhere(t=>{var e;return t.mode===this.mode&&Boolean(null==(e=t[d.COORDINATE_POINT_IDS])?void 0:e.length)});this.coordinatePoints.deletePointsByFeatureIds(t.map(t=>t.id))}}shouldFinishOnCommit(t){return!!this.finishOnNthCoordinate&&Math.max(0,t.coordinates.length-1)>=this.finishOnNthCoordinate}updateSnappedCoordinate(t){const e=this.snapCoordinate(t);return e?(this.snappedPointId?this.mutateFeature.updateGuidancePoints([{featureId:this.snappedPointId,coordinate:e}]):this.snappedPointId=this.mutateFeature.createGuidancePoint({coordinate:e,type:d.SNAPPING_POINT}),t.lng=e[0],t.lat=e[1]):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),e}close(){if(void 0===this.currentId)return;const t=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:r.Finish,action:e},coordinateMutations:[{type:X,index:-1}],propertyMutations:{[d.CURRENTLY_DRAWING]:void 0}});if(!t)return;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:t.geometry.coordinates});const i=this.currentId;this.currentCoordinate=0,this.currentId=void 0,this.lastCommittedCoordinates=void 0,this.undoRedo.clear(),"drawing"===this.state&&this.setStarted(),this.closingPoints.delete(),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0),this.onFinish(i,{mode:this.mode,action:e})}generateInsertCoordinates(t,e){if(!this.insertCoordinates||!this.lastCommittedCoordinates)throw new Error("Not able to insert coordinates");if("amount"!==this.insertCoordinates.strategy)throw new Error("Strategy does not exist");const i=C(t,e)/(this.insertCoordinates.value+1);let o=[];return"globe"===this.projection?o=this.insertPoint.generateInsertionGeodesicCoordinates(t,e,i):"web-mercator"===this.projection&&(o=this.insertPoint.generateInsertionCoordinates(t,e,i)),o}createLine(t){const e=this.mutateFeature.createLineString({coordinates:[t,t],properties:{mode:this.mode,[d.CURRENTLY_DRAWING]:!0}});this.lastCommittedCoordinates=e.geometry.coordinates,this.currentId=e.id,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.setDrawing(),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:e.geometry.coordinates})}firstUpdateToLine(t){if(!this.currentId)return;this.setCursor(this.cursors.close);const e=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:r.Commit},coordinateMutations:[{type:K,index:-1,coordinate:t}]});e&&(this.closingPoints.create(e.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:e.geometry.coordinates}),this.lastCommittedCoordinates=e.geometry.coordinates,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.shouldFinishOnCommit(e.geometry)&&this.close())}updateToLine(t,e){if(!this.currentId)return;const{isClosing:i}=this.closingPoints.isLineStringClosingPoint(t);if(i)return void this.close();this.setCursor(this.cursors.close);const o=this.mutateFeature.updateLineString({featureId:this.curren