Merge with master

This commit is contained in:
Igor Kulikov 2020-09-16 12:12:59 +03:00
commit 692f575661
16 changed files with 73 additions and 22 deletions

View File

@ -56,7 +56,9 @@ public class TbRuleEngineProcessingStrategyFactory {
private final boolean retryTimeout; private final boolean retryTimeout;
private final int maxRetries; private final int maxRetries;
private final double maxAllowedFailurePercentage; private final double maxAllowedFailurePercentage;
private final long pauseBetweenRetries; private final long maxPauseBetweenRetries;
private long pauseBetweenRetries;
private int initialTotalCount; private int initialTotalCount;
private int retryCount; private int retryCount;
@ -69,6 +71,7 @@ public class TbRuleEngineProcessingStrategyFactory {
this.maxRetries = configuration.getRetries(); this.maxRetries = configuration.getRetries();
this.maxAllowedFailurePercentage = configuration.getFailurePercentage(); this.maxAllowedFailurePercentage = configuration.getFailurePercentage();
this.pauseBetweenRetries = configuration.getPauseBetweenRetries(); this.pauseBetweenRetries = configuration.getPauseBetweenRetries();
this.maxPauseBetweenRetries = configuration.getMaxPauseBetweenRetries();
} }
@Override @Override
@ -108,6 +111,9 @@ public class TbRuleEngineProcessingStrategyFactory {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
if (maxPauseBetweenRetries > pauseBetweenRetries) {
pauseBetweenRetries = Math.min(maxPauseBetweenRetries, pauseBetweenRetries * 2);
}
} }
return new TbRuleEngineProcessingDecision(false, toReprocess); return new TbRuleEngineProcessingDecision(false, toReprocess);
} }

View File

@ -765,6 +765,7 @@ queue:
retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited
failure-percentage: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; failure-percentage: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries; pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries;
max-pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:3}"# Max allowed time in seconds for pause between retries.
- name: "${TB_QUEUE_RE_HP_QUEUE_NAME:HighPriority}" - name: "${TB_QUEUE_RE_HP_QUEUE_NAME:HighPriority}"
topic: "${TB_QUEUE_RE_HP_TOPIC:tb_rule_engine.hp}" topic: "${TB_QUEUE_RE_HP_TOPIC:tb_rule_engine.hp}"
poll-interval: "${TB_QUEUE_RE_HP_POLL_INTERVAL_MS:25}" poll-interval: "${TB_QUEUE_RE_HP_POLL_INTERVAL_MS:25}"
@ -780,6 +781,7 @@ queue:
retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRIES:0}" # Number of retries, 0 is unlimited retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRIES:0}" # Number of retries, 0 is unlimited
failure-percentage: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; failure-percentage: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries; pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries;
max-pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries.
- name: "${TB_QUEUE_RE_SQ_QUEUE_NAME:SequentialByOriginator}" - name: "${TB_QUEUE_RE_SQ_QUEUE_NAME:SequentialByOriginator}"
topic: "${TB_QUEUE_RE_SQ_TOPIC:tb_rule_engine.sq}" topic: "${TB_QUEUE_RE_SQ_TOPIC:tb_rule_engine.sq}"
poll-interval: "${TB_QUEUE_RE_SQ_POLL_INTERVAL_MS:25}" poll-interval: "${TB_QUEUE_RE_SQ_POLL_INTERVAL_MS:25}"
@ -795,6 +797,7 @@ queue:
retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited
failure-percentage: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages; failure-percentage: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries; pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries;
max-pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries.
transport: transport:
# For high priority notifications that require minimum latency and processing time # For high priority notifications that require minimum latency and processing time
notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb_transport.notifications}" notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb_transport.notifications}"

View File

@ -24,5 +24,6 @@ public class TbRuleEngineQueueAckStrategyConfiguration {
private int retries; private int retries;
private double failurePercentage; private double failurePercentage;
private long pauseBetweenRetries; private long pauseBetweenRetries;
private long maxPauseBetweenRetries;
} }

View File

@ -54,7 +54,7 @@
"jstree": "^3.3.10", "jstree": "^3.3.10",
"jstree-bootstrap-theme": "^1.0.1", "jstree-bootstrap-theme": "^1.0.1",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"leaflet": "^1.6.0", "leaflet": "^1.7.1",
"leaflet-editable": "^1.2.0", "leaflet-editable": "^1.2.0",
"leaflet-polylinedecorator": "^1.6.0", "leaflet-polylinedecorator": "^1.6.0",
"leaflet-providers": "^1.10.2", "leaflet-providers": "^1.10.2",

