-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBetter_Map_Widget.json
More file actions
150 lines (150 loc) · 78.5 KB
/
Copy pathBetter_Map_Widget.json
File metadata and controls
150 lines (150 loc) · 78.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{
"santabaRelease": 239,
"defaultDashboardFilters": {
"defaultDashboardFilterDetails": []
},
"widgetTokens": [
{
"name": "MapGroupPathFilter",
"value": "*"
},
{
"name": "MapShowWeather",
"value": "global"
},
{
"name": "MapIgnoreCleared",
"value": "false"
},
{
"name": "MapSourceType",
"value": "resources"
},
{
"name": "HideMapOptions",
"value": "false"
},
{
"name": "MapOverlayOption",
"value": "earthquakes"
},
{
"name": "MapIgnoreWarnings",
"value": "false"
},
{
"name": "MapIgnoreErrors",
"value": "false"
},
{
"name": "MapIgnoreCriticals",
"value": "false"
},
{
"name": "isMapWidgetVirtualizationDisabled",
"value": "true"
},
{
"name": "AutoResetMapOnRefresh",
"value": "false"
},
{
"name": "MapShowTiltControls",
"value": "true"
},
{
"name": "MapDisplayProperties",
"value": "region"
},
{
"name": "MapDisableClustering",
"value": "false"
},
{
"name": "MapStyle",
"value": "silverblue"
},
{
"name": "MapShowRoadLabels",
"value": "false"
},
{
"name": "MapLocationProperty",
"value": "location"
},
{
"name": "ShowMapSidebar",
"value": "false"
},
{
"name": "MapMarkerStyle",
"value": "pins"
},
{
"name": "MapConnectionCurvature",
"value": "18"
},
{
"name": "MapUseGeodesicLines",
"value": "true"
},
{
"name": "MapOnlyShowConnectedItems",
"value": "false"
},
{
"name": "MapShowConnectingLines",
"value": "true"
}
],
"name": "Better Map Widget",
"description": "This is a custom-developed widget to demonstrate several concepts I'd love to see rolled into LogicMonitor's core Map widget.",
"overwriteGroupFields": false,
"widgetsConfigVersion": 2,
"type": "dashboard",
"widgets": [
{
"position": {
"col": 1,
"sizex": 10,
"row": 1,
"sizey": 12
},
"config": {
"displaySettings": {},
"isSupportCustomProperty": false,
"supportCustomProperty": false,
"name": "Better Map Widget",
"description": "",
"theme": "newBorderGray",
"interval": 15,
"type": "text",
"timescale": "day",
"version": 2,
"content": "<!--\n\tBetter Map Widget\n\tVersion 1.26 - CDN Version\n\tDeveloped by Kevin Ford\n\n\tSome of the ideas behind this project:\n\t* Support for thousands pins on the map, though be aware that Google Maps will start to struggle if too many pins.\n\t* Adjacent pins get grouped/clustered together for a cleaner map display.\n\t* Clusters use a donut chart to represent the severities of the grouped markers.\n\t* Easy toggling of weather layers.\n\t* Display more information when clicking a marker.\n\t* Quick & easy filtering of what's displayed on the map.\n\t* Provide a way to plot connections between resources (and eventually groups).\n\n\tPrerequisites:\n\t* The user needs \"View\" permissions to the dashboard plus any displayed groups and/or resources.\n\t* Group's or resources with valid addresses set in the usual 'location' property.\n\n\tTO USE:\n\t1. Create a new Text widget to the dashboard.\n\t2. On the Text widget's edit dialog, click the \"Source\" button and paste in the contents of this script, then save the widget.\n\t3. At this point the widget should be ready to use. You can customize the defaults for the widget either via dashboard tokens or by changing variables here within the script.\n\t For instance, the script defaults to using \"*\" for the group filter. You can change the default by setting a \"MapGroupPathFilter\" dashboard token, or by hard-coding it in the script's \"groupPathFilter\" variable below.\n\t NOTE: defaults set via dashboard tokens will take precedence over those hard-coded in the script.\n\n\tOPTIONAL DASHBOARD TOKENS:\n\t* 'MapGroupPathFilter': Allows setting a default group path to start. Default is \"*\".\n\t* 'MapLocationProperty': The property to use for the location of the items on the map. Default is \"location\".\n\t* 'MapMarkerStyle': The style of marker to use for the items on the map. Options are \"pins\" or \"circles\". Legacy values \"default\", \"pin\", \"dot\", \"dots\", and \"circle\" are also accepted. Default is \"pins\".\n\t* 'MapShowWeather': If weather should be shown by default. Options are \"global\", \"nexrad\", \"openweather\", or \"xweather\". Default is \"no\".\n\t* 'OpenWeatherAPIKey': API key for OpenWeather radar tiles (required when using \"openweather\" weather option).\n\t* 'XweatherAPIID': API ID for Xweather radar tiles (required when using \"xweather\" weather option).\n\t* 'XweatherAPIKey': API secret for Xweather radar tiles (required when using \"xweather\" weather option).\n\t* 'MapOverlayOption': Which optional overlay to default to when weather is shown. Options are \"wildfires\", \"us-wildfires\", \"outages\", \"us-poweroutages\", \"us-flooding\" or \"earthquakes\". Default is \"earthquakes\".\n\t* 'HideMapOptions': If \"true\" then will hide the options bar by default. Default is \"false\".\n\t* 'ShowMapSidebar': If \"true\" then will show the sidebar by default. Default is \"false\".\n\t* 'MapSourceType': Whether to map \"groups\", \"resources\", or \"services\". Default is \"groups\".\n\t* 'MapIgnoreCleared': If \"true\" then will only show items currently alerting (useful for maps with thousands of markers). Default is \"false\".\n\t* 'MapIgnoreWarnings': If \"true\" then won't show items in \"Warning\" status. Default is \"false\".\n\t* 'MapIgnoreErrors': If \"true\" then won't show items in \"Error\" status. Default is \"false\".\n\t* 'MapIgnoreCriticals': If \"true\" then won't show items in \"Critical\" status. Default is \"false\".\n\t* 'MapIgnoreSDT': If \"true\" then won't show items in \"SDT\" status. Default is \"false\".\n\t* 'MapOnlyShowConnectedItems': If \"true\" then will only show items that participate in active map connections. Default is \"false\".\n\t* 'MapShowConnectingLines': If \"false\" then will hide status lines between connected endpoints. Default is \"true\".\n\t* 'AutoResetMapOnRefresh': If \"true\" then the map will automatically zoom to encompass all items on timed refreshes. Default is \"false\".\n\t* 'MapShowTiltControls': If \"true\" then the tilt & rotation controls for the map will be shown. Default is \"false\".\n\t* 'MapDisableClustering': If \"true\" then clustering of adjacent markers on the map will be disabled. Might be desirable if showing connections between locations since clustering might hide markers at certain zoom levels. Default is \"false\".\n\t* 'MapConnectionCurvature': Screen-pixel offset used to separate parallel connection lines between the same endpoints. Set to 0 for straight lines. Default is 18.\n\t* 'MapUseGeodesicLines': If \"false\" then connection lines are drawn as straight Mercator lines instead of great circles. Default is \"true\".\n\t* 'MapDisplayProperties': An optional comma-delimited list of custom properties to show when viewing a group's/resource's details.\n\t* 'MapStyle': Allows one of the following available map style options: \"silver\", \"standard\", \"dark\", \"aubergine\", \"satellite\", or \"silverblue\". Default is \"silverblue\".\n\t* 'MapShowRoadLabels': If \"true\" then road labels will be shown on the map. Default is \"false\".\n\t* 'apiBearerToken', or 'apiID' + 'apiKey': Optional LogicMonitor API bearer token or API ID & key to use for the widget. If not specified then the widget will use integrated portal authentication.\n\n\tLIMITATIONS:\n\t* This widget is currently unable to leverage LogicMonitor's native dashboard filters.\n\t* Being custom-developed, LogicMonitor's support teams will be limited in what they can assist with regarding questions/issues.\n--><!-- Here you can change specific defaults for the map. Many of these can be overridden via the dashboard tokens mentioned above. --><script data-better-map-defaults=\"\">\n\t\t(function(script) {\n\t\t\tvar registry = window.__betterMapWidgetRegistry = window.__betterMapWidgetRegistry || { instances: Object.create(null) };\n\t\t\tregistry.pendingDefaults = registry.pendingDefaults || [];\n\t\t\t// Edit the values after the colons below. Dashboard tokens still take precedence.\n\t\t\tvar defaults = {\n\t// Optional: You can specify a LogicMonitor API bearer token or API ID & key to use for the widget...\n\tapiBearerToken: \"\",\n\tlmAPIID: \"\",\n\tlmAPIKey: \"\",\n\n\t// Whether we're plotting \"groups\" or \"resources\" or \"services\" (strongly recommend staying with groups or services)...\n\t// You can either set it here or in a dashboard token named 'MapSourceType'...\n\tmapSourceType: \"groups\",\n\n\t// The property to use for the location of the items on the map. Default is \"location\"...\n\t// You can either set it here or in a dashboard token named 'MapLocationProperty'...\n\tmapLocationProperty: \"location\",\n\n\t// Preferred map style. Available options: \"silver\" (the default), \"standard\", \"dark\", \"aubergine\", \"silverblue\", \"satellite\", or \"satellite-light\"...\n\tmapStyle: \"silverblue\",\n\n\t// Whether to ignore items with no active alerts (useful for maps with thousands of markers)...\n\t// You can either set it here or in a dashboard token named 'MapIgnoreCleared'...\n\tshowCleared: true,\n\tshowWarnings: true,\n\tshowErrors: true,\n\tshowCriticals: true,\n\tshowSDT: true,\n\tshowOnlyConnected: false,\n\tshowConnections: true,\n\n\t// Capture if a group filter...\n\t// You can set it here or in a dashboard token named \"MapGroupPathFilter\"...\n\tgroupPathFilter: \"*\",\n\n\t// Interval for updating group status data (in minutes)...\n\tstatusUpdateIntervalMinutes: 2,\n\n\t// Flag to disable marker clustering if needed...\n\tdisableClustering: false,\n\n\t// Whether to show weather by default. Options are: \"no\", \"global\", \"nexrad\", \"openweather\", \"xweather\"...\n\t// You can set it here or in a dashboard token named \"MapShowWeather\"...\n\tshowWeatherDefault: \"no\",\n\n\t// If weather is shown, whether to show \"wildfires\" or \"us-wildfires\" or \"outages\" or \"us-poweroutages\" or \"us-flooding\" or \"earthquakes\"...\n\t// You can set it here or in a dashboard token named \"MapOverlayOption\"...\n\tadditionalOverlayOption: \"earthquakes\",\n\n\t// Whether to show or hide the map options along the top of the widget by default...\n\t// You can set it here or in a dashboard token named \"HideMapOptions\"...\n\thideMapOptionsByDefault: false,\n\n\t// Whether to show the map sidebar by default...\n\t// You can set it here or in a dashboard token named \"ShowMapSidebar\"...\n\tshowMapSidebarByDefault: false,\n\n\t// Whether to automatically center the map to encompass all items during timed refreshes...\n\t// You can set it here or in a dashboard token named \"AutoResetMapOnRefresh\"...\n\tautoResetMapOnRefresh: false,\n\n\t// When true will not refresh the data on a timed interval (useful ONLY during development)...\n\tdevelopmentFlag: false,\n\n\t// Since we generally don't need to poll all properties every time, we can just grab them initially then occasionally every x number of polls based on the following variable (set to 0 to perform a full refresh every time)...\n\tfullRefreshInterval: 0,\n\n\t// Optional angle & heading for the Google Map...\n\tshowMapTiltControls: false,\n\tmapTilt: 0,\n\tmapHeading: 0,\n\n\t// Whether to include inherited locations in addition to those directly set on resources and/or services (disabling this can greatly increase refresh speed)...\n\tpollInheritedLocations: true,\n\n\t// Typically if both a 'latitude' & 'longitude' property are set, then we can assume the address is already geocoded. Set this to \"true\" to force geocoding the address instead...\n\tignoreLatLongProps: false,\n\n\t// Whether the Google Maps uses the \"cooperative\" gesture handling, or \"greedy\" that allows mouse-wheel zooming without having to hold a modifier key (Google's default is \"cooperative\")...\n\tmapGestureHandling: \"cooperative\",\n\t// Whether to show road labels...\n\tshowRoadLabels: \"off\",\n\n\t// An optional comma-delimited list of custom properties to show when viewing a group's/resource's details...\n\t// You can set it here or in a dashboard token named \"MapDisplayProperties\"...\n\tdisplayProps: \"\",\n\n\t// Property to look for connecting information in...\n\tconnectionInfoProp: \"auto.custom_map_connection_data\",\n\t// Stroke weight of connecting lines...\n\tconnectingLineWeight: 3,\n\t// Whether to use geodesic (great circle) lines when connecting two locations...\n\t// You can set it here or in a dashboard token named \"MapUseGeodesicLines\"...\n\tuseGeodesicLines: true,\n\n\t// OpenWeather API key (required for OpenWeather radar)...\n\t// You can set it here or in a dashboard token named \"OpenWeatherAPIKey\"...\n\topenWeatherAPIKey: \"\",\n\n\t// Xweather API credentials (required for Xweather radar)...\n\t// You can set them here or in dashboard tokens named \"XweatherAPIID\" and \"XweatherAPIKey\"...\n\txweatherAPIID: \"\",\n\txweatherAPIKey: \"\",\n\n\t// Default opacity for weather layers...\n\tweatherOpacity: 0.35,\n\t// Default opacity for satellite weather layers...\n\tsatelliteWeatherOpacity: 0.6,\n\t// Color scheme for the \"global\" weather option...\n\t// See https://rainviewer.com/api/color-schemes.html for color scheme options (values are 0-8)...\n\trvOptionColorScheme: 8,\n\t// Weather refresh interval in minutes...\n\tweatherRefreshMinutes: 5,\n\t// Whether to display details about a wildfire on \"click\" or \"mouseover\"...\n\tshowWildfireInfoEvent: \"click\",\n\t\t// Whether the opacity of an earthquake's icon reflects \"time\" since the event, or \"magnitude\"...\n\t\tquakeMode: \"time\"\n\t\t\t};\n\t\t\tif (script) {\n\t\t\t\tscript.__betterMapDefaults = defaults;\n\t\t\t} else {\n\t\t\t\tregistry.pendingDefaults.push(defaults);\n\t\t\t}\n\t\t})(document.currentScript);\n\t</script><!-- Load our Javascript from the CDN... --><!-- <script>document.write('<script src=\"https://cdn.jsdelivr.net/gh/logicmonitor/custom_widgets@main/src/Better_Map_Widget.js?ts=' + Date.now() + '\" defer><\\/script>');</script> --><!-- Load our CSS styles from the CDN... --><!-- <script>document.write('<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/logicmonitor/custom_widgets@main/src/Better_Map_Widget.css?ts=' + Date.now() + '\" />');</script> --><!-- Our main widget body... --><div class=\"customMapBody\"> </div><!-- Area for capturing dashboard tokens... --><div id=\"tokenCaptureArea\" style=\"display: none;\"><div id=\"mapSourceTypeToken\">##MapSourceType##</div><div id=\"mapLocationPropertyToken\">##MapLocationProperty##</div><div id=\"mapStyleToken\">##MapStyle##</div><div id=\"hideMapOptionsByDefaultToken\">##HideMapOptions##</div><div id=\"showMapSidebarByDefaultToken\">##ShowMapSidebar##</div><div id=\"ignoreClearedToken\">##MapIgnoreCleared##</div><div id=\"ignoreWarningsToken\">##MapIgnoreWarnings##</div><div id=\"ignoreErrorsToken\">##MapIgnoreErrors##</div><div id=\"ignoreCriticalsToken\">##MapIgnoreCriticals##</div><div id=\"ignoreSDTToken\">##MapIgnoreSDT##</div><div id=\"onlyShowConnectedToken\">##MapOnlyShowConnectedItems##</div><div id=\"showConnectingLinesToken\">##MapShowConnectingLines##</div><div id=\"showMapTiltControlsToken\">##MapShowTiltControls##</div><div id=\"autoResetMapOnRefreshToken\">##AutoResetMapOnRefresh##</div><div id=\"dashboardGroupPathToken\">##MapGroupPathFilter##</div><div id=\"dashboardShowWeatherToken\">##MapShowWeather##</div><div id=\"openWeatherAPIKeyToken\">##OpenWeatherAPIKey##</div><div id=\"xweatherAPIIDToken\">##XweatherAPIID##</div><div id=\"xweatherAPIKeyToken\">##XweatherAPIKey##</div><div id=\"dashboardAddlOverlayToken\">##MapOverlayOption##</div><div id=\"displayPropsToken\">##MapDisplayProperties##</div><div id=\"disableClusteringToken\">##MapDisableClustering##</div><div id=\"showRoadLabelsToken\">##MapShowRoadLabels##</div><div id=\"apiBearerTokenToken\">##apiBearerToken##</div><div id=\"apiIDToken\">##apiID##</div><div id=\"apiKeyToken\">##apiKey##</div><div id=\"markerStyleToken\">##MapMarkerStyle##</div><div id=\"connectionCurvatureToken\">##MapConnectionCurvature##</div><div id=\"useGeodesicLinesToken\">##MapUseGeodesicLines##</div></div><!-- If used as an embedded widget outside a normal LM dashboard then trying to load Google's marker clustering script externally breaks due to XSS, so I'm embedding the entire script here. Normally we would load this from https://unpkg.com/@googlemaps/markerclusterer@2.6.2/dist/index.min.js.--><script>\n\twindow.markerClusterer = window.markerClusterer || function(t){\"use strict\";var r,e,n=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{},o={};function i(){if(e)return r;e=1;var t=function(t){return t&&t.Math===Math&&t};return r=t(\"object\"==typeof globalThis&&globalThis)||t(\"object\"==typeof window&&window)||t(\"object\"==typeof self&&self)||t(\"object\"==typeof n&&n)||t(\"object\"==typeof r&&r)||function(){return this}()||Function(\"return this\")()}var s,a,u,c,f,l,h,p,m={};function d(){return a?s:(a=1,s=function(t){try{return!!t()}catch(t){return!0}})}function g(){if(c)return u;c=1;var t=d();return u=!t(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})}function v(){if(l)return f;l=1;var t=d();return f=!t(function(){var t=function(){}.bind();return\"function\"!=typeof t||t.hasOwnProperty(\"prototype\")})}function y(){if(p)return h;p=1;var t=v(),r=Function.prototype.call;return h=t?r.bind(r):function(){return r.apply(r,arguments)},h}var w,b,E,k,x,M,O,P,C,S,j,A,I,_,T,L,q,R,Z,z,D,F,N,U,B,W,$,V,G,H,K,Y,X,J,Q,tt,rt,et,nt,ot,it,st={};function at(){return E?b:(E=1,b=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}})}function ut(){if(x)return k;x=1;var t=v(),r=Function.prototype,e=r.call,n=t&&r.bind.bind(e,e);return k=t?n:function(t){return function(){return e.apply(t,arguments)}},k}function ct(){if(O)return M;O=1;var t=ut(),r=t({}.toString),e=t(\"\".slice);return M=function(t){return e(r(t),8,-1)}}function ft(){return j?S:(j=1,S=function(t){return null==t})}function lt(){if(I)return A;I=1;var t=ft(),r=TypeError;return A=function(e){if(t(e))throw new r(\"Can't call method on \"+e);return e}}function ht(){if(T)return _;T=1;var t=function(){if(C)return P;C=1;var t=ut(),r=d(),e=ct(),n=Object,o=t(\"\".split);return P=r(function(){return!n(\"z\").propertyIsEnumerable(0)})?function(t){return\"String\"===e(t)?o(t,\"\"):n(t)}:n}(),r=lt();return _=function(e){return t(r(e))}}function pt(){if(q)return L;q=1;var t=\"object\"==typeof document&&document.all;return L=void 0===t&&void 0!==t?function(r){return\"function\"==typeof r||r===t}:function(t){return\"function\"==typeof t}}function mt(){if(Z)return R;Z=1;var t=pt();return R=function(r){return\"object\"==typeof r?null!==r:t(r)}}function dt(){if(D)return z;D=1;var t=i(),r=pt();return z=function(e,n){return arguments.length<2?(o=t[e],r(o)?o:void 0):t[e]&&t[e][n];var o},z}function gt(){if(N)return F;N=1;var t=ut();return F=t({}.isPrototypeOf)}function vt(){if($)return W;$=1;var t,r,e=i(),n=function(){if(B)return U;B=1;var t=i().navigator,r=t&&t.userAgent;return U=r?String(r):\"\"}(),o=e.process,s=e.Deno,a=o&&o.versions||s&&s.version,u=a&&a.v8;return u&&(r=(t=u.split(\".\"))[0]>0&&t[0]<4?1:+(t[0]+t[1])),!r&&n&&(!(t=n.match(/Edge\\/(\\d+)/))||t[1]>=74)&&(t=n.match(/Chrome\\/(\\d+)/))&&(r=+t[1]),W=r}function yt(){if(G)return V;G=1;var t=vt(),r=d(),e=i().String;return V=!!Object.getOwnPropertySymbols&&!r(function(){var r=Symbol(\"symbol detection\");return!e(r)||!(Object(r)instanceof Symbol)||!Symbol.sham&&t&&t<41})}function wt(){if(K)return H;K=1;var t=yt();return H=t&&!Symbol.sham&&\"symbol\"==typeof Symbol.iterator}function bt(){if(X)return Y;X=1;var t=dt(),r=pt(),e=gt(),n=wt(),o=Object;return Y=n?function(t){return\"symbol\"==typeof t}:function(n){var i=t(\"Symbol\");return r(i)&&e(i.prototype,o(n))}}function Et(){if(Q)return J;Q=1;var t=String;return J=function(r){try{return t(r)}catch(t){return\"Object\"}}}function kt(){if(rt)return tt;rt=1;var t=pt(),r=Et(),e=TypeError;return tt=function(n){if(t(n))return n;throw new e(r(n)+\" is not a function\")}}function xt(){if(nt)return et;nt=1;var t=kt(),r=ft();return et=function(e,n){var o=e[n];return r(o)?void 0:t(o)}}function Mt(){if(it)return ot;it=1;var t=y(),r=pt(),e=mt(),n=TypeError;return ot=function(o,i){var s,a;if(\"string\"===i&&r(s=o.toString)&&!e(a=t(s,o)))return a;if(r(s=o.valueOf)&&!e(a=t(s,o)))return a;if(\"string\"!==i&&r(s=o.toString)&&!e(a=t(s,o)))return a;throw new n(\"Can't convert object to primitive value\")}}var Ot,Pt,Ct,St,jt,At,It,_t,Tt,Lt,qt,Rt,Zt,zt,Dt,Ft,Nt,Ut,Bt,Wt,$t,Vt,Gt,Ht,Kt={exports:{}};function Yt(){return Pt?Ot:(Pt=1,Ot=!1)}function Xt(){if(St)return Ct;St=1;var t=i(),r=Object.defineProperty;return Ct=function(e,n){try{r(t,e,{value:n,configurable:!0,writable:!0})}catch(r){t[e]=n}return n}}function Jt(){if(jt)return Kt.exports;jt=1;var t=Yt(),r=i(),e=Xt(),n=\"__core-js_shared__\",o=Kt.exports=r[n]||e(n,{});return(o.versions||(o.versions=[])).push({version:\"3.44.0\",mode:t?\"pure\":\"global\",copyright:\"(c) 2014-2025 Denis Pushkarev (zloirock.ru)\",license:\"https://github.com/zloirock/core-js/blob/v3.44.0/LICENSE\",source:\"https://github.com/zloirock/core-js\"}),Kt.exports}function Qt(){if(It)return At;It=1;var t=Jt();return At=function(r,e){return t[r]||(t[r]=e||{})}}function tr(){if(Tt)return _t;Tt=1;var t=lt(),r=Object;return _t=function(e){return r(t(e))}}function rr(){if(qt)return Lt;qt=1;var t=ut(),r=tr(),e=t({}.hasOwnProperty);return Lt=Object.hasOwn||function(t,n){return e(r(t),n)}}function er(){if(Zt)return Rt;Zt=1;var t=ut(),r=0,e=Math.random(),n=t(1.1.toString);return Rt=function(t){return\"Symbol(\"+(void 0===t?\"\":t)+\")_\"+n(++r+e,36)}}function nr(){if(Dt)return zt;Dt=1;var t=i(),r=Qt(),e=rr(),n=er(),o=yt(),s=wt(),a=t.Symbol,u=r(\"wks\"),c=s?a.for||a:a&&a.withoutSetter||n;return zt=function(t){return e(u,t)||(u[t]=o&&e(a,t)?a[t]:c(\"Symbol.\"+t)),u[t]}}function or(){if(Nt)return Ft;Nt=1;var t=y(),r=mt(),e=bt(),n=xt(),o=Mt(),i=nr(),s=TypeError,a=i(\"toPrimitive\");return Ft=function(i,u){if(!r(i)||e(i))return i;var c,f=n(i,a);if(f){if(void 0===u&&(u=\"default\"),c=t(f,i,u),!r(c)||e(c))return c;throw new s(\"Can't convert object to primitive value\")}return void 0===u&&(u=\"number\"),o(i,u)}}function ir(){if(Bt)return Ut;Bt=1;var t=or(),r=bt();return Ut=function(e){var n=t(e,\"string\");return r(n)?n:n+\"\"}}function sr(){if($t)return Wt;$t=1;var t=i(),r=mt(),e=t.document,n=r(e)&&r(e.createElement);return Wt=function(t){return n?e.createElement(t):{}}}function ar(){if(Gt)return Vt;Gt=1;var t=g(),r=d(),e=sr();return Vt=!t&&!r(function(){return 7!==Object.defineProperty(e(\"div\"),\"a\",{get:function(){return 7}}).a})}function ur(){if(Ht)return m;Ht=1;var t=g(),r=y(),e=function(){if(w)return st;w=1;var t={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,e=r&&!t.call({1:2},1);return st.f=e?function(t){var e=r(this,t);return!!e&&e.enumerable}:t,st}(),n=at(),o=ht(),i=ir(),s=rr(),a=ar(),u=Object.getOwnPropertyDescriptor;return m.f=t?u:function(t,c){if(t=o(t),c=i(c),a)try{return u(t,c)}catch(t){}if(s(t,c))return n(!r(e.f,t,c),t[c])},m}var cr,fr,lr,hr,pr,mr,dr,gr={};function vr(){if(fr)return cr;fr=1;var t=g(),r=d();return cr=t&&r(function(){return 42!==Object.defineProperty(function(){},\"prototype\",{value:42,writable:!1}).prototype})}function yr(){if(hr)return lr;hr=1;var t=mt(),r=String,e=TypeError;return lr=function(n){if(t(n))return n;throw new e(r(n)+\" is not an object\")}}function wr(){if(pr)return gr;pr=1;var t=g(),r=ar(),e=vr(),n=yr(),o=ir(),i=TypeError,s=Object.defineProperty,a=Object.getOwnPropertyDescriptor,u=\"enumerable\",c=\"configurable\",f=\"writable\";return gr.f=t?e?function(t,r,e){if(n(t),r=o(r),n(e),\"function\"==typeof t&&\"prototype\"===r&&\"value\"in e&&f in e&&!e[f]){var i=a(t,r);i&&i[f]&&(t[r]=e.value,e={configurable:c in e?e[c]:i[c],enumerable:u in e?e[u]:i[u],writable:!1})}return s(t,r,e)}:s:function(t,e,a){if(n(t),e=o(e),n(a),r)try{return s(t,e,a)}catch(t){}if(\"get\"in a||\"set\"in a)throw new i(\"Accessors not supported\");return\"value\"in a&&(t[e]=a.value),t},gr}function br(){if(dr)return mr;dr=1;var t=g(),r=wr(),e=at();return mr=t?function(t,n,o){return r.f(t,n,e(1,o))}:function(t,r,e){return t[r]=e,t}}var Er,kr,xr,Mr,Or,Pr,Cr,Sr,jr,Ar,Ir,_r,Tr,Lr,qr,Rr={exports:{}};function Zr(){if(Mr)return xr;Mr=1;var t=ut(),r=pt(),e=Jt(),n=t(Function.toString);return r(e.inspectSource)||(e.inspectSource=function(t){return n(t)}),xr=e.inspectSource}function zr(){if(Sr)return Cr;Sr=1;var t=Qt(),r=er(),e=t(\"keys\");return Cr=function(t){return e[t]||(e[t]=r(t))}}function Dr(){return Ar?jr:(Ar=1,jr={})}function Fr(){if(_r)return Ir;_r=1;var t,r,e,n=function(){if(Pr)return Or;Pr=1;var t=i(),r=pt(),e=t.WeakMap;return Or=r(e)&&/native code/.test(String(e))}(),o=i(),s=mt(),a=br(),u=rr(),c=Jt(),f=zr(),l=Dr(),h=\"Object already initialized\",p=o.TypeError,m=o.WeakMap;if(n||c.state){var d=c.state||(c.state=new m);d.get=d.get,d.has=d.has,d.set=d.set,t=function(t,r){if(d.has(t))throw new p(h);return r.facade=t,d.set(t,r),r},r=function(t){return d.get(t)||{}},e=function(t){return d.has(t)}}else{var g=f(\"state\");l[g]=!0,t=function(t,r){if(u(t,g))throw new p(h);return r.facade=t,a(t,g,r),r},r=function(t){return u(t,g)?t[g]:{}},e=function(t){return u(t,g)}}return Ir={set:t,get:r,has:e,enforce:function(n){return e(n)?r(n):t(n,{})},getterFor:function(t){return function(e){var n;if(!s(e)||(n=r(e)).type!==t)throw new p(\"Incompatible receiver, \"+t+\" required\");return n}}}}function Nr(){if(Tr)return Rr.exports;Tr=1;var t=ut(),r=d(),e=pt(),n=rr(),o=g(),i=function(){if(kr)return Er;kr=1;var t=g(),r=rr(),e=Function.prototype,n=t&&Object.getOwnPropertyDescriptor,o=r(e,\"name\"),i=o&&\"something\"===function(){}.name,s=o&&(!t||t&&n(e,\"name\").configurable);return Er={EXISTS:o,PROPER:i,CONFIGURABLE:s}}().CONFIGURABLE,s=Zr(),a=Fr(),u=a.enforce,c=a.get,f=String,l=Object.defineProperty,h=t(\"\".slice),p=t(\"\".replace),m=t([].join),v=o&&!r(function(){return 8!==l(function(){},\"length\",{value:8}).length}),y=String(String).split(\"String\"),w=Rr.exports=function(t,r,e){\"Symbol(\"===h(f(r),0,7)&&(r=\"[\"+p(f(r),/^Symbol\\(([^)]*)\\).*$/,\"$1\")+\"]\"),e&&e.getter&&(r=\"get \"+r),e&&e.setter&&(r=\"set \"+r),(!n(t,\"name\")||i&&t.name!==r)&&(o?l(t,\"name\",{value:r,configurable:!0}):t.name=r),v&&e&&n(e,\"arity\")&&t.length!==e.arity&&l(t,\"length\",{value:e.arity});try{e&&n(e,\"constructor\")&&e.constructor?o&&l(t,\"prototype\",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var s=u(t);return n(s,\"source\")||(s.source=m(y,\"string\"==typeof r?r:\"\")),t};return Function.prototype.toString=w(function(){return e(this)&&c(this).source||s(this)},\"toString\"),Rr.exports}function Ur(){if(qr)return Lr;qr=1;var t=pt(),r=wr(),e=Nr(),n=Xt();return Lr=function(o,i,s,a){a||(a={});var u=a.enumerable,c=void 0!==a.name?a.name:i;if(t(s)&&e(s,c,a),a.global)u?o[i]=s:n(i,s);else{try{a.unsafe?o[i]&&(u=!0):delete o[i]}catch(t){}u?o[i]=s:r.f(o,i,{value:s,enumerable:!1,configurable:!a.nonConfigurable,writable:!a.nonWritable})}return o}}var Br,Wr,$r,Vr,Gr,Hr,Kr,Yr,Xr,Jr,Qr,te,re,ee,ne,oe,ie,se={};function ae(){if(Vr)return $r;Vr=1;var t=function(){if(Wr)return Br;Wr=1;var t=Math.ceil,r=Math.floor;return Br=Math.trunc||function(e){var n=+e;return(n>0?r:t)(n)}}();return $r=function(r){var e=+r;return e!=e||0===e?0:t(e)}}function ue(){if(Hr)return Gr;Hr=1;var t=ae(),r=Math.max,e=Math.min;return Gr=function(n,o){var i=t(n);return i<0?r(i+o,0):e(i,o)}}function ce(){if(Yr)return Kr;Yr=1;var t=ae(),r=Math.min;return Kr=function(e){var n=t(e);return n>0?r(n,9007199254740991):0}}function fe(){if(Jr)return Xr;Jr=1;var t=ce();return Xr=function(r){return t(r.length)}}function le(){if(ee)return re;ee=1;var t=ut(),r=rr(),e=ht(),n=function(){if(te)return Qr;te=1;var t=ht(),r=ue(),e=fe(),n=function(n){return function(o,i,s){var a=t(o),u=e(a);if(0===u)return!n&&-1;var c,f=r(s,u);if(n&&i!=i){for(;u>f;)if((c=a[f++])!=c)return!0}else for(;u>f;f++)if((n||f in a)&&a[f]===i)return n||f||0;return!n&&-1}};return Qr={includes:n(!0),indexOf:n(!1)}}().indexOf,o=Dr(),i=t([].push);return re=function(t,s){var a,u=e(t),c=0,f=[];for(a in u)!r(o,a)&&r(u,a)&&i(f,a);for(;s.length>c;)r(u,a=s[c++])&&(~n(f,a)||i(f,a));return f}}function he(){return oe?ne:(oe=1,ne=[\"constructor\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"toLocaleString\",\"toString\",\"valueOf\"])}var pe,me,de,ge,ve,ye,we,be,Ee,ke,xe,Me,Oe,Pe,Ce,Se,je,Ae,Ie,_e={};function Te(){if(de)return me;de=1;var t=dt(),r=ut(),e=function(){if(ie)return se;ie=1;var t=le(),r=he().concat(\"length\",\"prototype\");return se.f=Object.getOwnPropertyNames||function(e){return t(e,r)},se}(),n=(pe||(pe=1,_e.f=Object.getOwnPropertySymbols),_e),o=yr(),i=r([].concat);return me=t(\"Reflect\",\"ownKeys\")||function(t){var r=e.f(o(t)),s=n.f;return s?i(r,s(t)):r},me}function Le(){if(ve)return ge;ve=1;var t=rr(),r=Te(),e=ur(),n=wr();return ge=function(o,i,s){for(var a=r(i),u=n.f,c=e.f,f=0;f<a.length;f++){var l=a[f];t(o,l)||s&&t(s,l)||u(o,l,c(i,l))}},ge}function qe(){if(Ee)return be;Ee=1;var t=i(),r=ur().f,e=br(),n=Ur(),o=Xt(),s=Le(),a=function(){if(we)return ye;we=1;var t=d(),r=pt(),e=/#|\\.prototype\\./,n=function(e,n){var u=i[o(e)];return u===a||u!==s&&(r(n)?t(n):!!n)},o=n.normalize=function(t){return String(t).replace(e,\".\").toLowerCase()},i=n.data={},s=n.NATIVE=\"N\",a=n.POLYFILL=\"P\";return ye=n}();return be=function(i,u){var c,f,l,h,p,m=i.target,d=i.global,g=i.stat;if(c=d?t:g?t[m]||o(m,{}):t[m]&&t[m].prototype)for(f in u){if(h=u[f],l=i.dontCallGetSet?(p=r(c,f))&&p.value:c[f],!a(d?f:m+(g?\".\":\"#\")+f,i.forced)&&void 0!==l){if(typeof h==typeof l)continue;s(h,l)}(i.sham||l&&l.sham)&&e(h,\"sham\",!0),n(c,f,h,i)}}}function Re(){if(xe)return ke;xe=1;var t=gt(),r=TypeError;return ke=function(e,n){if(t(n,e))return e;throw new r(\"Incorrect invocation\")}}function Ze(){if(Ce)return Pe;Ce=1;var t=rr(),r=pt(),e=tr(),n=zr(),o=function(){if(Oe)return Me;Oe=1;var t=d();return Me=!t(function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype})}(),i=n(\"IE_PROTO\"),s=Object,a=s.prototype;return Pe=o?s.getPrototypeOf:function(n){var o=e(n);if(t(o,i))return o[i];var u=o.constructor;return r(u)&&o instanceof u?u.prototype:o instanceof s?a:null}}function ze(){if(je)return Se;je=1;var t=Nr(),r=wr();return Se=function(e,n,o){return o.get&&t(o.get,n,{getter:!0}),o.set&&t(o.set,n,{setter:!0}),r.f(e,n,o)}}function De(){if(Ie)return Ae;Ie=1;var t=g(),r=wr(),e=at();return Ae=function(n,o,i){t?r.f(n,o,e(0,i)):n[o]=i}}var Fe,Ne,Ue,Be,We,$e,Ve,Ge,He,Ke,Ye,Xe={};function Je(){if(Ne)return Fe;Ne=1;var t=le(),r=he();return Fe=Object.keys||function(e){return t(e,r)}}function Qe(){if(We)return Be;We=1;var t=dt();return Be=t(\"document\",\"documentElement\")}function tn(){if(Ve)return $e;Ve=1;var t,r=yr(),e=function(){if(Ue)return Xe;Ue=1;var t=g(),r=vr(),e=wr(),n=yr(),o=ht(),i=Je();return Xe.f=t&&!r?Object.defineProperties:function(t,r){n(t);for(var s,a=o(r),u=i(r),c=u.length,f=0;c>f;)e.f(t,s=u[f++],a[s]);return t},Xe}(),n=he(),o=Dr(),i=Qe(),s=sr(),a=zr(),u=\"prototype\",c=\"script\",f=a(\"IE_PROTO\"),l=function(){},h=function(t){return\"<\"+c+\">\"+t+\"</\"+c+\">\"},p=function(t){t.write(h(\"\")),t.close();var r=t.parentWindow.Object;return t=null,r},m=function(){try{t=new ActiveXObject(\"htmlfile\")}catch(t){}var r,e,o;m=\"undefined\"!=typeof document?document.domain&&t?p(t):(e=s(\"iframe\"),o=\"java\"+c+\":\",e.style.display=\"none\",i.appendChild(e),e.src=String(o),(r=e.contentWindow.document).open(),r.write(h(\"document.F=Object\")),r.close(),r.F):p(t);for(var a=n.length;a--;)delete m[u][n[a]];return m()};return o[f]=!0,$e=Object.create||function(t,n){var o;return null!==t?(l[u]=r(t),o=new l,l[u]=null,o[f]=t):o=m(),void 0===n?o:e.f(o,n)}}function rn(){if(He)return Ge;He=1;var t,r,e,n=d(),o=pt(),i=mt(),s=tn(),a=Ze(),u=Ur(),c=nr(),f=Yt(),l=c(\"iterator\"),h=!1;return[].keys&&(\"next\"in(e=[].keys())?(r=a(a(e)))!==Object.prototype&&(t=r):h=!0),!i(t)||n(function(){var r={};return t[l].call(r)!==r})?t={}:f&&(t=s(t)),o(t[l])||u(t,l,function(){return this}),Ge={IteratorPrototype:t,BUGGY_SAFARI_ITERATORS:h}}Ye||(Ye=1,function(){if(Ke)return o;Ke=1;var t=qe(),r=i(),e=Re(),n=yr(),s=pt(),a=Ze(),u=ze(),c=De(),f=d(),l=rr(),h=nr(),p=rn().IteratorPrototype,m=g(),v=Yt(),y=\"constructor\",w=\"Iterator\",b=h(\"toStringTag\"),E=TypeError,k=r[w],x=v||!s(k)||k.prototype!==p||!f(function(){k({})}),M=function(){if(e(this,p),a(this)===p)throw new E(\"Abstract class Iterator not directly constructable\")},O=function(t,r){m?u(p,t,{configurable:!0,get:function(){return r},set:function(r){if(n(this),this===p)throw new E(\"You can't redefine this property\");l(this,t)?this[t]=r:c(this,t,r)}}):p[t]=r};l(p,b)||O(b,w),!x&&l(p,y)&&p[y]!==Object||O(y,M),M.prototype=p,t({global:!0,constructor:!0,forced:x},{Iterator:M})}());var en,nn,on,sn,an,un,cn,fn,ln,hn,pn,mn,dn,gn,vn,yn,wn,bn,En,kn,xn={};function Mn(){return nn?en:(nn=1,en=function(t){return{iterator:t,next:t.next,done:!1}})}function On(){if(sn)return on;sn=1;var t=Ur();return on=function(r,e,n){for(var o in e)t(r,o,e[o],n);return r}}function Pn(){return un?an:(un=1,an=function(t,r){return{value:t,done:r}})}function Cn(){if(fn)return cn;fn=1;var t=y(),r=yr(),e=xt();return cn=function(n,o,i){var s,a;r(n);try{if(!(s=e(n,\"return\"))){if(\"throw\"===o)throw i;return i}s=t(s,n)}catch(t){a=!0,s=t}if(\"throw\"===o)throw i;if(a)throw s;return r(s),i}}function Sn(){if(hn)return ln;hn=1;var t=Cn();return ln=function(r,e,n){for(var o=r.length-1;o>=0;o--)if(void 0!==r[o])try{n=t(r[o].iterator,e,n)}catch(t){e=\"throw\",n=t}if(\"throw\"===e)throw n;return n}}function jn(){if(mn)return pn;mn=1;var t=y(),r=tn(),e=br(),n=On(),o=nr(),i=Fr(),s=xt(),a=rn().IteratorPrototype,u=Pn(),c=Cn(),f=Sn(),l=o(\"toStringTag\"),h=\"IteratorHelper\",p=\"WrapForValidIterator\",m=\"normal\",d=\"throw\",g=i.set,v=function(e){var o=i.getterFor(e?p:h);return n(r(a),{next:function(){var t=o(this);if(e)return t.nextHandler();if(t.done)return u(void 0,!0);try{var r=t.nextHandler();return t.returnHandlerResult?r:u(r,t.done)}catch(r){throw t.done=!0,r}},return:function(){var r=o(this),n=r.iterator;if(r.done=!0,e){var i=s(n,\"return\");return i?t(i,n):u(void 0,!0)}if(r.inner)try{c(r.inner.iterator,m)}catch(t){return c(n,d,t)}if(r.openIters)try{f(r.openIters,m)}catch(t){return c(n,d,t)}return n&&c(n,m),u(void 0,!0)}})},w=v(!0),b=v(!1);return e(b,l,\"Iterator Helper\"),pn=function(t,r,e){var n=function(n,o){o?(o.iterator=n.iterator,o.next=n.next):o=n,o.type=r?p:h,o.returnHandlerResult=!!e,o.nextHandler=t,o.counter=0,o.done=!1,g(this,o)};return n.prototype=r?w:b,n}}function An(){if(gn)return dn;gn=1;var t=yr(),r=Cn();return dn=function(e,n,o,i){try{return i?n(t(o)[0],o[1]):n(o)}catch(t){r(e,\"throw\",t)}}}function In(){return yn?vn:(yn=1,vn=function(t,r){var e=\"function\"==typeof Iterator&&Iterator.prototype[t];if(e)try{e.call({next:null},r).next()}catch(t){return!0}})}function _n(){if(bn)return wn;bn=1;var t=i();return wn=function(r,e){var n=t.Iterator,o=n&&n.prototype,i=o&&o[r],s=!1;if(i)try{i.call({next:function(){return{done:!0}},return:function(){s=!0}},-1)}catch(t){t instanceof e||(s=!1)}if(!s)return i}}function Tn(t,r){var e={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&r.indexOf(n)<0&&(e[n]=t[n]);if(null!=t&&\"function\"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(t);o<n.length;o++)r.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(t,n[o])&&(e[n[o]]=t[n[o]])}return e}kn||(kn=1,function(){if(En)return xn;En=1;var t=qe(),r=y(),e=kt(),n=yr(),o=Mn(),i=jn(),s=An(),a=Cn(),u=In(),c=_n(),f=Yt(),l=!f&&!u(\"map\",function(){}),h=!f&&!l&&c(\"map\",TypeError),p=f||l||h,m=i(function(){var t=this.iterator,e=n(r(this.next,t));if(!(this.done=!!e.done))return s(t,this.mapper,[e.value,this.counter++],!0)});t({target:\"Iterator\",proto:!0,real:!0,forced:p},{map:function(t){n(this);try{e(t)}catch(t){a(this,\"throw\",t)}return h?r(h,this,t):new m(o(this),{mapper:t})}})}()),\"function\"==typeof SuppressedError&&SuppressedError;var Ln,qn,Rn={};qn||(qn=1,function(){if(Ln)return Rn;Ln=1;var t=qe(),r=y(),e=kt(),n=yr(),o=Mn(),i=jn(),s=An(),a=Yt(),u=Cn(),c=In(),f=_n(),l=!a&&!c(\"filter\",function(){}),h=!a&&!l&&f(\"filter\",TypeError),p=a||l||h,m=i(function(){for(var t,e,o=this.iterator,i=this.predicate,a=this.next;;){if(t=n(r(a,o)),this.done=!!t.done)return;if(e=t.value,s(o,i,[e,this.counter++],!0))return e}});t({target:\"Iterator\",proto:!0,real:!0,forced:p},{filter:function(t){n(this);try{e(t)}catch(t){u(this,\"throw\",t)}return h?r(h,this,t):new m(o(this),{predicate:t})}})}());class Zn{static isAdvancedMarkerAvailable(t){return google.maps.marker&&!0===t.getMapCapabilities().isAdvancedMarkersAvailable}static isAdvancedMarker(t){return google.maps.marker&&t instanceof google.maps.marker.AdvancedMarkerElement}static setMap(t,r){this.isAdvancedMarker(t)?t.map=r:t.setMap(r)}static getPosition(t){if(this.isAdvancedMarker(t)){if(t.position){if(t.position instanceof google.maps.LatLng)return t.position;if(Number.isFinite(t.position.lat)&&Number.isFinite(t.position.lng))return new google.maps.LatLng(t.position.lat,t.position.lng)}return new google.maps.LatLng(null)}return t.getPosition()}static getVisible(t){return!!this.isAdvancedMarker(t)||t.getVisible()}}class zn{constructor(t){let{markers:r,position:e}=t;this.markers=[],r&&(this.markers=r),e&&(e instanceof google.maps.LatLng?this._position=e:this._position=new google.maps.LatLng(e))}get bounds(){if(0===this.markers.length&&!this._position)return;const t=new google.maps.LatLngBounds(this._position,this._position);for(const r of this.markers)t.extend(Zn.getPosition(r));return t}get position(){return this._position||this.bounds.getCenter()}get count(){return this.markers.filter(t=>Zn.getVisible(t)).length}push(t){this.markers.push(t)}delete(){this.marker&&(Zn.setMap(this.marker,null),this.marker=void 0),this.markers.length=0}}function Dn(t){if(null==t)throw Error(arguments.length>1&&void 0!==arguments[1]?arguments[1]:\"assertion failed\")}const Fn=(t,r,e,n)=>{const o=t.getBounds();Dn(o);const i=Nn(o,r,n);return e.filter(t=>i.contains(Zn.getPosition(t)))},Nn=(t,r,e)=>{const{northEast:n,southWest:o}=Wn(t,r),i=$n({northEast:n,southWest:o},e);return Vn(i,r)},Un=(t,r,e)=>{const n=Nn(t,r,e),o=n.getNorthEast(),i=n.getSouthWest();return[i.lng(),i.lat(),o.lng(),o.lat()]},Bn=(t,r)=>{const e=(r.lat-t.lat)*Math.PI/180,n=(r.lng-t.lng)*Math.PI/180,o=Math.sin(e/2),i=Math.sin(n/2),s=o*o+Math.cos(t.lat*Math.PI/180)*Math.cos(r.lat*Math.PI/180)*i*i;return 6371*(2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s)))},Wn=(t,r)=>{const e=r.fromLatLngToDivPixel(t.getNorthEast()),n=r.fromLatLngToDivPixel(t.getSouthWest());return Dn(e),Dn(n),{northEast:e,southWest:n}},$n=(t,r)=>{let{northEast:e,southWest:n}=t;return e.x+=r,e.y-=r,n.x-=r,n.y+=r,{northEast:e,southWest:n}},Vn=(t,r)=>{let{northEast:e,southWest:n}=t;const o=r.fromDivPixelToLatLng(n),i=r.fromDivPixelToLatLng(e);return new google.maps.LatLngBounds(o,i)};class Gn{constructor(t){let{maxZoom:r=16}=t;this.maxZoom=r}noop(t){let{markers:r}=t;return Kn(r)}}class Hn extends Gn{constructor(t){var{viewportPadding:r=60}=t;super(Tn(t,[\"viewportPadding\"])),this.viewportPadding=60,this.viewportPadding=r}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();return Dn(o),o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:!1}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}}const Kn=t=>t.map(t=>new zn({position:Zn.getPosition(t),markers:[t]}));var Yn,Xn,Jn,Qn,to,ro,eo,no,oo,io,so,ao,uo,co,fo,lo,ho,po,mo,go,vo={};function yo(){if(Qn)return Jn;Qn=1;var t=function(){if(Xn)return Yn;Xn=1;var t=ct(),r=ut();return Yn=function(e){if(\"Function\"===t(e))return r(e)}}(),r=kt(),e=v(),n=t(t.bind);return Jn=function(t,o){return r(t),void 0===o?t:e?n(t,o):function(){return t.apply(o,arguments)}},Jn}function wo(){return ro?to:(ro=1,to={})}function bo(){if(no)return eo;no=1;var t=nr(),r=wo(),e=t(\"iterator\"),n=Array.prototype;return eo=function(t){return void 0!==t&&(r.Array===t||n[e]===t)}}function Eo(){if(ao)return so;ao=1;var t=function(){if(io)return oo;io=1;var t={};return t[nr()(\"toStringTag\")]=\"z\",oo=\"[object z]\"===String(t)}(),r=pt(),e=ct(),n=nr()(\"toStringTag\"),o=Object,i=\"Arguments\"===e(function(){return arguments}());return so=t?e:function(t){var s,a,u;return void 0===t?\"Undefined\":null===t?\"Null\":\"string\"==typeof(a=function(t,r){try{return t[r]}catch(t){}}(s=o(t),n))?a:i?e(s):\"Object\"===(u=e(s))&&r(s.callee)?\"Arguments\":u}}function ko(){if(co)return uo;co=1;var t=Eo(),r=xt(),e=ft(),n=wo(),o=nr()(\"iterator\");return uo=function(i){if(!e(i))return r(i,o)||r(i,\"@@iterator\")||n[t(i)]}}function xo(){if(lo)return fo;lo=1;var t=y(),r=kt(),e=yr(),n=Et(),o=ko(),i=TypeError;return fo=function(s,a){var u=arguments.length<2?o(s):a;if(r(u))return e(t(u,s));throw new i(n(s)+\" is not iterable\")},fo}function Mo(){if(po)return ho;po=1;var t=yo(),r=y(),e=yr(),n=Et(),o=bo(),i=fe(),s=gt(),a=xo(),u=ko(),c=Cn(),f=TypeError,l=function(t,r){this.stopped=t,this.result=r},h=l.prototype;return ho=function(p,m,d){var g,v,y,w,b,E,k,x=d&&d.that,M=!(!d||!d.AS_ENTRIES),O=!(!d||!d.IS_RECORD),P=!(!d||!d.IS_ITERATOR),C=!(!d||!d.INTERRUPTED),S=t(m,x),j=function(t){return g&&c(g,\"normal\"),new l(!0,t)},A=function(t){return M?(e(t),C?S(t[0],t[1],j):S(t[0],t[1])):C?S(t,j):S(t)};if(O)g=p.iterator;else if(P)g=p;else{if(!(v=u(p)))throw new f(n(p)+\" is not iterable\");if(o(v)){for(y=0,w=i(p);w>y;y++)if((b=A(p[y]))&&s(h,b))return b;return new l(!1)}g=a(p,v)}for(E=O?p.next:g.next;!(k=r(E,g)).done;){try{b=A(k.value)}catch(t){c(g,\"throw\",t)}if(\"object\"==typeof b&&b&&s(h,b))return b}return new l(!1)}}go||(go=1,function(){if(mo)return vo;mo=1;var t=qe(),r=y(),e=Mo(),n=kt(),o=yr(),i=Mn(),s=Cn(),a=_n()(\"forEach\",TypeError);t({target:\"Iterator\",proto:!0,real:!0,forced:a},{forEach:function(t){o(this);try{n(t)}catch(t){s(this,\"throw\",t)}if(a)return r(a,this,t);var u=i(this),c=0;e(u,function(r){t(r,c++)},{IS_RECORD:!0})}})}());var Oo=Object.getOwnPropertyNames,Po=Object.getOwnPropertySymbols,Co=Object.prototype.hasOwnProperty;function So(t,r){return function(e,n,o){return t(e,n,o)&&r(e,n,o)}}function jo(t){return function(r,e,n){if(!r||!e||\"object\"!=typeof r||\"object\"!=typeof e)return t(r,e,n);var o=n.cache,i=o.get(r),s=o.get(e);if(i&&s)return i===e&&s===r;o.set(r,e),o.set(e,r);var a=t(r,e,n);return o.delete(r),o.delete(e),a}}function Ao(t){return Oo(t).concat(Po(t))}var Io=Object.hasOwn||function(t,r){return Co.call(t,r)};function _o(t,r){return t===r||!t&&!r&&t!=t&&r!=r}var To=Object.getOwnPropertyDescriptor,Lo=Object.keys;function qo(t,r,e){var n=t.length;if(r.length!==n)return!1;for(;n-- >0;)if(!e.equals(t[n],r[n],n,n,t,r,e))return!1;return!0}function Ro(t,r){return _o(t.getTime(),r.getTime())}function Zo(t,r){return t.name===r.name&&t.message===r.message&&t.cause===r.cause&&t.stack===r.stack}function zo(t,r){return t===r}function Do(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.entries(),u=0;(o=a.next())&&!o.done;){for(var c=r.entries(),f=!1,l=0;(i=c.next())&&!i.done;)if(s[l])l++;else{var h=o.value,p=i.value;if(e.equals(h[0],p[0],u,l,t,r,e)&&e.equals(h[1],p[1],h[0],p[0],t,r,e)){f=s[l]=!0;break}l++}if(!f)return!1;u++}return!0}var Fo=_o;function No(t,r,e){var n=Lo(t),o=n.length;if(Lo(r).length!==o)return!1;for(;o-- >0;)if(!Ho(t,r,e,n[o]))return!1;return!0}function Uo(t,r,e){var n,o,i,s=Ao(t),a=s.length;if(Ao(r).length!==a)return!1;for(;a-- >0;){if(!Ho(t,r,e,n=s[a]))return!1;if(o=To(t,n),i=To(r,n),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable))return!1}return!0}function Bo(t,r){return _o(t.valueOf(),r.valueOf())}function Wo(t,r){return t.source===r.source&&t.flags===r.flags}function $o(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.values();(o=a.next())&&!o.done;){for(var u=r.values(),c=!1,f=0;(i=u.next())&&!i.done;){if(!s[f]&&e.equals(o.value,i.value,o.value,i.value,t,r,e)){c=s[f]=!0;break}f++}if(!c)return!1}return!0}function Vo(t,r){var e=t.length;if(r.length!==e)return!1;for(;e-- >0;)if(t[e]!==r[e])return!1;return!0}function Go(t,r){return t.hostname===r.hostname&&t.pathname===r.pathname&&t.protocol===r.protocol&&t.port===r.port&&t.hash===r.hash&&t.username===r.username&&t.password===r.password}function Ho(t,r,e,n){return!(\"_owner\"!==n&&\"__o\"!==n&&\"__v\"!==n||!t.$typeof&&!r.$typeof)||Io(r,n)&&e.equals(t[n],r[n],n,n,t,r,e)}var Ko=Array.isArray,Yo=\"function\"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,Xo=Object.assign,Jo=Object.prototype.toString.call.bind(Object.prototype.toString);var Qo=ti();function ti(t){void 0===t&&(t={});var r,e=t.circular,n=void 0!==e&&e,o=t.createInternalComparator,i=t.createState,s=t.strict,a=void 0!==s&&s,u=function(t){var r=t.circular,e=t.createCustomConfig,n=t.strict,o={areArraysEqual:n?Uo:qo,areDatesEqual:Ro,areErrorsEqual:Zo,areFunctionsEqual:zo,areMapsEqual:n?So(Do,Uo):Do,areNumbersEqual:Fo,areObjectsEqual:n?Uo:No,arePrimitiveWrappersEqual:Bo,areRegExpsEqual:Wo,areSetsEqual:n?So($o,Uo):$o,areTypedArraysEqual:n?Uo:Vo,areUrlsEqual:Go};if(e&&(o=Xo({},o,e(o))),r){var i=jo(o.areArraysEqual),s=jo(o.areMapsEqual),a=jo(o.areObjectsEqual),u=jo(o.areSetsEqual);o=Xo({},o,{areArraysEqual:i,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:u})}return o}(t),c=function(t){var r=t.areArraysEqual,e=t.areDatesEqual,n=t.areErrorsEqual,o=t.areFunctionsEqual,i=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,u=t.arePrimitiveWrappersEqual,c=t.areRegExpsEqual,f=t.areSetsEqual,l=t.areTypedArraysEqual,h=t.areUrlsEqual;return function(t,p,m){if(t===p)return!0;if(null==t||null==p)return!1;var d=typeof t;if(d!==typeof p)return!1;if(\"object\"!==d)return\"number\"===d?s(t,p,m):\"function\"===d&&o(t,p,m);var g=t.constructor;if(g!==p.constructor)return!1;if(g===Object)return a(t,p,m);if(Ko(t))return r(t,p,m);if(null!=Yo&&Yo(t))return l(t,p,m);if(g===Date)return e(t,p,m);if(g===RegExp)return c(t,p,m);if(g===Map)return i(t,p,m);if(g===Set)return f(t,p,m);var v=Jo(t);return\"[object Date]\"===v?e(t,p,m):\"[object RegExp]\"===v?c(t,p,m):\"[object Map]\"===v?i(t,p,m):\"[object Set]\"===v?f(t,p,m):\"[object Object]\"===v?\"function\"!=typeof t.then&&\"function\"!=typeof p.then&&a(t,p,m):\"[object URL]\"===v?h(t,p,m):\"[object Error]\"===v?n(t,p,m):\"[object Arguments]\"===v?a(t,p,m):(\"[object Boolean]\"===v||\"[object Number]\"===v||\"[object String]\"===v)&&u(t,p,m)}}(u);return function(t){var r=t.circular,e=t.comparator,n=t.createState,o=t.equals,i=t.strict;if(n)return function(t,s){var a=n(),u=a.cache,c=void 0===u?r?new WeakMap:void 0:u,f=a.meta;return e(t,s,{cache:c,equals:o,meta:f,strict:i})};if(r)return function(t,r){return e(t,r,{cache:new WeakMap,equals:o,meta:void 0,strict:i})};var s={cache:void 0,equals:o,meta:void 0,strict:i};return function(t,r){return e(t,r,s)}}({circular:n,comparator:c,createState:i,equals:o?o(c):(r=c,function(t,e,n,o,i,s,a){return r(t,e,a)}),strict:a})}ti({strict:!0}),ti({circular:!0}),ti({circular:!0,strict:!0}),ti({createInternalComparator:function(){return _o}}),ti({strict:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o},strict:!0});const ri=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class ei{static from(t){if(!(t instanceof ArrayBuffer))throw new Error(\"Data must be an instance of ArrayBuffer.\");const[r,e]=new Uint8Array(t,0,2);if(219!==r)throw new Error(\"Data does not appear to be in a KDBush format.\");const n=e>>4;if(1!==n)throw new Error(`Got v${n} data when expected v1.`);const o=ri[15&e];if(!o)throw new Error(\"Unrecognized array type.\");const[i]=new Uint16Array(t,2,1),[s]=new Uint32Array(t,4,1);return new ei(s,i,o,t)}constructor(t,r=64,e=Float64Array,n){if(isNaN(t)||t<0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+r,2),65535),this.ArrayType=e,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const o=ri.indexOf(this.ArrayType),i=2*t*this.ArrayType.BYTES_PER_ELEMENT,s=t*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-s%8)%8;if(o<0)throw new Error(`Unexpected typed array class: ${e}.`);n&&n instanceof ArrayBuffer?(this.data=n,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+i+s+a),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+o]),new Uint16Array(this.data,2,1)[0]=r,new Uint32Array(this.data,4,1)[0]=t)}add(t,r){const e=this._pos>>1;return this.ids[e]=e,this.coords[this._pos++]=t,this.coords[this._pos++]=r,e}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return ni(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(t,r,e,n){if(!this._finished)throw new Error(\"Data not yet indexed - call index.finish().\");const{ids:o,coords:i,nodeSize:s}=this,a=[0,o.length-1,0],u=[];for(;a.length;){const c=a.pop()||0,f=a.pop()||0,l=a.pop()||0;if(f-l<=s){for(let s=l;s<=f;s++){const a=i[2*s],c=i[2*s+1];a>=t&&a<=e&&c>=r&&c<=n&&u.push(o[s])}continue}const h=l+f>>1,p=i[2*h],m=i[2*h+1];p>=t&&p<=e&&m>=r&&m<=n&&u.push(o[h]),(0===c?t<=p:r<=m)&&(a.push(l),a.push(h-1),a.push(1-c)),(0===c?e>=p:n>=m)&&(a.push(h+1),a.push(f),a.push(1-c))}return u}within(t,r,e){if(!this._finished)throw new Error(\"Data not yet indexed - call index.finish().\");const{ids:n,coords:o,nodeSize:i}=this,s=[0,n.length-1,0],a=[],u=e*e;for(;s.length;){const c=s.pop()||0,f=s.pop()||0,l=s.pop()||0;if(f-l<=i){for(let e=l;e<=f;e++)ai(o[2*e],o[2*e+1],t,r)<=u&&a.push(n[e]);continue}const h=l+f>>1,p=o[2*h],m=o[2*h+1];ai(p,m,t,r)<=u&&a.push(n[h]),(0===c?t-e<=p:r-e<=m)&&(s.push(l),s.push(h-1),s.push(1-c)),(0===c?t+e>=p:r+e>=m)&&(s.push(h+1),s.push(f),s.push(1-c))}return a}}function ni(t,r,e,n,o,i){if(o-n<=e)return;const s=n+o>>1;oi(t,r,s,n,o,i),ni(t,r,e,n,s-1,1-i),ni(t,r,e,s+1,o,1-i)}function oi(t,r,e,n,o,i){for(;o>n;){if(o-n>600){const s=o-n+1,a=e-n+1,u=Math.log(s),c=.5*Math.exp(2*u/3),f=.5*Math.sqrt(u*c*(s-c)/s)*(a-s/2<0?-1:1);oi(t,r,e,Math.max(n,Math.floor(e-a*c/s+f)),Math.min(o,Math.floor(e+(s-a)*c/s+f)),i)}const s=r[2*e+i];let a=n,u=o;for(ii(t,r,n,e),r[2*o+i]>s&&ii(t,r,n,o);a<u;){for(ii(t,r,a,u),a++,u--;r[2*a+i]<s;)a++;for(;r[2*u+i]>s;)u--}r[2*n+i]===s?ii(t,r,n,u):(u++,ii(t,r,u,o)),u<=e&&(n=u+1),e<=u&&(o=u-1)}}function ii(t,r,e,n){si(t,e,n),si(r,2*e,2*n),si(r,2*e+1,2*n+1)}function si(t,r,e){const n=t[r];t[r]=t[e],t[e]=n}function ai(t,r,e,n){const o=t-e,i=r-n;return o*o+i*i}const ui={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:t=>t},ci=Math.fround||(fi=new Float32Array(1),t=>(fi[0]=+t,fi[0]));var fi;class li{constructor(t){this.options=Object.assign(Object.create(ui),t),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(t){const{log:r,minZoom:e,maxZoom:n}=this.options;r&&console.time(\"total time\");const o=`prepare ${t.length} points`;r&&console.time(o),this.points=t;const i=[];for(let r=0;r<t.length;r++){const e=t[r];if(!e.geometry)continue;const[n,o]=e.geometry.coordinates,s=ci(mi(n)),a=ci(di(o));i.push(s,a,1/0,r,-1,1),this.options.reduce&&i.push(0)}let s=this.trees[n+1]=this._createTree(i);r&&console.timeEnd(o);for(let t=n;t>=e;t--){const e=+Date.now();s=this.trees[t]=this._createTree(this._cluster(s,t)),r&&console.log(\"z%d: %d clusters in %dms\",t,s.numItems,+Date.now()-e)}return r&&console.timeEnd(\"total time\"),this}getClusters(t,r){let e=((t[0]+180)%360+360)%360-180;const n=Math.max(-90,Math.min(90,t[1]));let o=180===t[2]?180:((t[2]+180)%360+360)%360-180;const i=Math.max(-90,Math.min(90,t[3]));if(t[2]-t[0]>=360)e=-180,o=180;else if(e>o){const t=this.getClusters([e,n,180,i],r),s=this.getClusters([-180,n,o,i],r);return t.concat(s)}const s=this.trees[this._limitZoom(r)],a=s.range(mi(e),di(i),mi(o),di(n)),u=s.data,c=[];for(const t of a){const r=this.stride*t;c.push(u[r+5]>1?hi(u,r,this.clusterProps):this.points[u[r+3]])}return c}getChildren(t){const r=this._getOriginId(t),e=this._getOriginZoom(t),n=\"No cluster with the specified id.\",o=this.trees[e];if(!o)throw new Error(n);const i=o.data;if(r*this.stride>=i.length)throw new Error(n);const s=this.options.radius/(this.options.extent*Math.pow(2,e-1)),a=i[r*this.stride],u=i[r*this.stride+1],c=o.within(a,u,s),f=[];for(const r of c){const e=r*this.stride;i[e+4]===t&&f.push(i[e+5]>1?hi(i,e,this.clusterProps):this.points[i[e+3]])}if(0===f.length)throw new Error(n);return f}getLeaves(t,r,e){r=r||10,e=e||0;const n=[];return this._appendLeaves(n,t,r,e,0),n}getTile(t,r,e){const n=this.trees[this._limitZoom(t)],o=Math.pow(2,t),{extent:i,radius:s}=this.options,a=s/i,u=(e-a)/o,c=(e+1+a)/o,f={features:[]};return this._addTileFeatures(n.range((r-a)/o,u,(r+1+a)/o,c),n.data,r,e,o,f),0===r&&this._addTileFeatures(n.range(1-a/o,u,1,c),n.data,o,e,o,f),r===o-1&&this._addTileFeatures(n.range(0,u,a/o,c),n.data,-1,e,o,f),f.features.length?f:null}getClusterExpansionZoom(t){let r=this._getOriginZoom(t)-1;for(;r<=this.options.maxZoom;){const e=this.getChildren(t);if(r++,1!==e.length)break;t=e[0].properties.cluster_id}return r}_appendLeaves(t,r,e,n,o){const i=this.getChildren(r);for(const r of i){const i=r.properties;if(i&&i.cluster?o+i.point_count<=n?o+=i.point_count:o=this._appendLeaves(t,i.cluster_id,e,n,o):o<n?o++:t.push(r),t.length===e)break}return o}_createTree(t){const r=new ei(t.length/this.stride|0,this.options.nodeSize,Float32Array);for(let e=0;e<t.length;e+=this.stride)r.add(t[e],t[e+1]);return r.finish(),r.data=t,r}_addTileFeatures(t,r,e,n,o,i){for(const s of t){const t=s*this.stride,a=r[t+5]>1;let u,c,f;if(a)u=pi(r,t,this.clusterProps),c=r[t],f=r[t+1];else{const e=this.points[r[t+3]];u=e.properties;const[n,o]=e.geometry.coordinates;c=mi(n),f=di(o)}const l={type:1,geometry:[[Math.round(this.options.extent*(c*o-e)),Math.round(this.options.extent*(f*o-n))]],tags:u};let h;h=a||this.options.generateId?r[t+3]:this.points[r[t+3]].id,void 0!==h&&(l.id=h),i.features.push(l)}}_limitZoom(t){return Math.max(this.options.minZoom,Math.min(Math.floor(+t),this.options.maxZoom+1))}_cluster(t,r){const{radius:e,extent:n,reduce:o,minPoints:i}=this.options,s=e/(n*Math.pow(2,r)),a=t.data,u=[],c=this.stride;for(let e=0;e<a.length;e+=c){if(a[e+2]<=r)continue;a[e+2]=r;const n=a[e],f=a[e+1],l=t.within(a[e],a[e+1],s),h=a[e+5];let p=h;for(const t of l){const e=t*c;a[e+2]>r&&(p+=a[e+5])}if(p>h&&p>=i){let t,i=n*h,s=f*h,m=-1;const d=(e/c<<5)+(r+1)+this.points.length;for(const n of l){const u=n*c;if(a[u+2]<=r)continue;a[u+2]=r;const f=a[u+5];i+=a[u]*f,s+=a[u+1]*f,a[u+4]=d,o&&(t||(t=this._map(a,e,!0),m=this.clusterProps.length,this.clusterProps.push(t)),o(t,this._map(a,u)))}a[e+4]=d,u.push(i/p,s/p,1/0,d,-1,p),o&&u.push(m)}else{for(let t=0;t<c;t++)u.push(a[e+t]);if(p>1)for(const t of l){const e=t*c;if(!(a[e+2]<=r)){a[e+2]=r;for(let t=0;t<c;t++)u.push(a[e+t])}}}}return u}_getOriginId(t){return t-this.points.length>>5}_getOriginZoom(t){return(t-this.points.length)%32}_map(t,r,e){if(t[r+5]>1){const n=this.clusterProps[t[r+6]];return e?Object.assign({},n):n}const n=this.points[t[r+3]].properties,o=this.options.map(n);return e&&o===n?Object.assign({},o):o}}function hi(t,r,e){return{type:\"Feature\",id:t[r+3],properties:pi(t,r,e),geometry:{type:\"Point\",coordinates:[(n=t[r],360*(n-.5)),gi(t[r+1])]}};var n}function pi(t,r,e){const n=t[r+5],o=n>=1e4?`${Math.round(n/1e3)}k`:n>=1e3?Math.round(n/100)/10+\"k\":n,i=t[r+6],s=-1===i?{}:Object.assign({},e[i]);return Object.assign(s,{cluster:!0,cluster_id:t[r+3],point_count:n,point_count_abbreviated:o})}function mi(t){return t/360+.5}function di(t){const r=Math.sin(t*Math.PI/180),e=.5-.25*Math.log((1+r)/(1-r))/Math.PI;return e<0?0:e>1?1:e}function gi(t){const r=(180-360*t)*Math.PI/180;return 360*Math.atan(Math.exp(r))/Math.PI-90}class vi extends Gn{constructor(t){var{maxZoom:r,radius:e=60}=t,n=Tn(t,[\"maxZoom\",\"radius\"]);super({maxZoom:r}),this.markers=[],this.clusters=[],this.state={zoom:-1},this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},n))}calculate(t){let r=!1,e=t.map.getZoom();Dn(e),e=Math.round(e);const n={zoom:e};if(!Qo(t.markers,this.markers)){r=!0,this.markers=[...t.markers];const e=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:\"Feature\",geometry:{type:\"Point\",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(e)}return r||(this.state.zoom<=this.maxZoom||n.zoom<=this.maxZoom)&&(r=!Qo(this.state,n)),this.state=n,0===t.markers.length?(this.clusters=[],{clusters:this.clusters,changed:r}):(r&&(this.clusters=this.cluster(t)),{clusters:this.clusters,changed:r})}cluster(t){let{map:r}=t;const e=r.getZoom();return Dn(e),this.superCluster.getClusters([-180,-90,180,90],Math.round(e)).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}}var yi,wi,bi,Ei,ki,xi={};function Mi(){if(bi)return xi;bi=1;var t=qe(),r=Mo(),e=kt(),n=yr(),o=Mn(),i=Cn(),s=_n(),a=function(){if(wi)return yi;wi=1;var t=v(),r=Function.prototype,e=r.apply,n=r.call;return yi=\"object\"==typeof Reflect&&Reflect.apply||(t?n.bind(e):function(){return n.apply(e,arguments)}),yi}(),u=d(),c=TypeError,f=u(function(){[].keys().reduce(function(){},void 0)}),l=!f&&s(\"reduce\",c);return t({target:\"Iterator\",proto:!0,real:!0,forced:f||l},{reduce:function(t){n(this);try{e(t)}catch(t){i(this,\"throw\",t)}var s=arguments.length<2,u=s?void 0:arguments[1];if(l)return a(l,this,s?[t]:[t,u]);var f=o(this),h=0;if(r(f,function(r){s?(s=!1,u=r):u=t(u,r,h),h++},{IS_RECORD:!0}),s)throw new c(\"Reduce of empty iterator with no initial value\");return u}}),xi}Ei||(Ei=1,Mi());class Oi{constructor(t,r){this.markers={sum:t.length};const e=r.map(t=>t.count),n=e.reduce((t,r)=>t+r,0);this.clusters={count:r.length,markers:{mean:n/r.length,sum:n,min:Math.min(...e),max:Math.max(...e)}}}}class Pi{render(t,r,e){let{count:n,position:o}=t;const i=`<svg fill=\"${n>Math.max(10,r.clusters.markers.mean)?\"#ff0000\":\"#0000ff\"}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 240 240\" width=\"50\" height=\"50\">\\n<circle cx=\"120\" cy=\"120\" opacity=\".6\" r=\"70\" />\\n<circle cx=\"120\" cy=\"120\" opacity=\".3\" r=\"90\" />\\n<circle cx=\"120\" cy=\"120\" opacity=\".2\" r=\"110\" />\\n<text x=\"50%\" y=\"50%\" style=\"fill:#fff\" text-anchor=\"middle\" font-size=\"50\" dominant-baseline=\"middle\" font-family=\"roboto,arial,sans-serif\">${n}</text>\\n</svg>`,s=`Cluster of ${n} markers`,a=Number(google.maps.Marker.MAX_ZINDEX)+n;if(Zn.isAdvancedMarkerAvailable(e)){const t=(new DOMParser).parseFromString(i,\"image/svg+xml\").documentElement;t.setAttribute(\"transform\",\"translate(0 25)\");const r={map:e,position:o,zIndex:a,title:s,content:t};return new google.maps.marker.AdvancedMarkerElement(r)}const u={position:o,zIndex:a,title:s,icon:{url:`data:image/svg+xml;base64,${btoa(i)}`,anchor:new google.maps.Point(25,25)}};return new google.maps.Marker(u)}}class Ci{constructor(){!function(t,r){for(let e in r.prototype)t.prototype[e]=r.prototype[e]}(Ci,google.maps.OverlayView)}}t.MarkerClustererEvents=void 0,(ki=t.MarkerClustererEvents||(t.MarkerClustererEvents={})).CLUSTERING_BEGIN=\"clusteringbegin\",ki.CLUSTERING_END=\"clusteringend\",ki.CLUSTER_CLICK=\"click\",ki.GMP_CLICK=\"gmp-click\";const Si=(t,r,e)=>{r.bounds&&e.fitBounds(r.bounds)};return t.AbstractAlgorithm=Gn,t.AbstractViewportAlgorithm=Hn,t.Cluster=zn,t.ClusterStats=Oi,t.DefaultRenderer=Pi,t.GridAlgorithm=class extends Hn{constructor(t){var{maxDistance:r=4e4,gridSize:e=40}=t;super(Tn(t,[\"maxDistance\",\"gridSize\"])),this.clusters=[],this.state={zoom:-1},this.maxDistance=r,this.gridSize=e}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();Dn(o);const i={zoom:o};let s=!1;return this.state.zoom>=this.maxZoom&&i.zoom>=this.maxZoom||(s=!Qo(this.state,i)),this.state=i,o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:s}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}cluster(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return this.clusters=[],r.forEach(t=>{this.addToClosestCluster(t,e,n)}),this.clusters}addToClosestCluster(t,r,e){let n=this.maxDistance,o=null;for(let r=0;r<this.clusters.length;r++){const e=this.clusters[r];Dn(e.bounds);const i=Bn(e.bounds.getCenter().toJSON(),Zn.getPosition(t).toJSON());i<n&&(n=i,o=e)}if(o)if(Dn(o.bounds),Nn(o.bounds,e,this.gridSize).contains(Zn.getPosition(t)))o.push(t);else{const r=new zn({markers:[t]});this.clusters.push(r)}else{const r=new zn({markers:[t]});this.clusters.push(r)}}},t.MarkerClusterer=class extends Ci{constructor(t){let{map:r,markers:e=[],algorithmOptions:n={},algorithm:o=new vi(n),renderer:i=new Pi,onClusterClick:s=Si}=t;super(),this.map=null,this.idleListener=null,this.markers=[...e],this.clusters=[],this.algorithm=o,this.renderer=i,this.onClusterClick=s,r&&this.setMap(r)}addMarker(t,r){this.markers.includes(t)||(this.markers.push(t),r||this.render())}addMarkers(t,r){t.forEach(t=>{this.addMarker(t,!0)}),r||this.render()}removeMarker(t,r){const e=this.markers.indexOf(t);return-1!==e&&(Zn.setMap(t,null),this.markers.splice(e,1),r||this.render(),!0)}removeMarkers(t,r){let e=!1;return t.forEach(t=>{e=this.removeMarker(t,!0)||e}),e&&!r&&this.render(),e}clearMarkers(t){this.markers.length=0,t||this.render()}render(){const r=this.getMap();if(r instanceof google.maps.Map&&r.getProjection()){google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_BEGIN,this);const{clusters:e,changed:n}=this.algorithm.calculate({markers:this.markers,map:r,mapCanvasProjection:this.getProjection()});if(n||null==n){const t=new Set;for(const r of e)1==r.markers.length&&t.add(r.markers[0]);const r=[];for(const e of this.clusters)null!=e.marker&&(1==e.markers.length?t.has(e.marker)||Zn.setMap(e.marker,null):r.push(e.marker));this.clusters=e,this.renderClusters(),requestAnimationFrame(()=>r.forEach(t=>Zn.setMap(t,null)))}google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_END,this)}}onAdd(){const t=this.getMap();Dn(t),this.idleListener=t.addListener(\"idle\",this.render.bind(this)),this.render()}onRemove(){this.idleListener&&google.maps.event.removeListener(this.idleListener),this.reset()}reset(){this.markers.forEach(t=>Zn.setMap(t,null)),this.clusters.forEach(t=>t.delete()),this.clusters=[]}renderClusters(){const r=new Oi(this.markers,this.clusters),e=this.getMap();this.clusters.forEach(n=>{if(1===n.markers.length)n.marker=n.markers[0];else if(n.marker=this.renderer.render(n,r,e),n.markers.forEach(t=>Zn.setMap(t,null)),this.onClusterClick){const r=Zn.isAdvancedMarker(n.marker)?t.MarkerClustererEvents.GMP_CLICK:t.MarkerClustererEvents.CLUSTER_CLICK;n.marker.addListener(r,r=>{google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTER_CLICK,n),this.onClusterClick(r,n,e)})}Zn.setMap(n.marker,e)})}},t.MarkerUtils=Zn,t.NoopAlgorithm=class extends Gn{constructor(t){super(Tn(t,[]))}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return{clusters:this.cluster({markers:r,map:e,mapCanvasProjection:n}),changed:!1}}cluster(t){return this.noop(t)}},t.SuperClusterAlgorithm=vi,t.SuperClusterViewportAlgorithm=class extends Hn{constructor(t){var{maxZoom:r,radius:e=60,viewportPadding:n=60}=t,o=Tn(t,[\"maxZoom\",\"radius\",\"viewportPadding\"]);super({maxZoom:r,viewportPadding:n}),this.markers=[],this.clusters=[],this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},o)),this.state={zoom:-1,view:[0,0,0,0]}}calculate(t){const r=this.getViewportState(t);let e=!Qo(this.state,r);if(!Qo(t.markers,this.markers)){e=!0,this.markers=[...t.markers];const r=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:\"Feature\",geometry:{type:\"Point\",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(r)}return e&&(this.clusters=this.cluster(t),this.state=r),{clusters:this.clusters,changed:e}}cluster(t){const r=this.getViewportState(t);return this.superCluster.getClusters(r.view,r.zoom).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}getViewportState(t){const r=t.map.getZoom(),e=t.map.getBounds();return Dn(r),Dn(e),{zoom:Math.round(r),view:Un(e,t.mapCanvasProjection,this.viewportPadding)}}},t.defaultOnClusterClickHandler=Si,t.distanceBetweenPoints=Bn,t.extendBoundsToPaddedViewport=Nn,t.extendPixelBounds=$n,t.filterMarkersToPaddedViewport=Fn,t.getPaddedViewport=Un,t.noop=Kn,t.pixelBoundsToLatLngBounds=Vn,t}({});\n</script><script>\n\t(function loadBetterMapAssets(loaderScript) {\n\t\tvar ts = Date.now();\n\t\tvar widgetBase = \"https://cdn.jsdelivr.net/gh/logicmonitor/custom_widgets@main/src/\";\n\t\t// var catchpointBeacon = \"https://g.3gl.net/jp/14586/latest/InitialLoadScript.js\";\n\t\tvar registry = window.__betterMapWidgetRegistry = window.__betterMapWidgetRegistry || { instances: Object.create(null) };\n\t\tif (!registry.instances) {\n\t\t\tregistry.instances = Object.create(null);\n\t\t}\n\n\t\t// Function to find a previous sibling element matching the supplied test...\n\t\tfunction previousElementMatching(start, predicate) {\n\t\t\tif (!start) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar element = start.previousElementSibling;\n\t\t\twhile (element) {\n\t\t\t\tif (predicate(element)) {\n\t\t\t\t\treturn element;\n\t\t\t\t}\n\t\t\t\telement = element.previousElementSibling;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t// Function to append dynamically-loaded files to the document head...\n\t\tfunction appendToHead(node) {\n\t\t\t(document.head || document.body || document.documentElement).appendChild(node);\n\t\t}\n\n\t\t// Function to create a unique ID for this widget instance...\n\t\tfunction makeInstanceId() {\n\t\t\tif (window.crypto && typeof window.crypto.randomUUID === \"function\") {\n\t\t\t\treturn window.crypto.randomUUID();\n\t\t\t}\n\t\t\treturn \"better-map-\" + Date.now() + \"-\" + Math.random().toString(36).slice(2);\n\t\t}\n\n\t\t// Function to find or create the map container for this widget instance...\n\t\tfunction ensureBetterMapRoot(referenceNode) {\n\t\t\tvar root = previousElementMatching(referenceNode, function(element) {\n\t\t\t\treturn element.classList && element.classList.contains(\"customMapBody\");\n\t\t\t}) || document.querySelector(\".customMapBody:not([data-better-map-instance-id])\") || document.querySelector(\".customMapBody\");\n\t\t\tif (root) {\n\t\t\t\treturn root;\n\t\t\t}\n\t\t\troot = document.createElement(\"div\");\n\t\t\troot.className = \"customMapBody\";\n\t\t\troot.innerHTML = \" \";\n\t\t\tif (referenceNode && referenceNode.parentNode) {\n\t\t\t\treferenceNode.parentNode.insertBefore(root, referenceNode);\n\t\t\t} else {\n\t\t\t\t(document.body || document.documentElement).appendChild(root);\n\t\t\t}\n\t\t\treturn root;\n\t\t}\n\n\t\t// Function to load an external script and tag it with this widget instance...\n\t\tfunction loadScript(url, options) {\n\t\t\toptions = options || {};\n\t\t\treturn new Promise(function(resolve, reject) {\n\t\t\t\tvar script = document.createElement(\"script\");\n\t\t\t\tscript.src = url;\n\t\t\t\tif (options.defer) {\n\t\t\t\t\tscript.defer = true;\n\t\t\t\t}\n\t\t\t\tif (options.async) {\n\t\t\t\t\tscript.async = true;\n\t\t\t\t}\n\t\t\t\tif (options.instanceId) {\n\t\t\t\t\tscript.setAttribute(\"data-better-map-instance-id\", options.instanceId);\n\t\t\t\t}\n\t\t\t\tscript.onload = function() {\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t\tscript.onerror = function() {\n\t\t\t\t\treject(new Error(\"Failed to load script: \" + url));\n\t\t\t\t};\n\t\t\t\tappendToHead(script);\n\t\t\t});\n\t\t}\n\n\t\t// Function to load an external stylesheet for the widget...\n\t\tfunction loadStylesheet(url) {\n\t\t\treturn new Promise(function(resolve, reject) {\n\t\t\t\tvar link = document.createElement(\"link\");\n\t\t\t\tlink.rel = \"stylesheet\";\n\t\t\t\tlink.href = url;\n\t\t\t\tlink.onload = function() {\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t\tlink.onerror = function() {\n\t\t\t\t\treject(new Error(\"Failed to load stylesheet: \" + url));\n\t\t\t\t};\n\t\t\t\tappendToHead(link);\n\t\t\t});\n\t\t}\n\n\t\tvar defaultsScript = previousElementMatching(loaderScript, function(element) {\n\t\t\treturn element.tagName === \"SCRIPT\" && element.hasAttribute(\"data-better-map-defaults\");\n\t\t}) || document.querySelector(\"script[data-better-map-defaults]\");\n\t\tvar mapBody = ensureBetterMapRoot(loaderScript);\n\t\tvar tokenArea = previousElementMatching(loaderScript, function(element) {\n\t\t\treturn element.id === \"tokenCaptureArea\";\n\t\t}) || document.querySelector(\"#tokenCaptureArea\");\n\t\tvar previousInstanceId = mapBody && mapBody.getAttribute(\"data-better-map-instance-id\");\n\t\tvar previousInstance = previousInstanceId && registry.instances[previousInstanceId];\n\n\t\tregistry.reloadGeneration = (registry.reloadGeneration || 0) + 1;\n\n\t\tif (previousInstance && typeof previousInstance.cleanup === \"function\") {\n\t\t\tpreviousInstance.cleanup();\n\t\t}\n\t\tif (previousInstanceId) {\n\t\t\tdelete registry.instances[previousInstanceId];\n\t\t}\n\n\t\tvar instanceId = makeInstanceId();\n\t\tif (mapBody) {\n\t\t\tmapBody.setAttribute(\"data-better-map-instance-id\", instanceId);\n\t\t}\n\t\tif (tokenArea) {\n\t\t\ttokenArea.setAttribute(\"data-better-map-instance-id\", instanceId);\n\t\t}\n\n\t\tregistry.instances[instanceId] = {\n\t\t\tcreatedAt: Date.now(),\n\t\t\treloadGeneration: registry.reloadGeneration,\n\t\t\tdefaults: (defaultsScript && defaultsScript.__betterMapDefaults) || (registry.pendingDefaults && registry.pendingDefaults.shift()) || {},\n\t\t\troot: mapBody,\n\t\t\ttokenRoot: tokenArea\n\t\t};\n\n\t\tObject.keys(registry.instances).forEach(function(id) {\n\t\t\tvar instance = registry.instances[id];\n\t\t\tif (instance && instance.root && !instance.root.isConnected) {\n\t\t\t\tif (typeof instance.cleanup === \"function\") {\n\t\t\t\t\tinstance.cleanup();\n\t\t\t\t}\n\t\t\t\tdelete registry.instances[id];\n\t\t\t}\n\t\t});\n\n\t\t// Remove previously loaded widget scripts from the SPA shell. The Google Maps\n\t\t// API stays loaded, but each widget save should not accumulate script tags.\n\t\tdocument.querySelectorAll(\"script[data-better-map-instance-id]\").forEach(function(script) {\n\t\t\tif (script.parentNode) {\n\t\t\t\tscript.parentNode.removeChild(script);\n\t\t\t}\n\t\t});\n\n\t\tloadStylesheet(widgetBase + \"Better_Map_Widget.css?ts=\" + ts);\n\t\tloadScript(widgetBase + \"Better_Map_Widget.js?ts=\" + ts, { defer: true, instanceId: instanceId });\n\t\t// loadScript(catchpointBeacon + \"?ts=\" + ts, { defer: true });\n\t})(document.currentScript);\n</script>"
}
},
{
"position": {
"col": 11,
"sizex": 2,
"row": 1,
"sizey": 12
},
"config": {
"displaySettings": {},
"isSupportCustomProperty": false,
"supportCustomProperty": false,
"name": "Description",
"description": "",
"theme": "newSolidBlue",
"interval": 15,
"type": "text",
"timescale": "day",
"version": 2,
"content": "<div style=\"font-size: 0.9em; line-height: 1.25em;\"><h3>Overview:</h3><p id=\"isPasted\">On this dashboard is a fully custom, standalone map widget to overcome some limitations with our core Map widget. The ideas behind this include:</p><ul><li>Support for 1,000+ pins on the map (vs 400) to accommodate larger customers</li><li>Marker clustering to group adjacent pins together until zoomed in (along with easy zoom reset)</li><li>A donut chart to represent the severities of clustered markers</li><li>Quick & easy on-the-fly filtering based on path and severities</li><li>Easy toggling of weather layers, earthquakes, US wildfires, and US power outages</li><li>More informational tips when clicking a pin</li><li>The ability to show colored lines representing connections between locations</li></ul><h3 id=\"isPasted\">Prerequisites:</h3><ul><li>Groups, resources, or services with valid addresses set in the usual 'location' property.</li><li>If you want to show connections between locations and their status, load the "Set Better Map Widget Connections" PropertySource.</li></ul><h3 id=\"isPasted\">Initial Configuration:</h3><ol><li>Create a new Text widget to the dashboard.</li><li>On the Text widget's edit dialog, click the "Source" button and paste in the contents of the script, then save the widget.</li><li>Add dashboard tokens to modify the defaults of the widget as desired. A list of token options is provided below. (can also be found at top of the widget's source script)</li></ol><h3>Usage:</h3><p>Clicking on a marker cluster will display more info about that group, including the option to zoom in to see the clustered markers. To quickly reset the zoom, just click the bottom button in the upper-left corner of the map (the one with the 4 arrows).</p><p>By default the map will auto-refresh every 2 minutes, though that's configurable by changing the 'statusUpdateIntervalMinutes' variable near the top of the script.</p><p>Note that by default the zoom level of the map will <em>not</em> auto-reset on refreshes to ensure that all markers are visible. Enabling that feature can be very useful when filtering on specific severities and new matching items appear, especially when displayed on overhead monitors.</p><p>Visibility of the toolbar along the top of the widget can be toggled using the button in the upper-left corner of the map.</p><h3>Optional Customization:</h3><p>Behavior of the widget can be customized using the following optional dashboard tokens.</p><ul><li id=\"isPasted\"><strong>MapGroupPathFilter</strong>: Allows setting a default group path to start. Default is "<span style=\"font-family: monospace;\">*</span>".</li><li id=\"isPasted\"><strong>MapLocationProperty</strong>: The property to use for the location of the items on the map. Default is "location".<strong></strong><br></li><li id=\"isPasted\"><strong>MapShowWeather</strong>: If weather should be shown by default. Options are "global", "nexrad", "xweather", or "openweather". Default is "global".</li><li id=\"isPasted\"><strong>MapOverlayOption</strong>: Which optional overlay to default to when weather is shown. Options are "earthquakes", "us-poweroutages" (or "outages"), "wildfires", or "us-flooding". Default is "earthquakes".</li><li id=\"isPasted\"><strong>HideMapOptions</strong>: If "true" then will hide the options bar by default. Default is "false".</li><li id=\"isPasted\"><strong>ShowMapSidebar</strong>:If "true" then will show the sidebar by default. Default is "false".<strong></strong></li><li id=\"isPasted\"><strong>MapSourceType</strong>: Whether to map "groups", "resources", or "services". Default is "groups".</li><li id=\"isPasted\"><strong>MapIgnoreCleared</strong>: If "true" then will only show items currently alerting (useful for maps with thousands of markers). Default is "false".</li><li id=\"isPasted\"><strong>MapIgnoreWarnings</strong>: If "true" then won't show items in "Warning" status. Default is "false".</li><li id=\"isPasted\"><strong>MapIgnoreErrors</strong>: If "true" then won't show items in "Error" status. Default is "false".</li><li id=\"isPasted\"><strong>MapIgnoreCriticals</strong>: If "true" then won't show items in "Critical" status. Default is "false".</li><li id=\"isPasted\"><strong>AutoResetMapOnRefresh</strong>: If "true" then the map will automatically zoom to encompass all items on timed refreshes. Default is "false".</li><li id=\"isPasted\"><strong>MapDisableClustering</strong>: If "true" then clustering of adjacent markers on the map will be disabled. Might be desirable if showing connections between locations since clustering might hide markers at certain zoom levels. Default is "false".</li><li id=\"isPasted\"><strong>MapDisplayProperties</strong>: An optional comma-delimited list of custom properties to show when viewing a group's/resource's details.</li><li id=\"isPasted\"><strong>MapStyle</strong>: Allows one of the following available map style options: "silver", "standard", "dark", "aubergine", "satellite", "satellite-light", or "silverblue". Default is "silverblue".</li><li id=\"isPasted\"><strong>MapMarkerStyle</strong>: The style of marker to use for the items on the map. Options are "pins" or "circles". Default is "pins".<strong></strong></li><li id=\"isPasted\"><strong>MapShowRoadLabels</strong>: If "true" then road labels will be shown on the map. Default is "false".</li><li id=\"isPasted\">'<strong>XweatherAPIID</strong>' & '<strong>XweatherAPIKey</strong>': Optional <a href=\"https://www.xweather.com/weather-api\" target=\"_blank\" rel=\"noopener noreferrer\">Xweather</a> API ID & key to use for global weather radar. Xweather is offers a great deal of optional details such as lightning strikes, hail, wind gusts, etc. Many personal weather stations such as Ecowitt provide free Xweather API access if you feed them your weather data.</li><li id=\"isPasted\"><strong></strong>'<strong>OpenWeatherAPIKey</strong>': Optional <a href=\"https://openweathermap.org/api\" target=\"_blank\" rel=\"noopener noreferrer\">OpenWeather</a> API key for global weather radar. A free API key will work for very basic radar information.<strong></strong></li></ul><h3>Showing Connections between Locations</h3><p>You can represent connectivity between locations. This only supports alert status of instances of the "SNMP_Network_Interfaces" datasource and any datasource with "VPN" in the name.</p><p>To configure, go to the specific instance of one of those datasources and add an instance-level property called 'custom_map_connection'. The value should be in the following format:</p><p>{Connection Title} > {Hostname/IP of the connected resource}</p><p>For example: "London WAN > 192.168.1.10" would show a line titled "London WAN" representing this specific interface connected to the resource monitored as 192.168.1.10. A PropertySource - "Set Better Map Widget Connections" - configures those instance-level properties as resource-level properties along with other necessary data for the widget to use.</p></div>"
}
}
],
"version": 2
}