/* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["components_MapComponent_js"],{ /***/ "./node_modules/leaflet-contextmenu/dist/leaflet.contextmenu.js": /*!**********************************************************************!*\ !*** ./node_modules/leaflet-contextmenu/dist/leaflet.contextmenu.js ***! \**********************************************************************/ /***/ (function(module, exports, __webpack_require__) { eval(__webpack_require__.ts("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*\n\tLeaflet.contextmenu, a context menu for Leaflet.\n\t(c) 2015, Adam Ratcliffe, GeoSmart Maps Limited\n\n\t@preserve\n*/\n\n(function(factory) {\n\t// Packaging/modules magic dance\n\tvar L;\n\tif (true) {\n\t\t// AMD\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! leaflet */ \"./node_modules/leaflet/dist/leaflet-src.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n})(function(L) {\nL.Map.mergeOptions({\n contextmenuItems: []\n});\n\nL.Map.ContextMenu = L.Handler.extend({\n _touchstart: L.Browser.msPointer ? 'MSPointerDown' : L.Browser.pointer ? 'pointerdown' : 'touchstart',\n \n statics: {\n BASE_CLS: 'leaflet-contextmenu'\n },\n \n initialize: function (map) {\n L.Handler.prototype.initialize.call(this, map);\n \n this._items = [];\n this._visible = false;\n\n var container = this._container = L.DomUtil.create('div', L.Map.ContextMenu.BASE_CLS, map._container);\n container.style.zIndex = 10000;\n container.style.position = 'absolute';\n\n if (map.options.contextmenuWidth) {\n container.style.width = map.options.contextmenuWidth + 'px';\n }\n\n this._createItems();\n\n L.DomEvent\n .on(container, 'click', L.DomEvent.stop)\n .on(container, 'mousedown', L.DomEvent.stop)\n .on(container, 'dblclick', L.DomEvent.stop)\n .on(container, 'contextmenu', L.DomEvent.stop);\n },\n\n addHooks: function () {\n var container = this._map.getContainer();\n\n L.DomEvent\n .on(container, 'mouseleave', this._hide, this)\n .on(document, 'keydown', this._onKeyDown, this);\n\n if (L.Browser.touch) {\n L.DomEvent.on(document, this._touchstart, this._hide, this);\n }\n\n this._map.on({\n contextmenu: this._show,\n mousedown: this._hide,\n movestart: this._hide,\n zoomstart: this._hide\n }, this);\n },\n\n removeHooks: function () {\n var container = this._map.getContainer();\n\n L.DomEvent\n .off(container, 'mouseleave', this._hide, this)\n .off(document, 'keydown', this._onKeyDown, this);\n\n if (L.Browser.touch) {\n L.DomEvent.off(document, this._touchstart, this._hide, this);\n }\n\n this._map.off({\n contextmenu: this._show,\n mousedown: this._hide,\n movestart: this._hide,\n zoomstart: this._hide\n }, this);\n },\n\n showAt: function (point, data) {\n if (point instanceof L.LatLng) {\n point = this._map.latLngToContainerPoint(point);\n }\n this._showAtPoint(point, data);\n },\n\n hide: function () {\n this._hide();\n },\n\n addItem: function (options) {\n return this.insertItem(options);\n },\n\n insertItem: function (options, index) {\n index = index !== undefined ? index: this._items.length;\n\n var item = this._createItem(this._container, options, index);\n\n this._items.push(item);\n\n this._sizeChanged = true;\n\n this._map.fire('contextmenu.additem', {\n contextmenu: this,\n el: item.el,\n index: index\n });\n\n return item.el;\n },\n\n removeItem: function (item) {\n var container = this._container;\n\n if (!isNaN(item)) {\n item = container.children[item];\n }\n\n if (item) {\n this._removeItem(L.Util.stamp(item));\n\n this._sizeChanged = true;\n\n this._map.fire('contextmenu.removeitem', {\n contextmenu: this,\n el: item\n });\n\n return item;\n }\n\n return null;\n },\n\n removeAllItems: function () {\n var items = this._container.children,\n item;\n\n while (items.length) {\n item = items[0];\n this._removeItem(L.Util.stamp(item));\n }\n return items;\n },\n\n hideAllItems: function () {\n var item, i, l;\n\n for (i = 0, l = this._items.length; i < l; i++) {\n item = this._items[i];\n item.el.style.display = 'none';\n }\n },\n\n showAllItems: function () {\n var item, i, l;\n\n for (i = 0, l = this._items.length; i < l; i++) {\n item = this._items[i];\n item.el.style.display = '';\n }\n },\n\n setDisabled: function (item, disabled) {\n var container = this._container,\n itemCls = L.Map.ContextMenu.BASE_CLS + '-item';\n\n if (!isNaN(item)) {\n item = container.children[item];\n }\n\n if (item && L.DomUtil.hasClass(item, itemCls)) {\n if (disabled) {\n L.DomUtil.addClass(item, itemCls + '-disabled');\n this._map.fire('contextmenu.disableitem', {\n contextmenu: this,\n el: item\n });\n } else {\n L.DomUtil.removeClass(item, itemCls + '-disabled');\n this._map.fire('contextmenu.enableitem', {\n contextmenu: this,\n el: item\n });\n }\n }\n },\n\n isVisible: function () {\n return this._visible;\n },\n\n _createItems: function () {\n var itemOptions = this._map.options.contextmenuItems,\n item,\n i, l;\n\n for (i = 0, l = itemOptions.length; i < l; i++) {\n this._items.push(this._createItem(this._container, itemOptions[i]));\n }\n },\n\n _createItem: function (container, options, index) {\n if (options.separator || options === '-') {\n return this._createSeparator(container, index);\n }\n\n var itemCls = L.Map.ContextMenu.BASE_CLS + '-item',\n cls = options.disabled ? (itemCls + ' ' + itemCls + '-disabled') : itemCls,\n el = this._insertElementAt('a', cls, container, index),\n callback = this._createEventHandler(el, options.callback, options.context, options.hideOnSelect),\n icon = this._getIcon(options),\n iconCls = this._getIconCls(options),\n html = '';\n\n if (icon) {\n html = '';\n } else if (iconCls) {\n html = '';\n }\n\n el.innerHTML = html + options.text;\n el.href = '#';\n\n L.DomEvent\n .on(el, 'mouseover', this._onItemMouseOver, this)\n .on(el, 'mouseout', this._onItemMouseOut, this)\n .on(el, 'mousedown', L.DomEvent.stopPropagation)\n .on(el, 'click', callback);\n\n if (L.Browser.touch) {\n L.DomEvent.on(el, this._touchstart, L.DomEvent.stopPropagation);\n }\n\n // Devices without a mouse fire \"mouseover\" on tap, but never “mouseout\"\n if (!L.Browser.pointer) {\n L.DomEvent.on(el, 'click', this._onItemMouseOut, this);\n }\n\n return {\n id: L.Util.stamp(el),\n el: el,\n callback: callback\n };\n },\n\n _removeItem: function (id) {\n var item,\n el,\n i, l, callback;\n\n for (i = 0, l = this._items.length; i < l; i++) {\n item = this._items[i];\n\n if (item.id === id) {\n el = item.el;\n callback = item.callback;\n\n if (callback) {\n L.DomEvent\n .off(el, 'mouseover', this._onItemMouseOver, this)\n .off(el, 'mouseover', this._onItemMouseOut, this)\n .off(el, 'mousedown', L.DomEvent.stopPropagation)\n .off(el, 'click', callback);\n\n if (L.Browser.touch) {\n L.DomEvent.off(el, this._touchstart, L.DomEvent.stopPropagation);\n }\n\n if (!L.Browser.pointer) {\n L.DomEvent.on(el, 'click', this._onItemMouseOut, this);\n }\n }\n\n this._container.removeChild(el);\n this._items.splice(i, 1);\n\n return item;\n }\n }\n return null;\n },\n\n _createSeparator: function (container, index) {\n var el = this._insertElementAt('div', L.Map.ContextMenu.BASE_CLS + '-separator', container, index);\n\n return {\n id: L.Util.stamp(el),\n el: el\n };\n },\n\n _createEventHandler: function (el, func, context, hideOnSelect) {\n var me = this,\n map = this._map,\n disabledCls = L.Map.ContextMenu.BASE_CLS + '-item-disabled',\n hideOnSelect = (hideOnSelect !== undefined) ? hideOnSelect : true;\n\n return function (e) {\n if (L.DomUtil.hasClass(el, disabledCls)) {\n return;\n }\n\n if (hideOnSelect) {\n me._hide();\n }\n\n if (func) {\n func.call(context || map, me._showLocation);\n }\n\n me._map.fire('contextmenu.select', {\n contextmenu: me,\n el: el\n });\n };\n },\n\n _insertElementAt: function (tagName, className, container, index) {\n var refEl,\n el = document.createElement(tagName);\n\n el.className = className;\n\n if (index !== undefined) {\n refEl = container.children[index];\n }\n\n if (refEl) {\n container.insertBefore(el, refEl);\n } else {\n container.appendChild(el);\n }\n\n return el;\n },\n\n _show: function (e) {\n this._showAtPoint(e.containerPoint, e);\n },\n\n _showAtPoint: function (pt, data) {\n if (this._items.length) {\n var map = this._map,\n layerPoint = map.containerPointToLayerPoint(pt),\n latlng = map.layerPointToLatLng(layerPoint),\n event = L.extend(data || {}, {contextmenu: this});\n\n this._showLocation = {\n latlng: latlng,\n layerPoint: layerPoint,\n containerPoint: pt\n };\n\n if (data && data.relatedTarget){\n this._showLocation.relatedTarget = data.relatedTarget;\n }\n\n this._setPosition(pt);\n\n if (!this._visible) {\n this._container.style.display = 'block';\n this._visible = true;\n }\n\n this._map.fire('contextmenu.show', event);\n }\n },\n\n _hide: function () {\n if (this._visible) {\n this._visible = false;\n this._container.style.display = 'none';\n this._map.fire('contextmenu.hide', {contextmenu: this});\n }\n },\n\n _getIcon: function (options) {\n return L.Browser.retina && options.retinaIcon || options.icon;\n },\n\n _getIconCls: function (options) {\n return L.Browser.retina && options.retinaIconCls || options.iconCls;\n },\n\n _setPosition: function (pt) {\n var mapSize = this._map.getSize(),\n container = this._container,\n containerSize = this._getElementSize(container),\n anchor;\n\n if (this._map.options.contextmenuAnchor) {\n anchor = L.point(this._map.options.contextmenuAnchor);\n pt = pt.add(anchor);\n }\n\n container._leaflet_pos = pt;\n\n if (pt.x + containerSize.x > mapSize.x) {\n container.style.left = 'auto';\n container.style.right = Math.min(Math.max(mapSize.x - pt.x, 0), mapSize.x - containerSize.x - 1) + 'px';\n } else {\n container.style.left = Math.max(pt.x, 0) + 'px';\n container.style.right = 'auto';\n }\n\n if (pt.y + containerSize.y > mapSize.y) {\n container.style.top = 'auto';\n container.style.bottom = Math.min(Math.max(mapSize.y - pt.y, 0), mapSize.y - containerSize.y - 1) + 'px';\n } else {\n container.style.top = Math.max(pt.y, 0) + 'px';\n container.style.bottom = 'auto';\n }\n },\n\n _getElementSize: function (el) {\n var size = this._size,\n initialDisplay = el.style.display;\n\n if (!size || this._sizeChanged) {\n size = {};\n\n el.style.left = '-999999px';\n el.style.right = 'auto';\n el.style.display = 'block';\n\n size.x = el.offsetWidth;\n size.y = el.offsetHeight;\n\n el.style.left = 'auto';\n el.style.display = initialDisplay;\n\n this._sizeChanged = false;\n }\n\n return size;\n },\n\n _onKeyDown: function (e) {\n var key = e.keyCode;\n\n // If ESC pressed and context menu is visible hide it\n if (key === 27) {\n this._hide();\n }\n },\n\n _onItemMouseOver: function (e) {\n L.DomUtil.addClass(e.target || e.srcElement, 'over');\n },\n\n _onItemMouseOut: function (e) {\n L.DomUtil.removeClass(e.target || e.srcElement, 'over');\n }\n});\n\nL.Map.addInitHook('addHandler', 'contextmenu', L.Map.ContextMenu);\nL.Mixin.ContextMenu = {\n bindContextMenu: function (options) {\n L.setOptions(this, options);\n this._initContextMenu();\n\n return this;\n },\n\n unbindContextMenu: function (){\n this.off('contextmenu', this._showContextMenu, this);\n\n return this;\n },\n\n addContextMenuItem: function (item) {\n this.options.contextmenuItems.push(item);\n },\n\n removeContextMenuItemWithIndex: function (index) {\n var items = [];\n for (var i = 0; i < this.options.contextmenuItems.length; i++) {\n if (this.options.contextmenuItems[i].index == index){\n items.push(i);\n }\n }\n var elem = items.pop();\n while (elem !== undefined) {\n this.options.contextmenuItems.splice(elem,1);\n elem = items.pop();\n }\n },\n\n replaceContextMenuItem: function (item) {\n this.removeContextMenuItemWithIndex(item.index);\n this.addContextMenuItem(item);\n },\n\n _initContextMenu: function () {\n this._items = [];\n\n this.on('contextmenu', this._showContextMenu, this);\n },\n\n _showContextMenu: function (e) {\n var itemOptions,\n data, pt, i, l;\n\n if (this._map.contextmenu) {\n data = L.extend({relatedTarget: this}, e);\n\n pt = this._map.mouseEventToContainerPoint(e.originalEvent);\n\n if (!this.options.contextmenuInheritItems) {\n this._map.contextmenu.hideAllItems();\n }\n\n for (i = 0, l = this.options.contextmenuItems.length; i < l; i++) {\n itemOptions = this.options.contextmenuItems[i];\n this._items.push(this._map.contextmenu.insertItem(itemOptions, itemOptions.index));\n }\n\n this._map.once('contextmenu.hide', this._hideContextMenu, this);\n\n this._map.contextmenu.showAt(pt, data);\n }\n },\n\n _hideContextMenu: function () {\n var i, l;\n\n for (i = 0, l = this._items.length; i < l; i++) {\n this._map.contextmenu.removeItem(this._items[i]);\n }\n this._items.length = 0;\n\n if (!this.options.contextmenuInheritItems) {\n this._map.contextmenu.showAllItems();\n }\n }\n};\n\nvar classes = [L.Marker, L.Path],\n defaultOptions = {\n contextmenu: false,\n contextmenuItems: [],\n contextmenuInheritItems: true\n },\n cls, i, l;\n\nfor (i = 0, l = classes.length; i < l; i++) {\n cls = classes[i];\n\n // L.Class should probably provide an empty options hash, as it does not test\n // for it here and add if needed\n if (!cls.prototype.options) {\n cls.prototype.options = defaultOptions;\n } else {\n cls.mergeOptions(defaultOptions);\n }\n\n cls.addInitHook(function () {\n if (this.options.contextmenu) {\n this._initContextMenu();\n }\n });\n\n cls.include(L.Mixin.ContextMenu);\n}\nreturn L.Map.ContextMenu;\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvbGVhZmxldC1jb250ZXh0bWVudS9kaXN0L2xlYWZsZXQuY29udGV4dG1lbnUuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSyxJQUEwQztBQUMvQztBQUNBLEVBQUUsaUNBQU8sQ0FBQyxnRkFBUyxDQUFDLG9DQUFFLE9BQU87QUFBQTtBQUFBO0FBQUEsa0dBQUM7QUFDOUIsR0FBRyxLQUFLLEVBVU47QUFDRixDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQSw0Q0FBNEMsT0FBTztBQUNuRDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUEsNENBQTRDLE9BQU87QUFDbkQ7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDLE9BQU87QUFDbkQ7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDLE9BQU87QUFDbkQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsR0FBRyxrQkFBa0I7O0FBRTVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGtCQUFrQjtBQUNsRTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0Esd0JBQXdCLDBDQUEwQztBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCLG9CQUFvQjs7QUFFakQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtFQUFrRSxPQUFPO0FBQ3pFO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBLDRDQUE0QyxPQUFPO0FBQ25EO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUEsZ0NBQWdDLE9BQU87QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL19OX0UvLi9ub2RlX21vZHVsZXMvbGVhZmxldC1jb250ZXh0bWVudS9kaXN0L2xlYWZsZXQuY29udGV4dG1lbnUuanM/NWQwZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuXHRMZWFmbGV0LmNvbnRleHRtZW51LCBhIGNvbnRleHQgbWVudSBmb3IgTGVhZmxldC5cblx0KGMpIDIwMTUsIEFkYW0gUmF0Y2xpZmZlLCBHZW9TbWFydCBNYXBzIExpbWl0ZWRcblxuXHRAcHJlc2VydmVcbiovXG5cbihmdW5jdGlvbihmYWN0b3J5KSB7XG5cdC8vIFBhY2thZ2luZy9tb2R1bGVzIG1hZ2ljIGRhbmNlXG5cdHZhciBMO1xuXHRpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFsnbGVhZmxldCddLCBmYWN0b3J5KTtcblx0fSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG5cdFx0Ly8gTm9kZS9Db21tb25KU1xuXHRcdEwgPSByZXF1aXJlKCdsZWFmbGV0Jyk7XG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KEwpO1xuXHR9IGVsc2Uge1xuXHRcdC8vIEJyb3dzZXIgZ2xvYmFsc1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LkwgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0xlYWZsZXQgbXVzdCBiZSBsb2FkZWQgZmlyc3QnKTtcblx0XHR9XG5cdFx0ZmFjdG9yeSh3aW5kb3cuTCk7XG5cdH1cbn0pKGZ1bmN0aW9uKEwpIHtcbkwuTWFwLm1lcmdlT3B0aW9ucyh7XG4gICAgY29udGV4dG1lbnVJdGVtczogW11cbn0pO1xuXG5MLk1hcC5Db250ZXh0TWVudSA9IEwuSGFuZGxlci5leHRlbmQoe1xuICAgIF90b3VjaHN0YXJ0OiBMLkJyb3dzZXIubXNQb2ludGVyID8gJ01TUG9pbnRlckRvd24nIDogTC5Ccm93c2VyLnBvaW50ZXIgPyAncG9pbnRlcmRvd24nIDogJ3RvdWNoc3RhcnQnLFxuICAgIFxuICAgIHN0YXRpY3M6IHtcbiAgICAgICAgQkFTRV9DTFM6ICdsZWFmbGV0LWNvbnRleHRtZW51J1xuICAgIH0sXG4gICAgXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG1hcCkge1xuICAgICAgICBMLkhhbmRsZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCh0aGlzLCBtYXApO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5faXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy5fdmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIgPSBMLkRvbVV0aWwuY3JlYXRlKCdkaXYnLCBMLk1hcC5Db250ZXh0TWVudS5CQVNFX0NMUywgbWFwLl9jb250YWluZXIpO1xuICAgICAgICBjb250YWluZXIuc3R5bGUuekluZGV4ID0gMTAwMDA7XG4gICAgICAgIGNvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cbiAgICAgICAgaWYgKG1hcC5vcHRpb25zLmNvbnRleHRtZW51V2lkdGgpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS53aWR0aCA9IG1hcC5vcHRpb25zLmNvbnRleHRtZW51V2lkdGggKyAncHgnO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY3JlYXRlSXRlbXMoKTtcblxuICAgICAgICBMLkRvbUV2ZW50XG4gICAgICAgICAgICAub24oY29udGFpbmVyLCAnY2xpY2snLCBMLkRvbUV2ZW50LnN0b3ApXG4gICAgICAgICAgICAub24oY29udGFpbmVyLCAnbW91c2Vkb3duJywgTC5Eb21FdmVudC5zdG9wKVxuICAgICAgICAgICAgLm9uKGNvbnRhaW5lciwgJ2RibGNsaWNrJywgTC5Eb21FdmVudC5zdG9wKVxuICAgICAgICAgICAgLm9uKGNvbnRhaW5lciwgJ2NvbnRleHRtZW51JywgTC5Eb21FdmVudC5zdG9wKTtcbiAgICB9LFxuXG4gICAgYWRkSG9va3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX21hcC5nZXRDb250YWluZXIoKTtcblxuICAgICAgICBMLkRvbUV2ZW50XG4gICAgICAgICAgICAub24oY29udGFpbmVyLCAnbW91c2VsZWF2ZScsIHRoaXMuX2hpZGUsIHRoaXMpXG4gICAgICAgICAgICAub24oZG9jdW1lbnQsICdrZXlkb3duJywgdGhpcy5fb25LZXlEb3duLCB0aGlzKTtcblxuICAgICAgICBpZiAoTC5Ccm93c2VyLnRvdWNoKSB7XG4gICAgICAgICAgICBMLkRvbUV2ZW50Lm9uKGRvY3VtZW50LCB0aGlzLl90b3VjaHN0YXJ0LCB0aGlzLl9oaWRlLCB0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21hcC5vbih7XG4gICAgICAgICAgICBjb250ZXh0bWVudTogdGhpcy5fc2hvdyxcbiAgICAgICAgICAgIG1vdXNlZG93bjogdGhpcy5faGlkZSxcbiAgICAgICAgICAgIG1vdmVzdGFydDogdGhpcy5faGlkZSxcbiAgICAgICAgICAgIHpvb21zdGFydDogdGhpcy5faGlkZVxuICAgICAgICB9LCB0aGlzKTtcbiAgICB9LFxuXG4gICAgcmVtb3ZlSG9va3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX21hcC5nZXRDb250YWluZXIoKTtcblxuICAgICAgICBMLkRvbUV2ZW50XG4gICAgICAgICAgICAub2ZmKGNvbnRhaW5lciwgJ21vdXNlbGVhdmUnLCB0aGlzLl9oaWRlLCB0aGlzKVxuICAgICAgICAgICAgLm9mZihkb2N1bWVudCwgJ2tleWRvd24nLCB0aGlzLl9vbktleURvd24sIHRoaXMpO1xuXG4gICAgICAgIGlmIChMLkJyb3dzZXIudG91Y2gpIHtcbiAgICAgICAgICAgIEwuRG9tRXZlbnQub2ZmKGRvY3VtZW50LCB0aGlzLl90b3VjaHN0YXJ0LCB0aGlzLl9oaWRlLCB0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21hcC5vZmYoe1xuICAgICAgICAgICAgY29udGV4dG1lbnU6IHRoaXMuX3Nob3csXG4gICAgICAgICAgICBtb3VzZWRvd246IHRoaXMuX2hpZGUsXG4gICAgICAgICAgICBtb3Zlc3RhcnQ6IHRoaXMuX2hpZGUsXG4gICAgICAgICAgICB6b29tc3RhcnQ6IHRoaXMuX2hpZGVcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfSxcblxuICAgIHNob3dBdDogZnVuY3Rpb24gKHBvaW50LCBkYXRhKSB7XG4gICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEwuTGF0TG5nKSB7XG4gICAgICAgICAgICBwb2ludCA9IHRoaXMuX21hcC5sYXRMbmdUb0NvbnRhaW5lclBvaW50KHBvaW50KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zaG93QXRQb2ludChwb2ludCwgZGF0YSk7XG4gICAgfSxcblxuICAgIGhpZGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5faGlkZSgpO1xuICAgIH0sXG5cbiAgICBhZGRJdGVtOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnNlcnRJdGVtKG9wdGlvbnMpO1xuICAgIH0sXG5cbiAgICBpbnNlcnRJdGVtOiBmdW5jdGlvbiAob3B0aW9ucywgaW5kZXgpIHtcbiAgICAgICAgaW5kZXggPSBpbmRleCAhPT0gdW5kZWZpbmVkID8gaW5kZXg6IHRoaXMuX2l0ZW1zLmxlbmd0aDtcblxuICAgICAgICB2YXIgaXRlbSA9IHRoaXMuX2NyZWF0ZUl0ZW0odGhpcy5fY29udGFpbmVyLCBvcHRpb25zLCBpbmRleCk7XG5cbiAgICAgICAgdGhpcy5faXRlbXMucHVzaChpdGVtKTtcblxuICAgICAgICB0aGlzLl9zaXplQ2hhbmdlZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fbWFwLmZpcmUoJ2NvbnRleHRtZW51LmFkZGl0ZW0nLCB7XG4gICAgICAgICAgICBjb250ZXh0bWVudTogdGhpcyxcbiAgICAgICAgICAgIGVsOiBpdGVtLmVsLFxuICAgICAgICAgICAgaW5kZXg6IGluZGV4XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBpdGVtLmVsO1xuICAgIH0sXG5cbiAgICByZW1vdmVJdGVtOiBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyO1xuXG4gICAgICAgIGlmICghaXNOYU4oaXRlbSkpIHtcbiAgICAgICAgICAgIGl0ZW0gPSBjb250YWluZXIuY2hpbGRyZW5baXRlbV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXRlbSkge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlSXRlbShMLlV0aWwuc3RhbXAoaXRlbSkpO1xuXG4gICAgICAgICAgICB0aGlzLl9zaXplQ2hhbmdlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIHRoaXMuX21hcC5maXJlKCdjb250ZXh0bWVudS5yZW1vdmVpdGVtJywge1xuICAgICAgICAgICAgICAgIGNvbnRleHRtZW51OiB0aGlzLFxuICAgICAgICAgICAgICAgIGVsOiBpdGVtXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgcmVtb3ZlQWxsSXRlbXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGl0ZW1zID0gdGhpcy5fY29udGFpbmVyLmNoaWxkcmVuLFxuICAgICAgICAgICAgaXRlbTtcblxuICAgICAgICB3aGlsZSAoaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpdGVtID0gaXRlbXNbMF07XG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVJdGVtKEwuVXRpbC5zdGFtcChpdGVtKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH0sXG5cbiAgICBoaWRlQWxsSXRlbXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGl0ZW0sIGksIGw7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuX2l0ZW1zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgaXRlbSA9IHRoaXMuX2l0ZW1zW2ldO1xuICAgICAgICAgICAgaXRlbS5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNob3dBbGxJdGVtczogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbSwgaSwgbDtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5faXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpdGVtID0gdGhpcy5faXRlbXNbaV07XG4gICAgICAgICAgICBpdGVtLmVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXREaXNhYmxlZDogZnVuY3Rpb24gKGl0ZW0sIGRpc2FibGVkKSB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIsXG4gICAgICAgIGl0ZW1DbHMgPSBMLk1hcC5Db250ZXh0TWVudS5CQVNFX0NMUyArICctaXRlbSc7XG5cbiAgICAgICAgaWYgKCFpc05hTihpdGVtKSkge1xuICAgICAgICAgICAgaXRlbSA9IGNvbnRhaW5lci5jaGlsZHJlbltpdGVtXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpdGVtICYmIEwuRG9tVXRpbC5oYXNDbGFzcyhpdGVtLCBpdGVtQ2xzKSkge1xuICAgICAgICAgICAgaWYgKGRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgTC5Eb21VdGlsLmFkZENsYXNzKGl0ZW0sIGl0ZW1DbHMgKyAnLWRpc2FibGVkJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWFwLmZpcmUoJ2NvbnRleHRtZW51LmRpc2FibGVpdGVtJywge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0bWVudTogdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgZWw6IGl0ZW1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgTC5Eb21VdGlsLnJlbW92ZUNsYXNzKGl0ZW0sIGl0ZW1DbHMgKyAnLWRpc2FibGVkJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWFwLmZpcmUoJ2NvbnRleHRtZW51LmVuYWJsZWl0ZW0nLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHRtZW51OiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICBlbDogaXRlbVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGlzVmlzaWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmlzaWJsZTtcbiAgICB9LFxuXG4gICAgX2NyZWF0ZUl0ZW1zOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpdGVtT3B0aW9ucyA9IHRoaXMuX21hcC5vcHRpb25zLmNvbnRleHRtZW51SXRlbXMsXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgaSwgbDtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXRlbU9wdGlvbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLl9pdGVtcy5wdXNoKHRoaXMuX2NyZWF0ZUl0ZW0odGhpcy5fY29udGFpbmVyLCBpdGVtT3B0aW9uc1tpXSkpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9jcmVhdGVJdGVtOiBmdW5jdGlvbiAoY29udGFpbmVyLCBvcHRpb25zLCBpbmRleCkge1xuICAgICAgICBpZiAob3B0aW9ucy5zZXBhcmF0b3IgfHwgb3B0aW9ucyA9PT0gJy0nKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlU2VwYXJhdG9yKGNvbnRhaW5lciwgaW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGl0ZW1DbHMgPSBMLk1hcC5Db250ZXh0TWVudS5CQVNFX0NMUyArICctaXRlbScsXG4gICAgICAgICAgICBjbHMgPSBvcHRpb25zLmRpc2FibGVkID8gKGl0ZW1DbHMgKyAnICcgKyBpdGVtQ2xzICsgJy1kaXNhYmxlZCcpIDogaXRlbUNscyxcbiAgICAgICAgICAgIGVsID0gdGhpcy5faW5zZXJ0RWxlbWVudEF0KCdhJywgY2xzLCBjb250YWluZXIsIGluZGV4KSxcbiAgICAgICAgICAgIGNhbGxiYWNrID0gdGhpcy5fY3JlYXRlRXZlbnRIYW5kbGVyKGVsLCBvcHRpb25zLmNhbGxiYWNrLCBvcHRpb25zLmNvbnRleHQsIG9wdGlvbnMuaGlkZU9uU2VsZWN0KSxcbiAgICAgICAgICAgIGljb24gPSB0aGlzLl9nZXRJY29uKG9wdGlvbnMpLFxuICAgICAgICAgICAgaWNvbkNscyA9IHRoaXMuX2dldEljb25DbHMob3B0aW9ucyksXG4gICAgICAgICAgICBodG1sID0gJyc7XG5cbiAgICAgICAgaWYgKGljb24pIHtcbiAgICAgICAgICAgIGh0bWwgPSAnPGltZyBjbGFzcz1cIicgKyBMLk1hcC5Db250ZXh0TWVudS5CQVNFX0NMUyArICctaWNvblwiIHNyYz1cIicgKyBpY29uICsgJ1wiLz4nO1xuICAgICAgICB9IGVsc2UgaWYgKGljb25DbHMpIHtcbiAgICAgICAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCInICsgTC5NYXAuQ29udGV4dE1lbnUuQkFTRV9DTFMgKyAnLWljb24gJyArIGljb25DbHMgKyAnXCI+PC9zcGFuPic7XG4gICAgICAgIH1cblxuICAgICAgICBlbC5pbm5lckhUTUwgPSBodG1sICsgb3B0aW9ucy50ZXh0O1xuICAgICAgICBlbC5ocmVmID0gJyMnO1xuXG4gICAgICAgIEwuRG9tRXZlbnRcbiAgICAgICAgICAgIC5vbihlbCwgJ21vdXNlb3ZlcicsIHRoaXMuX29uSXRlbU1vdXNlT3ZlciwgdGhpcylcbiAgICAgICAgICAgIC5vbihlbCwgJ21vdXNlb3V0JywgdGhpcy5fb25JdGVtTW91c2VPdXQsIHRoaXMpXG4gICAgICAgICAgICAub24oZWwsICdtb3VzZWRvd24nLCBMLkRvbUV2ZW50LnN0b3BQcm9wYWdhdGlvbilcbiAgICAgICAgICAgIC5vbihlbCwgJ2NsaWNrJywgY2FsbGJhY2spO1xuXG4gICAgICAgIGlmIChMLkJyb3dzZXIudG91Y2gpIHtcbiAgICAgICAgICAgIEwuRG9tRXZlbnQub24oZWwsIHRoaXMuX3RvdWNoc3RhcnQsIEwuRG9tRXZlbnQuc3RvcFByb3BhZ2F0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERldmljZXMgd2l0aG91dCBhIG1vdXNlIGZpcmUgXCJtb3VzZW92ZXJcIiBvbiB0YXAsIGJ1dCBuZXZlciDigJxtb3VzZW91dFwiXG4gICAgICAgIGlmICghTC5Ccm93c2VyLnBvaW50ZXIpIHtcbiAgICAgICAgICAgIEwuRG9tRXZlbnQub24oZWwsICdjbGljaycsIHRoaXMuX29uSXRlbU1vdXNlT3V0LCB0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDogTC5VdGlsLnN0YW1wKGVsKSxcbiAgICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFja1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBfcmVtb3ZlSXRlbTogZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHZhciBpdGVtLFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBpLCBsLCBjYWxsYmFjaztcblxuICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5faXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBpdGVtID0gdGhpcy5faXRlbXNbaV07XG5cbiAgICAgICAgICAgIGlmIChpdGVtLmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgIGVsID0gaXRlbS5lbDtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGl0ZW0uY2FsbGJhY2s7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgTC5Eb21FdmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLm9mZihlbCwgJ21vdXNlb3ZlcicsIHRoaXMuX29uSXRlbU1vdXNlT3ZlciwgdGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5vZmYoZWwsICdtb3VzZW92ZXInLCB0aGlzLl9vbkl0ZW1Nb3VzZU91dCwgdGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5vZmYoZWwsICdtb3VzZWRvd24nLCBMLkRvbUV2ZW50LnN0b3BQcm9wYWdhdGlvbilcbiAgICAgICAgICAgICAgICAgICAgICAgIC5vZmYoZWwsICdjbGljaycsIGNhbGxiYWNrKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoTC5Ccm93c2VyLnRvdWNoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMLkRvbUV2ZW50Lm9mZihlbCwgdGhpcy5fdG91Y2hzdGFydCwgTC5Eb21FdmVudC5zdG9wUHJvcGFnYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFMLkJyb3dzZXIucG9pbnRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgTC5Eb21FdmVudC5vbihlbCwgJ2NsaWNrJywgdGhpcy5fb25JdGVtTW91c2VPdXQsIHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fY29udGFpbmVyLnJlbW92ZUNoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pdGVtcy5zcGxpY2UoaSwgMSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgX2NyZWF0ZVNlcGFyYXRvcjogZnVuY3Rpb24gKGNvbnRhaW5lciwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGVsID0gdGhpcy5faW5zZXJ0RWxlbWVudEF0KCdkaXYnLCBMLk1hcC5Db250ZXh0TWVudS5CQVNFX0NMUyArICctc2VwYXJhdG9yJywgY29udGFpbmVyLCBpbmRleCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOiBMLlV0aWwuc3RhbXAoZWwpLFxuICAgICAgICAgICAgZWw6IGVsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIF9jcmVhdGVFdmVudEhhbmRsZXI6IGZ1bmN0aW9uIChlbCwgZnVuYywgY29udGV4dCwgaGlkZU9uU2VsZWN0KSB7XG4gICAgICAgIHZhciBtZSA9IHRoaXMsXG4gICAgICAgICAgICBtYXAgPSB0aGlzLl9tYXAsXG4gICAgICAgICAgICBkaXNhYmxlZENscyA9IEwuTWFwLkNvbnRleHRNZW51LkJBU0VfQ0xTICsgJy1pdGVtLWRpc2FibGVkJyxcbiAgICAgICAgICAgIGhpZGVPblNlbGVjdCA9IChoaWRlT25TZWxlY3QgIT09IHVuZGVmaW5lZCkgPyBoaWRlT25TZWxlY3QgOiB0cnVlO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKEwuRG9tVXRpbC5oYXNDbGFzcyhlbCwgZGlzYWJsZWRDbHMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGlkZU9uU2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgbWUuX2hpZGUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZ1bmMpIHtcbiAgICAgICAgICAgICAgICBmdW5jLmNhbGwoY29udGV4dCB8fCBtYXAsIG1lLl9zaG93TG9jYXRpb24pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtZS5fbWFwLmZpcmUoJ2NvbnRleHRtZW51LnNlbGVjdCcsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0bWVudTogbWUsXG4gICAgICAgICAgICAgICAgZWw6IGVsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgX2luc2VydEVsZW1lbnRBdDogZnVuY3Rpb24gKHRhZ05hbWUsIGNsYXNzTmFtZSwgY29udGFpbmVyLCBpbmRleCkge1xuICAgICAgICB2YXIgcmVmRWwsXG4gICAgICAgICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG5cbiAgICAgICAgZWwuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuXG4gICAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZWZFbCA9IGNvbnRhaW5lci5jaGlsZHJlbltpbmRleF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVmRWwpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUoZWwsIHJlZkVsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZWw7XG4gICAgfSxcblxuICAgIF9zaG93OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLl9zaG93QXRQb2ludChlLmNvbnRhaW5lclBvaW50LCBlKTtcbiAgICB9LFxuXG4gICAgX3Nob3dBdFBvaW50OiBmdW5jdGlvbiAocHQsIGRhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMuX2l0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcCxcbiAgICAgICAgICAgIGxheWVyUG9pbnQgPSBtYXAuY29udGFpbmVyUG9pbnRUb0xheWVyUG9pbnQocHQpLFxuICAgICAgICAgICAgbGF0bG5nID0gbWFwLmxheWVyUG9pbnRUb0xhdExuZyhsYXllclBvaW50KSxcbiAgICAgICAgICAgIGV2ZW50ID0gTC5leHRlbmQoZGF0YSB8fCB7fSwge2NvbnRleHRtZW51OiB0aGlzfSk7XG5cbiAgICAgICAgICAgIHRoaXMuX3Nob3dMb2NhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBsYXRsbmc6IGxhdGxuZyxcbiAgICAgICAgICAgICAgICBsYXllclBvaW50OiBsYXllclBvaW50LFxuICAgICAgICAgICAgICAgIGNvbnRhaW5lclBvaW50OiBwdFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5yZWxhdGVkVGFyZ2V0KXtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaG93TG9jYXRpb24ucmVsYXRlZFRhcmdldCA9IGRhdGEucmVsYXRlZFRhcmdldDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fc2V0UG9zaXRpb24ocHQpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICAgICAgdGhpcy5fdmlzaWJsZSA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX21hcC5maXJlKCdjb250ZXh0bWVudS5zaG93JywgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9oaWRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl92aXNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLl92aXNpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9jb250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuX21hcC5maXJlKCdjb250ZXh0bWVudS5oaWRlJywge2NvbnRleHRtZW51OiB0aGlzfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX2dldEljb246IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBMLkJyb3dzZXIucmV0aW5hICYmIG9wdGlvbnMucmV0aW5hSWNvbiB8fCBvcHRpb25zLmljb247XG4gICAgfSxcblxuICAgIF9nZXRJY29uQ2xzOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gTC5Ccm93c2VyLnJldGluYSAmJiBvcHRpb25zLnJldGluYUljb25DbHMgfHwgb3B0aW9ucy5pY29uQ2xzO1xuICAgIH0sXG5cbiAgICBfc2V0UG9zaXRpb246IGZ1bmN0aW9uIChwdCkge1xuICAgICAgICB2YXIgbWFwU2l6ZSA9IHRoaXMuX21hcC5nZXRTaXplKCksXG4gICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIsXG4gICAgICAgICAgICBjb250YWluZXJTaXplID0gdGhpcy5fZ2V0RWxlbWVudFNpemUoY29udGFpbmVyKSxcbiAgICAgICAgICAgIGFuY2hvcjtcblxuICAgICAgICBpZiAodGhpcy5fbWFwLm9wdGlvbnMuY29udGV4dG1lbnVBbmNob3IpIHtcbiAgICAgICAgICAgIGFuY2hvciA9IEwucG9pbnQodGhpcy5fbWFwLm9wdGlvbnMuY29udGV4dG1lbnVBbmNob3IpO1xuICAgICAgICAgICAgcHQgPSBwdC5hZGQoYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRhaW5lci5fbGVhZmxldF9wb3MgPSBwdDtcblxuICAgICAgICBpZiAocHQueCArIGNvbnRhaW5lclNpemUueCA+IG1hcFNpemUueCkge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAnYXV0byc7XG4gICAgICAgICAgICBjb250YWluZXIuc3R5bGUucmlnaHQgPSBNYXRoLm1pbihNYXRoLm1heChtYXBTaXplLnggLSBwdC54LCAwKSwgbWFwU2l6ZS54IC0gY29udGFpbmVyU2l6ZS54IC0gMSkgKyAncHgnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSBNYXRoLm1heChwdC54LCAwKSArICdweCc7XG4gICAgICAgICAgICBjb250YWluZXIuc3R5bGUucmlnaHQgPSAnYXV0byc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHQueSArIGNvbnRhaW5lclNpemUueSA+IG1hcFNpemUueSkge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnRvcCA9ICdhdXRvJztcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5ib3R0b20gPSBNYXRoLm1pbihNYXRoLm1heChtYXBTaXplLnkgLSBwdC55LCAwKSwgbWFwU2l6ZS55IC0gY29udGFpbmVyU2l6ZS55IC0gMSkgKyAncHgnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnRvcCA9IE1hdGgubWF4KHB0LnksIDApICsgJ3B4JztcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5ib3R0b20gPSAnYXV0byc7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX2dldEVsZW1lbnRTaXplOiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgdmFyIHNpemUgPSB0aGlzLl9zaXplLFxuICAgICAgICAgICAgaW5pdGlhbERpc3BsYXkgPSBlbC5zdHlsZS5kaXNwbGF5O1xuXG4gICAgICAgIGlmICghc2l6ZSB8fCB0aGlzLl9zaXplQ2hhbmdlZCkge1xuICAgICAgICAgICAgc2l6ZSA9IHt9O1xuXG4gICAgICAgICAgICBlbC5zdHlsZS5sZWZ0ID0gJy05OTk5OTlweCc7XG4gICAgICAgICAgICBlbC5zdHlsZS5yaWdodCA9ICdhdXRvJztcbiAgICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAgICAgICBzaXplLnggPSBlbC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIHNpemUueSA9IGVsLm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgZWwuc3R5bGUubGVmdCA9ICdhdXRvJztcbiAgICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBpbml0aWFsRGlzcGxheTtcblxuICAgICAgICAgICAgdGhpcy5fc2l6ZUNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzaXplO1xuICAgIH0sXG5cbiAgICBfb25LZXlEb3duOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIga2V5ID0gZS5rZXlDb2RlO1xuXG4gICAgICAgIC8vIElmIEVTQyBwcmVzc2VkIGFuZCBjb250ZXh0IG1lbnUgaXMgdmlzaWJsZSBoaWRlIGl0XG4gICAgICAgIGlmIChrZXkgPT09IDI3KSB7XG4gICAgICAgICAgICB0aGlzLl9oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX29uSXRlbU1vdXNlT3ZlcjogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgTC5Eb21VdGlsLmFkZENsYXNzKGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudCwgJ292ZXInKTtcbiAgICB9LFxuXG4gICAgX29uSXRlbU1vdXNlT3V0OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBMLkRvbVV0aWwucmVtb3ZlQ2xhc3MoZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50LCAnb3ZlcicpO1xuICAgIH1cbn0pO1xuXG5MLk1hcC5hZGRJbml0SG9vaygnYWRkSGFuZGxlcicsICdjb250ZXh0bWVudScsIEwuTWFwLkNvbnRleHRNZW51KTtcbkwuTWl4aW4uQ29udGV4dE1lbnUgPSB7XG4gICAgYmluZENvbnRleHRNZW51OiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICBMLnNldE9wdGlvbnModGhpcywgb3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX2luaXRDb250ZXh0TWVudSgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICB1bmJpbmRDb250ZXh0TWVudTogZnVuY3Rpb24gKCl7XG4gICAgICAgIHRoaXMub2ZmKCdjb250ZXh0bWVudScsIHRoaXMuX3Nob3dDb250ZXh0TWVudSwgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGFkZENvbnRleHRNZW51SXRlbTogZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5jb250ZXh0bWVudUl0ZW1zLnB1c2goaXRlbSk7XG4gICAgfSxcblxuICAgIHJlbW92ZUNvbnRleHRNZW51SXRlbVdpdGhJbmRleDogZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub3B0aW9ucy5jb250ZXh0bWVudUl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNvbnRleHRtZW51SXRlbXNbaV0uaW5kZXggPT0gaW5kZXgpe1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVsZW0gPSBpdGVtcy5wb3AoKTtcbiAgICAgICAgd2hpbGUgKGVsZW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmNvbnRleHRtZW51SXRlbXMuc3BsaWNlKGVsZW0sMSk7XG4gICAgICAgICAgICBlbGVtID0gaXRlbXMucG9wKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVwbGFjZUNvbnRleHRNZW51SXRlbTogZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5yZW1vdmVDb250ZXh0TWVudUl0ZW1XaXRoSW5kZXgoaXRlbS5pbmRleCk7XG4gICAgICAgIHRoaXMuYWRkQ29udGV4dE1lbnVJdGVtKGl0ZW0pO1xuICAgIH0sXG5cbiAgICBfaW5pdENvbnRleHRNZW51OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2l0ZW1zID0gW107XG5cbiAgICAgICAgdGhpcy5vbignY29udGV4dG1lbnUnLCB0aGlzLl9zaG93Q29udGV4dE1lbnUsIHRoaXMpO1xuICAgIH0sXG5cbiAgICBfc2hvd0NvbnRleHRNZW51OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgaXRlbU9wdGlvbnMsXG4gICAgICAgICAgICBkYXRhLCBwdCwgaSwgbDtcblxuICAgICAgICBpZiAodGhpcy5fbWFwLmNvbnRleHRtZW51KSB7XG4gICAgICAgICAgICBkYXRhID0gTC5leHRlbmQoe3JlbGF0ZWRUYXJnZXQ6IHRoaXN9LCBlKTtcblxuICAgICAgICAgICAgcHQgPSB0aGlzLl9tYXAubW91c2VFdmVudFRvQ29udGFpbmVyUG9pbnQoZS5vcmlnaW5hbEV2ZW50KTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuY29udGV4dG1lbnVJbmhlcml0SXRlbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXAuY29udGV4dG1lbnUuaGlkZUFsbEl0ZW1zKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLm9wdGlvbnMuY29udGV4dG1lbnVJdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpdGVtT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5jb250ZXh0bWVudUl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIHRoaXMuX2l0ZW1zLnB1c2godGhpcy5fbWFwLmNvbnRleHRtZW51Lmluc2VydEl0ZW0oaXRlbU9wdGlvbnMsIGl0ZW1PcHRpb25zLmluZGV4KSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX21hcC5vbmNlKCdjb250ZXh0bWVudS5oaWRlJywgdGhpcy5faGlkZUNvbnRleHRNZW51LCB0aGlzKTtcblxuICAgICAgICAgICAgdGhpcy5fbWFwLmNvbnRleHRtZW51LnNob3dBdChwdCwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX2hpZGVDb250ZXh0TWVudTogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaSwgbDtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5faXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXAuY29udGV4dG1lbnUucmVtb3ZlSXRlbSh0aGlzLl9pdGVtc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXRlbXMubGVuZ3RoID0gMDtcblxuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5jb250ZXh0bWVudUluaGVyaXRJdGVtcykge1xuICAgICAgICAgICAgdGhpcy5fbWFwLmNvbnRleHRtZW51LnNob3dBbGxJdGVtcygpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxudmFyIGNsYXNzZXMgPSBbTC5NYXJrZXIsIEwuUGF0aF0sXG4gICAgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgICAgIGNvbnRleHRtZW51OiBmYWxzZSxcbiAgICAgICAgY29udGV4dG1lbnVJdGVtczogW10sXG4gICAgICAgIGNvbnRleHRtZW51SW5oZXJpdEl0ZW1zOiB0cnVlXG4gICAgfSxcbiAgICBjbHMsIGksIGw7XG5cbmZvciAoaSA9IDAsIGwgPSBjbGFzc2VzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGNscyA9IGNsYXNzZXNbaV07XG5cbiAgICAvLyBMLkNsYXNzIHNob3VsZCBwcm9iYWJseSBwcm92aWRlIGFuIGVtcHR5IG9wdGlvbnMgaGFzaCwgYXMgaXQgZG9lcyBub3QgdGVzdFxuICAgIC8vIGZvciBpdCBoZXJlIGFuZCBhZGQgaWYgbmVlZGVkXG4gICAgaWYgKCFjbHMucHJvdG90eXBlLm9wdGlvbnMpIHtcbiAgICAgICAgY2xzLnByb3RvdHlwZS5vcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2xzLm1lcmdlT3B0aW9ucyhkZWZhdWx0T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY2xzLmFkZEluaXRIb29rKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb250ZXh0bWVudSkge1xuICAgICAgICAgICAgdGhpcy5faW5pdENvbnRleHRNZW51KCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGNscy5pbmNsdWRlKEwuTWl4aW4uQ29udGV4dE1lbnUpO1xufVxucmV0dXJuIEwuTWFwLkNvbnRleHRNZW51O1xufSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/leaflet-contextmenu/dist/leaflet.contextmenu.js\n")); /***/ }), /***/ "./node_modules/leaflet/dist/leaflet-src.js": /*!**************************************************!*\ !*** ./node_modules/leaflet/dist/leaflet-src.js ***! \**************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { eval(__webpack_require__.ts("/* @preserve\n * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com\n * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade\n */\n\n(function (global, factory) {\n true ? factory(exports) :\n 0;\n})(this, (function (exports) { 'use strict';\n\n var version = \"1.9.4\";\n\n /*\r\n * @namespace Util\r\n *\r\n * Various utility functions, used by Leaflet internally.\r\n */\r\n\r\n // @function extend(dest: Object, src?: Object): Object\r\n // Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.\r\n function extend(dest) {\r\n \tvar i, j, len, src;\r\n\r\n \tfor (j = 1, len = arguments.length; j < len; j++) {\r\n \t\tsrc = arguments[j];\r\n \t\tfor (i in src) {\r\n \t\t\tdest[i] = src[i];\r\n \t\t}\r\n \t}\r\n \treturn dest;\r\n }\r\n\r\n // @function create(proto: Object, properties?: Object): Object\r\n // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)\r\n var create$2 = Object.create || (function () {\r\n \tfunction F() {}\r\n \treturn function (proto) {\r\n \t\tF.prototype = proto;\r\n \t\treturn new F();\r\n \t};\r\n })();\r\n\r\n // @function bind(fn: Function, …): Function\r\n // Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\r\n // Has a `L.bind()` shortcut.\r\n function bind(fn, obj) {\r\n \tvar slice = Array.prototype.slice;\r\n\r\n \tif (fn.bind) {\r\n \t\treturn fn.bind.apply(fn, slice.call(arguments, 1));\r\n \t}\r\n\r\n \tvar args = slice.call(arguments, 2);\r\n\r\n \treturn function () {\r\n \t\treturn fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);\r\n \t};\r\n }\r\n\r\n // @property lastId: Number\r\n // Last unique ID used by [`stamp()`](#util-stamp)\r\n var lastId = 0;\r\n\r\n // @function stamp(obj: Object): Number\r\n // Returns the unique ID of an object, assigning it one if it doesn't have it.\r\n function stamp(obj) {\r\n \tif (!('_leaflet_id' in obj)) {\r\n \t\tobj['_leaflet_id'] = ++lastId;\r\n \t}\r\n \treturn obj._leaflet_id;\r\n }\r\n\r\n // @function throttle(fn: Function, time: Number, context: Object): Function\r\n // Returns a function which executes function `fn` with the given scope `context`\r\n // (so that the `this` keyword refers to `context` inside `fn`'s code). The function\r\n // `fn` will be called no more than one time per given amount of `time`. The arguments\r\n // received by the bound function will be any arguments passed when binding the\r\n // function, followed by any arguments passed when invoking the bound function.\r\n // Has an `L.throttle` shortcut.\r\n function throttle(fn, time, context) {\r\n \tvar lock, args, wrapperFn, later;\r\n\r\n \tlater = function () {\r\n \t\t// reset lock and call if queued\r\n \t\tlock = false;\r\n \t\tif (args) {\r\n \t\t\twrapperFn.apply(context, args);\r\n \t\t\targs = false;\r\n \t\t}\r\n \t};\r\n\r\n \twrapperFn = function () {\r\n \t\tif (lock) {\r\n \t\t\t// called too soon, queue to call later\r\n \t\t\targs = arguments;\r\n\r\n \t\t} else {\r\n \t\t\t// call and lock until later\r\n \t\t\tfn.apply(context, arguments);\r\n \t\t\tsetTimeout(later, time);\r\n \t\t\tlock = true;\r\n \t\t}\r\n \t};\r\n\r\n \treturn wrapperFn;\r\n }\r\n\r\n // @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number\r\n // Returns the number `num` modulo `range` in such a way so it lies within\r\n // `range[0]` and `range[1]`. The returned value will be always smaller than\r\n // `range[1]` unless `includeMax` is set to `true`.\r\n function wrapNum(x, range, includeMax) {\r\n \tvar max = range[1],\r\n \t min = range[0],\r\n \t d = max - min;\r\n \treturn x === max && includeMax ? x : ((x - min) % d + d) % d + min;\r\n }\r\n\r\n // @function falseFn(): Function\r\n // Returns a function which always returns `false`.\r\n function falseFn() { return false; }\r\n\r\n // @function formatNum(num: Number, precision?: Number|false): Number\r\n // Returns the number `num` rounded with specified `precision`.\r\n // The default `precision` value is 6 decimal places.\r\n // `false` can be passed to skip any processing (can be useful to avoid round-off errors).\r\n function formatNum(num, precision) {\r\n \tif (precision === false) { return num; }\r\n \tvar pow = Math.pow(10, precision === undefined ? 6 : precision);\r\n \treturn Math.round(num * pow) / pow;\r\n }\r\n\r\n // @function trim(str: String): String\r\n // Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)\r\n function trim(str) {\r\n \treturn str.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');\r\n }\r\n\r\n // @function splitWords(str: String): String[]\r\n // Trims and splits the string on whitespace and returns the array of parts.\r\n function splitWords(str) {\r\n \treturn trim(str).split(/\\s+/);\r\n }\r\n\r\n // @function setOptions(obj: Object, options: Object): Object\r\n // Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.\r\n function setOptions(obj, options) {\r\n \tif (!Object.prototype.hasOwnProperty.call(obj, 'options')) {\r\n \t\tobj.options = obj.options ? create$2(obj.options) : {};\r\n \t}\r\n \tfor (var i in options) {\r\n \t\tobj.options[i] = options[i];\r\n \t}\r\n \treturn obj.options;\r\n }\r\n\r\n // @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String\r\n // Converts an object into a parameter URL string, e.g. `{a: \"foo\", b: \"bar\"}`\r\n // translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will\r\n // be appended at the end. If `uppercase` is `true`, the parameter names will\r\n // be uppercased (e.g. `'?A=foo&B=bar'`)\r\n function getParamString(obj, existingUrl, uppercase) {\r\n \tvar params = [];\r\n \tfor (var i in obj) {\r\n \t\tparams.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));\r\n \t}\r\n \treturn ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');\r\n }\r\n\r\n var templateRe = /\\{ *([\\w_ -]+) *\\}/g;\r\n\r\n // @function template(str: String, data: Object): String\r\n // Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`\r\n // and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string\r\n // `('Hello foo, bar')`. You can also specify functions instead of strings for\r\n // data values — they will be evaluated passing `data` as an argument.\r\n function template(str, data) {\r\n \treturn str.replace(templateRe, function (str, key) {\r\n \t\tvar value = data[key];\r\n\r\n \t\tif (value === undefined) {\r\n \t\t\tthrow new Error('No value provided for variable ' + str);\r\n\r\n \t\t} else if (typeof value === 'function') {\r\n \t\t\tvalue = value(data);\r\n \t\t}\r\n \t\treturn value;\r\n \t});\r\n }\r\n\r\n // @function isArray(obj): Boolean\r\n // Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)\r\n var isArray = Array.isArray || function (obj) {\r\n \treturn (Object.prototype.toString.call(obj) === '[object Array]');\r\n };\r\n\r\n // @function indexOf(array: Array, el: Object): Number\r\n // Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)\r\n function indexOf(array, el) {\r\n \tfor (var i = 0; i < array.length; i++) {\r\n \t\tif (array[i] === el) { return i; }\r\n \t}\r\n \treturn -1;\r\n }\r\n\r\n // @property emptyImageUrl: String\r\n // Data URI string containing a base64-encoded empty GIF image.\r\n // Used as a hack to free memory from unused images on WebKit-powered\r\n // mobile devices (by setting image `src` to this string).\r\n var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';\r\n\r\n // inspired by https://paulirish.com/2011/requestanimationframe-for-smart-animating/\r\n\r\n function getPrefixed(name) {\r\n \treturn window['webkit' + name] || window['moz' + name] || window['ms' + name];\r\n }\r\n\r\n var lastTime = 0;\r\n\r\n // fallback for IE 7-8\r\n function timeoutDefer(fn) {\r\n \tvar time = +new Date(),\r\n \t timeToCall = Math.max(0, 16 - (time - lastTime));\r\n\r\n \tlastTime = time + timeToCall;\r\n \treturn window.setTimeout(fn, timeToCall);\r\n }\r\n\r\n var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;\r\n var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||\r\n \t\tgetPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };\r\n\r\n // @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number\r\n // Schedules `fn` to be executed when the browser repaints. `fn` is bound to\r\n // `context` if given. When `immediate` is set, `fn` is called immediately if\r\n // the browser doesn't have native support for\r\n // [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),\r\n // otherwise it's delayed. Returns a request ID that can be used to cancel the request.\r\n function requestAnimFrame(fn, context, immediate) {\r\n \tif (immediate && requestFn === timeoutDefer) {\r\n \t\tfn.call(context);\r\n \t} else {\r\n \t\treturn requestFn.call(window, bind(fn, context));\r\n \t}\r\n }\r\n\r\n // @function cancelAnimFrame(id: Number): undefined\r\n // Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).\r\n function cancelAnimFrame(id) {\r\n \tif (id) {\r\n \t\tcancelFn.call(window, id);\r\n \t}\r\n }\n\n var Util = {\n __proto__: null,\n extend: extend,\n create: create$2,\n bind: bind,\n get lastId () { return lastId; },\n stamp: stamp,\n throttle: throttle,\n wrapNum: wrapNum,\n falseFn: falseFn,\n formatNum: formatNum,\n trim: trim,\n splitWords: splitWords,\n setOptions: setOptions,\n getParamString: getParamString,\n template: template,\n isArray: isArray,\n indexOf: indexOf,\n emptyImageUrl: emptyImageUrl,\n requestFn: requestFn,\n cancelFn: cancelFn,\n requestAnimFrame: requestAnimFrame,\n cancelAnimFrame: cancelAnimFrame\n };\n\n // @class Class\r\n // @aka L.Class\r\n\r\n // @section\r\n // @uninheritable\r\n\r\n // Thanks to John Resig and Dean Edwards for inspiration!\r\n\r\n function Class() {}\r\n\r\n Class.extend = function (props) {\r\n\r\n \t// @function extend(props: Object): Function\r\n \t// [Extends the current class](#class-inheritance) given the properties to be included.\r\n \t// Returns a Javascript function that is a class constructor (to be called with `new`).\r\n \tvar NewClass = function () {\r\n\r\n \t\tsetOptions(this);\r\n\r\n \t\t// call the constructor\r\n \t\tif (this.initialize) {\r\n \t\t\tthis.initialize.apply(this, arguments);\r\n \t\t}\r\n\r\n \t\t// call all constructor hooks\r\n \t\tthis.callInitHooks();\r\n \t};\r\n\r\n \tvar parentProto = NewClass.__super__ = this.prototype;\r\n\r\n \tvar proto = create$2(parentProto);\r\n \tproto.constructor = NewClass;\r\n\r\n \tNewClass.prototype = proto;\r\n\r\n \t// inherit parent's statics\r\n \tfor (var i in this) {\r\n \t\tif (Object.prototype.hasOwnProperty.call(this, i) && i !== 'prototype' && i !== '__super__') {\r\n \t\t\tNewClass[i] = this[i];\r\n \t\t}\r\n \t}\r\n\r\n \t// mix static properties into the class\r\n \tif (props.statics) {\r\n \t\textend(NewClass, props.statics);\r\n \t}\r\n\r\n \t// mix includes into the prototype\r\n \tif (props.includes) {\r\n \t\tcheckDeprecatedMixinEvents(props.includes);\r\n \t\textend.apply(null, [proto].concat(props.includes));\r\n \t}\r\n\r\n \t// mix given properties into the prototype\r\n \textend(proto, props);\r\n \tdelete proto.statics;\r\n \tdelete proto.includes;\r\n\r\n \t// merge options\r\n \tif (proto.options) {\r\n \t\tproto.options = parentProto.options ? create$2(parentProto.options) : {};\r\n \t\textend(proto.options, props.options);\r\n \t}\r\n\r\n \tproto._initHooks = [];\r\n\r\n \t// add method for calling all hooks\r\n \tproto.callInitHooks = function () {\r\n\r\n \t\tif (this._initHooksCalled) { return; }\r\n\r\n \t\tif (parentProto.callInitHooks) {\r\n \t\t\tparentProto.callInitHooks.call(this);\r\n \t\t}\r\n\r\n \t\tthis._initHooksCalled = true;\r\n\r\n \t\tfor (var i = 0, len = proto._initHooks.length; i < len; i++) {\r\n \t\t\tproto._initHooks[i].call(this);\r\n \t\t}\r\n \t};\r\n\r\n \treturn NewClass;\r\n };\r\n\r\n\r\n // @function include(properties: Object): this\r\n // [Includes a mixin](#class-includes) into the current class.\r\n Class.include = function (props) {\r\n \tvar parentOptions = this.prototype.options;\r\n \textend(this.prototype, props);\r\n \tif (props.options) {\r\n \t\tthis.prototype.options = parentOptions;\r\n \t\tthis.mergeOptions(props.options);\r\n \t}\r\n \treturn this;\r\n };\r\n\r\n // @function mergeOptions(options: Object): this\r\n // [Merges `options`](#class-options) into the defaults of the class.\r\n Class.mergeOptions = function (options) {\r\n \textend(this.prototype.options, options);\r\n \treturn this;\r\n };\r\n\r\n // @function addInitHook(fn: Function): this\r\n // Adds a [constructor hook](#class-constructor-hooks) to the class.\r\n Class.addInitHook = function (fn) { // (Function) || (String, args...)\r\n \tvar args = Array.prototype.slice.call(arguments, 1);\r\n\r\n \tvar init = typeof fn === 'function' ? fn : function () {\r\n \t\tthis[fn].apply(this, args);\r\n \t};\r\n\r\n \tthis.prototype._initHooks = this.prototype._initHooks || [];\r\n \tthis.prototype._initHooks.push(init);\r\n \treturn this;\r\n };\r\n\r\n function checkDeprecatedMixinEvents(includes) {\r\n \t/* global L: true */\r\n \tif (typeof L === 'undefined' || !L || !L.Mixin) { return; }\r\n\r\n \tincludes = isArray(includes) ? includes : [includes];\r\n\r\n \tfor (var i = 0; i < includes.length; i++) {\r\n \t\tif (includes[i] === L.Mixin.Events) {\r\n \t\t\tconsole.warn('Deprecated include of L.Mixin.Events: ' +\r\n \t\t\t\t'this property will be removed in future releases, ' +\r\n \t\t\t\t'please inherit from L.Evented instead.', new Error().stack);\r\n \t\t}\r\n \t}\r\n }\n\n /*\r\n * @class Evented\r\n * @aka L.Evented\r\n * @inherits Class\r\n *\r\n * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * map.on('click', function(e) {\r\n * \talert(e.latlng);\r\n * } );\r\n * ```\r\n *\r\n * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:\r\n *\r\n * ```js\r\n * function onClick(e) { ... }\r\n *\r\n * map.on('click', onClick);\r\n * map.off('click', onClick);\r\n * ```\r\n */\r\n\r\n var Events = {\r\n \t/* @method on(type: String, fn: Function, context?: Object): this\r\n \t * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).\r\n \t *\r\n \t * @alternative\r\n \t * @method on(eventMap: Object): this\r\n \t * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`\r\n \t */\r\n \ton: function (types, fn, context) {\r\n\r\n \t\t// types can be a map of types/handlers\r\n \t\tif (typeof types === 'object') {\r\n \t\t\tfor (var type in types) {\r\n \t\t\t\t// we don't process space-separated events here for performance;\r\n \t\t\t\t// it's a hot path since Layer uses the on(obj) syntax\r\n \t\t\t\tthis._on(type, types[type], fn);\r\n \t\t\t}\r\n\r\n \t\t} else {\r\n \t\t\t// types can be a string of space-separated words\r\n \t\t\ttypes = splitWords(types);\r\n\r\n \t\t\tfor (var i = 0, len = types.length; i < len; i++) {\r\n \t\t\t\tthis._on(types[i], fn, context);\r\n \t\t\t}\r\n \t\t}\r\n\r\n \t\treturn this;\r\n \t},\r\n\r\n \t/* @method off(type: String, fn?: Function, context?: Object): this\r\n \t * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.\r\n \t *\r\n \t * @alternative\r\n \t * @method off(eventMap: Object): this\r\n \t * Removes a set of type/listener pairs.\r\n \t *\r\n \t * @alternative\r\n \t * @method off: this\r\n \t * Removes all listeners to all events on the object. This includes implicitly attached events.\r\n \t */\r\n \toff: function (types, fn, context) {\r\n\r\n \t\tif (!arguments.length) {\r\n \t\t\t// clear all listeners if called without arguments\r\n \t\t\tdelete this._events;\r\n\r\n \t\t} else if (typeof types === 'object') {\r\n \t\t\tfor (var type in types) {\r\n \t\t\t\tthis._off(type, types[type], fn);\r\n \t\t\t}\r\n\r\n \t\t} else {\r\n \t\t\ttypes = splitWords(types);\r\n\r\n \t\t\tvar removeAll = arguments.length === 1;\r\n \t\t\tfor (var i = 0, len = types.length; i < len; i++) {\r\n \t\t\t\tif (removeAll) {\r\n \t\t\t\t\tthis._off(types[i]);\r\n \t\t\t\t} else {\r\n \t\t\t\t\tthis._off(types[i], fn, context);\r\n \t\t\t\t}\r\n \t\t\t}\r\n \t\t}\r\n\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// attach listener (without syntactic sugar now)\r\n \t_on: function (type, fn, context, _once) {\r\n \t\tif (typeof fn !== 'function') {\r\n \t\t\tconsole.warn('wrong listener type: ' + typeof fn);\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\t// check if fn already there\r\n \t\tif (this._listens(type, fn, context) !== false) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tif (context === this) {\r\n \t\t\t// Less memory footprint.\r\n \t\t\tcontext = undefined;\r\n \t\t}\r\n\r\n \t\tvar newListener = {fn: fn, ctx: context};\r\n \t\tif (_once) {\r\n \t\t\tnewListener.once = true;\r\n \t\t}\r\n\r\n \t\tthis._events = this._events || {};\r\n \t\tthis._events[type] = this._events[type] || [];\r\n \t\tthis._events[type].push(newListener);\r\n \t},\r\n\r\n \t_off: function (type, fn, context) {\r\n \t\tvar listeners,\r\n \t\t i,\r\n \t\t len;\r\n\r\n \t\tif (!this._events) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tlisteners = this._events[type];\r\n \t\tif (!listeners) {\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tif (arguments.length === 1) { // remove all\r\n \t\t\tif (this._firingCount) {\r\n \t\t\t\t// Set all removed listeners to noop\r\n \t\t\t\t// so they are not called if remove happens in fire\r\n \t\t\t\tfor (i = 0, len = listeners.length; i < len; i++) {\r\n \t\t\t\t\tlisteners[i].fn = falseFn;\r\n \t\t\t\t}\r\n \t\t\t}\r\n \t\t\t// clear all listeners for a type if function isn't specified\r\n \t\t\tdelete this._events[type];\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tif (typeof fn !== 'function') {\r\n \t\t\tconsole.warn('wrong listener type: ' + typeof fn);\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\t// find fn and remove it\r\n \t\tvar index = this._listens(type, fn, context);\r\n \t\tif (index !== false) {\r\n \t\t\tvar listener = listeners[index];\r\n \t\t\tif (this._firingCount) {\r\n \t\t\t\t// set the removed listener to noop so that's not called if remove happens in fire\r\n \t\t\t\tlistener.fn = falseFn;\r\n\r\n \t\t\t\t/* copy array in case events are being fired */\r\n \t\t\t\tthis._events[type] = listeners = listeners.slice();\r\n \t\t\t}\r\n \t\t\tlisteners.splice(index, 1);\r\n \t\t}\r\n \t},\r\n\r\n \t// @method fire(type: String, data?: Object, propagate?: Boolean): this\r\n \t// Fires an event of the specified type. You can optionally provide a data\r\n \t// object — the first argument of the listener function will contain its\r\n \t// properties. The event can optionally be propagated to event parents.\r\n \tfire: function (type, data, propagate) {\r\n \t\tif (!this.listens(type, propagate)) { return this; }\r\n\r\n \t\tvar event = extend({}, data, {\r\n \t\t\ttype: type,\r\n \t\t\ttarget: this,\r\n \t\t\tsourceTarget: data && data.sourceTarget || this\r\n \t\t});\r\n\r\n \t\tif (this._events) {\r\n \t\t\tvar listeners = this._events[type];\r\n \t\t\tif (listeners) {\r\n \t\t\t\tthis._firingCount = (this._firingCount + 1) || 1;\r\n \t\t\t\tfor (var i = 0, len = listeners.length; i < len; i++) {\r\n \t\t\t\t\tvar l = listeners[i];\r\n \t\t\t\t\t// off overwrites l.fn, so we need to copy fn to a var\r\n \t\t\t\t\tvar fn = l.fn;\r\n \t\t\t\t\tif (l.once) {\r\n \t\t\t\t\t\tthis.off(type, fn, l.ctx);\r\n \t\t\t\t\t}\r\n \t\t\t\t\tfn.call(l.ctx || this, event);\r\n \t\t\t\t}\r\n\r\n \t\t\t\tthis._firingCount--;\r\n \t\t\t}\r\n \t\t}\r\n\r\n \t\tif (propagate) {\r\n \t\t\t// propagate the event to parents (set with addEventParent)\r\n \t\t\tthis._propagateEvent(event);\r\n \t\t}\r\n\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method listens(type: String, propagate?: Boolean): Boolean\r\n \t// @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean\r\n \t// Returns `true` if a particular event type has any listeners attached to it.\r\n \t// The verification can optionally be propagated, it will return `true` if parents have the listener attached to it.\r\n \tlistens: function (type, fn, context, propagate) {\r\n \t\tif (typeof type !== 'string') {\r\n \t\t\tconsole.warn('\"string\" type argument expected');\r\n \t\t}\r\n\r\n \t\t// we don't overwrite the input `fn` value, because we need to use it for propagation\r\n \t\tvar _fn = fn;\r\n \t\tif (typeof fn !== 'function') {\r\n \t\t\tpropagate = !!fn;\r\n \t\t\t_fn = undefined;\r\n \t\t\tcontext = undefined;\r\n \t\t}\r\n\r\n \t\tvar listeners = this._events && this._events[type];\r\n \t\tif (listeners && listeners.length) {\r\n \t\t\tif (this._listens(type, _fn, context) !== false) {\r\n \t\t\t\treturn true;\r\n \t\t\t}\r\n \t\t}\r\n\r\n \t\tif (propagate) {\r\n \t\t\t// also check parents for listeners if event propagates\r\n \t\t\tfor (var id in this._eventParents) {\r\n \t\t\t\tif (this._eventParents[id].listens(type, fn, context, propagate)) { return true; }\r\n \t\t\t}\r\n \t\t}\r\n \t\treturn false;\r\n \t},\r\n\r\n \t// returns the index (number) or false\r\n \t_listens: function (type, fn, context) {\r\n \t\tif (!this._events) {\r\n \t\t\treturn false;\r\n \t\t}\r\n\r\n \t\tvar listeners = this._events[type] || [];\r\n \t\tif (!fn) {\r\n \t\t\treturn !!listeners.length;\r\n \t\t}\r\n\r\n \t\tif (context === this) {\r\n \t\t\t// Less memory footprint.\r\n \t\t\tcontext = undefined;\r\n \t\t}\r\n\r\n \t\tfor (var i = 0, len = listeners.length; i < len; i++) {\r\n \t\t\tif (listeners[i].fn === fn && listeners[i].ctx === context) {\r\n \t\t\t\treturn i;\r\n \t\t\t}\r\n \t\t}\r\n \t\treturn false;\r\n\r\n \t},\r\n\r\n \t// @method once(…): this\r\n \t// Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.\r\n \tonce: function (types, fn, context) {\r\n\r\n \t\t// types can be a map of types/handlers\r\n \t\tif (typeof types === 'object') {\r\n \t\t\tfor (var type in types) {\r\n \t\t\t\t// we don't process space-separated events here for performance;\r\n \t\t\t\t// it's a hot path since Layer uses the on(obj) syntax\r\n \t\t\t\tthis._on(type, types[type], fn, true);\r\n \t\t\t}\r\n\r\n \t\t} else {\r\n \t\t\t// types can be a string of space-separated words\r\n \t\t\ttypes = splitWords(types);\r\n\r\n \t\t\tfor (var i = 0, len = types.length; i < len; i++) {\r\n \t\t\t\tthis._on(types[i], fn, context, true);\r\n \t\t\t}\r\n \t\t}\r\n\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method addEventParent(obj: Evented): this\r\n \t// Adds an event parent - an `Evented` that will receive propagated events\r\n \taddEventParent: function (obj) {\r\n \t\tthis._eventParents = this._eventParents || {};\r\n \t\tthis._eventParents[stamp(obj)] = obj;\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method removeEventParent(obj: Evented): this\r\n \t// Removes an event parent, so it will stop receiving propagated events\r\n \tremoveEventParent: function (obj) {\r\n \t\tif (this._eventParents) {\r\n \t\t\tdelete this._eventParents[stamp(obj)];\r\n \t\t}\r\n \t\treturn this;\r\n \t},\r\n\r\n \t_propagateEvent: function (e) {\r\n \t\tfor (var id in this._eventParents) {\r\n \t\t\tthis._eventParents[id].fire(e.type, extend({\r\n \t\t\t\tlayer: e.target,\r\n \t\t\t\tpropagatedFrom: e.target\r\n \t\t\t}, e), true);\r\n \t\t}\r\n \t}\r\n };\r\n\r\n // aliases; we should ditch those eventually\r\n\r\n // @method addEventListener(…): this\r\n // Alias to [`on(…)`](#evented-on)\r\n Events.addEventListener = Events.on;\r\n\r\n // @method removeEventListener(…): this\r\n // Alias to [`off(…)`](#evented-off)\r\n\r\n // @method clearAllEventListeners(…): this\r\n // Alias to [`off()`](#evented-off)\r\n Events.removeEventListener = Events.clearAllEventListeners = Events.off;\r\n\r\n // @method addOneTimeEventListener(…): this\r\n // Alias to [`once(…)`](#evented-once)\r\n Events.addOneTimeEventListener = Events.once;\r\n\r\n // @method fireEvent(…): this\r\n // Alias to [`fire(…)`](#evented-fire)\r\n Events.fireEvent = Events.fire;\r\n\r\n // @method hasEventListeners(…): Boolean\r\n // Alias to [`listens(…)`](#evented-listens)\r\n Events.hasEventListeners = Events.listens;\r\n\r\n var Evented = Class.extend(Events);\n\n /*\r\n * @class Point\r\n * @aka L.Point\r\n *\r\n * Represents a point with `x` and `y` coordinates in pixels.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var point = L.point(200, 300);\r\n * ```\r\n *\r\n * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:\r\n *\r\n * ```js\r\n * map.panBy([200, 300]);\r\n * map.panBy(L.point(200, 300));\r\n * ```\r\n *\r\n * Note that `Point` does not inherit from Leaflet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\n function Point(x, y, round) {\r\n \t// @property x: Number; The `x` coordinate of the point\r\n \tthis.x = (round ? Math.round(x) : x);\r\n \t// @property y: Number; The `y` coordinate of the point\r\n \tthis.y = (round ? Math.round(y) : y);\r\n }\r\n\r\n var trunc = Math.trunc || function (v) {\r\n \treturn v > 0 ? Math.floor(v) : Math.ceil(v);\r\n };\r\n\r\n Point.prototype = {\r\n\r\n \t// @method clone(): Point\r\n \t// Returns a copy of the current point.\r\n \tclone: function () {\r\n \t\treturn new Point(this.x, this.y);\r\n \t},\r\n\r\n \t// @method add(otherPoint: Point): Point\r\n \t// Returns the result of addition of the current and the given points.\r\n \tadd: function (point) {\r\n \t\t// non-destructive, returns a new point\r\n \t\treturn this.clone()._add(toPoint(point));\r\n \t},\r\n\r\n \t_add: function (point) {\r\n \t\t// destructive, used directly for performance in situations where it's safe to modify existing point\r\n \t\tthis.x += point.x;\r\n \t\tthis.y += point.y;\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method subtract(otherPoint: Point): Point\r\n \t// Returns the result of subtraction of the given point from the current.\r\n \tsubtract: function (point) {\r\n \t\treturn this.clone()._subtract(toPoint(point));\r\n \t},\r\n\r\n \t_subtract: function (point) {\r\n \t\tthis.x -= point.x;\r\n \t\tthis.y -= point.y;\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method divideBy(num: Number): Point\r\n \t// Returns the result of division of the current point by the given number.\r\n \tdivideBy: function (num) {\r\n \t\treturn this.clone()._divideBy(num);\r\n \t},\r\n\r\n \t_divideBy: function (num) {\r\n \t\tthis.x /= num;\r\n \t\tthis.y /= num;\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method multiplyBy(num: Number): Point\r\n \t// Returns the result of multiplication of the current point by the given number.\r\n \tmultiplyBy: function (num) {\r\n \t\treturn this.clone()._multiplyBy(num);\r\n \t},\r\n\r\n \t_multiplyBy: function (num) {\r\n \t\tthis.x *= num;\r\n \t\tthis.y *= num;\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method scaleBy(scale: Point): Point\r\n \t// Multiply each coordinate of the current point by each coordinate of\r\n \t// `scale`. In linear algebra terms, multiply the point by the\r\n \t// [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)\r\n \t// defined by `scale`.\r\n \tscaleBy: function (point) {\r\n \t\treturn new Point(this.x * point.x, this.y * point.y);\r\n \t},\r\n\r\n \t// @method unscaleBy(scale: Point): Point\r\n \t// Inverse of `scaleBy`. Divide each coordinate of the current point by\r\n \t// each coordinate of `scale`.\r\n \tunscaleBy: function (point) {\r\n \t\treturn new Point(this.x / point.x, this.y / point.y);\r\n \t},\r\n\r\n \t// @method round(): Point\r\n \t// Returns a copy of the current point with rounded coordinates.\r\n \tround: function () {\r\n \t\treturn this.clone()._round();\r\n \t},\r\n\r\n \t_round: function () {\r\n \t\tthis.x = Math.round(this.x);\r\n \t\tthis.y = Math.round(this.y);\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method floor(): Point\r\n \t// Returns a copy of the current point with floored coordinates (rounded down).\r\n \tfloor: function () {\r\n \t\treturn this.clone()._floor();\r\n \t},\r\n\r\n \t_floor: function () {\r\n \t\tthis.x = Math.floor(this.x);\r\n \t\tthis.y = Math.floor(this.y);\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method ceil(): Point\r\n \t// Returns a copy of the current point with ceiled coordinates (rounded up).\r\n \tceil: function () {\r\n \t\treturn this.clone()._ceil();\r\n \t},\r\n\r\n \t_ceil: function () {\r\n \t\tthis.x = Math.ceil(this.x);\r\n \t\tthis.y = Math.ceil(this.y);\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method trunc(): Point\r\n \t// Returns a copy of the current point with truncated coordinates (rounded towards zero).\r\n \ttrunc: function () {\r\n \t\treturn this.clone()._trunc();\r\n \t},\r\n\r\n \t_trunc: function () {\r\n \t\tthis.x = trunc(this.x);\r\n \t\tthis.y = trunc(this.y);\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method distanceTo(otherPoint: Point): Number\r\n \t// Returns the cartesian distance between the current and the given points.\r\n \tdistanceTo: function (point) {\r\n \t\tpoint = toPoint(point);\r\n\r\n \t\tvar x = point.x - this.x,\r\n \t\t y = point.y - this.y;\r\n\r\n \t\treturn Math.sqrt(x * x + y * y);\r\n \t},\r\n\r\n \t// @method equals(otherPoint: Point): Boolean\r\n \t// Returns `true` if the given point has the same coordinates.\r\n \tequals: function (point) {\r\n \t\tpoint = toPoint(point);\r\n\r\n \t\treturn point.x === this.x &&\r\n \t\t point.y === this.y;\r\n \t},\r\n\r\n \t// @method contains(otherPoint: Point): Boolean\r\n \t// Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).\r\n \tcontains: function (point) {\r\n \t\tpoint = toPoint(point);\r\n\r\n \t\treturn Math.abs(point.x) <= Math.abs(this.x) &&\r\n \t\t Math.abs(point.y) <= Math.abs(this.y);\r\n \t},\r\n\r\n \t// @method toString(): String\r\n \t// Returns a string representation of the point for debugging purposes.\r\n \ttoString: function () {\r\n \t\treturn 'Point(' +\r\n \t\t formatNum(this.x) + ', ' +\r\n \t\t formatNum(this.y) + ')';\r\n \t}\r\n };\r\n\r\n // @factory L.point(x: Number, y: Number, round?: Boolean)\r\n // Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.\r\n\r\n // @alternative\r\n // @factory L.point(coords: Number[])\r\n // Expects an array of the form `[x, y]` instead.\r\n\r\n // @alternative\r\n // @factory L.point(coords: Object)\r\n // Expects a plain object of the form `{x: Number, y: Number}` instead.\r\n function toPoint(x, y, round) {\r\n \tif (x instanceof Point) {\r\n \t\treturn x;\r\n \t}\r\n \tif (isArray(x)) {\r\n \t\treturn new Point(x[0], x[1]);\r\n \t}\r\n \tif (x === undefined || x === null) {\r\n \t\treturn x;\r\n \t}\r\n \tif (typeof x === 'object' && 'x' in x && 'y' in x) {\r\n \t\treturn new Point(x.x, x.y);\r\n \t}\r\n \treturn new Point(x, y, round);\r\n }\n\n /*\r\n * @class Bounds\r\n * @aka L.Bounds\r\n *\r\n * Represents a rectangular area in pixel coordinates.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var p1 = L.point(10, 10),\r\n * p2 = L.point(40, 60),\r\n * bounds = L.bounds(p1, p2);\r\n * ```\r\n *\r\n * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r\n *\r\n * ```js\r\n * otherBounds.intersects([[10, 10], [40, 60]]);\r\n * ```\r\n *\r\n * Note that `Bounds` does not inherit from Leaflet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\n function Bounds(a, b) {\r\n \tif (!a) { return; }\r\n\r\n \tvar points = b ? [a, b] : a;\r\n\r\n \tfor (var i = 0, len = points.length; i < len; i++) {\r\n \t\tthis.extend(points[i]);\r\n \t}\r\n }\r\n\r\n Bounds.prototype = {\r\n \t// @method extend(point: Point): this\r\n \t// Extends the bounds to contain the given point.\r\n\r\n \t// @alternative\r\n \t// @method extend(otherBounds: Bounds): this\r\n \t// Extend the bounds to contain the given bounds\r\n \textend: function (obj) {\r\n \t\tvar min2, max2;\r\n \t\tif (!obj) { return this; }\r\n\r\n \t\tif (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) {\r\n \t\t\tmin2 = max2 = toPoint(obj);\r\n \t\t} else {\r\n \t\t\tobj = toBounds(obj);\r\n \t\t\tmin2 = obj.min;\r\n \t\t\tmax2 = obj.max;\r\n\r\n \t\t\tif (!min2 || !max2) { return this; }\r\n \t\t}\r\n\r\n \t\t// @property min: Point\r\n \t\t// The top left corner of the rectangle.\r\n \t\t// @property max: Point\r\n \t\t// The bottom right corner of the rectangle.\r\n \t\tif (!this.min && !this.max) {\r\n \t\t\tthis.min = min2.clone();\r\n \t\t\tthis.max = max2.clone();\r\n \t\t} else {\r\n \t\t\tthis.min.x = Math.min(min2.x, this.min.x);\r\n \t\t\tthis.max.x = Math.max(max2.x, this.max.x);\r\n \t\t\tthis.min.y = Math.min(min2.y, this.min.y);\r\n \t\t\tthis.max.y = Math.max(max2.y, this.max.y);\r\n \t\t}\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method getCenter(round?: Boolean): Point\r\n \t// Returns the center point of the bounds.\r\n \tgetCenter: function (round) {\r\n \t\treturn toPoint(\r\n \t\t (this.min.x + this.max.x) / 2,\r\n \t\t (this.min.y + this.max.y) / 2, round);\r\n \t},\r\n\r\n \t// @method getBottomLeft(): Point\r\n \t// Returns the bottom-left point of the bounds.\r\n \tgetBottomLeft: function () {\r\n \t\treturn toPoint(this.min.x, this.max.y);\r\n \t},\r\n\r\n \t// @method getTopRight(): Point\r\n \t// Returns the top-right point of the bounds.\r\n \tgetTopRight: function () { // -> Point\r\n \t\treturn toPoint(this.max.x, this.min.y);\r\n \t},\r\n\r\n \t// @method getTopLeft(): Point\r\n \t// Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).\r\n \tgetTopLeft: function () {\r\n \t\treturn this.min; // left, top\r\n \t},\r\n\r\n \t// @method getBottomRight(): Point\r\n \t// Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).\r\n \tgetBottomRight: function () {\r\n \t\treturn this.max; // right, bottom\r\n \t},\r\n\r\n \t// @method getSize(): Point\r\n \t// Returns the size of the given bounds\r\n \tgetSize: function () {\r\n \t\treturn this.max.subtract(this.min);\r\n \t},\r\n\r\n \t// @method contains(otherBounds: Bounds): Boolean\r\n \t// Returns `true` if the rectangle contains the given one.\r\n \t// @alternative\r\n \t// @method contains(point: Point): Boolean\r\n \t// Returns `true` if the rectangle contains the given point.\r\n \tcontains: function (obj) {\r\n \t\tvar min, max;\r\n\r\n \t\tif (typeof obj[0] === 'number' || obj instanceof Point) {\r\n \t\t\tobj = toPoint(obj);\r\n \t\t} else {\r\n \t\t\tobj = toBounds(obj);\r\n \t\t}\r\n\r\n \t\tif (obj instanceof Bounds) {\r\n \t\t\tmin = obj.min;\r\n \t\t\tmax = obj.max;\r\n \t\t} else {\r\n \t\t\tmin = max = obj;\r\n \t\t}\r\n\r\n \t\treturn (min.x >= this.min.x) &&\r\n \t\t (max.x <= this.max.x) &&\r\n \t\t (min.y >= this.min.y) &&\r\n \t\t (max.y <= this.max.y);\r\n \t},\r\n\r\n \t// @method intersects(otherBounds: Bounds): Boolean\r\n \t// Returns `true` if the rectangle intersects the given bounds. Two bounds\r\n \t// intersect if they have at least one point in common.\r\n \tintersects: function (bounds) { // (Bounds) -> Boolean\r\n \t\tbounds = toBounds(bounds);\r\n\r\n \t\tvar min = this.min,\r\n \t\t max = this.max,\r\n \t\t min2 = bounds.min,\r\n \t\t max2 = bounds.max,\r\n \t\t xIntersects = (max2.x >= min.x) && (min2.x <= max.x),\r\n \t\t yIntersects = (max2.y >= min.y) && (min2.y <= max.y);\r\n\r\n \t\treturn xIntersects && yIntersects;\r\n \t},\r\n\r\n \t// @method overlaps(otherBounds: Bounds): Boolean\r\n \t// Returns `true` if the rectangle overlaps the given bounds. Two bounds\r\n \t// overlap if their intersection is an area.\r\n \toverlaps: function (bounds) { // (Bounds) -> Boolean\r\n \t\tbounds = toBounds(bounds);\r\n\r\n \t\tvar min = this.min,\r\n \t\t max = this.max,\r\n \t\t min2 = bounds.min,\r\n \t\t max2 = bounds.max,\r\n \t\t xOverlaps = (max2.x > min.x) && (min2.x < max.x),\r\n \t\t yOverlaps = (max2.y > min.y) && (min2.y < max.y);\r\n\r\n \t\treturn xOverlaps && yOverlaps;\r\n \t},\r\n\r\n \t// @method isValid(): Boolean\r\n \t// Returns `true` if the bounds are properly initialized.\r\n \tisValid: function () {\r\n \t\treturn !!(this.min && this.max);\r\n \t},\r\n\r\n\r\n \t// @method pad(bufferRatio: Number): Bounds\r\n \t// Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\r\n \t// For example, a ratio of 0.5 extends the bounds by 50% in each direction.\r\n \t// Negative values will retract the bounds.\r\n \tpad: function (bufferRatio) {\r\n \t\tvar min = this.min,\r\n \t\tmax = this.max,\r\n \t\theightBuffer = Math.abs(min.x - max.x) * bufferRatio,\r\n \t\twidthBuffer = Math.abs(min.y - max.y) * bufferRatio;\r\n\r\n\r\n \t\treturn toBounds(\r\n \t\t\ttoPoint(min.x - heightBuffer, min.y - widthBuffer),\r\n \t\t\ttoPoint(max.x + heightBuffer, max.y + widthBuffer));\r\n \t},\r\n\r\n\r\n \t// @method equals(otherBounds: Bounds): Boolean\r\n \t// Returns `true` if the rectangle is equivalent to the given bounds.\r\n \tequals: function (bounds) {\r\n \t\tif (!bounds) { return false; }\r\n\r\n \t\tbounds = toBounds(bounds);\r\n\r\n \t\treturn this.min.equals(bounds.getTopLeft()) &&\r\n \t\t\tthis.max.equals(bounds.getBottomRight());\r\n \t},\r\n };\r\n\r\n\r\n // @factory L.bounds(corner1: Point, corner2: Point)\r\n // Creates a Bounds object from two corners coordinate pairs.\r\n // @alternative\r\n // @factory L.bounds(points: Point[])\r\n // Creates a Bounds object from the given array of points.\r\n function toBounds(a, b) {\r\n \tif (!a || a instanceof Bounds) {\r\n \t\treturn a;\r\n \t}\r\n \treturn new Bounds(a, b);\r\n }\n\n /*\r\n * @class LatLngBounds\r\n * @aka L.LatLngBounds\r\n *\r\n * Represents a rectangular geographical area on a map.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var corner1 = L.latLng(40.712, -74.227),\r\n * corner2 = L.latLng(40.774, -74.125),\r\n * bounds = L.latLngBounds(corner1, corner2);\r\n * ```\r\n *\r\n * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r\n *\r\n * ```js\r\n * map.fitBounds([\r\n * \t[40.712, -74.227],\r\n * \t[40.774, -74.125]\r\n * ]);\r\n * ```\r\n *\r\n * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.\r\n *\r\n * Note that `LatLngBounds` does not inherit from Leaflet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\n function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[])\r\n \tif (!corner1) { return; }\r\n\r\n \tvar latlngs = corner2 ? [corner1, corner2] : corner1;\r\n\r\n \tfor (var i = 0, len = latlngs.length; i < len; i++) {\r\n \t\tthis.extend(latlngs[i]);\r\n \t}\r\n }\r\n\r\n LatLngBounds.prototype = {\r\n\r\n \t// @method extend(latlng: LatLng): this\r\n \t// Extend the bounds to contain the given point\r\n\r\n \t// @alternative\r\n \t// @method extend(otherBounds: LatLngBounds): this\r\n \t// Extend the bounds to contain the given bounds\r\n \textend: function (obj) {\r\n \t\tvar sw = this._southWest,\r\n \t\t ne = this._northEast,\r\n \t\t sw2, ne2;\r\n\r\n \t\tif (obj instanceof LatLng) {\r\n \t\t\tsw2 = obj;\r\n \t\t\tne2 = obj;\r\n\r\n \t\t} else if (obj instanceof LatLngBounds) {\r\n \t\t\tsw2 = obj._southWest;\r\n \t\t\tne2 = obj._northEast;\r\n\r\n \t\t\tif (!sw2 || !ne2) { return this; }\r\n\r\n \t\t} else {\r\n \t\t\treturn obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;\r\n \t\t}\r\n\r\n \t\tif (!sw && !ne) {\r\n \t\t\tthis._southWest = new LatLng(sw2.lat, sw2.lng);\r\n \t\t\tthis._northEast = new LatLng(ne2.lat, ne2.lng);\r\n \t\t} else {\r\n \t\t\tsw.lat = Math.min(sw2.lat, sw.lat);\r\n \t\t\tsw.lng = Math.min(sw2.lng, sw.lng);\r\n \t\t\tne.lat = Math.max(ne2.lat, ne.lat);\r\n \t\t\tne.lng = Math.max(ne2.lng, ne.lng);\r\n \t\t}\r\n\r\n \t\treturn this;\r\n \t},\r\n\r\n \t// @method pad(bufferRatio: Number): LatLngBounds\r\n \t// Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\r\n \t// For example, a ratio of 0.5 extends the bounds by 50% in each direction.\r\n \t// Negative values will retract the bounds.\r\n \tpad: function (bufferRatio) {\r\n \t\tvar sw = this._southWest,\r\n \t\t ne = this._northEast,\r\n \t\t heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,\r\n \t\t widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\r\n\r\n \t\treturn new LatLngBounds(\r\n \t\t new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),\r\n \t\t new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));\r\n \t},\r\n\r\n \t// @method getCenter(): LatLng\r\n \t// Returns the center point of the bounds.\r\n \tgetCenter: function () {\r\n \t\treturn new LatLng(\r\n \t\t (this._southWest.lat + this._northEast.lat) / 2,\r\n \t\t (this._southWest.lng + this._northEast.lng) / 2);\r\n \t},\r\n\r\n \t// @method getSouthWest(): LatLng\r\n \t// Returns the south-west point of the bounds.\r\n \tgetSouthWest: function () {\r\n \t\treturn this._southWest;\r\n \t},\r\n\r\n \t// @method getNorthEast(): LatLng\r\n \t// Returns the north-east point of the bounds.\r\n \tgetNorthEast: function () {\r\n \t\treturn this._northEast;\r\n \t},\r\n\r\n \t// @method getNorthWest(): LatLng\r\n \t// Returns the north-west point of the bounds.\r\n \tgetNorthWest: function () {\r\n \t\treturn new LatLng(this.getNorth(), this.getWest());\r\n \t},\r\n\r\n \t// @method getSouthEast(): LatLng\r\n \t// Returns the south-east point of the bounds.\r\n \tgetSouthEast: function () {\r\n \t\treturn new LatLng(this.getSouth(), this.getEast());\r\n \t},\r\n\r\n \t// @method getWest(): Number\r\n \t// Returns the west longitude of the bounds\r\n \tgetWest: function () {\r\n \t\treturn this._southWest.lng;\r\n \t},\r\n\r\n \t// @method getSouth(): Number\r\n \t// Returns the south latitude of the bounds\r\n \tgetSouth: function () {\r\n \t\treturn this._southWest.lat;\r\n \t},\r\n\r\n \t// @method getEast(): Number\r\n \t// Returns the east longitude of the bounds\r\n \tgetEast: function () {\r\n \t\treturn this._northEast.lng;\r\n \t},\r\n\r\n \t// @method getNorth(): Number\r\n \t// Returns the north latitude of the bounds\r\n \tgetNorth: function () {\r\n \t\treturn this._northEast.lat;\r\n \t},\r\n\r\n \t// @method contains(otherBounds: LatLngBounds): Boolean\r\n \t// Returns `true` if the rectangle contains the given one.\r\n\r\n \t// @alternative\r\n \t// @method contains (latlng: LatLng): Boolean\r\n \t// Returns `true` if the rectangle contains the given point.\r\n \tcontains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean\r\n \t\tif (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {\r\n \t\t\tobj = toLatLng(obj);\r\n \t\t} else {\r\n \t\t\tobj = toLatLngBounds(obj);\r\n \t\t}\r\n\r\n \t\tvar sw = this._southWest,\r\n \t\t ne = this._northEast,\r\n \t\t sw2, ne2;\r\n\r\n \t\tif (obj instanceof LatLngBounds) {\r\n \t\t\tsw2 = obj.getSouthWest();\r\n \t\t\tne2 = obj.getNorthEast();\r\n \t\t} else {\r\n \t\t\tsw2 = ne2 = obj;\r\n \t\t}\r\n\r\n \t\treturn (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&\r\n \t\t (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);\r\n \t},\r\n\r\n \t// @method intersects(otherBounds: LatLngBounds): Boolean\r\n \t// Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.\r\n \tintersects: function (bounds) {\r\n \t\tbounds = toLatLngBounds(bounds);\r\n\r\n \t\tvar sw = this._southWest,\r\n \t\t ne = this._northEast,\r\n \t\t sw2 = bounds.getSouthWest(),\r\n \t\t ne2 = bounds.getNorthEast(),\r\n\r\n \t\t latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),\r\n \t\t lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);\r\n\r\n \t\treturn latIntersects && lngIntersects;\r\n \t},\r\n\r\n \t// @method overlaps(otherBounds: LatLngBounds): Boolean\r\n \t// Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.\r\n \toverlaps: function (bounds) {\r\n \t\tbounds = toLatLngBounds(bounds);\r\n\r\n \t\tvar sw = this._southWest,\r\n \t\t ne = this._northEast,\r\n \t\t sw2 = bounds.getSouthWest(),\r\n \t\t ne2 = bounds.getNorthEast(),\r\n\r\n \t\t latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat),\r\n \t\t lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng);\r\n\r\n \t\treturn latOverlaps && lngOverlaps;\r\n \t},\r\n\r\n \t// @method toBBoxString(): String\r\n \t// Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.\r\n \ttoBBoxString: function () {\r\n \t\treturn [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');\r\n \t},\r\n\r\n \t// @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean\r\n \t// Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.\r\n \tequals: function (bounds, maxMargin) {\r\n \t\tif (!bounds) { return false; }\r\n\r\n \t\tbounds = toLatLngBounds(bounds);\r\n\r\n \t\treturn this._southWest.equals(bounds.getSouthWest(), maxMargin) &&\r\n \t\t this._northEast.equals(bounds.getNorthEast(), maxMargin);\r\n \t},\r\n\r\n \t// @method isValid(): Boolean\r\n \t// Returns `true` if the bounds are properly initialized.\r\n \tisValid: function () {\r\n \t\treturn !!(this._southWest && this._northEast);\r\n \t}\r\n };\r\n\r\n // TODO International date line?\r\n\r\n // @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)\r\n // Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.\r\n\r\n // @alternative\r\n // @factory L.latLngBounds(latlngs: LatLng[])\r\n // Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).\r\n function toLatLngBounds(a, b) {\r\n \tif (a instanceof LatLngBounds) {\r\n \t\treturn a;\r\n \t}\r\n \treturn new LatLngBounds(a, b);\r\n }\n\n /* @class LatLng\r\n * @aka L.LatLng\r\n *\r\n * Represents a geographical point with a certain latitude and longitude.\r\n *\r\n * @example\r\n *\r\n * ```\r\n * var latlng = L.latLng(50.5, 30.5);\r\n * ```\r\n *\r\n * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:\r\n *\r\n * ```\r\n * map.panTo([50, 30]);\r\n * map.panTo({lon: 30, lat: 50});\r\n * map.panTo({lat: 50, lng: 30});\r\n * map.panTo(L.latLng(50, 30));\r\n * ```\r\n *\r\n * Note that `LatLng` does not inherit from Leaflet's `Class` object,\r\n * which means new classes can't inherit from it, and new methods\r\n * can't be added to it with the `include` function.\r\n */\r\n\r\n function LatLng(lat, lng, alt) {\r\n \tif (isNaN(lat) || isNaN(lng)) {\r\n \t\tthrow new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');\r\n \t}\r\n\r\n \t// @property lat: Number\r\n \t// Latitude in degrees\r\n \tthis.lat = +lat;\r\n\r\n \t// @property lng: Number\r\n \t// Longitude in degrees\r\n \tthis.lng = +lng;\r\n\r\n \t// @property alt: Number\r\n \t// Altitude in meters (optional)\r\n \tif (alt !== undefined) {\r\n \t\tthis.alt = +alt;\r\n \t}\r\n }\r\n\r\n LatLng.prototype = {\r\n \t// @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean\r\n \t// Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.\r\n \tequals: function (obj, maxMargin) {\r\n \t\tif (!obj) { return false; }\r\n\r\n \t\tobj = toLatLng(obj);\r\n\r\n \t\tvar margin = Math.max(\r\n \t\t Math.abs(this.lat - obj.lat),\r\n \t\t Math.abs(this.lng - obj.lng));\r\n\r\n \t\treturn margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);\r\n \t},\r\n\r\n \t// @method toString(): String\r\n \t// Returns a string representation of the point (for debugging purposes).\r\n \ttoString: function (precision) {\r\n \t\treturn 'LatLng(' +\r\n \t\t formatNum(this.lat, precision) + ', ' +\r\n \t\t formatNum(this.lng, precision) + ')';\r\n \t},\r\n\r\n \t// @method distanceTo(otherLatLng: LatLng): Number\r\n \t// Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).\r\n \tdistanceTo: function (other) {\r\n \t\treturn Earth.distance(this, toLatLng(other));\r\n \t},\r\n\r\n \t// @method wrap(): LatLng\r\n \t// Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.\r\n \twrap: function () {\r\n \t\treturn Earth.wrapLatLng(this);\r\n \t},\r\n\r\n \t// @method toBounds(sizeInMeters: Number): LatLngBounds\r\n \t// Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.\r\n \ttoBounds: function (sizeInMeters) {\r\n \t\tvar latAccuracy = 180 * sizeInMeters / 40075017,\r\n \t\t lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);\r\n\r\n \t\treturn toLatLngBounds(\r\n \t\t [this.lat - latAccuracy, this.lng - lngAccuracy],\r\n \t\t [this.lat + latAccuracy, this.lng + lngAccuracy]);\r\n \t},\r\n\r\n \tclone: function () {\r\n \t\treturn new LatLng(this.lat, this.lng, this.alt);\r\n \t}\r\n };\r\n\r\n\r\n\r\n // @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng\r\n // Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).\r\n\r\n // @alternative\r\n // @factory L.latLng(coords: Array): LatLng\r\n // Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.\r\n\r\n // @alternative\r\n // @factory L.latLng(coords: Object): LatLng\r\n // Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.\r\n\r\n function toLatLng(a, b, c) {\r\n \tif (a instanceof LatLng) {\r\n \t\treturn a;\r\n \t}\r\n \tif (isArray(a) && typeof a[0] !== 'object') {\r\n \t\tif (a.length === 3) {\r\n \t\t\treturn new LatLng(a[0], a[1], a[2]);\r\n \t\t}\r\n \t\tif (a.length === 2) {\r\n \t\t\treturn new LatLng(a[0], a[1]);\r\n \t\t}\r\n \t\treturn null;\r\n \t}\r\n \tif (a === undefined || a === null) {\r\n \t\treturn a;\r\n \t}\r\n \tif (typeof a === 'object' && 'lat' in a) {\r\n \t\treturn new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\r\n \t}\r\n \tif (b === undefined) {\r\n \t\treturn null;\r\n \t}\r\n \treturn new LatLng(a, b, c);\r\n }\n\n /*\r\n * @namespace CRS\r\n * @crs L.CRS.Base\r\n * Object that defines coordinate reference systems for projecting\r\n * geographical points into pixel (screen) coordinates and back (and to\r\n * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See\r\n * [spatial reference system](https://en.wikipedia.org/wiki/Spatial_reference_system).\r\n *\r\n * Leaflet defines the most usual CRSs by default. If you want to use a\r\n * CRS not defined by default, take a look at the\r\n * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.\r\n *\r\n * Note that the CRS instances do not inherit from Leaflet's `Class` object,\r\n * and can't be instantiated. Also, new classes can't inherit from them,\r\n * and methods can't be added to them with the `include` function.\r\n */\r\n\r\n var CRS = {\r\n \t// @method latLngToPoint(latlng: LatLng, zoom: Number): Point\r\n \t// Projects geographical coordinates into pixel coordinates for a given zoom.\r\n \tlatLngToPoint: function (latlng, zoom) {\r\n \t\tvar projectedPoint = this.projection.project(latlng),\r\n \t\t scale = this.scale(zoom);\r\n\r\n \t\treturn this.transformation._transform(projectedPoint, scale);\r\n \t},\r\n\r\n \t// @method pointToLatLng(point: Point, zoom: Number): LatLng\r\n \t// The inverse of `latLngToPoint`. Projects pixel coordinates on a given\r\n \t// zoom into geographical coordinates.\r\n \tpointToLatLng: function (point, zoom) {\r\n \t\tvar scale = this.scale(zoom),\r\n \t\t untransformedPoint = this.transformation.untransform(point, scale);\r\n\r\n \t\treturn this.projection.unproject(untransformedPoint);\r\n \t},\r\n\r\n \t// @method project(latlng: LatLng): Point\r\n \t// Projects geographical coordinates into coordinates in units accepted for\r\n \t// this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).\r\n \tproject: function (latlng) {\r\n \t\treturn this.projection.project(latlng);\r\n \t},\r\n\r\n \t// @method unproject(point: Point): LatLng\r\n \t// Given a projected coordinate returns the corresponding LatLng.\r\n \t// The inverse of `project`.\r\n \tunproject: function (point) {\r\n \t\treturn this.projection.unproject(point);\r\n \t},\r\n\r\n \t// @method scale(zoom: Number): Number\r\n \t// Returns the scale used when transforming projected coordinates into\r\n \t// pixel coordinates for a particular zoom. For example, it returns\r\n \t// `256 * 2^zoom` for Mercator-based CRS.\r\n \tscale: function (zoom) {\r\n \t\treturn 256 * Math.pow(2, zoom);\r\n \t},\r\n\r\n \t// @method zoom(scale: Number): Number\r\n \t// Inverse of `scale()`, returns the zoom level corresponding to a scale\r\n \t// factor of `scale`.\r\n \tzoom: function (scale) {\r\n \t\treturn Math.log(scale / 256) / Math.LN2;\r\n \t},\r\n\r\n \t// @method getProjectedBounds(zoom: Number): Bounds\r\n \t// Returns the projection's bounds scaled and transformed for the provided `zoom`.\r\n \tgetProjectedBounds: function (zoom) {\r\n \t\tif (this.infinite) { return null; }\r\n\r\n \t\tvar b = this.projection.bounds,\r\n \t\t s = this.scale(zoom),\r\n \t\t min = this.transformation.transform(b.min, s),\r\n \t\t max = this.transformation.transform(b.max, s);\r\n\r\n \t\treturn new Bounds(min, max);\r\n \t},\r\n\r\n \t// @method distance(latlng1: LatLng, latlng2: LatLng): Number\r\n \t// Returns the distance between two geographical coordinates.\r\n\r\n \t// @property code: String\r\n \t// Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)\r\n \t//\r\n \t// @property wrapLng: Number[]\r\n \t// An array of two numbers defining whether the longitude (horizontal) coordinate\r\n \t// axis wraps around a given range and how. Defaults to `[-180, 180]` in most\r\n \t// geographical CRSs. If `undefined`, the longitude axis does not wrap around.\r\n \t//\r\n \t// @property wrapLat: Number[]\r\n \t// Like `wrapLng`, but for the latitude (vertical) axis.\r\n\r\n \t// wrapLng: [min, max],\r\n \t// wrapLat: [min, max],\r\n\r\n \t// @property infinite: Boolean\r\n \t// If true, the coordinate space will be unbounded (infinite in both axes)\r\n \tinfinite: false,\r\n\r\n \t// @method wrapLatLng(latlng: LatLng): LatLng\r\n \t// Returns a `LatLng` where lat and lng has been wrapped according to the\r\n \t// CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.\r\n \twrapLatLng: function (latlng) {\r\n \t\tvar lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,\r\n \t\t lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,\r\n \t\t alt = latlng.alt;\r\n\r\n \t\treturn new LatLng(lat, lng, alt);\r\n \t},\r\n\r\n \t// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds\r\n \t// Returns a `LatLngBounds` with the same size as the given one, ensuring\r\n \t// that its center is within the CRS's bounds.\r\n \t// Only accepts actual `L.LatLngBounds` instances, not arrays.\r\n \twrapLatLngBounds: function (bounds) {\r\n \t\tvar center = bounds.getCenter(),\r\n \t\t newCenter = this.wrapLatLng(center),\r\n \t\t latShift = center.lat - newCenter.lat,\r\n \t\t lngShift = center.lng - newCenter.lng;\r\n\r\n \t\tif (latShift === 0 && lngShift === 0) {\r\n \t\t\treturn bounds;\r\n \t\t}\r\n\r\n \t\tvar sw = bounds.getSouthWest(),\r\n \t\t ne = bounds.getNorthEast(),\r\n \t\t newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),\r\n \t\t newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);\r\n\r\n \t\treturn new LatLngBounds(newSw, newNe);\r\n \t}\r\n };\n\n /*\n * @namespace CRS\n * @crs L.CRS.Earth\n *\n * Serves as the base for CRS that are global such that they cover the earth.\n * Can only be used as the base for other CRS and cannot be used directly,\n * since it does not have a `code`, `projection` or `transformation`. `distance()` returns\n * meters.\n */\n\n var Earth = extend({}, CRS, {\n \twrapLng: [-180, 180],\n\n \t// Mean Earth Radius, as recommended for use by\n \t// the International Union of Geodesy and Geophysics,\n \t// see https://rosettacode.org/wiki/Haversine_formula\n \tR: 6371000,\n\n \t// distance between two geographical points using spherical law of cosines approximation\n \tdistance: function (latlng1, latlng2) {\n \t\tvar rad = Math.PI / 180,\n \t\t lat1 = latlng1.lat * rad,\n \t\t lat2 = latlng2.lat * rad,\n \t\t sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),\n \t\t sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),\n \t\t a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,\n \t\t c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n \t\treturn this.R * c;\n \t}\n });\n\n /*\r\n * @namespace Projection\r\n * @projection L.Projection.SphericalMercator\r\n *\r\n * Spherical Mercator projection — the most common projection for online maps,\r\n * used by almost all free and commercial tile providers. Assumes that Earth is\r\n * a sphere. Used by the `EPSG:3857` CRS.\r\n */\r\n\r\n var earthRadius = 6378137;\r\n\r\n var SphericalMercator = {\r\n\r\n \tR: earthRadius,\r\n \tMAX_LATITUDE: 85.0511287798,\r\n\r\n \tproject: function (latlng) {\r\n \t\tvar d = Math.PI / 180,\r\n \t\t max = this.MAX_LATITUDE,\r\n \t\t lat = Math.max(Math.min(max, latlng.lat), -max),\r\n \t\t sin = Math.sin(lat * d);\r\n\r\n \t\treturn new Point(\r\n \t\t\tthis.R * latlng.lng * d,\r\n \t\t\tthis.R * Math.log((1 + sin) / (1 - sin)) / 2);\r\n \t},\r\n\r\n \tunproject: function (point) {\r\n \t\tvar d = 180 / Math.PI;\r\n\r\n \t\treturn new LatLng(\r\n \t\t\t(2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,\r\n \t\t\tpoint.x * d / this.R);\r\n \t},\r\n\r\n \tbounds: (function () {\r\n \t\tvar d = earthRadius * Math.PI;\r\n \t\treturn new Bounds([-d, -d], [d, d]);\r\n \t})()\r\n };\n\n /*\r\n * @class Transformation\r\n * @aka L.Transformation\r\n *\r\n * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`\r\n * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing\r\n * the reverse. Used by Leaflet in its projections code.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * var transformation = L.transformation(2, 5, -1, 10),\r\n * \tp = L.point(1, 2),\r\n * \tp2 = transformation.transform(p), // L.point(7, 8)\r\n * \tp3 = transformation.untransform(p2); // L.point(1, 2)\r\n * ```\r\n */\r\n\r\n\r\n // factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)\r\n // Creates a `Transformation` object with the given coefficients.\r\n function Transformation(a, b, c, d) {\r\n \tif (isArray(a)) {\r\n \t\t// use array properties\r\n \t\tthis._a = a[0];\r\n \t\tthis._b = a[1];\r\n \t\tthis._c = a[2];\r\n \t\tthis._d = a[3];\r\n \t\treturn;\r\n \t}\r\n \tthis._a = a;\r\n \tthis._b = b;\r\n \tthis._c = c;\r\n \tthis._d = d;\r\n }\r\n\r\n Transformation.prototype = {\r\n \t// @method transform(point: Point, scale?: Number): Point\r\n \t// Returns a transformed point, optionally multiplied by the given scale.\r\n \t// Only accepts actual `L.Point` instances, not arrays.\r\n \ttransform: function (point, scale) { // (Point, Number) -> Point\r\n \t\treturn this._transform(point.clone(), scale);\r\n \t},\r\n\r\n \t// destructive transform (faster)\r\n \t_transform: function (point, scale) {\r\n \t\tscale = scale || 1;\r\n \t\tpoint.x = scale * (this._a * point.x + this._b);\r\n \t\tpoint.y = scale * (this._c * point.y + this._d);\r\n \t\treturn point;\r\n \t},\r\n\r\n \t// @method untransform(point: Point, scale?: Number): Point\r\n \t// Returns the reverse transformation of the given point, optionally divided\r\n \t// by the given scale. Only accepts actual `L.Point` instances, not arrays.\r\n \tuntransform: function (point, scale) {\r\n \t\tscale = scale || 1;\r\n \t\treturn new Point(\r\n \t\t (point.x / scale - this._b) / this._a,\r\n \t\t (point.y / scale - this._d) / this._c);\r\n \t}\r\n };\r\n\r\n // factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r\n\r\n // @factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r\n // Instantiates a Transformation object with the given coefficients.\r\n\r\n // @alternative\r\n // @factory L.transformation(coefficients: Array): Transformation\r\n // Expects an coefficients array of the form\r\n // `[a: Number, b: Number, c: Number, d: Number]`.\r\n\r\n function toTransformation(a, b, c, d) {\r\n \treturn new Transformation(a, b, c, d);\r\n }\n\n /*\r\n * @namespace CRS\r\n * @crs L.CRS.EPSG3857\r\n *\r\n * The most common CRS for online maps, used by almost all free and commercial\r\n * tile providers. Uses Spherical Mercator projection. Set in by default in\r\n * Map's `crs` option.\r\n */\r\n\r\n var EPSG3857 = extend({}, Earth, {\r\n \tcode: 'EPSG:3857',\r\n \tprojection: SphericalMercator,\r\n\r\n \ttransformation: (function () {\r\n \t\tvar scale = 0.5 / (Math.PI * SphericalMercator.R);\r\n \t\treturn toTransformation(scale, 0.5, -scale, 0.5);\r\n \t}())\r\n });\r\n\r\n var EPSG900913 = extend({}, EPSG3857, {\r\n \tcode: 'EPSG:900913'\r\n });\n\n // @namespace SVG; @section\n // There are several static functions which can be called without instantiating L.SVG:\n\n // @function create(name: String): SVGElement\n // Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),\n // corresponding to the class name passed. For example, using 'line' will return\n // an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).\n function svgCreate(name) {\n \treturn document.createElementNS('http://www.w3.org/2000/svg', name);\n }\n\n // @function pointsToPath(rings: Point[], closed: Boolean): String\n // Generates a SVG path string for multiple rings, with each ring turning\n // into \"M..L..L..\" instructions\n function pointsToPath(rings, closed) {\n \tvar str = '',\n \ti, j, len, len2, points, p;\n\n \tfor (i = 0, len = rings.length; i < len; i++) {\n \t\tpoints = rings[i];\n\n \t\tfor (j = 0, len2 = points.length; j < len2; j++) {\n \t\t\tp = points[j];\n \t\t\tstr += (j ? 'L' : 'M') + p.x + ' ' + p.y;\n \t\t}\n\n \t\t// closes the ring for polygons; \"x\" is VML syntax\n \t\tstr += closed ? (Browser.svg ? 'z' : 'x') : '';\n \t}\n\n \t// SVG complains about empty path strings\n \treturn str || 'M0 0';\n }\n\n /*\r\n * @namespace Browser\r\n * @aka L.Browser\r\n *\r\n * A namespace with static properties for browser/feature detection used by Leaflet internally.\r\n *\r\n * @example\r\n *\r\n * ```js\r\n * if (L.Browser.ielt9) {\r\n * alert('Upgrade your browser, dude!');\r\n * }\r\n * ```\r\n */\r\n\r\n var style = document.documentElement.style;\r\n\r\n // @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).\r\n var ie = 'ActiveXObject' in window;\r\n\r\n // @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.\r\n var ielt9 = ie && !document.addEventListener;\r\n\r\n // @property edge: Boolean; `true` for the Edge web browser.\r\n var edge = 'msLaunchUri' in navigator && !('documentMode' in document);\r\n\r\n // @property webkit: Boolean;\r\n // `true` for webkit-based browsers like Chrome and Safari (including mobile versions).\r\n var webkit = userAgentContains('webkit');\r\n\r\n // @property android: Boolean\r\n // **Deprecated.** `true` for any browser running on an Android platform.\r\n var android = userAgentContains('android');\r\n\r\n // @property android23: Boolean; **Deprecated.** `true` for browsers running on Android 2 or Android 3.\r\n var android23 = userAgentContains('android 2') || userAgentContains('android 3');\r\n\r\n /* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */\r\n var webkitVer = parseInt(/WebKit\\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit\r\n // @property androidStock: Boolean; **Deprecated.** `true` for the Android stock browser (i.e. not Chrome)\r\n var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);\r\n\r\n // @property opera: Boolean; `true` for the Opera browser\r\n var opera = !!window.opera;\r\n\r\n // @property chrome: Boolean; `true` for the Chrome browser.\r\n var chrome = !edge && userAgentContains('chrome');\r\n\r\n // @property gecko: Boolean; `true` for gecko-based browsers like Firefox.\r\n var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;\r\n\r\n // @property safari: Boolean; `true` for the Safari browser.\r\n var safari = !chrome && userAgentContains('safari');\r\n\r\n var phantom = userAgentContains('phantom');\r\n\r\n // @property opera12: Boolean\r\n // `true` for the Opera browser supporting CSS transforms (version 12 or later).\r\n var opera12 = 'OTransition' in style;\r\n\r\n // @property win: Boolean; `true` when the browser is running in a Windows platform\r\n var win = navigator.platform.indexOf('Win') === 0;\r\n\r\n // @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.\r\n var ie3d = ie && ('transition' in style);\r\n\r\n // @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.\r\n var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;\r\n\r\n // @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.\r\n var gecko3d = 'MozPerspective' in style;\r\n\r\n // @property any3d: Boolean\r\n // `true` for all browsers supporting CSS transforms.\r\n var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;\r\n\r\n // @property mobile: Boolean; `true` for all browsers running in a mobile device.\r\n var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');\r\n\r\n // @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.\r\n var mobileWebkit = mobile && webkit;\r\n\r\n // @property mobileWebkit3d: Boolean\r\n // `true` for all webkit-based browsers in a mobile device supporting CSS transforms.\r\n var mobileWebkit3d = mobile && webkit3d;\r\n\r\n // @property msPointer: Boolean\r\n // `true` for browsers implementing the Microsoft touch events model (notably IE10).\r\n var msPointer = !window.PointerEvent && window.MSPointerEvent;\r\n\r\n // @property pointer: Boolean\r\n // `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).\r\n var pointer = !!(window.PointerEvent || msPointer);\r\n\r\n // @property touchNative: Boolean\r\n // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).\r\n // **This does not necessarily mean** that the browser is running in a computer with\r\n // a touchscreen, it only means that the browser is capable of understanding\r\n // touch events.\r\n var touchNative = 'ontouchstart' in window || !!window.TouchEvent;\r\n\r\n // @property touch: Boolean\r\n // `true` for all browsers supporting either [touch](#browser-touch) or [pointer](#browser-pointer) events.\r\n // Note: pointer events will be preferred (if available), and processed for all `touch*` listeners.\r\n var touch = !window.L_NO_TOUCH && (touchNative || pointer);\r\n\r\n // @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.\r\n var mobileOpera = mobile && opera;\r\n\r\n // @property mobileGecko: Boolean\r\n // `true` for gecko-based browsers running in a mobile device.\r\n var mobileGecko = mobile && gecko;\r\n\r\n // @property retina: Boolean\r\n // `true` for browsers on a high-resolution \"retina\" screen or on any screen when browser's display zoom is more than 100%.\r\n var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;\r\n\r\n // @property passiveEvents: Boolean\r\n // `true` for browsers that support passive events.\r\n var passiveEvents = (function () {\r\n \tvar supportsPassiveOption = false;\r\n \ttry {\r\n \t\tvar opts = Object.defineProperty({}, 'passive', {\r\n \t\t\tget: function () { // eslint-disable-line getter-return\r\n \t\t\t\tsupportsPassiveOption = true;\r\n \t\t\t}\r\n \t\t});\r\n \t\twindow.addEventListener('testPassiveEventSupport', falseFn, opts);\r\n \t\twindow.removeEventListener('testPassiveEventSupport', falseFn, opts);\r\n \t} catch (e) {\r\n \t\t// Errors can safely be ignored since this is only a browser support test.\r\n \t}\r\n \treturn supportsPassiveOption;\r\n }());\r\n\r\n // @property canvas: Boolean\r\n // `true` when the browser supports [``](https://developer.mozilla.org/docs/Web/API/Canvas_API).\r\n var canvas$1 = (function () {\r\n \treturn !!document.createElement('canvas').getContext;\r\n }());\r\n\r\n // @property svg: Boolean\r\n // `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).\r\n var svg$1 = !!(document.createElementNS && svgCreate('svg').createSVGRect);\r\n\r\n var inlineSvg = !!svg$1 && (function () {\r\n \tvar div = document.createElement('div');\r\n \tdiv.innerHTML = '';\r\n \treturn (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg';\r\n })();\r\n\r\n // @property vml: Boolean\r\n // `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).\r\n var vml = !svg$1 && (function () {\r\n \ttry {\r\n \t\tvar div = document.createElement('div');\r\n \t\tdiv.innerHTML = '';\r\n\r\n \t\tvar shape = div.firstChild;\r\n \t\tshape.style.behavior = 'url(#default#VML)';\r\n\r\n \t\treturn shape && (typeof shape.adj === 'object');\r\n\r\n \t} catch (e) {\r\n \t\treturn false;\r\n \t}\r\n }());\r\n\r\n\r\n // @property mac: Boolean; `true` when the browser is running in a Mac platform\r\n var mac = navigator.platform.indexOf('Mac') === 0;\r\n\r\n // @property mac: Boolean; `true` when the browser is running in a Linux platform\r\n var linux = navigator.platform.indexOf('Linux') === 0;\r\n\r\n function userAgentContains(str) {\r\n \treturn navigator.userAgent.toLowerCase().indexOf(str) >= 0;\r\n }\r\n\r\n\r\n var Browser = {\r\n \tie: ie,\r\n \tielt9: ielt9,\r\n \tedge: edge,\r\n \twebkit: webkit,\r\n \tandroid: android,\r\n \tandroid23: android23,\r\n \tandroidStock: androidStock,\r\n \topera: opera,\r\n \tchrome: chrome,\r\n \tgecko: gecko,\r\n \tsafari: safari,\r\n \tphantom: phantom,\r\n \topera12: opera12,\r\n \twin: win,\r\n \tie3d: ie3d,\r\n \twebkit3d: webkit3d,\r\n \tgecko3d: gecko3d,\r\n \tany3d: any3d,\r\n \tmobile: mobile,\r\n \tmobileWebkit: mobileWebkit,\r\n \tmobileWebkit3d: mobileWebkit3d,\r\n \tmsPointer: msPointer,\r\n \tpointer: pointer,\r\n \ttouch: touch,\r\n \ttouchNative: touchNative,\r\n \tmobileOpera: mobileOpera,\r\n \tmobileGecko: mobileGecko,\r\n \tretina: retina,\r\n \tpassiveEvents: passiveEvents,\r\n \tcanvas: canvas$1,\r\n \tsvg: svg$1,\r\n \tvml: vml,\r\n \tinlineSvg: inlineSvg,\r\n \tmac: mac,\r\n \tlinux: linux\r\n };\n\n /*\n * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.\n */\n\n var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown';\n var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove';\n var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup';\n var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel';\n var pEvent = {\n \ttouchstart : POINTER_DOWN,\n \ttouchmove : POINTER_MOVE,\n \ttouchend : POINTER_UP,\n \ttouchcancel : POINTER_CANCEL\n };\n var handle = {\n \ttouchstart : _onPointerStart,\n \ttouchmove : _handlePointer,\n \ttouchend : _handlePointer,\n \ttouchcancel : _handlePointer\n };\n var _pointers = {};\n var _pointerDocListener = false;\n\n // Provides a touch events wrapper for (ms)pointer events.\n // ref https://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890\n\n function addPointerListener(obj, type, handler) {\n \tif (type === 'touchstart') {\n \t\t_addPointerDocListener();\n \t}\n \tif (!handle[type]) {\n \t\tconsole.warn('wrong event specified:', type);\n \t\treturn falseFn;\n \t}\n \thandler = handle[type].bind(this, handler);\n \tobj.addEventListener(pEvent[type], handler, false);\n \treturn handler;\n }\n\n function removePointerListener(obj, type, handler) {\n \tif (!pEvent[type]) {\n \t\tconsole.warn('wrong event specified:', type);\n \t\treturn;\n \t}\n \tobj.removeEventListener(pEvent[type], handler, false);\n }\n\n function _globalPointerDown(e) {\n \t_pointers[e.pointerId] = e;\n }\n\n function _globalPointerMove(e) {\n \tif (_pointers[e.pointerId]) {\n \t\t_pointers[e.pointerId] = e;\n \t}\n }\n\n function _globalPointerUp(e) {\n \tdelete _pointers[e.pointerId];\n }\n\n function _addPointerDocListener() {\n \t// need to keep track of what pointers and how many are active to provide e.touches emulation\n \tif (!_pointerDocListener) {\n \t\t// we listen document as any drags that end by moving the touch off the screen get fired there\n \t\tdocument.addEventListener(POINTER_DOWN, _globalPointerDown, true);\n \t\tdocument.addEventListener(POINTER_MOVE, _globalPointerMove, true);\n \t\tdocument.addEventListener(POINTER_UP, _globalPointerUp, true);\n \t\tdocument.addEventListener(POINTER_CANCEL, _globalPointerUp, true);\n\n \t\t_pointerDocListener = true;\n \t}\n }\n\n function _handlePointer(handler, e) {\n \tif (e.pointerType === (e.MSPOINTER_TYPE_MOUSE || 'mouse')) { return; }\n\n \te.touches = [];\n \tfor (var i in _pointers) {\n \t\te.touches.push(_pointers[i]);\n \t}\n \te.changedTouches = [e];\n\n \thandler(e);\n }\n\n function _onPointerStart(handler, e) {\n \t// IE10 specific: MsTouch needs preventDefault. See #2000\n \tif (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) {\n \t\tpreventDefault(e);\n \t}\n \t_handlePointer(handler, e);\n }\n\n /*\r\n * Extends the event handling code with double tap support for mobile browsers.\r\n *\r\n * Note: currently most browsers fire native dblclick, with only a few exceptions\r\n * (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386)\r\n */\r\n\r\n function makeDblclick(event) {\r\n \t// in modern browsers `type` cannot be just overridden:\r\n \t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only\r\n \tvar newEvent = {},\r\n \t prop, i;\r\n \tfor (i in event) {\r\n \t\tprop = event[i];\r\n \t\tnewEvent[i] = prop && prop.bind ? prop.bind(event) : prop;\r\n \t}\r\n \tevent = newEvent;\r\n \tnewEvent.type = 'dblclick';\r\n \tnewEvent.detail = 2;\r\n \tnewEvent.isTrusted = false;\r\n \tnewEvent._simulated = true; // for debug purposes\r\n \treturn newEvent;\r\n }\r\n\r\n var delay = 200;\r\n function addDoubleTapListener(obj, handler) {\r\n \t// Most browsers handle double tap natively\r\n \tobj.addEventListener('dblclick', handler);\r\n\r\n \t// On some platforms the browser doesn't fire native dblclicks for touch events.\r\n \t// It seems that in all such cases `detail` property of `click` event is always `1`.\r\n \t// So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed.\r\n \tvar last = 0,\r\n \t detail;\r\n \tfunction simDblclick(e) {\r\n \t\tif (e.detail !== 1) {\r\n \t\t\tdetail = e.detail; // keep in sync to avoid false dblclick in some cases\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\tif (e.pointerType === 'mouse' ||\r\n \t\t\t(e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents)) {\r\n\r\n \t\t\treturn;\r\n \t\t}\r\n\r\n \t\t// When clicking on an , the browser generates a click on its\r\n \t\t//