` element
+// and optionally an object literal with `Map options`.
+//
+// @alternative
+// @factory L.map(el: HTMLElement, options?: Map options)
+// Instantiates a map object given an instance of a `
` HTML element
+// and optionally an object literal with `Map options`.
+export function createMap(id, options) {
+ return new Map(id, options);
+}
diff --git a/packages/core/node_modules/leaflet/src/map/Map.methodOptions.leafdoc b/packages/core/node_modules/leaflet/src/map/Map.methodOptions.leafdoc
new file mode 100644
index 00000000..a625fee8
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/Map.methodOptions.leafdoc
@@ -0,0 +1,112 @@
+
+This file documents the common options passed to several map methods.
+
+
+@miniclass Locate options (Map)
+@aka locate options
+@section
+
+Some of the geolocation methods for `Map` take in an `options` parameter. This
+is a plain javascript object with the following optional components:
+
+@option watch: Boolean = false
+If `true`, starts continuous watching of location changes (instead of detecting it
+once) using W3C `watchPosition` method. You can later stop watching using
+`map.stopLocate()` method.
+
+
+@option setView: Boolean = false
+If `true`, automatically sets the map view to the user location with respect to
+detection accuracy, or to world view if geolocation failed.
+
+@option maxZoom: Number = Infinity
+The maximum zoom for automatic view setting when using `setView` option.
+
+@option timeout: Number = 10000
+Number of milliseconds to wait for a response from geolocation before firing a
+`locationerror` event.
+
+@option maximumAge: Number = 0
+Maximum age of detected location. If less than this amount of milliseconds
+passed since last geolocation response, `locate` will return a cached location.
+
+@option enableHighAccuracy: Boolean = false
+Enables high accuracy, see [description in the W3C spec](https://w3c.github.io/geolocation-api/#enablehighaccuracy-member).
+
+
+
+@miniclass Zoom options (Map)
+@aka zoom options
+@section
+
+Some of the `Map` methods which modify the zoom level take in an `options`
+parameter. This is a plain javascript object with the following optional
+components:
+
+
+@option animate: Boolean
+If not specified, zoom animation will happen if the zoom origin is inside the
+current view. If `true`, the map will attempt animating zoom disregarding where
+zoom origin is. Setting `false` will make it always reset the view completely
+without animation.
+
+
+
+
+@miniclass Pan options (Map)
+@aka pan options
+@section
+
+Some of the `Map` methods which modify the center of the map take in an `options`
+parameter. This is a plain javascript object with the following optional
+components:
+
+@option animate: Boolean
+If `true`, panning will always be animated if possible. If `false`, it will
+not animate panning, either resetting the map view if panning more than a
+screen away, or just setting a new offset for the map pane (except for `panBy`
+which always does the latter).
+
+@option duration: Number = 0.25
+Duration of animated panning, in seconds.
+
+@option easeLinearity: Number = 0.25
+The curvature factor of panning animation easing (third parameter of the
+[Cubic Bezier curve](https://cubic-bezier.com/)). 1.0 means linear animation,
+and the smaller this number, the more bowed the curve.
+
+@option noMoveStart: Boolean = false
+If `true`, panning won't fire `movestart` event on start (used internally for
+panning inertia).
+
+
+@miniclass Zoom/pan options (Map)
+@aka zoom/pan options
+@inherits Zoom options
+@inherits Pan options
+
+
+@miniclass Padding options (Map)
+@aka padding options
+@option paddingTopLeft: Point = [0, 0]
+Sets the amount of padding in the top left corner of a map container that
+shouldn't be accounted for when setting the view to fit bounds. Useful if you
+have some control overlays on the map like a sidebar and you don't want them
+to obscure objects you're zooming to.
+
+@option paddingBottomRight: Point = [0, 0]
+The same for the bottom right corner of the map.
+
+@option padding: Point = [0, 0]
+Equivalent of setting both top left and bottom right padding to the same value.
+
+
+@miniclass FitBounds options (Map)
+@aka fitBounds options
+@inherits Zoom/pan options
+@inherits Padding options
+
+@option maxZoom: Number = null
+The maximum possible zoom to use.
+
+
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.BoxZoom.js b/packages/core/node_modules/leaflet/src/map/handler/Map.BoxZoom.js
new file mode 100644
index 00000000..522cfd03
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.BoxZoom.js
@@ -0,0 +1,152 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import * as Util from '../../core/Util';
+import * as DomUtil from '../../dom/DomUtil';
+import * as DomEvent from '../../dom/DomEvent';
+import {LatLngBounds} from '../../geo/LatLngBounds';
+import {Bounds} from '../../geometry/Bounds';
+
+/*
+ * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
+ * (zoom to a selected bounding box), enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+ // @option boxZoom: Boolean = true
+ // Whether the map can be zoomed to a rectangular area specified by
+ // dragging the mouse while pressing the shift key.
+ boxZoom: true
+});
+
+export var BoxZoom = Handler.extend({
+ initialize: function (map) {
+ this._map = map;
+ this._container = map._container;
+ this._pane = map._panes.overlayPane;
+ this._resetStateTimeout = 0;
+ map.on('unload', this._destroy, this);
+ },
+
+ addHooks: function () {
+ DomEvent.on(this._container, 'mousedown', this._onMouseDown, this);
+ },
+
+ removeHooks: function () {
+ DomEvent.off(this._container, 'mousedown', this._onMouseDown, this);
+ },
+
+ moved: function () {
+ return this._moved;
+ },
+
+ _destroy: function () {
+ DomUtil.remove(this._pane);
+ delete this._pane;
+ },
+
+ _resetState: function () {
+ this._resetStateTimeout = 0;
+ this._moved = false;
+ },
+
+ _clearDeferredResetState: function () {
+ if (this._resetStateTimeout !== 0) {
+ clearTimeout(this._resetStateTimeout);
+ this._resetStateTimeout = 0;
+ }
+ },
+
+ _onMouseDown: function (e) {
+ if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
+
+ // Clear the deferred resetState if it hasn't executed yet, otherwise it
+ // will interrupt the interaction and orphan a box element in the container.
+ this._clearDeferredResetState();
+ this._resetState();
+
+ DomUtil.disableTextSelection();
+ DomUtil.disableImageDrag();
+
+ this._startPoint = this._map.mouseEventToContainerPoint(e);
+
+ DomEvent.on(document, {
+ contextmenu: DomEvent.stop,
+ mousemove: this._onMouseMove,
+ mouseup: this._onMouseUp,
+ keydown: this._onKeyDown
+ }, this);
+ },
+
+ _onMouseMove: function (e) {
+ if (!this._moved) {
+ this._moved = true;
+
+ this._box = DomUtil.create('div', 'leaflet-zoom-box', this._container);
+ DomUtil.addClass(this._container, 'leaflet-crosshair');
+
+ this._map.fire('boxzoomstart');
+ }
+
+ this._point = this._map.mouseEventToContainerPoint(e);
+
+ var bounds = new Bounds(this._point, this._startPoint),
+ size = bounds.getSize();
+
+ DomUtil.setPosition(this._box, bounds.min);
+
+ this._box.style.width = size.x + 'px';
+ this._box.style.height = size.y + 'px';
+ },
+
+ _finish: function () {
+ if (this._moved) {
+ DomUtil.remove(this._box);
+ DomUtil.removeClass(this._container, 'leaflet-crosshair');
+ }
+
+ DomUtil.enableTextSelection();
+ DomUtil.enableImageDrag();
+
+ DomEvent.off(document, {
+ contextmenu: DomEvent.stop,
+ mousemove: this._onMouseMove,
+ mouseup: this._onMouseUp,
+ keydown: this._onKeyDown
+ }, this);
+ },
+
+ _onMouseUp: function (e) {
+ if ((e.which !== 1) && (e.button !== 1)) { return; }
+
+ this._finish();
+
+ if (!this._moved) { return; }
+ // Postpone to next JS tick so internal click event handling
+ // still see it as "moved".
+ this._clearDeferredResetState();
+ this._resetStateTimeout = setTimeout(Util.bind(this._resetState, this), 0);
+
+ var bounds = new LatLngBounds(
+ this._map.containerPointToLatLng(this._startPoint),
+ this._map.containerPointToLatLng(this._point));
+
+ this._map
+ .fitBounds(bounds)
+ .fire('boxzoomend', {boxZoomBounds: bounds});
+ },
+
+ _onKeyDown: function (e) {
+ if (e.keyCode === 27) {
+ this._finish();
+ this._clearDeferredResetState();
+ this._resetState();
+ }
+ }
+});
+
+// @section Handlers
+// @property boxZoom: Handler
+// Box (shift-drag with mouse) zoom handler.
+Map.addInitHook('addHandler', 'boxZoom', BoxZoom);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.DoubleClickZoom.js b/packages/core/node_modules/leaflet/src/map/handler/Map.DoubleClickZoom.js
new file mode 100644
index 00000000..c105e8e0
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.DoubleClickZoom.js
@@ -0,0 +1,55 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+
+/*
+ * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+
+Map.mergeOptions({
+ // @option doubleClickZoom: Boolean|String = true
+ // Whether the map can be zoomed in by double clicking on it and
+ // zoomed out by double clicking while holding shift. If passed
+ // `'center'`, double-click zoom will zoom to the center of the
+ // view regardless of where the mouse was.
+ doubleClickZoom: true
+});
+
+export var DoubleClickZoom = Handler.extend({
+ addHooks: function () {
+ this._map.on('dblclick', this._onDoubleClick, this);
+ },
+
+ removeHooks: function () {
+ this._map.off('dblclick', this._onDoubleClick, this);
+ },
+
+ _onDoubleClick: function (e) {
+ var map = this._map,
+ oldZoom = map.getZoom(),
+ delta = map.options.zoomDelta,
+ zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
+
+ if (map.options.doubleClickZoom === 'center') {
+ map.setZoom(zoom);
+ } else {
+ map.setZoomAround(e.containerPoint, zoom);
+ }
+ }
+});
+
+// @section Handlers
+//
+// Map properties include interaction handlers that allow you to control
+// interaction behavior in runtime, enabling or disabling certain features such
+// as dragging or touch zoom (see `Handler` methods). For example:
+//
+// ```js
+// map.doubleClickZoom.disable();
+// ```
+//
+// @property doubleClickZoom: Handler
+// Double click zoom handler.
+Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.Drag.js b/packages/core/node_modules/leaflet/src/map/handler/Map.Drag.js
new file mode 100644
index 00000000..295f70fc
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.Drag.js
@@ -0,0 +1,235 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import {Draggable} from '../../dom/Draggable';
+import * as Util from '../../core/Util';
+import * as DomUtil from '../../dom/DomUtil';
+import {toLatLngBounds as latLngBounds} from '../../geo/LatLngBounds';
+import {toBounds} from '../../geometry/Bounds';
+
+/*
+ * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+ // @option dragging: Boolean = true
+ // Whether the map is draggable with mouse/touch or not.
+ dragging: true,
+
+ // @section Panning Inertia Options
+ // @option inertia: Boolean = *
+ // If enabled, panning of the map will have an inertia effect where
+ // the map builds momentum while dragging and continues moving in
+ // the same direction for some time. Feels especially nice on touch
+ // devices. Enabled by default.
+ inertia: true,
+
+ // @option inertiaDeceleration: Number = 3000
+ // The rate with which the inertial movement slows down, in pixels/secondĀ².
+ inertiaDeceleration: 3400, // px/s^2
+
+ // @option inertiaMaxSpeed: Number = Infinity
+ // Max speed of the inertial movement, in pixels/second.
+ inertiaMaxSpeed: Infinity, // px/s
+
+ // @option easeLinearity: Number = 0.2
+ easeLinearity: 0.2,
+
+ // TODO refactor, move to CRS
+ // @option worldCopyJump: Boolean = false
+ // With this option enabled, the map tracks when you pan to another "copy"
+ // of the world and seamlessly jumps to the original one so that all overlays
+ // like markers and vector layers are still visible.
+ worldCopyJump: false,
+
+ // @option maxBoundsViscosity: Number = 0.0
+ // If `maxBounds` is set, this option will control how solid the bounds
+ // are when dragging the map around. The default value of `0.0` allows the
+ // user to drag outside the bounds at normal speed, higher values will
+ // slow down map dragging outside bounds, and `1.0` makes the bounds fully
+ // solid, preventing the user from dragging outside the bounds.
+ maxBoundsViscosity: 0.0
+});
+
+export var Drag = Handler.extend({
+ addHooks: function () {
+ if (!this._draggable) {
+ var map = this._map;
+
+ this._draggable = new Draggable(map._mapPane, map._container);
+
+ this._draggable.on({
+ dragstart: this._onDragStart,
+ drag: this._onDrag,
+ dragend: this._onDragEnd
+ }, this);
+
+ this._draggable.on('predrag', this._onPreDragLimit, this);
+ if (map.options.worldCopyJump) {
+ this._draggable.on('predrag', this._onPreDragWrap, this);
+ map.on('zoomend', this._onZoomEnd, this);
+
+ map.whenReady(this._onZoomEnd, this);
+ }
+ }
+ DomUtil.addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
+ this._draggable.enable();
+ this._positions = [];
+ this._times = [];
+ },
+
+ removeHooks: function () {
+ DomUtil.removeClass(this._map._container, 'leaflet-grab');
+ DomUtil.removeClass(this._map._container, 'leaflet-touch-drag');
+ this._draggable.disable();
+ },
+
+ moved: function () {
+ return this._draggable && this._draggable._moved;
+ },
+
+ moving: function () {
+ return this._draggable && this._draggable._moving;
+ },
+
+ _onDragStart: function () {
+ var map = this._map;
+
+ map._stop();
+ if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
+ var bounds = latLngBounds(this._map.options.maxBounds);
+
+ this._offsetLimit = toBounds(
+ this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
+ this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
+ .add(this._map.getSize()));
+
+ this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
+ } else {
+ this._offsetLimit = null;
+ }
+
+ map
+ .fire('movestart')
+ .fire('dragstart');
+
+ if (map.options.inertia) {
+ this._positions = [];
+ this._times = [];
+ }
+ },
+
+ _onDrag: function (e) {
+ if (this._map.options.inertia) {
+ var time = this._lastTime = +new Date(),
+ pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
+
+ this._positions.push(pos);
+ this._times.push(time);
+
+ this._prunePositions(time);
+ }
+
+ this._map
+ .fire('move', e)
+ .fire('drag', e);
+ },
+
+ _prunePositions: function (time) {
+ while (this._positions.length > 1 && time - this._times[0] > 50) {
+ this._positions.shift();
+ this._times.shift();
+ }
+ },
+
+ _onZoomEnd: function () {
+ var pxCenter = this._map.getSize().divideBy(2),
+ pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
+
+ this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
+ this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
+ },
+
+ _viscousLimit: function (value, threshold) {
+ return value - (value - threshold) * this._viscosity;
+ },
+
+ _onPreDragLimit: function () {
+ if (!this._viscosity || !this._offsetLimit) { return; }
+
+ var offset = this._draggable._newPos.subtract(this._draggable._startPos);
+
+ var limit = this._offsetLimit;
+ if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
+ if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
+ if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
+ if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
+
+ this._draggable._newPos = this._draggable._startPos.add(offset);
+ },
+
+ _onPreDragWrap: function () {
+ // TODO refactor to be able to adjust map pane position after zoom
+ var worldWidth = this._worldWidth,
+ halfWidth = Math.round(worldWidth / 2),
+ dx = this._initialWorldOffset,
+ x = this._draggable._newPos.x,
+ newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
+ newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
+ newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
+
+ this._draggable._absPos = this._draggable._newPos.clone();
+ this._draggable._newPos.x = newX;
+ },
+
+ _onDragEnd: function (e) {
+ var map = this._map,
+ options = map.options,
+
+ noInertia = !options.inertia || e.noInertia || this._times.length < 2;
+
+ map.fire('dragend', e);
+
+ if (noInertia) {
+ map.fire('moveend');
+
+ } else {
+ this._prunePositions(+new Date());
+
+ var direction = this._lastPos.subtract(this._positions[0]),
+ duration = (this._lastTime - this._times[0]) / 1000,
+ ease = options.easeLinearity,
+
+ speedVector = direction.multiplyBy(ease / duration),
+ speed = speedVector.distanceTo([0, 0]),
+
+ limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
+ limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
+
+ decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
+ offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
+
+ if (!offset.x && !offset.y) {
+ map.fire('moveend');
+
+ } else {
+ offset = map._limitOffset(offset, map.options.maxBounds);
+
+ Util.requestAnimFrame(function () {
+ map.panBy(offset, {
+ duration: decelerationDuration,
+ easeLinearity: ease,
+ noMoveStart: true,
+ animate: true
+ });
+ });
+ }
+ }
+ }
+});
+
+// @section Handlers
+// @property dragging: Handler
+// Map dragging handler (by both mouse and touch).
+Map.addInitHook('addHandler', 'dragging', Drag);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.Keyboard.js b/packages/core/node_modules/leaflet/src/map/handler/Map.Keyboard.js
new file mode 100644
index 00000000..7244c4da
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.Keyboard.js
@@ -0,0 +1,183 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import {on, off, stop} from '../../dom/DomEvent';
+import {toPoint} from '../../geometry/Point';
+
+
+/*
+ * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
+ */
+
+// @namespace Map
+// @section Keyboard Navigation Options
+Map.mergeOptions({
+ // @option keyboard: Boolean = true
+ // Makes the map focusable and allows users to navigate the map with keyboard
+ // arrows and `+`/`-` keys.
+ keyboard: true,
+
+ // @option keyboardPanDelta: Number = 80
+ // Amount of pixels to pan when pressing an arrow key.
+ keyboardPanDelta: 80
+});
+
+export var Keyboard = Handler.extend({
+
+ keyCodes: {
+ left: [37],
+ right: [39],
+ down: [40],
+ up: [38],
+ zoomIn: [187, 107, 61, 171],
+ zoomOut: [189, 109, 54, 173]
+ },
+
+ initialize: function (map) {
+ this._map = map;
+
+ this._setPanDelta(map.options.keyboardPanDelta);
+ this._setZoomDelta(map.options.zoomDelta);
+ },
+
+ addHooks: function () {
+ var container = this._map._container;
+
+ // make the container focusable by tabbing
+ if (container.tabIndex <= 0) {
+ container.tabIndex = '0';
+ }
+
+ on(container, {
+ focus: this._onFocus,
+ blur: this._onBlur,
+ mousedown: this._onMouseDown
+ }, this);
+
+ this._map.on({
+ focus: this._addHooks,
+ blur: this._removeHooks
+ }, this);
+ },
+
+ removeHooks: function () {
+ this._removeHooks();
+
+ off(this._map._container, {
+ focus: this._onFocus,
+ blur: this._onBlur,
+ mousedown: this._onMouseDown
+ }, this);
+
+ this._map.off({
+ focus: this._addHooks,
+ blur: this._removeHooks
+ }, this);
+ },
+
+ _onMouseDown: function () {
+ if (this._focused) { return; }
+
+ var body = document.body,
+ docEl = document.documentElement,
+ top = body.scrollTop || docEl.scrollTop,
+ left = body.scrollLeft || docEl.scrollLeft;
+
+ this._map._container.focus();
+
+ window.scrollTo(left, top);
+ },
+
+ _onFocus: function () {
+ this._focused = true;
+ this._map.fire('focus');
+ },
+
+ _onBlur: function () {
+ this._focused = false;
+ this._map.fire('blur');
+ },
+
+ _setPanDelta: function (panDelta) {
+ var keys = this._panKeys = {},
+ codes = this.keyCodes,
+ i, len;
+
+ for (i = 0, len = codes.left.length; i < len; i++) {
+ keys[codes.left[i]] = [-1 * panDelta, 0];
+ }
+ for (i = 0, len = codes.right.length; i < len; i++) {
+ keys[codes.right[i]] = [panDelta, 0];
+ }
+ for (i = 0, len = codes.down.length; i < len; i++) {
+ keys[codes.down[i]] = [0, panDelta];
+ }
+ for (i = 0, len = codes.up.length; i < len; i++) {
+ keys[codes.up[i]] = [0, -1 * panDelta];
+ }
+ },
+
+ _setZoomDelta: function (zoomDelta) {
+ var keys = this._zoomKeys = {},
+ codes = this.keyCodes,
+ i, len;
+
+ for (i = 0, len = codes.zoomIn.length; i < len; i++) {
+ keys[codes.zoomIn[i]] = zoomDelta;
+ }
+ for (i = 0, len = codes.zoomOut.length; i < len; i++) {
+ keys[codes.zoomOut[i]] = -zoomDelta;
+ }
+ },
+
+ _addHooks: function () {
+ on(document, 'keydown', this._onKeyDown, this);
+ },
+
+ _removeHooks: function () {
+ off(document, 'keydown', this._onKeyDown, this);
+ },
+
+ _onKeyDown: function (e) {
+ if (e.altKey || e.ctrlKey || e.metaKey) { return; }
+
+ var key = e.keyCode,
+ map = this._map,
+ offset;
+
+ if (key in this._panKeys) {
+ if (!map._panAnim || !map._panAnim._inProgress) {
+ offset = this._panKeys[key];
+ if (e.shiftKey) {
+ offset = toPoint(offset).multiplyBy(3);
+ }
+
+ if (map.options.maxBounds) {
+ offset = map._limitOffset(toPoint(offset), map.options.maxBounds);
+ }
+
+ if (map.options.worldCopyJump) {
+ var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset)));
+ map.panTo(newLatLng);
+ } else {
+ map.panBy(offset);
+ }
+ }
+ } else if (key in this._zoomKeys) {
+ map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
+
+ } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
+ map.closePopup();
+
+ } else {
+ return;
+ }
+
+ stop(e);
+ }
+});
+
+// @section Handlers
+// @section Handlers
+// @property keyboard: Handler
+// Keyboard navigation handler.
+Map.addInitHook('addHandler', 'keyboard', Keyboard);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.ScrollWheelZoom.js b/packages/core/node_modules/leaflet/src/map/handler/Map.ScrollWheelZoom.js
new file mode 100644
index 00000000..85d9ee13
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.ScrollWheelZoom.js
@@ -0,0 +1,91 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import * as DomEvent from '../../dom/DomEvent';
+import * as Util from '../../core/Util';
+
+/*
+ * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+ // @section Mouse wheel options
+ // @option scrollWheelZoom: Boolean|String = true
+ // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
+ // it will zoom to the center of the view regardless of where the mouse was.
+ scrollWheelZoom: true,
+
+ // @option wheelDebounceTime: Number = 40
+ // Limits the rate at which a wheel can fire (in milliseconds). By default
+ // user can't zoom via wheel more often than once per 40 ms.
+ wheelDebounceTime: 40,
+
+ // @option wheelPxPerZoomLevel: Number = 60
+ // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
+ // mean a change of one full zoom level. Smaller values will make wheel-zooming
+ // faster (and vice versa).
+ wheelPxPerZoomLevel: 60
+});
+
+export var ScrollWheelZoom = Handler.extend({
+ addHooks: function () {
+ DomEvent.on(this._map._container, 'wheel', this._onWheelScroll, this);
+
+ this._delta = 0;
+ },
+
+ removeHooks: function () {
+ DomEvent.off(this._map._container, 'wheel', this._onWheelScroll, this);
+ },
+
+ _onWheelScroll: function (e) {
+ var delta = DomEvent.getWheelDelta(e);
+
+ var debounce = this._map.options.wheelDebounceTime;
+
+ this._delta += delta;
+ this._lastMousePos = this._map.mouseEventToContainerPoint(e);
+
+ if (!this._startTime) {
+ this._startTime = +new Date();
+ }
+
+ var left = Math.max(debounce - (+new Date() - this._startTime), 0);
+
+ clearTimeout(this._timer);
+ this._timer = setTimeout(Util.bind(this._performZoom, this), left);
+
+ DomEvent.stop(e);
+ },
+
+ _performZoom: function () {
+ var map = this._map,
+ zoom = map.getZoom(),
+ snap = this._map.options.zoomSnap || 0;
+
+ map._stop(); // stop panning and fly animations if any
+
+ // map the delta with a sigmoid function to -4..4 range leaning on -1..1
+ var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
+ d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
+ d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
+ delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
+
+ this._delta = 0;
+ this._startTime = null;
+
+ if (!delta) { return; }
+
+ if (map.options.scrollWheelZoom === 'center') {
+ map.setZoom(zoom + delta);
+ } else {
+ map.setZoomAround(this._lastMousePos, zoom + delta);
+ }
+ }
+});
+
+// @section Handlers
+// @property scrollWheelZoom: Handler
+// Scroll wheel zoom handler.
+Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.TapHold.js b/packages/core/node_modules/leaflet/src/map/handler/Map.TapHold.js
new file mode 100644
index 00000000..558ba77e
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.TapHold.js
@@ -0,0 +1,102 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import * as DomEvent from '../../dom/DomEvent';
+import {Point} from '../../geometry/Point';
+import * as Util from '../../core/Util';
+import Browser from '../../core/Browser';
+
+/*
+ * L.Map.TapHold is used to simulate `contextmenu` event on long hold,
+ * which otherwise is not fired by mobile Safari.
+ */
+
+var tapHoldDelay = 600;
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+ // @section Touch interaction options
+ // @option tapHold: Boolean
+ // Enables simulation of `contextmenu` event, default is `true` for mobile Safari.
+ tapHold: Browser.touchNative && Browser.safari && Browser.mobile,
+
+ // @option tapTolerance: Number = 15
+ // The max number of pixels a user can shift his finger during touch
+ // for it to be considered a valid tap.
+ tapTolerance: 15
+});
+
+export var TapHold = Handler.extend({
+ addHooks: function () {
+ DomEvent.on(this._map._container, 'touchstart', this._onDown, this);
+ },
+
+ removeHooks: function () {
+ DomEvent.off(this._map._container, 'touchstart', this._onDown, this);
+ },
+
+ _onDown: function (e) {
+ clearTimeout(this._holdTimeout);
+ if (e.touches.length !== 1) { return; }
+
+ var first = e.touches[0];
+ this._startPos = this._newPos = new Point(first.clientX, first.clientY);
+
+ this._holdTimeout = setTimeout(Util.bind(function () {
+ this._cancel();
+ if (!this._isTapValid()) { return; }
+
+ // prevent simulated mouse events https://w3c.github.io/touch-events/#mouse-events
+ DomEvent.on(document, 'touchend', DomEvent.preventDefault);
+ DomEvent.on(document, 'touchend touchcancel', this._cancelClickPrevent);
+ this._simulateEvent('contextmenu', first);
+ }, this), tapHoldDelay);
+
+ DomEvent.on(document, 'touchend touchcancel contextmenu', this._cancel, this);
+ DomEvent.on(document, 'touchmove', this._onMove, this);
+ },
+
+ _cancelClickPrevent: function cancelClickPrevent() {
+ DomEvent.off(document, 'touchend', DomEvent.preventDefault);
+ DomEvent.off(document, 'touchend touchcancel', cancelClickPrevent);
+ },
+
+ _cancel: function () {
+ clearTimeout(this._holdTimeout);
+ DomEvent.off(document, 'touchend touchcancel contextmenu', this._cancel, this);
+ DomEvent.off(document, 'touchmove', this._onMove, this);
+ },
+
+ _onMove: function (e) {
+ var first = e.touches[0];
+ this._newPos = new Point(first.clientX, first.clientY);
+ },
+
+ _isTapValid: function () {
+ return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
+ },
+
+ _simulateEvent: function (type, e) {
+ var simulatedEvent = new MouseEvent(type, {
+ bubbles: true,
+ cancelable: true,
+ view: window,
+ // detail: 1,
+ screenX: e.screenX,
+ screenY: e.screenY,
+ clientX: e.clientX,
+ clientY: e.clientY,
+ // button: 2,
+ // buttons: 2
+ });
+
+ simulatedEvent._simulated = true;
+
+ e.target.dispatchEvent(simulatedEvent);
+ }
+});
+
+// @section Handlers
+// @property tapHold: Handler
+// Long tap handler to simulate `contextmenu` event (useful in mobile Safari).
+Map.addInitHook('addHandler', 'tapHold', TapHold);
diff --git a/packages/core/node_modules/leaflet/src/map/handler/Map.TouchZoom.js b/packages/core/node_modules/leaflet/src/map/handler/Map.TouchZoom.js
new file mode 100644
index 00000000..2590d8fa
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/handler/Map.TouchZoom.js
@@ -0,0 +1,130 @@
+import {Map} from '../Map';
+import {Handler} from '../../core/Handler';
+import * as DomEvent from '../../dom/DomEvent';
+import * as Util from '../../core/Util';
+import * as DomUtil from '../../dom/DomUtil';
+import Browser from '../../core/Browser';
+
+/*
+ * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+ // @section Touch interaction options
+ // @option touchZoom: Boolean|String = *
+ // Whether the map can be zoomed by touch-dragging with two fingers. If
+ // passed `'center'`, it will zoom to the center of the view regardless of
+ // where the touch events (fingers) were. Enabled for touch-capable web
+ // browsers.
+ touchZoom: Browser.touch,
+
+ // @option bounceAtZoomLimits: Boolean = true
+ // Set it to false if you don't want the map to zoom beyond min/max zoom
+ // and then bounce back when pinch-zooming.
+ bounceAtZoomLimits: true
+});
+
+export var TouchZoom = Handler.extend({
+ addHooks: function () {
+ DomUtil.addClass(this._map._container, 'leaflet-touch-zoom');
+ DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this);
+ },
+
+ removeHooks: function () {
+ DomUtil.removeClass(this._map._container, 'leaflet-touch-zoom');
+ DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this);
+ },
+
+ _onTouchStart: function (e) {
+ var map = this._map;
+ if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
+
+ var p1 = map.mouseEventToContainerPoint(e.touches[0]),
+ p2 = map.mouseEventToContainerPoint(e.touches[1]);
+
+ this._centerPoint = map.getSize()._divideBy(2);
+ this._startLatLng = map.containerPointToLatLng(this._centerPoint);
+ if (map.options.touchZoom !== 'center') {
+ this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
+ }
+
+ this._startDist = p1.distanceTo(p2);
+ this._startZoom = map.getZoom();
+
+ this._moved = false;
+ this._zooming = true;
+
+ map._stop();
+
+ DomEvent.on(document, 'touchmove', this._onTouchMove, this);
+ DomEvent.on(document, 'touchend touchcancel', this._onTouchEnd, this);
+
+ DomEvent.preventDefault(e);
+ },
+
+ _onTouchMove: function (e) {
+ if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; }
+
+ var map = this._map,
+ p1 = map.mouseEventToContainerPoint(e.touches[0]),
+ p2 = map.mouseEventToContainerPoint(e.touches[1]),
+ scale = p1.distanceTo(p2) / this._startDist;
+
+ this._zoom = map.getScaleZoom(scale, this._startZoom);
+
+ if (!map.options.bounceAtZoomLimits && (
+ (this._zoom < map.getMinZoom() && scale < 1) ||
+ (this._zoom > map.getMaxZoom() && scale > 1))) {
+ this._zoom = map._limitZoom(this._zoom);
+ }
+
+ if (map.options.touchZoom === 'center') {
+ this._center = this._startLatLng;
+ if (scale === 1) { return; }
+ } else {
+ // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
+ var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
+ if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
+ this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom);
+ }
+
+ if (!this._moved) {
+ map._moveStart(true, false);
+ this._moved = true;
+ }
+
+ Util.cancelAnimFrame(this._animRequest);
+
+ var moveFn = Util.bind(map._move, map, this._center, this._zoom, {pinch: true, round: false}, undefined);
+ this._animRequest = Util.requestAnimFrame(moveFn, this, true);
+
+ DomEvent.preventDefault(e);
+ },
+
+ _onTouchEnd: function () {
+ if (!this._moved || !this._zooming) {
+ this._zooming = false;
+ return;
+ }
+
+ this._zooming = false;
+ Util.cancelAnimFrame(this._animRequest);
+
+ DomEvent.off(document, 'touchmove', this._onTouchMove, this);
+ DomEvent.off(document, 'touchend touchcancel', this._onTouchEnd, this);
+
+ // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
+ if (this._map.options.zoomAnimation) {
+ this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
+ } else {
+ this._map._resetView(this._center, this._map._limitZoom(this._zoom));
+ }
+ }
+});
+
+// @section Handlers
+// @property touchZoom: Handler
+// Touch zoom handler.
+Map.addInitHook('addHandler', 'touchZoom', TouchZoom);
diff --git a/packages/core/node_modules/leaflet/src/map/index.js b/packages/core/node_modules/leaflet/src/map/index.js
new file mode 100644
index 00000000..e35f7553
--- /dev/null
+++ b/packages/core/node_modules/leaflet/src/map/index.js
@@ -0,0 +1,17 @@
+import {Map} from './Map';
+import {BoxZoom} from './handler/Map.BoxZoom';
+Map.BoxZoom = BoxZoom;
+import {DoubleClickZoom} from './handler/Map.DoubleClickZoom';
+Map.DoubleClickZoom = DoubleClickZoom;
+import {Drag} from './handler/Map.Drag';
+Map.Drag = Drag;
+import {Keyboard} from './handler/Map.Keyboard';
+Map.Keyboard = Keyboard;
+import {ScrollWheelZoom} from './handler/Map.ScrollWheelZoom';
+Map.ScrollWheelZoom = ScrollWheelZoom;
+import {TapHold} from './handler/Map.TapHold';
+Map.TapHold = TapHold;
+import {TouchZoom} from './handler/Map.TouchZoom';
+Map.TouchZoom = TouchZoom;
+
+export {Map, createMap as map} from './Map';
diff --git a/packages/core/package.json b/packages/core/package.json
index 424c5207..4f90f50d 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/core",
"description": "The core dependencies for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",
@@ -28,9 +28,9 @@
"jquery": "^3.2.1",
"jquery-serializejson": "2.9.0",
"js-cookie": "^3.0.1",
- "leaflet": "1.3.1",
- "leaflet-tilelayer-here": "1.0.2",
- "leaflet.markercluster": "1.4.1",
+ "leaflet": "^1.9.4",
+ "leaflet-tilelayer-here": "^2.0.1",
+ "leaflet.markercluster": "^1.5.3",
"morphdom": "2.6.1",
"prop-types": "^15.7.2",
"quill": "1.3.7",
diff --git a/packages/dev/package.json b/packages/dev/package.json
index 5091e66b..1d31808b 100644
--- a/packages/dev/package.json
+++ b/packages/dev/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/dev",
"description": "The dev dependencies for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",
diff --git a/packages/elections/package.json b/packages/elections/package.json
index 2c16f548..c2d8e2f0 100644
--- a/packages/elections/package.json
+++ b/packages/elections/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/elections",
"description": "The elections and votings dependencies for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",
diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json
index 470f44cf..ad1e3ff5 100644
--- a/packages/eslint-config/package.json
+++ b/packages/eslint-config/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/eslint-config",
"description": "The eslint configuration for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",
diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json
index 98d2b578..2588384b 100644
--- a/packages/stylelint-config/package.json
+++ b/packages/stylelint-config/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/stylelint-config",
"description": "The stylelint configuration for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",
diff --git a/packages/webpacker/package.json b/packages/webpacker/package.json
index 093f691f..5da61013 100644
--- a/packages/webpacker/package.json
+++ b/packages/webpacker/package.json
@@ -1,7 +1,7 @@
{
"name": "@decidim/webpacker",
"description": "The webpacker dependencies for Decidim",
- "version": "0.27.5",
+ "version": "0.27.6",
"repository": {
"url": "git@github.com:decidim/decidim.git",
"type": "git",