diff --git a/.eslintrc b/.eslintrc
index 84cdc6bb85..a956ffdd47 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -119,6 +119,7 @@
"getCookies": true,
"get_url_arg": true,
"QUnit": true,
- "JsBarcode": true
+ "JsBarcode": true,
+ "L": true
}
}
diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json
index b00b0c7b07..32dd8031f4 100644
--- a/frappe/core/doctype/docfield/docfield.json
+++ b/frappe/core/doctype/docfield/docfield.json
@@ -96,7 +96,7 @@
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
- "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature",
+ "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -1364,7 +1364,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-10-07 19:20:15.888708",
+ "modified": "2017-10-24 11:39:56.795852",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
diff --git a/frappe/custom/doctype/custom_field/custom_field.json b/frappe/custom/doctype/custom_field/custom_field.json
index a4bec7ec1f..16e9408d3f 100644
--- a/frappe/custom/doctype/custom_field/custom_field.json
+++ b/frappe/custom/doctype/custom_field/custom_field.json
@@ -220,7 +220,7 @@
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
- "options": "Attach\nAttach Image\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature",
+ "options": "Attach\nAttach Image\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nGeolocation\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -1161,7 +1161,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-07-06 17:23:43.835189",
+ "modified": "2017-10-24 11:40:37.986457",
"modified_by": "Administrator",
"module": "Custom",
"name": "Custom Field",
diff --git a/frappe/custom/doctype/custom_field/test_custom_field.js b/frappe/custom/doctype/custom_field/test_custom_field.js
new file mode 100644
index 0000000000..4ca743a395
--- /dev/null
+++ b/frappe/custom/doctype/custom_field/test_custom_field.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Custom Field", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Custom Field
+ () => frappe.tests.make('Custom Field', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py
index 70251711f3..0392b46ee4 100644
--- a/frappe/custom/doctype/customize_form/customize_form.py
+++ b/frappe/custom/doctype/customize_form/customize_form.py
@@ -66,7 +66,7 @@ docfield_properties = {
allowed_fieldtype_change = (('Currency', 'Float', 'Percent'), ('Small Text', 'Data'),
('Text', 'Data'), ('Text', 'Text Editor', 'Code', 'Signature'), ('Data', 'Select'),
- ('Text', 'Small Text'), ('Text', 'Data', 'Barcode'))
+ ('Text', 'Small Text'), ('Text', 'Data', 'Barcode'), ('Code', 'Geolocation'))
allowed_fieldtype_for_options_change = ('Read Only', 'HTML', 'Select',)
diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.json b/frappe/custom/doctype/customize_form_field/customize_form_field.json
index 8dc0a6a3fa..98a9fe0db3 100644
--- a/frappe/custom/doctype/customize_form_field/customize_form_field.json
+++ b/frappe/custom/doctype/customize_form_field/customize_form_field.json
@@ -94,7 +94,7 @@
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
- "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSignature\nSmall Text\nTable\nText\nText Editor\nTime",
+ "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSignature\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -1202,7 +1202,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-10-11 06:45:20.172291",
+ "modified": "2017-10-24 11:41:31.075929",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customize Form Field",
diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py
index fb3de07332..f275cc7e57 100644
--- a/frappe/model/db_schema.py
+++ b/frappe/model/db_schema.py
@@ -26,25 +26,26 @@ type_map = {
,'Float': ('decimal', '18,6')
,'Percent': ('decimal', '18,6')
,'Check': ('int', '1')
- ,'Small Text': ('text', '')
- ,'Long Text': ('longtext', '')
+ ,'Small Text': ('text', '')
+ ,'Long Text': ('longtext', '')
,'Code': ('longtext', '')
- ,'Text Editor': ('longtext', '')
+ ,'Text Editor': ('longtext', '')
,'Date': ('date', '')
- ,'Datetime': ('datetime', '6')
+ ,'Datetime': ('datetime', '6')
,'Time': ('time', '6')
,'Text': ('text', '')
,'Data': ('varchar', varchar_len)
,'Link': ('varchar', varchar_len)
- ,'Dynamic Link':('varchar', varchar_len)
- ,'Password': ('varchar', varchar_len)
+ ,'Dynamic Link': ('varchar', varchar_len)
+ ,'Password': ('varchar', varchar_len)
,'Select': ('varchar', varchar_len)
- ,'Read Only': ('varchar', varchar_len)
+ ,'Read Only': ('varchar', varchar_len)
,'Attach': ('text', '')
- ,'Attach Image':('text', '')
- ,'Signature': ('longtext', '')
+ ,'Attach Image': ('text', '')
+ ,'Signature': ('longtext', '')
,'Color': ('varchar', varchar_len)
,'Barcode': ('longtext', '')
+ ,'Geolocation': ('longtext', '')
}
default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner',
diff --git a/frappe/public/build.json b/frappe/public/build.json
index 1a418248dd..7e02a8fe16 100755
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -53,7 +53,8 @@
"public/js/frappe/form/controls/html.js",
"public/js/frappe/form/controls/heading.js",
"public/js/frappe/form/controls/autocomplete.js",
- "public/js/frappe/form/controls/barcode.js"
+ "public/js/frappe/form/controls/barcode.js",
+ "public/js/frappe/form/controls/geolocation.js"
],
"js/dialog.min.js": [
"public/js/frappe/dom.js",
@@ -94,12 +95,17 @@
"public/js/frappe/form/controls/read_only.js",
"public/js/frappe/form/controls/button.js",
"public/js/frappe/form/controls/html.js",
- "public/js/frappe/form/controls/heading.js"
+ "public/js/frappe/form/controls/heading.js",
+ "public/js/frappe/form/controls/geolocation.js"
],
"css/desk.min.css": [
"public/js/lib/datepicker/datepicker.min.css",
"public/js/lib/awesomplete/awesomplete.css",
"public/js/lib/summernote/summernote.css",
+ "public/js/lib/leaflet/leaflet.css",
+ "public/js/lib/leaflet/leaflet.draw.css",
+ "public/js/lib/leaflet/L.Control.Locate.css",
+ "public/js/lib/leaflet/easy-button.css",
"public/css/bootstrap.css",
"public/css/font-awesome.css",
"public/css/octicons/octicons.css",
@@ -137,7 +143,11 @@
"public/js/lib/datepicker/datepicker.min.js",
"public/js/lib/datepicker/locale-all.js",
"public/js/lib/jquery.jrumble.min.js",
- "public/js/lib/webcam.min.js"
+ "public/js/lib/webcam.min.js",
+ "public/js/lib/leaflet/leaflet.js",
+ "public/js/lib/leaflet/leaflet.draw.js",
+ "public/js/lib/leaflet/L.Control.Locate.js",
+ "public/js/lib/leaflet/easy-button.js"
],
"js/desk.min.js": [
"public/js/frappe/class.js",
diff --git a/frappe/public/images/leaflet/layers-2x.png b/frappe/public/images/leaflet/layers-2x.png
new file mode 100644
index 0000000000..200c333dca
Binary files /dev/null and b/frappe/public/images/leaflet/layers-2x.png differ
diff --git a/frappe/public/images/leaflet/layers.png b/frappe/public/images/leaflet/layers.png
new file mode 100644
index 0000000000..1a72e5784b
Binary files /dev/null and b/frappe/public/images/leaflet/layers.png differ
diff --git a/frappe/public/images/leaflet/leafletmarker-icon.png b/frappe/public/images/leaflet/leafletmarker-icon.png
new file mode 100644
index 0000000000..950edf2467
Binary files /dev/null and b/frappe/public/images/leaflet/leafletmarker-icon.png differ
diff --git a/frappe/public/images/leaflet/leafletmarker-shadow.png b/frappe/public/images/leaflet/leafletmarker-shadow.png
new file mode 100644
index 0000000000..9fd2979532
Binary files /dev/null and b/frappe/public/images/leaflet/leafletmarker-shadow.png differ
diff --git a/frappe/public/images/leaflet/lego.png b/frappe/public/images/leaflet/lego.png
new file mode 100644
index 0000000000..f173107335
Binary files /dev/null and b/frappe/public/images/leaflet/lego.png differ
diff --git a/frappe/public/images/leaflet/marker-icon-2x.png b/frappe/public/images/leaflet/marker-icon-2x.png
new file mode 100644
index 0000000000..e4abba3b51
Binary files /dev/null and b/frappe/public/images/leaflet/marker-icon-2x.png differ
diff --git a/frappe/public/images/leaflet/marker-icon.png b/frappe/public/images/leaflet/marker-icon.png
new file mode 100644
index 0000000000..950edf2467
Binary files /dev/null and b/frappe/public/images/leaflet/marker-icon.png differ
diff --git a/frappe/public/images/leaflet/marker-shadow.png b/frappe/public/images/leaflet/marker-shadow.png
new file mode 100644
index 0000000000..9fd2979532
Binary files /dev/null and b/frappe/public/images/leaflet/marker-shadow.png differ
diff --git a/frappe/public/images/leaflet/spritesheet-2x.png b/frappe/public/images/leaflet/spritesheet-2x.png
new file mode 100644
index 0000000000..c45231aff8
Binary files /dev/null and b/frappe/public/images/leaflet/spritesheet-2x.png differ
diff --git a/frappe/public/images/leaflet/spritesheet.png b/frappe/public/images/leaflet/spritesheet.png
new file mode 100644
index 0000000000..97d71c6805
Binary files /dev/null and b/frappe/public/images/leaflet/spritesheet.png differ
diff --git a/frappe/public/images/leaflet/spritesheet.svg b/frappe/public/images/leaflet/spritesheet.svg
new file mode 100644
index 0000000000..3c00f30314
--- /dev/null
+++ b/frappe/public/images/leaflet/spritesheet.svg
@@ -0,0 +1,156 @@
+
+
diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js
index b4ceac66bd..ec7a4b9e06 100644
--- a/frappe/public/js/frappe/dom.js
+++ b/frappe/public/js/frappe/dom.js
@@ -10,6 +10,11 @@ frappe.dom = {
by_id: function(id) {
return document.getElementById(id);
},
+ get_unique_id: function() {
+ const id = 'unique-' + frappe.dom.id_count;
+ frappe.dom.id_count++;
+ return id;
+ },
set_unique_id: function(ele) {
var $ele = $(ele);
if($ele.attr('id')) {
diff --git a/frappe/public/js/frappe/form/controls/geolocation.js b/frappe/public/js/frappe/form/controls/geolocation.js
new file mode 100644
index 0000000000..515620da21
--- /dev/null
+++ b/frappe/public/js/frappe/form/controls/geolocation.js
@@ -0,0 +1,183 @@
+frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
+ make_wrapper() {
+ // Create the elements for map area
+ this._super();
+
+ let $input_wrapper = this.$wrapper.find('.control-input-wrapper');
+ this.map_id = frappe.dom.get_unique_id();
+ this.map_area = $(
+ `
`
+ );
+ this.map_area.prependTo($input_wrapper);
+ this.$wrapper.find('.control-input').addClass("hidden");
+ this.bind_leaflet_map();
+ this.bind_leaflet_draw_control();
+ this.bind_leaflet_locate_control();
+ this.bind_leaflet_refresh_button();
+ },
+
+ format_for_input(value) {
+ // render raw value from db into map
+ this.clear_editable_layers();
+ if(value) {
+ var data_layers = new L.FeatureGroup()
+ .addLayer(L.geoJson(JSON.parse(value),{
+ pointToLayer: function(geoJsonPoint, latlng) {
+ if (geoJsonPoint.properties.point_type == "circle"){
+ return L.circle(latlng, {radius: geoJsonPoint.properties.radius});
+ } else if (geoJsonPoint.properties.point_type == "circlemarker") {
+ return L.circleMarker(latlng, {radius: geoJsonPoint.properties.radius});
+ }
+ else {
+ return L.marker(latlng);
+ }
+ }
+ }));
+ this.add_non_group_layers(data_layers, this.editableLayers);
+ try {
+ this.map.flyToBounds(this.editableLayers.getBounds(), {
+ padding: [50,50]
+ });
+ }
+ catch(err) {
+ // suppress error if layer has a point.
+ }
+ this.editableLayers.addTo(this.map);
+ } else if ((value===undefined) || (value == JSON.stringify(new L.FeatureGroup().toGeoJSON()))) {
+ this.locate_control.start();
+ }
+ },
+
+ bind_leaflet_map() {
+
+ var circleToGeoJSON = L.Circle.prototype.toGeoJSON;
+ L.Circle.include({
+ toGeoJSON: function() {
+ var feature = circleToGeoJSON.call(this);
+ feature.properties = {
+ point_type: 'circle',
+ radius: this.getRadius()
+ };
+ return feature;
+ }
+ });
+
+ L.CircleMarker.include({
+ toGeoJSON: function() {
+ var feature = circleToGeoJSON.call(this);
+ feature.properties = {
+ point_type: 'circlemarker',
+ radius: this.getRadius()
+ };
+ return feature;
+ }
+ });
+
+ L.Icon.Default.imagePath = '/assets/frappe/images/leaflet/';
+ this.map = L.map(this.map_id).setView([19.0800, 72.8961], 13);
+
+ L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
+ attribution: '© OpenStreetMap contributors'
+ }).addTo(this.map);
+ },
+
+ bind_leaflet_locate_control() {
+ // To request location update and set location, sets current geolocation on load
+ this.locate_control = L.control.locate({position:'topright'});
+ this.locate_control.addTo(this.map);
+ },
+
+ bind_leaflet_draw_control() {
+ this.editableLayers = new L.FeatureGroup();
+
+ var options = {
+ position: 'topleft',
+ draw: {
+ polyline: {
+ shapeOptions: {
+ color: frappe.ui.color.get('blue'),
+ weight: 10
+ }
+ },
+ polygon: {
+ allowIntersection: false, // Restricts shapes to simple polygons
+ drawError: {
+ color: frappe.ui.color.get('orange'), // Color the shape will turn when intersects
+ message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect
+ },
+ shapeOptions: {
+ color: frappe.ui.color.get('blue')
+ }
+ },
+ circle: true,
+ rectangle: {
+ shapeOptions: {
+ clickable: false
+ }
+ }
+ },
+ edit: {
+ featureGroup: this.editableLayers, //REQUIRED!!
+ remove: true
+ }
+ };
+
+ // create control and add to map
+ var drawControl = new L.Control.Draw(options);
+
+ this.map.addControl(drawControl);
+
+ this.map.on('draw:created', (e) => {
+ var type = e.layerType,
+ layer = e.layer;
+ if (type === 'marker') {
+ layer.bindPopup('Marker');
+ }
+ this.editableLayers.addLayer(layer);
+ this.set_value(JSON.stringify(this.editableLayers.toGeoJSON()));
+ });
+
+ this.map.on('draw:deleted draw:edited', (e) => {
+ var layer = e.layer;
+ this.editableLayers.removeLayer(layer);
+ this.set_value(JSON.stringify(this.editableLayers.toGeoJSON()));
+ });
+ },
+
+ bind_leaflet_refresh_button() {
+ L.easyButton({
+ id: 'refresh-map-'+this.df.fieldname,
+ position: 'topright',
+ type: 'replace',
+ leafletClasses: true,
+ states:[{
+ stateName: 'refresh-map',
+ onClick: function(button, map){
+ map._onResize();
+ },
+ title: 'Refresh map',
+ icon: 'fa fa-refresh'
+ }]
+ }).addTo(this.map);
+ },
+
+ add_non_group_layers(source_layer, target_group) {
+ // https://gis.stackexchange.com/a/203773
+ // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
+ if (source_layer instanceof L.LayerGroup) {
+ source_layer.eachLayer((layer)=>{
+ this.add_non_group_layers(layer, target_group);
+ });
+ } else {
+ target_group.addLayer(source_layer);
+ }
+ },
+
+ clear_editable_layers() {
+ this.editableLayers.eachLayer((l)=>{
+ this.editableLayers.removeLayer(l);
+ });
+ }
+});
diff --git a/frappe/public/js/lib/leaflet/L.Control.Locate.css b/frappe/public/js/lib/leaflet/L.Control.Locate.css
new file mode 100644
index 0000000000..1fa5e7b67b
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/L.Control.Locate.css
@@ -0,0 +1,12 @@
+/* Compatible with Leaflet 0.7 */
+.leaflet-control-locate a {
+ font-size: 1.4em;
+ color: #444;
+ cursor: pointer;
+}
+.leaflet-control-locate.active a {
+ color: #2074B6;
+}
+.leaflet-control-locate.active.following a {
+ color: #FC8428;
+}
diff --git a/frappe/public/js/lib/leaflet/L.Control.Locate.js b/frappe/public/js/lib/leaflet/L.Control.Locate.js
new file mode 100644
index 0000000000..8544e17a04
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/L.Control.Locate.js
@@ -0,0 +1,591 @@
+/*!
+Copyright (c) 2016 Dominik Moritz
+
+This file is part of the leaflet locate control. It is licensed under the MIT license.
+You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
+*/
+(function (factory, window) {
+ // see https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md#module-loaders
+ // for details on how to structure a leaflet plugin.
+
+ // define an AMD module that relies on 'leaflet'
+ if (typeof define === 'function' && define.amd) {
+ define(['leaflet'], factory);
+
+ // define a Common JS module that relies on 'leaflet'
+ } else if (typeof exports === 'object') {
+ if (typeof window !== 'undefined' && window.L) {
+ module.exports = factory(L);
+ } else {
+ module.exports = factory(require('leaflet'));
+ }
+ }
+
+ // attach your plugin to the global 'L' variable
+ if (typeof window !== 'undefined' && window.L){
+ window.L.Control.Locate = factory(L);
+ }
+} (function (L) {
+ var LDomUtilApplyClassesMethod = function(method, element, classNames) {
+ classNames = classNames.split(' ');
+ classNames.forEach(function(className) {
+ L.DomUtil[method].call(this, element, className);
+ });
+ };
+
+ var addClasses = function(el, names) { LDomUtilApplyClassesMethod('addClass', el, names); };
+ var removeClasses = function(el, names) { LDomUtilApplyClassesMethod('removeClass', el, names); };
+
+ var LocateControl = L.Control.extend({
+ options: {
+ /** Position of the control */
+ position: 'topleft',
+ /** The layer that the user's location should be drawn on. By default creates a new layer. */
+ layer: undefined,
+ /**
+ * Automatically sets the map view (zoom and pan) to the user's location as it updates.
+ * While the map is following the user's location, the control is in the `following` state,
+ * which changes the style of the control and the circle marker.
+ *
+ * Possible values:
+ * - false: never updates the map view when location changes.
+ * - 'once': set the view when the location is first determined
+ * - 'always': always updates the map view when location changes.
+ * The map view follows the users location.
+ * - 'untilPan': (default) like 'always', except stops updating the
+ * view if the user has manually panned the map.
+ * The map view follows the users location until she pans.
+ */
+ setView: 'untilPan',
+ /** Keep the current map zoom level when setting the view and only pan. */
+ keepCurrentZoomLevel: false,
+ /** Smooth pan and zoom to the location of the marker. Only works in Leaflet 1.0+. */
+ flyTo: false,
+ /**
+ * The user location can be inside and outside the current view when the user clicks on the
+ * control that is already active. Both cases can be configures separately.
+ * Possible values are:
+ * - 'setView': zoom and pan to the current location
+ * - 'stop': stop locating and remove the location marker
+ */
+ clickBehavior: {
+ /** What should happen if the user clicks on the control while the location is within the current view. */
+ inView: 'stop',
+ /** What should happen if the user clicks on the control while the location is outside the current view. */
+ outOfView: 'setView',
+ },
+ /**
+ * If set, save the map bounds just before centering to the user's
+ * location. When control is disabled, set the view back to the
+ * bounds that were saved.
+ */
+ returnToPrevBounds: false,
+ /**
+ * Keep a cache of the location after the user deactivates the control. If set to false, the user has to wait
+ * until the locate API returns a new location before they see where they are again.
+ */
+ cacheLocation: true,
+ /** If set, a circle that shows the location accuracy is drawn. */
+ drawCircle: true,
+ /** If set, the marker at the users' location is drawn. */
+ drawMarker: true,
+ /** The class to be used to create the marker. For example L.CircleMarker or L.Marker */
+ markerClass: L.CircleMarker,
+ /** Accuracy circle style properties. */
+ circleStyle: {
+ color: '#136AEC',
+ fillColor: '#136AEC',
+ fillOpacity: 0.15,
+ weight: 2,
+ opacity: 0.5
+ },
+ /** Inner marker style properties. Only works if your marker class supports `setStyle`. */
+ markerStyle: {
+ color: '#136AEC',
+ fillColor: '#2A93EE',
+ fillOpacity: 0.7,
+ weight: 2,
+ opacity: 0.9,
+ radius: 5
+ },
+ /**
+ * Changes to accuracy circle and inner marker while following.
+ * It is only necessary to provide the properties that should change.
+ */
+ followCircleStyle: {},
+ followMarkerStyle: {
+ // color: '#FFA500',
+ // fillColor: '#FFB000'
+ },
+ /** The CSS class for the icon. For example fa-location-arrow or fa-map-marker */
+ icon: 'fa fa-map-marker',
+ iconLoading: 'fa fa-spinner fa-spin',
+ /** The element to be created for icons. For example span or i */
+ iconElementTag: 'span',
+ /** Padding around the accuracy circle. */
+ circlePadding: [0, 0],
+ /** Use metric units. */
+ metric: true,
+ /**
+ * This callback can be used in case you would like to override button creation behavior.
+ * This is useful for DOM manipulation frameworks such as angular etc.
+ * This function should return an object with HtmlElement for the button (link property) and the icon (icon property).
+ */
+ createButtonCallback: function (container, options) {
+ var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container);
+ link.title = options.strings.title;
+ var icon = L.DomUtil.create(options.iconElementTag, options.icon, link);
+ return { link: link, icon: icon };
+ },
+ /** This event is called in case of any location error that is not a time out error. */
+ onLocationError: function(err, control) {
+ alert(err.message);
+ },
+ /**
+ * This even is called when the user's location is outside the bounds set on the map.
+ * The event is called repeatedly when the location changes.
+ */
+ onLocationOutsideMapBounds: function(control) {
+ control.stop();
+ alert(control.options.strings.outsideMapBoundsMsg);
+ },
+ /** Display a pop-up when the user click on the inner marker. */
+ showPopup: true,
+ strings: {
+ title: "Show me where I am",
+ metersUnit: "meters",
+ feetUnit: "feet",
+ popup: "You are within {distance} {unit} from this point",
+ outsideMapBoundsMsg: "You seem located outside the boundaries of the map"
+ },
+ /** The default options passed to leaflets locate method. */
+ locateOptions: {
+ maxZoom: Infinity,
+ watch: true, // if you overwrite this, visualization cannot be updated
+ setView: false // have to set this to false because we have to
+ // do setView manually
+ }
+ },
+
+ initialize: function (options) {
+ // set default options if nothing is set (merge one step deep)
+ for (var i in options) {
+ if (typeof this.options[i] === 'object') {
+ L.extend(this.options[i], options[i]);
+ } else {
+ this.options[i] = options[i];
+ }
+ }
+
+ // extend the follow marker style and circle from the normal style
+ this.options.followMarkerStyle = L.extend({}, this.options.markerStyle, this.options.followMarkerStyle);
+ this.options.followCircleStyle = L.extend({}, this.options.circleStyle, this.options.followCircleStyle);
+ },
+
+ /**
+ * Add control to map. Returns the container for the control.
+ */
+ onAdd: function (map) {
+ var container = L.DomUtil.create('div',
+ 'leaflet-control-locate leaflet-bar leaflet-control');
+
+ this._layer = this.options.layer || new L.LayerGroup();
+ this._layer.addTo(map);
+ this._event = undefined;
+ this._prevBounds = null;
+
+ var linkAndIcon = this.options.createButtonCallback(container, this.options);
+ this._link = linkAndIcon.link;
+ this._icon = linkAndIcon.icon;
+
+ L.DomEvent
+ .on(this._link, 'click', L.DomEvent.stopPropagation)
+ .on(this._link, 'click', L.DomEvent.preventDefault)
+ .on(this._link, 'click', this._onClick, this)
+ .on(this._link, 'dblclick', L.DomEvent.stopPropagation);
+
+ this._resetVariables();
+
+ this._map.on('unload', this._unload, this);
+
+ return container;
+ },
+
+ /**
+ * This method is called when the user clicks on the control.
+ */
+ _onClick: function() {
+ this._justClicked = true;
+ this._userPanned = false;
+
+ if (this._active && !this._event) {
+ // click while requesting
+ this.stop();
+ } else if (this._active && this._event !== undefined) {
+ var behavior = this._map.getBounds().contains(this._event.latlng) ?
+ this.options.clickBehavior.inView : this.options.clickBehavior.outOfView;
+ switch (behavior) {
+ case 'setView':
+ this.setView();
+ break;
+ case 'stop':
+ this.stop();
+ if (this.options.returnToPrevBounds) {
+ var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds;
+ f.bind(this._map)(this._prevBounds);
+ }
+ break;
+ }
+ } else {
+ if (this.options.returnToPrevBounds) {
+ this._prevBounds = this._map.getBounds();
+ }
+ this.start();
+ }
+
+ this._updateContainerStyle();
+ },
+
+ /**
+ * Starts the plugin:
+ * - activates the engine
+ * - draws the marker (if coordinates available)
+ */
+ start: function() {
+ this._activate();
+
+ if (this._event) {
+ this._drawMarker(this._map);
+
+ // if we already have a location but the user clicked on the control
+ if (this.options.setView) {
+ this.setView();
+ }
+ }
+ this._updateContainerStyle();
+ },
+
+ /**
+ * Stops the plugin:
+ * - deactivates the engine
+ * - reinitializes the button
+ * - removes the marker
+ */
+ stop: function() {
+ this._deactivate();
+
+ this._cleanClasses();
+ this._resetVariables();
+
+ this._removeMarker();
+ },
+
+ /**
+ * This method launches the location engine.
+ * It is called before the marker is updated,
+ * event if it does not mean that the event will be ready.
+ *
+ * Override it if you want to add more functionalities.
+ * It should set the this._active to true and do nothing if
+ * this._active is true.
+ */
+ _activate: function() {
+ if (!this._active) {
+ this._map.locate(this.options.locateOptions);
+ this._active = true;
+
+ // bind event listeners
+ this._map.on('locationfound', this._onLocationFound, this);
+ this._map.on('locationerror', this._onLocationError, this);
+ this._map.on('dragstart', this._onDrag, this);
+ }
+ },
+
+ /**
+ * Called to stop the location engine.
+ *
+ * Override it to shutdown any functionalities you added on start.
+ */
+ _deactivate: function() {
+ this._map.stopLocate();
+ this._active = false;
+
+ if (!this.options.cacheLocation) {
+ this._event = undefined;
+ }
+
+ // unbind event listeners
+ this._map.off('locationfound', this._onLocationFound, this);
+ this._map.off('locationerror', this._onLocationError, this);
+ this._map.off('dragstart', this._onDrag, this);
+ },
+
+ /**
+ * Zoom (unless we should keep the zoom level) and an to the current view.
+ */
+ setView: function() {
+ this._drawMarker();
+ if (this._isOutsideMapBounds()) {
+ this._event = undefined; // clear the current location so we can get back into the bounds
+ this.options.onLocationOutsideMapBounds(this);
+ } else {
+ if (this.options.keepCurrentZoomLevel) {
+ var f = this.options.flyTo ? this._map.flyTo : this._map.panTo;
+ f.bind(this._map)([this._event.latitude, this._event.longitude]);
+ } else {
+ var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds;
+ f.bind(this._map)(this._event.bounds, {
+ padding: this.options.circlePadding,
+ maxZoom: this.options.locateOptions.maxZoom
+ });
+ }
+ }
+ },
+
+ /**
+ * Draw the marker and accuracy circle on the map.
+ *
+ * Uses the event retrieved from onLocationFound from the map.
+ */
+ _drawMarker: function() {
+ if (this._event.accuracy === undefined) {
+ this._event.accuracy = 0;
+ }
+
+ var radius = this._event.accuracy;
+ var latlng = this._event.latlng;
+
+ // circle with the radius of the location's accuracy
+ if (this.options.drawCircle) {
+ var style = this._isFollowing() ? this.options.followCircleStyle : this.options.circleStyle;
+
+ if (!this._circle) {
+ this._circle = L.circle(latlng, radius, style).addTo(this._layer);
+ } else {
+ this._circle.setLatLng(latlng).setRadius(radius).setStyle(style);
+ }
+ }
+
+ var distance, unit;
+ if (this.options.metric) {
+ distance = radius.toFixed(0);
+ unit = this.options.strings.metersUnit;
+ } else {
+ distance = (radius * 3.2808399).toFixed(0);
+ unit = this.options.strings.feetUnit;
+ }
+
+ // small inner marker
+ if (this.options.drawMarker) {
+ var mStyle = this._isFollowing() ? this.options.followMarkerStyle : this.options.markerStyle;
+ if (!this._marker) {
+ this._marker = new this.options.markerClass(latlng, mStyle).addTo(this._layer);
+ } else {
+ this._marker.setLatLng(latlng);
+ // If the markerClass can be updated with setStyle, update it.
+ if (this._marker.setStyle) {
+ this._marker.setStyle(mStyle);
+ }
+ }
+ }
+
+ var t = this.options.strings.popup;
+ if (this.options.showPopup && t && this._marker) {
+ this._marker
+ .bindPopup(L.Util.template(t, {distance: distance, unit: unit}))
+ ._popup.setLatLng(latlng);
+ }
+ },
+
+ /**
+ * Remove the marker from map.
+ */
+ _removeMarker: function() {
+ this._layer.clearLayers();
+ this._marker = undefined;
+ this._circle = undefined;
+ },
+
+ /**
+ * Unload the plugin and all event listeners.
+ * Kind of the opposite of onAdd.
+ */
+ _unload: function() {
+ this.stop();
+ this._map.off('unload', this._unload, this);
+ },
+
+ /**
+ * Calls deactivate and dispatches an error.
+ */
+ _onLocationError: function(err) {
+ // ignore time out error if the location is watched
+ if (err.code == 3 && this.options.locateOptions.watch) {
+ return;
+ }
+
+ this.stop();
+ this.options.onLocationError(err, this);
+ },
+
+ /**
+ * Stores the received event and updates the marker.
+ */
+ _onLocationFound: function(e) {
+ // no need to do anything if the location has not changed
+ if (this._event &&
+ (this._event.latlng.lat === e.latlng.lat &&
+ this._event.latlng.lng === e.latlng.lng &&
+ this._event.accuracy === e.accuracy)) {
+ return;
+ }
+
+ if (!this._active) {
+ // we may have a stray event
+ return;
+ }
+
+ this._event = e;
+
+ this._drawMarker();
+ this._updateContainerStyle();
+
+ switch (this.options.setView) {
+ case 'once':
+ if (this._justClicked) {
+ this.setView();
+ }
+ break;
+ case 'untilPan':
+ if (!this._userPanned) {
+ this.setView();
+ }
+ break;
+ case 'always':
+ this.setView();
+ break;
+ case false:
+ // don't set the view
+ break;
+ }
+
+ this._justClicked = false;
+ },
+
+ /**
+ * When the user drags. Need a separate even so we can bind and unbind even listeners.
+ */
+ _onDrag: function() {
+ // only react to drags once we have a location
+ if (this._event) {
+ this._userPanned = true;
+ this._updateContainerStyle();
+ this._drawMarker();
+ }
+ },
+
+ /**
+ * Compute whether the map is following the user location with pan and zoom.
+ */
+ _isFollowing: function() {
+ if (!this._active) {
+ return false;
+ }
+
+ if (this.options.setView === 'always') {
+ return true;
+ } else if (this.options.setView === 'untilPan') {
+ return !this._userPanned;
+ }
+ },
+
+ /**
+ * Check if location is in map bounds
+ */
+ _isOutsideMapBounds: function() {
+ if (this._event === undefined) {
+ return false;
+ }
+ return this._map.options.maxBounds &&
+ !this._map.options.maxBounds.contains(this._event.latlng);
+ },
+
+ /**
+ * Toggles button class between following and active.
+ */
+ _updateContainerStyle: function() {
+ if (!this._container) {
+ return;
+ }
+
+ if (this._active && !this._event) {
+ // active but don't have a location yet
+ this._setClasses('requesting');
+ } else if (this._isFollowing()) {
+ this._setClasses('following');
+ } else if (this._active) {
+ this._setClasses('active');
+ } else {
+ this._cleanClasses();
+ }
+ },
+
+ /**
+ * Sets the CSS classes for the state.
+ */
+ _setClasses: function(state) {
+ if (state == 'requesting') {
+ removeClasses(this._container, "active following");
+ addClasses(this._container, "requesting");
+
+ removeClasses(this._icon, this.options.icon);
+ addClasses(this._icon, this.options.iconLoading);
+ } else if (state == 'active') {
+ removeClasses(this._container, "requesting following");
+ addClasses(this._container, "active");
+
+ removeClasses(this._icon, this.options.iconLoading);
+ addClasses(this._icon, this.options.icon);
+ } else if (state == 'following') {
+ removeClasses(this._container, "requesting");
+ addClasses(this._container, "active following");
+
+ removeClasses(this._icon, this.options.iconLoading);
+ addClasses(this._icon, this.options.icon);
+ }
+ },
+
+ /**
+ * Removes all classes from button.
+ */
+ _cleanClasses: function() {
+ L.DomUtil.removeClass(this._container, "requesting");
+ L.DomUtil.removeClass(this._container, "active");
+ L.DomUtil.removeClass(this._container, "following");
+
+ removeClasses(this._icon, this.options.iconLoading);
+ addClasses(this._icon, this.options.icon);
+ },
+
+ /**
+ * Reinitializes state variables.
+ */
+ _resetVariables: function() {
+ // whether locate is active or not
+ this._active = false;
+
+ // true if the control was clicked for the first time
+ // we need this so we can pan and zoom once we have the location
+ this._justClicked = false;
+
+ // true if the user has panned the map after clicking the control
+ this._userPanned = false;
+ }
+ });
+
+ L.control.locate = function (options) {
+ return new L.Control.Locate(options);
+ };
+
+ return LocateControl;
+}, window));
diff --git a/frappe/public/js/lib/leaflet/easy-button.css b/frappe/public/js/lib/leaflet/easy-button.css
new file mode 100644
index 0000000000..18ce9ac161
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/easy-button.css
@@ -0,0 +1,56 @@
+.leaflet-bar button,
+.leaflet-bar button:hover {
+ background-color: #fff;
+ border: none;
+ border-bottom: 1px solid #ccc;
+ width: 26px;
+ height: 26px;
+ line-height: 26px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: black;
+}
+
+.leaflet-bar button {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ overflow: hidden;
+ display: block;
+}
+
+.leaflet-bar button:hover {
+ background-color: #f4f4f4;
+}
+
+.leaflet-bar button:first-of-type {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.leaflet-bar button:last-of-type {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom: none;
+}
+
+.leaflet-bar.disabled,
+.leaflet-bar button.disabled {
+ cursor: default;
+ pointer-events: none;
+ opacity: .4;
+}
+
+.easy-button-button .button-state{
+ display: block;
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+
+
+.leaflet-touch .leaflet-bar button {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
diff --git a/frappe/public/js/lib/leaflet/easy-button.js b/frappe/public/js/lib/leaflet/easy-button.js
new file mode 100644
index 0000000000..579dca6913
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/easy-button.js
@@ -0,0 +1,370 @@
+(function(){
+
+// This is for grouping buttons into a bar
+// takes an array of `L.easyButton`s and
+// then the usual `.addTo(map)`
+L.Control.EasyBar = L.Control.extend({
+
+ options: {
+ position: 'topleft', // part of leaflet's defaults
+ id: null, // an id to tag the Bar with
+ leafletClasses: true // use leaflet classes?
+ },
+
+
+ initialize: function(buttons, options){
+
+ if(options){
+ L.Util.setOptions( this, options );
+ }
+
+ this._buildContainer();
+ this._buttons = [];
+
+ for(var i = 0; i < buttons.length; i++){
+ buttons[i]._bar = this;
+ buttons[i]._container = buttons[i].button;
+ this._buttons.push(buttons[i]);
+ this.container.appendChild(buttons[i].button);
+ }
+
+ },
+
+
+ _buildContainer: function(){
+ this._container = this.container = L.DomUtil.create('div', '');
+ this.options.leafletClasses && L.DomUtil.addClass(this.container, 'leaflet-bar easy-button-container leaflet-control');
+ this.options.id && (this.container.id = this.options.id);
+ },
+
+
+ enable: function(){
+ L.DomUtil.addClass(this.container, 'enabled');
+ L.DomUtil.removeClass(this.container, 'disabled');
+ this.container.setAttribute('aria-hidden', 'false');
+ return this;
+ },
+
+
+ disable: function(){
+ L.DomUtil.addClass(this.container, 'disabled');
+ L.DomUtil.removeClass(this.container, 'enabled');
+ this.container.setAttribute('aria-hidden', 'true');
+ return this;
+ },
+
+
+ onAdd: function () {
+ return this.container;
+ },
+
+ addTo: function (map) {
+ this._map = map;
+
+ for(var i = 0; i < this._buttons.length; i++){
+ this._buttons[i]._map = map;
+ }
+
+ var container = this._container = this.onAdd(map),
+ pos = this.getPosition(),
+ corner = map._controlCorners[pos];
+
+ L.DomUtil.addClass(container, 'leaflet-control');
+
+ if (pos.indexOf('bottom') !== -1) {
+ corner.insertBefore(container, corner.firstChild);
+ } else {
+ corner.appendChild(container);
+ }
+
+ return this;
+ }
+
+});
+
+L.easyBar = function(){
+ var args = [L.Control.EasyBar];
+ for(var i = 0; i < arguments.length; i++){
+ args.push( arguments[i] );
+ }
+ return new (Function.prototype.bind.apply(L.Control.EasyBar, args));
+};
+
+// L.EasyButton is the actual buttons
+// can be called without being grouped into a bar
+L.Control.EasyButton = L.Control.extend({
+
+ options: {
+ position: 'topleft', // part of leaflet's defaults
+
+ id: null, // an id to tag the button with
+
+ type: 'replace', // [(replace|animate)]
+ // replace swaps out elements
+ // animate changes classes with all elements inserted
+
+ states: [], // state names look like this
+ // {
+ // stateName: 'untracked',
+ // onClick: function(){ handle_nav_manually(); };
+ // title: 'click to make inactive',
+ // icon: 'fa-circle', // wrapped with
+ // }
+
+ leafletClasses: true, // use leaflet styles for the button
+ tagName: 'button',
+ },
+
+
+
+ initialize: function(icon, onClick, title, id){
+
+ // clear the states manually
+ this.options.states = [];
+
+ // add id to options
+ if(id != null){
+ this.options.id = id;
+ }
+
+ // storage between state functions
+ this.storage = {};
+
+ // is the last item an object?
+ if( typeof arguments[arguments.length-1] === 'object' ){
+
+ // if so, it should be the options
+ L.Util.setOptions( this, arguments[arguments.length-1] );
+ }
+
+ // if there aren't any states in options
+ // use the early params
+ if( this.options.states.length === 0 &&
+ typeof icon === 'string' &&
+ typeof onClick === 'function'){
+
+ // turn the options object into a state
+ this.options.states.push({
+ icon: icon,
+ onClick: onClick,
+ title: typeof title === 'string' ? title : ''
+ });
+ }
+
+ // curate and move user's states into
+ // the _states for internal use
+ this._states = [];
+
+ for(var i = 0; i < this.options.states.length; i++){
+ this._states.push( new State(this.options.states[i], this) );
+ }
+
+ this._buildButton();
+
+ this._activateState(this._states[0]);
+
+ },
+
+ _buildButton: function(){
+
+ this.button = L.DomUtil.create(this.options.tagName, '');
+
+ if (this.options.tagName === 'button') {
+ this.button.setAttribute('type', 'button');
+ }
+
+ if (this.options.id ){
+ this.button.id = this.options.id;
+ }
+
+ if (this.options.leafletClasses){
+ L.DomUtil.addClass(this.button, 'easy-button-button leaflet-bar-part leaflet-interactive');
+ }
+
+ // don't let double clicks and mousedown get to the map
+ L.DomEvent.addListener(this.button, 'dblclick', L.DomEvent.stop);
+ L.DomEvent.addListener(this.button, 'mousedown', L.DomEvent.stop);
+
+ // take care of normal clicks
+ L.DomEvent.addListener(this.button,'click', function(e){
+ L.DomEvent.stop(e);
+ this._currentState.onClick(this, this._map ? this._map : null );
+ this._map && this._map.getContainer().focus();
+ }, this);
+
+ // prep the contents of the control
+ if(this.options.type == 'replace'){
+ this.button.appendChild(this._currentState.icon);
+ } else {
+ for(var i=0;i"']/) ){
+
+ // if so, the user should have put in html
+ // so move forward as such
+ tmpIcon = ambiguousIconString;
+
+ // then it wasn't html, so
+ // it's a class list, figure out what kind
+ } else {
+ ambiguousIconString = ambiguousIconString.replace(/(^\s*|\s*$)/g,'');
+ tmpIcon = L.DomUtil.create('span', '');
+
+ if( ambiguousIconString.indexOf('fa-') === 0 ){
+ L.DomUtil.addClass(tmpIcon, 'fa ' + ambiguousIconString)
+ } else if ( ambiguousIconString.indexOf('glyphicon-') === 0 ) {
+ L.DomUtil.addClass(tmpIcon, 'glyphicon ' + ambiguousIconString)
+ } else {
+ L.DomUtil.addClass(tmpIcon, /*rollwithit*/ ambiguousIconString)
+ }
+
+ // make this a string so that it's easy to set innerHTML below
+ tmpIcon = tmpIcon.outerHTML;
+ }
+
+ return tmpIcon;
+}
+
+})();
diff --git a/frappe/public/js/lib/leaflet/leaflet.css b/frappe/public/js/lib/leaflet/leaflet.css
new file mode 100644
index 0000000000..0d01a59ea3
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/leaflet.css
@@ -0,0 +1,632 @@
+/* required styles */
+
+.leaflet-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-container,
+.leaflet-pane > svg,
+.leaflet-pane > canvas,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ }
+.leaflet-container {
+ overflow: hidden;
+ }
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ }
+/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
+.leaflet-safari .leaflet-tile {
+ image-rendering: -webkit-optimize-contrast;
+ }
+/* hack that prevents hw layers "stretching" when loading new tiles */
+.leaflet-safari .leaflet-tile-container {
+ width: 1600px;
+ height: 1600px;
+ -webkit-transform-origin: 0 0;
+ }
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ display: block;
+ }
+/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
+/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
+.leaflet-container .leaflet-overlay-pane svg,
+.leaflet-container .leaflet-marker-pane img,
+.leaflet-container .leaflet-shadow-pane img,
+.leaflet-container .leaflet-tile-pane img,
+.leaflet-container img.leaflet-image-layer {
+ max-width: none !important; /* csslint allow: important */
+ }
+
+.leaflet-container.leaflet-touch-zoom {
+ -ms-touch-action: pan-x pan-y;
+ touch-action: pan-x pan-y;
+ }
+.leaflet-container.leaflet-touch-drag {
+ -ms-touch-action: pinch-zoom;
+ }
+.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.leaflet-container {
+ -webkit-tap-highlight-color: transparent;
+}
+.leaflet-container a {
+ -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
+}
+.leaflet-tile {
+ filter: inherit;
+ visibility: hidden;
+ }
+.leaflet-tile-loaded {
+ visibility: inherit;
+ }
+.leaflet-zoom-box {
+ width: 0;
+ height: 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ z-index: 800;
+ }
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+.leaflet-overlay-pane svg {
+ -moz-user-select: none;
+ }
+
+.leaflet-pane { z-index: 400; }
+
+.leaflet-tile-pane { z-index: 200; }
+.leaflet-overlay-pane { z-index: 400; }
+.leaflet-shadow-pane { z-index: 500; }
+.leaflet-marker-pane { z-index: 600; }
+.leaflet-tooltip-pane { z-index: 650; }
+.leaflet-popup-pane { z-index: 700; }
+
+.leaflet-map-pane canvas { z-index: 100; }
+.leaflet-map-pane svg { z-index: 200; }
+
+.leaflet-vml-shape {
+ width: 1px;
+ height: 1px;
+ }
+.lvml {
+ behavior: url(#default#VML);
+ display: inline-block;
+ position: absolute;
+ }
+
+
+/* control positioning */
+
+.leaflet-control {
+ position: relative;
+ z-index: 800;
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+ pointer-events: auto;
+ }
+.leaflet-top,
+.leaflet-bottom {
+ position: absolute;
+ z-index: 1000;
+ pointer-events: none;
+ }
+.leaflet-top {
+ top: 0;
+ }
+.leaflet-right {
+ right: 0;
+ }
+.leaflet-bottom {
+ bottom: 0;
+ }
+.leaflet-left {
+ left: 0;
+ }
+.leaflet-control {
+ float: left;
+ clear: both;
+ }
+.leaflet-right .leaflet-control {
+ float: right;
+ }
+.leaflet-top .leaflet-control {
+ margin-top: 10px;
+ }
+.leaflet-bottom .leaflet-control {
+ margin-bottom: 10px;
+ }
+.leaflet-left .leaflet-control {
+ margin-left: 10px;
+ }
+.leaflet-right .leaflet-control {
+ margin-right: 10px;
+ }
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile {
+ will-change: opacity;
+ }
+.leaflet-fade-anim .leaflet-popup {
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ -moz-transition: opacity 0.2s linear;
+ -o-transition: opacity 0.2s linear;
+ transition: opacity 0.2s linear;
+ }
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+ opacity: 1;
+ }
+.leaflet-zoom-animated {
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+ }
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ will-change: transform;
+ }
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
+ -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
+ -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
+ transition: transform 0.25s cubic-bezier(0,0,0.25,1);
+ }
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile {
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+ visibility: hidden;
+ }
+
+
+/* cursors */
+
+.leaflet-interactive {
+ cursor: pointer;
+ }
+.leaflet-grab {
+ cursor: -webkit-grab;
+ cursor: -moz-grab;
+ }
+.leaflet-crosshair,
+.leaflet-crosshair .leaflet-interactive {
+ cursor: crosshair;
+ }
+.leaflet-popup-pane,
+.leaflet-control {
+ cursor: auto;
+ }
+.leaflet-dragging .leaflet-grab,
+.leaflet-dragging .leaflet-grab .leaflet-interactive,
+.leaflet-dragging .leaflet-marker-draggable {
+ cursor: move;
+ cursor: -webkit-grabbing;
+ cursor: -moz-grabbing;
+ }
+
+/* marker & overlays interactivity */
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-image-layer,
+.leaflet-pane > svg path,
+.leaflet-tile-container {
+ pointer-events: none;
+ }
+
+.leaflet-marker-icon.leaflet-interactive,
+.leaflet-image-layer.leaflet-interactive,
+.leaflet-pane > svg path.leaflet-interactive {
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+ pointer-events: auto;
+ }
+
+/* visual tweaks */
+
+.leaflet-container {
+ background: #ddd;
+ outline: 0;
+ }
+.leaflet-container a {
+ color: #0078A8;
+ }
+.leaflet-container a.leaflet-active {
+ outline: 2px solid orange;
+ }
+.leaflet-zoom-box {
+ border: 2px dotted #38f;
+ background: rgba(255,255,255,0.5);
+ }
+
+
+/* general typography */
+.leaflet-container {
+ font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+ }
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+ box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+ border-radius: 4px;
+ }
+.leaflet-bar a,
+.leaflet-bar a:hover {
+ background-color: #fff;
+ border-bottom: 1px solid #ccc;
+ width: 26px;
+ height: 26px;
+ line-height: 26px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: black;
+ }
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ display: block;
+ }
+.leaflet-bar a:hover {
+ background-color: #f4f4f4;
+ }
+.leaflet-bar a:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ }
+.leaflet-bar a:last-child {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom: none;
+ }
+.leaflet-bar a.leaflet-disabled {
+ cursor: default;
+ background-color: #f4f4f4;
+ color: #bbb;
+ }
+
+.leaflet-touch .leaflet-bar a {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ }
+.leaflet-touch .leaflet-bar a:first-child {
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ }
+.leaflet-touch .leaflet-bar a:last-child {
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+ }
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+ font: bold 18px 'Lucida Console', Monaco, monospace;
+ text-indent: 1px;
+ }
+
+.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
+ font-size: 22px;
+ }
+
+
+/* layers control */
+
+.leaflet-control-layers {
+ box-shadow: 0 1px 5px rgba(0,0,0,0.4);
+ background: #fff;
+ border-radius: 5px;
+ }
+.leaflet-control-layers-toggle {
+ background-image: url(/assets/frappe/images/leaflet/layers.png);
+ width: 36px;
+ height: 36px;
+ }
+.leaflet-retina .leaflet-control-layers-toggle {
+ background-image: url(/assets/frappe/images/leaflet/layers-2x.png);
+ background-size: 26px 26px;
+ }
+.leaflet-touch .leaflet-control-layers-toggle {
+ width: 44px;
+ height: 44px;
+ }
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+ display: none;
+ }
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+ display: block;
+ position: relative;
+ }
+.leaflet-control-layers-expanded {
+ padding: 6px 10px 6px 6px;
+ color: #333;
+ background: #fff;
+ }
+.leaflet-control-layers-scrollbar {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ padding-right: 5px;
+ }
+.leaflet-control-layers-selector {
+ margin-top: 2px;
+ position: relative;
+ top: 1px;
+ }
+.leaflet-control-layers label {
+ display: block;
+ }
+.leaflet-control-layers-separator {
+ height: 0;
+ border-top: 1px solid #ddd;
+ margin: 5px -10px 5px -6px;
+ }
+
+/* Default icon URLs */
+.leaflet-default-icon-path {
+ background-image: url(/assets/frappe/images/leaflet/marker-icon.png);
+ }
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.7);
+ margin: 0;
+ }
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+ padding: 0 5px;
+ color: #333;
+ }
+.leaflet-control-attribution a {
+ text-decoration: none;
+ }
+.leaflet-control-attribution a:hover {
+ text-decoration: underline;
+ }
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+ font-size: 11px;
+ }
+.leaflet-left .leaflet-control-scale {
+ margin-left: 5px;
+ }
+.leaflet-bottom .leaflet-control-scale {
+ margin-bottom: 5px;
+ }
+.leaflet-control-scale-line {
+ border: 2px solid #777;
+ border-top: none;
+ line-height: 1.1;
+ padding: 2px 5px 1px;
+ font-size: 11px;
+ white-space: nowrap;
+ overflow: hidden;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+
+ background: #fff;
+ background: rgba(255, 255, 255, 0.5);
+ }
+.leaflet-control-scale-line:not(:first-child) {
+ border-top: 2px solid #777;
+ border-bottom: none;
+ margin-top: -2px;
+ }
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+ border-bottom: 2px solid #777;
+ }
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ box-shadow: none;
+ }
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ border: 2px solid rgba(0,0,0,0.2);
+ background-clip: padding-box;
+ }
+
+
+/* popup */
+
+.leaflet-popup {
+ position: absolute;
+ text-align: center;
+ margin-bottom: 20px;
+ }
+.leaflet-popup-content-wrapper {
+ padding: 1px;
+ text-align: left;
+ border-radius: 12px;
+ }
+.leaflet-popup-content {
+ margin: 13px 19px;
+ line-height: 1.4;
+ }
+.leaflet-popup-content p {
+ margin: 18px 0;
+ }
+.leaflet-popup-tip-container {
+ width: 40px;
+ height: 20px;
+ position: absolute;
+ left: 50%;
+ margin-left: -20px;
+ overflow: hidden;
+ pointer-events: none;
+ }
+.leaflet-popup-tip {
+ width: 17px;
+ height: 17px;
+ padding: 1px;
+
+ margin: -10px auto 0;
+
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
+ }
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+ background: white;
+ color: #333;
+ box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+ }
+.leaflet-container a.leaflet-popup-close-button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 4px 4px 0 0;
+ border: none;
+ text-align: center;
+ width: 18px;
+ height: 14px;
+ font: 16px/14px Tahoma, Verdana, sans-serif;
+ color: #c3c3c3;
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+ }
+.leaflet-container a.leaflet-popup-close-button:hover {
+ color: #999;
+ }
+.leaflet-popup-scrolled {
+ overflow: auto;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ }
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+ zoom: 1;
+ }
+.leaflet-oldie .leaflet-popup-tip {
+ width: 24px;
+ margin: 0 auto;
+
+ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+ filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+ }
+.leaflet-oldie .leaflet-popup-tip-container {
+ margin-top: -1px;
+ }
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+ border: 1px solid #999;
+ }
+
+
+/* div icon */
+
+.leaflet-div-icon {
+ background: #fff;
+ border: 1px solid #666;
+ }
+
+
+/* Tooltip */
+/* Base styles for the element that has a tooltip */
+.leaflet-tooltip {
+ position: absolute;
+ padding: 6px;
+ background-color: #fff;
+ border: 1px solid #fff;
+ border-radius: 3px;
+ color: #222;
+ white-space: nowrap;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ pointer-events: none;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.4);
+ }
+.leaflet-tooltip.leaflet-clickable {
+ cursor: pointer;
+ pointer-events: auto;
+ }
+.leaflet-tooltip-top:before,
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+ position: absolute;
+ pointer-events: none;
+ border: 6px solid transparent;
+ background: transparent;
+ content: "";
+ }
+
+/* Directions */
+
+.leaflet-tooltip-bottom {
+ margin-top: 6px;
+}
+.leaflet-tooltip-top {
+ margin-top: -6px;
+}
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-top:before {
+ left: 50%;
+ margin-left: -6px;
+ }
+.leaflet-tooltip-top:before {
+ bottom: 0;
+ margin-bottom: -12px;
+ border-top-color: #fff;
+ }
+.leaflet-tooltip-bottom:before {
+ top: 0;
+ margin-top: -12px;
+ margin-left: -6px;
+ border-bottom-color: #fff;
+ }
+.leaflet-tooltip-left {
+ margin-left: -6px;
+}
+.leaflet-tooltip-right {
+ margin-left: 6px;
+}
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+ top: 50%;
+ margin-top: -6px;
+ }
+.leaflet-tooltip-left:before {
+ right: 0;
+ margin-right: -12px;
+ border-left-color: #fff;
+ }
+.leaflet-tooltip-right:before {
+ left: 0;
+ margin-left: -12px;
+ border-right-color: #fff;
+ }
diff --git a/frappe/public/js/lib/leaflet/leaflet.draw.css b/frappe/public/js/lib/leaflet/leaflet.draw.css
new file mode 100644
index 0000000000..d1accd63bf
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/leaflet.draw.css
@@ -0,0 +1,10 @@
+.leaflet-draw-section{position:relative}.leaflet-draw-toolbar{margin-top:12px}.leaflet-draw-toolbar-top{margin-top:0}.leaflet-draw-toolbar-notop a:first-child{border-top-right-radius:0}.leaflet-draw-toolbar-nobottom a:last-child{border-bottom-right-radius:0}.leaflet-draw-toolbar a{background-image:url('/assets/frappe/images/leaflet/spritesheet.png');background-image:linear-gradient(transparent,transparent),url('/assets/frappe/images/leaflet/spritesheet.svg');background-repeat:no-repeat;background-size:300px 30px;background-clip:padding-box}.leaflet-retina .leaflet-draw-toolbar a{background-image:url('/assets/frappe/images/leaflet/spritesheet-2x.png');background-image:linear-gradient(transparent,transparent),url('/assets/frappe/images/leaflet/spritesheet.svg')}
+.leaflet-draw a{display:block;text-align:center;text-decoration:none}.leaflet-draw a .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.leaflet-draw-actions{display:none;list-style:none;margin:0;padding:0;position:absolute;left:26px;top:0;white-space:nowrap}.leaflet-touch .leaflet-draw-actions{left:32px}.leaflet-right .leaflet-draw-actions{right:26px;left:auto}.leaflet-touch .leaflet-right .leaflet-draw-actions{right:32px;left:auto}.leaflet-draw-actions li{display:inline-block}
+.leaflet-draw-actions li:first-child a{border-left:0}.leaflet-draw-actions li:last-child a{-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.leaflet-right .leaflet-draw-actions li:last-child a{-webkit-border-radius:0;border-radius:0}.leaflet-right .leaflet-draw-actions li:first-child a{-webkit-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.leaflet-draw-actions a{background-color:#919187;border-left:1px solid #AAA;color:#FFF;font:11px/19px "Helvetica Neue",Arial,Helvetica,sans-serif;line-height:28px;text-decoration:none;padding-left:10px;padding-right:10px;height:28px}
+.leaflet-touch .leaflet-draw-actions a{font-size:12px;line-height:30px;height:30px}.leaflet-draw-actions-bottom{margin-top:0}.leaflet-draw-actions-top{margin-top:1px}.leaflet-draw-actions-top a,.leaflet-draw-actions-bottom a{height:27px;line-height:27px}.leaflet-draw-actions a:hover{background-color:#a0a098}.leaflet-draw-actions-top.leaflet-draw-actions-bottom a{height:26px;line-height:26px}.leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:-2px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:0 -1px}
+.leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-31px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-29px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-62px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-60px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-92px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-90px -1px}
+.leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-122px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-120px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-273px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-271px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-152px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-150px -1px}
+.leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-182px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-180px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-212px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-210px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-242px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-240px -2px}
+.leaflet-mouse-marker{background-color:#fff;cursor:crosshair}.leaflet-draw-tooltip{background:#363636;background:rgba(0,0,0,0.5);border:1px solid transparent;-webkit-border-radius:4px;border-radius:4px;color:#fff;font:12px/18px "Helvetica Neue",Arial,Helvetica,sans-serif;margin-left:20px;margin-top:-21px;padding:4px 8px;position:absolute;visibility:hidden;white-space:nowrap;z-index:6}.leaflet-draw-tooltip:before{border-right:6px solid black;border-right-color:rgba(0,0,0,0.5);border-top:6px solid transparent;border-bottom:6px solid transparent;content:"";position:absolute;top:7px;left:-7px}
+.leaflet-error-draw-tooltip{background-color:#f2dede;border:1px solid #e6b6bd;color:#b94a48}.leaflet-error-draw-tooltip:before{border-right-color:#e6b6bd}.leaflet-draw-tooltip-single{margin-top:-12px}.leaflet-draw-tooltip-subtext{color:#f8d5e4}.leaflet-draw-guide-dash{font-size:1%;opacity:.6;position:absolute;width:5px;height:5px}.leaflet-edit-marker-selected{background-color:rgba(254,87,161,0.1);border:4px dashed rgba(254,87,161,0.6);-webkit-border-radius:4px;border-radius:4px;box-sizing:content-box}
+.leaflet-edit-move{cursor:move}.leaflet-edit-resize{cursor:pointer}.leaflet-oldie .leaflet-draw-toolbar{border:1px solid #999}
\ No newline at end of file
diff --git a/frappe/public/js/lib/leaflet/leaflet.draw.js b/frappe/public/js/lib/leaflet/leaflet.draw.js
new file mode 100644
index 0000000000..9fb5892a0c
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/leaflet.draw.js
@@ -0,0 +1,1702 @@
+/*
+ Leaflet.draw 0.4.12, a plugin that adds drawing and editing tools to Leaflet powered maps.
+ (c) 2012-2017, Jacob Toye, Jon West, Smartrak, Leaflet
+
+ https://github.com/Leaflet/Leaflet.draw
+ http://leafletjs.com
+ */
+! function(t, e, i) {
+ function o(t, e) {
+ for (;
+ (t = t.parentElement) && !t.classList.contains(e););
+ return t
+ }
+ L.drawVersion = "0.4.12", L.Draw = {}, L.drawLocal = {
+ draw: {
+ toolbar: {
+ actions: {
+ title: "Cancel drawing",
+ text: "Cancel"
+ },
+ finish: {
+ title: "Finish drawing",
+ text: "Finish"
+ },
+ undo: {
+ title: "Delete last point drawn",
+ text: "Delete last point"
+ },
+ buttons: {
+ polyline: "Draw a polyline",
+ polygon: "Draw a polygon",
+ rectangle: "Draw a rectangle",
+ circle: "Draw a circle",
+ marker: "Draw a marker",
+ circlemarker: "Draw a circlemarker"
+ }
+ },
+ handlers: {
+ circle: {
+ tooltip: {
+ start: "Click and drag to draw circle."
+ },
+ radius: "Radius"
+ },
+ circlemarker: {
+ tooltip: {
+ start: "Click map to place circle marker."
+ }
+ },
+ marker: {
+ tooltip: {
+ start: "Click map to place marker."
+ }
+ },
+ polygon: {
+ tooltip: {
+ start: "Click to start drawing shape.",
+ cont: "Click to continue drawing shape.",
+ end: "Click first point to close this shape."
+ }
+ },
+ polyline: {
+ error: "Error: shape edges cannot cross!",
+ tooltip: {
+ start: "Click to start drawing line.",
+ cont: "Click to continue drawing line.",
+ end: "Click last point to finish line."
+ }
+ },
+ rectangle: {
+ tooltip: {
+ start: "Click and drag to draw rectangle."
+ }
+ },
+ simpleshape: {
+ tooltip: {
+ end: "Release mouse to finish drawing."
+ }
+ }
+ }
+ },
+ edit: {
+ toolbar: {
+ actions: {
+ save: {
+ title: "Save changes",
+ text: "Save"
+ },
+ cancel: {
+ title: "Cancel editing, discards all changes",
+ text: "Cancel"
+ },
+ clearAll: {
+ title: "Clear all layers",
+ text: "Clear All"
+ }
+ },
+ buttons: {
+ edit: "Edit layers",
+ editDisabled: "No layers to edit",
+ remove: "Delete layers",
+ removeDisabled: "No layers to delete"
+ }
+ },
+ handlers: {
+ edit: {
+ tooltip: {
+ text: "Drag handles or markers to edit features.",
+ subtext: "Click cancel to undo changes."
+ }
+ },
+ remove: {
+ tooltip: {
+ text: "Click on a feature to remove."
+ }
+ }
+ }
+ }
+ }, L.Draw.Event = {}, L.Draw.Event.CREATED = "draw:created", L.Draw.Event.EDITED = "draw:edited", L.Draw.Event.DELETED = "draw:deleted", L.Draw.Event.DRAWSTART = "draw:drawstart", L.Draw.Event.DRAWSTOP = "draw:drawstop", L.Draw.Event.DRAWVERTEX = "draw:drawvertex", L.Draw.Event.EDITSTART = "draw:editstart", L.Draw.Event.EDITMOVE = "draw:editmove", L.Draw.Event.EDITRESIZE = "draw:editresize", L.Draw.Event.EDITVERTEX = "draw:editvertex", L.Draw.Event.EDITSTOP = "draw:editstop", L.Draw.Event.DELETESTART = "draw:deletestart", L.Draw.Event.DELETESTOP = "draw:deletestop", L.Draw = L.Draw || {}, L.Draw.Feature = L.Handler.extend({
+ initialize: function(t, e) {
+ this._map = t, this._container = t._container, this._overlayPane = t._panes.overlayPane, this._popupPane = t._panes.popupPane, e && e.shapeOptions && (e.shapeOptions = L.Util.extend({}, this.options.shapeOptions, e.shapeOptions)), L.setOptions(this, e);
+ var version = L.version.split(".");
+ if(parseInt(version[0],10) === 1 && parseInt(version[1],10) >= 2 ) {
+ L.Draw.Feature.include(L.Evented.prototype);
+ } else {
+ L.Draw.Feature.include(L.Mixin.Events);
+ }
+
+ },
+ enable: function() {
+ this._enabled || (L.Handler.prototype.enable.call(this), this.fire("enabled", {
+ handler: this.type
+ }), this._map.fire(L.Draw.Event.DRAWSTART, {
+ layerType: this.type
+ }))
+ },
+ disable: function() {
+ this._enabled && (L.Handler.prototype.disable.call(this), this._map.fire(L.Draw.Event.DRAWSTOP, {
+ layerType: this.type
+ }), this.fire("disabled", {
+ handler: this.type
+ }))
+ },
+ addHooks: function() {
+ var t = this._map;
+ t && (L.DomUtil.disableTextSelection(), t.getContainer().focus(), this._tooltip = new L.Draw.Tooltip(this._map), L.DomEvent.on(this._container, "keyup", this._cancelDrawing, this))
+ },
+ removeHooks: function() {
+ this._map && (L.DomUtil.enableTextSelection(), this._tooltip.dispose(), this._tooltip = null, L.DomEvent.off(this._container, "keyup", this._cancelDrawing, this))
+ },
+ setOptions: function(t) {
+ L.setOptions(this, t)
+ },
+ _fireCreatedEvent: function(t) {
+ this._map.fire(L.Draw.Event.CREATED, {
+ layer: t,
+ layerType: this.type
+ })
+ },
+ _cancelDrawing: function(t) {
+ 27 === t.keyCode && (this._map.fire("draw:canceled", {
+ layerType: this.type
+ }), this.disable())
+ }
+ }), L.Draw.Polyline = L.Draw.Feature.extend({
+ statics: {
+ TYPE: "polyline"
+ },
+ Poly: L.Polyline,
+ options: {
+ allowIntersection: !0,
+ repeatMode: !1,
+ drawError: {
+ color: "#b00b00",
+ timeout: 2500
+ },
+ icon: new L.DivIcon({
+ iconSize: new L.Point(8, 8),
+ className: "leaflet-div-icon leaflet-editing-icon"
+ }),
+ touchIcon: new L.DivIcon({
+ iconSize: new L.Point(20, 20),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-touch-icon"
+ }),
+ guidelineDistance: 20,
+ maxGuideLineLength: 4e3,
+ shapeOptions: {
+ stroke: !0,
+ color: "#3388ff",
+ weight: 4,
+ opacity: .5,
+ fill: !1,
+ clickable: !0
+ },
+ metric: !0,
+ feet: !0,
+ nautic: !1,
+ showLength: !0,
+ zIndexOffset: 2e3,
+ factor: 1
+ },
+ initialize: function(t, e) {
+ L.Browser.touch && (this.options.icon = this.options.touchIcon), this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error, e && e.drawError && (e.drawError = L.Util.extend({}, this.options.drawError, e.drawError)), this.type = L.Draw.Polyline.TYPE, L.Draw.Feature.prototype.initialize.call(this, t, e)
+ },
+ addHooks: function() {
+ L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._markers = [], this._markerGroup = new L.LayerGroup, this._map.addLayer(this._markerGroup), this._poly = new L.Polyline([], this.options.shapeOptions), this._tooltip.updateContent(this._getTooltipText()), this._mouseMarker || (this._mouseMarker = L.marker(this._map.getCenter(), {
+ icon: L.divIcon({
+ className: "leaflet-mouse-marker",
+ iconAnchor: [20, 20],
+ iconSize: [40, 40]
+ }),
+ opacity: 0,
+ zIndexOffset: this.options.zIndexOffset
+ })), this._mouseMarker.on("mouseout", this._onMouseOut, this).on("mousemove", this._onMouseMove, this).on("mousedown", this._onMouseDown, this).on("mouseup", this._onMouseUp, this).addTo(this._map), this._map.on("mouseup", this._onMouseUp, this).on("mousemove", this._onMouseMove, this).on("zoomlevelschange", this._onZoomEnd, this).on("touchstart", this._onTouch, this).on("zoomend", this._onZoomEnd, this))
+ },
+ removeHooks: function() {
+ L.Draw.Feature.prototype.removeHooks.call(this), this._clearHideErrorTimeout(), this._cleanUpShape(), this._map.removeLayer(this._markerGroup), delete this._markerGroup, delete this._markers, this._map.removeLayer(this._poly), delete this._poly, this._mouseMarker.off("mousedown", this._onMouseDown, this).off("mouseout", this._onMouseOut, this).off("mouseup", this._onMouseUp, this).off("mousemove", this._onMouseMove, this), this._map.removeLayer(this._mouseMarker), delete this._mouseMarker, this._clearGuides(), this._map.off("mouseup", this._onMouseUp, this).off("mousemove", this._onMouseMove, this).off("zoomlevelschange", this._onZoomEnd, this).off("zoomend", this._onZoomEnd, this).off("touchstart", this._onTouch, this).off("click", this._onTouch, this)
+ },
+ deleteLastVertex: function() {
+ if (!(this._markers.length <= 1)) {
+ var t = this._markers.pop(),
+ e = this._poly,
+ i = e.getLatLngs(),
+ o = i.splice(-1, 1)[0];
+ this._poly.setLatLngs(i), this._markerGroup.removeLayer(t), e.getLatLngs().length < 2 && this._map.removeLayer(e), this._vertexChanged(o, !1)
+ }
+ },
+ addVertex: function(t) {
+ if (this._markers.length >= 2 && !this.options.allowIntersection && this._poly.newLatLngIntersects(t)) return void this._showErrorTooltip();
+ this._errorShown && this._hideErrorTooltip(), this._markers.push(this._createMarker(t)), this._poly.addLatLng(t), 2 === this._poly.getLatLngs().length && this._map.addLayer(this._poly), this._vertexChanged(t, !0)
+ },
+ completeShape: function() {
+ this._markers.length <= 1 || (this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable())
+ },
+ _finishShape: function() {
+ var t = this._poly._defaultShape ? this._poly._defaultShape() : this._poly.getLatLngs(),
+ e = this._poly.newLatLngIntersects(t[t.length - 1]);
+ if (!this.options.allowIntersection && e || !this._shapeIsValid()) return void this._showErrorTooltip();
+ this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable()
+ },
+ _shapeIsValid: function() {
+ return !0
+ },
+ _onZoomEnd: function() {
+ null !== this._markers && this._updateGuide()
+ },
+ _onMouseMove: function(t) {
+ var e = this._map.mouseEventToLayerPoint(t.originalEvent),
+ i = this._map.layerPointToLatLng(e);
+ this._currentLatLng = i, this._updateTooltip(i), this._updateGuide(e), this._mouseMarker.setLatLng(i), L.DomEvent.preventDefault(t.originalEvent)
+ },
+ _vertexChanged: function(t, e) {
+ this._map.fire(L.Draw.Event.DRAWVERTEX, {
+ layers: this._markerGroup
+ }), this._updateFinishHandler(), this._updateRunningMeasure(t, e), this._clearGuides(), this._updateTooltip()
+ },
+ _onMouseDown: function(t) {
+ if (!this._clickHandled && !this._touchHandled && !this._disableMarkers) {
+ this._onMouseMove(t), this._clickHandled = !0, this._disableNewMarkers();
+ var e = t.originalEvent,
+ i = e.clientX,
+ o = e.clientY;
+ this._startPoint.call(this, i, o)
+ }
+ },
+ _startPoint: function(t, e) {
+ this._mouseDownOrigin = L.point(t, e)
+ },
+ _onMouseUp: function(t) {
+ var e = t.originalEvent,
+ i = e.clientX,
+ o = e.clientY;
+ this._endPoint.call(this, i, o, t), this._clickHandled = null
+ },
+ _endPoint: function(e, i, o) {
+ if (this._mouseDownOrigin) {
+ var n = L.point(e, i).distanceTo(this._mouseDownOrigin);
+ this._calculateFinishDistance(o.latlng) < 10 && L.Browser.touch ? this._finishShape() : Math.abs(n) < 9 * (t.devicePixelRatio || 1) && this.addVertex(o.latlng), this._enableNewMarkers()
+ }
+ this._mouseDownOrigin = null
+ },
+ _onTouch: function(t) {
+ var e, i, o = t.originalEvent;
+ !o.touches || !o.touches[0] || this._clickHandled || this._touchHandled || this._disableMarkers || (e = o.touches[0].clientX, i = o.touches[0].clientY, this._disableNewMarkers(), this._touchHandled = !0, this._startPoint.call(this, e, i), this._endPoint.call(this, e, i, t), this._touchHandled = null), this._clickHandled = null
+ },
+ _onMouseOut: function() {
+ this._tooltip && this._tooltip._onMouseOut.call(this._tooltip)
+ },
+ _calculateFinishDistance: function(t) {
+ var e;
+ if (this._markers.length > 0) {
+ var i;
+ if (this.type === L.Draw.Polyline.TYPE) i = this._markers[this._markers.length - 1];
+ else {
+ if (this.type !== L.Draw.Polygon.TYPE) return 1 / 0;
+ i = this._markers[0]
+ }
+ var o = this._map.latLngToContainerPoint(i.getLatLng()),
+ n = new L.Marker(t, {
+ icon: this.options.icon,
+ zIndexOffset: 2 * this.options.zIndexOffset
+ }),
+ a = this._map.latLngToContainerPoint(n.getLatLng());
+ e = o.distanceTo(a)
+ } else e = 1 / 0;
+ return e
+ },
+ _updateFinishHandler: function() {
+ var t = this._markers.length;
+ t > 1 && this._markers[t - 1].on("click", this._finishShape, this), t > 2 && this._markers[t - 2].off("click", this._finishShape, this)
+ },
+ _createMarker: function(t) {
+ var e = new L.Marker(t, {
+ icon: this.options.icon,
+ zIndexOffset: 2 * this.options.zIndexOffset
+ });
+ return this._markerGroup.addLayer(e), e
+ },
+ _updateGuide: function(t) {
+ var e = this._markers ? this._markers.length : 0;
+ e > 0 && (t = t || this._map.latLngToLayerPoint(this._currentLatLng), this._clearGuides(), this._drawGuide(this._map.latLngToLayerPoint(this._markers[e - 1].getLatLng()), t))
+ },
+ _updateTooltip: function(t) {
+ var e = this._getTooltipText();
+ t && this._tooltip.updatePosition(t), this._errorShown || this._tooltip.updateContent(e)
+ },
+ _drawGuide: function(t, e) {
+ var i, o, n, a = Math.floor(Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2))),
+ s = this.options.guidelineDistance,
+ r = this.options.maxGuideLineLength,
+ l = a > r ? a - r : s;
+ for (this._guidesContainer || (this._guidesContainer = L.DomUtil.create("div", "leaflet-draw-guides", this._overlayPane)); l < a; l += this.options.guidelineDistance) i = l / a, o = {
+ x: Math.floor(t.x * (1 - i) + i * e.x),
+ y: Math.floor(t.y * (1 - i) + i * e.y)
+ }, n = L.DomUtil.create("div", "leaflet-draw-guide-dash", this._guidesContainer), n.style.backgroundColor = this._errorShown ? this.options.drawError.color : this.options.shapeOptions.color, L.DomUtil.setPosition(n, o)
+ },
+ _updateGuideColor: function(t) {
+ if (this._guidesContainer)
+ for (var e = 0, i = this._guidesContainer.childNodes.length; e < i; e++) this._guidesContainer.childNodes[e].style.backgroundColor = t
+ },
+ _clearGuides: function() {
+ if (this._guidesContainer)
+ for (; this._guidesContainer.firstChild;) this._guidesContainer.removeChild(this._guidesContainer.firstChild)
+ },
+ _getTooltipText: function() {
+ var t, e, i = this.options.showLength;
+ return L.Browser.touch && (i = !1), 0 === this._markers.length ? t = {
+ text: L.drawLocal.draw.handlers.polyline.tooltip.start
+ } : (e = i ? this._getMeasurementString() : "", t = 1 === this._markers.length ? {
+ text: L.drawLocal.draw.handlers.polyline.tooltip.cont,
+ subtext: e
+ } : {
+ text: L.drawLocal.draw.handlers.polyline.tooltip.end,
+ subtext: e
+ }), t
+ },
+ _updateRunningMeasure: function(t, e) {
+ var i, o, n = this._markers.length;
+ 1 === this._markers.length ? this._measurementRunningTotal = 0 : (i = n - (e ? 2 : 1), o = this._map.distance(t, this._markers[i].getLatLng()) * (this.options.factor || 1), this._measurementRunningTotal += o * (e ? 1 : -1))
+ },
+ _getMeasurementString: function() {
+ var t, e = this._currentLatLng,
+ i = this._markers[this._markers.length - 1].getLatLng();
+ return t = i && e ? this._measurementRunningTotal + this._map.distance(e, i) * (this.options.factor || 1) : this._measurementRunningTotal || 0, L.GeometryUtil.readableDistance(t, this.options.metric, this.options.feet, this.options.nautic, this.options.precision)
+ },
+ _showErrorTooltip: function() {
+ this._errorShown = !0, this._tooltip.showAsError().updateContent({
+ text: this.options.drawError.message
+ }), this._updateGuideColor(this.options.drawError.color), this._poly.setStyle({
+ color: this.options.drawError.color
+ }), this._clearHideErrorTimeout(), this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorTooltip, this), this.options.drawError.timeout)
+ },
+ _hideErrorTooltip: function() {
+ this._errorShown = !1, this._clearHideErrorTimeout(), this._tooltip.removeError().updateContent(this._getTooltipText()), this._updateGuideColor(this.options.shapeOptions.color), this._poly.setStyle({
+ color: this.options.shapeOptions.color
+ })
+ },
+ _clearHideErrorTimeout: function() {
+ this._hideErrorTimeout && (clearTimeout(this._hideErrorTimeout), this._hideErrorTimeout = null)
+ },
+ _disableNewMarkers: function() {
+ this._disableMarkers = !0
+ },
+ _enableNewMarkers: function() {
+ setTimeout(function() {
+ this._disableMarkers = !1
+ }.bind(this), 50)
+ },
+ _cleanUpShape: function() {
+ this._markers.length > 1 && this._markers[this._markers.length - 1].off("click", this._finishShape, this)
+ },
+ _fireCreatedEvent: function() {
+ var t = new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions);
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, t)
+ }
+ }), L.Draw.Polygon = L.Draw.Polyline.extend({
+ statics: {
+ TYPE: "polygon"
+ },
+ Poly: L.Polygon,
+ options: {
+ showArea: !1,
+ showLength: !1,
+ shapeOptions: {
+ stroke: !0,
+ color: "#3388ff",
+ weight: 4,
+ opacity: .5,
+ fill: !0,
+ fillColor: null,
+ fillOpacity: .2,
+ clickable: !0
+ },
+ metric: !0,
+ feet: !0,
+ nautic: !1,
+ precision: {}
+ },
+ initialize: function(t, e) {
+ L.Draw.Polyline.prototype.initialize.call(this, t, e), this.type = L.Draw.Polygon.TYPE
+ },
+ _updateFinishHandler: function() {
+ var t = this._markers.length;
+ 1 === t && this._markers[0].on("click", this._finishShape, this), t > 2 && (this._markers[t - 1].on("dblclick", this._finishShape, this), t > 3 && this._markers[t - 2].off("dblclick", this._finishShape, this))
+ },
+ _getTooltipText: function() {
+ var t, e;
+ return 0 === this._markers.length ? t = L.drawLocal.draw.handlers.polygon.tooltip.start : this._markers.length < 3 ? (t = L.drawLocal.draw.handlers.polygon.tooltip.cont, e = this._getMeasurementString()) : (t = L.drawLocal.draw.handlers.polygon.tooltip.end, e = this._getMeasurementString()), {
+ text: t,
+ subtext: e
+ }
+ },
+ _getMeasurementString: function() {
+ var t = this._area,
+ e = "";
+ return t || this.options.showLength ? (this.options.showLength && (e = L.Draw.Polyline.prototype._getMeasurementString.call(this)), t && (e += "
" + L.GeometryUtil.readableArea(t, this.options.metric, this.options.precision)), e) : null
+ },
+ _shapeIsValid: function() {
+ return this._markers.length >= 3
+ },
+ _vertexChanged: function(t, e) {
+ var i;
+ !this.options.allowIntersection && this.options.showArea && (i = this._poly.getLatLngs(), this._area = L.GeometryUtil.geodesicArea(i)), L.Draw.Polyline.prototype._vertexChanged.call(this, t, e)
+ },
+ _cleanUpShape: function() {
+ var t = this._markers.length;
+ t > 0 && (this._markers[0].off("click", this._finishShape, this), t > 2 && this._markers[t - 1].off("dblclick", this._finishShape, this))
+ }
+ }), L.SimpleShape = {}, L.Draw.SimpleShape = L.Draw.Feature.extend({
+ options: {
+ repeatMode: !1
+ },
+ initialize: function(t, e) {
+ this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end, L.Draw.Feature.prototype.initialize.call(this, t, e)
+ },
+ addHooks: function() {
+ L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._mapDraggable = this._map.dragging.enabled(), this._mapDraggable && this._map.dragging.disable(), this._container.style.cursor = "crosshair", this._tooltip.updateContent({
+ text: this._initialLabelText
+ }), this._map.on("mousedown", this._onMouseDown, this).on("mousemove", this._onMouseMove, this).on("touchstart", this._onMouseDown, this).on("touchmove", this._onMouseMove, this))
+ },
+ removeHooks: function() {
+ L.Draw.Feature.prototype.removeHooks.call(this), this._map && (this._mapDraggable && this._map.dragging.enable(), this._container.style.cursor = "", this._map.off("mousedown", this._onMouseDown, this).off("mousemove", this._onMouseMove, this).off("touchstart", this._onMouseDown, this).off("touchmove", this._onMouseMove, this), L.DomEvent.off(e, "mouseup", this._onMouseUp, this), L.DomEvent.off(e, "touchend", this._onMouseUp, this), this._shape && (this._map.removeLayer(this._shape), delete this._shape)), this._isDrawing = !1
+ },
+ _getTooltipText: function() {
+ return {
+ text: this._endLabelText
+ }
+ },
+ _onMouseDown: function(t) {
+ this._isDrawing = !0, this._startLatLng = t.latlng, L.DomEvent.on(e, "mouseup", this._onMouseUp, this).on(e, "touchend", this._onMouseUp, this).preventDefault(t.originalEvent)
+ },
+ _onMouseMove: function(t) {
+ var e = t.latlng;
+ this._tooltip.updatePosition(e), this._isDrawing && (this._tooltip.updateContent(this._getTooltipText()), this._drawShape(e))
+ },
+ _onMouseUp: function() {
+ this._shape && this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable()
+ }
+ }), L.Draw.Rectangle = L.Draw.SimpleShape.extend({
+ statics: {
+ TYPE: "rectangle"
+ },
+ options: {
+ shapeOptions: {
+ stroke: !0,
+ color: "#3388ff",
+ weight: 4,
+ opacity: .5,
+ fill: !0,
+ fillColor: null,
+ fillOpacity: .2,
+ showArea: !0,
+ clickable: !0
+ },
+ metric: !0
+ },
+ initialize: function(t, e) {
+ this.type = L.Draw.Rectangle.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start, L.Draw.SimpleShape.prototype.initialize.call(this, t, e)
+ },
+ disable: function() {
+ this._enabled && (this._isCurrentlyTwoClickDrawing = !1, L.Draw.SimpleShape.prototype.disable.call(this))
+ },
+ _onMouseUp: function(t) {
+ if (!this._shape && !this._isCurrentlyTwoClickDrawing) return void(this._isCurrentlyTwoClickDrawing = !0);
+ this._isCurrentlyTwoClickDrawing && !o(t.target, "leaflet-pane") || L.Draw.SimpleShape.prototype._onMouseUp.call(this)
+ },
+ _drawShape: function(t) {
+ this._shape ? this._shape.setBounds(new L.LatLngBounds(this._startLatLng, t)) : (this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, t), this.options.shapeOptions), this._map.addLayer(this._shape))
+ },
+ _fireCreatedEvent: function() {
+ var t = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions);
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, t)
+ },
+ _getTooltipText: function() {
+ var t, e, i, o = L.Draw.SimpleShape.prototype._getTooltipText.call(this),
+ n = this._shape,
+ a = this.options.showArea;
+ return n && (t = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(), e = L.GeometryUtil.geodesicArea(t), i = a ? L.GeometryUtil.readableArea(e, this.options.metric) : ""), {
+ text: o.text,
+ subtext: i
+ }
+ }
+ }), L.Draw.Marker = L.Draw.Feature.extend({
+ statics: {
+ TYPE: "marker"
+ },
+ options: {
+ icon: new L.Icon.Default,
+ repeatMode: !1,
+ zIndexOffset: 2e3
+ },
+ initialize: function(t, e) {
+ this.type = L.Draw.Marker.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.marker.tooltip.start, L.Draw.Feature.prototype.initialize.call(this, t, e)
+ },
+ addHooks: function() {
+ L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._tooltip.updateContent({
+ text: this._initialLabelText
+ }), this._mouseMarker || (this._mouseMarker = L.marker(this._map.getCenter(), {
+ icon: L.divIcon({
+ className: "leaflet-mouse-marker",
+ iconAnchor: [20, 20],
+ iconSize: [40, 40]
+ }),
+ opacity: 0,
+ zIndexOffset: this.options.zIndexOffset
+ })), this._mouseMarker.on("click", this._onClick, this).addTo(this._map), this._map.on("mousemove", this._onMouseMove, this), this._map.on("click", this._onTouch, this))
+ },
+ removeHooks: function() {
+ L.Draw.Feature.prototype.removeHooks.call(this), this._map && (this._marker && (this._marker.off("click", this._onClick, this), this._map.off("click", this._onClick, this).off("click", this._onTouch, this).removeLayer(this._marker), delete this._marker), this._mouseMarker.off("click", this._onClick, this), this._map.removeLayer(this._mouseMarker), delete this._mouseMarker, this._map.off("mousemove", this._onMouseMove, this))
+ },
+ _onMouseMove: function(t) {
+ var e = t.latlng;
+ this._tooltip.updatePosition(e), this._mouseMarker.setLatLng(e), this._marker ? (e = this._mouseMarker.getLatLng(), this._marker.setLatLng(e)) : (this._marker = this._createMarker(e), this._marker.on("click", this._onClick, this), this._map.on("click", this._onClick, this).addLayer(this._marker))
+ },
+ _createMarker: function(t) {
+ return new L.Marker(t, {
+ icon: this.options.icon,
+ zIndexOffset: this.options.zIndexOffset
+ })
+ },
+ _onClick: function() {
+ this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable()
+ },
+ _onTouch: function(t) {
+ this._onMouseMove(t), this._onClick()
+ },
+ _fireCreatedEvent: function() {
+ var t = new L.Marker.Touch(this._marker.getLatLng(), {
+ icon: this.options.icon
+ });
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, t)
+ }
+ }), L.Draw.CircleMarker = L.Draw.Marker.extend({
+ statics: {
+ TYPE: "circlemarker"
+ },
+ options: {
+ stroke: !0,
+ color: "#3388ff",
+ weight: 4,
+ opacity: .5,
+ fill: !0,
+ fillColor: null,
+ fillOpacity: .2,
+ clickable: !0,
+ zIndexOffset: 2e3
+ },
+ initialize: function(t, e) {
+ this.type = L.Draw.CircleMarker.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.circlemarker.tooltip.start, L.Draw.Feature.prototype.initialize.call(this, t, e)
+ },
+ _fireCreatedEvent: function() {
+ var t = new L.CircleMarker(this._marker.getLatLng(), this.options);
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, t)
+ },
+ _createMarker: function(t) {
+ return new L.CircleMarker(t, this.options)
+ }
+ }), L.Draw.Circle = L.Draw.SimpleShape.extend({
+ statics: {
+ TYPE: "circle"
+ },
+ options: {
+ shapeOptions: {
+ stroke: !0,
+ color: "#3388ff",
+ weight: 4,
+ opacity: .5,
+ fill: !0,
+ fillColor: null,
+ fillOpacity: .2,
+ clickable: !0
+ },
+ showRadius: !0,
+ metric: !0,
+ feet: !0,
+ nautic: !1
+ },
+ initialize: function(t, e) {
+ this.type = L.Draw.Circle.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start, L.Draw.SimpleShape.prototype.initialize.call(this, t, e)
+ },
+ _drawShape: function(t) {
+ var e = this._map.distance(this._startLatLng, t);
+ this._shape ? this._shape.setRadius(e) : (this._shape = new L.Circle(this._startLatLng, e, this.options.shapeOptions), this._map.addLayer(this._shape))
+ },
+ _fireCreatedEvent: function() {
+ var t = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions);
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, t)
+ },
+ _onMouseMove: function(t) {
+ var e, i = t.latlng,
+ o = this.options.showRadius,
+ n = this.options.metric;
+ if (this._tooltip.updatePosition(i), this._isDrawing) {
+ this._drawShape(i), e = this._shape.getRadius().toFixed(1);
+ var a = "";
+ o && (a = L.drawLocal.draw.handlers.circle.radius + ": " + L.GeometryUtil.readableDistance(e, n, this.options.feet, this.options.nautic)), this._tooltip.updateContent({
+ text: this._endLabelText,
+ subtext: a
+ })
+ }
+ }
+ }), L.Edit = L.Edit || {}, L.Edit.Marker = L.Handler.extend({
+ initialize: function(t, e) {
+ this._marker = t, L.setOptions(this, e)
+ },
+ addHooks: function() {
+ var t = this._marker;
+ t.dragging.enable(), t.on("dragend", this._onDragEnd, t), this._toggleMarkerHighlight()
+ },
+ removeHooks: function() {
+ var t = this._marker;
+ t.dragging.disable(), t.off("dragend", this._onDragEnd, t), this._toggleMarkerHighlight()
+ },
+ _onDragEnd: function(t) {
+ var e = t.target;
+ e.edited = !0, this._map.fire(L.Draw.Event.EDITMOVE, {
+ layer: e
+ })
+ },
+ _toggleMarkerHighlight: function() {
+ var t = this._marker._icon;
+ t && (t.style.display = "none", L.DomUtil.hasClass(t, "leaflet-edit-marker-selected") ? (L.DomUtil.removeClass(t, "leaflet-edit-marker-selected"), this._offsetMarker(t, -4)) : (L.DomUtil.addClass(t, "leaflet-edit-marker-selected"), this._offsetMarker(t, 4)), t.style.display = "")
+ },
+ _offsetMarker: function(t, e) {
+ var i = parseInt(t.style.marginTop, 10) - e,
+ o = parseInt(t.style.marginLeft, 10) - e;
+ t.style.marginTop = i + "px", t.style.marginLeft = o + "px"
+ }
+ }), L.Marker.addInitHook(function() {
+ L.Edit.Marker && (this.editing = new L.Edit.Marker(this), this.options.editable && this.editing.enable())
+ }), L.Edit = L.Edit || {}, L.Edit.Poly = L.Handler.extend({
+ options: {},
+ initialize: function(t, e) {
+ this.latlngs = [t._latlngs], t._holes && (this.latlngs = this.latlngs.concat(t._holes)), this._poly = t, L.setOptions(this, e), this._poly.on("revert-edited", this._updateLatLngs, this)
+ },
+ _defaultShape: function() {
+ return L.Polyline._flat ? L.Polyline._flat(this._poly._latlngs) ? this._poly._latlngs : this._poly._latlngs[0] : this._poly._latlngs
+ },
+ _eachVertexHandler: function(t) {
+ for (var e = 0; e < this._verticesHandlers.length; e++) t(this._verticesHandlers[e])
+ },
+ addHooks: function() {
+ this._initHandlers(), this._eachVertexHandler(function(t) {
+ t.addHooks()
+ })
+ },
+ removeHooks: function() {
+ this._eachVertexHandler(function(t) {
+ t.removeHooks()
+ })
+ },
+ updateMarkers: function() {
+ this._eachVertexHandler(function(t) {
+ t.updateMarkers()
+ })
+ },
+ _initHandlers: function() {
+ this._verticesHandlers = [];
+ for (var t = 0; t < this.latlngs.length; t++) this._verticesHandlers.push(new L.Edit.PolyVerticesEdit(this._poly, this.latlngs[t], this.options))
+ },
+ _updateLatLngs: function(t) {
+ this.latlngs = [t.layer._latlngs], t.layer._holes && (this.latlngs = this.latlngs.concat(t.layer._holes))
+ }
+ }), L.Edit.PolyVerticesEdit = L.Handler.extend({
+ options: {
+ icon: new L.DivIcon({
+ iconSize: new L.Point(8, 8),
+ className: "leaflet-div-icon leaflet-editing-icon"
+ }),
+ touchIcon: new L.DivIcon({
+ iconSize: new L.Point(20, 20),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-touch-icon"
+ }),
+ drawError: {
+ color: "#b00b00",
+ timeout: 1e3
+ }
+ },
+ initialize: function(t, e, i) {
+ L.Browser.touch && (this.options.icon = this.options.touchIcon), this._poly = t, i && i.drawError && (i.drawError = L.Util.extend({}, this.options.drawError, i.drawError)), this._latlngs = e, L.setOptions(this, i)
+ },
+ _defaultShape: function() {
+ return L.Polyline._flat ? L.Polyline._flat(this._latlngs) ? this._latlngs : this._latlngs[0] : this._latlngs
+ },
+ addHooks: function() {
+ var t = this._poly;
+ t instanceof L.Polygon || (t.options.fill = !1, t.options.editing && (t.options.editing.fill = !1)), t.setStyle(t.options.editing), this._poly._map && (this._map = this._poly._map, this._markerGroup || this._initMarkers(), this._poly._map.addLayer(this._markerGroup))
+ },
+ removeHooks: function() {
+ var t = this._poly;
+ t.setStyle(t.options.original), t._map && (t._map.removeLayer(this._markerGroup), delete this._markerGroup, delete this._markers)
+ },
+ updateMarkers: function() {
+ this._markerGroup.clearLayers(), this._initMarkers()
+ },
+ _initMarkers: function() {
+ this._markerGroup || (this._markerGroup = new L.LayerGroup), this._markers = [];
+ var t, e, i, o, n = this._defaultShape();
+ for (t = 0, i = n.length; t < i; t++) o = this._createMarker(n[t], t), o.on("click", this._onMarkerClick, this), this._markers.push(o);
+ var a, s;
+ for (t = 0, e = i - 1; t < i; e = t++)(0 !== t || L.Polygon && this._poly instanceof L.Polygon) && (a = this._markers[e], s = this._markers[t], this._createMiddleMarker(a, s), this._updatePrevNext(a, s))
+ },
+ _createMarker: function(t, e) {
+ var i = new L.Marker.Touch(t, {
+ draggable: !0,
+ icon: this.options.icon
+ });
+ return i._origLatLng = t, i._index = e, i.on("dragstart", this._onMarkerDragStart, this).on("drag", this._onMarkerDrag, this).on("dragend", this._fireEdit, this).on("touchmove", this._onTouchMove, this).on("touchend", this._fireEdit, this).on("MSPointerMove", this._onTouchMove, this).on("MSPointerUp", this._fireEdit, this), this._markerGroup.addLayer(i), i
+ },
+ _onMarkerDragStart: function() {
+ this._poly.fire("editstart")
+ },
+ _spliceLatLngs: function() {
+ var t = this._defaultShape(),
+ e = [].splice.apply(t, arguments);
+ return this._poly._convertLatLngs(t, !0), this._poly.redraw(), e
+ },
+ _removeMarker: function(t) {
+ var e = t._index;
+ this._markerGroup.removeLayer(t), this._markers.splice(e, 1), this._spliceLatLngs(e, 1), this._updateIndexes(e, -1), t.off("dragstart", this._onMarkerDragStart, this).off("drag", this._onMarkerDrag, this).off("dragend", this._fireEdit, this).off("touchmove", this._onMarkerDrag, this).off("touchend", this._fireEdit, this).off("click", this._onMarkerClick, this).off("MSPointerMove", this._onTouchMove, this).off("MSPointerUp", this._fireEdit, this)
+ },
+ _fireEdit: function() {
+ this._poly.edited = !0, this._poly.fire("edit"), this._poly._map.fire(L.Draw.Event.EDITVERTEX, {
+ layers: this._markerGroup,
+ poly: this._poly
+ })
+ },
+ _onMarkerDrag: function(t) {
+ var e = t.target,
+ i = this._poly;
+ if (L.extend(e._origLatLng, e._latlng), e._middleLeft && e._middleLeft.setLatLng(this._getMiddleLatLng(e._prev, e)), e._middleRight && e._middleRight.setLatLng(this._getMiddleLatLng(e, e._next)), i.options.poly) {
+ var o = i._map._editTooltip;
+ if (!i.options.poly.allowIntersection && i.intersects()) {
+ var n = i.options.color;
+ i.setStyle({
+ color: this.options.drawError.color
+ }), 0 !== L.version.indexOf("0.7") && e.dragging._draggable._onUp(t), this._onMarkerClick(t), o && o.updateContent({
+ text: L.drawLocal.draw.handlers.polyline.error
+ }), setTimeout(function() {
+ i.setStyle({
+ color: n
+ }), o && o.updateContent({
+ text: L.drawLocal.edit.handlers.edit.tooltip.text,
+ subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
+ })
+ }, 1e3)
+ }
+ }
+ this._poly.redraw(), this._poly.fire("editdrag")
+ },
+ _onMarkerClick: function(t) {
+ var e = L.Polygon && this._poly instanceof L.Polygon ? 4 : 3,
+ i = t.target;
+ this._defaultShape().length < e || (this._removeMarker(i), this._updatePrevNext(i._prev, i._next), i._middleLeft && this._markerGroup.removeLayer(i._middleLeft), i._middleRight && this._markerGroup.removeLayer(i._middleRight), i._prev && i._next ? this._createMiddleMarker(i._prev, i._next) : i._prev ? i._next || (i._prev._middleRight = null) : i._next._middleLeft = null, this._fireEdit())
+ },
+ _onTouchMove: function(t) {
+ var e = this._map.mouseEventToLayerPoint(t.originalEvent.touches[0]),
+ i = this._map.layerPointToLatLng(e),
+ o = t.target;
+ L.extend(o._origLatLng, i), o._middleLeft && o._middleLeft.setLatLng(this._getMiddleLatLng(o._prev, o)), o._middleRight && o._middleRight.setLatLng(this._getMiddleLatLng(o, o._next)), this._poly.redraw(), this.updateMarkers()
+ },
+ _updateIndexes: function(t, e) {
+ this._markerGroup.eachLayer(function(i) {
+ i._index > t && (i._index += e)
+ })
+ },
+ _createMiddleMarker: function(t, e) {
+ var i, o, n, a = this._getMiddleLatLng(t, e),
+ s = this._createMarker(a);
+ s.setOpacity(.6), t._middleRight = e._middleLeft = s, o = function() {
+ s.off("touchmove", o, this);
+ var n = e._index;
+ s._index = n, s.off("click", i, this).on("click", this._onMarkerClick, this), a.lat = s.getLatLng().lat, a.lng = s.getLatLng().lng, this._spliceLatLngs(n, 0, a), this._markers.splice(n, 0, s), s.setOpacity(1), this._updateIndexes(n, 1), e._index++, this._updatePrevNext(t, s), this._updatePrevNext(s, e), this._poly.fire("editstart")
+ }, n = function() {
+ s.off("dragstart", o, this), s.off("dragend", n, this), s.off("touchmove", o, this), this._createMiddleMarker(t, s), this._createMiddleMarker(s, e)
+ }, i = function() {
+ o.call(this), n.call(this), this._fireEdit()
+ }, s.on("click", i, this).on("dragstart", o, this).on("dragend", n, this).on("touchmove", o, this), this._markerGroup.addLayer(s)
+ },
+ _updatePrevNext: function(t, e) {
+ t && (t._next = e), e && (e._prev = t)
+ },
+ _getMiddleLatLng: function(t, e) {
+ var i = this._poly._map,
+ o = i.project(t.getLatLng()),
+ n = i.project(e.getLatLng());
+ return i.unproject(o._add(n)._divideBy(2))
+ }
+ }), L.Polyline.addInitHook(function() {
+ this.editing || (L.Edit.Poly && (this.editing = new L.Edit.Poly(this, this.options.poly), this.options.editable && this.editing.enable()), this.on("add", function() {
+ this.editing && this.editing.enabled() && this.editing.addHooks()
+ }), this.on("remove", function() {
+ this.editing && this.editing.enabled() && this.editing.removeHooks()
+ }))
+ }), L.Edit = L.Edit || {}, L.Edit.SimpleShape = L.Handler.extend({
+ options: {
+ moveIcon: new L.DivIcon({
+ iconSize: new L.Point(8, 8),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-move"
+ }),
+ resizeIcon: new L.DivIcon({
+ iconSize: new L.Point(8, 8),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-resize"
+ }),
+ touchMoveIcon: new L.DivIcon({
+ iconSize: new L.Point(20, 20),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-move leaflet-touch-icon"
+ }),
+ touchResizeIcon: new L.DivIcon({
+ iconSize: new L.Point(20, 20),
+ className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-resize leaflet-touch-icon"
+ })
+ },
+ initialize: function(t, e) {
+ L.Browser.touch && (this.options.moveIcon = this.options.touchMoveIcon, this.options.resizeIcon = this.options.touchResizeIcon), this._shape = t, L.Util.setOptions(this, e)
+ },
+ addHooks: function() {
+ var t = this._shape;
+ this._shape._map && (this._map = this._shape._map, t.setStyle(t.options.editing), t._map && (this._map = t._map, this._markerGroup || this._initMarkers(), this._map.addLayer(this._markerGroup)))
+ },
+ removeHooks: function() {
+ var t = this._shape;
+ if (t.setStyle(t.options.original), t._map) {
+ this._unbindMarker(this._moveMarker);
+ for (var e = 0, i = this._resizeMarkers.length; e < i; e++) this._unbindMarker(this._resizeMarkers[e]);
+ this._resizeMarkers = null, this._map.removeLayer(this._markerGroup), delete this._markerGroup
+ }
+ this._map = null
+ },
+ updateMarkers: function() {
+ this._markerGroup.clearLayers(), this._initMarkers()
+ },
+ _initMarkers: function() {
+ this._markerGroup || (this._markerGroup = new L.LayerGroup), this._createMoveMarker(), this._createResizeMarker()
+ },
+ _createMoveMarker: function() {},
+ _createResizeMarker: function() {},
+ _createMarker: function(t, e) {
+ var i = new L.Marker.Touch(t, {
+ draggable: !0,
+ icon: e,
+ zIndexOffset: 10
+ });
+ return this._bindMarker(i), this._markerGroup.addLayer(i), i
+ },
+ _bindMarker: function(t) {
+ t.on("dragstart", this._onMarkerDragStart, this).on("drag", this._onMarkerDrag, this).on("dragend", this._onMarkerDragEnd, this).on("touchstart", this._onTouchStart, this).on("touchmove", this._onTouchMove, this).on("MSPointerMove", this._onTouchMove, this).on("touchend", this._onTouchEnd, this).on("MSPointerUp", this._onTouchEnd, this)
+ },
+ _unbindMarker: function(t) {
+ t.off("dragstart", this._onMarkerDragStart, this).off("drag", this._onMarkerDrag, this).off("dragend", this._onMarkerDragEnd, this).off("touchstart", this._onTouchStart, this).off("touchmove", this._onTouchMove, this).off("MSPointerMove", this._onTouchMove, this).off("touchend", this._onTouchEnd, this).off("MSPointerUp", this._onTouchEnd, this)
+ },
+ _onMarkerDragStart: function(t) {
+ t.target.setOpacity(0), this._shape.fire("editstart")
+ },
+ _fireEdit: function() {
+ this._shape.edited = !0, this._shape.fire("edit")
+ },
+ _onMarkerDrag: function(t) {
+ var e = t.target,
+ i = e.getLatLng();
+ e === this._moveMarker ? this._move(i) : this._resize(i), this._shape.redraw(), this._shape.fire("editdrag")
+ },
+ _onMarkerDragEnd: function(t) {
+ t.target.setOpacity(1), this._fireEdit()
+ },
+ _onTouchStart: function(t) {
+ if (L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, t), "function" == typeof this._getCorners) {
+ var e = this._getCorners(),
+ i = t.target,
+ o = i._cornerIndex;
+ i.setOpacity(0), this._oppositeCorner = e[(o + 2) % 4], this._toggleCornerMarkers(0, o)
+ }
+ this._shape.fire("editstart")
+ },
+ _onTouchMove: function(t) {
+ var e = this._map.mouseEventToLayerPoint(t.originalEvent.touches[0]),
+ i = this._map.layerPointToLatLng(e);
+ return t.target === this._moveMarker ? this._move(i) : this._resize(i), this._shape.redraw(), !1
+ },
+ _onTouchEnd: function(t) {
+ t.target.setOpacity(1), this.updateMarkers(), this._fireEdit()
+ },
+ _move: function() {},
+ _resize: function() {}
+ }), L.Edit = L.Edit || {}, L.Edit.Rectangle = L.Edit.SimpleShape.extend({
+ _createMoveMarker: function() {
+ var t = this._shape.getBounds(),
+ e = t.getCenter();
+ this._moveMarker = this._createMarker(e, this.options.moveIcon)
+ },
+ _createResizeMarker: function() {
+ var t = this._getCorners();
+ this._resizeMarkers = [];
+ for (var e = 0, i = t.length; e < i; e++) this._resizeMarkers.push(this._createMarker(t[e], this.options.resizeIcon)), this._resizeMarkers[e]._cornerIndex = e
+ },
+ _onMarkerDragStart: function(t) {
+ L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, t);
+ var e = this._getCorners(),
+ i = t.target,
+ o = i._cornerIndex;
+ this._oppositeCorner = e[(o + 2) % 4], this._toggleCornerMarkers(0, o)
+ },
+ _onMarkerDragEnd: function(t) {
+ var e, i, o = t.target;
+ o === this._moveMarker && (e = this._shape.getBounds(), i = e.getCenter(), o.setLatLng(i)), this._toggleCornerMarkers(1), this._repositionCornerMarkers(), L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, t)
+ },
+ _move: function(t) {
+ for (var e, i = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(), o = this._shape.getBounds(), n = o.getCenter(), a = [], s = 0, r = i.length; s < r; s++) e = [i[s].lat - n.lat, i[s].lng - n.lng], a.push([t.lat + e[0], t.lng + e[1]]);
+ this._shape.setLatLngs(a), this._repositionCornerMarkers(), this._map.fire(L.Draw.Event.EDITMOVE, {
+ layer: this._shape
+ })
+ },
+ _resize: function(t) {
+ var e;
+ this._shape.setBounds(L.latLngBounds(t, this._oppositeCorner)), e = this._shape.getBounds(), this._moveMarker.setLatLng(e.getCenter()), this._map.fire(L.Draw.Event.EDITRESIZE, {
+ layer: this._shape
+ })
+ },
+ _getCorners: function() {
+ var t = this._shape.getBounds();
+ return [t.getNorthWest(), t.getNorthEast(), t.getSouthEast(), t.getSouthWest()]
+ },
+ _toggleCornerMarkers: function(t) {
+ for (var e = 0, i = this._resizeMarkers.length; e < i; e++) this._resizeMarkers[e].setOpacity(t)
+ },
+ _repositionCornerMarkers: function() {
+ for (var t = this._getCorners(), e = 0, i = this._resizeMarkers.length; e < i; e++) this._resizeMarkers[e].setLatLng(t[e])
+ }
+ }), L.Rectangle.addInitHook(function() {
+ L.Edit.Rectangle && (this.editing = new L.Edit.Rectangle(this), this.options.editable && this.editing.enable())
+ }), L.Edit = L.Edit || {}, L.Edit.CircleMarker = L.Edit.SimpleShape.extend({
+ _createMoveMarker: function() {
+ var t = this._shape.getLatLng();
+ this._moveMarker = this._createMarker(t, this.options.moveIcon)
+ },
+ _createResizeMarker: function() {
+ this._resizeMarkers = []
+ },
+ _move: function(t) {
+ if (this._resizeMarkers.length) {
+ var e = this._getResizeMarkerPoint(t);
+ this._resizeMarkers[0].setLatLng(e)
+ }
+ this._shape.setLatLng(t), this._map.fire(L.Draw.Event.EDITMOVE, {
+ layer: this._shape
+ })
+ }
+ }), L.CircleMarker.addInitHook(function() {
+ L.Edit.CircleMarker && (this.editing = new L.Edit.CircleMarker(this), this.options.editable && this.editing.enable()), this.on("add", function() {
+ this.editing && this.editing.enabled() && this.editing.addHooks()
+ }), this.on("remove", function() {
+ this.editing && this.editing.enabled() && this.editing.removeHooks()
+ })
+ }), L.Edit = L.Edit || {}, L.Edit.Circle = L.Edit.CircleMarker.extend({
+ _createResizeMarker: function() {
+ var t = this._shape.getLatLng(),
+ e = this._getResizeMarkerPoint(t);
+ this._resizeMarkers = [], this._resizeMarkers.push(this._createMarker(e, this.options.resizeIcon))
+ },
+ _getResizeMarkerPoint: function(t) {
+ var e = this._shape._radius * Math.cos(Math.PI / 4),
+ i = this._map.project(t);
+ return this._map.unproject([i.x + e, i.y - e])
+ },
+ _resize: function(t) {
+ var e = this._moveMarker.getLatLng(),
+ i = this._map.distance(e, t);
+ this._shape.setRadius(i), this._map.fire(L.Draw.Event.EDITRESIZE, {
+ layer: this._shape
+ })
+ }
+ }), L.Circle.addInitHook(function() {
+ L.Edit.Circle && (this.editing = new L.Edit.Circle(this), this.options.editable && this.editing.enable()), this.on("add", function() {
+ this.editing && this.editing.enabled() && this.editing.addHooks()
+ }), this.on("remove", function() {
+ this.editing && this.editing.enabled() && this.editing.removeHooks()
+ })
+ }), L.Map.mergeOptions({
+ touchExtend: !0
+ }), L.Map.TouchExtend = L.Handler.extend({
+ initialize: function(t) {
+ this._map = t, this._container = t._container, this._pane = t._panes.overlayPane
+ },
+ addHooks: function() {
+ L.DomEvent.on(this._container, "touchstart", this._onTouchStart, this), L.DomEvent.on(this._container, "touchend", this._onTouchEnd, this), L.DomEvent.on(this._container, "touchmove", this._onTouchMove, this), this._detectIE() ? (L.DomEvent.on(this._container, "MSPointerDown", this._onTouchStart, this), L.DomEvent.on(this._container, "MSPointerUp", this._onTouchEnd, this), L.DomEvent.on(this._container, "MSPointerMove", this._onTouchMove, this), L.DomEvent.on(this._container, "MSPointerCancel", this._onTouchCancel, this)) : (L.DomEvent.on(this._container, "touchcancel", this._onTouchCancel, this), L.DomEvent.on(this._container, "touchleave", this._onTouchLeave, this))
+ },
+ removeHooks: function() {
+ L.DomEvent.off(this._container, "touchstart", this._onTouchStart), L.DomEvent.off(this._container, "touchend", this._onTouchEnd), L.DomEvent.off(this._container, "touchmove", this._onTouchMove), this._detectIE() ? (L.DomEvent.off(this._container, "MSPointerDowm", this._onTouchStart), L.DomEvent.off(this._container, "MSPointerUp", this._onTouchEnd), L.DomEvent.off(this._container, "MSPointerMove", this._onTouchMove), L.DomEvent.off(this._container, "MSPointerCancel", this._onTouchCancel)) : (L.DomEvent.off(this._container, "touchcancel", this._onTouchCancel), L.DomEvent.off(this._container, "touchleave", this._onTouchLeave))
+ },
+ _touchEvent: function(t, e) {
+ var i = {};
+ if (void 0 !== t.touches) {
+ if (!t.touches.length) return;
+ i = t.touches[0]
+ } else {
+ if ("touch" !== t.pointerType) return;
+ if (i = t, !this._filterClick(t)) return
+ }
+ var o = this._map.mouseEventToContainerPoint(i),
+ n = this._map.mouseEventToLayerPoint(i),
+ a = this._map.layerPointToLatLng(n);
+ this._map.fire(e, {
+ latlng: a,
+ layerPoint: n,
+ containerPoint: o,
+ pageX: i.pageX,
+ pageY: i.pageY,
+ originalEvent: t
+ })
+ },
+ _filterClick: function(t) {
+ var e = t.timeStamp || t.originalEvent.timeStamp,
+ i = L.DomEvent._lastClick && e - L.DomEvent._lastClick;
+ return i && i > 100 && i < 500 || t.target._simulatedClick && !t._simulated ? (L.DomEvent.stop(t), !1) : (L.DomEvent._lastClick = e, !0)
+ },
+ _onTouchStart: function(t) {
+ if (this._map._loaded) {
+ this._touchEvent(t, "touchstart")
+ }
+ },
+ _onTouchEnd: function(t) {
+ if (this._map._loaded) {
+ this._touchEvent(t, "touchend")
+ }
+ },
+ _onTouchCancel: function(t) {
+ if (this._map._loaded) {
+ var e = "touchcancel";
+ this._detectIE() && (e = "pointercancel"), this._touchEvent(t, e)
+ }
+ },
+ _onTouchLeave: function(t) {
+ if (this._map._loaded) {
+ this._touchEvent(t, "touchleave")
+ }
+ },
+ _onTouchMove: function(t) {
+ if (this._map._loaded) {
+ this._touchEvent(t, "touchmove")
+ }
+ },
+ _detectIE: function() {
+ var e = t.navigator.userAgent,
+ i = e.indexOf("MSIE ");
+ if (i > 0) return parseInt(e.substring(i + 5, e.indexOf(".", i)), 10);
+ if (e.indexOf("Trident/") > 0) {
+ var o = e.indexOf("rv:");
+ return parseInt(e.substring(o + 3, e.indexOf(".", o)), 10)
+ }
+ var n = e.indexOf("Edge/");
+ return n > 0 && parseInt(e.substring(n + 5, e.indexOf(".", n)), 10)
+ }
+ }), L.Map.addInitHook("addHandler", "touchExtend", L.Map.TouchExtend), L.Marker.Touch = L.Marker.extend({
+ _initInteraction: function() {
+ return this.addInteractiveTarget ? L.Marker.prototype._initInteraction.apply(this) : this._initInteractionLegacy()
+ },
+ _initInteractionLegacy: function() {
+ if (this.options.clickable) {
+ var t = this._icon,
+ e = ["dblclick", "mousedown", "mouseover", "mouseout", "contextmenu", "touchstart", "touchend", "touchmove"];
+ this._detectIE ? e.concat(["MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel"]) : e.concat(["touchcancel"]), L.DomUtil.addClass(t, "leaflet-clickable"), L.DomEvent.on(t, "click", this._onMouseClick, this), L.DomEvent.on(t, "keypress", this._onKeyPress, this);
+ for (var i = 0; i < e.length; i++) L.DomEvent.on(t, e[i], this._fireMouseEvent, this);
+ L.Handler.MarkerDrag && (this.dragging = new L.Handler.MarkerDrag(this), this.options.draggable && this.dragging.enable())
+ }
+ },
+ _detectIE: function() {
+ var e = t.navigator.userAgent,
+ i = e.indexOf("MSIE ");
+ if (i > 0) return parseInt(e.substring(i + 5, e.indexOf(".", i)), 10);
+ if (e.indexOf("Trident/") > 0) {
+ var o = e.indexOf("rv:");
+ return parseInt(e.substring(o + 3, e.indexOf(".", o)), 10)
+ }
+ var n = e.indexOf("Edge/");
+ return n > 0 && parseInt(e.substring(n + 5, e.indexOf(".", n)), 10)
+ }
+ }), L.LatLngUtil = {
+ cloneLatLngs: function(t) {
+ for (var e = [], i = 0, o = t.length; i < o; i++) Array.isArray(t[i]) ? e.push(L.LatLngUtil.cloneLatLngs(t[i])) : e.push(this.cloneLatLng(t[i]));
+ return e
+ },
+ cloneLatLng: function(t) {
+ return L.latLng(t.lat, t.lng)
+ }
+ },
+ function() {
+ var t = {
+ km: 2,
+ ha: 2,
+ m: 0,
+ mi: 2,
+ ac: 2,
+ yd: 0,
+ ft: 0,
+ nm: 2
+ };
+ L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
+ geodesicArea: function(t) {
+ var e, i, o = t.length,
+ n = 0,
+ a = Math.PI / 180;
+ if (o > 2) {
+ for (var s = 0; s < o; s++) e = t[s], i = t[(s + 1) % o], n += (i.lng - e.lng) * a * (2 + Math.sin(e.lat * a) + Math.sin(i.lat * a));
+ n = 6378137 * n * 6378137 / 2
+ }
+ return Math.abs(n)
+ },
+ formattedNumber: function(t, e) {
+ var i = parseFloat(t).toFixed(e),
+ o = L.drawLocal.format && L.drawLocal.format.numeric,
+ n = o && o.delimiters,
+ a = n && n.thousands,
+ s = n && n.decimal;
+ if (a || s) {
+ var r = i.split(".");
+ i = a ? r[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1" + a) : r[0], s = s || ".", r.length > 1 && (i = i + s + r[1])
+ }
+ return i
+ },
+ readableArea: function(e, i, o) {
+ var n, a, o = L.Util.extend({}, t, o);
+ return i ? (a = ["ha", "m"], type = typeof i, "string" === type ? a = [i] : "boolean" !== type && (a = i), n = e >= 1e6 && -1 !== a.indexOf("km") ? L.GeometryUtil.formattedNumber(1e-6 * e, o.km) + " km²" : e >= 1e4 && -1 !== a.indexOf("ha") ? L.GeometryUtil.formattedNumber(1e-4 * e, o.ha) + " ha" : L.GeometryUtil.formattedNumber(e, o.m) + " m²") : (e /= .836127, n = e >= 3097600 ? L.GeometryUtil.formattedNumber(e / 3097600, o.mi) + " mi²" : e >= 4840 ? L.GeometryUtil.formattedNumber(e / 4840, o.ac) + " acres" : L.GeometryUtil.formattedNumber(e, o.yd) + " yd²"), n
+ },
+ readableDistance: function(e, i, o, n, a) {
+ var s, a = L.Util.extend({}, t, a);
+ switch (i ? "string" == typeof i ? i : "metric" : o ? "feet" : n ? "nauticalMile" : "yards") {
+ case "metric":
+ s = e > 1e3 ? L.GeometryUtil.formattedNumber(e / 1e3, a.km) + " km" : L.GeometryUtil.formattedNumber(e, a.m) + " m";
+ break;
+ case "feet":
+ e *= 3.28083, s = L.GeometryUtil.formattedNumber(e, a.ft) + " ft";
+ break;
+ case "nauticalMile":
+ e *= .53996, s = L.GeometryUtil.formattedNumber(e / 1e3, a.nm) + " nm";
+ break;
+ case "yards":
+ default:
+ e *= 1.09361, s = e > 1760 ? L.GeometryUtil.formattedNumber(e / 1760, a.mi) + " miles" : L.GeometryUtil.formattedNumber(e, a.yd) + " yd"
+ }
+ return s
+ }
+ })
+ }(), L.Util.extend(L.LineUtil, {
+ segmentsIntersect: function(t, e, i, o) {
+ return this._checkCounterclockwise(t, i, o) !== this._checkCounterclockwise(e, i, o) && this._checkCounterclockwise(t, e, i) !== this._checkCounterclockwise(t, e, o)
+ },
+ _checkCounterclockwise: function(t, e, i) {
+ return (i.y - t.y) * (e.x - t.x) > (e.y - t.y) * (i.x - t.x)
+ }
+ }), L.Polyline.include({
+ intersects: function() {
+ var t, e, i, o = this._getProjectedPoints(),
+ n = o ? o.length : 0;
+ if (this._tooFewPointsForIntersection()) return !1;
+ for (t = n - 1; t >= 3; t--)
+ if (e = o[t - 1], i = o[t], this._lineSegmentsIntersectsRange(e, i, t - 2)) return !0;
+ return !1
+ },
+ newLatLngIntersects: function(t, e) {
+ return !!this._map && this.newPointIntersects(this._map.latLngToLayerPoint(t), e)
+ },
+ newPointIntersects: function(t, e) {
+ var i = this._getProjectedPoints(),
+ o = i ? i.length : 0,
+ n = i ? i[o - 1] : null,
+ a = o - 2;
+ return !this._tooFewPointsForIntersection(1) && this._lineSegmentsIntersectsRange(n, t, a, e ? 1 : 0)
+ },
+ _tooFewPointsForIntersection: function(t) {
+ var e = this._getProjectedPoints(),
+ i = e ? e.length : 0;
+ return i += t || 0, !e || i <= 3
+ },
+ _lineSegmentsIntersectsRange: function(t, e, i, o) {
+ var n, a, s = this._getProjectedPoints();
+ o = o || 0;
+ for (var r = i; r > o; r--)
+ if (n = s[r - 1], a = s[r], L.LineUtil.segmentsIntersect(t, e, n, a)) return !0;
+ return !1
+ },
+ _getProjectedPoints: function() {
+ if (!this._defaultShape) return this._originalPoints;
+ for (var t = [], e = this._defaultShape(), i = 0; i < e.length; i++) t.push(this._map.latLngToLayerPoint(e[i]));
+ return t
+ }
+ }), L.Polygon.include({
+ intersects: function() {
+ var t, e, i, o, n = this._getProjectedPoints();
+ return !this._tooFewPointsForIntersection() && (!!L.Polyline.prototype.intersects.call(this) || (t = n.length, e = n[0], i = n[t - 1], o = t - 2, this._lineSegmentsIntersectsRange(i, e, o, 1)))
+ }
+ }), L.Control.Draw = L.Control.extend({
+ options: {
+ position: "topleft",
+ draw: {},
+ edit: !1
+ },
+ initialize: function(t) {
+ if (L.version < "0.7") throw new Error("Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/");
+ L.Control.prototype.initialize.call(this, t);
+ var e;
+ this._toolbars = {}, L.DrawToolbar && this.options.draw && (e = new L.DrawToolbar(this.options.draw), this._toolbars[L.DrawToolbar.TYPE] = e, this._toolbars[L.DrawToolbar.TYPE].on("enable", this._toolbarEnabled, this)), L.EditToolbar && this.options.edit && (e = new L.EditToolbar(this.options.edit), this._toolbars[L.EditToolbar.TYPE] = e, this._toolbars[L.EditToolbar.TYPE].on("enable", this._toolbarEnabled, this)), L.toolbar = this
+ },
+ onAdd: function(t) {
+ var e, i = L.DomUtil.create("div", "leaflet-draw"),
+ o = !1;
+ for (var n in this._toolbars) this._toolbars.hasOwnProperty(n) && (e = this._toolbars[n].addToolbar(t)) && (o || (L.DomUtil.hasClass(e, "leaflet-draw-toolbar-top") || L.DomUtil.addClass(e.childNodes[0], "leaflet-draw-toolbar-top"), o = !0), i.appendChild(e));
+ return i
+ },
+ onRemove: function() {
+ for (var t in this._toolbars) this._toolbars.hasOwnProperty(t) && this._toolbars[t].removeToolbar()
+ },
+ setDrawingOptions: function(t) {
+ for (var e in this._toolbars) this._toolbars[e] instanceof L.DrawToolbar && this._toolbars[e].setOptions(t)
+ },
+ _toolbarEnabled: function(t) {
+ var e = t.target;
+ for (var i in this._toolbars) this._toolbars[i] !== e && this._toolbars[i].disable()
+ }
+ }), L.Map.mergeOptions({
+ drawControlTooltips: !0,
+ drawControl: !1
+ }), L.Map.addInitHook(function() {
+ this.options.drawControl && (this.drawControl = new L.Control.Draw, this.addControl(this.drawControl))
+ }), L.Toolbar = L.Class.extend({
+ initialize: function(t) {
+ L.setOptions(this, t);
+ this._modes = {};
+ this._actionButtons = [];
+ this._activeMode = null;
+ var version = L.version.split(".");
+ if (parseInt(version[0],10) === 1 && parseInt(version[1],10) >= 2 ) {
+ L.Toolbar.include(L.Evented.prototype);
+ } else {
+ L.Toolbar.include(L.Mixin.Events);
+ }
+ },
+ enabled: function() {
+ return this._activeMode !== null;
+ },
+ disable: function() {
+ this.enabled() && this._activeMode.handler.disable()
+ },
+ addToolbar: function(t) {
+ var e, i = L.DomUtil.create("div", "leaflet-draw-section"),
+ o = 0,
+ n = this._toolbarClass || "",
+ a = this.getModeHandlers(t);
+ for (this._toolbarContainer = L.DomUtil.create("div", "leaflet-draw-toolbar leaflet-bar"), this._map = t, e = 0; e < a.length; e++) a[e].enabled && this._initModeHandler(a[e].handler, this._toolbarContainer, o++, n, a[e].title);
+ if (o) return this._lastButtonIndex = --o, this._actionsContainer = L.DomUtil.create("ul", "leaflet-draw-actions"), i.appendChild(this._toolbarContainer), i.appendChild(this._actionsContainer), i
+ },
+ removeToolbar: function() {
+ for (var t in this._modes) this._modes.hasOwnProperty(t) && (this._disposeButton(this._modes[t].button, this._modes[t].handler.enable, this._modes[t].handler), this._modes[t].handler.disable(), this._modes[t].handler.off("enabled", this._handlerActivated, this).off("disabled", this._handlerDeactivated, this));
+ this._modes = {};
+ for (var e = 0, i = this._actionButtons.length; e < i; e++) this._disposeButton(this._actionButtons[e].button, this._actionButtons[e].callback, this);
+ this._actionButtons = [], this._actionsContainer = null
+ },
+ _initModeHandler: function(t, e, i, o, n) {
+ var a = t.type;
+ this._modes[a] = {}, this._modes[a].handler = t, this._modes[a].button = this._createButton({
+ type: a,
+ title: n,
+ className: o + "-" + a,
+ container: e,
+ callback: this._modes[a].handler.enable,
+ context: this._modes[a].handler
+ }), this._modes[a].buttonIndex = i, this._modes[a].handler.on("enabled", this._handlerActivated, this).on("disabled", this._handlerDeactivated, this)
+ },
+ _detectIOS: function() {
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) && !t.MSStream
+ },
+ _createButton: function(t) {
+ var e = L.DomUtil.create("a", t.className || "", t.container),
+ i = L.DomUtil.create("span", "sr-only", t.container);
+ e.href = "#", e.appendChild(i), t.title && (e.title = t.title, i.innerHTML = t.title), t.text && (e.innerHTML = t.text, i.innerHTML = t.text);
+ var o = this._detectIOS() ? "touchstart" : "click";
+ return L.DomEvent.on(e, "click", L.DomEvent.stopPropagation).on(e, "mousedown", L.DomEvent.stopPropagation).on(e, "dblclick", L.DomEvent.stopPropagation).on(e, "touchstart", L.DomEvent.stopPropagation).on(e, "click", L.DomEvent.preventDefault).on(e, o, t.callback, t.context), e
+ },
+ _disposeButton: function(t, e) {
+ var i = this._detectIOS() ? "touchstart" : "click";
+ L.DomEvent.off(t, "click", L.DomEvent.stopPropagation).off(t, "mousedown", L.DomEvent.stopPropagation).off(t, "dblclick", L.DomEvent.stopPropagation).off(t, "touchstart", L.DomEvent.stopPropagation).off(t, "click", L.DomEvent.preventDefault).off(t, i, e)
+ },
+ _handlerActivated: function(t) {
+ this.disable(), this._activeMode = this._modes[t.handler], L.DomUtil.addClass(this._activeMode.button, "leaflet-draw-toolbar-button-enabled"), this._showActionsToolbar(), this.fire("enable")
+ },
+ _handlerDeactivated: function() {
+ this._hideActionsToolbar(), L.DomUtil.removeClass(this._activeMode.button, "leaflet-draw-toolbar-button-enabled"), this._activeMode = null, this.fire("disable")
+ },
+ _createActions: function(t) {
+ var e, i, o, n, a = this._actionsContainer,
+ s = this.getActions(t),
+ r = s.length;
+ for (i = 0, o = this._actionButtons.length; i < o; i++) this._disposeButton(this._actionButtons[i].button, this._actionButtons[i].callback);
+ for (this._actionButtons = []; a.firstChild;) a.removeChild(a.firstChild);
+ for (var l = 0; l < r; l++) "enabled" in s[l] && !s[l].enabled || (e = L.DomUtil.create("li", "", a), n = this._createButton({
+ title: s[l].title,
+ text: s[l].text,
+ container: e,
+ callback: s[l].callback,
+ context: s[l].context
+ }), this._actionButtons.push({
+ button: n,
+ callback: s[l].callback
+ }))
+ },
+ _showActionsToolbar: function() {
+ var t = this._activeMode.buttonIndex,
+ e = this._lastButtonIndex,
+ i = this._activeMode.button.offsetTop - 1;
+ this._createActions(this._activeMode.handler), this._actionsContainer.style.top = i + "px", 0 === t && (L.DomUtil.addClass(this._toolbarContainer, "leaflet-draw-toolbar-notop"), L.DomUtil.addClass(this._actionsContainer, "leaflet-draw-actions-top")), t === e && (L.DomUtil.addClass(this._toolbarContainer, "leaflet-draw-toolbar-nobottom"), L.DomUtil.addClass(this._actionsContainer, "leaflet-draw-actions-bottom")), this._actionsContainer.style.display = "block"
+ },
+ _hideActionsToolbar: function() {
+ this._actionsContainer.style.display = "none", L.DomUtil.removeClass(this._toolbarContainer, "leaflet-draw-toolbar-notop"), L.DomUtil.removeClass(this._toolbarContainer, "leaflet-draw-toolbar-nobottom"), L.DomUtil.removeClass(this._actionsContainer, "leaflet-draw-actions-top"), L.DomUtil.removeClass(this._actionsContainer, "leaflet-draw-actions-bottom")
+ }
+ }), L.Draw = L.Draw || {}, L.Draw.Tooltip = L.Class.extend({
+ initialize: function(t) {
+ this._map = t, this._popupPane = t._panes.popupPane, this._visible = !1, this._container = t.options.drawControlTooltips ? L.DomUtil.create("div", "leaflet-draw-tooltip", this._popupPane) : null, this._singleLineLabel = !1, this._map.on("mouseout", this._onMouseOut, this)
+ },
+ dispose: function() {
+ this._map.off("mouseout", this._onMouseOut, this), this._container && (this._popupPane.removeChild(this._container), this._container = null)
+ },
+ updateContent: function(t) {
+ return this._container ? (t.subtext = t.subtext || "", 0 !== t.subtext.length || this._singleLineLabel ? t.subtext.length > 0 && this._singleLineLabel && (L.DomUtil.removeClass(this._container, "leaflet-draw-tooltip-single"), this._singleLineLabel = !1) : (L.DomUtil.addClass(this._container, "leaflet-draw-tooltip-single"), this._singleLineLabel = !0), this._container.innerHTML = (t.subtext.length > 0 ? '' + t.subtext + "
" : "") + "" + t.text + "", t.text || t.subtext ? (this._visible = !0, this._container.style.visibility = "inherit") : (this._visible = !1, this._container.style.visibility = "hidden"), this) : this
+ },
+ updatePosition: function(t) {
+ var e = this._map.latLngToLayerPoint(t),
+ i = this._container;
+ return this._container && (this._visible && (i.style.visibility = "inherit"), L.DomUtil.setPosition(i, e)), this
+ },
+ showAsError: function() {
+ return this._container && L.DomUtil.addClass(this._container, "leaflet-error-draw-tooltip"), this
+ },
+ removeError: function() {
+ return this._container && L.DomUtil.removeClass(this._container, "leaflet-error-draw-tooltip"), this
+ },
+ _onMouseOut: function() {
+ this._container && (this._container.style.visibility = "hidden")
+ }
+ }), L.DrawToolbar = L.Toolbar.extend({
+ statics: {
+ TYPE: "draw"
+ },
+ options: {
+ polyline: {},
+ polygon: {},
+ rectangle: {},
+ circle: {},
+ marker: {},
+ circlemarker: {}
+ },
+ initialize: function(t) {
+ for (var e in this.options) this.options.hasOwnProperty(e) && t[e] && (t[e] = L.extend({}, this.options[e], t[e]));
+ this._toolbarClass = "leaflet-draw-draw", L.Toolbar.prototype.initialize.call(this, t)
+ },
+ getModeHandlers: function(t) {
+ return [{
+ enabled: this.options.polyline,
+ handler: new L.Draw.Polyline(t, this.options.polyline),
+ title: L.drawLocal.draw.toolbar.buttons.polyline
+ }, {
+ enabled: this.options.polygon,
+ handler: new L.Draw.Polygon(t, this.options.polygon),
+ title: L.drawLocal.draw.toolbar.buttons.polygon
+ }, {
+ enabled: this.options.rectangle,
+ handler: new L.Draw.Rectangle(t, this.options.rectangle),
+ title: L.drawLocal.draw.toolbar.buttons.rectangle
+ }, {
+ enabled: this.options.circle,
+ handler: new L.Draw.Circle(t, this.options.circle),
+ title: L.drawLocal.draw.toolbar.buttons.circle
+ }, {
+ enabled: this.options.marker,
+ handler: new L.Draw.Marker(t, this.options.marker),
+ title: L.drawLocal.draw.toolbar.buttons.marker
+ }, {
+ enabled: this.options.circlemarker,
+ handler: new L.Draw.CircleMarker(t, this.options.circlemarker),
+ title: L.drawLocal.draw.toolbar.buttons.circlemarker
+ }]
+ },
+ getActions: function(t) {
+ return [{
+ enabled: t.completeShape,
+ title: L.drawLocal.draw.toolbar.finish.title,
+ text: L.drawLocal.draw.toolbar.finish.text,
+ callback: t.completeShape,
+ context: t
+ }, {
+ enabled: t.deleteLastVertex,
+ title: L.drawLocal.draw.toolbar.undo.title,
+ text: L.drawLocal.draw.toolbar.undo.text,
+ callback: t.deleteLastVertex,
+ context: t
+ }, {
+ title: L.drawLocal.draw.toolbar.actions.title,
+ text: L.drawLocal.draw.toolbar.actions.text,
+ callback: this.disable,
+ context: this
+ }]
+ },
+ setOptions: function(t) {
+ L.setOptions(this, t);
+ for (var e in this._modes) this._modes.hasOwnProperty(e) && t.hasOwnProperty(e) && this._modes[e].handler.setOptions(t[e])
+ }
+ }), L.EditToolbar = L.Toolbar.extend({
+ statics: {
+ TYPE: "edit"
+ },
+ options: {
+ edit: {
+ selectedPathOptions: {
+ dashArray: "10, 10",
+ fill: !0,
+ fillColor: "#fe57a1",
+ fillOpacity: .1,
+ maintainColor: !1
+ }
+ },
+ remove: {},
+ poly: null,
+ featureGroup: null
+ },
+ initialize: function(t) {
+ t.edit && (void 0 === t.edit.selectedPathOptions && (t.edit.selectedPathOptions = this.options.edit.selectedPathOptions), t.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, t.edit.selectedPathOptions)), t.remove && (t.remove = L.extend({}, this.options.remove, t.remove)), t.poly && (t.poly = L.extend({}, this.options.poly, t.poly)), this._toolbarClass = "leaflet-draw-edit", L.Toolbar.prototype.initialize.call(this, t), this._selectedFeatureCount = 0
+ },
+ getModeHandlers: function(t) {
+ var e = this.options.featureGroup;
+ return [{
+ enabled: this.options.edit,
+ handler: new L.EditToolbar.Edit(t, {
+ featureGroup: e,
+ selectedPathOptions: this.options.edit.selectedPathOptions,
+ poly: this.options.poly
+ }),
+ title: L.drawLocal.edit.toolbar.buttons.edit
+ }, {
+ enabled: this.options.remove,
+ handler: new L.EditToolbar.Delete(t, {
+ featureGroup: e
+ }),
+ title: L.drawLocal.edit.toolbar.buttons.remove
+ }]
+ },
+ getActions: function(t) {
+ var e = [{
+ title: L.drawLocal.edit.toolbar.actions.save.title,
+ text: L.drawLocal.edit.toolbar.actions.save.text,
+ callback: this._save,
+ context: this
+ }, {
+ title: L.drawLocal.edit.toolbar.actions.cancel.title,
+ text: L.drawLocal.edit.toolbar.actions.cancel.text,
+ callback: this.disable,
+ context: this
+ }];
+ return t.removeAllLayers && e.push({
+ title: L.drawLocal.edit.toolbar.actions.clearAll.title,
+ text: L.drawLocal.edit.toolbar.actions.clearAll.text,
+ callback: this._clearAllLayers,
+ context: this
+ }), e
+ },
+ addToolbar: function(t) {
+ var e = L.Toolbar.prototype.addToolbar.call(this, t);
+ return this._checkDisabled(), this.options.featureGroup.on("layeradd layerremove", this._checkDisabled, this), e
+ },
+ removeToolbar: function() {
+ this.options.featureGroup.off("layeradd layerremove", this._checkDisabled, this), L.Toolbar.prototype.removeToolbar.call(this)
+ },
+ disable: function() {
+ this.enabled() && (this._activeMode.handler.revertLayers(), L.Toolbar.prototype.disable.call(this))
+ },
+ _save: function() {
+ this._activeMode.handler.save(), this._activeMode && this._activeMode.handler.disable()
+ },
+ _clearAllLayers: function() {
+ this._activeMode.handler.removeAllLayers(), this._activeMode && this._activeMode.handler.disable()
+ },
+ _checkDisabled: function() {
+ var t, e = this.options.featureGroup,
+ i = 0 !== e.getLayers().length;
+ this.options.edit && (t = this._modes[L.EditToolbar.Edit.TYPE].button, i ? L.DomUtil.removeClass(t, "leaflet-disabled") : L.DomUtil.addClass(t, "leaflet-disabled"), t.setAttribute("title", i ? L.drawLocal.edit.toolbar.buttons.edit : L.drawLocal.edit.toolbar.buttons.editDisabled)), this.options.remove && (t = this._modes[L.EditToolbar.Delete.TYPE].button, i ? L.DomUtil.removeClass(t, "leaflet-disabled") : L.DomUtil.addClass(t, "leaflet-disabled"), t.setAttribute("title", i ? L.drawLocal.edit.toolbar.buttons.remove : L.drawLocal.edit.toolbar.buttons.removeDisabled))
+ }
+ }), L.EditToolbar.Edit = L.Handler.extend({
+ statics: {
+ TYPE: "edit"
+ },
+ initialize: function(t, e) {
+ if (L.Handler.prototype.initialize.call(this, t), L.setOptions(this, e), this._featureGroup = e.featureGroup, !(this._featureGroup instanceof L.FeatureGroup)) throw new Error("options.featureGroup must be a L.FeatureGroup");
+ this._uneditedLayerProps = {}, this.type = L.EditToolbar.Edit.TYPE;
+ var version = L.version.split(".");
+ if(parseInt(version[0],10) === 1 && parseInt(version[1],10) >= 2 ) {
+ L.EditToolbar.Edit.include(L.Evented.prototype);
+ } else {
+ L.EditToolbar.Edit.include(L.Mixin.Events);
+ }
+ },
+ enable: function() {
+ !this._enabled && this._hasAvailableLayers() && (this.fire("enabled", {
+ handler: this.type
+ }), this._map.fire(L.Draw.Event.EDITSTART, {
+ handler: this.type
+ }), L.Handler.prototype.enable.call(this), this._featureGroup.on("layeradd", this._enableLayerEdit, this).on("layerremove", this._disableLayerEdit, this))
+ },
+ disable: function() {
+ this._enabled && (this._featureGroup.off("layeradd", this._enableLayerEdit, this).off("layerremove", this._disableLayerEdit, this), L.Handler.prototype.disable.call(this), this._map.fire(L.Draw.Event.EDITSTOP, {
+ handler: this.type
+ }), this.fire("disabled", {
+ handler: this.type
+ }))
+ },
+ addHooks: function() {
+ var t = this._map;
+ t && (t.getContainer().focus(), this._featureGroup.eachLayer(this._enableLayerEdit, this), this._tooltip = new L.Draw.Tooltip(this._map), this._tooltip.updateContent({
+ text: L.drawLocal.edit.handlers.edit.tooltip.text,
+ subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
+ }), t._editTooltip = this._tooltip, this._updateTooltip(), this._map.on("mousemove", this._onMouseMove, this).on("touchmove", this._onMouseMove, this).on("MSPointerMove", this._onMouseMove, this).on(L.Draw.Event.EDITVERTEX, this._updateTooltip, this))
+ },
+ removeHooks: function() {
+ this._map && (this._featureGroup.eachLayer(this._disableLayerEdit, this), this._uneditedLayerProps = {}, this._tooltip.dispose(), this._tooltip = null, this._map.off("mousemove", this._onMouseMove, this).off("touchmove", this._onMouseMove, this).off("MSPointerMove", this._onMouseMove, this).off(L.Draw.Event.EDITVERTEX, this._updateTooltip, this))
+ },
+ revertLayers: function() {
+ this._featureGroup.eachLayer(function(t) {
+ this._revertLayer(t)
+ }, this)
+ },
+ save: function() {
+ var t = new L.LayerGroup;
+ this._featureGroup.eachLayer(function(e) {
+ e.edited && (t.addLayer(e), e.edited = !1)
+ }), this._map.fire(L.Draw.Event.EDITED, {
+ layers: t
+ })
+ },
+ _backupLayer: function(t) {
+ var e = L.Util.stamp(t);
+ this._uneditedLayerProps[e] || (t instanceof L.Polyline || t instanceof L.Polygon || t instanceof L.Rectangle ? this._uneditedLayerProps[e] = {
+ latlngs: L.LatLngUtil.cloneLatLngs(t.getLatLngs())
+ } : t instanceof L.Circle ? this._uneditedLayerProps[e] = {
+ latlng: L.LatLngUtil.cloneLatLng(t.getLatLng()),
+ radius: t.getRadius()
+ } : (t instanceof L.Marker || t instanceof L.CircleMarker) && (this._uneditedLayerProps[e] = {
+ latlng: L.LatLngUtil.cloneLatLng(t.getLatLng())
+ }))
+ },
+ _getTooltipText: function() {
+ return {
+ text: L.drawLocal.edit.handlers.edit.tooltip.text,
+ subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
+ }
+ },
+ _updateTooltip: function() {
+ this._tooltip.updateContent(this._getTooltipText())
+ },
+ _revertLayer: function(t) {
+ var e = L.Util.stamp(t);
+ t.edited = !1, this._uneditedLayerProps.hasOwnProperty(e) && (t instanceof L.Polyline || t instanceof L.Polygon || t instanceof L.Rectangle ? t.setLatLngs(this._uneditedLayerProps[e].latlngs) : t instanceof L.Circle ? (t.setLatLng(this._uneditedLayerProps[e].latlng), t.setRadius(this._uneditedLayerProps[e].radius)) : (t instanceof L.Marker || t instanceof L.CircleMarker) && t.setLatLng(this._uneditedLayerProps[e].latlng), t.fire("revert-edited", {
+ layer: t
+ }))
+ },
+ _enableLayerEdit: function(t) {
+ var e, i, o = t.layer || t.target || t;
+ this._backupLayer(o), this.options.poly && (i = L.Util.extend({}, this.options.poly), o.options.poly = i), this.options.selectedPathOptions && (e = L.Util.extend({}, this.options.selectedPathOptions), e.maintainColor && (e.color = o.options.color, e.fillColor = o.options.fillColor), o.options.original = L.extend({}, o.options), o.options.editing = e), o instanceof L.Marker ? (o.editing && o.editing.enable(), o.dragging.enable(), o.on("dragend", this._onMarkerDragEnd).on("touchmove", this._onTouchMove, this).on("MSPointerMove", this._onTouchMove, this).on("touchend", this._onMarkerDragEnd, this).on("MSPointerUp", this._onMarkerDragEnd, this)) : o.editing.enable()
+ },
+ _disableLayerEdit: function(t) {
+ var e = t.layer || t.target || t;
+ e.edited = !1, e.editing && e.editing.disable(), delete e.options.editing, delete e.options.original, this._selectedPathOptions && (e instanceof L.Marker ? this._toggleMarkerHighlight(e) : (e.setStyle(e.options.previousOptions), delete e.options.previousOptions)), e instanceof L.Marker ? (e.dragging.disable(), e.off("dragend", this._onMarkerDragEnd, this).off("touchmove", this._onTouchMove, this).off("MSPointerMove", this._onTouchMove, this).off("touchend", this._onMarkerDragEnd, this).off("MSPointerUp", this._onMarkerDragEnd, this)) : e.editing.disable()
+ },
+ _onMouseMove: function(t) {
+ this._tooltip.updatePosition(t.latlng)
+ },
+ _onMarkerDragEnd: function(t) {
+ var e = t.target;
+ e.edited = !0, this._map.fire(L.Draw.Event.EDITMOVE, {
+ layer: e
+ })
+ },
+ _onTouchMove: function(t) {
+ var e = t.originalEvent.changedTouches[0],
+ i = this._map.mouseEventToLayerPoint(e),
+ o = this._map.layerPointToLatLng(i);
+ t.target.setLatLng(o)
+ },
+ _hasAvailableLayers: function() {
+ return 0 !== this._featureGroup.getLayers().length
+ }
+ }), L.EditToolbar.Delete = L.Handler.extend({
+ statics: {
+ TYPE: "remove"
+ },
+ initialize: function(t, e) {
+ if (L.Handler.prototype.initialize.call(this, t), L.Util.setOptions(this, e), this._deletableLayers = this.options.featureGroup, !(this._deletableLayers instanceof L.FeatureGroup)) throw new Error("options.featureGroup must be a L.FeatureGroup");
+ this.type = L.EditToolbar.Delete.TYPE;
+ var version = L.version.split(".");
+ if(parseInt(version[0],10) === 1 && parseInt(version[1],10) >= 2 ) {
+ L.EditToolbar.Delete.include(L.Evented.prototype);
+ } else {
+ L.EditToolbar.Delete.include(L.Mixin.Events);
+ }
+ },
+ enable: function() {
+ !this._enabled && this._hasAvailableLayers() && (this.fire("enabled", {
+ handler: this.type
+ }), this._map.fire(L.Draw.Event.DELETESTART, {
+ handler: this.type
+ }), L.Handler.prototype.enable.call(this), this._deletableLayers.on("layeradd", this._enableLayerDelete, this).on("layerremove", this._disableLayerDelete, this))
+ },
+ disable: function() {
+ this._enabled && (this._deletableLayers.off("layeradd", this._enableLayerDelete, this).off("layerremove", this._disableLayerDelete, this), L.Handler.prototype.disable.call(this), this._map.fire(L.Draw.Event.DELETESTOP, {
+ handler: this.type
+ }), this.fire("disabled", {
+ handler: this.type
+ }))
+ },
+ addHooks: function() {
+ var t = this._map;
+ t && (t.getContainer().focus(), this._deletableLayers.eachLayer(this._enableLayerDelete, this), this._deletedLayers = new L.LayerGroup, this._tooltip = new L.Draw.Tooltip(this._map), this._tooltip.updateContent({
+ text: L.drawLocal.edit.handlers.remove.tooltip.text
+ }), this._map.on("mousemove", this._onMouseMove, this))
+ },
+ removeHooks: function() {
+ this._map && (this._deletableLayers.eachLayer(this._disableLayerDelete, this), this._deletedLayers = null, this._tooltip.dispose(), this._tooltip = null,
+ this._map.off("mousemove", this._onMouseMove, this))
+ },
+ revertLayers: function() {
+ this._deletedLayers.eachLayer(function(t) {
+ this._deletableLayers.addLayer(t), t.fire("revert-deleted", {
+ layer: t
+ })
+ }, this)
+ },
+ save: function() {
+ this._map.fire(L.Draw.Event.DELETED, {
+ layers: this._deletedLayers
+ })
+ },
+ removeAllLayers: function() {
+ this._deletableLayers.eachLayer(function(t) {
+ this._removeLayer({
+ layer: t
+ })
+ }, this), this.save()
+ },
+ _enableLayerDelete: function(t) {
+ (t.layer || t.target || t).on("click", this._removeLayer, this)
+ },
+ _disableLayerDelete: function(t) {
+ var e = t.layer || t.target || t;
+ e.off("click", this._removeLayer, this), this._deletedLayers.removeLayer(e)
+ },
+ _removeLayer: function(t) {
+ var e = t.layer || t.target || t;
+ this._deletableLayers.removeLayer(e), this._deletedLayers.addLayer(e), e.fire("deleted")
+ },
+ _onMouseMove: function(t) {
+ this._tooltip.updatePosition(t.latlng)
+ },
+ _hasAvailableLayers: function() {
+ return 0 !== this._deletableLayers.getLayers().length
+ }
+ })
+}(window, document);
diff --git a/frappe/public/js/lib/leaflet/leaflet.js b/frappe/public/js/lib/leaflet/leaflet.js
new file mode 100644
index 0000000000..b9fc9bcf58
--- /dev/null
+++ b/frappe/public/js/lib/leaflet/leaflet.js
@@ -0,0 +1,5 @@
+/* @preserve
+ * Leaflet 1.2.0, a JS library for interactive maps. http://leafletjs.com
+ * (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+ */
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e=0}function I(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function A(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(Xi,n,!1):"touchmove"===i?t.removeEventListener(Ji,n,!1):"touchend"===i&&(t.removeEventListener($i,n,!1),t.removeEventListener(Qi,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(te.indexOf(t.target.tagName)<0))return;$(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(Xi,o,!1),ee||(document.documentElement.addEventListener(Xi,R,!0),document.documentElement.addEventListener(Ji,D,!0),document.documentElement.addEventListener($i,N,!0),document.documentElement.addEventListener(Qi,N,!0),ee=!0)}function R(t){ie[t.pointerId]=t,ne++}function D(t){ie[t.pointerId]&&(ie[t.pointerId]=t)}function N(t){delete ie[t.pointerId],ne--}function j(t,i){t.touches=[];for(var e in ie)t.touches.push(ie[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(Ji,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener($i,n,!1),t.addEventListener(Qi,n,!1)}function F(t,i,e){function n(t){var i;if(Wi){if(!Li||"mouse"===t.pointerType)return;i=ne}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Wi){if(!Li||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[re+oe+e]=n,t[re+se+e]=o,t[re+"dblclick"+e]=i,t.addEventListener(oe,n,!1),t.addEventListener(se,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[re+oe+i],n=t[re+se+i],o=t[re+"dblclick"+i];return t.removeEventListener(oe,e,!1),t.removeEventListener(se,n,!1),Li||t.removeEventListener("dblclick",o,!1),this}function V(t,i,e,n){if("object"==typeof i)for(var o in i)q(t,o,i[o],e);else for(var s=0,r=(i=u(i)).length;s100&&n<500||t.target._simulatedClick&&!t._simulated?Q(t):(di=e,i(t))}function rt(t){return"string"==typeof t?document.getElementById(t):t}function at(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function ht(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function ut(t){var i=t.parentNode;i&&i.removeChild(t)}function lt(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function ct(t){var i=t.parentNode;i.lastChild!==t&&i.appendChild(t)}function _t(t){var i=t.parentNode;i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function dt(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=gt(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function pt(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;nh&&(s=r,h=a);h>e&&(i[s]=1,St(t,i,e,n,s),St(t,i,e,s,o))}function kt(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;ni&&(e.push(t[n]),o=n);return oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function Ot(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Rt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function Dt(t){return!ei(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Nt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),Dt(t)}function jt(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng1,Gi=!!document.createElement("canvas").getContext,qi=!(!document.createElementNS||!S("svg").createSVGRect),Ki=!qi&&function(){try{var t=document.createElement("div");t.innerHTML='';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),Yi=(Object.freeze||Object)({ie:xi,ielt9:wi,edge:Li,webkit:Pi,android:bi,android23:Ti,opera:zi,chrome:Mi,gecko:Ci,safari:Zi,phantom:Ei,opera12:Si,win:ki,ie3d:Bi,webkit3d:Ii,gecko3d:Ai,any3d:Oi,mobile:Ri,mobileWebkit:Di,mobileWebkit3d:Ni,msPointer:ji,pointer:Wi,touch:Hi,mobileOpera:Fi,mobileGecko:Ui,retina:Vi,canvas:Gi,svg:qi,vml:Ki}),Xi=ji?"MSPointerDown":"pointerdown",Ji=ji?"MSPointerMove":"pointermove",$i=ji?"MSPointerUp":"pointerup",Qi=ji?"MSPointerCancel":"pointercancel",te=["INPUT","SELECT","OPTION"],ie={},ee=!1,ne=0,oe=ji?"MSPointerDown":Wi?"pointerdown":"touchstart",se=ji?"MSPointerUp":Wi?"pointerup":"touchend",re="_leaflet_",ae="_leaflet_events",he=ki&&Mi?2*window.devicePixelRatio:Ci?window.devicePixelRatio:1,ue={},le=(Object.freeze||Object)({on:V,off:G,stopPropagation:Y,disableScrollPropagation:X,disableClickPropagation:J,preventDefault:$,stop:Q,getMousePosition:tt,getWheelDelta:it,fakeStop:et,skipped:nt,isExternalTarget:ot,addListener:V,removeListener:G}),ce=xt(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),_e=xt(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===_e||"OTransition"===_e?_e+"End":"transitionend";if("onselectstart"in document)pi=function(){V(window,"selectstart",$)},mi=function(){G(window,"selectstart",$)};else{var pe=xt(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);pi=function(){if(pe){var t=document.documentElement.style;fi=t[pe],t[pe]="none"}},mi=function(){pe&&(document.documentElement.style[pe]=fi,fi=void 0)}}var me,fe,ge=(Object.freeze||Object)({TRANSFORM:ce,TRANSITION:_e,TRANSITION_END:de,get:rt,getStyle:at,create:ht,remove:ut,empty:lt,toFront:ct,toBack:_t,hasClass:dt,addClass:pt,removeClass:mt,setClass:ft,getClass:gt,setOpacity:vt,testProp:xt,setTransform:wt,setPosition:Lt,getPosition:Pt,disableTextSelection:pi,enableTextSelection:mi,disableImageDrag:bt,enableImageDrag:Tt,preventOutline:zt,restoreOutline:Mt}),ve=ui.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=Pt(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;ithis.options.maxZoom?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}ut(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)ut(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=ht("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=Oi?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return tt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=rt(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");V(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&Oi,pt(t,"leaflet-container"+(Hi?" leaflet-touch":"")+(Vi?" leaflet-retina":"")+(wi?" leaflet-oldie":"")+(Zi?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=at(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Lt(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(pt(t.markerPane,"leaflet-zoom-hide"),pt(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){Lt(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t){return t&&this.fire("zoomstart"),this.fire("movestart")},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Lt(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?G:V;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),Oi&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!ot(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!ot(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!nt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||zt(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&$(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.options&&"icon"in s.options;r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=Oi?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){mt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._floor();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=ht("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=ce,e=this._proxy.style[i];wt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();wt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){ut(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,pt(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250)},_onZoomTransitionEnd:function(){this._animatingZoom&&(mt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),xe=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return pt(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(ut(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),we=function(t){return new xe(t)};ye.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=ht("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=ht("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)ut(this._controlCorners[t]);ut(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Le=xe.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),V(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),Pe=xe.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ht("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ht("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),J(s),V(s,"click",Q),V(s,"click",o,this),V(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";mt(this._zoomInButton,i),mt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&pt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&pt(this._zoomInButton,i)}});ye.mergeOptions({zoomControl:!0}),ye.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new Pe,this.addControl(this.zoomControl))});var be=xe.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=ht("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ht("div",i,e)),t.imperial&&(this._iScale=ht("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Te=xe.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=ht("div","leaflet-control-attribution"),J(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});ye.mergeOptions({attributionControl:!0}),ye.addInitHook(function(){this.options.attributionControl&&(new Te).addTo(this)});xe.Layers=Le,xe.Zoom=Pe,xe.Scale=be,xe.Attribution=Te,we.layers=function(t,i,e){return new Le(t,i,e)},we.zoom=function(t){return new Pe(t)},we.scale=function(t){return new be(t)},we.attribution=function(t){return new Te(t)};var ze,Me=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}}),Ce={Events:hi},Ze=Hi?"touchstart mousedown":"mousedown",Ee={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Se={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},ke=ui.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(V(this._dragStartTarget,Ze,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(ke._dragging===this&&this.finishDrag(),G(this._dragStartTarget,Ze,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!dt(this._element,"leaflet-zoom-anim")&&!(ke._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(ke._dragging=this,this._preventOutline&&zt(this._element),bt(),pi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t;this._startPoint=new x(i.clientX,i.clientY),V(document,Se[t.type],this._onMove,this),V(document,Ee[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY).subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},Re=(Object.freeze||Object)({LonLat:Ae,Mercator:Oe,SphericalMercator:_i}),De=i({},ci,{code:"EPSG:3395",projection:Oe,transformation:function(){var t=.5/(Math.PI*Oe.R);return E(t,.5,-t,.5)}()}),Ne=i({},ci,{code:"EPSG:4326",projection:Ae,transformation:E(1/180,1,-1/180,.5)}),je=i({},li,{projection:Ae,transformation:E(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});li.Earth=ci,li.EPSG3395=De,li.EPSG3857=gi,li.EPSG900913=vi,li.EPSG4326=Ne,li.Simple=je;var We=ui.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});ye.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?ei(t)?t:[t]:[]).length;ithis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return Dt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=Dt(t),n=0,o=t.length;n=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){Je.prototype._setLatLngs.call(this,t),Dt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return Dt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;ot.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||Je.prototype._containsPoint.call(this,t,!0)}}),Qe=Fe.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=ei(t)?t:t.features;if(o){for(i=0,e=o.length;io?(i.height=o+"px",pt(t,"leaflet-popup-scrolled")):mt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();Lt(this._container,i.add(e))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,i=parseInt(at(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(Pt(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Q(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});ye.mergeOptions({closePopupOnClick:!0}),ye.include({openPopup:function(t,i,e){return t instanceof rn||(t=new rn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),We.include({bindPopup:function(t,i){return t instanceof rn?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new rn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof We||(i=t,t=this),t instanceof Fe)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Q(t),i instanceof Ke?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var an=sn.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){sn.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){sn.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=sn.prototype.getEvents.call(this);return Hi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ht("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||en&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1this.options.maxZoom||void 0!==this.options.minZoom&&o1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);d.z=this._tileZoom,this._isValidTile(d)&&(this._tiles[this._tileCoordsToKey(d)]||r.push(d))}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var p=document.createDocumentFragment();for(_=0;_e.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToBounds:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e),s=new T(i.unproject(n,t.z),i.unproject(o,t.z));return this.options.noWrap||i.wrapLatLngBounds(s),s},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(ut(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){pt(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,wi&&this.options.opacity<1&&vt(t,this.options.opacity),bi&&!Ti&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),Lt(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){if(this._map){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(vt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(pt(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),wi||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),ln=un.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Vi&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),bi||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return V(n,"load",e(this._tileOnLoad,this,i,n)),V(n,"error",e(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Vi?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){wi?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.src!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=ni,ut(i)))}}),cn=ln.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);e=l(this,e),n.width=n.height=e.tileSize*(e.detectRetina&&Vi?2:1),this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,ln.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToBounds(t),e=this._crs.project(i.getNorthWest()),n=this._crs.project(i.getSouthEast()),o=(this._wmsVersion>=1.3&&this._crs===Ne?[n.y,e.x,e.y,n.x]:[e.x,n.y,n.x,e.y]).join(","),s=ln.prototype.getTileUrl.call(this,t);return s+c(this.wmsParams,s,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+o},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});ln.WMS=cn,Yt.wms=function(t,i){return new cn(t,i)};var _n=We.extend({options:{padding:.1},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&pt(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=Pt(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);Oi?wt(this._container,a,e):Lt(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),dn=_n.extend({getEvents:function(){var t=_n.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){_n.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");V(t,"mousemove",o(this._onMouseMove,32,this),this),V(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),V(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){delete this._ctx,ut(this._container),G(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},_n.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Vi?2:1;Lt(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Vi&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){_n.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,n=i.prev;e?e.prev=n:this._drawLast=n,n?n.next=e:this._drawFirst=e,delete t._order,delete this._layers[L.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var i,e=t.options.dashArray.split(","),n=[];for(i=0;i')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),mn={_initContainer:function(){this._container=ht("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(_n.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=pn("shape");pt(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=pn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;ut(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=pn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=ei(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=pn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){ct(t._container)},_bringToBack:function(t){_t(t._container)}},fn=Ki?pn:S,gn=_n.extend({getEvents:function(){var t=_n.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=fn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=fn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){ut(this._container),G(this._container),delete this._container,delete this._rootGroup},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){_n.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Lt(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=fn("path");t.options.className&&pt(i,t.options.className),t.options.interactive&&pt(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){ut(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=t._radius,n="a"+e+","+(t._radiusY||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){ct(t._path)},_bringToBack:function(t){_t(t._path)}});Ki&&gn.include(mn),ye.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this.options.preferCanvas&&Xt()||Jt()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=gn&&Jt({pane:t})||dn&&Xt({pane:t}),this._paneRenderers[t]=i),i}});var vn=$e.extend({initialize:function(t,i){$e.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});gn.create=fn,gn.pointsToPath=k,Qe.geometryToLayer=Wt,Qe.coordsToLatLng=Ht,Qe.coordsToLatLngs=Ft,Qe.latLngToCoords=Ut,Qe.latLngsToCoords=Vt,Qe.getFeature=Gt,Qe.asFeature=qt,ye.mergeOptions({boxZoom:!0});var yn=Me.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){V(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){G(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){ut(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),pi(),bt(),this._startPoint=this._map.mouseEventToContainerPoint(t),V(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ht("div","leaflet-zoom-box",this._container),pt(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();Lt(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(ut(this._box),mt(this._container,"leaflet-crosshair")),mi(),Tt(),G(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});ye.addInitHook("addHandler","boxZoom",yn),ye.mergeOptions({doubleClickZoom:!0});var xn=Me.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});ye.addInitHook("addHandler","doubleClickZoom",xn),ye.mergeOptions({dragging:!0,inertia:!Ti,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var wn=Me.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new ke(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}pt(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){mt(this._map._container,"leaflet-grab"),mt(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 t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),i-this._times[0]>50&&(this._positions.shift(),this._times.shift())}this._map.fire("move",t).fire("drag",t)},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.xi.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});ye.addInitHook("addHandler","scrollWheelZoom",Pn),ye.mergeOptions({tap:!0,tapTolerance:15});var bn=Me.extend({addHooks:function(){V(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){G(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if($(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&pt(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),V(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),G(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&mt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});Hi&&!Wi&&ye.addInitHook("addHandler","tap",bn),ye.mergeOptions({touchZoom:Hi&&!Ti,bounceAtZoomLimits:!0});var Tn=Me.extend({addHooks:function(){pt(this._map._container,"leaflet-touch-zoom"),V(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){mt(this._map._container,"leaflet-touch-zoom"),G(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),V(document,"touchmove",this._onTouchMove,this),V(document,"touchend",this._onTouchEnd,this),$(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoomi.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),$(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),G(document,"touchmove",this._onTouchMove),G(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});ye.addInitHook("addHandler","touchZoom",Tn),ye.BoxZoom=yn,ye.DoubleClickZoom=xn,ye.Drag=wn,ye.Keyboard=Ln,ye.ScrollWheelZoom=Pn,ye.Tap=bn,ye.TouchZoom=Tn;var zn=window.L;window.L=t,Object.freeze=$t,t.version="1.2.0",t.noConflict=function(){return window.L=zn,this},t.Control=xe,t.control=we,t.Browser=Yi,t.Evented=ui,t.Mixin=Ce,t.Util=ai,t.Class=v,t.Handler=Me,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=le,t.DomUtil=ge,t.PosAnimation=ve,t.Draggable=ke,t.LineUtil=Be,t.PolyUtil=Ie,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=Z,t.transformation=E,t.Projection=Re,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=li,t.GeoJSON=Qe,t.geoJSON=Kt,t.geoJson=en,t.Layer=We,t.LayerGroup=He,t.layerGroup=function(t){return new He(t)},t.FeatureGroup=Fe,t.featureGroup=function(t){return new Fe(t)},t.ImageOverlay=nn,t.imageOverlay=function(t,i,e){return new nn(t,i,e)},t.VideoOverlay=on,t.videoOverlay=function(t,i,e){return new on(t,i,e)},t.DivOverlay=sn,t.Popup=rn,t.popup=function(t,i){return new rn(t,i)},t.Tooltip=an,t.tooltip=function(t,i){return new an(t,i)},t.Icon=Ue,t.icon=function(t){return new Ue(t)},t.DivIcon=hn,t.divIcon=function(t){return new hn(t)},t.Marker=qe,t.marker=function(t,i){return new qe(t,i)},t.TileLayer=ln,t.tileLayer=Yt,t.GridLayer=un,t.gridLayer=function(t){return new un(t)},t.SVG=gn,t.svg=Jt,t.Renderer=_n,t.Canvas=dn,t.canvas=Xt,t.Path=Ke,t.CircleMarker=Ye,t.circleMarker=function(t,i){return new Ye(t,i)},t.Circle=Xe,t.circle=function(t,i,e){return new Xe(t,i,e)},t.Polyline=Je,t.polyline=function(t,i){return new Je(t,i)},t.Polygon=$e,t.polygon=function(t,i){return new $e(t,i)},t.Rectangle=vn,t.rectangle=function(t,i){return new vn(t,i)},t.Map=ye,t.map=function(t,i){return new ye(t,i)}});
\ No newline at end of file
diff --git a/frappe/templates/print_formats/standard_macros.html b/frappe/templates/print_formats/standard_macros.html
index a720b404f0..9d04bc1c0a 100644
--- a/frappe/templates/print_formats/standard_macros.html
+++ b/frappe/templates/print_formats/standard_macros.html
@@ -8,6 +8,8 @@
{%- elif df.fieldtype in ("Image", "Attach Image", "Attach", "Signature")
and (guess_mimetype(doc[df.fieldname])[0] or "").startswith("image/") -%}
{{ render_image(df, doc) }}
+ {%- elif df.fieldtype=="Geolocation" -%}
+ {{ render_geolocation(df, doc) }}
{%- else -%}
{{ render_field_with_label(df, doc) }}
{%- endif -%}
@@ -98,6 +100,10 @@ data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
{{ print_value(df, doc) }}
{% endmacro %}
+{%- macro render_geolocation(df, doc) -%}
+ {{ "" }}
+{%- endmacro -%}
+
{%- macro print_value(df, doc, parent_doc=None, visible_columns=None) -%}
{% if doc.print_templates and
doc.print_templates.get(df.fieldname) %}
diff --git a/frappe/tests/ui/test_control_geolocation.js b/frappe/tests/ui/test_control_geolocation.js
new file mode 100644
index 0000000000..0e3bedda26
--- /dev/null
+++ b/frappe/tests/ui/test_control_geolocation.js
@@ -0,0 +1,39 @@
+QUnit.module('controls');
+
+QUnit.test("Test ControlGeolocation", function(assert) {
+ assert.expect(1);
+
+ const random_name = frappe.utils.get_random(3).toLowerCase();
+
+ let done = assert.async();
+
+ // geolocation alert dialog suppressed (only secure origins or localhost allowed)
+ window.alert = function() {
+ console.log.apply(console, arguments); //eslint-disable-line
+ };
+
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Custom Field', [
+ {dt: 'ToDo'},
+ {fieldtype: 'Geolocation'},
+ {label: random_name},
+ ]);
+ },
+ () => frappe.set_route('List', 'ToDo'),
+ () => frappe.new_doc('ToDo'),
+ () => {
+ if (frappe.quick_entry)
+ {
+ frappe.quick_entry.dialog.$wrapper.find('.edit-full').click();
+ return frappe.timeout(1);
+ }
+ },
+ () => {
+ const control = $(`.frappe-control[data-fieldname="${random_name}"]`);
+
+ return assert.ok(control.data('fieldtype') === 'Geolocation');
+ },
+ () => done()
+ ]);
+});
diff --git a/frappe/tests/ui/tests.txt b/frappe/tests/ui/tests.txt
index 3c0bb98ebb..4526159cd4 100644
--- a/frappe/tests/ui/tests.txt
+++ b/frappe/tests/ui/tests.txt
@@ -14,3 +14,4 @@ frappe/desk/doctype/event/test_event.js
frappe/workflow/doctype/workflow/tests/test_workflow_create.js
frappe/workflow/doctype/workflow/tests/test_workflow_test.js
frappe/tests/ui/test_control_html.js
+frappe/tests/ui/test_control_geolocation.js