@sindicum/libre-draw 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LibreDraw.d.ts +11 -1
- package/dist/core/ModeContext.d.ts +36 -0
- package/dist/core/ModeManager.d.ts +2 -4
- package/dist/index.d.ts +3 -2
- package/dist/input/MouseInput.d.ts +4 -2
- package/dist/input/TouchInput.d.ts +6 -0
- package/dist/libre-draw.cjs +1 -1
- package/dist/libre-draw.cjs.map +1 -1
- package/dist/libre-draw.js +950 -758
- package/dist/libre-draw.js.map +1 -1
- package/dist/modes/DrawMode.d.ts +7 -29
- package/dist/modes/IdleMode.d.ts +4 -0
- package/dist/modes/Mode.d.ts +9 -0
- package/dist/modes/PolygonDragger.d.ts +23 -0
- package/dist/modes/SelectMode.d.ts +15 -126
- package/dist/modes/SelectionManager.d.ts +19 -0
- package/dist/modes/VertexEditor.d.ts +28 -0
- package/dist/rendering/RenderManager.d.ts +11 -1
- package/dist/rendering/SourceManager.d.ts +4 -0
- package/dist/types/events.d.ts +3 -2
- package/dist/types/features.d.ts +3 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/mode.d.ts +4 -0
- package/dist/types/options.d.ts +3 -0
- package/dist/types/style.d.ts +84 -0
- package/dist/utils/featureSnapshot.d.ts +21 -0
- package/dist/utils/geometry.d.ts +25 -0
- package/package.json +2 -4
package/dist/LibreDraw.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
2
2
|
import type { LibreDrawFeature, FeatureCollection, LibreDrawEventMap, LibreDrawOptions } from './types';
|
|
3
|
-
import type { ModeName } from './
|
|
3
|
+
import type { ModeName } from './types/mode';
|
|
4
4
|
/**
|
|
5
5
|
* LibreDraw - A MapLibre GL JS polygon drawing and editing library.
|
|
6
6
|
*
|
|
@@ -27,6 +27,8 @@ export declare class LibreDraw {
|
|
|
27
27
|
private toolbar;
|
|
28
28
|
private selectMode;
|
|
29
29
|
private destroyed;
|
|
30
|
+
private inputEnabled;
|
|
31
|
+
private handleStyleData;
|
|
30
32
|
/**
|
|
31
33
|
* Create a new LibreDraw instance attached to a MapLibre GL JS map.
|
|
32
34
|
*
|
|
@@ -365,10 +367,18 @@ export declare class LibreDraw {
|
|
|
365
367
|
* Create the toolbar UI.
|
|
366
368
|
*/
|
|
367
369
|
private createToolbar;
|
|
370
|
+
/**
|
|
371
|
+
* Apply map interaction settings declared by the active mode.
|
|
372
|
+
*/
|
|
373
|
+
private applyMapInteractions;
|
|
368
374
|
/**
|
|
369
375
|
* Update toolbar undo/redo button states.
|
|
370
376
|
*/
|
|
371
377
|
private updateToolbarHistoryState;
|
|
378
|
+
/**
|
|
379
|
+
* Clear selection-related rendering and state.
|
|
380
|
+
*/
|
|
381
|
+
private resetSelectionState;
|
|
372
382
|
/**
|
|
373
383
|
* Assert that this instance has not been destroyed.
|
|
374
384
|
* @throws LibreDrawError if destroyed.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LibreDrawEventMap } from '../types/events';
|
|
2
|
+
import type { Action, LibreDrawFeature, Position } from '../types/features';
|
|
3
|
+
/**
|
|
4
|
+
* Shared dependencies injected into modes.
|
|
5
|
+
*/
|
|
6
|
+
export interface ModeContext {
|
|
7
|
+
store: {
|
|
8
|
+
add(feature: LibreDrawFeature): LibreDrawFeature;
|
|
9
|
+
update(id: string, feature: LibreDrawFeature): void;
|
|
10
|
+
remove(id: string): LibreDrawFeature | undefined;
|
|
11
|
+
getById(id: string): LibreDrawFeature | undefined;
|
|
12
|
+
getAll(): LibreDrawFeature[];
|
|
13
|
+
};
|
|
14
|
+
history: {
|
|
15
|
+
push(action: Action): void;
|
|
16
|
+
};
|
|
17
|
+
events: {
|
|
18
|
+
emit<K extends keyof LibreDrawEventMap>(type: K, payload: LibreDrawEventMap[K]): void;
|
|
19
|
+
};
|
|
20
|
+
render: {
|
|
21
|
+
renderFeatures(): void;
|
|
22
|
+
renderPreview(coordinates: Position[]): void;
|
|
23
|
+
clearPreview(): void;
|
|
24
|
+
renderVertices(vertices: Position[], midpoints: Position[], highlightIndex?: number): void;
|
|
25
|
+
clearVertices(): void;
|
|
26
|
+
setSelectedIds(ids: string[]): void;
|
|
27
|
+
};
|
|
28
|
+
getScreenPoint(lngLat: {
|
|
29
|
+
lng: number;
|
|
30
|
+
lat: number;
|
|
31
|
+
}): {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
};
|
|
35
|
+
setDragPan(enabled: boolean): void;
|
|
36
|
+
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { Mode } from '../modes/Mode';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*/
|
|
5
|
-
export type ModeName = 'idle' | 'draw' | 'select';
|
|
2
|
+
import type { ModeName } from '../types/mode';
|
|
3
|
+
export type { ModeName } from '../types/mode';
|
|
6
4
|
/**
|
|
7
5
|
* Manages the active drawing mode and handles transitions between modes.
|
|
8
6
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { LibreDraw } from './LibreDraw';
|
|
2
2
|
export type { Position, PolygonGeometry, FeatureProperties, LibreDrawFeature, FeatureCollection, ActionType, Action, } from './types';
|
|
3
3
|
export type { LibreDrawEventMap, CreateEvent, UpdateEvent, DeleteEvent, SelectionChangeEvent, ModeChangeEvent, } from './types';
|
|
4
|
-
export type { LibreDrawOptions, ToolbarOptions, ToolbarPosition, ToolbarControls, } from './types';
|
|
4
|
+
export type { LibreDrawOptions, ToolbarOptions, ToolbarPosition, ToolbarControls, StyleConfig, PartialStyleConfig, } from './types';
|
|
5
5
|
export type { NormalizedInputEvent, InputType, } from './types';
|
|
6
|
-
export type { ModeName } from './
|
|
6
|
+
export type { ModeName } from './types';
|
|
7
7
|
export { LibreDrawError } from './core/errors';
|
|
8
|
+
export { DEFAULT_STYLE_CONFIG, mergeStyleConfig, } from './types';
|
|
@@ -17,9 +17,11 @@ export declare class MouseInput {
|
|
|
17
17
|
private map;
|
|
18
18
|
private callbacks;
|
|
19
19
|
private canvas;
|
|
20
|
+
private isPointerDown;
|
|
20
21
|
private handleMouseDown;
|
|
21
|
-
private
|
|
22
|
-
private
|
|
22
|
+
private handleMouseMoveCanvas;
|
|
23
|
+
private handleMouseMoveWindow;
|
|
24
|
+
private handleMouseUpWindow;
|
|
23
25
|
private handleDblClick;
|
|
24
26
|
constructor(map: MaplibreMap, callbacks: MouseInputCallbacks);
|
|
25
27
|
/**
|
|
@@ -26,9 +26,11 @@ export declare class TouchInput {
|
|
|
26
26
|
private longPressTimer;
|
|
27
27
|
private touchStartPos;
|
|
28
28
|
private isPinching;
|
|
29
|
+
private longPressFired;
|
|
29
30
|
private handleTouchStart;
|
|
30
31
|
private handleTouchMove;
|
|
31
32
|
private handleTouchEnd;
|
|
33
|
+
private handleTouchCancel;
|
|
32
34
|
constructor(map: MaplibreMap, callbacks: TouchInputCallbacks);
|
|
33
35
|
/**
|
|
34
36
|
* Start listening for touch events on the map canvas.
|
|
@@ -46,6 +48,10 @@ export declare class TouchInput {
|
|
|
46
48
|
* Cancel the long press detection timer.
|
|
47
49
|
*/
|
|
48
50
|
private cancelLongPress;
|
|
51
|
+
/**
|
|
52
|
+
* End the current pointer interaction if active.
|
|
53
|
+
*/
|
|
54
|
+
private endPointerIfActive;
|
|
49
55
|
/**
|
|
50
56
|
* Convert a TouchEvent into a NormalizedInputEvent using the first touch.
|
|
51
57
|
*/
|
package/dist/libre-draw.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class ue{constructor(e){this.feature=e,this.type="create"}apply(e){e.add(this.feature)}revert(e){e.remove(this.feature.id)}}class ${constructor(e,t,s){this.id=e,this.oldFeature=t,this.newFeature=s,this.type="update"}apply(e){e.update(this.id,this.newFeature)}revert(e){e.update(this.id,this.oldFeature)}}class oe{constructor(e){this.feature=e,this.type="delete"}apply(e){e.remove(this.feature.id)}revert(e){e.add(this.feature)}}class ge{constructor(){this.listeners=new Map}on(e,t){let s=this.listeners.get(e);s||(s=new Set,this.listeners.set(e,s)),s.add(t)}off(e,t){const s=this.listeners.get(e);s&&s.delete(t)}emit(e,t){const s=this.listeners.get(e);if(s)for(const i of s)i(t)}removeAllListeners(){this.listeners.clear()}}class R{constructor(){this.features=new Map}add(e){const t=e.id||crypto.randomUUID(),s={...e,id:t};return this.features.set(t,s),s}update(e,t){this.features.has(e)&&this.features.set(e,{...t,id:e})}remove(e){const t=this.features.get(e);return t&&this.features.delete(e),t}getAll(){return Array.from(this.features.values())}getById(e){return this.features.get(e)}clear(){this.features.clear()}setAll(e){this.features.clear();for(const t of e){const s=t.id||crypto.randomUUID();this.features.set(s,{...t,id:s})}}toGeoJSON(){return{type:"FeatureCollection",features:this.getAll()}}static cloneFeature(e){return{id:e.id,type:"Feature",geometry:{type:"Polygon",coordinates:e.geometry.coordinates.map(t=>t.map(s=>[...s]))},properties:{...e.properties}}}}class fe{constructor(e=100){this.undoStack=[],this.redoStack=[],this.limit=e}push(e){this.undoStack.push(e),this.redoStack=[],this.undoStack.length>this.limit&&this.undoStack.shift()}undo(e){const t=this.undoStack.pop();return t?(t.revert(e),this.redoStack.push(t),!0):!1}redo(e){const t=this.redoStack.pop();return t?(t.apply(e),this.undoStack.push(t),!0):!1}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}clear(){this.undoStack=[],this.redoStack=[]}}class pe{constructor(){this.modes=new Map,this.currentModeName="idle"}registerMode(e,t){this.modes.set(e,t)}setOnModeChange(e){this.onModeChange=e}setMode(e){if(e===this.currentModeName)return;const t=this.currentModeName,s=this.modes.get(this.currentModeName);s&&s.deactivate(),this.currentModeName=e;const i=this.modes.get(e);i&&i.activate(),this.onModeChange&&this.onModeChange(e,t)}getMode(){return this.currentModeName}getCurrentMode(){return this.modes.get(this.currentModeName)}}class v extends Error{constructor(e){super(e),this.name="LibreDrawError"}}function z(r,e,t){const s=(e[1]-r[1])*(t[0]-e[0])-(e[0]-r[0])*(t[1]-e[1]);return Math.abs(s)<1e-10?0:s>0?1:2}function j(r,e,t){return e[0]<=Math.max(r[0],t[0])&&e[0]>=Math.min(r[0],t[0])&&e[1]<=Math.max(r[1],t[1])&&e[1]>=Math.min(r[1],t[1])}function X(r,e){return Math.abs(r[0]-e[0])<1e-10&&Math.abs(r[1]-e[1])<1e-10}function J(r,e,t,s){if(X(r,t)||X(r,s)||X(e,t)||X(e,s))return!1;const i=z(r,e,t),n=z(r,e,s),o=z(t,s,r),l=z(t,s,e);return!!(i!==n&&o!==l||i===0&&j(r,t,e)||n===0&&j(r,s,e)||o===0&&j(t,r,s)||l===0&&j(t,e,s))}function ae(r){const e=r.length-1;if(e<3)return!1;for(let t=0;t<e;t++)for(let s=t+2;s<e;s++)if(!(t===0&&s===e-1)&&J(r[t],r[t+1],r[s],r[s+1]))return!0;return!1}function ye(r,e){if(r.length<2)return!1;const t=r[r.length-1];for(let s=0;s<r.length-2;s++)if(J(t,e,r[s],r[s+1]))return!0;return!1}function q(r){if(r.length<3)return!1;const e=r[0],t=r[r.length-1];for(let s=1;s<r.length-2;s++)if(J(t,e,r[s],r[s+1]))return!0;return!1}function me(r,e){return r[0]===e[0]&&r[1]===e[1]}function be(r){const[e,t]=r;if(typeof e!="number"||typeof t!="number")throw new v(`Invalid coordinate: expected [number, number], got [${typeof e}, ${typeof t}]`);if(e<-180||e>180)throw new v(`Invalid longitude: ${e}. Must be between -180 and 180.`);if(t<-90||t>90)throw new v(`Invalid latitude: ${t}. Must be between -90 and 90.`)}function ve(r){if(!Array.isArray(r))throw new v("Ring must be an array of positions.");if(r.length<4)throw new v(`Ring must have at least 4 positions (got ${r.length}). A valid polygon ring requires 3 unique vertices plus a closing vertex.`);const e=r[0],t=r[r.length-1];if(!me(e,t))throw new v("Ring is not closed. The first and last positions must be identical.");for(const s of r){if(!Array.isArray(s)||s.length<2)throw new v("Each position in a ring must be an array of at least 2 numbers.");be(s)}if(ae(r))throw new v("Ring has self-intersections. Polygon edges must not cross each other.")}function le(r){if(r==null||typeof r!="object")throw new v("Feature must be a non-null object.");const e=r;if(e.type!=="Feature")throw new v(`Feature.type must be "Feature", got "${String(e.type)}".`);if(e.geometry===null||e.geometry===void 0||typeof e.geometry!="object")throw new v("Feature.geometry must be a non-null object.");const t=e.geometry;if(t.type!=="Polygon")throw new v(`Feature.geometry.type must be "Polygon", got "${String(t.type)}".`);if(!Array.isArray(t.coordinates))throw new v("Feature.geometry.coordinates must be an array.");const s=t.coordinates;if(s.length===0)throw new v("Polygon must have at least one ring (outer ring).");for(const i of s)ve(i);return r}function Ee(r){if(r==null||typeof r!="object")throw new v("GeoJSON must be a non-null object.");const e=r;if(e.type!=="FeatureCollection")throw new v(`GeoJSON.type must be "FeatureCollection", got "${String(e.type)}".`);if(!Array.isArray(e.features))throw new v("GeoJSON.features must be an array.");const t=r,s=[];for(let i=0;i<t.features.length;i++)try{s.push(le(t.features[i]))}catch(n){throw n instanceof v?new v(`Invalid feature at index ${i}: ${n.message}`):n}return{type:"FeatureCollection",features:s}}class Ie{activate(){}deactivate(){}onPointerDown(e){}onPointerMove(e){}onPointerUp(e){}onDoubleClick(e){}onLongPress(e){}onKeyDown(e,t){}}const we=10,W=3;class Se{constructor(e){this.vertices=[],this.isActive=!1,this.callbacks=e}activate(){this.isActive=!0,this.vertices=[]}deactivate(){this.isActive=!1,this.vertices=[],this.callbacks.clearPreview()}onPointerDown(e){if(!this.isActive)return;const t=[e.lngLat.lng,e.lngLat.lat];if(this.vertices.length>=W){const s=this.vertices[0],i=this.callbacks.getScreenPoint({lng:s[0],lat:s[1]}),n=e.point.x-i.x,o=e.point.y-i.y;if(Math.sqrt(n*n+o*o)<=we){if(q(this.vertices))return;this.finalizePolygon();return}}ye(this.vertices,t)||(this.vertices.push(t),this.updatePreview(e))}onPointerMove(e){!this.isActive||this.vertices.length===0||this.updatePreview(e)}onPointerUp(e){}onDoubleClick(e){this.isActive&&(this.vertices.length>W&&this.vertices.pop(),this.vertices.length>=W&&(q(this.vertices)||this.finalizePolygon()),e.originalEvent.preventDefault(),e.originalEvent.stopPropagation())}onLongPress(e){this.isActive&&this.vertices.length>0&&(this.vertices.pop(),this.vertices.length===0?this.callbacks.clearPreview():this.callbacks.renderPreview(this.buildPreviewCoordinates()))}onKeyDown(e,t){this.isActive&&e==="Escape"&&this.cancelDrawing()}buildPreviewCoordinates(e){const t=[...this.vertices];return e&&t.push(e),t.length>0&&t.push([...t[0]]),t}updatePreview(e){const t=[e.lngLat.lng,e.lngLat.lat],s=this.buildPreviewCoordinates(t);this.callbacks.renderPreview(s)}finalizePolygon(){if(this.vertices.length<W)return;const e=[...this.vertices,[...this.vertices[0]]],t={id:crypto.randomUUID(),type:"Feature",geometry:{type:"Polygon",coordinates:[e]},properties:{}},s=this.callbacks.addFeatureToStore(t),i=new ue(s);this.callbacks.pushToHistory(i),this.callbacks.emitEvent("create",{feature:s}),this.callbacks.renderFeatures(),this.vertices=[],this.callbacks.clearPreview()}cancelDrawing(){this.vertices=[],this.callbacks.clearPreview()}}const N=11102230246251565e-32,F=134217729,Te=(3+8*N)*N;function Y(r,e,t,s,i){let n,o,l,h,d=e[0],u=s[0],a=0,c=0;u>d==u>-d?(n=d,d=e[++a]):(n=u,u=s[++c]);let g=0;if(a<r&&c<t)for(u>d==u>-d?(o=d+n,l=n-(o-d),d=e[++a]):(o=u+n,l=n-(o-u),u=s[++c]),n=o,l!==0&&(i[g++]=l);a<r&&c<t;)u>d==u>-d?(o=n+d,h=o-n,l=n-(o-h)+(d-h),d=e[++a]):(o=n+u,h=o-n,l=n-(o-h)+(u-h),u=s[++c]),n=o,l!==0&&(i[g++]=l);for(;a<r;)o=n+d,h=o-n,l=n-(o-h)+(d-h),d=e[++a],n=o,l!==0&&(i[g++]=l);for(;c<t;)o=n+u,h=o-n,l=n-(o-h)+(u-h),u=s[++c],n=o,l!==0&&(i[g++]=l);return(n!==0||g===0)&&(i[g++]=n),g}function Me(r,e){let t=e[0];for(let s=1;s<r;s++)t+=e[s];return t}function H(r){return new Float64Array(r)}const Pe=(3+16*N)*N,ke=(2+12*N)*N,Fe=(9+64*N)*N*N,O=H(4),Q=H(8),Z=H(12),ee=H(16),D=H(4);function De(r,e,t,s,i,n,o){let l,h,d,u,a,c,g,y,p,m,f,b,T,I,M,P,C,k;const L=r-i,x=t-i,V=e-n,A=s-n;I=L*A,c=F*L,g=c-(c-L),y=L-g,c=F*A,p=c-(c-A),m=A-p,M=y*m-(I-g*p-y*p-g*m),P=V*x,c=F*V,g=c-(c-V),y=V-g,c=F*x,p=c-(c-x),m=x-p,C=y*m-(P-g*p-y*p-g*m),f=M-C,a=M-f,O[0]=M-(f+a)+(a-C),b=I+f,a=b-I,T=I-(b-a)+(f-a),f=T-P,a=T-f,O[1]=T-(f+a)+(a-P),k=b+f,a=k-b,O[2]=b-(k-a)+(f-a),O[3]=k;let _=Me(4,O),U=ke*o;if(_>=U||-_>=U||(a=r-L,l=r-(L+a)+(a-i),a=t-x,d=t-(x+a)+(a-i),a=e-V,h=e-(V+a)+(a-n),a=s-A,u=s-(A+a)+(a-n),l===0&&h===0&&d===0&&u===0)||(U=Fe*o+Te*Math.abs(_),_+=L*u+A*l-(V*d+x*h),_>=U||-_>=U))return _;I=l*A,c=F*l,g=c-(c-l),y=l-g,c=F*A,p=c-(c-A),m=A-p,M=y*m-(I-g*p-y*p-g*m),P=h*x,c=F*h,g=c-(c-h),y=h-g,c=F*x,p=c-(c-x),m=x-p,C=y*m-(P-g*p-y*p-g*m),f=M-C,a=M-f,D[0]=M-(f+a)+(a-C),b=I+f,a=b-I,T=I-(b-a)+(f-a),f=T-P,a=T-f,D[1]=T-(f+a)+(a-P),k=b+f,a=k-b,D[2]=b-(k-a)+(f-a),D[3]=k;const ce=Y(4,O,4,D,Q);I=L*u,c=F*L,g=c-(c-L),y=L-g,c=F*u,p=c-(c-u),m=u-p,M=y*m-(I-g*p-y*p-g*m),P=V*d,c=F*V,g=c-(c-V),y=V-g,c=F*d,p=c-(c-d),m=d-p,C=y*m-(P-g*p-y*p-g*m),f=M-C,a=M-f,D[0]=M-(f+a)+(a-C),b=I+f,a=b-I,T=I-(b-a)+(f-a),f=T-P,a=T-f,D[1]=T-(f+a)+(a-P),k=b+f,a=k-b,D[2]=b-(k-a)+(f-a),D[3]=k;const he=Y(ce,Q,4,D,Z);I=l*u,c=F*l,g=c-(c-l),y=l-g,c=F*u,p=c-(c-u),m=u-p,M=y*m-(I-g*p-y*p-g*m),P=h*d,c=F*h,g=c-(c-h),y=h-g,c=F*d,p=c-(c-d),m=d-p,C=y*m-(P-g*p-y*p-g*m),f=M-C,a=M-f,D[0]=M-(f+a)+(a-C),b=I+f,a=b-I,T=I-(b-a)+(f-a),f=T-P,a=T-f,D[1]=T-(f+a)+(a-P),k=b+f,a=k-b,D[2]=b-(k-a)+(f-a),D[3]=k;const de=Y(he,Z,4,D,ee);return ee[de-1]}function Ce(r,e,t,s,i,n){const o=(e-n)*(t-i),l=(r-i)*(s-n),h=o-l,d=Math.abs(o+l);return Math.abs(h)>=Pe*d?h:-De(r,e,t,s,i,n,d)}function Le(r,e){var t,s,i=0,n,o,l,h,d,u,a,c=r[0],g=r[1],y=e.length;for(t=0;t<y;t++){s=0;var p=e[t],m=p.length-1;if(u=p[0],u[0]!==p[m][0]&&u[1]!==p[m][1])throw new Error("First and last coordinates in a ring must be the same");for(o=u[0]-c,l=u[1]-g,s;s<m;s++){if(a=p[s+1],h=a[0]-c,d=a[1]-g,l===0&&d===0){if(h<=0&&o>=0||o<=0&&h>=0)return 0}else if(d>=0&&l<=0||d<=0&&l>=0){if(n=Ce(o,h,l,d,0,0),n===0)return 0;(n>0&&d>0&&l<=0||n<0&&d<=0&&l>0)&&i++}u=a,l=d,o=h}}return i%2!==0}function xe(r,e,t={}){const s={type:"Feature"};return(t.id===0||t.id)&&(s.id=t.id),t.bbox&&(s.bbox=t.bbox),s.properties={},s.geometry=r,s}function te(r,e,t={}){if(!r)throw new Error("coordinates is required");if(!Array.isArray(r))throw new Error("coordinates must be an Array");if(r.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!se(r[0])||!se(r[1]))throw new Error("coordinates must contain numbers");return xe({type:"Point",coordinates:r},e,t)}function se(r){return!isNaN(r)&&r!==null&&!Array.isArray(r)}function Ve(r){if(!r)throw new Error("coord is required");if(!Array.isArray(r)){if(r.type==="Feature"&&r.geometry!==null&&r.geometry.type==="Point")return[...r.geometry.coordinates];if(r.type==="Point")return[...r.coordinates]}if(Array.isArray(r)&&r.length>=2&&!Array.isArray(r[0])&&!Array.isArray(r[1]))return[...r];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function Ae(r){return r.type==="Feature"?r.geometry:r}function _e(r,e,t={}){if(!r)throw new Error("point is required");if(!e)throw new Error("polygon is required");const s=Ve(r),i=Ae(e),n=i.type,o=e.bbox;let l=i.coordinates;if(o&&Re(s,o)===!1)return!1;n==="Polygon"&&(l=[l]);let h=!1;for(var d=0;d<l.length;++d){const u=Le(s,l[d]);if(u===0)return!t.ignoreBoundary;u&&(h=!0)}return h}function Re(r,e){return e[0]<=r[0]&&e[1]<=r[1]&&e[2]>=r[0]&&e[3]>=r[1]}var ie=_e;const re=10,Ne=24,ne=3;class Oe{constructor(e,t){this.selectedIds=new Set,this.isActive=!1,this.dragging=!1,this.dragVertexIndex=-1,this.dragStartFeature=null,this.draggingPolygon=!1,this.dragPolygonStartLngLat=null,this.highlightedVertexIndex=-1,this.callbacks=e,this.onSelectionChange=t}activate(){this.isActive=!0}deactivate(){this.isActive=!1,this.highlightedVertexIndex=-1,this.endDrag(),this.selectedIds.size>0&&(this.selectedIds.clear(),this.callbacks.clearVertices(),this.notifySelectionChange())}getSelectedIds(){return Array.from(this.selectedIds)}selectFeature(e){if(!this.isActive)return!1;const t=this.callbacks.getFeatureById(e);return t?(this.highlightedVertexIndex=-1,this.endDrag(),this.selectedIds.clear(),this.selectedIds.add(e),this.showVertexHandles(t),this.notifySelectionChange(),this.callbacks.renderFeatures(),!0):!1}clearSelection(){this.isActive&&this.selectedIds.size!==0&&(this.highlightedVertexIndex=-1,this.endDrag(),this.selectedIds.clear(),this.callbacks.clearVertices(),this.notifySelectionChange(),this.callbacks.renderFeatures())}onPointerDown(e){if(!this.isActive)return;const t=this.getFirstSelectedId();if(t){const o=this.callbacks.getFeatureById(t);if(o){const l=this.getVertices(o),h=this.getThreshold(e),d=this.findNearestVertex(l,e.point,h);if(d>=0){this.startDrag(o,d);return}const u=this.computeMidpoints(l),a=this.findNearestPoint(u,e.point,h);if(a>=0){const g=R.cloneFeature(o),y=this.insertVertex(o,a+1,u[a]);this.callbacks.updateFeatureInStore(t,y),this.showVertexHandles(y),this.startDrag(y,a+1),this.dragStartFeature=g;return}const c=te([e.lngLat.lng,e.lngLat.lat]);if(ie(c,o.geometry)){this.startPolygonDrag(o,e.lngLat);return}}}this.highlightedVertexIndex=-1;const s=te([e.lngLat.lng,e.lngLat.lat]),i=this.callbacks.getAllFeatures();let n;for(let o=i.length-1;o>=0;o--){const l=i[o],h=l.geometry;if(ie(s,h)){n=l;break}}n?this.selectedIds.has(n.id)?(this.selectedIds.delete(n.id),this.callbacks.clearVertices()):(this.selectedIds.clear(),this.selectedIds.add(n.id),this.showVertexHandles(n)):(this.selectedIds.clear(),this.callbacks.clearVertices()),this.notifySelectionChange(),this.callbacks.renderFeatures()}onPointerMove(e){if(!this.isActive)return;if(this.dragging){const l=this.getFirstSelectedId();if(!l)return;const h=this.callbacks.getFeatureById(l);if(!h)return;const d=[e.lngLat.lng,e.lngLat.lat],u=this.moveVertex(h,this.dragVertexIndex,d);if(ae(u.geometry.coordinates[0]))return;this.callbacks.updateFeatureInStore(l,u),this.callbacks.renderFeatures(),this.showVertexHandles(u);return}if(this.draggingPolygon){const l=this.getFirstSelectedId();if(!l||!this.dragStartFeature||!this.dragPolygonStartLngLat)return;const h=e.lngLat.lng-this.dragPolygonStartLngLat.lng,d=e.lngLat.lat-this.dragPolygonStartLngLat.lat,u=this.movePolygon(this.dragStartFeature,h,d);this.callbacks.updateFeatureInStore(l,u),this.callbacks.renderFeatures(),this.showVertexHandles(u);return}const t=this.getFirstSelectedId();if(!t)return;const s=this.callbacks.getFeatureById(t);if(!s)return;const i=this.getVertices(s),n=this.getThreshold(e),o=this.findNearestVertex(i,e.point,n);o!==this.highlightedVertexIndex&&(this.highlightedVertexIndex=o,this.showVertexHandles(s))}onPointerUp(e){if(!this.isActive||!this.dragging&&!this.draggingPolygon)return;const t=this.getFirstSelectedId();if(!t||!this.dragStartFeature){this.endDrag();return}const s=this.callbacks.getFeatureById(t);if(s){const i=new $(t,this.dragStartFeature,R.cloneFeature(s));this.callbacks.pushToHistory(i),this.callbacks.emitEvent("update",{feature:s,oldFeature:this.dragStartFeature})}this.endDrag()}onDoubleClick(e){if(!this.isActive)return;const t=this.getFirstSelectedId();if(!t)return;const s=this.callbacks.getFeatureById(t);if(!s)return;const i=this.getVertices(s),n=this.getThreshold(e),o=this.findNearestVertex(i,e.point,n);if(o>=0&&i.length>ne){const l=R.cloneFeature(s),h=this.removeVertex(s,o);this.callbacks.updateFeatureInStore(t,h);const d=new $(t,l,R.cloneFeature(h));this.callbacks.pushToHistory(d),this.callbacks.emitEvent("update",{feature:h,oldFeature:l}),this.callbacks.renderFeatures(),this.showVertexHandles(h),e.originalEvent.preventDefault(),e.originalEvent.stopPropagation()}}onLongPress(e){if(!this.isActive)return;const t=this.getFirstSelectedId();if(!t)return;const s=this.callbacks.getFeatureById(t);if(!s)return;const i=this.getVertices(s),n=this.getThreshold(e),o=this.findNearestVertex(i,e.point,n);if(o>=0&&i.length>ne){const l=R.cloneFeature(s),h=this.removeVertex(s,o);this.callbacks.updateFeatureInStore(t,h);const d=new $(t,l,R.cloneFeature(h));this.callbacks.pushToHistory(d),this.callbacks.emitEvent("update",{feature:h,oldFeature:l}),this.callbacks.renderFeatures(),this.showVertexHandles(h)}}onKeyDown(e,t){this.isActive&&(e==="Delete"||e==="Backspace")&&this.deleteSelected()}getThreshold(e){return e.inputType==="touch"?Ne:re}getVertices(e){const t=e.geometry.coordinates[0];return t.slice(0,t.length-1)}findNearestVertex(e,t,s){return this.findNearestPoint(e,t,s)}findNearestPoint(e,t,s=re){let i=1/0,n=-1;for(let o=0;o<e.length;o++){const l=this.callbacks.getScreenPoint({lng:e[o][0],lat:e[o][1]}),h=t.x-l.x,d=t.y-l.y,u=Math.sqrt(h*h+d*d);u<=s&&u<i&&(i=u,n=o)}return n}computeMidpoints(e){const t=[];for(let s=0;s<e.length;s++){const i=(s+1)%e.length;t.push([(e[s][0]+e[i][0])/2,(e[s][1]+e[i][1])/2])}return t}startDrag(e,t){this.dragging=!0,this.dragVertexIndex=t,this.dragStartFeature=R.cloneFeature(e),this.callbacks.setDragPan(!1)}startPolygonDrag(e,t){this.draggingPolygon=!0,this.dragPolygonStartLngLat=t,this.dragStartFeature=R.cloneFeature(e),this.callbacks.setDragPan(!1)}endDrag(){(this.dragging||this.draggingPolygon)&&this.callbacks.setDragPan(!0),this.dragging=!1,this.dragVertexIndex=-1,this.dragStartFeature=null,this.draggingPolygon=!1,this.dragPolygonStartLngLat=null,this.highlightedVertexIndex=-1}moveVertex(e,t,s){const i=[...e.geometry.coordinates[0]];return i[t]=s,t===0&&(i[i.length-1]=s),t===i.length-1&&(i[0]=s),{...e,geometry:{type:"Polygon",coordinates:[i]}}}movePolygon(e,t,s){const i=e.geometry.coordinates[0].map(n=>[n[0]+t,n[1]+s]);return{...e,geometry:{type:"Polygon",coordinates:[i]}}}insertVertex(e,t,s){const i=[...e.geometry.coordinates[0]];return i.splice(t,0,s),{...e,geometry:{type:"Polygon",coordinates:[i]}}}removeVertex(e,t){const i=this.getVertices(e).filter((o,l)=>l!==t),n=[...i,[...i[0]]];return{...e,geometry:{type:"Polygon",coordinates:[n]}}}refreshVertexHandles(){if(!this.isActive)return;const e=this.getFirstSelectedId();if(!e)return;const t=this.callbacks.getFeatureById(e);t?this.showVertexHandles(t):(this.selectedIds.delete(e),this.callbacks.clearVertices(),this.notifySelectionChange())}showVertexHandles(e){const t=this.getVertices(e),s=this.computeMidpoints(t);this.callbacks.renderVertices(e.id,t,s,this.highlightedVertexIndex>=0?this.highlightedVertexIndex:void 0)}getFirstSelectedId(){return this.selectedIds.values().next().value}deleteSelected(){if(this.selectedIds.size===0)return;const e=Array.from(this.selectedIds);for(const t of e){const s=this.callbacks.getFeatureById(t);if(s){this.callbacks.removeFeatureFromStore(t);const i=new oe(s);this.callbacks.pushToHistory(i),this.callbacks.emitEvent("delete",{feature:s})}}this.selectedIds.clear(),this.callbacks.clearVertices(),this.notifySelectionChange(),this.callbacks.renderFeatures()}notifySelectionChange(){const e=this.getSelectedIds();this.callbacks.emitEvent("selectionchange",{selectedIds:e}),this.onSelectionChange&&this.onSelectionChange(e)}}class Ue{constructor(e,t){this.handleMouseDown=s=>{this.callbacks.onPointerDown(this.normalize(s))},this.handleMouseMove=s=>{this.callbacks.onPointerMove(this.normalize(s))},this.handleMouseUp=s=>{this.callbacks.onPointerUp(this.normalize(s))},this.handleDblClick=s=>{this.callbacks.onDoubleClick(this.normalize(s))},this.map=e,this.callbacks=t,this.canvas=e.getCanvasContainer()}enable(){this.canvas.addEventListener("mousedown",this.handleMouseDown),this.canvas.addEventListener("mousemove",this.handleMouseMove),this.canvas.addEventListener("mouseup",this.handleMouseUp),this.canvas.addEventListener("dblclick",this.handleDblClick)}disable(){this.canvas.removeEventListener("mousedown",this.handleMouseDown),this.canvas.removeEventListener("mousemove",this.handleMouseMove),this.canvas.removeEventListener("mouseup",this.handleMouseUp),this.canvas.removeEventListener("dblclick",this.handleDblClick)}destroy(){this.disable()}normalize(e){const t=this.canvas.getBoundingClientRect(),s=e.clientX-t.left,i=e.clientY-t.top,n=this.map.unproject([s,i]);return{lngLat:{lng:n.lng,lat:n.lat},point:{x:s,y:i},originalEvent:e,inputType:"mouse"}}}const Be=300,He=500,ze=15;class je{constructor(e,t){this.lastTapTime=0,this.longPressTimer=null,this.touchStartPos=null,this.isPinching=!1,this.handleTouchStart=s=>{if(s.touches.length>=2){this.isPinching=!0,this.cancelLongPress();return}this.isPinching=!1;const i=this.normalize(s);this.touchStartPos={x:i.point.x,y:i.point.y},this.cancelLongPress(),this.longPressTimer=setTimeout(()=>{this.touchStartPos&&(this.callbacks.onLongPress(i),this.touchStartPos=null)},He),this.callbacks.onPointerDown(i)},this.handleTouchMove=s=>{if(this.isPinching||s.touches.length>=2){this.cancelLongPress();return}const i=this.normalize(s);if(this.touchStartPos){const n=i.point.x-this.touchStartPos.x,o=i.point.y-this.touchStartPos.y;Math.sqrt(n*n+o*o)>ze&&this.cancelLongPress()}this.callbacks.onPointerMove(i)},this.handleTouchEnd=s=>{if(this.cancelLongPress(),this.isPinching){s.touches.length===0&&(this.isPinching=!1);return}if(s.changedTouches.length===0)return;const i=this.normalizeChangedTouch(s),n=Date.now();n-this.lastTapTime<Be?(this.callbacks.onDoubleClick(i),this.lastTapTime=0):this.lastTapTime=n,this.touchStartPos&&(this.callbacks.onPointerUp(i),this.touchStartPos=null)},this.map=e,this.callbacks=t,this.canvas=e.getCanvasContainer()}enable(){this.canvas.addEventListener("touchstart",this.handleTouchStart,{passive:!1}),this.canvas.addEventListener("touchmove",this.handleTouchMove,{passive:!1}),this.canvas.addEventListener("touchend",this.handleTouchEnd)}disable(){this.canvas.removeEventListener("touchstart",this.handleTouchStart),this.canvas.removeEventListener("touchmove",this.handleTouchMove),this.canvas.removeEventListener("touchend",this.handleTouchEnd),this.cancelLongPress()}destroy(){this.disable()}cancelLongPress(){this.longPressTimer!==null&&(clearTimeout(this.longPressTimer),this.longPressTimer=null)}normalize(e){const t=e.touches[0],s=this.canvas.getBoundingClientRect(),i=t.clientX-s.left,n=t.clientY-s.top,o=this.map.unproject([i,n]);return{lngLat:{lng:o.lng,lat:o.lat},point:{x:i,y:n},originalEvent:e,inputType:"touch"}}normalizeChangedTouch(e){const t=e.changedTouches[0],s=this.canvas.getBoundingClientRect(),i=t.clientX-s.left,n=t.clientY-s.top,o=this.map.unproject([i,n]);return{lngLat:{lng:o.lng,lat:o.lat},point:{x:i,y:n},originalEvent:e,inputType:"touch"}}}const K=class K{constructor(e){this.handleKeyDown=t=>{K.RELEVANT_KEYS.has(t.key)&&this.callbacks.onKeyDown(t.key,t)},this.callbacks=e}enable(){document.addEventListener("keydown",this.handleKeyDown)}disable(){document.removeEventListener("keydown",this.handleKeyDown)}destroy(){this.disable()}};K.RELEVANT_KEYS=new Set(["Escape","Delete","Backspace"]);let G=K;class Xe{constructor(e,t){this.getActiveMode=t;const s={onPointerDown:i=>{var n;(n=this.getActiveMode())==null||n.onPointerDown(i)},onPointerMove:i=>{var n;(n=this.getActiveMode())==null||n.onPointerMove(i)},onPointerUp:i=>{var n;(n=this.getActiveMode())==null||n.onPointerUp(i)},onDoubleClick:i=>{var n;(n=this.getActiveMode())==null||n.onDoubleClick(i)},onLongPress:i=>{var n;(n=this.getActiveMode())==null||n.onLongPress(i)}};this.mouseInput=new Ue(e,s),this.touchInput=new je(e,s),this.keyboardInput=new G({onKeyDown:(i,n)=>{var o;(o=this.getActiveMode())==null||o.onKeyDown(i,n)}})}enable(){this.mouseInput.enable(),this.touchInput.enable(),this.keyboardInput.enable()}disable(){this.mouseInput.disable(),this.touchInput.disable(),this.keyboardInput.disable()}destroy(){this.mouseInput.destroy(),this.touchInput.destroy(),this.keyboardInput.destroy()}}const E={FEATURES:"libre-draw-features",PREVIEW:"libre-draw-preview",EDIT_VERTICES:"libre-draw-edit-vertices"},B={type:"FeatureCollection",features:[]};class We{constructor(e){this.initialized=!1,this.map=e}initialize(){this.initialized||(this.map.getSource(E.FEATURES)||this.map.addSource(E.FEATURES,{type:"geojson",data:B}),this.map.getSource(E.PREVIEW)||this.map.addSource(E.PREVIEW,{type:"geojson",data:B}),this.map.getSource(E.EDIT_VERTICES)||this.map.addSource(E.EDIT_VERTICES,{type:"geojson",data:B}),this.initialized=!0)}updateFeatures(e){const t=this.map.getSource(E.FEATURES);t&&t.setData(e)}updatePreview(e){const t=this.map.getSource(E.PREVIEW);t&&t.setData(e)}clearPreview(){this.updatePreview(B)}updateEditVertices(e){const t=this.map.getSource(E.EDIT_VERTICES);t&&t.setData(e)}clearEditVertices(){this.updateEditVertices(B)}destroy(){this.map.getSource(E.FEATURES)&&this.map.removeSource(E.FEATURES),this.map.getSource(E.PREVIEW)&&this.map.removeSource(E.PREVIEW),this.map.getSource(E.EDIT_VERTICES)&&this.map.removeSource(E.EDIT_VERTICES),this.initialized=!1}}const S={FILL:"libre-draw-fill",OUTLINE:"libre-draw-outline",VERTICES:"libre-draw-vertices",PREVIEW:"libre-draw-preview",EDIT_VERTICES:"libre-draw-edit-vertices",EDIT_MIDPOINTS:"libre-draw-edit-midpoints"},w={FILL:"#3bb2d0",FILL_OPACITY:.2,FILL_SELECTED:"#fbb03b",FILL_SELECTED_OPACITY:.4,OUTLINE:"#3bb2d0",OUTLINE_WIDTH:2,OUTLINE_SELECTED:"#fbb03b",VERTEX_COLOR:"#ffffff",VERTEX_STROKE:"#3bb2d0",VERTEX_RADIUS:4,PREVIEW_OUTLINE:"#3bb2d0",PREVIEW_OUTLINE_DASH:[2,2],EDIT_VERTEX_COLOR:"#ffffff",EDIT_VERTEX_STROKE:"#3bb2d0",EDIT_VERTEX_RADIUS:5,EDIT_VERTEX_STROKE_WIDTH:2,MIDPOINT_COLOR:"#3bb2d0",MIDPOINT_OPACITY:.5,MIDPOINT_RADIUS:3};class Ke{constructor(e,t){this.selectedIds=new Set,this.pendingRender=!1,this.pendingFeatures=null,this.initialized=!1,this.map=e,this.sourceManager=t}initialize(){this.initialized||(this.sourceManager.initialize(),this.map.getLayer(S.FILL)||this.map.addLayer({id:S.FILL,type:"fill",source:E.FEATURES,paint:{"fill-color":["case",["boolean",["get","_selected"],!1],w.FILL_SELECTED,w.FILL],"fill-opacity":["case",["boolean",["get","_selected"],!1],w.FILL_SELECTED_OPACITY,w.FILL_OPACITY]}}),this.map.getLayer(S.OUTLINE)||this.map.addLayer({id:S.OUTLINE,type:"line",source:E.FEATURES,paint:{"line-color":["case",["boolean",["get","_selected"],!1],w.OUTLINE_SELECTED,w.OUTLINE],"line-width":w.OUTLINE_WIDTH}}),this.map.getLayer(S.VERTICES)||this.map.addLayer({id:S.VERTICES,type:"circle",source:E.FEATURES,filter:["==","$type","Point"],paint:{"circle-radius":w.VERTEX_RADIUS,"circle-color":w.VERTEX_COLOR,"circle-stroke-color":w.VERTEX_STROKE,"circle-stroke-width":2}}),this.map.getLayer(S.PREVIEW)||this.map.addLayer({id:S.PREVIEW,type:"line",source:E.PREVIEW,paint:{"line-color":w.PREVIEW_OUTLINE,"line-width":2,"line-dasharray":w.PREVIEW_OUTLINE_DASH}}),this.map.getLayer(S.EDIT_MIDPOINTS)||this.map.addLayer({id:S.EDIT_MIDPOINTS,type:"circle",source:E.EDIT_VERTICES,filter:["==",["get","_type"],"midpoint"],paint:{"circle-radius":w.MIDPOINT_RADIUS,"circle-color":w.MIDPOINT_COLOR,"circle-opacity":w.MIDPOINT_OPACITY}}),this.map.getLayer(S.EDIT_VERTICES)||this.map.addLayer({id:S.EDIT_VERTICES,type:"circle",source:E.EDIT_VERTICES,filter:["==",["get","_type"],"vertex"],paint:{"circle-radius":["case",["boolean",["get","_highlighted"],!1],7,w.EDIT_VERTEX_RADIUS],"circle-color":["case",["boolean",["get","_highlighted"],!1],"#ff4444",w.EDIT_VERTEX_COLOR],"circle-stroke-color":["case",["boolean",["get","_highlighted"],!1],"#cc0000",w.EDIT_VERTEX_STROKE],"circle-stroke-width":w.EDIT_VERTEX_STROKE_WIDTH}}),this.initialized=!0)}render(e){this.pendingFeatures=e,this.pendingRender||(this.pendingRender=!0,requestAnimationFrame(()=>{this.performRender(),this.pendingRender=!1}))}renderPreview(e){if(e.length<2){this.clearPreview();return}const t=e.map(i=>[i[0],i[1]]),s={type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:t}}]};this.sourceManager.updatePreview(s)}clearPreview(){this.sourceManager.clearPreview()}renderVertices(e,t,s){const i=[];for(let n=0;n<e.length;n++){const o=e[n];i.push({type:"Feature",properties:{_type:"vertex",_highlighted:n===s},geometry:{type:"Point",coordinates:[o[0],o[1]]}})}for(const n of t)i.push({type:"Feature",properties:{_type:"midpoint"},geometry:{type:"Point",coordinates:[n[0],n[1]]}});this.sourceManager.updateEditVertices({type:"FeatureCollection",features:i})}clearVertices(){this.sourceManager.clearEditVertices()}setSelectedIds(e){this.selectedIds=new Set(e)}destroy(){const e=[S.EDIT_VERTICES,S.EDIT_MIDPOINTS,S.PREVIEW,S.VERTICES,S.OUTLINE,S.FILL];for(const t of e)this.map.getLayer(t)&&this.map.removeLayer(t);this.sourceManager.destroy(),this.initialized=!1}performRender(){if(!this.pendingFeatures)return;const t={type:"FeatureCollection",features:this.pendingFeatures.map(s=>({type:"Feature",id:s.id,properties:{...s.properties,_id:s.id,_selected:this.selectedIds.has(s.id)},geometry:s.geometry}))};this.sourceManager.updateFeatures(t),this.pendingFeatures=null}}class $e{constructor(e){this.options=e,this.element=document.createElement("button"),this.element.type="button",this.element.title=e.title,this.element.setAttribute("aria-label",e.title),this.element.dataset.libreDrawButton=e.id,this.applyStyles(),this.iconContainer=document.createElement("span"),this.iconContainer.style.display="flex",this.iconContainer.style.alignItems="center",this.iconContainer.style.justifyContent="center",this.setIcon(e.icon),this.element.appendChild(this.iconContainer),this.element.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.element.disabled||e.onClick()})}getElement(){return this.element}setActive(e){e?(this.element.style.backgroundColor="#3bb2d0",this.element.style.color="#ffffff"):(this.element.style.backgroundColor="#ffffff",this.element.style.color="#333333"),this.element.setAttribute("aria-pressed",String(e))}setDisabled(e){this.element.disabled=e,this.element.style.opacity=e?"0.4":"1",this.element.style.cursor=e?"not-allowed":"pointer"}destroy(){this.element.remove()}setIcon(e){const i=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;for(;this.iconContainer.firstChild;)this.iconContainer.removeChild(this.iconContainer.firstChild);this.iconContainer.appendChild(document.importNode(i,!0))}applyStyles(){const e=this.element.style;e.display="flex",e.alignItems="center",e.justifyContent="center",e.width="44px",e.height="44px",e.padding="0",e.margin="0",e.border="1px solid #ddd",e.borderRadius="4px",e.backgroundColor="#ffffff",e.color="#333333",e.cursor="pointer",e.outline="none",e.transition="background-color 0.15s, color 0.15s",e.boxSizing="border-box"}}const Ye='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l8.5 6.2-3.2 9.8H6.7L3.5 8.2z"/></svg>',Ge='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/></svg>',Je='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>',qe='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 00-4-4H4"/></svg>',Qe='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 14 20 9 15 4"/><path d="M4 20v-7a4 4 0 014-4h12"/></svg>',Ze={draw:!0,select:!0,delete:!0,undo:!0,redo:!0};class et{constructor(e,t,s={}){this.buttons=new Map,this.map=e,this.callbacks=t,this.options=s,this.container=document.createElement("div"),this.container.className="libre-draw-toolbar",this.applyContainerStyles(),this.createButtons(),this.mount()}setActiveMode(e){const t=this.buttons.get("draw"),s=this.buttons.get("select");t&&t.setActive(e==="draw"),s&&s.setActive(e==="select")}setHistoryState(e,t){const s=this.buttons.get("undo"),i=this.buttons.get("redo");s&&s.setDisabled(!e),i&&i.setDisabled(!t)}destroy(){for(const e of this.buttons.values())e.destroy();this.buttons.clear(),this.container.remove()}createButtons(){const e={...Ze,...this.options.controls};e.draw&&this.addButton("draw",Ye,"Draw polygon",()=>{this.callbacks.onDrawClick()},!0),e.select&&this.addButton("select",Ge,"Select feature",()=>{this.callbacks.onSelectClick()},!0),e.delete&&this.addButton("delete",Je,"Delete selected",()=>{this.callbacks.onDeleteClick()}),e.undo&&this.addButton("undo",qe,"Undo",()=>{this.callbacks.onUndoClick()}),e.redo&&this.addButton("redo",Qe,"Redo",()=>{this.callbacks.onRedoClick()})}addButton(e,t,s,i,n){const o=new $e({id:e,icon:t,title:s,onClick:i,isToggle:n});this.buttons.set(e,o),this.container.appendChild(o.getElement())}mount(){const e=this.options.position||"top-right",t=this.map.getContainer(),s=t.querySelector(`.maplibregl-ctrl-${e}`);s?s.appendChild(this.container):t.appendChild(this.container)}applyContainerStyles(){const e=this.container.style;e.display="flex",e.flexDirection="column",e.gap="4px",e.padding="4px",e.backgroundColor="rgba(255, 255, 255, 0.9)",e.borderRadius="4px",e.boxShadow="0 1px 4px rgba(0, 0, 0, 0.3)",e.zIndex="1",e.pointerEvents="auto"}}class tt{constructor(e,t={}){this.toolbar=null,this.destroyed=!1,this.map=e,this.eventBus=new ge,this.featureStore=new R,this.historyManager=new fe(t.historyLimit??100),this.modeManager=new pe,this.sourceManager=new We(e),this.renderManager=new Ke(e,this.sourceManager);const s=new Se({addFeatureToStore:i=>this.featureStore.add(i),pushToHistory:i=>{this.historyManager.push(i),this.updateToolbarHistoryState()},emitEvent:(i,n)=>this.eventBus.emit(i,n),renderPreview:i=>this.renderManager.renderPreview(i),clearPreview:()=>this.renderManager.clearPreview(),renderFeatures:()=>this.renderAllFeatures(),getScreenPoint:i=>{const n=e.project([i.lng,i.lat]);return{x:n.x,y:n.y}}});if(this.selectMode=new Oe({removeFeatureFromStore:i=>this.featureStore.remove(i),pushToHistory:i=>{this.historyManager.push(i),this.updateToolbarHistoryState()},emitEvent:(i,n)=>this.eventBus.emit(i,n),renderFeatures:()=>this.renderAllFeatures(),getFeatureById:i=>this.featureStore.getById(i),getAllFeatures:()=>this.featureStore.getAll(),getScreenPoint:i=>{const n=e.project([i.lng,i.lat]);return{x:n.x,y:n.y}},updateFeatureInStore:(i,n)=>this.featureStore.update(i,n),renderVertices:(i,n,o,l)=>this.renderManager.renderVertices(n,o,l),clearVertices:()=>this.renderManager.clearVertices(),setDragPan:i=>{i?e.dragPan.enable():e.dragPan.disable()}},i=>{this.renderManager.setSelectedIds(i)}),this.modeManager.registerMode("idle",new Ie),this.modeManager.registerMode("draw",s),this.modeManager.registerMode("select",this.selectMode),this.modeManager.setOnModeChange((i,n)=>{this.eventBus.emit("modechange",{mode:i,previousMode:n}),this.toolbar&&this.toolbar.setActiveMode(i),i==="draw"?(e.dragPan.disable(),e.doubleClickZoom.disable()):i==="select"?e.doubleClickZoom.disable():(e.dragPan.enable(),e.doubleClickZoom.enable())}),this.inputHandler=new Xe(e,()=>this.modeManager.getCurrentMode()),t.toolbar!==!1&&t.toolbar!==void 0){const i=typeof t.toolbar=="object"?t.toolbar:{};this.createToolbar(i)}e.isStyleLoaded()?this.initialize():e.once("load",()=>{this.initialize()})}setMode(e){this.assertNotDestroyed(),this.modeManager.setMode(e)}getMode(){return this.assertNotDestroyed(),this.modeManager.getMode()}getFeatures(){return this.assertNotDestroyed(),this.featureStore.getAll()}toGeoJSON(){return this.assertNotDestroyed(),this.featureStore.toGeoJSON()}setFeatures(e){this.assertNotDestroyed();const t=Ee(e);this.featureStore.setAll(t.features),this.historyManager.clear(),this.renderAllFeatures(),this.updateToolbarHistoryState()}addFeatures(e){this.assertNotDestroyed();for(const t of e){const s=le(t);this.featureStore.add(s)}this.renderAllFeatures()}getSelectedFeatureIds(){return this.assertNotDestroyed(),this.selectMode.getSelectedIds()}getFeatureById(e){return this.assertNotDestroyed(),this.featureStore.getById(e)}deleteFeature(e){this.assertNotDestroyed();const t=this.featureStore.getById(e);if(!t)return;this.selectMode.getSelectedIds().includes(e)&&this.selectMode.clearSelection(),this.featureStore.remove(e);const i=new oe(t);return this.historyManager.push(i),this.eventBus.emit("delete",{feature:t}),this.renderAllFeatures(),this.updateToolbarHistoryState(),t}selectFeature(e){if(this.assertNotDestroyed(),!this.featureStore.getById(e))throw new v(`Feature not found: ${e}`);this.modeManager.getMode()!=="select"&&this.modeManager.setMode("select"),this.selectMode.selectFeature(e)}clearSelection(){this.assertNotDestroyed(),this.selectMode.clearSelection()}undo(){this.assertNotDestroyed();const e=this.historyManager.undo(this.featureStore);return e&&(this.renderAllFeatures(),this.selectMode.refreshVertexHandles(),this.updateToolbarHistoryState()),e}redo(){this.assertNotDestroyed();const e=this.historyManager.redo(this.featureStore);return e&&(this.renderAllFeatures(),this.selectMode.refreshVertexHandles(),this.updateToolbarHistoryState()),e}on(e,t){this.assertNotDestroyed(),this.eventBus.on(e,t)}off(e,t){this.assertNotDestroyed(),this.eventBus.off(e,t)}destroy(){this.destroyed||(this.destroyed=!0,this.modeManager.setMode("idle"),this.inputHandler.destroy(),this.renderManager.destroy(),this.eventBus.removeAllListeners(),this.historyManager.clear(),this.featureStore.clear(),this.toolbar&&(this.toolbar.destroy(),this.toolbar=null))}initialize(){this.destroyed||(this.renderManager.initialize(),this.inputHandler.enable())}renderAllFeatures(){const e=this.featureStore.getAll();this.renderManager.render(e)}createToolbar(e){this.toolbar=new et(this.map,{onDrawClick:()=>{const t=this.modeManager.getMode();this.modeManager.setMode(t==="draw"?"idle":"draw")},onSelectClick:()=>{const t=this.modeManager.getMode();this.modeManager.setMode(t==="select"?"idle":"select")},onDeleteClick:()=>{if(this.modeManager.getMode()==="select"){const t=this.selectMode.getSelectedIds();for(const s of t)this.deleteFeature(s)}},onUndoClick:()=>{this.undo()},onRedoClick:()=>{this.redo()}},e),this.toolbar.setActiveMode(this.modeManager.getMode()),this.toolbar.setHistoryState(this.historyManager.canUndo(),this.historyManager.canRedo())}updateToolbarHistoryState(){this.toolbar&&this.toolbar.setHistoryState(this.historyManager.canUndo(),this.historyManager.canRedo())}assertNotDestroyed(){if(this.destroyed)throw new v("This LibreDraw instance has been destroyed.")}}exports.LibreDraw=tt;exports.LibreDrawError=v;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function J(s){if(Array.isArray(s))return s.map(e=>J(e));if(s!==null&&typeof s=="object"){const e={};for(const[t,r]of Object.entries(s))e[t]=J(r);return e}return s}function pe(s){return s.map(e=>e.map(t=>[t[0],t[1]]))}function ye(s){return J(s)}function v(s){return{id:s.id,type:"Feature",geometry:{type:"Polygon",coordinates:pe(s.geometry.coordinates)},properties:ye(s.properties)}}function me(s){return{type:"FeatureCollection",features:s.features.map(e=>v(e))}}class ve{constructor(e){this.type="create",this.feature=v(e)}apply(e){e.add(this.feature)}revert(e){e.remove(this.feature.id)}}class ae{constructor(e,t,r){this.type="update",this.id=e,this.oldFeature=v(t),this.newFeature=v(r)}apply(e){e.update(this.id,this.newFeature)}revert(e){e.update(this.id,this.oldFeature)}}class le{constructor(e){this.type="delete",this.feature=v(e)}apply(e){e.remove(this.feature.id)}revert(e){e.add(this.feature)}}class we{constructor(){this.listeners=new Map}on(e,t){let r=this.listeners.get(e);r||(r=new Set,this.listeners.set(e,r)),r.add(t)}off(e,t){const r=this.listeners.get(e);r&&r.delete(t)}emit(e,t){const r=this.listeners.get(e);if(r)for(const n of r)n(t)}removeAllListeners(){this.listeners.clear()}}class Se{constructor(){this.features=new Map}add(e){const t=e.id||crypto.randomUUID(),r=v({...e,id:t});return this.features.set(t,r),v(r)}update(e,t){this.features.has(e)&&this.features.set(e,v({...t,id:e}))}remove(e){const t=this.features.get(e);if(t)return this.features.delete(e),v(t)}getAll(){return Array.from(this.features.values(),e=>v(e))}getById(e){const t=this.features.get(e);return t?v(t):void 0}clear(){this.features.clear()}setAll(e){this.features.clear();for(const t of e){const r=t.id||crypto.randomUUID();this.features.set(r,v({...t,id:r}))}}toGeoJSON(){return me({features:Array.from(this.features.values())})}static cloneFeature(e){return v(e)}}class be{constructor(e=100){this.undoStack=[],this.redoStack=[],this.limit=e}push(e){this.undoStack.push(e),this.redoStack=[],this.undoStack.length>this.limit&&this.undoStack.shift()}undo(e){const t=this.undoStack.pop();return t?(t.revert(e),this.redoStack.push(t),!0):!1}redo(e){const t=this.redoStack.pop();return t?(t.apply(e),this.undoStack.push(t),!0):!1}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}clear(){this.undoStack=[],this.redoStack=[]}}class Ee{constructor(){this.modes=new Map,this.currentModeName="idle"}registerMode(e,t){this.modes.set(e,t)}setOnModeChange(e){this.onModeChange=e}setMode(e){if(e===this.currentModeName)return;const t=this.currentModeName,r=this.modes.get(this.currentModeName);r&&r.deactivate(),this.currentModeName=e;const n=this.modes.get(e);n&&n.activate(),this.onModeChange&&this.onModeChange(e,t)}getMode(){return this.currentModeName}getCurrentMode(){return this.modes.get(this.currentModeName)}}class E extends Error{constructor(e){super(e),this.name="LibreDrawError"}}function j(s,e,t){const r=(e[1]-s[1])*(t[0]-e[0])-(e[0]-s[0])*(t[1]-e[1]);return Math.abs(r)<1e-10?0:r>0?1:2}function W(s,e,t){return e[0]<=Math.max(s[0],t[0])&&e[0]>=Math.min(s[0],t[0])&&e[1]<=Math.max(s[1],t[1])&&e[1]>=Math.min(s[1],t[1])}function G(s,e){return Math.abs(s[0]-e[0])<1e-10&&Math.abs(s[1]-e[1])<1e-10}function X(s,e,t,r){if(G(s,t)||G(s,r)||G(e,t)||G(e,r))return!1;const n=j(s,e,t),i=j(s,e,r),o=j(t,r,s),a=j(t,r,e);return!!(n!==i&&o!==a||n===0&&W(s,t,e)||i===0&&W(s,r,e)||o===0&&W(t,s,r)||a===0&&W(t,e,r))}function he(s){const e=s.length-1;if(e<3)return!1;for(let t=0;t<e;t++)for(let r=t+2;r<e;r++)if(!(t===0&&r===e-1)&&X(s[t],s[t+1],s[r],s[r+1]))return!0;return!1}function Ie(s,e){if(s.length<2)return!1;const t=s[s.length-1];for(let r=0;r<s.length-2;r++)if(X(t,e,s[r],s[r+1]))return!0;return!1}function Z(s){if(s.length<3)return!1;const e=s[0],t=s[s.length-1];for(let r=1;r<s.length-2;r++)if(X(t,e,s[r],s[r+1]))return!0;return!1}function Me(s,e){return s[0]===e[0]&&s[1]===e[1]}function xe(s){const[e,t]=s;if(typeof e!="number"||typeof t!="number")throw new E(`Invalid coordinate: expected [number, number], got [${typeof e}, ${typeof t}]`);if(e<-180||e>180)throw new E(`Invalid longitude: ${e}. Must be between -180 and 180.`);if(t<-90||t>90)throw new E(`Invalid latitude: ${t}. Must be between -90 and 90.`)}function Pe(s){if(!Array.isArray(s))throw new E("Ring must be an array of positions.");if(s.length<4)throw new E(`Ring must have at least 4 positions (got ${s.length}). A valid polygon ring requires 3 unique vertices plus a closing vertex.`);const e=s[0],t=s[s.length-1];if(!Me(e,t))throw new E("Ring is not closed. The first and last positions must be identical.");for(const r of s){if(!Array.isArray(r)||r.length<2)throw new E("Each position in a ring must be an array of at least 2 numbers.");xe(r)}if(he(s))throw new E("Ring has self-intersections. Polygon edges must not cross each other.")}function ce(s){if(s==null||typeof s!="object")throw new E("Feature must be a non-null object.");const e=s;if(e.type!=="Feature")throw new E(`Feature.type must be "Feature", got "${String(e.type)}".`);if(e.geometry===null||e.geometry===void 0||typeof e.geometry!="object")throw new E("Feature.geometry must be a non-null object.");const t=e.geometry;if(t.type!=="Polygon")throw new E(`Feature.geometry.type must be "Polygon", got "${String(t.type)}".`);if(!Array.isArray(t.coordinates))throw new E("Feature.geometry.coordinates must be an array.");const r=t.coordinates;if(r.length===0)throw new E("Polygon must have at least one ring (outer ring).");for(const a of r)Pe(a);const n=typeof e.id=="string"?e.id:"",i=e.properties,o=i!=null&&typeof i=="object"&&!Array.isArray(i)?J(i):{};return{id:n,type:"Feature",geometry:{type:"Polygon",coordinates:r.map(a=>a.map(h=>[h[0],h[1]]))},properties:o}}function Ce(s){if(s==null||typeof s!="object")throw new E("GeoJSON must be a non-null object.");const e=s;if(e.type!=="FeatureCollection")throw new E(`GeoJSON.type must be "FeatureCollection", got "${String(e.type)}".`);if(!Array.isArray(e.features))throw new E("GeoJSON.features must be an array.");const t=s,r=[];for(let n=0;n<t.features.length;n++)try{r.push(ce(t.features[n]))}catch(i){throw i instanceof E?new E(`Invalid feature at index ${n}: ${i.message}`):i}return{type:"FeatureCollection",features:r}}class De{mapInteractions(){return{dragPan:!0,doubleClickZoom:!0}}activate(){}deactivate(){}onPointerDown(e){}onPointerMove(e){}onPointerUp(e){}onDoubleClick(e){}onLongPress(e){}onKeyDown(e,t){}}const Fe=10,$=3;class Te{constructor(e){this.vertices=[],this.isActive=!1,this.context=e}mapInteractions(){return{dragPan:!1,doubleClickZoom:!1}}activate(){this.isActive=!0,this.vertices=[]}deactivate(){this.isActive=!1,this.vertices=[],this.context.render.clearPreview()}onPointerDown(e){if(!this.isActive)return;const t=[e.lngLat.lng,e.lngLat.lat];if(this.vertices.length>=$){const r=this.vertices[0],n=this.context.getScreenPoint({lng:r[0],lat:r[1]}),i=e.point.x-n.x,o=e.point.y-n.y;if(Math.sqrt(i*i+o*o)<=Fe){if(Z(this.vertices))return;this.finalizePolygon();return}}Ie(this.vertices,t)||(this.vertices.push(t),this.updatePreview(e))}onPointerMove(e){!this.isActive||this.vertices.length===0||this.updatePreview(e)}onPointerUp(e){}onDoubleClick(e){this.isActive&&(this.vertices.length>$&&this.vertices.pop(),this.vertices.length>=$&&(Z(this.vertices)||this.finalizePolygon()),e.originalEvent.preventDefault(),e.originalEvent.stopPropagation())}onLongPress(e){this.isActive&&this.vertices.length>0&&(this.vertices.pop(),this.vertices.length===0?this.context.render.clearPreview():this.context.render.renderPreview(this.buildPreviewCoordinates()))}onKeyDown(e,t){this.isActive&&e==="Escape"&&this.cancelDrawing()}buildPreviewCoordinates(e){const t=[...this.vertices];return e&&t.push(e),t.length>0&&t.push([...t[0]]),t}updatePreview(e){const t=[e.lngLat.lng,e.lngLat.lat],r=this.buildPreviewCoordinates(t);this.context.render.renderPreview(r)}finalizePolygon(){if(this.vertices.length<$)return;const e=[...this.vertices,[...this.vertices[0]]],t={id:crypto.randomUUID(),type:"Feature",geometry:{type:"Polygon",coordinates:[e]},properties:{}},r=this.context.store.add(t),n=new ve(r);this.context.history.push(n),this.context.events.emit("create",{feature:v(r)}),this.context.render.renderFeatures(),this.vertices=[],this.context.render.clearPreview()}cancelDrawing(){this.vertices=[],this.context.render.clearPreview()}}class Le{constructor(e,t){this.selectedIds=new Set,this.context=e,this.onSelectionChange=t}getSelectedIds(){return Array.from(this.selectedIds)}getFirstSelectedId(){return this.selectedIds.values().next().value}hasSelection(){return this.selectedIds.size>0}has(e){return this.selectedIds.has(e)}selectOnly(e){this.selectedIds.clear(),this.selectedIds.add(e)}remove(e){this.selectedIds.delete(e)}clear(){this.selectedIds.clear()}clearAndNotify(){return this.hasSelection()?(this.clear(),this.notify(),!0):!1}notify(){const e=this.getSelectedIds();this.context.render.setSelectedIds(e),this.context.events.emit("selectionchange",{selectedIds:e}),this.onSelectionChange&&this.onSelectionChange(e)}}function z(s){const e=s.geometry.coordinates[0];return e.slice(0,e.length-1)}function Q(s){const e=[];for(let t=0;t<s.length;t++){const r=(t+1)%s.length;e.push([(s[t][0]+s[r][0])/2,(s[t][1]+s[r][1])/2])}return e}function Ae(s,e,t){const r=[...s.geometry.coordinates[0]];return r[e]=t,e===0&&(r[r.length-1]=t),e===r.length-1&&(r[0]=t),{...s,geometry:{type:"Polygon",coordinates:[r]}}}function ke(s,e,t){const r=s.geometry.coordinates[0].map(n=>[n[0]+e,n[1]+t]);return{...s,geometry:{type:"Polygon",coordinates:[r]}}}function Ve(s,e,t){const r=[...s.geometry.coordinates[0]];return r.splice(e,0,t),{...s,geometry:{type:"Polygon",coordinates:[r]}}}function Re(s,e){const r=z(s).filter((i,o)=>o!==e),n=[...r,[...r[0]]];return{...s,geometry:{type:"Polygon",coordinates:[n]}}}const ee=10,_e=24,Ne=3;class Be{constructor(e){this.dragging=!1,this.dragVertexIndex=-1,this.dragStartFeature=null,this.highlightedVertexIndex=-1,this.context=e}isDragging(){return this.dragging}getDragStartFeature(){return this.dragStartFeature}resetInteractionState(){this.endDrag(),this.highlightedVertexIndex=-1}clearHighlight(){this.highlightedVertexIndex=-1}tryStartVertexDragOrInsert(e,t,r){const n=z(e),i=this.getThreshold(r),o=this.findNearestVertex(n,r.point,i);if(o>=0)return this.startDrag(e,o),!0;const a=Q(n),h=this.findNearestPoint(a,r.point,i);if(h>=0){const d=v(e),u=Ve(e,h+1,a[h]);return this.context.store.update(t,u),this.renderHandles(u),this.startDrag(u,h+1,d),!0}return!1}handleDragMove(e,t){if(!this.dragging)return!1;const r=this.context.store.getById(e);if(!r)return!0;const n=[t.lngLat.lng,t.lngLat.lat],i=Ae(r,this.dragVertexIndex,n);return he(i.geometry.coordinates[0])||(this.context.store.update(e,i),this.context.render.renderFeatures(),this.renderHandles(i)),!0}updateHighlightIfNeeded(e,t){const r=z(e),n=this.getThreshold(t),i=this.findNearestVertex(r,t.point,n);i!==this.highlightedVertexIndex&&(this.highlightedVertexIndex=i,this.renderHandles(e))}deleteVertexAtPointer(e,t,r){const n=z(t),i=this.getThreshold(r),o=this.findNearestVertex(n,r.point,i);if(o<0||n.length<=Ne)return!1;const a=v(t),h=Re(t,o);this.context.store.update(e,h);const d=new ae(e,a,v(h));return this.context.history.push(d),this.context.events.emit("update",{feature:v(h),oldFeature:v(a)}),this.context.render.renderFeatures(),this.renderHandles(h),!0}renderHandles(e){const t=z(e),r=Q(t);this.context.render.renderVertices(t,r,this.highlightedVertexIndex>=0?this.highlightedVertexIndex:void 0)}endDrag(){this.dragging&&this.context.setDragPan(!0),this.dragging=!1,this.dragVertexIndex=-1,this.dragStartFeature=null}startDrag(e,t,r=v(e)){this.dragging=!0,this.dragVertexIndex=t,this.dragStartFeature=r,this.context.setDragPan(!1)}getThreshold(e){return e.inputType==="touch"?_e:ee}findNearestVertex(e,t,r){return this.findNearestPoint(e,t,r)}findNearestPoint(e,t,r=ee){let n=1/0,i=-1;for(let o=0;o<e.length;o++){const a=this.context.getScreenPoint({lng:e[o][0],lat:e[o][1]}),h=t.x-a.x,d=t.y-a.y,u=Math.sqrt(h*h+d*d);u<=r&&u<n&&(n=u,i=o)}return i}}class Ue{constructor(e,t){this.dragging=!1,this.dragStartFeature=null,this.dragStartLngLat=null,this.context=e,this.onFeatureMoved=t}isDragging(){return this.dragging}getDragStartFeature(){return this.dragStartFeature}startDrag(e,t){this.dragging=!0,this.dragStartFeature=v(e),this.dragStartLngLat=t,this.context.setDragPan(!1)}handleDragMove(e,t){if(!this.dragging)return!1;if(!this.dragStartFeature||!this.dragStartLngLat)return!0;const r=t.lngLat.lng-this.dragStartLngLat.lng,n=t.lngLat.lat-this.dragStartLngLat.lat,i=ke(this.dragStartFeature,r,n);return this.context.store.update(e,i),this.context.render.renderFeatures(),this.onFeatureMoved(i),!0}endDrag(){this.dragging&&this.context.setDragPan(!0),this.dragging=!1,this.dragStartFeature=null,this.dragStartLngLat=null}resetInteractionState(){this.endDrag()}}const _=11102230246251565e-32,D=134217729,Oe=(3+8*_)*_;function Y(s,e,t,r,n){let i,o,a,h,d=e[0],u=r[0],l=0,c=0;u>d==u>-d?(i=d,d=e[++l]):(i=u,u=r[++c]);let g=0;if(l<s&&c<t)for(u>d==u>-d?(o=d+i,a=i-(o-d),d=e[++l]):(o=u+i,a=i-(o-u),u=r[++c]),i=o,a!==0&&(n[g++]=a);l<s&&c<t;)u>d==u>-d?(o=i+d,h=o-i,a=i-(o-h)+(d-h),d=e[++l]):(o=i+u,h=o-i,a=i-(o-h)+(u-h),u=r[++c]),i=o,a!==0&&(n[g++]=a);for(;l<s;)o=i+d,h=o-i,a=i-(o-h)+(d-h),d=e[++l],i=o,a!==0&&(n[g++]=a);for(;c<t;)o=i+u,h=o-i,a=i-(o-h)+(u-h),u=r[++c],i=o,a!==0&&(n[g++]=a);return(i!==0||g===0)&&(n[g++]=i),g}function ze(s,e){let t=e[0];for(let r=1;r<s;r++)t+=e[r];return t}function H(s){return new Float64Array(s)}const He=(3+16*_)*_,je=(2+12*_)*_,We=(9+64*_)*_*_,B=H(4),te=H(8),re=H(12),se=H(16),F=H(4);function Ge(s,e,t,r,n,i,o){let a,h,d,u,l,c,g,m,p,y,f,w,M,I,x,P,T,C;const L=s-n,A=t-n,k=e-i,V=r-i;I=L*V,c=D*L,g=c-(c-L),m=L-g,c=D*V,p=c-(c-V),y=V-p,x=m*y-(I-g*p-m*p-g*y),P=k*A,c=D*k,g=c-(c-k),m=k-g,c=D*A,p=c-(c-A),y=A-p,T=m*y-(P-g*p-m*p-g*y),f=x-T,l=x-f,B[0]=x-(f+l)+(l-T),w=I+f,l=w-I,M=I-(w-l)+(f-l),f=M-P,l=M-f,B[1]=M-(f+l)+(l-P),C=w+f,l=C-w,B[2]=w-(C-l)+(f-l),B[3]=C;let R=ze(4,B),U=je*o;if(R>=U||-R>=U||(l=s-L,a=s-(L+l)+(l-n),l=t-A,d=t-(A+l)+(l-n),l=e-k,h=e-(k+l)+(l-i),l=r-V,u=r-(V+l)+(l-i),a===0&&h===0&&d===0&&u===0)||(U=We*o+Oe*Math.abs(R),R+=L*u+V*a-(k*d+A*h),R>=U||-R>=U))return R;I=a*V,c=D*a,g=c-(c-a),m=a-g,c=D*V,p=c-(c-V),y=V-p,x=m*y-(I-g*p-m*p-g*y),P=h*A,c=D*h,g=c-(c-h),m=h-g,c=D*A,p=c-(c-A),y=A-p,T=m*y-(P-g*p-m*p-g*y),f=x-T,l=x-f,F[0]=x-(f+l)+(l-T),w=I+f,l=w-I,M=I-(w-l)+(f-l),f=M-P,l=M-f,F[1]=M-(f+l)+(l-P),C=w+f,l=C-w,F[2]=w-(C-l)+(f-l),F[3]=C;const ue=Y(4,B,4,F,te);I=L*u,c=D*L,g=c-(c-L),m=L-g,c=D*u,p=c-(c-u),y=u-p,x=m*y-(I-g*p-m*p-g*y),P=k*d,c=D*k,g=c-(c-k),m=k-g,c=D*d,p=c-(c-d),y=d-p,T=m*y-(P-g*p-m*p-g*y),f=x-T,l=x-f,F[0]=x-(f+l)+(l-T),w=I+f,l=w-I,M=I-(w-l)+(f-l),f=M-P,l=M-f,F[1]=M-(f+l)+(l-P),C=w+f,l=C-w,F[2]=w-(C-l)+(f-l),F[3]=C;const ge=Y(ue,te,4,F,re);I=a*u,c=D*a,g=c-(c-a),m=a-g,c=D*u,p=c-(c-u),y=u-p,x=m*y-(I-g*p-m*p-g*y),P=h*d,c=D*h,g=c-(c-h),m=h-g,c=D*d,p=c-(c-d),y=d-p,T=m*y-(P-g*p-m*p-g*y),f=x-T,l=x-f,F[0]=x-(f+l)+(l-T),w=I+f,l=w-I,M=I-(w-l)+(f-l),f=M-P,l=M-f,F[1]=M-(f+l)+(l-P),C=w+f,l=C-w,F[2]=w-(C-l)+(f-l),F[3]=C;const fe=Y(ge,re,4,F,se);return se[fe-1]}function $e(s,e,t,r,n,i){const o=(e-i)*(t-n),a=(s-n)*(r-i),h=o-a,d=Math.abs(o+a);return Math.abs(h)>=He*d?h:-Ge(s,e,t,r,n,i,d)}function Je(s,e){var t,r,n=0,i,o,a,h,d,u,l,c=s[0],g=s[1],m=e.length;for(t=0;t<m;t++){r=0;var p=e[t],y=p.length-1;if(u=p[0],u[0]!==p[y][0]&&u[1]!==p[y][1])throw new Error("First and last coordinates in a ring must be the same");for(o=u[0]-c,a=u[1]-g,r;r<y;r++){if(l=p[r+1],h=l[0]-c,d=l[1]-g,a===0&&d===0){if(h<=0&&o>=0||o<=0&&h>=0)return 0}else if(d>=0&&a<=0||d<=0&&a>=0){if(i=$e(o,h,a,d,0,0),i===0)return 0;(i>0&&d>0&&a<=0||i<0&&d<=0&&a>0)&&n++}u=l,a=d,o=h}}return n%2!==0}function Ke(s,e,t={}){const r={type:"Feature"};return(t.id===0||t.id)&&(r.id=t.id),t.bbox&&(r.bbox=t.bbox),r.properties={},r.geometry=s,r}function ie(s,e,t={}){if(!s)throw new Error("coordinates is required");if(!Array.isArray(s))throw new Error("coordinates must be an Array");if(s.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!ne(s[0])||!ne(s[1]))throw new Error("coordinates must contain numbers");return Ke({type:"Point",coordinates:s},e,t)}function ne(s){return!isNaN(s)&&s!==null&&!Array.isArray(s)}function Ye(s){if(!s)throw new Error("coord is required");if(!Array.isArray(s)){if(s.type==="Feature"&&s.geometry!==null&&s.geometry.type==="Point")return[...s.geometry.coordinates];if(s.type==="Point")return[...s.coordinates]}if(Array.isArray(s)&&s.length>=2&&!Array.isArray(s[0])&&!Array.isArray(s[1]))return[...s];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function qe(s){return s.type==="Feature"?s.geometry:s}function Xe(s,e,t={}){if(!s)throw new Error("point is required");if(!e)throw new Error("polygon is required");const r=Ye(s),n=qe(e),i=n.type,o=e.bbox;let a=n.coordinates;if(o&&Ze(r,o)===!1)return!1;i==="Polygon"&&(a=[a]);let h=!1;for(var d=0;d<a.length;++d){const u=Je(r,a[d]);if(u===0)return!t.ignoreBoundary;u&&(h=!0)}return h}function Ze(s,e){return e[0]<=s[0]&&e[1]<=s[1]&&e[2]>=s[0]&&e[3]>=s[1]}var oe=Xe;class Qe{constructor(e,t){this.isActive=!1,this.context=e,this.selection=new Le(e,t),this.vertexEditor=new Be(e),this.polygonDragger=new Ue(e,r=>{this.vertexEditor.renderHandles(r)})}mapInteractions(){return{dragPan:!0,doubleClickZoom:!1}}activate(){this.isActive=!0}deactivate(){this.isActive=!1,this.forceClearSelectionState()}getSelectedIds(){return this.selection.getSelectedIds()}selectFeature(e){if(!this.isActive)return!1;const t=this.context.store.getById(e);return t?(this.vertexEditor.resetInteractionState(),this.polygonDragger.resetInteractionState(),this.selection.selectOnly(e),this.vertexEditor.renderHandles(t),this.selection.notify(),this.context.render.renderFeatures(),!0):!1}clearSelection(){this.isActive&&this.selection.hasSelection()&&(this.forceClearSelectionState(),this.context.render.renderFeatures())}onPointerDown(e){if(!this.isActive)return;const t=this.selection.getFirstSelectedId();if(t){const o=this.context.store.getById(t);if(o){if(this.vertexEditor.tryStartVertexDragOrInsert(o,t,e))return;const a=ie([e.lngLat.lng,e.lngLat.lat]);if(oe(a,o.geometry)){this.polygonDragger.startDrag(o,e.lngLat);return}}}this.vertexEditor.clearHighlight();const r=ie([e.lngLat.lng,e.lngLat.lat]),n=this.context.store.getAll();let i;for(let o=n.length-1;o>=0;o--){const a=n[o];if(oe(r,a.geometry)){i=a;break}}i?this.selection.has(i.id)?(this.selection.remove(i.id),this.context.render.clearVertices()):(this.selection.selectOnly(i.id),this.vertexEditor.renderHandles(i)):(this.selection.clear(),this.context.render.clearVertices()),this.selection.notify(),this.context.render.renderFeatures()}onPointerMove(e){if(!this.isActive)return;const t=this.selection.getFirstSelectedId();if(!t||this.vertexEditor.handleDragMove(t,e)||this.polygonDragger.handleDragMove(t,e))return;const r=this.context.store.getById(t);r&&this.vertexEditor.updateHighlightIfNeeded(r,e)}onPointerUp(e){if(!this.isActive)return;const t=this.vertexEditor.isDragging(),r=this.polygonDragger.isDragging();if(!t&&!r)return;const n=this.selection.getFirstSelectedId();if(!n){this.vertexEditor.endDrag(),this.polygonDragger.endDrag();return}if(t){this.commitDragUpdate(n,this.vertexEditor.getDragStartFeature()),this.vertexEditor.endDrag();return}r&&(this.commitDragUpdate(n,this.polygonDragger.getDragStartFeature()),this.polygonDragger.endDrag())}onDoubleClick(e){if(!this.isActive)return;const t=this.selection.getFirstSelectedId();if(!t)return;const r=this.context.store.getById(t);r&&this.vertexEditor.deleteVertexAtPointer(t,r,e)&&(e.originalEvent.preventDefault(),e.originalEvent.stopPropagation())}onLongPress(e){if(!this.isActive)return;const t=this.selection.getFirstSelectedId();if(!t)return;const r=this.context.store.getById(t);r&&this.vertexEditor.deleteVertexAtPointer(t,r,e)}onKeyDown(e,t){this.isActive&&(e==="Delete"||e==="Backspace")&&this.deleteSelected()}refreshVertexHandles(){if(!this.isActive)return;const e=this.selection.getFirstSelectedId();if(!e)return;const t=this.context.store.getById(e);t?this.vertexEditor.renderHandles(t):(this.selection.remove(e),this.context.render.clearVertices(),this.selection.notify())}forceClearSelectionState(){this.vertexEditor.resetInteractionState(),this.polygonDragger.resetInteractionState(),this.selection.clearAndNotify()&&this.context.render.clearVertices()}commitDragUpdate(e,t){if(!t)return;const r=this.context.store.getById(e);if(!r||!this.hasGeometryChanged(t,r))return;const n=new ae(e,t,v(r));this.context.history.push(n),this.context.events.emit("update",{feature:v(r),oldFeature:v(t)})}deleteSelected(){if(!this.selection.hasSelection())return;const e=this.selection.getSelectedIds();for(const t of e){const r=this.context.store.getById(t);if(!r)continue;this.context.store.remove(t);const n=new le(r);this.context.history.push(n),this.context.events.emit("delete",{feature:v(r)})}this.selection.clear(),this.context.render.clearVertices(),this.selection.notify(),this.context.render.renderFeatures()}hasGeometryChanged(e,t){const r=e.geometry.coordinates,n=t.geometry.coordinates;if(r.length!==n.length)return!0;for(let i=0;i<r.length;i++){const o=r[i],a=n[i];if(o.length!==a.length)return!0;for(let h=0;h<o.length;h++)if(o[h][0]!==a[h][0]||o[h][1]!==a[h][1])return!0}return!1}}class et{constructor(e,t){this.isPointerDown=!1,this.handleMouseDown=r=>{this.isPointerDown=!0,this.callbacks.onPointerDown(this.normalize(r))},this.handleMouseMoveCanvas=r=>{this.isPointerDown||this.callbacks.onPointerMove(this.normalize(r))},this.handleMouseMoveWindow=r=>{this.isPointerDown&&this.callbacks.onPointerMove(this.normalize(r))},this.handleMouseUpWindow=r=>{this.isPointerDown&&(this.isPointerDown=!1,this.callbacks.onPointerUp(this.normalize(r)))},this.handleDblClick=r=>{this.callbacks.onDoubleClick(this.normalize(r))},this.map=e,this.callbacks=t,this.canvas=e.getCanvasContainer()}enable(){this.canvas.addEventListener("mousedown",this.handleMouseDown),this.canvas.addEventListener("mousemove",this.handleMouseMoveCanvas),window.addEventListener("mousemove",this.handleMouseMoveWindow),window.addEventListener("mouseup",this.handleMouseUpWindow),this.canvas.addEventListener("dblclick",this.handleDblClick)}disable(){this.canvas.removeEventListener("mousedown",this.handleMouseDown),this.canvas.removeEventListener("mousemove",this.handleMouseMoveCanvas),window.removeEventListener("mousemove",this.handleMouseMoveWindow),window.removeEventListener("mouseup",this.handleMouseUpWindow),this.canvas.removeEventListener("dblclick",this.handleDblClick),this.isPointerDown=!1}destroy(){this.disable()}normalize(e){const t=this.canvas.getBoundingClientRect(),r=e.clientX-t.left,n=e.clientY-t.top,i=this.map.unproject([r,n]);return{lngLat:{lng:i.lng,lat:i.lat},point:{x:r,y:n},originalEvent:e,inputType:"mouse"}}}const tt=300,rt=500,st=15;class it{constructor(e,t){this.lastTapTime=0,this.longPressTimer=null,this.touchStartPos=null,this.isPinching=!1,this.longPressFired=!1,this.handleTouchStart=r=>{if(r.touches.length>=2){const i=this.normalize(r);this.isPinching=!0,this.cancelLongPress(),this.endPointerIfActive(i),this.longPressFired=!1;return}this.isPinching=!1;const n=this.normalize(r);this.touchStartPos={x:n.point.x,y:n.point.y},this.longPressFired=!1,this.cancelLongPress(),this.longPressTimer=setTimeout(()=>{!this.touchStartPos||this.isPinching||(this.endPointerIfActive(n),this.longPressFired=!0,this.callbacks.onLongPress(n))},rt),this.callbacks.onPointerDown(n)},this.handleTouchMove=r=>{if(r.touches.length>=2){const i=this.normalize(r);this.isPinching=!0,this.endPointerIfActive(i),this.cancelLongPress();return}if(this.isPinching){this.cancelLongPress();return}const n=this.normalize(r);if(this.touchStartPos){const i=n.point.x-this.touchStartPos.x,o=n.point.y-this.touchStartPos.y;Math.sqrt(i*i+o*o)>st&&this.cancelLongPress()}this.callbacks.onPointerMove(n)},this.handleTouchEnd=r=>{if(this.cancelLongPress(),r.changedTouches.length===0)return;const n=this.normalizeChangedTouch(r);if(this.endPointerIfActive(n),this.isPinching){r.touches.length===0&&(this.isPinching=!1),this.longPressFired=!1;return}if(this.longPressFired){this.longPressFired=!1,this.lastTapTime=0;return}const i=Date.now();i-this.lastTapTime<tt?(this.callbacks.onDoubleClick(n),this.lastTapTime=0):this.lastTapTime=i},this.handleTouchCancel=r=>{this.cancelLongPress(),r.changedTouches.length>0&&this.endPointerIfActive(this.normalizeChangedTouch(r)),this.touchStartPos=null,this.isPinching=!1,this.longPressFired=!1,this.lastTapTime=0},this.map=e,this.callbacks=t,this.canvas=e.getCanvasContainer()}enable(){this.canvas.addEventListener("touchstart",this.handleTouchStart,{passive:!1}),this.canvas.addEventListener("touchmove",this.handleTouchMove,{passive:!1}),this.canvas.addEventListener("touchend",this.handleTouchEnd),this.canvas.addEventListener("touchcancel",this.handleTouchCancel)}disable(){this.canvas.removeEventListener("touchstart",this.handleTouchStart),this.canvas.removeEventListener("touchmove",this.handleTouchMove),this.canvas.removeEventListener("touchend",this.handleTouchEnd),this.canvas.removeEventListener("touchcancel",this.handleTouchCancel),this.cancelLongPress(),this.touchStartPos=null,this.isPinching=!1,this.longPressFired=!1,this.lastTapTime=0}destroy(){this.disable()}cancelLongPress(){this.longPressTimer!==null&&(clearTimeout(this.longPressTimer),this.longPressTimer=null)}endPointerIfActive(e){this.touchStartPos&&(this.callbacks.onPointerUp(e),this.touchStartPos=null)}normalize(e){const t=e.touches[0],r=this.canvas.getBoundingClientRect(),n=t.clientX-r.left,i=t.clientY-r.top,o=this.map.unproject([n,i]);return{lngLat:{lng:o.lng,lat:o.lat},point:{x:n,y:i},originalEvent:e,inputType:"touch"}}normalizeChangedTouch(e){const t=e.changedTouches[0],r=this.canvas.getBoundingClientRect(),n=t.clientX-r.left,i=t.clientY-r.top,o=this.map.unproject([n,i]);return{lngLat:{lng:o.lng,lat:o.lat},point:{x:n,y:i},originalEvent:e,inputType:"touch"}}}const K=class K{constructor(e){this.handleKeyDown=t=>{K.RELEVANT_KEYS.has(t.key)&&this.callbacks.onKeyDown(t.key,t)},this.callbacks=e}enable(){document.addEventListener("keydown",this.handleKeyDown)}disable(){document.removeEventListener("keydown",this.handleKeyDown)}destroy(){this.disable()}};K.RELEVANT_KEYS=new Set(["Escape","Delete","Backspace"]);let q=K;class nt{constructor(e,t){this.getActiveMode=t;const r={onPointerDown:n=>{var i;(i=this.getActiveMode())==null||i.onPointerDown(n)},onPointerMove:n=>{var i;(i=this.getActiveMode())==null||i.onPointerMove(n)},onPointerUp:n=>{var i;(i=this.getActiveMode())==null||i.onPointerUp(n)},onDoubleClick:n=>{var i;(i=this.getActiveMode())==null||i.onDoubleClick(n)},onLongPress:n=>{var i;(i=this.getActiveMode())==null||i.onLongPress(n)}};this.mouseInput=new et(e,r),this.touchInput=new it(e,r),this.keyboardInput=new q({onKeyDown:(n,i)=>{var o;(o=this.getActiveMode())==null||o.onKeyDown(n,i)}})}enable(){this.mouseInput.enable(),this.touchInput.enable(),this.keyboardInput.enable()}disable(){this.mouseInput.disable(),this.touchInput.disable(),this.keyboardInput.disable()}destroy(){this.mouseInput.destroy(),this.touchInput.destroy(),this.keyboardInput.destroy()}}const b={FEATURES:"libre-draw-features",PREVIEW:"libre-draw-preview",EDIT_VERTICES:"libre-draw-edit-vertices"},O={type:"FeatureCollection",features:[]};class ot{constructor(e){this.initialized=!1,this.map=e}hasAllSources(){return!!(this.map.getSource(b.FEATURES)&&this.map.getSource(b.PREVIEW)&&this.map.getSource(b.EDIT_VERTICES))}initialize(){this.initialized&&this.hasAllSources()||(this.map.getSource(b.FEATURES)||this.map.addSource(b.FEATURES,{type:"geojson",data:O}),this.map.getSource(b.PREVIEW)||this.map.addSource(b.PREVIEW,{type:"geojson",data:O}),this.map.getSource(b.EDIT_VERTICES)||this.map.addSource(b.EDIT_VERTICES,{type:"geojson",data:O}),this.initialized=!0)}updateFeatures(e){const t=this.map.getSource(b.FEATURES);t&&t.setData(e)}updatePreview(e){const t=this.map.getSource(b.PREVIEW);t&&t.setData(e)}clearPreview(){this.updatePreview(O)}updateEditVertices(e){const t=this.map.getSource(b.EDIT_VERTICES);t&&t.setData(e)}clearEditVertices(){this.updateEditVertices(O)}destroy(){this.map.getSource(b.FEATURES)&&this.map.removeSource(b.FEATURES),this.map.getSource(b.PREVIEW)&&this.map.removeSource(b.PREVIEW),this.map.getSource(b.EDIT_VERTICES)&&this.map.removeSource(b.EDIT_VERTICES),this.initialized=!1}}const N={fill:{color:"#3bb2d0",opacity:.2,selectedColor:"#fbb03b",selectedOpacity:.4},outline:{color:"#3bb2d0",width:2,selectedColor:"#fbb03b"},vertex:{color:"#ffffff",strokeColor:"#3bb2d0",strokeWidth:2,radius:4},preview:{color:"#3bb2d0",width:2,dasharray:[2,2]},editVertex:{color:"#ffffff",strokeColor:"#3bb2d0",strokeWidth:2,radius:5,highlightedColor:"#ff4444",highlightedStrokeColor:"#cc0000",highlightedRadius:7},midpoint:{color:"#3bb2d0",opacity:.5,radius:3}};function de(s){var e;return{fill:{...N.fill,...s==null?void 0:s.fill},outline:{...N.outline,...s==null?void 0:s.outline},vertex:{...N.vertex,...s==null?void 0:s.vertex},preview:{...N.preview,...s==null?void 0:s.preview,dasharray:[...((e=s==null?void 0:s.preview)==null?void 0:e.dasharray)??N.preview.dasharray]},editVertex:{...N.editVertex,...s==null?void 0:s.editVertex},midpoint:{...N.midpoint,...s==null?void 0:s.midpoint}}}const S={FILL:"libre-draw-fill",OUTLINE:"libre-draw-outline",VERTICES:"libre-draw-vertices",PREVIEW:"libre-draw-preview",EDIT_VERTICES:"libre-draw-edit-vertices",EDIT_MIDPOINTS:"libre-draw-edit-midpoints"};class at{constructor(e,t,r){this.selectedIds=new Set,this.pendingRender=!1,this.pendingFeatures=null,this.initialized=!1,this.map=e,this.sourceManager=t,this.style=de(r)}isReadyForCurrentStyle(){return this.sourceManager.hasAllSources()&&this.hasAllLayers()}initialize(){if(!(this.initialized&&this.isReadyForCurrentStyle())){if(this.sourceManager.initialize(),this.hasAllLayers()){this.initialized=!0;return}this.map.getLayer(S.FILL)||this.map.addLayer({id:S.FILL,type:"fill",source:b.FEATURES,paint:{"fill-color":["case",["boolean",["get","_selected"],!1],this.style.fill.selectedColor,this.style.fill.color],"fill-opacity":["case",["boolean",["get","_selected"],!1],this.style.fill.selectedOpacity,this.style.fill.opacity]}}),this.map.getLayer(S.OUTLINE)||this.map.addLayer({id:S.OUTLINE,type:"line",source:b.FEATURES,paint:{"line-color":["case",["boolean",["get","_selected"],!1],this.style.outline.selectedColor,this.style.outline.color],"line-width":this.style.outline.width}}),this.map.getLayer(S.VERTICES)||this.map.addLayer({id:S.VERTICES,type:"circle",source:b.FEATURES,filter:["==","$type","Point"],paint:{"circle-radius":this.style.vertex.radius,"circle-color":this.style.vertex.color,"circle-stroke-color":this.style.vertex.strokeColor,"circle-stroke-width":this.style.vertex.strokeWidth}}),this.map.getLayer(S.PREVIEW)||this.map.addLayer({id:S.PREVIEW,type:"line",source:b.PREVIEW,paint:{"line-color":this.style.preview.color,"line-width":this.style.preview.width,"line-dasharray":this.style.preview.dasharray}}),this.map.getLayer(S.EDIT_MIDPOINTS)||this.map.addLayer({id:S.EDIT_MIDPOINTS,type:"circle",source:b.EDIT_VERTICES,filter:["==",["get","_type"],"midpoint"],paint:{"circle-radius":this.style.midpoint.radius,"circle-color":this.style.midpoint.color,"circle-opacity":this.style.midpoint.opacity}}),this.map.getLayer(S.EDIT_VERTICES)||this.map.addLayer({id:S.EDIT_VERTICES,type:"circle",source:b.EDIT_VERTICES,filter:["==",["get","_type"],"vertex"],paint:{"circle-radius":["case",["boolean",["get","_highlighted"],!1],this.style.editVertex.highlightedRadius,this.style.editVertex.radius],"circle-color":["case",["boolean",["get","_highlighted"],!1],this.style.editVertex.highlightedColor,this.style.editVertex.color],"circle-stroke-color":["case",["boolean",["get","_highlighted"],!1],this.style.editVertex.highlightedStrokeColor,this.style.editVertex.strokeColor],"circle-stroke-width":this.style.editVertex.strokeWidth}}),this.initialized=!0}}render(e){this.pendingFeatures=e,this.pendingRender||(this.pendingRender=!0,requestAnimationFrame(()=>{this.performRender(),this.pendingRender=!1}))}renderPreview(e){if(e.length<2){this.clearPreview();return}const t=e.map(n=>[n[0],n[1]]),r={type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:t}}]};this.sourceManager.updatePreview(r)}clearPreview(){this.sourceManager.clearPreview()}renderVertices(e,t,r){const n=[];for(let i=0;i<e.length;i++){const o=e[i];n.push({type:"Feature",properties:{_type:"vertex",_highlighted:i===r},geometry:{type:"Point",coordinates:[o[0],o[1]]}})}for(const i of t)n.push({type:"Feature",properties:{_type:"midpoint"},geometry:{type:"Point",coordinates:[i[0],i[1]]}});this.sourceManager.updateEditVertices({type:"FeatureCollection",features:n})}clearVertices(){this.sourceManager.clearEditVertices()}setSelectedIds(e){this.selectedIds=new Set(e)}destroy(){const e=[S.EDIT_VERTICES,S.EDIT_MIDPOINTS,S.PREVIEW,S.VERTICES,S.OUTLINE,S.FILL];for(const t of e)this.map.getLayer(t)&&this.map.removeLayer(t);this.sourceManager.destroy(),this.initialized=!1}performRender(){if(!this.pendingFeatures)return;const t={type:"FeatureCollection",features:this.pendingFeatures.map(r=>({type:"Feature",id:r.id,properties:{...r.properties,_id:r.id,_selected:this.selectedIds.has(r.id)},geometry:r.geometry}))};this.sourceManager.updateFeatures(t),this.pendingFeatures=null}hasAllLayers(){return!!(this.map.getLayer(S.FILL)&&this.map.getLayer(S.OUTLINE)&&this.map.getLayer(S.VERTICES)&&this.map.getLayer(S.PREVIEW)&&this.map.getLayer(S.EDIT_MIDPOINTS)&&this.map.getLayer(S.EDIT_VERTICES))}}class lt{constructor(e){this.options=e,this.element=document.createElement("button"),this.element.type="button",this.element.title=e.title,this.element.setAttribute("aria-label",e.title),this.element.dataset.libreDrawButton=e.id,this.applyStyles(),this.iconContainer=document.createElement("span"),this.iconContainer.style.display="flex",this.iconContainer.style.alignItems="center",this.iconContainer.style.justifyContent="center",this.setIcon(e.icon),this.element.appendChild(this.iconContainer),this.element.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.element.disabled||e.onClick()})}getElement(){return this.element}setActive(e){e?(this.element.style.backgroundColor="#3bb2d0",this.element.style.color="#ffffff"):(this.element.style.backgroundColor="#ffffff",this.element.style.color="#333333"),this.element.setAttribute("aria-pressed",String(e))}setDisabled(e){this.element.disabled=e,this.element.style.opacity=e?"0.4":"1",this.element.style.cursor=e?"not-allowed":"pointer"}destroy(){this.element.remove()}setIcon(e){const n=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;for(;this.iconContainer.firstChild;)this.iconContainer.removeChild(this.iconContainer.firstChild);this.iconContainer.appendChild(document.importNode(n,!0))}applyStyles(){const e=this.element.style;e.display="flex",e.alignItems="center",e.justifyContent="center",e.width="44px",e.height="44px",e.padding="0",e.margin="0",e.border="1px solid #ddd",e.borderRadius="4px",e.backgroundColor="#ffffff",e.color="#333333",e.cursor="pointer",e.outline="none",e.transition="background-color 0.15s, color 0.15s",e.boxSizing="border-box"}}const ht='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l8.5 6.2-3.2 9.8H6.7L3.5 8.2z"/></svg>',ct='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/></svg>',dt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>',ut='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 00-4-4H4"/></svg>',gt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 14 20 9 15 4"/><path d="M4 20v-7a4 4 0 014-4h12"/></svg>',ft={draw:!0,select:!0,delete:!0,undo:!0,redo:!0};class pt{constructor(e,t,r={}){this.buttons=new Map,this.map=e,this.callbacks=t,this.options=r,this.container=document.createElement("div"),this.container.className="libre-draw-toolbar",this.applyContainerStyles(),this.createButtons(),this.mount()}setActiveMode(e){const t=this.buttons.get("draw"),r=this.buttons.get("select");t&&t.setActive(e==="draw"),r&&r.setActive(e==="select")}setHistoryState(e,t){const r=this.buttons.get("undo"),n=this.buttons.get("redo");r&&r.setDisabled(!e),n&&n.setDisabled(!t)}destroy(){for(const e of this.buttons.values())e.destroy();this.buttons.clear(),this.container.remove()}createButtons(){const e={...ft,...this.options.controls};e.draw&&this.addButton("draw",ht,"Draw polygon",()=>{this.callbacks.onDrawClick()},!0),e.select&&this.addButton("select",ct,"Select feature",()=>{this.callbacks.onSelectClick()},!0),e.delete&&this.addButton("delete",dt,"Delete selected",()=>{this.callbacks.onDeleteClick()}),e.undo&&this.addButton("undo",ut,"Undo",()=>{this.callbacks.onUndoClick()}),e.redo&&this.addButton("redo",gt,"Redo",()=>{this.callbacks.onRedoClick()})}addButton(e,t,r,n,i){const o=new lt({id:e,icon:t,title:r,onClick:n,isToggle:i});this.buttons.set(e,o),this.container.appendChild(o.getElement())}mount(){const e=this.options.position||"top-right",t=this.map.getContainer(),r=t.querySelector(`.maplibregl-ctrl-${e}`);r?r.appendChild(this.container):t.appendChild(this.container)}applyContainerStyles(){const e=this.container.style;e.display="flex",e.flexDirection="column",e.gap="4px",e.padding="4px",e.backgroundColor="rgba(255, 255, 255, 0.9)",e.borderRadius="4px",e.boxShadow="0 1px 4px rgba(0, 0, 0, 0.3)",e.zIndex="1",e.pointerEvents="auto"}}class yt{constructor(e,t={}){this.toolbar=null,this.destroyed=!1,this.inputEnabled=!1,this.handleStyleData=()=>{this.destroyed||!this.map.isStyleLoaded()||this.renderManager.isReadyForCurrentStyle()||(this.renderManager.initialize(),this.renderAllFeatures(),this.modeManager.getMode()==="select"?this.selectMode.refreshVertexHandles():this.renderManager.clearVertices())},this.map=e,this.eventBus=new we,this.featureStore=new Se,this.historyManager=new be(t.historyLimit??100),this.modeManager=new Ee,this.sourceManager=new ot(e),this.renderManager=new at(e,this.sourceManager,t.style);const r={store:{add:o=>this.featureStore.add(o),update:(o,a)=>this.featureStore.update(o,a),remove:o=>this.featureStore.remove(o),getById:o=>this.featureStore.getById(o),getAll:()=>this.featureStore.getAll()},history:{push:o=>{this.historyManager.push(o),this.updateToolbarHistoryState()}},events:{emit:(o,a)=>this.eventBus.emit(o,a)},render:{renderFeatures:()=>this.renderAllFeatures(),renderPreview:o=>this.renderManager.renderPreview(o),clearPreview:()=>this.renderManager.clearPreview(),renderVertices:(o,a,h)=>this.renderManager.renderVertices(o,a,h),clearVertices:()=>this.renderManager.clearVertices(),setSelectedIds:o=>this.renderManager.setSelectedIds(o)},getScreenPoint:o=>{const a=e.project([o.lng,o.lat]);return{x:a.x,y:a.y}},setDragPan:o=>{o?e.dragPan.enable():e.dragPan.disable()}},n=new Te(r);this.selectMode=new Qe(r),this.modeManager.registerMode("idle",new De),this.modeManager.registerMode("draw",n),this.modeManager.registerMode("select",this.selectMode),this.modeManager.setOnModeChange((o,a)=>{this.eventBus.emit("modechange",{mode:o,previousMode:a}),this.toolbar&&this.toolbar.setActiveMode(o);const h=this.modeManager.getCurrentMode();h&&this.applyMapInteractions(h.mapInteractions())});const i=this.modeManager.getCurrentMode();if(i&&this.applyMapInteractions(i.mapInteractions()),this.inputHandler=new nt(e,()=>this.modeManager.getCurrentMode()),t.toolbar!==!1&&t.toolbar!==void 0){const o=typeof t.toolbar=="object"?t.toolbar:{};this.createToolbar(o)}e.on("styledata",this.handleStyleData),e.isStyleLoaded()?this.initialize():e.once("load",()=>{this.initialize()})}setMode(e){this.assertNotDestroyed(),this.modeManager.setMode(e)}getMode(){return this.assertNotDestroyed(),this.modeManager.getMode()}getFeatures(){return this.assertNotDestroyed(),this.featureStore.getAll()}toGeoJSON(){return this.assertNotDestroyed(),this.featureStore.toGeoJSON()}setFeatures(e){this.assertNotDestroyed();const t=Ce(e);this.featureStore.setAll(t.features),this.resetSelectionState(),this.historyManager.clear(),this.renderAllFeatures(),this.updateToolbarHistoryState()}addFeatures(e){this.assertNotDestroyed();for(const t of e){const r=ce(t);this.featureStore.add(r)}this.renderAllFeatures()}getSelectedFeatureIds(){return this.assertNotDestroyed(),this.selectMode.getSelectedIds()}getFeatureById(e){return this.assertNotDestroyed(),this.featureStore.getById(e)}deleteFeature(e){this.assertNotDestroyed();const t=this.featureStore.getById(e);if(!t)return;this.selectMode.getSelectedIds().includes(e)&&this.selectMode.clearSelection(),this.featureStore.remove(e);const n=new le(t);return this.historyManager.push(n),this.eventBus.emit("delete",{feature:v(t)}),this.renderAllFeatures(),this.updateToolbarHistoryState(),t}selectFeature(e){if(this.assertNotDestroyed(),!this.featureStore.getById(e))throw new E(`Feature not found: ${e}`);this.modeManager.getMode()!=="select"&&this.modeManager.setMode("select"),this.selectMode.selectFeature(e)}clearSelection(){this.assertNotDestroyed(),this.selectMode.clearSelection()}undo(){this.assertNotDestroyed();const e=this.historyManager.undo(this.featureStore);return e&&(this.renderAllFeatures(),this.selectMode.refreshVertexHandles(),this.updateToolbarHistoryState()),e}redo(){this.assertNotDestroyed();const e=this.historyManager.redo(this.featureStore);return e&&(this.renderAllFeatures(),this.selectMode.refreshVertexHandles(),this.updateToolbarHistoryState()),e}on(e,t){this.assertNotDestroyed(),this.eventBus.on(e,t)}off(e,t){this.assertNotDestroyed(),this.eventBus.off(e,t)}destroy(){this.destroyed||(this.destroyed=!0,this.map.off("styledata",this.handleStyleData),this.modeManager.setMode("idle"),this.inputHandler.destroy(),this.renderManager.destroy(),this.eventBus.removeAllListeners(),this.historyManager.clear(),this.featureStore.clear(),this.toolbar&&(this.toolbar.destroy(),this.toolbar=null))}initialize(){this.destroyed||(this.renderManager.initialize(),this.inputEnabled||(this.inputHandler.enable(),this.inputEnabled=!0),this.renderAllFeatures())}renderAllFeatures(){const e=this.featureStore.getAll();this.renderManager.render(e)}createToolbar(e){this.toolbar=new pt(this.map,{onDrawClick:()=>{const t=this.modeManager.getMode();this.modeManager.setMode(t==="draw"?"idle":"draw")},onSelectClick:()=>{const t=this.modeManager.getMode();this.modeManager.setMode(t==="select"?"idle":"select")},onDeleteClick:()=>{if(this.modeManager.getMode()==="select"){const t=this.selectMode.getSelectedIds();for(const r of t)this.deleteFeature(r)}},onUndoClick:()=>{this.undo()},onRedoClick:()=>{this.redo()}},e),this.toolbar.setActiveMode(this.modeManager.getMode()),this.toolbar.setHistoryState(this.historyManager.canUndo(),this.historyManager.canRedo())}applyMapInteractions(e){e.dragPan?this.map.dragPan.enable():this.map.dragPan.disable(),e.doubleClickZoom?this.map.doubleClickZoom.enable():this.map.doubleClickZoom.disable()}updateToolbarHistoryState(){this.toolbar&&this.toolbar.setHistoryState(this.historyManager.canUndo(),this.historyManager.canRedo())}resetSelectionState(){this.selectMode.clearSelection(),this.renderManager.setSelectedIds([]),this.renderManager.clearVertices()}assertNotDestroyed(){if(this.destroyed)throw new E("This LibreDraw instance has been destroyed.")}}exports.DEFAULT_STYLE_CONFIG=N;exports.LibreDraw=yt;exports.LibreDrawError=E;exports.mergeStyleConfig=de;
|
|
2
2
|
//# sourceMappingURL=libre-draw.cjs.map
|