Browse Source

Merge branch 'master' into fix_bug_lwm2m_fota

pull/12876/head
nick 2 years ago
parent
commit
ae4713a668
  1. 12
      application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
  2. 10
      application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java
  3. 32
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  4. 4
      application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java
  5. 8
      application/src/main/java/org/thingsboard/server/service/cf/cache/DefaultCalculatedFieldEntityProfileCache.java
  6. 9
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java
  7. 10
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/KafkaCalculatedFieldStateService.java
  8. 2
      application/src/main/java/org/thingsboard/server/service/install/DefaultDatabaseSchemaSettingsService.java
  9. 18
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java
  10. 4
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  11. 3
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java
  12. 7
      application/src/main/resources/thingsboard.yml
  13. 2
      common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/FieldsUtil.java
  14. 3
      common/edqs/src/main/java/org/thingsboard/server/edqs/repo/TenantRepo.java
  15. 13
      common/edqs/src/main/java/org/thingsboard/server/edqs/stats/EdqsStatsService.java
  16. 2
      common/message/src/main/java/org/thingsboard/server/common/msg/cf/CalculatedFieldPartitionChangeMsg.java
  17. 41
      common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java
  18. 4
      common/queue/src/main/java/org/thingsboard/server/queue/discovery/PartitionService.java
  19. 3
      common/queue/src/main/java/org/thingsboard/server/queue/discovery/QueueKey.java
  20. 4
      common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java
  21. 8
      common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java
  22. 8
      common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java
  23. 4
      docker/docker-compose.edqs.volumes.yml
  24. 12
      docker/docker-compose.edqs.yml
  25. 0
      docker/tb-edqs.env
  26. 4
      docker/tb-edqs/conf/logback.xml
  27. 4
      docker/tb-edqs/conf/tb-edqs.conf
  28. 2
      edqs/src/main/resources/edqs.yml
  29. 2
      ui-ngx/package.json
  30. 21
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet/leaflet-tb.ts
  31. 116
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts
  32. 8
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map.scss
  33. 3
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts
  34. 11
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html
  35. 9
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.ts
  36. 28
      ui-ngx/src/app/shared/models/widget/maps/map.models.ts
  37. 6
      ui-ngx/src/assets/locale/locale.constant-en_US.json
  38. 25800
      ui-ngx/src/assets/map/openstreetmap_hybrid_reference_style.json
  39. 57837
      ui-ngx/src/assets/map/world_edition_hybrid_reference_style.json
  40. 1
      ui-ngx/src/typings/leaflet-extend-tb.d.ts
  41. 228
      ui-ngx/yarn.lock

12
application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java