View File

@ -1277,7 +1277,7 @@ export class WidgetSubscription implements IWidgetSubscription {
const index = startIndex + dataIndex * dataKeysCount + dataKeyIndex; const index = startIndex + dataIndex * dataKeysCount + dataKeyIndex;
let update = true; let update = true;
let currentData: DataSetHolder; let currentData: DataSetHolder;
if (this.displayLegend && this.legendData.keys[index].dataKey.hidden) { if (this.displayLegend && this.legendData.keys.find(key => key.dataIndex === index).dataKey.hidden) {
currentData = this.hiddenData[index]; currentData = this.hiddenData[index];
} else { } else {
currentData = this.data[index]; currentData = this.data[index];

View File

@ -14,9 +14,11 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { HasUUID } from '@shared/models/id/has-uuid';
export declare type MenuSectionType = 'link' | 'toggle'; export declare type MenuSectionType = 'link' | 'toggle';
export class MenuSection { export interface MenuSection extends HasUUID{
name: string; name: string;
type: MenuSectionType; type: MenuSectionType;
path: string; path: string;
@ -26,12 +28,12 @@ export class MenuSection {
pages?: Array<MenuSection>; pages?: Array<MenuSection>;
} }
export class HomeSection { export interface HomeSection {
name: string; name: string;
places: Array<HomeSectionPlace>; places: Array<HomeSectionPlace>;
} }
export class HomeSectionPlace { export interface HomeSectionPlace {
name: string; name: string;
icon: string; icon: string;
isMdiIcon?: boolean; isMdiIcon?: boolean;

View File

@ -24,6 +24,7 @@ import { HomeSection, MenuSection } from '@core/services/menu.models';
import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { Authority } from '@shared/models/authority.enum'; import { Authority } from '@shared/models/authority.enum';
import { AuthUser } from '@shared/models/user.model'; import { AuthUser } from '@shared/models/user.model';
import { guid } from '@core/utils';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -74,18 +75,21 @@ export class MenuService {
const sections: Array<MenuSection> = []; const sections: Array<MenuSection> = [];
sections.push( sections.push(
{ {
id: guid(),
name: 'home.home', name: 'home.home',
type: 'link', type: 'link',
path: '/home', path: '/home',
icon: 'home' icon: 'home'
}, },
{ {
id: guid(),
name: 'tenant.tenants', name: 'tenant.tenants',
type: 'link', type: 'link',
path: '/tenants', path: '/tenants',
icon: 'supervisor_account' icon: 'supervisor_account'
}, },
{ {
id: guid(),
name: 'tenant-profile.tenant-profiles', name: 'tenant-profile.tenant-profiles',
type: 'link', type: 'link',
path: '/tenantProfiles', path: '/tenantProfiles',
@ -93,12 +97,14 @@ export class MenuService {
isMdiIcon: true isMdiIcon: true
}, },
{ {
id: guid(),
name: 'widget.widget-library', name: 'widget.widget-library',
type: 'link', type: 'link',
path: '/widgets-bundles', path: '/widgets-bundles',
icon: 'now_widgets' icon: 'now_widgets'
}, },
{ {
id: guid(),
name: 'admin.system-settings', name: 'admin.system-settings',
type: 'toggle', type: 'toggle',
path: '/settings', path: '/settings',
@ -106,18 +112,21 @@ export class MenuService {
icon: 'settings', icon: 'settings',
pages: [ pages: [
{ {
id: guid(),
name: 'admin.general', name: 'admin.general',
type: 'link', type: 'link',
path: '/settings/general', path: '/settings/general',
icon: 'settings_applications' icon: 'settings_applications'
}, },
{ {
id: guid(),
name: 'admin.outgoing-mail', name: 'admin.outgoing-mail',
type: 'link', type: 'link',
path: '/settings/outgoing-mail', path: '/settings/outgoing-mail',
icon: 'mail' icon: 'mail'
}, },
{ {
id: guid(),
name: 'admin.security-settings', name: 'admin.security-settings',
type: 'link', type: 'link',
path: '/settings/security-settings', path: '/settings/security-settings',
@ -186,36 +195,42 @@ export class MenuService {
const sections: Array<MenuSection> = []; const sections: Array<MenuSection> = [];
sections.push( sections.push(
{ {
id: guid(),
name: 'home.home', name: 'home.home',
type: 'link', type: 'link',
path: '/home', path: '/home',
icon: 'home' icon: 'home'
}, },
{ {
id: guid(),
name: 'rulechain.rulechains', name: 'rulechain.rulechains',
type: 'link', type: 'link',
path: '/ruleChains', path: '/ruleChains',
icon: 'settings_ethernet' icon: 'settings_ethernet'
}, },
{ {
id: guid(),
name: 'customer.customers', name: 'customer.customers',
type: 'link', type: 'link',
path: '/customers', path: '/customers',
icon: 'supervisor_account' icon: 'supervisor_account'
}, },
{ {
id: guid(),
name: 'asset.assets', name: 'asset.assets',
type: 'link', type: 'link',
path: '/assets', path: '/assets',
icon: 'domain' icon: 'domain'
}, },
{ {
id: guid(),
name: 'device.devices', name: 'device.devices',
type: 'link', type: 'link',
path: '/devices', path: '/devices',
icon: 'devices_other' icon: 'devices_other'
}, },
{ {
id: guid(),
name: 'device-profile.device-profiles', name: 'device-profile.device-profiles',
type: 'link', type: 'link',
path: '/deviceProfiles', path: '/deviceProfiles',
@ -223,24 +238,28 @@ export class MenuService {
isMdiIcon: true isMdiIcon: true
}, },
{ {
id: guid(),
name: 'entity-view.entity-views', name: 'entity-view.entity-views',
type: 'link', type: 'link',
path: '/entityViews', path: '/entityViews',
icon: 'view_quilt' icon: 'view_quilt'
}, },
{ {
id: guid(),
name: 'widget.widget-library', name: 'widget.widget-library',
type: 'link', type: 'link',
path: '/widgets-bundles', path: '/widgets-bundles',
icon: 'now_widgets' icon: 'now_widgets'
}, },
{ {
id: guid(),
name: 'dashboard.dashboards', name: 'dashboard.dashboards',
type: 'link', type: 'link',
path: '/dashboards', path: '/dashboards',
icon: 'dashboards' icon: 'dashboards'
}, },
{ {
id: guid(),
name: 'audit-log.audit-logs', name: 'audit-log.audit-logs',
type: 'link', type: 'link',
path: '/auditLogs', path: '/auditLogs',
@ -342,30 +361,35 @@ export class MenuService {
const sections: Array<MenuSection> = []; const sections: Array<MenuSection> = [];
sections.push( sections.push(
{ {
id: guid(),
name: 'home.home', name: 'home.home',
type: 'link', type: 'link',
path: '/home', path: '/home',
icon: 'home' icon: 'home'
}, },
{ {
id: guid(),
name: 'asset.assets', name: 'asset.assets',
type: 'link', type: 'link',
path: '/assets', path: '/assets',
icon: 'domain' icon: 'domain'
}, },
{ {
id: guid(),
name: 'device.devices', name: 'device.devices',
type: 'link', type: 'link',
path: '/devices', path: '/devices',
icon: 'devices_other' icon: 'devices_other'
}, },
{ {
id: guid(),
name: 'entity-view.entity-views', name: 'entity-view.entity-views',
type: 'link', type: 'link',
path: '/entityViews', path: '/entityViews',
icon: 'view_quilt' icon: 'view_quilt'
}, },
{ {
id: guid(),
name: 'dashboard.dashboards', name: 'dashboard.dashboards',
type: 'link', type: 'link',
path: '/dashboards', path: '/dashboards',

View File

@ -86,8 +86,7 @@ export default abstract class LeafletMap {
public initSettings(options: MapSettings) { public initSettings(options: MapSettings) {
this.options.tinyColor = tinycolor(this.options.color || defaultSettings.color); this.options.tinyColor = tinycolor(this.options.color || defaultSettings.color);
const { disableScrollZooming, const { useClusterMarkers,
useClusterMarkers,
zoomOnClick, zoomOnClick,
showCoverageOnHover, showCoverageOnHover,
removeOutsideVisibleBounds, removeOutsideVisibleBounds,
@ -95,9 +94,6 @@ export default abstract class LeafletMap {
chunkedLoading, chunkedLoading,
maxClusterRadius, maxClusterRadius,
maxZoom }: MapSettings = options; maxZoom }: MapSettings = options;
if (disableScrollZooming) {
this.map.scrollWheelZoom.disable();
}
if (useClusterMarkers) { if (useClusterMarkers) {
const clusteringSettings: MarkerClusterGroupOptions = { const clusteringSettings: MarkerClusterGroupOptions = {
zoomToBoundsOnClick: zoomOnClick, zoomToBoundsOnClick: zoomOnClick,
@ -307,8 +303,11 @@ export default abstract class LeafletMap {
} else { } else {
this.bounds = new L.LatLngBounds(null, null); this.bounds = new L.LatLngBounds(null, null);
} }
if (this.options.disableScrollZooming) {
this.map.scrollWheelZoom.disable();
}
if (this.options.draggableMarker) { if (this.options.draggableMarker) {
this.addMarkerControl(); this.addMarkerControl();
} }
if (this.options.editablePolygon) { if (this.options.editablePolygon) {
this.addPolygonControl(); this.addPolygonControl();
@ -623,10 +622,10 @@ export default abstract class LeafletMap {
// Polyline // Polyline
updatePolylines(polyData: FormattedData[][], updateBounds = true, data?: FormattedData) { updatePolylines(polyData: FormattedData[][], updateBounds = true, activePolyline?: FormattedData) {
const keys: string[] = []; const keys: string[] = [];
polyData.forEach((dataSource: FormattedData[]) => { polyData.forEach((dataSource: FormattedData[]) => {
data = data || dataSource[0]; const data = activePolyline || dataSource[0];
if (dataSource.length && data.entityName === dataSource[0].entityName) { if (dataSource.length && data.entityName === dataSource[0].entityName) {
if (this.polylines.get(data.entityName)) { if (this.polylines.get(data.entityName)) {
this.updatePolyline(data, dataSource, this.options, updateBounds); this.updatePolyline(data, dataSource, this.options, updateBounds);

View File

@ -24,7 +24,7 @@
[ngClass]="{'tb-toggled' : sectionActive()}"></span> [ngClass]="{'tb-toggled' : sectionActive()}"></span>
</a> </a>
<ul id="docs-menu-{{section.name | nospace}}" class="tb-menu-toggle-list" [ngStyle]="{height: sectionHeight()}"> <ul id="docs-menu-{{section.name | nospace}}" class="tb-menu-toggle-list" [ngStyle]="{height: sectionHeight()}">
<li *ngFor="let page of section.pages"> <li *ngFor="let page of section.pages; trackBy: trackBySectionPages">
<tb-menu-link [section]="page"></tb-menu-link> <tb-menu-link [section]="page"></tb-menu-link>
</li> </li>
</ul> </ul>

View File

@ -44,4 +44,8 @@ export class MenuToggleComponent implements OnInit {
return '0px'; return '0px';
} }
} }
trackBySectionPages(index: number, section: MenuSection){
return section.id;
}
} }

View File

@ -16,7 +16,7 @@
--> -->
<ul fxFlex fxLayout="column" fxLayoutAlign="start stretch" class="tb-side-menu"> <ul fxFlex fxLayout="column" fxLayoutAlign="start stretch" class="tb-side-menu">
<li *ngFor="let section of menuSections$| async" [ngSwitch]="section.type === 'link'"> <li *ngFor="let section of menuSections$ | async; trackBy: trackByMenuSection" [ngSwitch]="section.type === 'link'">
<tb-menu-link *ngSwitchCase="true" [section]="section"></tb-menu-link> <tb-menu-link *ngSwitchCase="true" [section]="section"></tb-menu-link>
<tb-menu-toggle *ngSwitchCase="false" [section]="section"></tb-menu-toggle> <tb-menu-toggle *ngSwitchCase="false" [section]="section"></tb-menu-toggle>
</li> </li>

View File

@ -16,6 +16,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MenuService } from '@core/services/menu.service'; import { MenuService } from '@core/services/menu.service';
import { MenuSection } from '@core/services/menu.models';
@Component({ @Component({
selector: 'tb-side-menu', selector: 'tb-side-menu',
@ -29,6 +30,10 @@ export class SideMenuComponent implements OnInit {
constructor(private menuService: MenuService) { constructor(private menuService: MenuService) {
} }
trackByMenuSection(index: number, section: MenuSection){
return section.id;
}
ngOnInit() { ngOnInit() {
} }

View File

@ -19,7 +19,7 @@
<h1 fxFlex fxHide.gt-sm *ngIf="lastBreadcrumb$ | async; let breadcrumb"> <h1 fxFlex fxHide.gt-sm *ngIf="lastBreadcrumb$ | async; let breadcrumb">
{{ breadcrumb.ignoreTranslate ? (breadcrumb.labelFunction ? breadcrumb.labelFunction() : breadcrumb.label) : (breadcrumb.label | translate) }} {{ breadcrumb.ignoreTranslate ? (breadcrumb.labelFunction ? breadcrumb.labelFunction() : breadcrumb.label) : (breadcrumb.label | translate) }}
</h1> </h1>
<span fxHide.lt-md fxLayout="row" *ngFor="let breadcrumb of breadcrumbs$ | async; last as isLast;" [ngSwitch]="isLast"> <span fxHide.lt-md fxLayout="row" *ngFor="let breadcrumb of breadcrumbs$ | async; trackBy: trackByBreadcrumbs; last as isLast;" [ngSwitch]="isLast">
<a *ngSwitchCase="false" [routerLink]="breadcrumb.link" [queryParams]="breadcrumb.queryParams"> <a *ngSwitchCase="false" [routerLink]="breadcrumb.link" [queryParams]="breadcrumb.queryParams">
<mat-icon *ngIf="breadcrumb.isMdiIcon" [svgIcon]="breadcrumb.icon"> <mat-icon *ngIf="breadcrumb.isMdiIcon" [svgIcon]="breadcrumb.icon">
</mat-icon> </mat-icon>

View File

@ -20,6 +20,7 @@ import { BreadCrumb, BreadCrumbConfig } from './breadcrumb';
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';
import { distinctUntilChanged, filter, map } from 'rxjs/operators'; import { distinctUntilChanged, filter, map } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { guid } from '@core/utils';
@Component({ @Component({
selector: 'tb-breadcrumb', selector: 'tb-breadcrumb',
@ -94,6 +95,7 @@ export class BreadcrumbComponent implements OnInit, OnDestroy {
const isMdiIcon = icon.startsWith('mdi:'); const isMdiIcon = icon.startsWith('mdi:');
const link = [ route.pathFromRoot.map(v => v.url.map(segment => segment.toString()).join('/')).join('/') ]; const link = [ route.pathFromRoot.map(v => v.url.map(segment => segment.toString()).join('/')).join('/') ];
const breadcrumb = { const breadcrumb = {
id: guid(),
label, label,
labelFunction, labelFunction,
ignoreTranslate, ignoreTranslate,
@ -110,4 +112,8 @@ export class BreadcrumbComponent implements OnInit, OnDestroy {
} }
return newBreadcrumbs; return newBreadcrumbs;
} }
trackByBreadcrumbs(index: number, breadcrumb: BreadCrumb){
return breadcrumb.id;
}
} }

View File

@ -16,8 +16,9 @@
import { ActivatedRouteSnapshot, Params } from '@angular/router'; import { ActivatedRouteSnapshot, Params } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { HasUUID } from '@shared/models/id/has-uuid';
export interface BreadCrumb { export interface BreadCrumb extends HasUUID{
label: string; label: string;
labelFunction?: () => string; labelFunction?: () => string;
ignoreTranslate: boolean; ignoreTranslate: boolean;

View File

@ -5770,10 +5770,10 @@ leaflet.markercluster@^1.4.1:
resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.4.1.tgz#b53f2c4f2ca7306ddab1dbb6f1861d5e8aa6c5e5" resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.4.1.tgz#b53f2c4f2ca7306ddab1dbb6f1861d5e8aa6c5e5"
integrity sha512-ZSEpE/EFApR0bJ1w/dUGwTSUvWlpalKqIzkaYdYB7jaftQA/Y2Jav+eT4CMtEYFj+ZK4mswP13Q2acnPBnhGOw== integrity sha512-ZSEpE/EFApR0bJ1w/dUGwTSUvWlpalKqIzkaYdYB7jaftQA/Y2Jav+eT4CMtEYFj+ZK4mswP13Q2acnPBnhGOw==
leaflet@^1.6.0: leaflet@^1.7.1:
version "1.6.0" version "1.7.1"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.6.0.tgz#aecbb044b949ec29469eeb31c77a88e2f448f308" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19"
integrity sha512-CPkhyqWUKZKFJ6K8umN5/D2wrJ2+/8UIpXppY7QDnUZW5bZL5+SEI2J7GBpwh4LIupOKqbNSQXgqmrEJopHVNQ== integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==
less-loader@6.1.0: less-loader@6.1.0:
version "6.1.0" version "6.1.0"