PageSourceSearch

https://lahioluvut.fi/leaflet-binding-2.1.1/leaflet.js

js lahioluvut.fi collected 2026-09-27 10:10:52 UTC 95,234 bytes, 2,785 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2"use strict";
3
4Object.defineProperty(exports, "__esModule", {
5  value: true
6});
7exports["default"] = undefined;
8
9var _util = require("./util");
10
11function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
13function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
14
15function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
16
17var ClusterLayerStore = /*#__PURE__*/function () {
18  function ClusterLayerStore(group) {
19    _classCallCheck(this, ClusterLayerStore);
20
21    this._layers = {};
22    this._group = group;
23  }
24
25  _createClass(ClusterLayerStore, [{
26    key: "add",
27    value: function add(layer, id) {
28      if (typeof id !== "undefined" && id !== null) {
29        if (this._layers[id]) {
30          this._group.removeLayer(this._layers[id]);
31        }
32
33        this._layers[id] = layer;
34      }
35
36      this._group.addLayer(layer);
37    }
38  }, {
39    key: "remove",
40    value: function remove(id) {
41      if (typeof id === "undefined" || id === null) {
42        return;
43      }
44
45      id = (0, _util.asArray)(id);
46
47      for (var i = 0; i < id.length; i++) {
48        if (this._layers[id[i]]) {
49          this._group.removeLayer(this._layers[id[i]]);
50
51          delete this._layers[id[i]];
52        }
53      }
54    }
55  }, {
56    key: "clear",
57    value: function clear() {
58      this._layers = {};
59
60      this._group.clearLayers();
61    }
62  }]);
63
64  return ClusterLayerStore;
65}();
66
67exports["default"] = ClusterLayerStore;
68
69
70},{"./util":17}],2:[function(require,module,exports){
71"use strict";
72
73Object.defineProperty(exports, "__esModule", {
74  value: true
75});
76
77function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
78
79function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
80
81function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
82
83var ControlStore = /*#__PURE__*/function () {
84  function ControlStore(map) {
85    _classCallCheck(this, ControlStore);
86
87    this._controlsNoId = [];
88    this._controlsById = {};
89    this._map = map;
90  }
91
92  _createClass(ControlStore, [{
93    key: "add",
94    value: function add(control, id, html) {
95      if (typeof id !== "undefined" && id !== null) {
96        if (this._controlsById[id]) {
97          this._map.removeControl(this._controlsById[id]);
98        }
99
100        this._controlsById[id] = control;
101      } else {
102        this._controlsNoId.push(control);
103      }
104
105      this._map.addControl(control);
106    }
107  }, {
108    key: "get",
109    value: function get(id) {
110      var control = null;
111
112      if (this._controlsById[id]) {
113        control = this._controlsById[id];
114      }
115
116      return control;
117    }
118  }, {
119    key: "remove",
120    value: function remove(id) {
121      if (this._controlsById[id]) {
122        var control = this._controlsById[id];
123
124        this._map.removeControl(control);
125
126        delete this._controlsById[id];
127      }
128    }
129  }, {
130    key: "clear",
131    value: function clear() {
132      for (var i = 0; i < this._controlsNoId.length; i++) {
133        var control = this._controlsNoId[i];
134
135        this._map.removeControl(control);
136      }
137
138      this._controlsNoId = [];
139
140      for (var key in this._controlsById) {
141        var _control = this._controlsById[key];
142
143        this._map.removeControl(_control);
144      }
145
146      this._controlsById = {};
147    }
148  }]);
149
150  return ControlStore;
151}();
152
153exports["default"] = ControlStore;
154
155
156},{}],3:[function(require,module,exports){
157"use strict";
158
159Object.defineProperty(exports, "__esModule", {
160  value: true
161});
162exports.getCRS = getCRS;
163
164var _leaflet = require("./global/leaflet");
165
166var _leaflet2 = _interopRequireDefault(_leaflet);
167
168var _proj4leaflet = require("./global/proj4leaflet");
169
170var _proj4leaflet2 = _interopRequireDefault(_proj4leaflet);
171
172function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
173
174// Helper function to instanciate a ICRS instance.
175function getCRS(crsOptions) {
176  var crs = _leaflet2["default"].CRS.EPSG3857; // Default Spherical Mercator
177
178  switch (crsOptions.crsClass) {
179    case "L.CRS.EPSG3857":
180      crs = _leaflet2["default"].CRS.EPSG3857;
181      break;
182
183    case "L.CRS.EPSG4326":
184      crs = _leaflet2["default"].CRS.EPSG4326;
185      break;
186
187    case "L.CRS.EPSG3395":
188      crs = _leaflet2["default"].CRS.EPSG3395;
189      break;
190
191    case "L.CRS.Simple":
192      crs = _leaflet2["default"].CRS.Simple;
193      break;
194
195    case "L.Proj.CRS":
196      if (crsOptions.options && crsOptions.options.bounds) {
197        crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds);
198      }
199
200      if (crsOptions.options && crsOptions.options.transformation) {
201        crsOptions.options.transformation = new _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]);
202      }
203
204      crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options);
205      break;
206
207    case "L.Proj.CRS.TMS":
208      if (crsOptions.options && crsOptions.options.bounds) {
209        crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds);
210      }
211
212      if (crsOptions.options && crsOptions.options.transformation) {
213        crsOptions.options.transformation = _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]);
214      } // L.Proj.CRS.TMS is deprecated as of Leaflet 1.x, fall back to L.Proj.CRS
215      //crs = new Proj4Leaflet.CRS.TMS(crsOptions.code, crsOptions.proj4def, crsOptions.projectedBounds, crsOptions.options);
216
217
218      crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options);
219      break;
220  }
221
222  return crs;
223}
224
225
226},{"./global/leaflet":10,"./global/proj4leaflet":11}],4:[function(require,module,exports){
227"use strict";
228
229Object.defineProperty(exports, "__esModule", {
230  value: true
231});
232exports["default"] = undefined;
233
234var _util = require("./util");
235
236function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
237
238function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
239
240function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
241
242var DataFrame = /*#__PURE__*/function () {
243  function DataFrame() {
244    _classCallCheck(this, DataFrame);
245
246    this.columns = [];
247    this.colnames = [];
248    this.colstrict = [];
249    this.effectiveLength = 0;
250    this.colindices = {};
251  }
252
253  _createClass(DataFrame, [{
254    key: "_updateCachedProperties",
255    value: function _updateCachedProperties() {
256      var _this = this;
257
258      this.effectiveLength = 0;
259      this.colindices = {};
260      this.columns.forEach(function (column, i) {
261        _this.effectiveLength = Math.max(_this.effectiveLength, column.length);
262        _this.colindices[_this.colnames[i]] = i;
263      });
264    }
265  }, {
266    key: "_colIndex",
267    value: function _colIndex(colname) {
268      var index = this.colindices[colname];
269      if (typeof index === "undefined") return -1;
270      return index;
271    }
272  }, {
273    key: "col",
274    value: function col(name, values, strict) {
275      if (typeof name !== "string") throw new Error("Invalid column name \"" + name + "\"");
276
277      var index = this._colIndex(name);
278
279      if (arguments.length === 1) {
280        if (index < 0) return null;else return (0, _util.recycle)(this.columns[index], this.effectiveLength);
281      }
282
283      if (index < 0) {
284        index = this.colnames.length;
285        this.colnames.push(name);
286      }
287
288      this.columns[index] = (0, _util.asArray)(values);
289      this.colstrict[index] = !!strict; // TODO: Validate strictness (ensure lengths match up with other stricts)
290
291      this._updateCachedProperties();
292
293      return this;
294    }
295  }, {
296    key: "cbind",
297    value: function cbind(obj, strict) {
298      var _this2 = this;
299
300      Object.keys(obj).forEach(function (name) {
301        var coldata = obj[name];
302
303        _this2.col(name, coldata);
304      });
305      return this;
306    }
307  }, {
308    key: "get",
309    value: function get(row, col, missingOK) {
310      var _this3 = this;
311
312      if (row > this.effectiveLength) throw new Error("Row argument was out of bounds: " + row + " > " + this.effectiveLength);
313      var colIndex = -1;
314
315      if (typeof col === "undefined") {
316        var rowData = {};
317        this.colnames.forEach(function (name, i) {
318          rowData[name] = _this3.columns[i][row % _this3.columns[i].length];
319        });
320        return rowData;
321      } else if (typeof col === "string") {
322        colIndex = this._colIndex(col);
323      } else if (typeof col === "number") {
324        colIndex = col;
325      }
326
327      if (colIndex < 0 || colIndex > this.columns.length) {
328        if (missingOK) return void 0;else throw new Error("Unknown column index: " + col);
329      }
330
331      return this.columns[colIndex][row % this.columns[colIndex].length];
332    }
333  }, {
334    key: "nrow",
335    value: function nrow() {
336      return this.effectiveLength;
337    }
338  }]);
339
340  return DataFrame;
341}();
342
343exports["default"] = DataFrame;
344
345
346},{"./util":17}],5:[function(require,module,exports){
347"use strict";
348
349var _leaflet = require("./global/leaflet");
350
351var _leaflet2 = _interopRequireDefault(_leaflet);
352
353function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
354
355// In RMarkdown's self-contained mode, we don't have a way to carry around the
356// images that Leaflet needs but doesn't load into the page. Instead, we'll use
357// the unpkg CDN.
358if (typeof _leaflet2["default"].Icon.Default.imagePath === "undefined") {
359  _leaflet2["default"].Icon.Default.imagePath = "https://unpkg.com/[email protected]/dist/images/";
360}
361
362
363},{"./global/leaflet":10}],6:[function(require,module,exports){
364"use strict";
365
366var _leaflet = require("./global/leaflet");
367
368var _leaflet2 = _interopRequireDefault(_leaflet);
369
370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
371
372// add texxtsize, textOnly, and style
373_leaflet2["default"].Tooltip.prototype.options.textsize = "10px";
374_leaflet2["default"].Tooltip.prototype.options.textOnly = false;
375_leaflet2["default"].Tooltip.prototype.options.style = null; // copy original layout to not completely stomp it.
376
377var initLayoutOriginal = _leaflet2["default"].Tooltip.prototype._initLayout;
378
379_leaflet2["default"].Tooltip.prototype._initLayout = function () {
380  initLayoutOriginal.call(this);
381  this._container.style.fontSize = this.options.textsize;
382
383  if (this.options.textOnly) {
384    _leaflet2["default"].DomUtil.addClass(this._container, "leaflet-tooltip-text-only");
385  }
386
387  if (this.options.style) {
388    for (var property in this.options.style) {
389      this._container.style[property] = this.options.style[property];
390    }
391  }
392};
393
394
395},{"./global/leaflet":10}],7:[function(require,module,exports){
396"use strict";
397
398var _leaflet = require("./global/leaflet");
399
400var _leaflet2 = _interopRequireDefault(_leaflet);
401
402function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
403
404var protocolRegex = /^\/\//;
405
406var upgrade_protocol = function upgrade_protocol(urlTemplate) {
407  if (protocolRegex.test(urlTemplate)) {
408    if (window.location.protocol === "file:") {
409      // if in a local file, support http
410      // http should auto upgrade if necessary
411      urlTemplate = "http:" + urlTemplate;
412    }
413  }
414
415  return urlTemplate;
416};
417
418var originalLTileLayerInitialize = _leaflet2["default"].TileLayer.prototype.initialize;
419
420_leaflet2["default"].TileLayer.prototype.initialize = function (urlTemplate, options) {
421  urlTemplate = upgrade_protocol(urlTemplate);
422  originalLTileLayerInitialize.call(this, urlTemplate, options);
423};
424
425var originalLTileLayerWMSInitialize = _leaflet2["default"].TileLayer.WMS.prototype.initialize;
426
427_leaflet2["default"].TileLayer.WMS.prototype.initialize = function (urlTemplate, options) {
428  urlTemplate = upgrade_protocol(urlTemplate);
429  originalLTileLayerWMSInitialize.call(this, urlTemplate, options);
430};
431
432
433},{"./global/leaflet":10}],8:[function(require,module,exports){
434(function (global){(function (){
435"use strict";
436
437Object.defineProperty(exports, "__esModule", {
438  value: true
439});
440exports["default"] = global.HTMLWidgets;
441
442
443}
443).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
444},{}],9:[function(require,module,exports){
445(function (global){(function (){
446"use strict";
447
448Object.defineProperty(exports, "__esModule", {
449  value: true
450});
451exports["default"] = global.jQuery;
452
453
454}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
455},{}],10:[function(require,module,exports){
456(function (global){(function (){
457"use strict";
458
459Object.defineProperty(exports, "__esModule", {
460  value: true
461});
462exports["default"] = global.L;
463
464
465}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
466},{}],11:[function(require,module,exports){
467(function (global){(function (){
468"use strict";
469
470Object.defineProperty(exports, "__esModule", {
471  value: true
472});
473exports["default"] = global.L.Proj;
474
475
476}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
477},{}],12:[function(require,module,exports){
478(function (global){(function (){
479"use strict";
480
481Object.defineProperty(exports, "__esModule", {
482  value: true
483});
484exports["default"] = global.Shiny;
485
486
487}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
488},{}],13:[function(require,module,exports){
489"use strict";
490
491var _jquery = require("./global/jquery");
492
493var _jquery2 = _interopRequireDefault(_jquery);
494
495var _leaflet = require("./global/leaflet");
496
497var _leaflet2 = _interopRequireDefault(_leaflet);
498
499var _shiny = require("./global/shiny");
500
501var _shiny2 = _interopRequireDefault(_shiny);
502
503var _htmlwidgets = require("./global/htmlwidgets");
504
505var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
506
507var _util = require("./util");
508
509var _crs_utils = require("./crs_utils");
510
511var _controlStore = require("./control-store");
512
513var _controlStore2 = _interopRequireDefault(_controlStore);
514
515var _layerManager = require("./layer-manager");
516
517var _layerManager2 = _interopRequireDefault(_layerManager);
518
519var _methods = require("./methods");
520
521var _methods2 = _interopRequireDefault(_methods);
522
523require("./fixup-default-icon");
524
525require("./fixup-default-tooltip");
526
527require("./fixup-url-protocol");
528
529var _dataframe = require("./dataframe");
530
531var _dataframe2 = _interopRequireDefault(_dataframe);
532
533var _clusterLayerStore = require("./cluster-layer-store");
534
535var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
536
537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
538
539window.LeafletWidget = {};
540window.LeafletWidget.utils = {};
541
542var methods = window.LeafletWidget.methods = _jquery2["default"].extend({}, _methods2["default"]);
543
544window.LeafletWidget.DataFrame = _dataframe2["default"];
545window.LeafletWidget.ClusterLayerStore = _clusterLayerStore2["default"];
546window.LeafletWidget.utils.getCRS = _crs_utils.getCRS; // Send updated bounds back to app. Takes a leaflet event object as input.
547
548function updateBounds(map) {
549  var id = map.getContainer().id;
550  var bounds = map.getBounds();
551
552  _shiny2["default"].onInputChange(id + "_bounds", {
553    north: bounds.getNorthEast().lat,
554    east: bounds.getNorthEast().lng,
555    south: bounds.getSouthWest().lat,
556    west: bounds.getSouthWest().lng
557  });
558
559  _shiny2["default"].onInputChange(id + "_center", {
560    lng: map.getCenter().lng,
561    lat: map.getCenter().lat
562  });
563
564  _shiny2["default"].onInputChange(id + "_zoom", map.getZoom());
565}
566
567function preventUnintendedZoomOnScroll(map) {
568  // Prevent unwanted scroll capturing. Similar in purpose to
569  // https://github.com/CliffCloud/Leaflet.Sleep but with a
570  // different set of heuristics.
571  // The basic idea is that when a mousewheel/DOMMouseScroll
572  // event is seen, we disable scroll wheel zooming until the
573  // user moves their mouse cursor or clicks on the map. This
574  // is slightly trickier than just listening for mousemove,
575  // because mousemove is fired when the page is scrolled,
576  // even if the user did not physically move the mouse. We
577  // handle this by examining the mousemove event's screenX
578  // and screenY properties; if they change, we know it's a
579  // "true" move.
580  // lastScreen can never be null, but its x and y can.
581  var lastScreen = {
582    x: null,
583    y: null
584  };
585  (0, _jquery2["default"])(document).on("mousewheel DOMMouseScroll", "*", function (e) {
586    // Disable zooming (until the mouse moves or click)
587    map.scrollWheelZoom.disable(); // Any mousemove events at this screen position will be ignored.
588
589    lastScreen = {
590      x: e.originalEvent.screenX,
591      y: e.originalEvent.screenY
592    };
593  });
594  (0, _jquery2["default"])(document).on("mousemove", "*", function (e) {
595    // Did the mouse really move?
596    if (lastScreen.x !== null && e.screenX !== lastScreen.x || e.screenY !== lastScreen.y) {
597      // It really moved. Enable zooming.
598      map.scrollWheelZoom.enable();
599      lastScreen = {
600        x: null,
601        y: null
602      };
603    }
604  });
605  (0, _jquery2["default"])(document).on("mousedown", ".leaflet", function (e) {
606    // Clicking always enables zooming.
607    map.scrollWheelZoom.enable();
608    lastScreen = {
609      x: null,
610      y: null
611    };
612  });
613}
614
615_htmlwidgets2["default"].widget({
616  name: "leaflet",
617  type: "output",
618  factory: function factory(el, width, height) {
619    var map = null;
620    return {
621      // we need to store our map in our returned object.
622      getMap: function getMap() {
623        return map;
624      },
625      renderValue: function renderValue(data) {
626        // Create an appropriate CRS Object if specified
627        if (data && data.options && data.options.crs) {
628          data.options.crs = (0, _crs_utils.getCRS)(data.options.crs);
629        } // As per https://github.com/rstudio/leaflet/pull/294#discussion_r79584810
630
631
632        if (map) {
633          map.remove();
634
635          map = function () {
636            return;
637          }(); // undefine map
638
639        }
640
641        if (data.options.mapFactory && typeof data.options.mapFactory === "function") {
642          map = data.options.mapFactory(el, data.options);
643        } else {
644          map = _leaflet2["default"].map(el, data.options);
645        }
646
647        preventUnintendedZoomOnScroll(map); // Store some state in the map object
648
649        map.leafletr = {
650          // Has the map ever rendered successfully?
651          hasRendered: false,
652          // Data to be rendered when resize is called with area != 0
653          pendingRenderData: null
654        }; // Check if the map is rendered statically (no output binding)
655
656        if (_htmlwidgets2["default"].shinyMode && /\bshiny-bound-output\b/.test(el.className)) {
657          map.id = el.id; // Store the map on the element so we can find it later by ID
658
659          (0, _jquery2["default"])(el).data("leaflet-map", map); // When the map is clicked, send the coordinates back to the app
660
661          map.on("click", function (e) {
662            _shiny2["default"].onInputChange(map.id + "_click", {
663              lat: e.latlng.lat,
664              lng: e.latlng.lng,
665              ".nonce": Math.random() // Force reactivity if lat/lng hasn't changed
666
667            });
668          });
669          var groupTimerId = null;
670          map.on("moveend", function (e) {
671            updateBounds(e.target);
672          }).on("layeradd layerremove", function (e) {
673            // If the layer that's coming or going is a group we created, tell
674            // the server.
675            if (map.layerManager.getGroupNameFromLayerGroup(e.layer)) {
676              // But to avoid chattiness, coalesce events
677              if (groupTimerId) {
678                clearTimeout(groupTimerId);
679                groupTimerId = null;
680              }
681
682              groupTimerId = setTimeout(function () {
683                groupTimerId = null;
684
685                _shiny2["default"].onInputChange(map.id + "_groups", map.layerManager.getVisibleGroups());
686              }, 100);
687            }
688          });
689        }
690
691        this.doRenderValue(data, map);
692      },
693      doRenderValue: function doRenderValue(data, map) {
694        // Leaflet does not behave well when you set up a bunch of layers when
695        // the map is not visible (width/height == 0). Popups get misaligned
696        // relative to their owning markers, and the fitBounds calculations
697        // are off. Therefore we wait until the map is actually showing to
698        // render the value (we rely on the resize() callback being invoked
699        // at the appropriate time).
700        if (el.offsetWidth === 0 || el.offsetHeight === 0) {
701          map.leafletr.pendingRenderData = data;
702          return;
703        }
704
705        map.leafletr.pendingRenderData = null; // Merge data options into defaults
706
707        var options = _jquery2["default"].extend({
708          zoomToLimits: "always"
709        }, data.options);
710
711        if (!map.layerManager) {
712          map.controls = new _controlStore2["default"](map);
713          map.layerManager = new _layerManager2["default"](map);
714        } else {
715          map.controls.clear();
716          map.layerManager.clear();
717        }
718
719        var explicitView = false;
720
721        if (data.setView) {
722          explicitView = true;
723          map.setView.apply(map, data.setView);
724        }
725
726        if (data.fitBounds) {
727          explicitView = true;
728          methods.fitBounds.apply(map, data.fitBounds);
729        }
730
731        if (data.flyTo) {
732          if (!explicitView && !map.leafletr.hasRendered) {
733            // must be done to give a initial starting point
734            map.fitWorld();
735          }
736
737          explicitView = true;
738          map.flyTo.apply(map, data.flyTo);
739        }
740
741        if (data.flyToBounds) {
742          if (!explicitView && !map.leafletr.hasRendered) {
743            // must be done to give a initial starting point
744            map.fitWorld();
745          }
746
747          explicitView = true;
748          methods.flyToBounds.apply(map, data.flyToBounds);
749        }
750
751        if (data.options.center) {
752          explicitView = true;
753        } // Returns true if the zoomToLimits option says that the map should be
754        // zoomed to map elements.
755
756
757        function needsZoom() {
758          return options.zoomToLimits === "always" || options.zoomToLimits === "first" && !map.leafletr.hasRendered;
759        }
760
761        if (!explicitView && needsZoom() && !map.getZoom()) {
762          if (data.limits && !_jquery2["default"].isEmptyObject(data.limits)) {
763            // Use the natural limits of what's being drawn on the map
764            // If the size of the bounding box is 0, leaflet gets all weird
765            var pad = 0.006;
766
767            if (data.limits.lat[0] === data.limits.lat[1]) {
768              data.limits.lat[0] = data.limits.lat[0] - pad;
769              data.limits.lat[1] = data.limits.lat[1] + pad;
770            }
771
772            if (data.limits.lng[0] === data.limits.lng[1]) {
773              data.limits.lng[0] = data.limits.lng[0] - pad;
774              data.limits.lng[1] = data.limits.lng[1] + pad;
775            }
776
777            map.fitBounds([[data.limits.lat[0], data.limits.lng[0]], [data.limits.lat[1], data.limits.lng[1]]]);
778          } else {
779            map.fitWorld();
780          }
781        }
782
783        for (var i = 0; data.calls && i < data.calls.length; i++) {
784          var call = data.calls[i];
785          if (methods[call.method]) methods[call.method].apply(map, call.args);else (0, _util.log)("Unknown method " + call.method);
786        }
787
788        map.leafletr.hasRendered = true;
789
790        if (_htmlwidgets2["default"].shinyMode) {
791          setTimeout(function () {
792            updateBounds(map);
793          }, 1);
794        }
795      },
796      resize: function resize(width, height) {
797        if (map) {
798          map.invalidateSize();
799
800          if (map.leafletr.pendingRenderData) {
801            this.doRenderValue(map.leafletr.pendingRenderData, map);
802          }
803        }
804      }
805    };
806  }
807});
808
809if (_htmlwidgets2["default"].shinyMode) {
810  _shiny2["default"].addCustomMessageHandler("leaflet-calls", function (data) {
811    var id = data.id;
812    var el = document.getElementById(id);
813    var map = el ? (0, _jquery2["default"])(el).data("leaflet-map") : null;
814
815    if (!map) {
816      (0, _util.log)("Couldn't find map with id " + id);
817      return;
818    } // If the map has not rendered, stash the proposed `leafletProxy()` calls
819    // in `pendingRenderData.calls` to be run on display via `doRenderValue()`.
820    // This is necessary if the map has not been rendered.
821    // If new pendingRenderData is set via a new `leaflet()`, the previous calls will be discarded.
822
823
824    if (!map.leafletr.hasRendered) {
825      map.leafletr.pendingRenderData.calls = map.leafletr.pendingRenderData.calls.concat(data.calls);
826      return;
827    }
828
829    for (var i = 0; i < data.calls.length; i++) {
830      var call = data.calls[i];
831      var args = call.args;
832
833      for (var _i = 0; _i < call.evals.length; _i++) {
834        window.HTMLWidgets.evaluateStringMember(args, call.evals[_i]);
835      }
836
837      if (call.dependencies) {
838        _shiny2["default"].renderDependencies(call.dependencies);
839      }
840
841      if (methods[call.method]) methods[call.method].apply(map, args);else (0, _util.log)("Unknown method " + call.method);
842    }
843  });
844}
845
846
847},{"./cluster-layer-store":1,"./control-store":2,"./crs_utils":3,"./dataframe":4,"./fixup-default-icon":5,"./fixup-default-tooltip":6,"./fixup-url-protocol":7,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./layer-manager"
847:14,"./methods":15,"./util":17}],14:[function(require,module,exports){
848(function (global){(function (){
849"use strict";
850
851Object.defineProperty(exports, "__esModule", {
852  value: true
853});
854exports["default"] = undefined;
855
856var _jquery = require("./global/jquery");
857
858var _jquery2 = _interopRequireDefault(_jquery);
859
860var _leaflet = require("./global/leaflet");
861
862var _leaflet2 = _interopRequireDefault(_leaflet);
863
864var _util = require("./util");
865
866function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
867
868function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
869
870function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
871
872function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
873
874var LayerManager = /*#__PURE__*/function () {
875  function LayerManager(map) {
876    _classCallCheck(this, LayerManager);
877
878    this._map = map; // BEGIN layer indices
879    // {<groupname>: {<stamp>: layer}}
880
881    this._byGroup = {}; // {<categoryName>: {<stamp>: layer}}
882
883    this._byCategory = {}; // {<categoryName_layerId>: layer}
884
885    this._byLayerId = {}; // {<stamp>: {
886    //             "group": <groupname>,
887    //             "layerId": <layerId>,
888    //             "category": <category>,
889    //             "container": <container>
890    //           }
891    // }
892
893    this._byStamp = {}; // {<crosstalkGroupName>: {<key>: [<stamp>, <stamp>, ...], ...}}
894
895    this._byCrosstalkGroup = {}; // END layer indices
896    // {<categoryName>: L.layerGroup}
897
898    this._categoryContainers = {}; // {<groupName>: L.layerGroup}
899
900    this._groupContainers = {};
901  }
902
903  _createClass(LayerManager, [{
904    key: "addLayer",
905    value: function addLayer(layer, category, layerId, group, ctGroup, ctKey) {
906      var _this = this;
907
908      // Was a group provided?
909      var hasId = typeof layerId === "string";
910      var grouped = typeof group === "string";
911      var stamp = _leaflet2["default"].Util.stamp(layer) + ""; // This will be the default layer group to add the layer to.
912      // We may overwrite this let before using it (i.e. if a group is assigned).
913      // This one liner creates the _categoryContainers[category] entry if it
914      // doesn't already exist.
915
916      var container = this._categoryContainers[category] = this._categoryContainers[category] || _leaflet2["default"].layerGroup().addTo(this._map);
917
918      var oldLayer = null;
919
920      if (hasId) {
921        // First, remove any layer with the same category and layerId
922        var prefixedLayerId = this._layerIdKey(category, layerId);
923
924        oldLayer = this._byLayerId[prefixedLayerId];
925
926        if (oldLayer) {
927          this._removeLayer(oldLayer);
928        } // Update layerId index
929
930
931        this._byLayerId[prefixedLayerId] = layer;
932      } // Update group index
933
934
935      if (grouped) {
936        this._byGroup[group] = this._byGroup[group] || {};
937        this._byGroup[group][stamp] = layer; // Since a group is assigned, don't add the layer to the category's layer
938        // group; instead, use the group's layer group.
939        // This one liner creates the _groupContainers[group] entry if it doesn't
940        // already exist.
941
942        container = this.getLayerGroup(group, true);
943      } // Update category index
944
945
946      this._byCategory[category] = this._byCategory[category] || {};
947      this._byCategory[category][stamp] = layer; // Update stamp index
948
949      var layerInfo = this._byStamp[stamp] = {
950        layer: layer,
951        group: group,
952        ctGroup: ctGroup,
953        ctKey: ctKey,
954        layerId: layerId,
955        category: category,
956        container: container,
957        hidden: false
958      }; // Update crosstalk group index
959
960      if (ctGroup) {
961        if (layer.setStyle) {
962          // Need to save this info so we know what to set opacity to later
963          layer.options.origOpacity = typeof layer.options.opacity !== "undefined" ? layer.options.opacity : 0.5;
964          layer.options.origFillOpacity = typeof layer.options.fillOpacity !== "undefined" ? layer.options.fillOpacity : 0.2;
965        }
966
967        var ctg = this._byCrosstalkGroup[ctGroup];
968
969        if (!ctg) {
970          ctg = this._byCrosstalkGroup[ctGroup] = {};
971          var crosstalk = global.crosstalk;
972
973          var handleFilter = function handleFilter(e) {
974            if (!e.value) {
975              var groupKeys = Object.keys(ctg);
976
977              for (var i = 0; i < groupKeys.length; i++) {
978                var key = groupKeys[i];
979                var _layerInfo = _this._byStamp[ctg[key]];
980
981                _this._setVisibility(_layerInfo, true);
982              }
983            } else {
984              var selectedKeys = {};
985
986              for (var _i = 0; _i < e.value.length; _i++) {
987                selectedKeys[e.value[_i]] = true;
988              }
989
990              var _groupKeys = Object.keys(ctg);
991
992              for (var _i2 = 0; _i2 < _groupKeys.length; _i2++) {
993                var _key = _groupKeys[_i2];
994                var _layerInfo2 = _this._byStamp[ctg[_key]];
995
996                _this._setVisibility(_layerInfo2, selectedKeys[_groupKeys[_i2]]);
997              }
998            }
999          };
1000
1001          var filterHandle = new crosstalk.FilterHandle(ctGroup);
1002          filterHandle.on("change", handleFilter);
1003
1004          var handleSelection = function handleSelection(e) {
1005            if (!e.value || !e.value.length) {
1006              var groupKeys = Object.keys(ctg);
1007
1008              for (var i = 0; i < groupKeys.length; i++) {
1009                var key = groupKeys[i];
1010                var _layerInfo3 = _this._byStamp[ctg[key]];
1011
1012                _this._setOpacity(_layerInfo3, 1.0);
1013              }
1014            } else {
1015              var selectedKeys = {};
1016
1017              for (var _i3 = 0; _i3 < e.value.length; _i3++) {
1018                selectedKeys[e.value[_i3]] = true;
1019              }
1020
1021              var _groupKeys2 = Object.keys(ctg);
1022
1023              for (var _i4 = 0; _i4 < _groupKeys2.length; _i4++) {
1024                var _key2 = _groupKeys2[_i4];
1025                var _layerInfo4 = _this._byStamp[ctg[_key2]];
1026
1027                _this._setOpacity(_layerInfo4, selectedKeys[_groupKeys2[_i4]] ? 1.0 : 0.2);
1028              }
1029            }
1030          };
1031
1032          var selHandle = new crosstalk.SelectionHandle(ctGroup);
1033          selHandle.on("change", handleSelection);
1034          setTimeout(function () {
1035            handleFilter({
1036              value: filterHandle.filteredKeys
1037            });
1038            handleSelection({
1039              value: selHandle.value
1040            });
1041          }, 100);
1042        }
1043
1044        if (!ctg[ctKey]) ctg[ctKey] = [];
1045        ctg[ctKey].push(stamp);
1046      } // Add to container
1047
1048
1049      if (!layerInfo.hidden) container.addLayer(layer);
1050      return oldLayer;
1051    }
1052  }, {
1053    key: "brush",
1054    value: function brush(bounds, extraInfo) {
1055      var _this2 = this;
1056
1057      /* eslint-disable no-console */
1058      // For each Crosstalk group...
1059      Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
1060        var ctg = _this2._byCrosstalkGroup[ctGroupName];
1061        var selection = []; // ...iterate over each Crosstalk key (each of which may have multiple
1062        // layers)...
1063
1064        Object.keys(ctg).forEach(function (ctKey) {
1065          // ...and for each layer...
1066          ctg[ctKey].forEach(function (stamp) {
1067            var layerInfo = _this2._byStamp[stamp]; // ...if it's something with a point...
1068
1069            if (layerInfo.layer.getLatLng) {
1070              // ... and it's inside the selection bounds...
1071              // TODO: Use pixel containment, not lat/lng containment
1072              if (bounds.contains(layerInfo.layer.getLatLng())) {
1073                // ...add the key to the selection.
1074                selection.push(ctKey);
1075              }
1076            }
1077          });
1078        });
1079        new global.crosstalk.SelectionHandle(ctGroupName).set(selection, extraInfo);
1080      });
1081    }
1082  }, {
1083    key: "unbrush",
1084    value: function unbrush(extraInfo) {
1085      Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
1086        new global.crosstalk.SelectionHandle(ctGroupName).clear(extraInfo);
1087      });
1088    }
1089  }, {
1090    key: "_setVisibility",
1091    value: function _setVisibility(layerInfo, visible) {
1092      if (layerInfo.hidden ^ visible) {
1093        return;
1094      } else if (visible) {
1095        layerInfo.container.addLayer(layerInfo.layer);
1096        layerInfo.hidden = false;
1097      } else {
1098        layerInfo.container.removeLayer(layerInfo.layer);
1099        layerInfo.hidden = true;
1100      }
1101    }
1102  }, {
1103    key: "_setOpacity",
1104    value: function _setOpacity(layerInfo, opacity) {
1105      if (layerInfo.layer.setOpacity) {
1106        layerInfo.layer.setOpacity(opacity);
1107      } else if (layerInfo.layer.setStyle) {
1108        layerInfo.layer.setStyle({
1109          opacity: opacity * layerInfo.layer.options.origOpacity,
1110          fillOpacity: opacity * layerInfo.layer.options.origFillOpacity
1111        });
1112      }
1113    }
1114  }, {
1115    key: "getLayer",
1116    value: function getLayer(category, layerId) {
1117      return this._byLayerId[this._layerIdKey(category, layerId)];
1118    }
1119  }, {
1120    key: "removeLayer",
1121    value: function removeLayer(category, layerIds) {
1122      var _this3 = this;
1123
1124      // Find layer info
1125      _jquery2["default"].each((0, _util.asArray)(layerIds), function (i, layerId) {
1126        var layer = _this3._byLayerId[_this3._layerIdKey(category, layerId)];
1127
1128        if (layer) {
1129          _this3._removeLayer(layer);
1130        }
1131      });
1132    }
1133  }, {
1134    key: "clearLayers",
1135    value: function clearLayers(category) {
1136      var _this4 = this;
1137
1138      // Find all layers in _byCategory[category]
1139      var catTable = this._byCategory[category];
1140
1141      if (!catTable) {
1142        return false;
1143      } // Remove all layers. Make copy of keys to avoid mutating the collection
1144      // behind the iterator you're accessing.
1145
1146
1147      var stamps = [];
1148
1149      _jquery2["default"].each(catTable, function (k, v) {
1150        stamps.push(k);
1151      });
1152
1153      _jquery2["default"].each(stamps, function (i, stamp) {
1154        _this4._removeLayer(stamp);
1155      });
1156    }
1157  }, {
1158    key: "getLayerGroup",
1159    value: function getLayerGroup(group, ensureExists) {
1160      var g = this._groupContainers[group];
1161
1162      if (ensureExists && !g) {
1163        this._byGroup[group] = this._byGroup[group] || {};
1164        g = this._groupContainers[group] = _leaflet2["default"].featureGroup();
1165        g.groupname = group;
1166        g.addTo(this._map);
1167      }
1168
1169      return g;
1170    }
1171  }, {
1172    key: "getGroupNameFromLayerGroup",
1173    value: function getGroupNameFromLayerGroup(layerGroup) {
1174      return layerGroup.groupname;
1175    }
1176  }, {
1177    key: "getVisibleGroups",
1178    value: function getVisibleGroups() {
1179      var _this5 = this;
1180
1181      var result = [];
1182
1183      _jquery2["default"].each(this._groupContainers, function (k, v) {
1184        if (_this5._map.hasLayer(v)) {
1185          result.push(k);
1186        }
1187      });
1188
1189      return result;
1190    }
1191  }, {
1192    key: "getAllGroupNames",
1193    value: function getAllGroupNames() {
1194      var result = [];
1195
1196      _jquery2["default"].each(this._groupContainers, function (k, v) {
1197        result.push(k);
1198      });
1199
1200      return result;
1201    }
1202  }, {
1203    key: "clearGroup",
1204    value: function clearGroup(group) {
1205      var _this6 = this;
1206
1207      // Find all layers in _byGroup[group]
1208      var groupTable = this._byGroup[group];
1209
1210      if (!groupTable) {
1211        return false;
1212      } // Remove all layers. Make copy of keys to avoid mutating the collection
1213      // behind the iterator you're accessing.
1214
1215
1216      var stamps = [];
1217
1218      _jquery2["default"].each(groupTable, function (k, v) {
1219        stamps.push(k);
1220      });
1221
1222      _jquery2["default"].each(stamps, function (i, stamp) {
1223        _this6._removeLayer(stamp);
1224      });
1225    }
1226  }, {
1227    key: "clear",
1228    value: function clear() {
1229      function clearLayerGroup(key, layerGroup) {
1230        layerGroup.clearLayers();
1231      } // Clear all indices and layerGroups
1232
1233
1234      this._byGroup = {};
1235      this._byCategory = {};
1236      this._byLayerId = {};
1237      this._byStamp = {};
1238      this._byCrosstalkGroup = {};
1239
1240      _jquery2["default"].each(this._categoryContainers, clearLayerGroup);
1241
1242      this._categoryContainers = {};
1243
1244      _jquery2["default"].each(this._groupContainers, clearLayerGroup);
1245
1246      this._groupContainers = {};
1247    }
1248  }, {
1249    key: "_removeLayer",
1250    value: function _removeLayer(layer) {
1251      var stamp;
1252
1253      if (typeof layer === "string") {
1254        stamp = layer;
1255      } else {
1256        stamp = _leaflet2["default"].Util.stamp(layer);
1257      }
1258
1259      var layerInfo = this._byStamp[stamp];
1260
1261      if (!layerInfo) {
1262        return false;
1263      }
1264
1265      layerInfo.container.removeLayer(stamp);
1266
1267      if (typeof layerInfo.group === "string") {
1268        delete this._byGroup[layerInfo.group][stamp];
1269      }
1270
1271      if (typeof layerInfo.layerId === "string") {
1272        delete this._byLayerId[this._layerIdKey(layerInfo.category, layerInfo.layerId)];
1273      }
1274
1275      delete this._byCategory[layerInfo.category][stamp];
1276      delete this._byStamp[stamp];
1277
1278      if (layerInfo.ctGroup) {
1279        var ctGroup = this._byCrosstalkGroup[layerInfo.ctGroup];
1280        var layersForKey = ctGroup[layerInfo.ctKey];
1281        var idx = layersForKey ? layersForKey.indexOf(stamp) : -1;
1282
1283        if (idx >= 0) {
1284          if (layersForKey.length === 1) {
1285            delete ctGroup[layerInfo.ctKey];
1286          } else {
1287            layersForKey.splice(idx, 1);
1288          }
1289        }
1290      }
1291    }
1292  }, {
1293    key: "_layerIdKey",
1294    value: function _layerIdKey(category, layerId) {
1295      return category + "\n" + layerId;
1296    }
1297  }]);
1298
1299  return LayerManager;
1300}();
1301
1302exports["default"] = LayerManager;
1303
1304
1305}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1306},{"./global/jquery":9,"./global/leaflet":10,"./util":17}],15:[function(require,module,exports){
1307(function (global){(function (){
1308"use strict";
1309
1310Object.defineProperty(exports, "__esModule", {
1311  value: true
1312});
1313
1314var _jquery = require("./global/jquery");
1315
1316var _jquery2 = _interopRequireDefault(_jquery);
1317
1318var _leaflet = require("./global/leaflet");
1319
1320var _leaflet2 = _interopRequireDefault(_leaflet);
1321
1322var _shiny = require("./global/shiny");
1323
1324var _shiny2 = _interopRequireDefault(_shiny);
1325
1326var _htmlwidgets = require("./global/htmlwidgets");
1327
1328var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
1329
1330var _util = require("./util");
1331
1332var _crs_utils = require("./crs_utils");
1333
1334var _dataframe = require("./dataframe");
1335
1336var _dataframe2 = _interopRequireDefault(_dataframe);
1337
1338var _clusterLayerStore = require("./cluster-layer-store");
1339
1340var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
1341
1342var _mipmapper = require("./mipmapper");
1343
1344var _mipmapper2 = _interopRequireDefault(_mipmapper);
1345
1346function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
1347
1348var methods = {};
1349exports["default"] = methods;
1350
1351function mouseHandler(mapId, layerId, group, eventName, extraInfo) {
1352  return function (e) {
1353    if (!_htmlwidgets2["default"].shinyMode) return;
1354    var latLng = e.target.getLatLng ? e.target.getLatLng() : e.latlng;
1355
1356    if (latLng) {
1357      // retrieve only lat, lon values to remove prototype
1358      //   and extra parameters added by 3rd party modules
1359      // these objects are for json serialization, not javascript
1360      var latLngVal = _leaflet2["default"].latLng(latLng); // make sure it has consistent shape
1361
1362
1363      latLng = {
1364        lat: latLngVal.lat,
1365        lng: latLngVal.lng
1366      };
1367    }
1368
1369    var eventInfo = _jquery2["default"].extend({
1370      id: layerId,
1371      ".nonce": Math.random() // force reactivity
1372
1373    }, group !== null ? {
1374      group: group
1375    } : null, latLng, extraInfo);
1376
1377    _shiny2["default"].onInputChange(mapId + "_" + eventName, eventInfo);
1378  };
1379}
1380
1381methods.mouseHandler = mouseHandler;
1382
1383methods.clearGroup = function (group) {
1384  var _this = this;
1385
1386  _jquery2["default"].each((0, _util.asArray)(group), function (i, v) {
1387    _this.layerManager.clearGroup(v);
1388  });
1389};
1390
1391methods.setView = function (center, zoom, options) {
1392  this.setView(center, zoom, options);
1393};
1394
1395methods.fitBounds = function (lat1, lng1, lat2, lng2, options) {
1396  this.fitBounds([[lat1, lng1], [lat2, lng2]], options);
1397};
1398
1399methods.flyTo = function (center, zoom, options) {
1400  this.flyTo(center, zoom, options);
1401};
1402
1403methods.flyToBounds = function (lat1, lng1, lat2, lng2, options) {
1404  this.flyToBounds([[lat1, lng1], [lat2, lng2]], options);
1405};
1406
1407methods.setMaxBounds = function (lat1, lng1, lat2, lng2) {
1408  this.setMaxBounds([[lat1, lng1], [lat2, lng2]]);
1409};
1410
1411methods.addPopups = function (lat, lng, popup, layerId, group, options) {
1412  var _this2 = this;
1413
1414  var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("popup", popup).col("layerId", layerId).col("group", group).cbind(options);
1415
1416  var _loop = function _loop(i) {
1417    if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
1418      (function () {
1419        var popup = _leaflet2["default"].popup(df.get(i)).setLatLng([df.get(i, "lat"), df.get(i, "lng")]).setContent(df.get(i, "popup"));
1420
1421        var thisId = df.get(i, "layerId");
1422        var thisGroup = df.get(i, "group");
1423        this.layerManager.addLayer(popup, "popup", thisId, thisGroup);
1424      }).call(_this2);
1425    }
1426  };
1427
1428  for (var i = 0; i < df.nrow(); i++) {
1429    _loop(i);
1430  }
1431};
1432
1433methods.removePopup = function (layerId) {
1434  this.layerManager.removeLayer("popup", layerId);
1435};
1436
1437methods.clearPopups = function () {
1438  this.layerManager.clearLayers("popup");
1439};
1440
1441methods.addTiles = function (urlTemplate, layerId, group, options) {
1442  this.layerManager.addLayer(_leaflet2["default"].tileLayer(urlTemplate, options), "tile", layerId, group);
1443};
1444
1445methods.removeTiles = function (layerId) {
1446  this.layerManager.removeLayer("tile", layerId);
1447};
1448
1449methods.clearTiles = function () {
1450  this.layerManager.clearLayers("tile");
1451};
1452
1453methods.addWMSTiles = function (baseUrl, layerId, group, options) {
1454  if (options && options.crs) {
1455    options.crs = (0, _crs_utils.getCRS)(options.crs);
1456  }
1457
1458  this.layerManager.addLayer(_leaflet2["default"].tileLayer.wms(baseUrl, options), "tile", layerId, group);
1459}; // Given:
1460//   {data: ["a", "b", "c"], index: [0, 1, 0, 2]}
1461// returns:
1462//   ["a", "b", "a", "c"]
1463
1464
1465function unpackStrings(iconset) {
1466  if (!iconset) {
1467    return iconset;
1468  }
1469
1470  if (typeof iconset.index === "undefined") {
1471    return iconset;
1472  }
1473
1474  iconset.data = (0, _util.asArray)(iconset.data);
1475  iconset.index = (0, _util.asArray)(iconset.index);
1476  return _jquery2["default"].map(iconset.index, function (e, i) {
1477    return iconset.data[e];
1478  });
1479}
1480
1481function addMarkers(map, df, group, clusterOptions, clusterId, markerFunc) {
1482  (function () {
1483    var _this3 = this;
1484
1485    var clusterGroup = this.layerManager.getLayer("cluster", clusterId),
1486        cluster = clusterOptions !== null;
1487
1488    if (cluster && !clusterGroup) {
1489      clusterGroup = _leaflet2["default"].markerClusterGroup.layerSupport(clusterOptions);
1490
1491      if (clusterOptions.freezeAtZoom) {
1492        var freezeAtZoom = clusterOptions.freezeAtZoom;
1493        delete clusterOptions.freezeAtZoom;
1494        clusterGroup.freezeAtZoom(freezeAtZoom);
1495      }
1496
1497      clusterGroup.clusterLayerStore = new _clusterLayerStore2["default"](clusterGroup);
1498    }
1499
1500    var extraInfo = cluster ? {
1501      clusterId: clusterId
1502    } : {};
1503
1504    var _loop2 = function _loop2(i) {
1505      if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
1506        (function () {
1507          var marker = markerFunc(df, i);
1508          var thisId = df.get(i, "layerId");
1509          var thisGroup = cluster ? null : df.get(i, "group");
1510
1511          if (cluster) {
1512            clusterGroup.clusterLayerStore.add(marker, thisId);
1513          } else {
1514            this.layerManager.addLayer(marker, "marker", thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
1515          }
1516
1517          var popup = df.get(i, "popup");
1518          var popupOptions = df.get(i, "popupOptions");
1519
1520          if (popup !== null) {
1521            if (popupOptions !== null) {
1522              marker.bindPopup(popup, popupOptions);
1523            } else {
1524              marker.bindPopup(popup);
1525            }
1526          }
1527
1528          var label = df.get(i, "label");
1529          var labelOptions = df.get(i, "labelOptions");
1530
1531          if (label !== null) {
1532            if (labelOptions !== null) {
1533              if (labelOptions.permanent) {
1534                marker.bindTooltip(label, labelOptions).openTooltip();
1535              } else {
1536                marker.bindTooltip(label, labelOptions);
1537              }
1538            } else {
1539              marker.bindTooltip(label);
1540            }
1541          }
1542
1543          marker.on("click", mouseHandler(this.id, thisId, thisGroup, "marker_click", extraInfo), this);
1544          marker.on("mouseover", mouseHandler(this.id, thisId, thisGroup, "marker_mouseover", extraInfo), this);
1545          marker.on("mouseout", mouseHandler(this.id, thisId, thisGroup, "marker_mouseout", extraInfo), this);
1546          marker.on("dragend", mouseHandler(this.id, thisId, thisGroup, "marker_dragend", extraInfo), this);
1547        }).call(_this3);
1548      }
1549    };
1550
1551    for (var i = 0; i < df.nrow(); i++) {
1552      _loop2(i);
1553    }
1554
1555    if (cluster) {
1556      this.layerManager.addLayer(clusterGroup, "cluster", clusterId, group);
1557    }
1558  }).call(map);
1559}
1560
1561methods.addGenericMarkers = addMarkers;
1562
1563methods.addMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
1564  var icondf;
1565  var getIcon;
1566
1567  if (icon) {
1568    // Unpack icons
1569    icon.iconUrl = unpackStrings(icon.iconUrl);
1570    icon.iconRetinaUrl = unpackStrings(icon.iconRetinaUrl);
1571    icon.shadowUrl = unpackStrings(icon.shadowUrl);
1572    icon.shadowRetinaUrl = unpackStrings(icon.shadowRetinaUrl); // This cbinds the icon URLs and any other icon options; they're all
1573    // present on the icon object.
1574
1575    icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
1576
1577    getIcon = function getIcon(i) {
1578      var opts = icondf.get(i);
1579
1580      if (!opts.iconUrl) {
1581        return new _leaflet2["default"].Icon.Default();
1582      } // Composite options (like points or sizes) are passed from R with each
1583      // individual component as its own option. We need to combine them now
1584      // into their composite form.
1585
1586
1587      if (opts.iconWidth) {
1588        opts.iconSize = [opts.iconWidth, opts.iconHeight];
1589      }
1590
1591      if (opts.shadowWidth) {
1592        opts.shadowSize = [opts.shadowWidth, opts.shadowHeight];
1593      }
1594
1595      if (opts.iconAnchorX) {
1596        opts.iconAnchor = [opts.iconAnchorX, opts.iconAnchorY];
1597      }
1598
1599      if (opts.shadowAnchorX) {
1600        opts.shadowAnchor = [opts.shadowAnchorX, opts.shadowAnchorY];
1601      }
1602
1603      if (opts.popupAnchorX) {
1604        opts.popupAnchor = [opts.popupAnchorX, opts.popupAnchorY];
1605      }
1606
1607      return new _leaflet2["default"].Icon(opts);
1608    };
1609  }
1610
1611  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1612    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {});
1613    if (icon) icondf.effectiveLength = df.nrow();
1614    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1615      var options = df.get(i);
1616      if (icon) options.icon = getIcon(i);
1617      return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
1618    });
1619  }
1620};
1621
1622methods.addAwesomeMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
1623  var icondf;
1624  var getIcon;
1625
1626  if (icon) {
1627    // This cbinds the icon URLs and any other icon options; they're all
1628    // present on the icon object.
1629    icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
1630
1631    getIcon = function getIcon(i) {
1632      var opts = icondf.get(i);
1633
1634      if (!opts) {
1635        return new _leaflet2["default"].AwesomeMarkers.icon();
1636      }
1637
1638      if (opts.squareMarker) {
1639        opts.className = "awesome-marker awesome-marker-square";
1640      }
1641
1642      return new _leaflet2["default"].AwesomeMarkers.icon(opts);
1643    };
1644  }
1645
1646  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1647    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {});
1648    if (icon) icondf.effectiveLength = df.nrow();
1649    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1650      var options = df.get(i);
1651      if (icon) options.icon = getIcon(i);
1652      return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
1653    });
1654  }
1655};
1656
1657function addLayers(map, category, df, layerFunc) {
1658  var _loop3 = function _loop3(i) {
1659    (function () {
1660      var layer = layerFunc(df, i);
1661
1662      if (!_jquery2["default"].isEmptyObject(layer)) {
1663        var thisId = df.get(i, "layerId");
1664        var thisGroup = df.get(i, "group");
1665        this.layerManager.addLayer(layer, category, thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
1666
1667        if (layer.bindPopup) {
1668          var popup = df.get(i, "popup");
1669          var popupOptions = df.get(i, "popupOptions");
1670
1671          if (popup !== null) {
1672            if (popupOptions !== null) {
1673              layer.bindPopup(popup, popupOptions);
1674            } else {
1675              layer.bindPopup(popup);
1676            }
1677          }
1678        }
1679
1680        if (layer.bindTooltip) {
1681          var label = df.get(i, "label");
1682          var labelOptions = df.get(i, "labelOptions");
1683
1684          if (label !== null) {
1685            if (labelOptions !== null) {
1686              layer.bindTooltip(label, labelOptions);
1687            } else {
1688              layer.bindTooltip(label);
1689            }
1690          }
1691        }
1692
1693        layer.on("click", mouseHandler(this.id, thisId, thisGroup, category + "_click"), this);
1694        layer.on("mouseover", mouseHandler(this.id, thisId, thisGroup, category + "_mouseover"), this);
1695        layer.on("mouseout", mouseHandler(this.id, thisId, thisGroup, category + "_mouseout"), this);
1696        var highlightStyle = df.get(i, "highlightOptions");
1697
1698        if (!_jquery2["default"].isEmptyObject(highlightStyle)) {
1699          var defaultStyle = {};
1700
1701          _jquery2["default"].each(highlightStyle, function (k, v) {
1702            if (k != "bringToFront" && k != "sendToBack") {
1703              if (df.get(i, k)) {
1704                defaultStyle[k] = df.get(i, k);
1705              }
1706            }
1707          });
1708
1709          layer.on("mouseover", function (e) {
1710            this.setStyle(highlightStyle);
1711
1712            if (highlightStyle.bringToFront) {
1713              this.bringToFront();
1714            }
1715          });
1716          layer.on("mouseout", function (e) {
1717            this.setStyle(defaultStyle);
1718
1719            if (highlightStyle.sendToBack) {
1720              this.bringToBack();
1721            }
1722          });
1723        }
1724      }
1725    }).call(map);
1726  };
1727
1728  for (var i = 0; i < df.nrow(); i++) {
1729    _loop3(i);
1730  }
1731}
1732
1733methods.addGenericLayers = addLayers;
1734
1735methods.addCircles = function (lat, lng, radius, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions, crosstalkOptions) {
1736  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1737    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options).cbind(crosstalkOptions || {});
1738    addLayers(this, "shape", df, function (df, i) {
1739      if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng")) && _jquery2["default"].isNumeric(df.get(i, "radius"))) {
1740        return _leaflet2["default"].circle([df.get(i, "lat"), df.get(i, "lng")], df.get(i, "radius"), df.get(i));
1741      } else {
1742        return null;
1743      }
1744    });
1745  }
1746};
1747
1748methods.addCircleMarkers = function (lat, lng, radius, layerId, group, options, clusterOptions, clusterId, popup, popupOptions, label, labelOptions, crosstalkOptions) {
1749  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1750    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(crosstalkOptions || {}).cbind(options);
1751    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1752      return _leaflet2["default"].circleMarker([df.get(i, "lat"), df.get(i, "lng")], df.get(i));
1753    });
1754  }
1755};
1756/*
1757 * @param lat Array of arrays of latitude coordinates for polylines
1758 * @param lng Array of arrays of longitude coordinates for polylines
1759 */
1760
1761
1762methods.addPolylines = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1763  if (polygons.length > 0) {
1764    var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1765    addLayers(this, "shape", df, function (df, i) {
1766      var shapes = df.get(i, "shapes");
1767      shapes = shapes.map(function (shape) {
1768        return _htmlwidgets2["default"].dataframeToD3(shape[0]);
1769      });
1770
1771      if (shapes.length > 1) {
1772        return _leaflet2["default"].polyline(shapes, df.get(i));
1773      } else {
1774        return _leaflet2["default"].polyline(shapes[0], df.get(i));
1775      }
1776    });
1777  }
1778};
1779
1780methods.removeMarker = function (layerId) {
1781  this.layerManager.removeLayer("marker", layerId);
1782};
1783
1784methods.clearMarkers = function () {
1785  this.layerManager.clearLayers("marker");
1786};
1787
1788methods.removeMarkerCluster = function (layerId) {
1789  this.layerManager.removeLayer("cluster", layerId);
1790};
1791
1792methods.removeMarkerFromCluster = function (layerId, clusterId) {
1793  var cluster = this.layerManager.getLayer("cluster", clusterId);
1794  if (!cluster) return;
1795  cluster.clusterLayerStore.remove(layerId);
1796};
1797
1798methods.clearMarkerClusters = function () {
1799  this.layerManager.clearLayers("cluster");
1800};
1801
1802methods.removeShape = function (layerId) {
1803  this.layerManager.removeLayer("shape", layerId);
1804};
1805
1806methods.clearShapes = function () {
1807  this.layerManager.clearLayers("shape");
1808};
1809
1810methods.addRectangles = function (lat1, lng1, lat2, lng2, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1811  var df = new _dataframe2["default"]().col("lat1", lat1).col("lng1", lng1).col("lat2", lat2).col("lng2", lng2).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1812  addLayers(this, "shape", df, function (df, i) {
1813    if (_jquery2["default"].isNumeric(df.get(i, "lat1")) && _jquery2["default"].isNumeric(df.get(i, "lng1")) && _jquery2["default"].isNumeric(df.get(i, "lat2")) && _jquery2["default"].isNumeric(df.get(i, "lng2"))) {
1814      return _leaflet2["default"].rectangle([[df.get(i, "lat1"), df.get(i, "lng1")], [df.get(i, "lat2"), df.get(i, "lng2")]], df.get(i));
1815    } else {
1816      return null;
1817    }
1818  });
1819};
1820/*
1821 * @param lat Array of arrays of latitude coordinates for polygons
1822 * @param lng Array of arrays of longitude coordinates for polygons
1823 */
1824
1825
1826methods.addPolygons = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1827  if (polygons.length > 0) {
1828    var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1829    addLayers(this, "shape", df, function (df, i) {
1830      // This code used to use L.multiPolygon, but that caused
1831      // double-click on a multipolygon to fail to zoom in on the
1832      // map. Surprisingly, putting all the rings in a single
1833      // polygon seems to still work; complicated multipolygons
1834      // are still rendered correctly.
1835      var shapes = df.get(i, "shapes").map(function (polygon) {
1836        return polygon.map(_htmlwidgets2["default"].dataframeToD3);
1837      }).reduce(function (acc, val) {
1838        return acc.concat(val);
1839      }, []);
1840      return _leaflet2["default"].polygon(shapes, df.get(i));
1841    });
1842  }
1843};
1844
1845methods.addGeoJSON = function (data, layerId, group, style) {
1846  // This time, self is actually needed because the callbacks below need
1847  // to access both the inner and outer senses of "this"
1848  var self = this;
1849
1850  if (typeof data === "string") {
1851    data = JSON.parse(data);
1852  }
1853
1854  var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
1855
1856  var gjlayer = _leaflet2["default"].geoJson(data, {
1857    style: function style(feature) {
1858      if (feature.style || feature.properties.style) {
1859        return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
1860      } else {
1861        return globalStyle;
1862      }
1863    },
1864    onEachFeature: function onEachFeature(feature, layer) {
1865      var extraInfo = {
1866        featureId: feature.id,
1867        properties: feature.properties
1868      };
1869      var popup = feature.properties ? feature.properties.popup : null;
1870      if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
1871      layer.on("click", mouseHandler(self.id, layerId, group, "geojson_click", extraInfo), this);
1872      layer.on("mouseover", mouseHandler(self.id, layerId, group, "geojson_mouseover", extraInfo), this);
1873      layer.on("mouseout", mouseHandler(self.id, layerId, group, "geojson_mouseout", extraInfo), this);
1874    }
1875  });
1876
1877  this.layerManager.addLayer(gjlayer, "geojson", layerId, group);
1878};
1879
1880methods.removeGeoJSON = function (layerId) {
1881  this.layerManager.removeLayer("geojson", layerId);
1882};
1883
1884methods.clearGeoJSON = function () {
1885  this.layerManager.clearLayers("geojson");
1886};
1887
1888methods.addTopoJSON = function (data, layerId, group, style) {
1889  // This time, self is actually needed because the callbacks below need
1890  // to access both the inner and outer senses of "this"
1891  var self = this;
1892
1893  if (typeof data === "string") {
1894    data = JSON.parse(data);
1895  }
1896
1897  var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
1898
1899  var gjlayer = _leaflet2["default"].geoJson(null, {
1900    style: function style(feature) {
1901      if (feature.style || feature.properties.style) {
1902        return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
1903      } else {
1904        return globalStyle;
1905      }
1906    },
1907    onEachFeature: function onEachFeature(feature, layer) {
1908      var extraInfo = {
1909        featureId: feature.id,
1910        properties: feature.properties
1911      };
1912      var popup = feature.properties.popup;
1913      if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
1914      layer.on("click", mouseHandler(self.id, layerId, group, "topojson_click", extraInfo), this);
1915      layer.on("mouseover", mouseHandler(self.id, layerId, group, "topojson_mouseover", extraInfo), this);
1916      layer.on("mouseout", mouseHandler(self.id, layerId, group, "topojson_mouseout", extraInfo), this);
1917    }
1918  });
1919
1920  global.omnivore.topojson.parse(data, null, gjlayer);
1921  this.layerManager.addLayer(gjlayer, "topojson", layerId, group);
1922};
1923
1924methods.removeTopoJSON = function (layerId) {
1925  this.layerManager.removeLayer("topojson", layerId);
1926};
1927
1928methods.clearTopoJSON = function () {
1929  this.layerManager.clearLayers("topojson");
1930};
1931
1932methods.addControl = function (html, position, layerId, classes) {
1933  function onAdd(map) {
1934    var div = _leaflet2["default"].DomUtil.create("div", classes);
1935
1936    if (typeof layerId !== "undefined" && layerId !== null) {
1937      div.setAttribute("id", layerId);
1938    }
1939
1940    this._div = div; // It's possible for window.Shiny to be true but Shiny.initializeInputs to
1941    // not be, when a static leaflet widget is included as part of the shiny
1942    // UI directly (not through leafletOutput or uiOutput). In this case we
1943    // don't do the normal Shiny stuff as that will all happen when Shiny
1944    // itself loads and binds the entire doc.
1945
1946    if (window.Shiny && _shiny2["default"].initializeInputs) {
1947      _shiny2["default"].renderHtml(html, this._div);
1948
1949      _shiny2["default"].initializeInputs(this._div);
1950
1951      _shiny2["default"].bindAll(this._div);
1952    } else {
1953      this._div.innerHTML = html;
1954    }
1955
1956    return this._div;
1957  }
1958
1959  function onRemove(map) {
1960    if (window.Shiny && _shiny2["default"].unbindAll) {
1961      _shiny2["default"].unbindAll(this._div);
1962    }
1963  }
1964
1965  var Control = _leaflet2["default"].Control.extend({
1966    options: {
1967      position: position
1968    },
1969    onAdd: onAdd,
1970    onRemove: onRemove
1971  });
1972
1973  this.controls.add(new Control(), layerId, html);
1974};
1975
1976methods.addCustomControl = function (control, layerId) {
1977  this.controls.add(control, layerId);
1978};
1979
1980methods.removeControl = function (layerId) {
1981  this.controls.remove(layerId);
1982};
1983
1984methods.getControl = function (layerId) {
1985  this.controls.get(layerId);
1986};
1987
1988methods.clearControls = function () {
1989  this.controls.clear();
1990};
1991
1992methods.addLegend = function (options) {
1993  var legend = _leaflet2["default"].control({
1994    position: options.position
1995  });
1996
1997  var gradSpan;
1998
1999  legend.onAdd = function (map) {
2000    var div = _leaflet2["default"].DomUtil.create("div", options.className),
2001        colors = options.colors,
2002        labels = options.labels,
2003        legendHTML = "";
2004
2005    if (options.type === "numeric") {
2006      // # Formatting constants.
2007      var singleBinHeight = 20; // The distance between tick marks, in px
2008
2009      var vMargin = 8; // If 1st tick mark starts at top of gradient, how
2010      // many extra px are needed for the top half of the
2011      // 1st label? (ditto for last tick mark/label)
2012
2013      var tickWidth = 4; // How wide should tick marks be, in px?
2014
2015      var labelPadding = 6; // How much distance to reserve for tick mark?
2016      // (Must be >= tickWidth)
2017      // # Derived formatting parameters.
2018      // What's the height of a single bin, in percentage (of gradient height)?
2019      // It might not just be 1/(n-1), if the gradient extends past the tick
2020      // marks (which can be the case for pretty cut points).
2021
2022      var singleBinPct = (options.extra.p_n - options.extra.p_1) / (labels.length - 1); // Each bin is `singleBinHeight` high. How tall is the gradient?
2023
2024      var totalHeight = 1 / singleBinPct * singleBinHeight + 1; // How far should the first tick be shifted down, relative to the top
2025      // of the gradient?
2026
2027      var tickOffset = singleBinHeight / singleBinPct * options.extra.p_1;
2028      gradSpan = (0, _jquery2["default"])("<span/>").css({
2029        "background": "linear-gradient(" + colors + ")",
2030        "opacity": options.opacity,
2031        "height": totalHeight + "px",
2032        "width": "18px",
2033        "display": "block",
2034        "margin-top": vMargin + "px"
2035      });
2036      var leftDiv = (0, _jquery2["default"])("<div/>").css("float", "left"),
2037          rightDiv = (0, _jquery2["default"])("<div/>").css("float", "left");
2038      leftDiv.append(gradSpan);
2039      (0, _jquery2["default"])(div).append(leftDiv).append(rightDiv).append((0, _jquery2["default"])("<br>")); // Have to attach the div to the body at this early point, so that the
2040      // svg text getComputedTextLength() actually works, below.
2041
2042      document.body.appendChild(div);
2043      var ns = "http://www.w3.org/2000/svg";
2044      var svg = document.createElementNS(ns, "svg");
2045      rightDiv.append(svg);
2046      var g = document.createElementNS(ns, "g");
2047      (0, _jquery2["default"])(g).attr("transform", "translate(0, " + vMargin + ")");
2048      svg.appendChild(g); // max label width needed to set width of svg, and right-justify text
2049
2050      var maxLblWidth = 0; // Create tick marks and labels
2051
2052      _jquery2["default"].each(labels, function (i, label) {
2053        var y = tickOffset + i * singleBinHeight + 0.5;
2054        var thisLabel = document.createElementNS(ns, "text");
2055        (0, _jquery2["default"])(thisLabel).text(labels[i]).attr("y", y).attr("dx", labelPadding).attr("dy", "0.5ex");
2056        g.appendChild(thisLabel);
2057        maxLblWidth = Math.max(maxLblWidth, thisLabel.getComputedTextLength());
2058        var thisTick = document.createElementNS(ns, "line");
2059        (0, _jquery2["default"])(thisTick).attr("x1", 0).attr("x2", tickWidth).attr("y1", y).attr("y2", y).attr("stroke-width", 1);
2060        g.appendChild(thisTick);
2061      }); // Now that we know the max label width, we can right-justify
2062
2063
2064      (0, _jquery2["default"])(svg).find("text").attr("dx", labelPadding + maxLblWidth).attr("text-anchor", "end"); // Final size for <svg>
2065
2066      (0, _jquery2["default"])(svg).css({
2067        width: maxLblWidth + labelPadding + "px",
2068        height: totalHeight + vMargin * 2 + "px"
2069      });
2070
2071      if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
2072        (0, _jquery2["default"])(div).append("<div><i style=\"" + "background:" + options.na_color + ";opacity:" + options.opacity + ";margin-right:" + labelPadding + "px" + ";\"></i>" + options.na_label + "</div>");
2073      }
2074    } else {
2075      if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
2076        colors.push(options.na_color);
2077        labels.push(options.na_label);
2078      }
2079
2080      for (var i = 0; i < colors.length; i++) {
2081        legendHTML += "<i style=\"background:" + colors[i] + ";opacity:" + options.opacity + "\"></i> " + labels[i] + "<br>";
2082      }
2083
2084      div.innerHTML = legendHTML;
2085    }
2086
2087    if (options.title) (0, _jquery2["default"])(div).prepend("<div style=\"margin-bottom:3px\"><strong>" + options.title + "</strong></div>");
2088    return div;
2089  };
2090
2091  if (options.group) {
2092    // Auto generate a layerID if not provided
2093    if (!options.layerId) {
2094      options.layerId = _leaflet2["default"].Util.stamp(legend);
2095    }
2096
2097    var map = this;
2098    map.on("overlayadd", function (e) {
2099      if (e.name === options.group) {
2100        map.controls.add(legend, options.layerId);
2101      }
2102    });
2103    map.on("overlayremove", function (e) {
2104      if (e.name === options.group) {
2105        map.controls.remove(options.layerId);
2106      }
2107    });
2108    map.on("groupadd", function (e) {
2109      if (e.name === options.group) {
2110        map.controls.add(legend, options.layerId);
2111      }
2112    });
2113    map.on("groupremove", function (e) {
2114      if (e.name === options.group) {
2115        map.controls.remove(options.layerId);
2116      }
2117    });
2118  }
2119
2120  this.controls.add(legend, options.layerId);
2121};
2122
2123methods.addLayersControl = function (baseGroups, overlayGroups, options) {
2124  var _this4 = this;
2125
2126  // Only allow one layers control at a time
2127  methods.removeLayersControl.call(this);
2128  var firstLayer = true;
2129  var base = {};
2130
2131  _jquery2["default"].each((0, _util.asArray)(baseGroups), function (i, g) {
2132    var layer = _this4.layerManager.getLayerGroup(g, true);
2133
2134    if (layer) {
2135      base[g] = layer; // Check if >1 base layers are visible; if so, hide all but the first one
2136
2137      if (_this4.hasLayer(layer)) {
2138        if (firstLayer) {
2139          firstLayer = false;
2140        } else {
2141          _this4.removeLayer(layer);
2142        }
2143      }
2144    }
2145  });
2146
2147  var overlay = {};
2148
2149  _jquery2["default"].each((0, _util.asArray)(overlayGroups), function (i, g) {
2150    var layer = _this4.layerManager.getLayerGroup(g, true);
2151
2152    if (layer) {
2153      overlay[g] = layer;
2154    }
2155  });
2156
2157  this.currentLayersControl = _leaflet2["default"].control.layers(base, overlay, options);
2158  this.addControl(this.currentLayersControl);
2159};
2160
2161methods.removeLayersControl = function () {
2162  if (this.currentLayersControl) {
2163    this.removeControl(this.currentLayersControl);
2164    this.currentLayersControl = null;
2165  }
2166};
2167
2168methods.addScaleBar = function (options) {
2169  // Only allow one scale bar at a time
2170  methods.removeScaleBar.call(this);
2171
2172  var scaleBar = _leaflet2["default"].control.scale(options).addTo(this);
2173
2174  this.currentScaleBar = scaleBar;
2175};
2176
2177methods.removeScaleBar = function () {
2178  if (this.currentScaleBar) {
2179    this.currentScaleBar.remove();
2180    this.currentScaleBar = null;
2181  }
2182};
2183
2184methods.hideGroup = function (group) {
2185  var _this5 = this;
2186
2187  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2188    var layer = _this5.layerManager.getLayerGroup(g, true);
2189
2190    if (layer) {
2191      _this5.removeLayer(layer);
2192    }
2193  });
2194};
2195
2196methods.showGroup = function (group) {
2197  var _this6 = this;
2198
2199  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2200    var layer = _this6.layerManager.getLayerGroup(g, true);
2201
2202    if (layer) {
2203      _this6.addLayer(layer);
2204    }
2205  });
2206};
2207
2208function setupShowHideGroupsOnZoom(map) {
2209  if (map.leafletr._hasInitializedShowHideGroups) {
2210    return;
2211  }
2212
2213  map.leafletr._hasInitializedShowHideGroups = true;
2214
2215  function setVisibility(layer, visible, group) {
2216    if (visible !== map.hasLayer(layer)) {
2217      if (visible) {
2218        map.addLayer(layer);
2219        map.fire("groupadd", {
2220          "name": group,
2221          "layer": layer
2222        });
2223      } else {
2224        map.removeLayer(layer);
2225        map.fire("groupremove", {
2226          "name": group,
2227          "layer": layer
2228        });
2229      }
2230    }
2231  }
2232
2233  function showHideGroupsOnZoom() {
2234    if (!map.layerManager) return;
2235    var zoom = map.getZoom();
2236    map.layerManager.getAllGroupNames().forEach(function (group) {
2237      var layer = map.layerManager.getLayerGroup(group, false);
2238
2239      if (layer && typeof layer.zoomLevels !== "undefined") {
2240        setVisibility(layer, layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0, group);
2241      }
2242    });
2243  }
2244
2245  map.showHideGroupsOnZoom = showHideGroupsOnZoom;
2246  map.on("zoomend", showHideGroupsOnZoom);
2247}
2248
2249methods.setGroupOptions = function (group, options) {
2250  var _this7 = this;
2251
2252  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2253    var layer = _this7.layerManager.getLayerGroup(g, true); // This slightly tortured check is because 0 is a valid value for zoomLevels
2254
2255
2256    if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) {
2257      layer.zoomLevels = (0, _util.asArray)(options.zoomLevels);
2258    }
2259  });
2260
2261  setupShowHideGroupsOnZoom(this);
2262  this.showHideGroupsOnZoom();
2263};
2264
2265methods.addRasterImage = function (uri, bounds, opacity, attribution, layerId, group) {
2266  // uri is a data URI containing an image. We want to paint this image as a
2267  // layer at (top-left) bounds[0] to (bottom-right) bounds[1].
2268  // We can't simply use ImageOverlay, as it uses bilinear scaling which looks
2269  // awful as you zoom in (and sometimes shifts positions or disappears).
2270  // Instead, we'll use a TileLayer.Canvas to draw pieces of the image.
2271  // First, some helper functions.
2272  // degree2tile converts latitude, longitude, and zoom to x and y tile
2273  // numbers. The tile numbers returned can be non-integral, as there's no
2274  // reason to expect that the lat/lng inputs are exactly on the border of two
2275  // tiles.
2276  //
2277  // We'll use this to convert the bounds we got from the server, into coords
2278  // in tile-space at a given zoom level. Note that once we do the conversion,
2279  // we don't to do any more trigonometry to convert between pixel coordinates
2280  // and tile coordinates; the source image pixel coords, destination canvas
2281  // pixel coords, and tile coords all can be scaled linearly.
2282  function degree2tile(lat, lng, zoom) {
2283    // See http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
2284    var latRad = lat * Math.PI / 180;
2285    var n = Math.pow(2, zoom);
2286    var x = (lng + 180) / 360 * n;
2287    var y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * n;
2288    return {
2289      x: x,
2290      y: y
2291    };
2292  }
2292 // Given a range [from,to) and either one or two numbers, returns true if
2293  // there is any overlap between [x,x1) and the range--or if x1 is omitted,
2294  // then returns true if x is within [from,to).
2295
2296
2297  function overlap(from, to, x,
2298  /* optional */
2299  x1) {
2300    if (arguments.length == 3) x1 = x;
2301    return x < to && x1 >= from;
2302  }
2303
2304  function getCanvasSmoothingProperty(ctx) {
2305    var candidates = ["imageSmoothingEnabled", "mozImageSmoothingEnabled", "webkitImageSmoothingEnabled", "msImageSmoothingEnabled"];
2306
2307    for (var i = 0; i < candidates.length; i++) {
2308      if (typeof ctx[candidates[i]] !== "undefined") {
2309        return candidates[i];
2310      }
2311    }
2312
2313    return null;
2314  } // Our general strategy is to:
2315  // 1. Load the data URI in an Image() object, so we can get its pixel
2316  //    dimensions and the underlying image data. (We could have done this
2317  //    by not encoding as PNG at all but just send an array of RGBA values
2318  //    from the server, but that would inflate the JSON too much.)
2319  // 2. Create a hidden canvas that we use just to extract the image data
2320  //    from the Image (using Context2D.getImageData()).
2321  // 3. Create a TileLayer.Canvas and add it to the map.
2322  // We want to synchronously create and attach the TileLayer.Canvas (so an
2323  // immediate call to clearRasters() will be respected, for example), but
2324  // Image loads its data asynchronously. Fortunately we can resolve this
2325  // by putting TileLayer.Canvas into async mode, which will let us create
2326  // and attach the layer but have it wait until the image is loaded before
2327  // it actually draws anything.
2328  // These are the variables that we will populate once the image is loaded.
2329
2330
2331  var imgData = null; // 1d row-major array, four [0-255] integers per pixel
2332
2333  var imgDataMipMapper = null;
2334  var w = null; // image width in pixels
2335
2336  var h = null; // image height in pixels
2337  // We'll use this array to store callbacks that need to be invoked once
2338  // imgData, w, and h have been resolved.
2339
2340  var imgDataCallbacks = []; // Consumers of imgData, w, and h can call this to be notified when data
2341  // is available.
2342
2343  function getImageData(callback) {
2344    if (imgData != null) {
2345      // Must not invoke the callback immediately; it's too confusing and
2346      // fragile to have a function invoke the callback *either* immediately
2347      // or in the future. Better to be consistent here.
2348      setTimeout(function () {
2349        callback(imgData, w, h, imgDataMipMapper);
2350      }, 0);
2351    } else {
2352      imgDataCallbacks.push(callback);
2353    }
2354  }
2355
2356  var img = new Image();
2357
2358  img.onload = function () {
2359    // Save size
2360    w = img.width;
2361    h = img.height; // Create a dummy canvas to extract the image data
2362
2363    var imgDataCanvas = document.createElement("canvas");
2364    imgDataCanvas.width = w;
2365    imgDataCanvas.height = h;
2366    imgDataCanvas.style.display = "none";
2367    document.body.appendChild(imgDataCanvas);
2368    var imgDataCtx = imgDataCanvas.getContext("2d");
2369    imgDataCtx.drawImage(img, 0, 0); // Save the image data.
2370
2371    imgData = imgDataCtx.getImageData(0, 0, w, h).data;
2372    imgDataMipMapper = new _mipmapper2["default"](img); // Done with the canvas, remove it from the page so it can be gc'd.
2373
2374    document.body.removeChild(imgDataCanvas); // Alert any getImageData callers who are waiting.
2375
2376    for (var i = 0; i < imgDataCallbacks.length; i++) {
2377      imgDataCallbacks[i](imgData, w, h, imgDataMipMapper);
2378    }
2379
2380    imgDataCallbacks = [];
2381  };
2382
2383  img.src = uri;
2384
2385  var canvasTiles = _leaflet2["default"].gridLayer({
2386    opacity: opacity,
2387    attribution: attribution,
2388    detectRetina: true,
2389    async: true
2390  }); // NOTE: The done() function MUST NOT be invoked until after the current
2391  // tick; done() looks in Leaflet's tile cache for the current tile, and
2392  // since it's still being constructed, it won't be found.
2393
2394
2395  canvasTiles.createTile = function (tilePoint, done) {
2396    var zoom = tilePoint.z;
2397
2398    var canvas = _leaflet2["default"].DomUtil.create("canvas");
2399
2400    var error; // setup tile width and height according to the options
2401
2402    var size = this.getTileSize();
2403    canvas.width = size.x;
2404    canvas.height = size.y;
2405    getImageData(function (imgData, w, h, mipmapper) {
2406      try {
2407        // The Context2D we'll being drawing onto. It's always 256x256.
2408        var ctx = canvas.getContext("2d"); // Convert our image data's top-left and bottom-right locations into
2409        // x/y tile coordinates. This is essentially doing a spherical mercator
2410        // projection, then multiplying by 2^zoom.
2411
2412        var topLeft = degree2tile(bounds[0][0], bounds[0][1], zoom);
2413        var bottomRight = degree2tile(bounds[1][0], bounds[1][1], zoom); // The size of the image in x/y tile coordinates.
2414
2415        var extent = {
2416          x: bottomRight.x - topLeft.x,
2417          y: bottomRight.y - topLeft.y
2418        }; // Short circuit if tile is totally disjoint from image.
2419
2420        if (!overlap(tilePoint.x, tilePoint.x + 1, topLeft.x, bottomRight.x)) return;
2421        if (!overlap(tilePoint.y, tilePoint.y + 1, topLeft.y, bottomRight.y)) return; // The linear resolution of the tile we're drawing is always 256px per tile unit.
2422        // If the linear resolution (in either direction) of the image is less than 256px
2423        // per tile unit, then use nearest neighbor; otherwise, use the canvas's built-in
2424        // scaling.
2425
2426        var imgRes = {
2427          x: w / extent.x,
2428          y: h / extent.y
2429        }; // We can do the actual drawing in one of three ways:
2430        // - Call drawImage(). This is easy and fast, and results in smooth
2431        //   interpolation (bilinear?). This is what we want when we are
2432        //   reducing the image from its native size.
2433        // - Call drawImage() with imageSmoothingEnabled=false. This is easy
2434        //   and fast and gives us nearest-neighbor interpolation, which is what
2435        //   we want when enlarging the image. However, it's unsupported on many
2436        //   browsers (including QtWebkit).
2437        // - Do a manual nearest-neighbor interpolation. This is what we'll fall
2438        //   back to when enlarging, and imageSmoothingEnabled isn't supported.
2439        //   In theory it's slower, but still pretty fast on my machine, and the
2440        //   results look the same AFAICT.
2441        // Is imageSmoothingEnabled supported? If so, we can let canvas do
2442        // nearest-neighbor interpolation for us.
2443
2444        var smoothingProperty = getCanvasSmoothingProperty(ctx);
2445
2446        if (smoothingProperty || imgRes.x >= 256 && imgRes.y >= 256) {
2447          // Use built-in scaling
2448          // Turn off anti-aliasing if necessary
2449          if (smoothingProperty) {
2450            ctx[smoothingProperty] = imgRes.x >= 256 && imgRes.y >= 256;
2451          } // Don't necessarily draw with the full-size image; if we're
2452          // downscaling, use the mipmapper to get a pre-downscaled image
2453          // (see comments on Mipmapper class for why this matters).
2454
2455
2456          mipmapper.getBySize(extent.x * 256, extent.y * 256, function (mip) {
2457            // It's possible that the image will go off the edge of the canvas--
2458            // that's OK, the canvas should clip appropriately.
2459            ctx.drawImage(mip, // Convert abs tile coords to rel tile coords, then *256 to convert
2460            // to rel pixel coords
2461            (topLeft.x - tilePoint.x) * 256, (topLeft.y - tilePoint.y) * 256, // Always draw the whole thing and let canvas clip; so we can just
2462            // convert from size in tile coords straight to pixels
2463            extent.x * 256, extent.y * 256);
2464          });
2465        } else {
2466          // Use manual nearest-neighbor interpolation
2467          // Calculate the source image pixel coordinates that correspond with
2468          // the top-left and bottom-right of this tile. (If the source image
2469          // only partially overlaps the tile, we use max/min to limit the
2470          // sourceStart/End to only reflect the overlapping portion.)
2471          var sourceStart = {
2472            x: Math.max(0, Math.floor((tilePoint.x - topLeft.x) * imgRes.x)),
2473            y: Math.max(0, Math.floor((tilePoint.y - topLeft.y) * imgRes.y))
2474          };
2475          var sourceEnd = {
2476            x: Math.min(w, Math.ceil((tilePoint.x + 1 - topLeft.x) * imgRes.x)),
2477            y: Math.min(h, Math.ceil((tilePoint.y + 1 - topLeft.y) * imgRes.y))
2478          }; // The size, in dest pixels, that each source pixel should occupy.
2479          // This might be greater or less than 1 (e.g. if x and y resolution
2480          // are very different).
2481
2482          var pixelSize = {
2483            x: 256 / imgRes.x,
2484            y: 256 / imgRes.y
2485          }; // For each pixel in the source image that overlaps the tile...
2486
2487          for (var row = sourceStart.y; row < sourceEnd.y; row++) {
2488            for (var col = sourceStart.x; col < sourceEnd.x; col++) {
2489              // ...extract the pixel data...
2490              var i = (row * w + col) * 4;
2491              var r = imgData[i];
2492              var g = imgData[i + 1];
2493              var b = imgData[i + 2];
2494              var a = imgData[i + 3];
2495              ctx.fillStyle = "rgba(" + [r, g, b, a / 255].join(",") + ")"; // ...calculate the corresponding pixel coord in the dest image
2496              // where it should be drawn...
2497
2498              var pixelPos = {
2499                x: (col / imgRes.x + topLeft.x - tilePoint.x) * 256,
2500                y: (row / imgRes.y + topLeft.y - tilePoint.y) * 256
2501              }; // ...and draw a rectangle there.
2502
2503              ctx.fillRect(Math.round(pixelPos.x), Math.round(pixelPos.y), // Looks crazy, but this is necessary to prevent roun
2503ding from
2504              // causing overlap between this rect and its neighbors. The
2505              // minuend is the location of the next pixel, while the
2506              // subtrahend is the position of the current pixel (to turn an
2507              // absolute coordinate to a width/height). Yes, I had to look
2508              // up minuend and subtrahend.
2509              Math.round(pixelPos.x + pixelSize.x) - Math.round(pixelPos.x), Math.round(pixelPos.y + pixelSize.y) - Math.round(pixelPos.y));
2510            }
2511          }
2512        }
2513      } catch (e) {
2514        error = e;
2515      } finally {
2516        done(error, canvas);
2517      }
2518    });
2519    return canvas;
2520  };
2521
2522  this.layerManager.addLayer(canvasTiles, "image", layerId, group);
2523};
2524
2525methods.removeImage = function (layerId) {
2526  this.layerManager.removeLayer("image", layerId);
2527};
2528
2529methods.clearImages = function () {
2530  this.layerManager.clearLayers("image");
2531};
2532
2533methods.addMeasure = function (options) {
2534  // if a measureControl already exists, then remove it and
2535  //   replace with a new one
2536  methods.removeMeasure.call(this);
2537  this.measureControl = _leaflet2["default"].control.measure(options);
2538  this.addControl(this.measureControl);
2539};
2540
2541methods.removeMeasure = function () {
2542  if (this.measureControl) {
2543    this.removeControl(this.measureControl);
2544    this.measureControl = null;
2545  }
2546};
2547
2548methods.addSelect = function (ctGroup) {
2549  var _this8 = this;
2550
2551  methods.removeSelect.call(this);
2552  this._selectButton = _leaflet2["default"].easyButton({
2553    states: [{
2554      stateName: "select-inactive",
2555      icon: "ion-qr-scanner",
2556      title: "Make a selection",
2557      onClick: function onClick(btn, map) {
2558        btn.state("select-active");
2559        _this8._locationFilter = new _leaflet2["default"].LocationFilter2();
2560
2561        if (ctGroup) {
2562          var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup);
2563          selectionHandle.on("change", function (e) {
2564            if (e.sender !== selectionHandle) {
2565              if (_this8._locationFilter) {
2566                _this8._locationFilter.disable();
2567
2568                btn.state("select-inactive");
2569              }
2570            }
2571          });
2572
2573          var handler = function handler(e) {
2574            _this8.layerManager.brush(_this8._locationFilter.getBounds(), {
2575              sender: selectionHandle
2576            });
2577          };
2578
2579          _this8._locationFilter.on("enabled", handler);
2580
2581          _this8._locationFilter.on("change", handler);
2582
2583          _this8._locationFilter.on("disabled", function () {
2584            selectionHandle.close();
2585            _this8._locationFilter = null;
2586          });
2587        }
2588
2589        _this8._locationFilter.addTo(map);
2590      }
2591    }, {
2592      stateName: "select-active",
2593      icon: "ion-close-round",
2594      title: "Dismiss selection",
2595      onClick: function onClick(btn, map) {
2596        btn.state("select-inactive");
2597
2598        _this8._locationFilter.disable(); // If explicitly dismissed, clear the crosstalk selections
2599
2600
2601        _this8.layerManager.unbrush();
2602      }
2603    }]
2604  });
2605
2606  this._selectButton.addTo(this);
2607};
2608
2609methods.removeSelect = function () {
2610  if (this._locationFilter) {
2611    this._locationFilter.disable();
2612  }
2613
2614  if (this._selectButton) {
2615    this.removeControl(this._selectButton);
2616    this._selectButton = null;
2617  }
2618};
2619
2620methods.createMapPane = function (name, zIndex) {
2621  this.createPane(name);
2622  this.getPane(name).style.zIndex = zIndex;
2623};
2624
2625
2626}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2627},{"./cluster-layer-store":1,"./crs_utils":3,"./dataframe":4,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./mipmapper":16,"./util":17}],16:[function(require,module,exports){
2628"use strict";
2629
2630Object.defineProperty(exports, "__esModule", {
2631  value: true
2632});
2633
2634function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2635
2636function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
2637
2638function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
2639
2640// This class simulates a mipmap, which shrinks images by powers of two. This
2641// stepwise reduction results in "pixel-perfect downscaling" (where every
2642// pixel of the original image has some contribution to the downscaled image)
2643// as opposed to a single-step downscaling which will discard a lot of data
2644// (and with sparse images at small scales can give very surprising results).
2645var Mipmapper = /*#__PURE__*/function () {
2646  function Mipmapper(img) {
2647    _classCallCheck(this, Mipmapper);
2648
2649    this._layers = [img];
2650  } // The various functions on this class take a callback function BUT MAY OR MAY
2651  // NOT actually behave asynchronously.
2652
2653
2654  _createClass(Mipmapper, [{
2655    key: "getBySize",
2656    value: function getBySize(desiredWidth, desiredHeight, callback) {
2657      var _this = this;
2658
2659      var i = 0;
2660      var lastImg = this._layers[0];
2661
2662      var testNext = function testNext() {
2663        _this.getByIndex(i, function (img) {
2664          // If current image is invalid (i.e. too small to be rendered) or
2665          // it's smaller than what we wanted, return the last known good image.
2666          if (!img || img.width < desiredWidth || img.height < desiredHeight) {
2667            callback(lastImg);
2668            return;
2669          } else {
2670            lastImg = img;
2671            i++;
2672            testNext();
2673            return;
2674          }
2675        });
2676      };
2677
2678      testNext();
2679    }
2680  }, {
2681    key: "getByIndex",
2682    value: function getByIndex(i, callback) {
2683      var _this2 = this;
2684
2685      if (this._layers[i]) {
2686        callback(this._layers[i]);
2687        return;
2688      }
2689
2690      this.getByIndex(i - 1, function (prevImg) {
2691        if (!prevImg) {
2692          // prevImg could not be calculated (too small, possibly)
2693          callback(null);
2694          return;
2695        }
2696
2697        if (prevImg.width < 2 || prevImg.height < 2) {
2698          // Can't reduce this image any further
2699          callback(null);
2700          return;
2701        } // If reduce ever becomes truly asynchronous, we should stuff a promise or
2702        // something into this._layers[i] before calling this.reduce(), to prevent
2703        // redundant reduce operations from happening.
2704
2705
2706        _this2.reduce(prevImg, function (reducedImg) {
2707          _this2._layers[i] = reducedImg;
2708          callback(reducedImg);
2709          return;
2710        });
2711      });
2712    }
2713  }, {
2714    key: "reduce",
2715    value: function reduce(img, callback) {
2716      var imgDataCanvas = document.createElement("canvas");
2717      imgDataCanvas.width = Math.ceil(img.width / 2);
2718      imgDataCanvas.height = Math.ceil(img.height / 2);
2719      imgDataCanvas.style.display = "none";
2720      document.body.appendChild(imgDataCanvas);
2721
2722      try {
2723        var imgDataCtx = imgDataCanvas.getContext("2d");
2724        imgDataCtx.drawImage(img, 0, 0, img.width / 2, img.height / 2);
2725        callback(imgDataCanvas);
2726      } finally {
2727        document.body.removeChild(imgDataCanvas);
2728      }
2729    }
2730  }]);
2731
2732  return Mipmapper;
2733}();
2734
2735exports["default"] = Mipmapper;
2736
2737
2738},{}],17:[function(require,module,exports){
2739"use strict";
2740
2741Object.defineProperty(exports, "__esModule", {
2742  value: true
2743});
2744exports.log = log;
2745exports.recycle = recycle;
2746exports.asArray = asArray;
2747
2748function log(message) {
2749  /* eslint-disable no-console */
2750  if (console && console.log) console.log(message);
2751  /* eslint-enable no-console */
2752}
2753
2754function recycle(values, length, inPlace) {
2755  if (length === 0 && !inPlace) return [];
2756
2757  if (!(values instanceof Array)) {
2758    if (inPlace) {
2759      throw new Error("Can't do in-place recycling of a non-Array value");
2760    }
2761
2762    values = [values];
2763  }
2764
2765  if (typeof length === "undefined") length = values.length;
2766  var dest = inPlace ? values : [];
2767  var origLength = values.length;
2768
2769  while (dest.length < length) {
2770    dest.push(values[dest.length % origLength]);
2771  }
2772
2773  if (dest.length > length) {
2774    dest.splice(length, dest.length - length);
2775  }
2776
2777  return dest;
2778}
2779
2780function asArray(value) {
2781  if (value instanceof Array) return value;else return [value];
2782}
2783
2784
2785},{}]},{},[13]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.