@ -24,6 +24,7 @@ import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.AttributeScope;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.cf.configuration.Argument; import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.ArgumentType; import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
@ -34,6 +35,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg; import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeScopeProto; import org.thingsboard.server.gen.transport.TransportProtos.AttributeScopeProto;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeValueProto; import org.thingsboard.server.gen.transport.TransportProtos.AttributeValueProto;
@ -74,7 +76,6 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
final EntityId entityId; final EntityId entityId;
final CalculatedFieldProcessingService cfService; final CalculatedFieldProcessingService cfService;
final CalculatedFieldStateService cfStateService; final CalculatedFieldStateService cfStateService;
final int partition;
TbActorCtx ctx; TbActorCtx ctx;
Map<CalculatedFieldId, CalculatedFieldState> states = new HashMap<>(); Map<CalculatedFieldId, CalculatedFieldState> states = new HashMap<>();
@ -85,7 +86,6 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
this.entityId = entityId; this.entityId = entityId;
this.cfService = systemContext.getCalculatedFieldProcessingService(); this.cfService = systemContext.getCalculatedFieldProcessingService();
this.cfStateService = systemContext.getCalculatedFieldStateService(); this.cfStateService = systemContext.getCalculatedFieldStateService();
this.partition = systemContext.getCalculatedFieldEntityProfileCache().getEntityIdPartition(tenantId, entityId);
} }
void init(TbActorCtx ctx) { void init(TbActorCtx ctx) {
@ -93,8 +93,8 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
} }
public void process(CalculatedFieldPartitionChangeMsg msg) { public void process(CalculatedFieldPartitionChangeMsg msg) {
if (!msg.getPartitions()[partition]) { if (!systemContext.getPartitionService().resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId).isMyPartition()) {
log.info("[{}][{}] Stopping entity actor due to change partition event.", partition, entityId); log.info("[{}] Stopping entity actor due to change partition event.", entityId);
ctx.stop(ctx.getSelf()); ctx.stop(ctx.getSelf());
} }
} }
@ -153,7 +153,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
} }
public void process(EntityCalculatedFieldTelemetryMsg msg) throws CalculatedFieldException { public void process(EntityCalculatedFieldTelemetryMsg msg) throws CalculatedFieldException {
log.info("[{}] Processing CF telemetry msg.", msg.getEntityId()); log.debug("[{}] Processing CF telemetry msg.", msg.getEntityId());
var proto = msg.getProto(); var proto = msg.getProto();
var numberOfCallbacks = CALLBACKS_PER_CF * (msg.getEntityIdFields().size() + msg.getProfileIdFields().size()); var numberOfCallbacks = CALLBACKS_PER_CF * (msg.getEntityIdFields().size() + msg.getProfileIdFields().size());
MultipleTbCallback callback = new MultipleTbCallback(numberOfCallbacks, msg.getCallback()); MultipleTbCallback callback = new MultipleTbCallback(numberOfCallbacks, msg.getCallback());
@ -168,7 +168,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
} }
public void process(EntityCalculatedFieldLinkedTelemetryMsg msg) throws CalculatedFieldException { public void process(EntityCalculatedFieldLinkedTelemetryMsg msg) throws CalculatedFieldException {
log.info("[{}] Processing CF link telemetry msg.", msg.getEntityId()); log.debug("[{}] Processing CF link telemetry msg.", msg.getEntityId());
var proto = msg.getProto(); var proto = msg.getProto();
var ctx = msg.getCtx(); var ctx = msg.getCtx();
var callback = new MultipleTbCallback(CALLBACKS_PER_CF, msg.getCallback()); var callback = new MultipleTbCallback(CALLBACKS_PER_CF, msg.getCallback());

10
application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java

@ -318,14 +318,14 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
public void onTelemetryMsg(CalculatedFieldTelemetryMsg msg) { public void onTelemetryMsg(CalculatedFieldTelemetryMsg msg) {
EntityId entityId = msg.getEntityId(); EntityId entityId = msg.getEntityId();
log.info("Received telemetry msg from entity [{}]", entityId); log.debug("Received telemetry msg from entity [{}]", entityId);
// 2 = 1 for CF processing + 1 for links processing // 2 = 1 for CF processing + 1 for links processing
MultipleTbCallback callback = new MultipleTbCallback(2, msg.getCallback()); MultipleTbCallback callback = new MultipleTbCallback(2, msg.getCallback());
// process all cfs related to entity, or it's profile; // process all cfs related to entity, or it's profile;
var entityIdFields = getCalculatedFieldsByEntityId(entityId); var entityIdFields = getCalculatedFieldsByEntityId(entityId);
var profileIdFields = getCalculatedFieldsByEntityId(getProfileId(tenantId, entityId)); var profileIdFields = getCalculatedFieldsByEntityId(getProfileId(tenantId, entityId));
if (!entityIdFields.isEmpty() || !profileIdFields.isEmpty()) { if (!entityIdFields.isEmpty() || !profileIdFields.isEmpty()) {
log.info("Pushing telemetry msg to specific actor [{}]", entityId); log.debug("Pushing telemetry msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(new EntityCalculatedFieldTelemetryMsg(msg, entityIdFields, profileIdFields, callback)); getOrCreateActor(entityId).tell(new EntityCalculatedFieldTelemetryMsg(msg, entityIdFields, profileIdFields, callback));
} else { } else {
callback.onSuccess(); callback.onSuccess();
@ -342,7 +342,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
public void onLinkedTelemetryMsg(CalculatedFieldLinkedTelemetryMsg msg) { public void onLinkedTelemetryMsg(CalculatedFieldLinkedTelemetryMsg msg) {
EntityId sourceEntityId = msg.getEntityId(); EntityId sourceEntityId = msg.getEntityId();
log.info("Received linked telemetry msg from entity [{}]", sourceEntityId); log.debug("Received linked telemetry msg from entity [{}]", sourceEntityId);
var proto = msg.getProto(); var proto = msg.getProto();
var linksList = proto.getLinksList(); var linksList = proto.getLinksList();
for (var linkProto : linksList) { for (var linkProto : linksList) {
@ -357,14 +357,14 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
MultipleTbCallback callback = new MultipleTbCallback(entityIds.size(), msg.getCallback()); MultipleTbCallback callback = new MultipleTbCallback(entityIds.size(), msg.getCallback());
var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, callback); var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, callback);
entityIds.forEach(entityId -> { entityIds.forEach(entityId -> {
log.info("Pushing linked telemetry msg to specific actor [{}]", entityId); log.debug("Pushing linked telemetry msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(newMsg); getOrCreateActor(entityId).tell(newMsg);
}); });
} else { } else {
msg.getCallback().onSuccess(); msg.getCallback().onSuccess();
} }
} else { } else {
log.info("Pushing linked telemetry msg to specific actor [{}]", targetEntityId); log.debug("Pushing linked telemetry msg to specific actor [{}]", targetEntityId);
var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, msg.getCallback()); var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, msg.getCallback());
getOrCreateActor(targetEntityId).tell(newMsg); getOrCreateActor(targetEntityId).tell(newMsg);
} }

32
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -91,6 +91,15 @@ public class TenantActor extends RuleChainManagerActor {
isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE);
if (isRuleEngine) { if (isRuleEngine) {
if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) { if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) {
try {
//TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
() -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
() -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
() -> true);
} catch (Exception e) {
log.info("[{}] Failed to init CF Actor.", tenantId, e);
}
try { try {
if (getApiUsageState().isReExecEnabled()) { if (getApiUsageState().isReExecEnabled()) {
log.debug("[{}] Going to init rule chains", tenantId); log.debug("[{}] Going to init rule chains", tenantId);
@ -98,11 +107,6 @@ public class TenantActor extends RuleChainManagerActor {
} else { } else {
log.info("[{}] Skip init of the rule chains due to API limits", tenantId); log.info("[{}] Skip init of the rule chains due to API limits", tenantId);
} }
//TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
() -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
() -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
() -> true);
} catch (Exception e) { } catch (Exception e) {
log.info("Failed to check ApiUsage \"ReExecEnabled\"!!!", e); log.info("Failed to check ApiUsage \"ReExecEnabled\"!!!", e);
cantFindTenant = true; cantFindTenant = true;
@ -185,6 +189,10 @@ public class TenantActor extends RuleChainManagerActor {
} }
private void onToCalculatedFieldSystemActorMsg(ToCalculatedFieldSystemMsg msg, boolean priority) { private void onToCalculatedFieldSystemActorMsg(ToCalculatedFieldSystemMsg msg, boolean priority) {
if (cfActor == null) {
log.warn("[{}] CF Actor is not initialized.", tenantId);
return;
}
if (priority) { if (priority) {
cfActor.tellWithHighPriority(msg); cfActor.tellWithHighPriority(msg);
} else { } else {
@ -251,11 +259,25 @@ public class TenantActor extends RuleChainManagerActor {
ServiceType serviceType = msg.getServiceType(); ServiceType serviceType = msg.getServiceType();
if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) { if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) {
if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) { if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) {
if (cfActor == null) {
try {
//TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
() -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
() -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
() -> true);
} catch (Exception e) {
log.info("[{}] Failed to init CF Actor.", tenantId, e);
}
}
if (!ruleChainsInitialized) { if (!ruleChainsInitialized) {
log.info("Tenant {} is now managed by this service, initializing rule chains", tenantId); log.info("Tenant {} is now managed by this service, initializing rule chains", tenantId);
initRuleChains(); initRuleChains();
} }
} else { } else {
if (cfActor != null) {
ctx.stop(cfActor.getActorId());
}
if (ruleChainsInitialized) { if (ruleChainsInitialized) {
log.info("Tenant {} is no longer managed by this service, stopping rule chains", tenantId); log.info("Tenant {} is no longer managed by this service, stopping rule chains", tenantId);
destroyRuleChains(); destroyRuleChains();

4
application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldProcessingService.java

@ -30,6 +30,7 @@ import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg; import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg;
import org.thingsboard.server.actors.calculatedField.MultipleTbCallback; import org.thingsboard.server.actors.calculatedField.MultipleTbCallback;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.cf.configuration.Argument; import org.thingsboard.server.common.data.cf.configuration.Argument;
@ -51,6 +52,7 @@ import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.attributes.AttributesService;
@ -200,7 +202,7 @@ public class DefaultCalculatedFieldProcessingService implements CalculatedFieldP
if (broadcast) { if (broadcast) {
broadcasts.add(link); broadcasts.add(link);
} else { } else {
TopicPartitionInfo tpi = partitionService.resolve(QueueKey.CF, link.entityId()); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, link.tenantId(), link.entityId());
unicasts.computeIfAbsent(tpi, k -> new ArrayList<>()).add(link); unicasts.computeIfAbsent(tpi, k -> new ArrayList<>()).add(link);
} }
} }

8
application/src/main/java/org/thingsboard/server/service/cf/cache/DefaultCalculatedFieldEntityProfileCache.java

@ -18,8 +18,10 @@ package org.thingsboard.server.service.cf.cache;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.QueueKey; import org.thingsboard.server.queue.discovery.QueueKey;
@ -57,7 +59,7 @@ public class DefaultCalculatedFieldEntityProfileCache extends TbApplicationEvent
@Override @Override
public void add(TenantId tenantId, EntityId profileId, EntityId entityId) { public void add(TenantId tenantId, EntityId profileId, EntityId entityId) {
var tpi = partitionService.resolve(QueueKey.CF, entityId); var tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId);
var partition = tpi.getPartition().orElse(UNKNOWN); var partition = tpi.getPartition().orElse(UNKNOWN);
tenantCache.computeIfAbsent(tenantId, id -> new TenantEntityProfileCache()) tenantCache.computeIfAbsent(tenantId, id -> new TenantEntityProfileCache())
.add(profileId, entityId, partition, tpi.isMyPartition()); .add(profileId, entityId, partition, tpi.isMyPartition());
@ -65,7 +67,7 @@ public class DefaultCalculatedFieldEntityProfileCache extends TbApplicationEvent
@Override @Override
public void update(TenantId tenantId, EntityId oldProfileId, EntityId newProfileId, EntityId entityId) { public void update(TenantId tenantId, EntityId oldProfileId, EntityId newProfileId, EntityId entityId) {
var tpi = partitionService.resolve(QueueKey.CF, entityId); var tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId);
var partition = tpi.getPartition().orElse(UNKNOWN); var partition = tpi.getPartition().orElse(UNKNOWN);
var cache = tenantCache.computeIfAbsent(tenantId, id -> new TenantEntityProfileCache()); var cache = tenantCache.computeIfAbsent(tenantId, id -> new TenantEntityProfileCache());
//TODO: make this method atomic; //TODO: make this method atomic;
@ -86,7 +88,7 @@ public class DefaultCalculatedFieldEntityProfileCache extends TbApplicationEvent
@Override @Override
public int getEntityIdPartition(TenantId tenantId, EntityId entityId) { public int getEntityIdPartition(TenantId tenantId, EntityId entityId) {
var tpi = partitionService.resolve(QueueKey.CF, entityId); var tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId);
return tpi.getPartition().orElse(UNKNOWN); return tpi.getPartition().orElse(UNKNOWN);
} }

9
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/CalculatedFieldCtx.java

@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.util.TbPair;
import org.thingsboard.server.common.util.ProtoUtils; import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.dao.usagerecord.ApiLimitService; import org.thingsboard.server.dao.usagerecord.ApiLimitService;
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto; import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto;
@ -44,7 +43,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
@Data @Data
public class CalculatedFieldCtx { public class CalculatedFieldCtx {
@ -58,8 +56,6 @@ public class CalculatedFieldCtx {
private final Map<String, Argument> arguments; private final Map<String, Argument> arguments;
private final Map<ReferencedEntityKey, String> mainEntityArguments; private final Map<ReferencedEntityKey, String> mainEntityArguments;
private final Map<EntityId, Map<ReferencedEntityKey, String>> linkedEntityArguments; private final Map<EntityId, Map<ReferencedEntityKey, String>> linkedEntityArguments;
private final Map<TbPair<EntityId, ReferencedEntityKey>, String> referencedEntityKeys;
private final List<String> argNames; private final List<String> argNames;
private Output output; private Output output;
private String expression; private String expression;
@ -93,11 +89,6 @@ public class CalculatedFieldCtx {
linkedEntityArguments.computeIfAbsent(refId, key -> new HashMap<>()).put(refKey, entry.getKey()); linkedEntityArguments.computeIfAbsent(refId, key -> new HashMap<>()).put(refKey, entry.getKey());
} }
} }
this.referencedEntityKeys = arguments.entrySet().stream()
.collect(Collectors.toMap(
entry -> new TbPair<>(entry.getValue().getRefEntityId() == null ? entityId : entry.getValue().getRefEntityId(), entry.getValue().getRefEntityKey()),
Map.Entry::getKey
));
this.argNames = new ArrayList<>(arguments.keySet()); this.argNames = new ArrayList<>(arguments.keySet());
this.output = configuration.getOutput(); this.output = configuration.getOutput();
this.expression = configuration.getExpression(); this.expression = configuration.getExpression();

10
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/KafkaCalculatedFieldStateService.java

@ -20,10 +20,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.id.CalculatedFieldId; import org.thingsboard.server.common.data.id.CalculatedFieldId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldStateProto; import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldStateProto;
@ -67,9 +69,11 @@ public class KafkaCalculatedFieldStateService extends AbstractCalculatedFieldSta
@Override @Override
public void init(PartitionedQueueConsumerManager<TbProtoQueueMsg<ToCalculatedFieldMsg>> eventConsumer) { public void init(PartitionedQueueConsumerManager<TbProtoQueueMsg<ToCalculatedFieldMsg>> eventConsumer) {
super.init(eventConsumer); super.init(eventConsumer);
var queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.CF_STATES_QUEUE_NAME);
this.stateConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<CalculatedFieldStateProto>>create() this.stateConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<CalculatedFieldStateProto>>create()
.queueKey(QueueKey.CF_STATES) .queueKey(queueKey)
.topic(partitionService.getTopic(QueueKey.CF_STATES)) .topic(partitionService.getTopic(queueKey))
.pollInterval(pollInterval) .pollInterval(pollInterval)
.msgPackProcessor((msgs, consumer, config) -> { .msgPackProcessor((msgs, consumer, config) -> {
for (TbProtoQueueMsg<CalculatedFieldStateProto> msg : msgs) { for (TbProtoQueueMsg<CalculatedFieldStateProto> msg : msgs) {
@ -101,7 +105,7 @@ public class KafkaCalculatedFieldStateService extends AbstractCalculatedFieldSta
@Override @Override
protected void doPersist(CalculatedFieldEntityCtxId stateId, CalculatedFieldStateProto stateMsgProto, TbCallback callback) { protected void doPersist(CalculatedFieldEntityCtxId stateId, CalculatedFieldStateProto stateMsgProto, TbCallback callback) {
TopicPartitionInfo tpi = partitionService.resolve(QueueKey.CF_STATES, stateId.entityId()); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_STATES_QUEUE_NAME, stateId.tenantId(), stateId.entityId());
TbProtoQueueMsg<CalculatedFieldStateProto> msg = new TbProtoQueueMsg<>(stateId.entityId().getId(), stateMsgProto); TbProtoQueueMsg<CalculatedFieldStateProto> msg = new TbProtoQueueMsg<>(stateId.entityId().getId(), stateMsgProto);
if (stateMsgProto == null) { if (stateMsgProto == null) {
putStateId(msg.getHeaders(), stateId); putStateId(msg.getHeaders(), stateId);

2
application/src/main/java/org/thingsboard/server/service/install/DefaultDatabaseSchemaSettingsService.java

@ -32,7 +32,7 @@ public class DefaultDatabaseSchemaSettingsService implements DatabaseSchemaSetti
// This list should include all versions which are compatible for the upgrade. // This list should include all versions which are compatible for the upgrade.
// The compatibility cycle usually breaks when we have some scripts written in Java that may not work after new release. // The compatibility cycle usually breaks when we have some scripts written in Java that may not work after new release.
private static final List<String> SUPPORTED_VERSIONS_FOR_UPGRADE = List.of("3.9.0"); private static final List<String> SUPPORTED_VERSIONS_FOR_UPGRADE = List.of("3.9.0", "3.9.1");
private final ProjectInfo projectInfo; private final ProjectInfo projectInfo;
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;

18
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCalculatedFieldConsumerService.java

@ -27,6 +27,7 @@ import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.calculatedField.CalculatedFieldLinkedTelemetryMsg; import org.thingsboard.server.actors.calculatedField.CalculatedFieldLinkedTelemetryMsg;
import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg; import org.thingsboard.server.actors.calculatedField.CalculatedFieldTelemetryMsg;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.QueueConfig; import org.thingsboard.server.common.data.queue.QueueConfig;
@ -79,8 +80,6 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
private long pollInterval; private long pollInterval;
@Value("${queue.calculated_fields.pack_processing_timeout:60000}") @Value("${queue.calculated_fields.pack_processing_timeout:60000}")
private long packProcessingTimeout; private long packProcessingTimeout;
@Value("${queue.calculated_fields.pool_size:8}")
private int poolSize;
private final TbRuleEngineQueueFactory queueFactory; private final TbRuleEngineQueueFactory queueFactory;
private final CalculatedFieldStateService stateService; private final CalculatedFieldStateService stateService;
@ -108,9 +107,10 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
public void init() { public void init() {
super.init("tb-cf"); super.init("tb-cf");
var queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME);
this.eventConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<ToCalculatedFieldMsg>>create() this.eventConsumer = PartitionedQueueConsumerManager.<TbProtoQueueMsg<ToCalculatedFieldMsg>>create()
.queueKey(QueueKey.CF) .queueKey(queueKey)
.topic(partitionService.getTopic(QueueKey.CF)) .topic(partitionService.getTopic(queueKey))
.pollInterval(pollInterval) .pollInterval(pollInterval)
.msgPackProcessor(this::processMsgs) .msgPackProcessor(this::processMsgs)
.consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer()) .consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer())
@ -140,20 +140,12 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
// Cleanup old entities after corresponding consumers are stopped. // Cleanup old entities after corresponding consumers are stopped.
// Any periodic tasks need to check that the entity is still managed by the current server before processing. // Any periodic tasks need to check that the entity is still managed by the current server before processing.
actorContext.tell(new CalculatedFieldPartitionChangeMsg(partitionsToBooleanIndexArray(partitions))); actorContext.tell(new CalculatedFieldPartitionChangeMsg());
} catch (Throwable t) { } catch (Throwable t) {
log.error("Failed to process partition change event: {}", event, t); log.error("Failed to process partition change event: {}", event, t);
} }
} }
private boolean[] partitionsToBooleanIndexArray(Set<TopicPartitionInfo> partitions) {
boolean[] myPartitions = new boolean[partitionService.getTotalCalculatedFieldPartitions()];
for (var tpi : partitions) {
tpi.getPartition().ifPresent(partition -> myPartitions[partition] = true);
}
return myPartitions;
}
private void processMsgs(List<TbProtoQueueMsg<ToCalculatedFieldMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldMsg>> consumer, QueueConfig config) throws Exception { private void processMsgs(List<TbProtoQueueMsg<ToCalculatedFieldMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldMsg>> consumer, QueueConfig config) throws Exception {
List<IdMsgPair<ToCalculatedFieldMsg>> orderedMsgList = msgs.stream().map(msg -> new IdMsgPair<>(UUID.randomUUID(), msg)).toList(); List<IdMsgPair<ToCalculatedFieldMsg>> orderedMsgList = msgs.stream().map(msg -> new IdMsgPair<>(UUID.randomUUID(), msg)).toList();
ConcurrentMap<UUID, TbProtoQueueMsg<ToCalculatedFieldMsg>> pendingMap = orderedMsgList.stream().collect( ConcurrentMap<UUID, TbProtoQueueMsg<ToCalculatedFieldMsg>> pendingMap = orderedMsgList.stream().collect(

4
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java

@ -358,7 +358,7 @@ public class DefaultTbClusterService implements TbClusterService {
@Override @Override
public void pushMsgToCalculatedFields(TenantId tenantId, EntityId entityId, ToCalculatedFieldMsg msg, TbQueueCallback callback) { public void pushMsgToCalculatedFields(TenantId tenantId, EntityId entityId, ToCalculatedFieldMsg msg, TbQueueCallback callback) {
TopicPartitionInfo tpi = partitionService.resolve(QueueKey.CF, entityId); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId);
pushMsgToCalculatedFields(tpi, UUID.randomUUID(), msg, callback); pushMsgToCalculatedFields(tpi, UUID.randomUUID(), msg, callback);
} }
@ -371,7 +371,7 @@ public class DefaultTbClusterService implements TbClusterService {
@Override @Override
public void pushNotificationToCalculatedFields(TenantId tenantId, EntityId entityId, ToCalculatedFieldNotificationMsg msg, TbQueueCallback callback) { public void pushNotificationToCalculatedFields(TenantId tenantId, EntityId entityId, ToCalculatedFieldNotificationMsg msg, TbQueueCallback callback) {
TopicPartitionInfo tpi = partitionService.resolve(QueueKey.CF, entityId); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId);
producerProvider.getCalculatedFieldsNotificationsMsgProducer().send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), callback); producerProvider.getCalculatedFieldsNotificationsMsgProducer().send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), callback);
toRuleEngineNfs.incrementAndGet(); toRuleEngineNfs.incrementAndGet();
} }

3
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java

@ -22,6 +22,7 @@ import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -108,7 +109,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
@Override @Override
protected void onTbApplicationEvent(PartitionChangeEvent event) { protected void onTbApplicationEvent(PartitionChangeEvent event) {
event.getNewPartitions().forEach((queueKey, partitions) -> { event.getNewPartitions().forEach((queueKey, partitions) -> {
if (CollectionsUtil.isOneOf(queueKey, QueueKey.CF, QueueKey.CF_STATES)) { if (DataConstants.CF_QUEUE_NAME.equals(queueKey.getQueueName()) || DataConstants.CF_STATES_QUEUE_NAME.equals(queueKey.getQueueName())) {
return; return;
} }
if (partitionService.isManagedByCurrentService(queueKey.getTenantId())) { if (partitionService.isManagedByCurrentService(queueKey.getTenantId())) {

7
application/src/main/resources/thingsboard.yml

@ -1757,9 +1757,6 @@ queue:
stats: stats:
# Enable/disable statistics for EDQS # Enable/disable statistics for EDQS
enabled: "${TB_EDQS_STATS_ENABLED:true}" enabled: "${TB_EDQS_STATS_ENABLED:true}"
# Statistics printing interval for EDQS
print-interval-ms: "${TB_EDQS_STATS_PRINT_INTERVAL_MS:300000}"
vc: vc:
# Default topic name # Default topic name
topic: "${TB_QUEUE_VC_TOPIC:tb_version_control}" topic: "${TB_QUEUE_VC_TOPIC:tb_version_control}"
@ -1816,9 +1813,7 @@ queue:
# 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_CF_NOTIFICATIONS_TOPIC:calculated_field.notifications}" notifications_topic: "${TB_QUEUE_CF_NOTIFICATIONS_TOPIC:calculated_field.notifications}"
# Interval in milliseconds to poll messages by CF (Rule Engine) microservices # Interval in milliseconds to poll messages by CF (Rule Engine) microservices
poll_interval: "${TB_QUEUE_CF_POLL_INTERVAL_MS:25}" poll_interval: "${TB_QUEUE_CF_POLL_INTERVAL_MS:1000}"
# Amount of partitions used by CF microservices
partitions: "${TB_QUEUE_CF_PARTITIONS:10}"
# Timeout for processing a message pack by CF microservices # Timeout for processing a message pack by CF microservices
pack_processing_timeout: "${TB_QUEUE_CF_PACK_PROCESSING_TIMEOUT_MS:60000}" pack_processing_timeout: "${TB_QUEUE_CF_PACK_PROCESSING_TIMEOUT_MS:60000}"
# Thread pool size for processing of the incoming messages # Thread pool size for processing of the incoming messages

2
common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/FieldsUtil.java

@ -289,7 +289,7 @@ public class FieldsUtil {
} }
public static String getText(JsonNode node) { public static String getText(JsonNode node) {
return node != null ? node.asText() : ""; return node != null ? node.toString() : "";
} }
private static UUID getCustomerId(CustomerId customerId) { private static UUID getCustomerId(CustomerId customerId) {

3
common/edqs/src/main/java/org/thingsboard/server/edqs/repo/TenantRepo.java

@ -430,6 +430,9 @@ public class TenantRepo {
private String getEntityName(EntityId entityId) { private String getEntityName(EntityId entityId) {
EntityType entityType = entityId.getEntityType(); EntityType entityType = entityId.getEntityType();
if (entityType == EntityType.TENANT && entityId.getId().equals(TenantId.NULL_UUID)) {
return "";
}
return switch (entityType) { return switch (entityType) {
case CUSTOMER, TENANT -> getEntityMap(entityType).get(entityId.getId()).getFields().getName(); case CUSTOMER, TENANT -> getEntityMap(entityType).get(entityId.getId()).getFields().getName();
default -> throw new RuntimeException("Unsupported entity type: " + entityType); default -> throw new RuntimeException("Unsupported entity type: " + entityType);

13
common/edqs/src/main/java/org/thingsboard/server/edqs/stats/EdqsStatsService.java

@ -20,7 +20,6 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.ObjectType; import org.thingsboard.server.common.data.ObjectType;
import org.thingsboard.server.common.data.edqs.EdqsEventType; import org.thingsboard.server.common.data.edqs.EdqsEventType;
@ -43,18 +42,6 @@ public class EdqsStatsService {
private final ConcurrentHashMap<TenantId, EdqsStats> statsMap = new ConcurrentHashMap<>(); private final ConcurrentHashMap<TenantId, EdqsStats> statsMap = new ConcurrentHashMap<>();
private final StatsFactory statsFactory; private final StatsFactory statsFactory;
@Scheduled(initialDelayString = "${queue.edqs.stats.print-interval-ms:300000}",
fixedDelayString = "${queue.edqs.stats.print-interval-ms:300000}")
private void reportStats() {
if (statsMap.isEmpty()) {
return;
}
String values = statsMap.entrySet().stream()
.map(kv -> "TenantId [" + kv.getKey() + "] stats [" + kv.getValue() + "]")
.collect(Collectors.joining(System.lineSeparator()));
log.info("EDQS Stats: {}", values);
}
public void reportEvent(TenantId tenantId, ObjectType objectType, EdqsEventType eventType) { public void reportEvent(TenantId tenantId, ObjectType objectType, EdqsEventType eventType) {
statsMap.computeIfAbsent(tenantId, id -> new EdqsStats(tenantId, statsFactory)) statsMap.computeIfAbsent(tenantId, id -> new EdqsStats(tenantId, statsFactory))
.reportEvent(objectType, eventType); .reportEvent(objectType, eventType);

2
common/message/src/main/java/org/thingsboard/server/common/msg/cf/CalculatedFieldPartitionChangeMsg.java

@ -26,8 +26,6 @@ import java.util.Set;
@Data @Data
public class CalculatedFieldPartitionChangeMsg implements ToCalculatedFieldSystemMsg { public class CalculatedFieldPartitionChangeMsg implements ToCalculatedFieldSystemMsg {
private final boolean[] partitions;
@Override @Override
public TenantId getTenantId() { public TenantId getTenantId() {
return TenantId.SYS_TENANT_ID; return TenantId.SYS_TENANT_ID;

41
common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java

@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.exception.TenantNotFoundException; import org.thingsboard.server.common.data.exception.TenantNotFoundException;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -67,8 +68,6 @@ public class HashPartitionService implements PartitionService {
private String cfEventTopic; private String cfEventTopic;
@Value("${queue.calculated_fields.state_topic:tb_cf_state}") @Value("${queue.calculated_fields.state_topic:tb_cf_state}")
private String cfStateTopic; private String cfStateTopic;
@Value("${queue.calculated_fields.partitions:10}")
private Integer cfPartitions;
@Value("${queue.vc.topic:tb_version_control}") @Value("${queue.vc.topic:tb_version_control}")
private String vcTopic; private String vcTopic;
@Value("${queue.vc.partitions:10}") @Value("${queue.vc.partitions:10}")
@ -122,11 +121,6 @@ public class HashPartitionService implements PartitionService {
partitionSizesMap.put(coreKey, corePartitions); partitionSizesMap.put(coreKey, corePartitions);
partitionTopicsMap.put(coreKey, coreTopic); partitionTopicsMap.put(coreKey, coreTopic);
partitionSizesMap.put(QueueKey.CF, cfPartitions);
partitionTopicsMap.put(QueueKey.CF, cfEventTopic);
partitionSizesMap.put(QueueKey.CF_STATES, cfPartitions);
partitionTopicsMap.put(QueueKey.CF_STATES, cfStateTopic);
QueueKey vcKey = new QueueKey(ServiceType.TB_VC_EXECUTOR); QueueKey vcKey = new QueueKey(ServiceType.TB_VC_EXECUTOR);
partitionSizesMap.put(vcKey, vcPartitions); partitionSizesMap.put(vcKey, vcPartitions);
partitionTopicsMap.put(vcKey, vcTopic); partitionTopicsMap.put(vcKey, vcTopic);
@ -165,6 +159,14 @@ public class HashPartitionService implements PartitionService {
List<QueueRoutingInfo> queueRoutingInfoList = getQueueRoutingInfos(); List<QueueRoutingInfo> queueRoutingInfoList = getQueueRoutingInfos();
queueRoutingInfoList.forEach(queue -> { queueRoutingInfoList.forEach(queue -> {
QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, queue); QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, queue);
if (DataConstants.MAIN_QUEUE_NAME.equals(queueKey.getQueueName())) {
QueueKey cfQueueKey = queueKey.withQueueName(DataConstants.CF_QUEUE_NAME);
partitionSizesMap.put(cfQueueKey, queue.getPartitions());
partitionTopicsMap.put(cfQueueKey, cfEventTopic);
QueueKey cfQueueStatesKey = queueKey.withQueueName(DataConstants.CF_STATES_QUEUE_NAME);
partitionSizesMap.put(cfQueueStatesKey, queue.getPartitions());
partitionTopicsMap.put(cfQueueStatesKey, cfStateTopic);
}
partitionTopicsMap.put(queueKey, queue.getQueueTopic()); partitionTopicsMap.put(queueKey, queue.getQueueTopic());
partitionSizesMap.put(queueKey, queue.getPartitions()); partitionSizesMap.put(queueKey, queue.getPartitions());
queueConfigs.put(queueKey, new QueueConfig(queue)); queueConfigs.put(queueKey, new QueueConfig(queue));
@ -213,6 +215,14 @@ public class HashPartitionService implements PartitionService {
QueueRoutingInfo queueRoutingInfo = new QueueRoutingInfo(queueUpdateMsg); QueueRoutingInfo queueRoutingInfo = new QueueRoutingInfo(queueUpdateMsg);
TenantId tenantId = queueRoutingInfo.getTenantId(); TenantId tenantId = queueRoutingInfo.getTenantId();
QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, queueRoutingInfo.getQueueName(), tenantId); QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, queueRoutingInfo.getQueueName(), tenantId);
if (DataConstants.MAIN_QUEUE_NAME.equals(queueKey.getQueueName())) {
QueueKey cfQueueKey = queueKey.withQueueName(DataConstants.CF_QUEUE_NAME);
partitionSizesMap.put(cfQueueKey, queueRoutingInfo.getPartitions());
partitionTopicsMap.put(cfQueueKey, cfEventTopic);
QueueKey cfQueueStatesKey = queueKey.withQueueName(DataConstants.CF_STATES_QUEUE_NAME);
partitionSizesMap.put(cfQueueStatesKey, queueRoutingInfo.getPartitions());
partitionTopicsMap.put(cfQueueStatesKey, cfStateTopic);
}
partitionTopicsMap.put(queueKey, queueRoutingInfo.getQueueTopic()); partitionTopicsMap.put(queueKey, queueRoutingInfo.getQueueTopic());
partitionSizesMap.put(queueKey, queueRoutingInfo.getPartitions()); partitionSizesMap.put(queueKey, queueRoutingInfo.getPartitions());
queueConfigs.put(queueKey, new QueueConfig(queueRoutingInfo)); queueConfigs.put(queueKey, new QueueConfig(queueRoutingInfo));
@ -252,6 +262,15 @@ public class HashPartitionService implements PartitionService {
partitionTopicsMap.remove(queueKey); partitionTopicsMap.remove(queueKey);
partitionSizesMap.remove(queueKey); partitionSizesMap.remove(queueKey);
queueConfigs.remove(queueKey); queueConfigs.remove(queueKey);
if (DataConstants.MAIN_QUEUE_NAME.equals(queueKey.getQueueName())) {
QueueKey cfQueueKey = queueKey.withQueueName(DataConstants.CF_QUEUE_NAME);
partitionSizesMap.remove(cfQueueKey);
partitionTopicsMap.remove(cfQueueKey);
QueueKey cfQueueStatesKey = queueKey.withQueueName(DataConstants.CF_STATES_QUEUE_NAME);
partitionSizesMap.remove(cfQueueStatesKey);
partitionTopicsMap.remove(cfQueueStatesKey);
}
} }
@Override @Override
@ -336,8 +355,7 @@ public class HashPartitionService implements PartitionService {
} }
} }
@Override private TopicPartitionInfo resolve(QueueKey queueKey, EntityId entityId) {
public TopicPartitionInfo resolve(QueueKey queueKey, EntityId entityId) {
Integer partitionSize = partitionSizesMap.get(queueKey); Integer partitionSize = partitionSizesMap.get(queueKey);
if (partitionSize == null) { if (partitionSize == null) {
throw new IllegalStateException("Partitions info for queue " + queueKey + " is missing"); throw new IllegalStateException("Partitions info for queue " + queueKey + " is missing");
@ -552,11 +570,6 @@ public class HashPartitionService implements PartitionService {
return list == null ? 0 : list.size(); return list == null ? 0 : list.size();
} }
@Override
public int getTotalCalculatedFieldPartitions() {
return cfPartitions;
}
private Map<QueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) { private Map<QueueKey, List<ServiceInfo>> getServiceKeyListMap(List<ServiceInfo> services) {
final Map<QueueKey, List<ServiceInfo>> currentMap = new HashMap<>(); final Map<QueueKey, List<ServiceInfo>> currentMap = new HashMap<>();
services.forEach(serviceInfo -> { services.forEach(serviceInfo -> {

4
common/queue/src/main/java/org/thingsboard/server/queue/discovery/PartitionService.java

@ -37,8 +37,6 @@ public interface PartitionService {
TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId); TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId);
TopicPartitionInfo resolve(QueueKey queueKey, EntityId entityId);
List<TopicPartitionInfo> resolveAll(ServiceType serviceType, String queueName, TenantId tenantId, EntityId entityId); List<TopicPartitionInfo> resolveAll(ServiceType serviceType, String queueName, TenantId tenantId, EntityId entityId);
boolean isMyPartition(ServiceType serviceType, TenantId tenantId, EntityId entityId); boolean isMyPartition(ServiceType serviceType, TenantId tenantId, EntityId entityId);
@ -81,6 +79,4 @@ public interface PartitionService {
int resolvePartitionIndex(UUID entityId, int partitions); int resolvePartitionIndex(UUID entityId, int partitions);
int getTotalCalculatedFieldPartitions();
} }

3
common/queue/src/main/java/org/thingsboard/server/queue/discovery/QueueKey.java

@ -35,9 +35,6 @@ public class QueueKey {
private final String queueName; private final String queueName;
private final TenantId tenantId; private final TenantId tenantId;
public static final QueueKey CF = new QueueKey(ServiceType.TB_RULE_ENGINE).withQueueName(CF_QUEUE_NAME);
public static final QueueKey CF_STATES = new QueueKey(ServiceType.TB_RULE_ENGINE).withQueueName(CF_STATES_QUEUE_NAME);
public QueueKey(ServiceType type, Queue queue) { public QueueKey(ServiceType type, Queue queue) {
this.type = type; this.type = type;
this.queueName = queue.getName(); this.queueName = queue.getName();

4
common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java

@ -64,10 +64,10 @@ public class PartitionChangeEvent extends TbApplicationEvent {
} }
public Set<TopicPartitionInfo> getCfPartitions() { public Set<TopicPartitionInfo> getCfPartitions() {
return newPartitions.getOrDefault(QueueKey.CF, Collections.emptySet()); return getPartitionsByServiceTypeAndQueueName(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME);
} }
private Set<TopicPartitionInfo> getPartitionsByServiceTypeAndQueueName(ServiceType serviceType, String queueName) { public Set<TopicPartitionInfo> getPartitionsByServiceTypeAndQueueName(ServiceType serviceType, String queueName) {
return newPartitions.entrySet() return newPartitions.entrySet()
.stream() .stream()
.filter(entry -> serviceType.equals(entry.getKey().getType()) && queueName.equals(entry.getKey().getQueueName())) .filter(entry -> serviceType.equals(entry.getKey().getType()) && queueName.equals(entry.getKey().getQueueName()))

8
common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java

@ -18,8 +18,6 @@ package org.thingsboard.script.api.tbel;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.mvel2.ConversionHandler;
import org.mvel2.DataConversion;
import org.mvel2.ExecutionContext; import org.mvel2.ExecutionContext;
import org.mvel2.ParserConfiguration; import org.mvel2.ParserConfiguration;
import org.mvel2.execution.ExecutionArrayList; import org.mvel2.execution.ExecutionArrayList;
@ -259,6 +257,8 @@ public class TbUtils {
float.class, int.class))); float.class, int.class)));
parserConfig.addImport("toInt", new MethodStub(TbUtils.class.getMethod("toInt", parserConfig.addImport("toInt", new MethodStub(TbUtils.class.getMethod("toInt",
double.class))); double.class)));
parserConfig.addImport("isNaN", new MethodStub(TbUtils.class.getMethod("isNaN",
double.class)));
parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes", parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes",
ExecutionContext.class, String.class))); ExecutionContext.class, String.class)));
parserConfig.addImport("hexToBytesArray", new MethodStub(TbUtils.class.getMethod("hexToBytesArray", parserConfig.addImport("hexToBytesArray", new MethodStub(TbUtils.class.getMethod("hexToBytesArray",
@ -1163,6 +1163,10 @@ public class TbUtils {
return BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP).intValue(); return BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP).intValue();
} }
public static boolean isNaN(double value) {
return Double.isNaN(value);
}
public static ExecutionHashMap<String, Object> toFlatMap(ExecutionContext ctx, Map<String, Object> json) { public static ExecutionHashMap<String, Object> toFlatMap(ExecutionContext ctx, Map<String, Object> json) {
return toFlatMap(ctx, json, new ArrayList<>(), true); return toFlatMap(ctx, json, new ArrayList<>(), true);
} }

8
common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java

@ -1138,12 +1138,18 @@ public class TbUtilsTest {
} }
@Test @Test
void toInt() { public void toInt() {
Assertions.assertEquals(1729, TbUtils.toInt(doubleVal)); Assertions.assertEquals(1729, TbUtils.toInt(doubleVal));
Assertions.assertEquals(13, TbUtils.toInt(12.8)); Assertions.assertEquals(13, TbUtils.toInt(12.8));
Assertions.assertEquals(28, TbUtils.toInt(28.0)); Assertions.assertEquals(28, TbUtils.toInt(28.0));
} }
@Test
public void isNaN() {
Assertions.assertFalse(TbUtils.isNaN(doubleVal));
Assertions.assertTrue(TbUtils.isNaN(Double.NaN));
}
private static List<Byte> toList(byte[] data) { private static List<Byte> toList(byte[] data) {
List<Byte> result = new ArrayList<>(data.length); List<Byte> result = new ArrayList<>(data.length);
for (Byte b : data) { for (Byte b : data) {

4
docker/docker-compose.edqs.volumes.yml

@ -19,10 +19,10 @@ version: '3.0'
services: services:
tb-edqs-1: tb-edqs-1:
volumes: volumes:
- tb-edqs-log-volume:/var/log/edqs - tb-edqs-log-volume:/var/log/tb-edqs
tb-edqs-2: tb-edqs-2:
volumes: volumes:
- tb-edqs-log-volume:/var/log/edqs - tb-edqs-log-volume:/var/log/tb-edqs
volumes: volumes:
tb-edqs-log-volume: tb-edqs-log-volume:

12
docker/docker-compose.edqs.yml

@ -33,10 +33,10 @@ services:
restart: always restart: always
image: "${DOCKER_REPO}/${EDQS_DOCKER_NAME}:${TB_VERSION}" image: "${DOCKER_REPO}/${EDQS_DOCKER_NAME}:${TB_VERSION}"
env_file: env_file:
- edqs.env - tb-edqs.env
volumes: volumes:
- ./edqs/conf:/usr/share/edqs/conf - ./tb-edqs/conf:/usr/share/tb-edqs/conf
- ./edqs/log:/var/log/edqs - ./tb-edqs/log:/var/log/tb-edqs
ports: ports:
- "8080" - "8080"
depends_on: depends_on:
@ -46,10 +46,10 @@ services:
restart: always restart: always
image: "${DOCKER_REPO}/${EDQS_DOCKER_NAME}:${TB_VERSION}" image: "${DOCKER_REPO}/${EDQS_DOCKER_NAME}:${TB_VERSION}"
env_file: env_file:
- edqs.env - tb-edqs.env
volumes: volumes:
- ./edqs/conf:/usr/share/edqs/conf - ./tb-edqs/conf:/usr/share/tb-edqs/conf
- ./edqs/log:/var/log/edqs - ./tb-edqs/log:/var/log/tb-edqs
ports: ports:
- "8080" - "8080"
depends_on: depends_on:

0
docker/edqs.env → docker/tb-edqs.env

4
docker/edqs/conf/logback.xml → docker/tb-edqs/conf/logback.xml

@ -21,10 +21,10 @@
<appender name="fileLogAppender" <appender name="fileLogAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender"> class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/edqs/${TB_SERVICE_ID}/tb-edqs.log</file> <file>/var/log/tb-edqs/${TB_SERVICE_ID}/tb-edqs.log</file>
<rollingPolicy <rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/var/log/edqs/tb-edqs.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <fileNamePattern>/var/log/tb-edqs/tb-edqs.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize> <maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory> <maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap> <totalSizeCap>3GB</totalSizeCap>

4
docker/edqs/conf/edqs.conf → docker/tb-edqs/conf/tb-edqs.conf

@ -14,9 +14,9 @@
# limitations under the License. # limitations under the License.
# #
export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/edqs/${TB_SERVICE_ID}-gc.log:time,uptime,level,tags:filecount=10,filesize=10M" export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/tb-edqs/${TB_SERVICE_ID}-gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError" export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError"
export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark" export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10" export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
export LOG_FILENAME=tb-edqs.out export LOG_FILENAME=tb-edqs.out
export LOADER_PATH=/usr/share/edqs/conf export LOADER_PATH=/usr/share/tb-edqs/conf

2
edqs/src/main/resources/edqs.yml

@ -70,8 +70,6 @@ queue:
stats: stats:
# Enable/disable statistics for EDQS # Enable/disable statistics for EDQS
enabled: "${TB_EDQS_STATS_ENABLED:true}" enabled: "${TB_EDQS_STATS_ENABLED:true}"
# Statistics printing interval for EDQS
print-interval-ms: "${TB_EDQS_STATS_PRINT_INTERVAL_MS:300000}"
kafka: kafka:
# Kafka Bootstrap nodes in "host:port" format # Kafka Bootstrap nodes in "host:port" format

2
ui-ngx/package.json

@ -28,6 +28,7 @@
"@flowjs/ngx-flow": "18.0.1", "@flowjs/ngx-flow": "18.0.1",
"@geoman-io/leaflet-geoman-free": "2.17.0", "@geoman-io/leaflet-geoman-free": "2.17.0",
"@iplab/ngx-color-picker": "^18.0.1", "@iplab/ngx-color-picker": "^18.0.1",
"@maplibre/maplibre-gl-leaflet": "^0.0.22",
"@mat-datetimepicker/core": "~14.0.0", "@mat-datetimepicker/core": "~14.0.0",
"@mdi/svg": "^7.4.47", "@mdi/svg": "^7.4.47",
"@messageformat/core": "^3.4.0", "@messageformat/core": "^3.4.0",
@ -64,6 +65,7 @@
"leaflet.gridlayer.googlemutant": "0.14.1", "leaflet.gridlayer.googlemutant": "0.14.1",
"leaflet.markercluster": "1.5.3", "leaflet.markercluster": "1.5.3",
"libphonenumber-js": "^1.11.15", "libphonenumber-js": "^1.11.15",
"maplibre-gl": "^4.7.1",
"marked": "~12.0.2", "marked": "~12.0.2",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.45", "moment-timezone": "^0.5.45",

21
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet/leaflet-tb.ts

@ -17,6 +17,7 @@
import L, { TB } from 'leaflet'; import L, { TB } from 'leaflet';
import { guid, isNotEmptyStr } from '@core/utils'; import { guid, isNotEmptyStr } from '@core/utils';
import 'leaflet-providers'; import 'leaflet-providers';
import '@maplibre/maplibre-gl-leaflet';
import '@geoman-io/leaflet-geoman-free'; import '@geoman-io/leaflet-geoman-free';
import 'leaflet.markercluster'; import 'leaflet.markercluster';
import { MatIconRegistry } from '@angular/material/icon'; import { MatIconRegistry } from '@angular/material/icon';
@ -211,15 +212,19 @@ class LayersControl extends SidebarPaneControl<TB.LayersControlOptions> {
input.on('click', (e: JQuery.MouseEventBase) => { input.on('click', (e: JQuery.MouseEventBase) => {
e.stopPropagation(); e.stopPropagation();
layers.forEach((other) => { if (!map.hasLayer(layerData.layer)) {
if (other.layer === layerData.layer) { map.addLayer(layerData.layer);
map.addLayer(other.layer); map.attributionControl.setPrefix(layerData.attributionPrefix);
map.attributionControl.setPrefix(other.attributionPrefix); if (layerData.onAdd) {
} else { layerData.onAdd();
map.removeLayer(other.layer);
} }
}); layers.forEach((other) => {
map.fire('baselayerchange', { layer: layerData.layer }); if (other.layer !== layerData.layer) {
map.removeLayer(other.layer);
}
});
map.fire('baselayerchange', { layer: layerData.layer });
}
}); });
item.on('dblclick', (e) => { item.on('dblclick', (e) => {

116
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-layer.ts

@ -26,17 +26,34 @@ import {
HereMapLayerSettings, HereMapLayerSettings,
MapLayerSettings, MapLayerSettings,
MapProvider, MapProvider,
OpenStreetMapLayerSettings, OpenStreetMapLayerSettings, ReferenceLayerType,
TencentMapLayerSettings TencentMapLayerSettings
} from '@shared/models/widget/maps/map.models'; } from '@shared/models/widget/maps/map.models';
import { WidgetContext } from '@home/models/widget-component.models'; import { WidgetContext } from '@home/models/widget-component.models';
import { DeepPartial } from '@shared/models/common'; import { DeepPartial } from '@shared/models/common';
import { mergeDeep } from '@core/utils'; import { mergeDeep } from '@core/utils';
import { Observable, of, switchMap } from 'rxjs'; import { Observable, of, shareReplay, switchMap } from 'rxjs';
import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe';
import L from 'leaflet'; import L from 'leaflet';
import { catchError, map } from 'rxjs/operators'; import { catchError, map } from 'rxjs/operators';
import { ResourcesService } from '@core/services/resources.service'; import { ResourcesService } from '@core/services/resources.service';
import { StyleSpecification, VectorSourceSpecification } from '@maplibre/maplibre-gl-style-spec';
import { ResourceType } from 'maplibre-gl';
const referenceLayerStyleUrlMap = new Map<ReferenceLayerType, string>(
[
[ReferenceLayerType.openstreetmap_hybrid, '/assets/map/openstreetmap_hybrid_reference_style.json'],
[ReferenceLayerType.world_edition_hybrid, '/assets/map/world_edition_hybrid_reference_style.json']
]
);
const referenceLayerCache = new Map<ReferenceLayerType, Observable<StyleSpecification>>();
interface TbMapLayerData {
layer: L.Layer;
attribution: boolean;
onAdd?: () => void;
}
export abstract class TbMapLayer<S extends MapLayerSettings> { export abstract class TbMapLayer<S extends MapLayerSettings> {
@ -65,19 +82,23 @@ export abstract class TbMapLayer<S extends MapLayerSettings> {
} }
public loadLayer(theMap: L.Map): Observable<L.TB.LayerData> { public loadLayer(theMap: L.Map): Observable<L.TB.LayerData> {
return this.createLayer().pipe( return this.generateLayer().pipe(
switchMap((layer) => { switchMap((layerData) => {
if (layer) { if (layerData) {
return this.createLayer().pipe( return this.generateLayer().pipe(
map((mini) => { map((miniLayerData) => {
if (mini) { if (miniLayerData) {
const attribution = layer.getAttribution(); const attributionPrefix = layerData.attribution ? theMap.attributionControl.options.prefix as string : null;
const attributionPrefix = attribution ? theMap.attributionControl.options.prefix as string : null;
return { return {
title: this.title(), title: this.title(),
attributionPrefix: attributionPrefix, attributionPrefix: attributionPrefix,
layer, layer: layerData.layer,
mini mini: miniLayerData.layer,
onAdd: () => {
if (layerData.onAdd) {
layerData.onAdd();
}
}
}; };
} else { } else {
return null; return null;
@ -91,6 +112,77 @@ export abstract class TbMapLayer<S extends MapLayerSettings> {
); );
} }
private generateLayer(): Observable<TbMapLayerData> {
return this.createLayer().pipe(
switchMap((baseLayer) => {
if (baseLayer) {
if (this.settings.referenceLayer) {
return this.loadReferenceLayer(this.settings.referenceLayer).pipe(
map((referenceLayer) => {
if (referenceLayer) {
const layer = L.featureGroup();
baseLayer.addTo(layer);
referenceLayer.addTo(layer);
return {
layer,
attribution: !!baseLayer.getAttribution() || !!referenceLayer.getAttribution(),
onAdd: () => {
(referenceLayer as any)._update();
}
};
} else {
return {
layer: baseLayer,
attribution: !!baseLayer.getAttribution()
};
}
}));
} else {
return of({
layer: baseLayer,
attribution: !!baseLayer.getAttribution()
});
}
} else {
return of(null);
}
}
));
}
private loadReferenceLayer(referenceLayer: ReferenceLayerType): Observable<L.Layer> {
let spec$ = referenceLayerCache.get(referenceLayer);
if (!spec$) {
const styleUrl = referenceLayerStyleUrlMap.get(referenceLayer);
spec$ = this.ctx.http.get<StyleSpecification>(styleUrl).pipe(
shareReplay({
bufferSize: 1,
refCount: true
})
);
referenceLayerCache.set(referenceLayer, spec$);
}
return spec$.pipe(
map(spec => {
const sourceSpec = (spec.sources['esri'] as VectorSourceSpecification);
const tileUrl = sourceSpec.url;
const attribution = sourceSpec.attribution;
const transformRequest = (url: string, resourceType: ResourceType) => {
if (resourceType === 'Tile') {
url = tileUrl + '/' + url;
}
return {url}
}
const gl = L.maplibreGL({
style: spec,
transformRequest
});
gl.options.attribution = attribution;
return gl;
})
);
}
private title(): string { private title(): string {
const customTranslate = this.ctx.$injector.get(CustomTranslatePipe); const customTranslate = this.ctx.$injector.get(CustomTranslatePipe);
if (this.settings.label) { if (this.settings.label) {

8
ui-ngx/src/app/modules/home/components/widget/lib/maps/map.scss

@ -35,6 +35,10 @@ div.tb-widget .tb-widget-content.tb-no-interaction {
.tb-map-container { .tb-map-container {
flex-direction: column; flex-direction: column;
.leaflet-gl-layer.maplibregl-map {
position: relative;
z-index: 1;
}
} }
.tb-map-layout { .tb-map-layout {
@ -47,6 +51,10 @@ div.tb-widget .tb-widget-content.tb-no-interaction {
.tb-map { .tb-map {
position: relative; position: relative;
flex: 1; flex: 1;
.leaflet-control-attribution {
font-size: 0.6rem;
background: rgba(255,255,255,0.5);
}
&.leaflet-touch { &.leaflet-touch {
.leaflet-bar { .leaflet-bar {
border: 1px solid rgba(0,0,0,0.38); border: 1px solid rgba(0,0,0,0.38);

3
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts

@ -123,7 +123,8 @@ export class MapLayerRowComponent implements ControlValueAccessor, OnInit {
provider: [null, [Validators.required]], provider: [null, [Validators.required]],
layerType: [null, [Validators.required]], layerType: [null, [Validators.required]],
tileUrl: [null, [Validators.required]], tileUrl: [null, [Validators.required]],
apiKey: [null, [Validators.required]] apiKey: [null, [Validators.required]],
referenceLayer: [null, []]
}); });
this.layerFormGroup.valueChanges.pipe( this.layerFormGroup.valueChanges.pipe(
takeUntilDestroyed(this.destroyRef) takeUntilDestroyed(this.destroyRef)

11
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.html

@ -82,6 +82,17 @@
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
<div class="tb-form-row space-between column-xs">
<div class="fixed-title-width" translate>widgets.maps.layer.reference.reference-layer</div>
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="referenceLayer" placeholder="{{'widgets.maps.layer.reference.no-layer' | translate}}">
<mat-option [value]="null">{{ 'widgets.maps.layer.reference.no-layer' | translate }}</mat-option>
<mat-option *ngFor="let layer of referenceLayerTypes" [value]="layer">
{{ referenceLayerTypeTranslationMap.get(layer) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div> </div>
<div class="tb-map-layer-settings-panel-buttons"> <div class="tb-map-layer-settings-panel-buttons">
<button mat-button <button mat-button

9
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-settings-panel.component.ts

@ -30,7 +30,7 @@ import {
mapProviders, mapProviders,
mapProviderTranslationMap, mapProviderTranslationMap,
openStreetLayerTypes, openStreetLayerTypes,
openStreetMapLayerTranslationMap, openStreetMapLayerTranslationMap, referenceLayerTypes, referenceLayerTypeTranslationMap,
tencentLayerTranslationMap, tencentLayerTranslationMap,
tencentLayerTypes tencentLayerTypes
} from '@shared/models/widget/maps/map.models'; } from '@shared/models/widget/maps/map.models';
@ -67,6 +67,10 @@ export class MapLayerSettingsPanelComponent implements OnInit {
tencentLayerTranslationMap = tencentLayerTranslationMap; tencentLayerTranslationMap = tencentLayerTranslationMap;
referenceLayerTypes = referenceLayerTypes;
referenceLayerTypeTranslationMap = referenceLayerTypeTranslationMap;
@Input() @Input()
mapLayerSettings: MapLayerSettings; mapLayerSettings: MapLayerSettings;
@ -90,7 +94,8 @@ export class MapLayerSettingsPanelComponent implements OnInit {
provider: [null, [Validators.required]], provider: [null, [Validators.required]],
layerType: [null, [Validators.required]], layerType: [null, [Validators.required]],
tileUrl: [null, [Validators.required]], tileUrl: [null, [Validators.required]],
apiKey: [null, [Validators.required]] apiKey: [null, [Validators.required]],
referenceLayer: [null, []]
} }
); );
this.layerFormGroup.patchValue( this.layerFormGroup.patchValue(

28
ui-ngx/src/app/shared/models/widget/maps/map.models.ts

@ -438,19 +438,19 @@ export const defaultBaseTripsDataLayerSettings = (mapType: MapType): Partial<Tri
rotateMarker: true, rotateMarker: true,
offsetAngle: 0, offsetAngle: 0,
markerShape: { markerShape: {
shape: MarkerShape.tripMarkerShape1 shape: MarkerShape.tripMarkerShape2
}, },
markerIcon: { markerIcon: {
iconContainer: MarkerIconContainer.tripIconContainer1, iconContainer: MarkerIconContainer.tripIconContainer1,
icon: 'arrow_forward' icon: 'arrow_forward'
}, },
markerImage: { markerImage: {
image: '/assets/markers/tripShape1.svg' image: '/assets/markers/tripShape2.svg'
}, },
markerOffsetX: 0.5, markerOffsetX: 0.5,
markerOffsetY: 0.5, markerOffsetY: 0.5,
showPath: true, showPath: true,
pathStrokeWeight: 2, pathStrokeWeight: 4,
pathStrokeColor: { pathStrokeColor: {
type: DataLayerColorType.constant, type: DataLayerColorType.constant,
color: '#307FE5', color: '#307FE5',
@ -755,9 +755,24 @@ export const mapProviderTranslationMap = new Map<MapProvider, string>(
] ]
); );
export enum ReferenceLayerType {
openstreetmap_hybrid = 'openstreetmap_hybrid',
world_edition_hybrid = 'world_edition_hybrid',
}
export const referenceLayerTypes = Object.keys(ReferenceLayerType) as ReferenceLayerType[];
export const referenceLayerTypeTranslationMap = new Map<ReferenceLayerType, string>(
[
[ReferenceLayerType.openstreetmap_hybrid, 'widgets.maps.layer.reference.openstreetmap-hybrid'],
[ReferenceLayerType.world_edition_hybrid, 'widgets.maps.layer.reference.world-edition-hybrid']
]
);
export interface MapLayerSettings { export interface MapLayerSettings {
label?: string; label?: string;
provider: MapProvider; provider: MapProvider;
referenceLayer?: ReferenceLayerType;
} }
export const mapLayerValid = (layer: MapLayerSettings): boolean => { export const mapLayerValid = (layer: MapLayerSettings): boolean => {
@ -973,9 +988,10 @@ export const defaultMapLayers: MapLayerSettings[] = [
} as OpenStreetMapLayerSettings, } as OpenStreetMapLayerSettings,
{ {
label: '{i18n:widgets.maps.layer.hybrid}', label: '{i18n:widgets.maps.layer.hybrid}',
provider: MapProvider.google, provider: MapProvider.openstreet,
layerType: GoogleLayerType.hybrid, layerType: OpenStreetLayerType.esriWorldImagery,
} as GoogleMapLayerSettings referenceLayer: ReferenceLayerType.openstreetmap_hybrid
} as OpenStreetMapLayerSettings
]; ];
export interface GeoMapSettings extends BaseMapSettings { export interface GeoMapSettings extends BaseMapSettings {

6
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -7906,6 +7906,12 @@
"roadmap": "Roadmap", "roadmap": "Roadmap",
"satellite": "Satellite", "satellite": "Satellite",
"hybrid": "Hybrid", "hybrid": "Hybrid",
"reference": {
"reference-layer": "Reference layer",
"no-layer": "No layer",
"openstreetmap-hybrid": "OpenStreetMap Hybrid",
"world-edition-hybrid": "World Edition Hybrid"
},
"provider": { "provider": {
"provider": "Provider", "provider": "Provider",
"openstreet": { "openstreet": {

25800
ui-ngx/src/assets/map/openstreetmap_hybrid_reference_style.json

File diff suppressed because it is too large

57837
ui-ngx/src/assets/map/world_edition_hybrid_reference_style.json

File diff suppressed because it is too large

1
ui-ngx/src/typings/leaflet-extend-tb.d.ts

@ -61,6 +61,7 @@ declare module 'leaflet' {
attributionPrefix?: string; attributionPrefix?: string;
layer: Layer; layer: Layer;
mini: Layer; mini: Layer;
onAdd?: () => void;
} }
interface LayersControlOptions extends SidebarPaneControlOptions { interface LayersControlOptions extends SidebarPaneControlOptions {

228
ui-ngx/yarn.lock

@ -1931,6 +1931,64 @@
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.13.tgz#93bcd6dc24afd1cc60dd88a65b9e4fab32dcf397" resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.13.tgz#93bcd6dc24afd1cc60dd88a65b9e4fab32dcf397"
integrity sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA== integrity sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA==
"@mapbox/geojson-rewind@^0.5.2":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz#591a5d71a9cd1da1a0bf3420b3bea31b0fc7946a"
integrity sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==
dependencies:
get-stream "^6.0.1"
minimist "^1.2.6"
"@mapbox/jsonlint-lines-primitives@^2.0.2", "@mapbox/jsonlint-lines-primitives@~2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==
"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==
"@mapbox/tiny-sdf@^2.0.6":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz#9a1d33e5018093e88f6a4df2343e886056287282"
integrity sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==
"@mapbox/unitbezier@^0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01"
integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==
"@mapbox/vector-tile@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666"
integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==
dependencies:
"@mapbox/point-geometry" "~0.1.0"
"@mapbox/whoots-js@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe"
integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
"@maplibre/maplibre-gl-leaflet@^0.0.22":
version "0.0.22"
resolved "https://registry.yarnpkg.com/@maplibre/maplibre-gl-leaflet/-/maplibre-gl-leaflet-0.0.22.tgz#04c4d5b65f44be0962330f8b5a7cafc8c3bd2676"
integrity sha512-9p4DSPLUE5t0StXH/IcZw37/UL7Ekea4jcVdkSsb2jWI+sM3K7mYHLOnti/2wn+HqxG4jMVUHah7Xun3bs00AQ==
"@maplibre/maplibre-gl-style-spec@^20.3.1":
version "20.4.0"
resolved "https://registry.yarnpkg.com/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.4.0.tgz#408339e051fb51e022b40af2235e0beb037937ea"
integrity sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==
dependencies:
"@mapbox/jsonlint-lines-primitives" "~2.0.2"
"@mapbox/unitbezier" "^0.0.1"
json-stringify-pretty-compact "^4.0.0"
minimist "^1.2.8"
quickselect "^2.0.0"
rw "^1.3.3"
tinyqueue "^3.0.0"
"@mat-datetimepicker/core@~14.0.0": "@mat-datetimepicker/core@~14.0.0":
version "14.0.0" version "14.0.0"
resolved "https://registry.yarnpkg.com/@mat-datetimepicker/core/-/core-14.0.0.tgz#1776ae74c3ff94b2bf4e1c6c01c9366c8ab876b5" resolved "https://registry.yarnpkg.com/@mat-datetimepicker/core/-/core-14.0.0.tgz#1776ae74c3ff94b2bf4e1c6c01c9366c8ab876b5"
@ -2656,6 +2714,13 @@
resolved "https://registry.yarnpkg.com/@types/flowjs/-/flowjs-2.13.14.tgz#62cdd8d5d8e0222e505e4a140e73cd385c0a496c" resolved "https://registry.yarnpkg.com/@types/flowjs/-/flowjs-2.13.14.tgz#62cdd8d5d8e0222e505e4a140e73cd385c0a496c"
integrity sha512-OlZFH9hbOq5B+GeBjcM3UvvSailseRT+sKoi9jyFFczvvS1n1LTiTKJysDSLVWnUvGD+tsn7kxb6eC2uaJD+Zw== integrity sha512-OlZFH9hbOq5B+GeBjcM3UvvSailseRT+sKoi9jyFFczvvS1n1LTiTKJysDSLVWnUvGD+tsn7kxb6eC2uaJD+Zw==
"@types/geojson-vt@3.2.5":
version "3.2.5"
resolved "https://registry.yarnpkg.com/@types/geojson-vt/-/geojson-vt-3.2.5.tgz#b6c356874991d9ab4207533476dfbcdb21e38408"
integrity sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==
dependencies:
"@types/geojson" "*"
"@types/geojson@*", "@types/geojson@^7946.0.10": "@types/geojson@*", "@types/geojson@^7946.0.10":
version "7946.0.14" version "7946.0.14"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613"
@ -2666,6 +2731,11 @@
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca"
integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==
"@types/geojson@^7946.0.14":
version "7946.0.16"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a"
integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==
"@types/hammerjs@^2.0.45": "@types/hammerjs@^2.0.45":
version "2.0.45" version "2.0.45"
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.45.tgz#ffa764bb68a66c08db6efb9c816eb7be850577b1" resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.45.tgz#ffa764bb68a66c08db6efb9c816eb7be850577b1"
@ -2745,6 +2815,20 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb"
integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
"@types/mapbox__point-geometry@*", "@types/mapbox__point-geometry@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz#0ef017b75eedce02ff6243b4189210e2e6d5e56d"
integrity sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==
"@types/mapbox__vector-tile@^1.3.4":
version "1.3.4"
resolved "https://registry.yarnpkg.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz#ad757441ef1d34628d9e098afd9c91423c1f8734"
integrity sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==
dependencies:
"@types/geojson" "*"
"@types/mapbox__point-geometry" "*"
"@types/pbf" "*"
"@types/mime@^1": "@types/mime@^1":
version "1.3.5" version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
@ -2783,6 +2867,11 @@
dependencies: dependencies:
undici-types "~6.19.2" undici-types "~6.19.2"
"@types/pbf@*", "@types/pbf@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.5.tgz#a9495a58d8c75be4ffe9a0bd749a307715c07404"
integrity sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==
"@types/qs@*": "@types/qs@*":
version "6.9.16" version "6.9.16"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794"
@ -2839,6 +2928,13 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/supercluster@^7.1.3":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@types/supercluster/-/supercluster-7.1.3.tgz#1a1bc2401b09174d9c9e44124931ec7874a72b27"
integrity sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==
dependencies:
"@types/geojson" "*"
"@types/systemjs@6.15.1": "@types/systemjs@6.15.1":
version "6.15.1" version "6.15.1"
resolved "https://registry.yarnpkg.com/@types/systemjs/-/systemjs-6.15.1.tgz#dae1ec2fbe66af7c6ca1a110e2c9ca6b85135eec" resolved "https://registry.yarnpkg.com/@types/systemjs/-/systemjs-6.15.1.tgz#dae1ec2fbe66af7c6ca1a110e2c9ca6b85135eec"
@ -4697,6 +4793,11 @@ domutils@^3.0.1:
domelementtype "^2.3.0" domelementtype "^2.3.0"
domhandler "^5.0.3" domhandler "^5.0.3"
earcut@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/earcut/-/earcut-3.0.1.tgz#f60b3f671c5657cca9d3e131c5527c5dde00ef38"
integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==
eastasianwidth@^0.2.0: eastasianwidth@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@ -5513,6 +5614,11 @@ geojson-rbush@3.x:
"@types/geojson" "7946.0.8" "@types/geojson" "7946.0.8"
rbush "^3.0.1" rbush "^3.0.1"
geojson-vt@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-4.0.2.tgz#1162f6c7d61a0ba305b1030621e6e111f847828a"
integrity sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==
get-caller-file@^2.0.1, get-caller-file@^2.0.5: get-caller-file@^2.0.1, get-caller-file@^2.0.5:
version "2.0.5" version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
@ -5534,7 +5640,7 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@
has-symbols "^1.0.3" has-symbols "^1.0.3"
hasown "^2.0.0" hasown "^2.0.0"
get-stream@^6.0.0: get-stream@^6.0.0, get-stream@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
@ -5548,6 +5654,11 @@ get-symbol-description@^1.0.2:
es-errors "^1.3.0" es-errors "^1.3.0"
get-intrinsic "^1.2.4" get-intrinsic "^1.2.4"
gl-matrix@^3.4.3:
version "3.4.3"
resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9"
integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==
glob-parent@^5.1.2, glob-parent@~5.1.2: glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@ -5591,6 +5702,15 @@ glob@^7.1.3:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
global-prefix@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-4.0.0.tgz#e9cc79aab9be1d03287e156a3f912dd0895463ed"
integrity sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==
dependencies:
ini "^4.1.3"
kind-of "^6.0.3"
which "^4.0.0"
globals@^11.1.0: globals@^11.1.0:
version "11.12.0" version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -5859,7 +5979,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0:
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
ieee754@^1.1.13: ieee754@^1.1.12, ieee754@^1.1.13:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@ -6388,6 +6508,11 @@ json-stable-stringify@^1.0.2:
jsonify "^0.0.1" jsonify "^0.0.1"
object-keys "^1.1.1" object-keys "^1.1.1"
json-stringify-pretty-compact@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz#cf4844770bddee3cb89a6170fe4b00eee5dbf1d4"
integrity sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==
json5@^1.0.2: json5@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
@ -6462,6 +6587,11 @@ katex@^0.16.0, katex@^0.16.9:
dependencies: dependencies:
commander "^8.3.0" commander "^8.3.0"
kdbush@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39"
integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==
keyv@^4.5.4: keyv@^4.5.4:
version "4.5.4" version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
@ -6474,7 +6604,7 @@ khroma@^2.1.0:
resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1" resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1"
integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==
kind-of@^6.0.2: kind-of@^6.0.2, kind-of@^6.0.3:
version "6.0.3" version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
@ -6803,6 +6933,38 @@ make-plural@^7.0.0:
resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-7.4.0.tgz#fa6990dd550dea4de6b20163f74e5ed83d8a8d6d" resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-7.4.0.tgz#fa6990dd550dea4de6b20163f74e5ed83d8a8d6d"
integrity sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg== integrity sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==
maplibre-gl@^4.7.1:
version "4.7.1"
resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-4.7.1.tgz#06a524438ee2aafbe8bcd91002a4e01468ea5486"
integrity sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==
dependencies:
"@mapbox/geojson-rewind" "^0.5.2"
"@mapbox/jsonlint-lines-primitives" "^2.0.2"
"@mapbox/point-geometry" "^0.1.0"
"@mapbox/tiny-sdf" "^2.0.6"
"@mapbox/unitbezier" "^0.0.1"
"@mapbox/vector-tile" "^1.3.1"
"@mapbox/whoots-js" "^3.1.0"
"@maplibre/maplibre-gl-style-spec" "^20.3.1"
"@types/geojson" "^7946.0.14"
"@types/geojson-vt" "3.2.5"
"@types/mapbox__point-geometry" "^0.1.4"
"@types/mapbox__vector-tile" "^1.3.4"
"@types/pbf" "^3.0.5"
"@types/supercluster" "^7.1.3"
earcut "^3.0.0"
geojson-vt "^4.0.2"
gl-matrix "^3.4.3"
global-prefix "^4.0.0"
kdbush "^4.0.2"
murmurhash-js "^1.0.0"
pbf "^3.3.0"
potpack "^2.0.0"
quickselect "^3.0.0"
supercluster "^8.0.1"
tinyqueue "^3.0.0"
vt-pbf "^3.1.3"
marked@^13.0.2: marked@^13.0.2:
version "13.0.3" version "13.0.3"
resolved "https://registry.yarnpkg.com/marked/-/marked-13.0.3.tgz#5c5b4a5d0198060c7c9bc6ef9420a7fed30f822d" resolved "https://registry.yarnpkg.com/marked/-/marked-13.0.3.tgz#5c5b4a5d0198060c7c9bc6ef9420a7fed30f822d"
@ -6947,7 +7109,7 @@ minimatch@^9.0.0, minimatch@^9.0.4:
dependencies: dependencies:
brace-expansion "^2.0.1" brace-expansion "^2.0.1"
minimist@1.2.8, minimist@^1.2.0, minimist@^1.2.6: minimist@1.2.8, minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8:
version "1.2.8" version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@ -7097,6 +7259,11 @@ multicast-dns@^7.2.5:
dns-packet "^5.2.2" dns-packet "^5.2.2"
thunky "^1.0.2" thunky "^1.0.2"
murmurhash-js@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
integrity sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==
mute-stream@^1.0.0: mute-stream@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e"
@ -7778,6 +7945,14 @@ pathe@^1.1.2:
resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
pbf@^3.2.1, pbf@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.3.0.tgz#1790f3d99118333cc7f498de816028a346ef367f"
integrity sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==
dependencies:
ieee754 "^1.1.12"
resolve-protobuf-schema "^2.1.0"
picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1: picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
@ -7971,6 +8146,11 @@ postinstall-prepare@^2.0.0:
resolved "https://registry.yarnpkg.com/postinstall-prepare/-/postinstall-prepare-2.0.0.tgz#2a6867c1a13a05502aa115d0495efbbd778769cb" resolved "https://registry.yarnpkg.com/postinstall-prepare/-/postinstall-prepare-2.0.0.tgz#2a6867c1a13a05502aa115d0495efbbd778769cb"
integrity sha512-lLFwEKdnGLAaRAm8OpXP6HwrXRW+b8Hh9vRhVHZKmCdobd+D21YM38BCDsi3zrePLSe8Tt0H/mbYkh7/ySQQMg== integrity sha512-lLFwEKdnGLAaRAm8OpXP6HwrXRW+b8Hh9vRhVHZKmCdobd+D21YM38BCDsi3zrePLSe8Tt0H/mbYkh7/ySQQMg==
potpack@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/potpack/-/potpack-2.0.0.tgz#61f4dd2dc4b3d5e996e3698c0ec9426d0e169104"
integrity sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==
prelude-ls@^1.2.1: prelude-ls@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -8009,6 +8189,11 @@ proto-list@~1.2.1:
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
protocol-buffers-schema@^3.3.1:
version "3.6.0"
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03"
integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
proxy-addr@~2.0.7: proxy-addr@~2.0.7:
version "2.0.7" version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
@ -8053,6 +8238,11 @@ quickselect@^2.0.0:
resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018"
integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==
quickselect@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-3.0.0.tgz#a37fc953867d56f095a20ac71c6d27063d2de603"
integrity sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==
randombytes@^2.1.0: randombytes@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -8228,6 +8418,13 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-protobuf-schema@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758"
integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
dependencies:
protocol-buffers-schema "^3.3.1"
resolve-url-loader@5.0.0: resolve-url-loader@5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795"
@ -8350,7 +8547,7 @@ run-parallel@^1.1.9:
dependencies: dependencies:
queue-microtask "^1.2.2" queue-microtask "^1.2.2"
rw@1: rw@1, rw@^1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
@ -8957,6 +9154,13 @@ sucrase@^3.35.0:
pirates "^4.0.1" pirates "^4.0.1"
ts-interface-checker "^0.1.9" ts-interface-checker "^0.1.9"
supercluster@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-8.0.1.tgz#9946ba123538e9e9ab15de472531f604e7372df5"
integrity sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==
dependencies:
kdbush "^4.0.2"
supports-color@^5.3.0: supports-color@^5.3.0:
version "5.5.0" version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@ -9138,6 +9342,11 @@ tinymce@6.8.5, "tinymce@^7.0.0 || ^6.0.0 || ^5.5.0", tinymce@~6.8.5:
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.8.5.tgz#aa9a711c4e0b59d506dd281bade857d35a7b3c59" resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.8.5.tgz#aa9a711c4e0b59d506dd281bade857d35a7b3c59"
integrity sha512-qAL/FxL7cwZHj4BfaF818zeJJizK9jU5IQzTcSLL4Rj5MaJdiVblEj7aDr80VCV1w9h4Lak9hlnALhq/kVtN1g== integrity sha512-qAL/FxL7cwZHj4BfaF818zeJJizK9jU5IQzTcSLL4Rj5MaJdiVblEj7aDr80VCV1w9h4Lak9hlnALhq/kVtN1g==
tinyqueue@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-3.0.0.tgz#101ea761ccc81f979e29200929e78f1556e3661e"
integrity sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==
tmp@^0.0.33: tmp@^0.0.33:
version "0.0.33" version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -9530,6 +9739,15 @@ vscode-uri@~3.0.8:
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
vt-pbf@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac"
integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==
dependencies:
"@mapbox/point-geometry" "0.1.0"
"@mapbox/vector-tile" "^1.3.1"
pbf "^3.2.1"
watchpack@2.4.1: watchpack@2.4.1:
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff"

Loading…
Cancel
Save