From 3fea0f88f36d5e2d14376281d6b877d32d39a06e Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 14:03:48 +0100 Subject: [PATCH 01/91] moved queueName from rule-node config to rule-node --- .../main/data/upgrade/3.6.2/schema_update.sql | 19 +++++++ .../actors/ruleChain/DefaultTbContext.java | 4 +- .../install/ThingsboardInstallService.java | 5 ++ .../AnnotationComponentDiscoveryService.java | 1 + .../install/SqlDatabaseUpgradeService.java | 3 ++ .../update/DefaultDataUpdateService.java | 49 +++++++++++++++++++ .../impl/RuleChainImportService.java | 21 +++++++- .../data/plugin/ComponentDescriptor.java | 7 +++ .../server/common/data/rule/RuleNode.java | 6 ++- .../server/dao/model/ModelConstants.java | 2 + .../model/sql/ComponentDescriptorEntity.java | 5 ++ .../server/dao/model/sql/RuleNodeEntity.java | 5 ++ ...ctComponentDescriptorInsertRepository.java | 3 +- ...qlComponentDescriptorInsertRepository.java | 4 +- .../main/resources/sql/schema-entities.sql | 4 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 + .../rule/engine/debug/TbMsgGeneratorNode.java | 9 ++-- .../TbMsgGeneratorNodeConfiguration.java | 1 - .../deduplication/TbMsgDeduplicationNode.java | 5 +- .../TbMsgDeduplicationNodeConfiguration.java | 1 - .../rule/engine/flow/TbCheckpointNode.java | 9 ++-- .../flow/TbCheckpointNodeConfiguration.java | 30 ------------ .../transform/TbMsgDeduplicationNodeTest.java | 17 +++++-- 23 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update.sql delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeConfiguration.java diff --git a/application/src/main/data/upgrade/3.6.2/schema_update.sql b/application/src/main/data/upgrade/3.6.2/schema_update.sql new file mode 100644 index 0000000000..903137be79 --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update.sql @@ -0,0 +1,19 @@ +-- +-- Copyright © 2016-2023 The Thingsboard Authors +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS queue_name varchar(255); + +ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS has_queue_name boolean DEFAULT false; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index 28963b383a..bf61cf7a59 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -185,7 +185,7 @@ class DefaultTbContext implements TbContext { @Override public void enqueue(TbMsg tbMsg, Runnable onSuccess, Consumer onFailure) { - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), tbMsg.getOriginator()); enqueue(tpi, tbMsg, onFailure, onSuccess); } @@ -310,7 +310,7 @@ class DefaultTbContext implements TbContext { @Override public boolean isLocalEntity(EntityId entityId) { - return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition(); + return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), entityId).isMyPartition(); } private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) { diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 3fc68b9cc3..1be7fdecc4 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -277,6 +277,11 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } + break; + case "3.6.2": + log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); + dataUpdateService.updateData("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index d5f150ce24..571d37f05b 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -189,6 +189,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe scannedComponent.setName(ruleNodeAnnotation.name()); scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); + scannedComponent.setHasQueueName(ruleNodeAnnotation.hasQueueName()); NodeDefinition nodeDefinition = prepareNodeDefinition(clazz, ruleNodeAnnotation); ObjectNode configurationDescriptor = JacksonUtil.newObjectNode(); JsonNode node = JacksonUtil.valueToTree(nodeDefinition); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index c2444390f6..4a96d0d2c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -772,6 +772,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } }); break; + case "3.6.2": + updateSchema("3.6.2", 3006002, "3.6.3", 3006003, null); + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 7d08fdca00..c57d38b66d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -227,11 +227,25 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.6.0 to 3.6.1 ..."); migrateDeviceConnectivity(); break; + case "3.6.2": + updateRuleNodesQueueName(); + break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } + private void updateRuleNodesQueueName() { + String[] ruleNodeTypes = { + "org.thingsboard.rule.engine.debug.TbMsgGeneratorNode", + "org.thingsboard.rule.engine.flow.TbCheckpointNode", + "org.thingsboard.rule.engine.deduplication.TbMsgDeduplicationNode" + }; + for (String ruleNodeType : ruleNodeTypes) { + ruleNodeQueueNameUpdater.updateEntities(ruleNodeType); + } + } + private void migrateEdgeEvents(String logPrefix) { boolean skipEdgeEventsMigration = getEnv("TB_SKIP_EDGE_EVENTS_MIGRATION", false); if (!skipEdgeEventsMigration) { @@ -792,4 +806,39 @@ public class DefaultDataUpdateService implements DataUpdateService { } } + private final PaginatedUpdater ruleNodeQueueNameUpdater = + new PaginatedUpdater<>() { + + @Override + protected String getName() { + return "RuleNode queue name updater"; + } + + @Override + protected boolean forceReportTotal() { + return true; + } + + @Override + protected PageData findEntities(String type, PageLink pageLink) { + return ruleChainService.findAllRuleNodesByType(type, pageLink); + } + + @Override + protected void updateEntity(RuleNode ruleNode) { + try { + ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); + JsonNode queueName = configuration.remove("queueName"); + if (queueName != null) { + if (!queueName.isNull()) { + ruleNode.setQueueName(queueName.asText()); + } + ruleChainService.saveRuleNode(null, ruleNode); + } + } catch (Exception e) { + log.error("Unable to update RuleNode", e); + } + } + }; + } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java index d2673595ff..f3a01913a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java @@ -15,13 +15,14 @@ */ package org.thingsboard.server.service.sync.ie.importing.impl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; @@ -84,12 +85,14 @@ public class RuleChainImportService extends BaseEntityImportService { node.setRuleChainId(null); node.setExternalId(node.getId()); node.setId(null); + setQueueName(node); }); } @@ -105,6 +108,22 @@ public class RuleChainImportService extends BaseEntityImportService clazz = Class.forName(ruleNode.getType()); + org.thingsboard.rule.engine.api.RuleNode ruleNodeAnnotation = clazz.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); + if (ruleNodeAnnotation.hasQueueName()) { + ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); + JsonNode queueName = configuration.remove("queueName"); + if (queueName != null && !queueName.isNull()) { + ruleNode.setQueueName(queueName.asText()); + } + } + } catch (ClassNotFoundException e) { + log.warn("[{}] RuleNode class not found [{}]", ruleNode.getName(), ruleNode.getType()); + } + } + @Override protected RuleChain saveOrUpdate(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) { ruleChain = ruleChainService.saveRuleChain(ruleChain); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index aab0a8f858..0e9b31ec09 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -55,6 +55,8 @@ public class ComponentDescriptor extends BaseData { @Length(fieldName = "actions") @ApiModelProperty(position = 10, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; + @ApiModelProperty(position = 11, value = "Indicates that the RuleNode is support queue name.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") + @Getter @Setter private boolean hasQueueName; public ComponentDescriptor() { super(); @@ -74,6 +76,7 @@ public class ComponentDescriptor extends BaseData { this.configurationDescriptor = plugin.getConfigurationDescriptor(); this.configurationVersion = plugin.getConfigurationVersion(); this.actions = plugin.getActions(); + this.hasQueueName = plugin.isHasQueueName(); } @ApiModelProperty(position = 1, value = "JSON object with the descriptor Id. " + @@ -104,6 +107,8 @@ public class ComponentDescriptor extends BaseData { if (!Objects.equals(actions, that.actions)) return false; if (!Objects.equals(configurationDescriptor, that.configurationDescriptor)) return false; if (configurationVersion != that.configurationVersion) return false; + if (clusteringMode != that.clusteringMode) return false; + if (hasQueueName != that.isHasQueueName()) return false; return Objects.equals(clazz, that.clazz); } @@ -115,6 +120,8 @@ public class ComponentDescriptor extends BaseData { result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (clazz != null ? clazz.hashCode() : 0); result = 31 * result + (actions != null ? actions.hashCode() : 0); + result = 31 * result + (clusteringMode != null ? clusteringMode.hashCode() : 0); + result = 31 * result + (hasQueueName ? 1 : 0); return result; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index 3fc1ceb628..3123ab1577 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -50,9 +50,11 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements private boolean debugMode; @ApiModelProperty(position = 7, value = "Enable/disable singleton mode. ", example = "false") private boolean singletonMode; - @ApiModelProperty(position = 8, value = "Version of rule node configuration. ", example = "0") + @ApiModelProperty(position = 8, value = "Queue name. ", example = "Main") + private String queueName; + @ApiModelProperty(position = 9, value = "Version of rule node configuration. ", example = "0") private int configurationVersion; - @ApiModelProperty(position = 9, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @ApiModelProperty(position = 10, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") private transient JsonNode configuration; @JsonIgnore private byte[] configurationBytes; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 21cea59ee3..2a9672de76 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -354,6 +354,7 @@ public class ModelConstants { public static final String COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY = "configuration_descriptor"; public static final String COMPONENT_DESCRIPTOR_CONFIGURATION_VERSION_PROPERTY = "configuration_version"; public static final String COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY = "actions"; + public static final String COMPONENT_DESCRIPTOR_HAS_QUEUE_NAME_PROPERTY = "has_queue_name"; /** * Event constants. @@ -389,6 +390,7 @@ public class ModelConstants { public static final String DEBUG_MODE = "debug_mode"; public static final String SINGLETON_MODE = "singleton_mode"; + public static final String QUEUE_NAME = "queue_name"; /** * Rule chain constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java index a476d69c97..c4fa05ef03 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java @@ -70,6 +70,9 @@ public class ComponentDescriptorEntity extends BaseSqlEntity { @Column(name = ModelConstants.SINGLETON_MODE) private boolean singletonMode; + @Column(name = ModelConstants.QUEUE_NAME) + private String queueName; + @Column(name = ModelConstants.EXTERNAL_ID_PROPERTY) private UUID externalId; @@ -84,6 +87,7 @@ public class RuleNodeEntity extends BaseSqlEntity { this.name = ruleNode.getName(); this.debugMode = ruleNode.isDebugMode(); this.singletonMode = ruleNode.isSingletonMode(); + this.queueName = ruleNode.getQueueName(); this.configurationVersion = ruleNode.getConfigurationVersion(); this.configuration = ruleNode.getConfiguration(); this.additionalInfo = ruleNode.getAdditionalInfo(); @@ -103,6 +107,7 @@ public class RuleNodeEntity extends BaseSqlEntity { ruleNode.setName(name); ruleNode.setDebugMode(debugMode); ruleNode.setSingletonMode(singletonMode); + ruleNode.setQueueName(queueName); ruleNode.setConfigurationVersion(configurationVersion); ruleNode.setConfiguration(configuration); ruleNode.setAdditionalInfo(additionalInfo); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java index ad8a07be08..0c2587dd5b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java @@ -77,7 +77,8 @@ public abstract class AbstractComponentDescriptorInsertRepository implements Com .setParameter("name", entity.getName()) .setParameter("scope", entity.getScope().name()) .setParameter("type", entity.getType().name()) - .setParameter("clustering_mode", entity.getClusteringMode().name()); + .setParameter("clustering_mode", entity.getClusteringMode().name()) + .setParameter("has_queue_name", entity.isHasQueueName()); } private ComponentDescriptorEntity processSaveOrUpdate(ComponentDescriptorEntity entity, String query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java index c462f263f1..5a3038ab0e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java @@ -44,10 +44,10 @@ public class SqlComponentDescriptorInsertRepository extends AbstractComponentDes } private static String getInsertOrUpdateStatement(String conflictKeyStatement, String updateKeyStatement) { - return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, configuration_version, name, scope, type, clustering_mode) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :configuration_version, :name, :scope, :type, :clustering_mode) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; + return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, configuration_version, name, scope, type, clustering_mode, has_queue_name) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :configuration_version, :name, :scope, :type, :clustering_mode, :has_queue_name) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; } private static String getUpdateStatement(String id) { - return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, configuration_version = :configuration_version, name = :name, scope = :scope, type = :type, clustering_mode = :clustering_mode"; + return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, configuration_version = :configuration_version, name = :name, scope = :scope, type = :type, clustering_mode = :clustering_mode, has_queue_name = :has_queue_name"; } } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 35d1d49cda..402e0d23b5 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -126,7 +126,8 @@ CREATE TABLE IF NOT EXISTS component_descriptor ( name varchar(255), scope varchar(255), type varchar(255), - clustering_mode varchar(255) + clustering_mode varchar(255), + has_queue_name boolean DEFAULT false ); CREATE TABLE IF NOT EXISTS customer ( @@ -187,6 +188,7 @@ CREATE TABLE IF NOT EXISTS rule_node ( name varchar(255), debug_mode boolean, singleton_mode boolean, + queue_name varchar(255), external_id uuid ); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java index 7037f2f3fe..65fe9457ca 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java @@ -42,6 +42,8 @@ public @interface RuleNode { ComponentClusteringMode clusteringMode() default ComponentClusteringMode.ENABLED; + boolean hasQueueName() default false; + boolean inEnabled() default true; boolean outEnabled() default true; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index b31c98bc0f..0b60f38981 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -50,6 +50,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; type = ComponentType.ACTION, name = "generator", configClazz = TbMsgGeneratorNodeConfiguration.class, + hasQueueName = true, nodeDescription = "Periodically generates messages", nodeDetails = "Generates messages with configurable period. Javascript function used for message generation.", inEnabled = false, @@ -69,6 +70,7 @@ public class TbMsgGeneratorNode implements TbNode { private UUID nextTickId; private TbMsg prevMsg; private final AtomicBoolean initialized = new AtomicBoolean(false); + private String queueName; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { @@ -76,6 +78,7 @@ public class TbMsgGeneratorNode implements TbNode { this.config = TbNodeUtils.convert(configuration, TbMsgGeneratorNodeConfiguration.class); this.delay = TimeUnit.SECONDS.toMillis(config.getPeriodInSeconds()); this.currentMsgCount = 0; + this.queueName = ctx.getSelf().getQueueName(); if (!StringUtils.isEmpty(config.getOriginatorId())) { originatorId = EntityIdFactory.getByTypeAndUuid(config.getOriginatorType(), config.getOriginatorId()); ctx.checkTenantEntity(originatorId); @@ -137,7 +140,7 @@ public class TbMsgGeneratorNode implements TbNode { } lastScheduledTs = lastScheduledTs + delay; long curDelay = Math.max(0L, (lastScheduledTs - curTs)); - TbMsg tickMsg = ctx.newMsg(config.getQueueName(), TbMsgType.GENERATOR_NODE_SELF_MSG, ctx.getSelfId(), + TbMsg tickMsg = ctx.newMsg(queueName, TbMsgType.GENERATOR_NODE_SELF_MSG, ctx.getSelfId(), getCustomerIdFromMsg(msg), TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); nextTickId = tickMsg.getId(); ctx.tellSelf(tickMsg, curDelay); @@ -146,14 +149,14 @@ public class TbMsgGeneratorNode implements TbNode { private ListenableFuture generate(TbContext ctx, TbMsg msg) { log.trace("generate, config {}", config); if (prevMsg == null) { - prevMsg = ctx.newMsg(config.getQueueName(), TbMsg.EMPTY_STRING, originatorId, msg.getCustomerId(), TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); + prevMsg = ctx.newMsg(queueName, TbMsg.EMPTY_STRING, originatorId, msg.getCustomerId(), TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); } if (initialized.get()) { ctx.logJsEvalRequest(); return Futures.transformAsync(scriptEngine.executeGenerateAsync(prevMsg), generated -> { log.trace("generate process response, generated {}, config {}", generated, config); ctx.logJsEvalResponse(); - prevMsg = ctx.newMsg(config.getQueueName(), generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData()); + prevMsg = ctx.newMsg(queueName, generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData()); return Futures.immediateFuture(prevMsg); }, MoreExecutors.directExecutor()); //usually it runs on js-executor-remote-callback thread pool } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java index 5f12603832..027f4aa708 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java @@ -36,7 +36,6 @@ public class TbMsgGeneratorNodeConfiguration implements NodeConfiguration deduplicationMap; private long deduplicationInterval; + private String queueName; public TbMsgDeduplicationNode() { this.deduplicationMap = new HashMap<>(); @@ -75,6 +77,7 @@ public class TbMsgDeduplicationNode implements TbNode { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeduplicationNodeConfiguration.class); this.deduplicationInterval = TimeUnit.SECONDS.toMillis(config.getInterval()); + this.queueName = ctx.getSelf().getQueueName(); } @Override @@ -132,7 +135,7 @@ public class TbMsgDeduplicationNode implements TbNode { } } deduplicationResults.add(TbMsg.newMsg( - config.getQueueName(), + queueName, config.getOutMsgType(), deduplicationId, getMetadata(), diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java index 9560247033..08e81d8a6e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java @@ -26,7 +26,6 @@ public class TbMsgDeduplicationNodeConfiguration implements NodeConfiguration { - - private String queueName; - - @Override - public TbCheckpointNodeConfiguration defaultConfiguration() { - return new TbCheckpointNodeConfiguration(); - } -} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index be6aea6fa5..4e3ae2a015 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; +import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -241,7 +242,7 @@ public class TbMsgDeduplicationNodeTest { config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - config.setQueueName(DataConstants.HP_QUEUE_NAME); + setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -268,7 +269,7 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(getMergedData(inputMsgs), outMessage.getData()); Assertions.assertEquals(deviceId, outMessage.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), outMessage.getType()); - Assertions.assertEquals(config.getQueueName(), outMessage.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, outMessage.getQueueName()); } @Test @@ -281,7 +282,7 @@ public class TbMsgDeduplicationNodeTest { config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - config.setQueueName(DataConstants.HP_QUEUE_NAME); + setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -316,13 +317,13 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(getMergedData(firstMsgPack), firstMsg.getData()); Assertions.assertEquals(deviceId, firstMsg.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), firstMsg.getType()); - Assertions.assertEquals(config.getQueueName(), firstMsg.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, firstMsg.getQueueName()); TbMsg secondMsg = resultMsgs.get(1); Assertions.assertEquals(getMergedData(secondMsgPack), secondMsg.getData()); Assertions.assertEquals(deviceId, secondMsg.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), secondMsg.getType()); - Assertions.assertEquals(config.getQueueName(), secondMsg.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, secondMsg.getQueueName()); } @Test @@ -429,4 +430,10 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } + private void setQueueName(String queueName) { + RuleNode ruleNode = new RuleNode(); + ruleNode.setQueueName(queueName); + when(ctx.getSelf()).thenReturn(ruleNode); + } + } From b65391e6ac5fc1cb3ec861feb371db1d3041ca02 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 16:47:19 +0100 Subject: [PATCH 02/91] fixed TbMsgDeduplicationNodeTest --- .../rule/engine/transform/TbMsgDeduplicationNodeTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index 4e3ae2a015..ac3f2acfd5 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -94,6 +94,7 @@ public class TbMsgDeduplicationNodeTest { when(ctx.getSelfId()).thenReturn(ruleNodeId); when(ctx.getTenantId()).thenReturn(tenantId); + when(ctx.getSelf()).thenReturn(new RuleNode()); doAnswer((Answer) invocationOnMock -> { TbMsgType type = (TbMsgType) (invocationOnMock.getArguments())[1]; From e8dc2ddc2d388936a7d7d1b4351b793c74b5eeb7 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 20:47:25 +0100 Subject: [PATCH 03/91] used TbNodeUpgradeUtils instead of rule-node upgrade --- .../install/ThingsboardInstallService.java | 1 - .../update/DefaultDataUpdateService.java | 49 ------------------- .../impl/RuleChainImportService.java | 20 -------- .../server/utils/TbNodeUpgradeUtils.java | 6 +++ .../rule/engine/api/util/TbNodeUtils.java | 1 + .../rule/engine/debug/TbMsgGeneratorNode.java | 21 ++++++++ .../deduplication/TbMsgDeduplicationNode.java | 20 ++++++++ .../rule/engine/flow/TbCheckpointNode.java | 22 +++++++++ 8 files changed, 70 insertions(+), 70 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 1be7fdecc4..054c7a6751 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -281,7 +281,6 @@ public class ThingsboardInstallService { case "3.6.2": log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); - dataUpdateService.updateData("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index c57d38b66d..7d08fdca00 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -227,25 +227,11 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.6.0 to 3.6.1 ..."); migrateDeviceConnectivity(); break; - case "3.6.2": - updateRuleNodesQueueName(); - break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } - private void updateRuleNodesQueueName() { - String[] ruleNodeTypes = { - "org.thingsboard.rule.engine.debug.TbMsgGeneratorNode", - "org.thingsboard.rule.engine.flow.TbCheckpointNode", - "org.thingsboard.rule.engine.deduplication.TbMsgDeduplicationNode" - }; - for (String ruleNodeType : ruleNodeTypes) { - ruleNodeQueueNameUpdater.updateEntities(ruleNodeType); - } - } - private void migrateEdgeEvents(String logPrefix) { boolean skipEdgeEventsMigration = getEnv("TB_SKIP_EDGE_EVENTS_MIGRATION", false); if (!skipEdgeEventsMigration) { @@ -806,39 +792,4 @@ public class DefaultDataUpdateService implements DataUpdateService { } } - private final PaginatedUpdater ruleNodeQueueNameUpdater = - new PaginatedUpdater<>() { - - @Override - protected String getName() { - return "RuleNode queue name updater"; - } - - @Override - protected boolean forceReportTotal() { - return true; - } - - @Override - protected PageData findEntities(String type, PageLink pageLink) { - return ruleChainService.findAllRuleNodesByType(type, pageLink); - } - - @Override - protected void updateEntity(RuleNode ruleNode) { - try { - ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); - JsonNode queueName = configuration.remove("queueName"); - if (queueName != null) { - if (!queueName.isNull()) { - ruleNode.setQueueName(queueName.asText()); - } - ruleChainService.saveRuleNode(null, ruleNode); - } - } catch (Exception e) { - log.error("Unable to update RuleNode", e); - } - } - }; - } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java index f3a01913a2..bb930f9634 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.service.sync.ie.importing.impl; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -85,14 +83,12 @@ public class RuleChainImportService extends BaseEntityImportService { node.setRuleChainId(null); node.setExternalId(node.getId()); node.setId(null); - setQueueName(node); }); } @@ -108,22 +104,6 @@ public class RuleChainImportService extends BaseEntityImportService clazz = Class.forName(ruleNode.getType()); - org.thingsboard.rule.engine.api.RuleNode ruleNodeAnnotation = clazz.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); - if (ruleNodeAnnotation.hasQueueName()) { - ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); - JsonNode queueName = configuration.remove("queueName"); - if (queueName != null && !queueName.isNull()) { - ruleNode.setQueueName(queueName.asText()); - } - } - } catch (ClassNotFoundException e) { - log.warn("[{}] RuleNode class not found [{}]", ruleNode.getName(), ruleNode.getType()); - } - } - @Override protected RuleChain saveOrUpdate(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) { ruleChain = ruleChainService.saveRuleChain(ruleChain); diff --git a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java index 530679683d..23c75b430b 100644 --- a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java +++ b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java @@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.service.component.RuleNodeClassInfo; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @Slf4j public class TbNodeUpgradeUtils { @@ -44,9 +46,13 @@ public class TbNodeUpgradeUtils { } else { var tbVersionedNode = getTbVersionedNode(nodeInfo); try { + JsonNode queueName = oldConfiguration.get(QUEUE_NAME); TbPair upgradeResult = tbVersionedNode.upgrade(configurationVersion, oldConfiguration); if (upgradeResult.getFirst()) { node.setConfiguration(upgradeResult.getSecond()); + if (nodeInfo.getAnnotation().hasQueueName() && queueName != null && queueName.isTextual()) { + node.setQueueName(queueName.asText()); + } } } catch (Exception e) { try { diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java index 396d810b00..cce5649336 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; */ public class TbNodeUtils { + public static final String QUEUE_NAME = "queueName"; private static final Pattern DATA_PATTERN = Pattern.compile("(\\$\\[)(.*?)(])"); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index 0b60f38981..80170a28f1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -15,6 +15,8 @@ */ package org.thingsboard.rule.engine.debug; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; @@ -35,6 +37,7 @@ import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.script.ScriptLanguage; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; @@ -44,12 +47,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.thingsboard.common.util.DonAsynchron.withCallback; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; @Slf4j @RuleNode( type = ComponentType.ACTION, name = "generator", configClazz = TbMsgGeneratorNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "Periodically generates messages", nodeDetails = "Generates messages with configurable period. Javascript function used for message generation.", @@ -177,4 +182,20 @@ public class TbMsgGeneratorNode implements TbNode { scriptEngine = null; } } + + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index a7a8b44b21..8f818583e8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.deduplication; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; @@ -43,10 +44,13 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @RuleNode( type = ComponentType.TRANSFORMATION, name = "deduplication", configClazz = TbMsgDeduplicationNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "Deduplicate messages within the same originator entity for a configurable period " + "based on a specified deduplication strategy.", @@ -94,6 +98,22 @@ public class TbMsgDeduplicationNode implements TbNode { deduplicationMap.clear(); } + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } + private void processOnRegularMsg(TbContext ctx, TbMsg msg) { EntityId id = msg.getOriginator(); DeduplicationData deduplicationMsgs = deduplicationMap.computeIfAbsent(id, k -> new DeduplicationData()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index eb658ada68..8fe2de58b2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -15,6 +15,8 @@ */ package org.thingsboard.rule.engine.flow; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; @@ -25,13 +27,17 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @Slf4j @RuleNode( type = ComponentType.FLOW, name = "checkpoint", configClazz = EmptyNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "transfers the message to another queue", nodeDetails = "After successful transfer incoming message is automatically acknowledged. Queue name is configurable.", @@ -52,4 +58,20 @@ public class TbCheckpointNode implements TbNode { ctx.enqueueForTellNext(msg, queueName, TbNodeConnectionType.SUCCESS, () -> ctx.ack(msg), error -> ctx.tellFailure(msg, error)); } + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } + } From 1e2c7f95791f4340e1156608634b19f7089f94a9 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 13 Dec 2023 10:35:13 +0100 Subject: [PATCH 04/91] refactoring --- .../server/actors/ruleChain/DefaultTbContext.java | 9 +++++++-- .../org/thingsboard/rule/engine/api/TbContext.java | 2 ++ .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../engine/deduplication/TbMsgDeduplicationNode.java | 2 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../engine/transform/TbMsgDeduplicationNodeTest.java | 11 ++--------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index bf61cf7a59..0d1a65d899 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -185,7 +185,7 @@ class DefaultTbContext implements TbContext { @Override public void enqueue(TbMsg tbMsg, Runnable onSuccess, Consumer onFailure) { - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), tbMsg.getOriginator()); + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), tbMsg.getOriginator()); enqueue(tpi, tbMsg, onFailure, onSuccess); } @@ -310,7 +310,7 @@ class DefaultTbContext implements TbContext { @Override public boolean isLocalEntity(EntityId entityId) { - return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), entityId).isMyPartition(); + return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), entityId).isMyPartition(); } private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) { @@ -509,6 +509,11 @@ class DefaultTbContext implements TbContext { return ruleChainName; } + @Override + public String getQueueName() { + return getSelf().getQueueName(); + } + @Override public TenantId getTenantId() { return nodeCtx.getTenantId(); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java index 40ed2c378a..241e20115f 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java @@ -255,6 +255,8 @@ public interface TbContext { String getRuleChainName(); + String getQueueName(); + TenantId getTenantId(); AttributesService getAttributesService(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index 80170a28f1..cec7aca0a3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -83,7 +83,7 @@ public class TbMsgGeneratorNode implements TbNode { this.config = TbNodeUtils.convert(configuration, TbMsgGeneratorNodeConfiguration.class); this.delay = TimeUnit.SECONDS.toMillis(config.getPeriodInSeconds()); this.currentMsgCount = 0; - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); if (!StringUtils.isEmpty(config.getOriginatorId())) { originatorId = EntityIdFactory.getByTypeAndUuid(config.getOriginatorType(), config.getOriginatorId()); ctx.checkTenantEntity(originatorId); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index 8f818583e8..17b72cd27a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -81,7 +81,7 @@ public class TbMsgDeduplicationNode implements TbNode { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeduplicationNodeConfiguration.class); this.deduplicationInterval = TimeUnit.SECONDS.toMillis(config.getInterval()); - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index 8fe2de58b2..9616d8a167 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -50,7 +50,7 @@ public class TbCheckpointNode implements TbNode { @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); } @Override diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index ac3f2acfd5..8e8340c713 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -94,7 +94,6 @@ public class TbMsgDeduplicationNodeTest { when(ctx.getSelfId()).thenReturn(ruleNodeId); when(ctx.getTenantId()).thenReturn(tenantId); - when(ctx.getSelf()).thenReturn(new RuleNode()); doAnswer((Answer) invocationOnMock -> { TbMsgType type = (TbMsgType) (invocationOnMock.getArguments())[1]; @@ -240,10 +239,10 @@ public class TbMsgDeduplicationNodeTest { awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation); + when(ctx.getQueueName()).thenReturn(DataConstants.HP_QUEUE_NAME); config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -280,10 +279,10 @@ public class TbMsgDeduplicationNodeTest { awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation, true, 3); + when(ctx.getQueueName()).thenReturn(DataConstants.HP_QUEUE_NAME); config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -431,10 +430,4 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } - private void setQueueName(String queueName) { - RuleNode ruleNode = new RuleNode(); - ruleNode.setQueueName(queueName); - when(ctx.getSelf()).thenReturn(ruleNode); - } - } From 65a8b0a34c4972793f1c41f32761853d640fd871 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 13 Dec 2023 23:13:05 +0100 Subject: [PATCH 05/91] added test for singleton mqtt node --- .../server/msa/ContainerTestSuite.java | 2 + .../server/msa/TestProperties.java | 9 + .../server/msa/TestRestClient.java | 41 ++++ .../server/msa/rule/node/MqttNodeTest.java | 204 ++++++++++++++++++ .../resources/MqttRuleNodeTestMetadata.json | 79 +++++++ .../resources/docker-compose.mosquitto.yml | 25 +++ .../test/resources/mosquitto/mosquitto.conf | 18 ++ 7 files changed, 378 insertions(+) create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java create mode 100644 msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json create mode 100644 msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml create mode 100644 msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index dd3948c495..142b42e5b2 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -107,6 +107,7 @@ public class ContainerTestSuite { List composeFiles = new ArrayList<>(Arrays.asList( new File(targetDir + "docker-compose.yml"), new File(targetDir + "docker-compose.volumes.yml"), + new File(targetDir + "docker-compose.mosquitto.yml"), new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid.yml" : "docker-compose.postgres.yml")), new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid-test-extras.yml" : "docker-compose.postgres-test-extras.yml")), new File(targetDir + "docker-compose.postgres.volumes.yml"), @@ -162,6 +163,7 @@ public class ContainerTestSuite { .withEnv(queueEnv) .withEnv("LOAD_BALANCER_NAME", "") .withExposedService("haproxy", 80, Wait.forHttp("/swagger-ui.html").withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) + .withExposedService("broker", 1883) .waitingFor("tb-core1", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) .waitingFor("tb-core2", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) .waitingFor("tb-http-transport1", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java index a70d1022ce..26f9da3618 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java @@ -48,4 +48,13 @@ public class TestProperties { } return System.getProperty("tb.wsUrl", "ws://localhost:8080"); } + + public static String getMqttBrokerUrl() { + if (instance.isActive()) { + String host = instance.getTestContainer().getServiceHost("broker", 1883); + Integer port = instance.getTestContainer().getServicePort("broker", 1883); + return "tcp://" + host + ":" + port; + } + return System.getProperty("mqtt.broker", "tcp://localhost:1883"); + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java index f04331e01e..a675ef4a20 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java @@ -31,10 +31,12 @@ import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; +import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetProfileId; @@ -45,9 +47,11 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; @@ -527,4 +531,41 @@ public class TestRestClient { .then() .statusCode(HTTP_OK); } + + public PageData getEvents(EntityId entityId, EventType eventType, TenantId tenantId, TimePageLink pageLink) { + Map params = new HashMap<>(); + params.put("entityType", entityId.getEntityType().name()); + params.put("entityId", entityId.getId().toString()); + params.put("eventType", eventType.name()); + params.put("tenantId", tenantId.getId().toString()); + addTimePageLinkToParam(params, pageLink); + + return given().spec(requestSpec) + .get("/api/events/{entityType}/{entityId}/{eventType}?tenantId={tenantId}&" + getTimeUrlParams(pageLink), params) + .then() + .statusCode(HTTP_OK) + .extract() + .as(new TypeRef<>() {}); + } + + private void addTimePageLinkToParam(Map params, TimePageLink pageLink) { + this.addPageLinkToParam(params, pageLink); + if (pageLink.getStartTime() != null) { + params.put("startTime", String.valueOf(pageLink.getStartTime())); + } + if (pageLink.getEndTime() != null) { + params.put("endTime", String.valueOf(pageLink.getEndTime())); + } + } + + private String getTimeUrlParams(TimePageLink pageLink) { + String urlParams = getUrlParams(pageLink); + if (pageLink.getStartTime() != null) { + urlParams += "&startTime={startTime}"; + } + if (pageLink.getEndTime() != null) { + urlParams += "&endTime={endTime}"; + } + return urlParams; + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java new file mode 100644 index 0000000000..5aa0ae48fb --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java @@ -0,0 +1,204 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.msa.rule.node; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.awaitility.Awaitility; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.event.EventType; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.rule.NodeConnectionInfo; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.msa.AbstractContainerTest; +import org.thingsboard.server.msa.DisableUIListeners; +import org.thingsboard.server.msa.TestProperties; +import org.thingsboard.server.msa.WsClient; +import org.thingsboard.server.msa.mapper.WsTelemetryResponse; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.fail; +import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype; + +@DisableUIListeners +@Slf4j +public class MqttNodeTest extends AbstractContainerTest { + + private static final String TOPIC = "tb/mqtt/device"; + + private Device device; + + @BeforeMethod + public void setUp() { + testRestClient.login("tenant@thingsboard.org", "tenant"); + device = testRestClient.postDevice("", defaultDevicePrototype("mqtt_")); + } + + @AfterMethod + public void tearDown() { + testRestClient.deleteDeviceIfExists(device.getId()); + } + + @Test + public void telemetryUpload() throws Exception { + RuleChainId defaultRuleChainId = getDefaultRuleChainId(); + + createRootRuleChainWithTestNode("MqttRuleNodeTestMetadata.json", "org.thingsboard.rule.engine.mqtt.TbMqttNode", 2); + + DeviceCredentials deviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId()); + + WsClient wsClient = subscribeToWebSocket(device.getId(), "LATEST_TELEMETRY", CmdsType.TS_SUB_CMDS); + + MqttMessageListener messageListener = new MqttMessageListener(); + MqttClient responseClient = new MqttClient(TestProperties.getMqttBrokerUrl(), StringUtils.randomAlphanumeric(10), new MemoryPersistence()); + responseClient.connect(); + responseClient.subscribe(TOPIC, messageListener); + + MqttClient mqttClient = new MqttClient("tcp://localhost:1883", StringUtils.randomAlphanumeric(10), new MemoryPersistence()); + MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); + mqttConnectOptions.setUserName(deviceCredentials.getCredentialsId()); + mqttClient.connect(mqttConnectOptions); + mqttClient.publish("v1/devices/me/telemetry", new MqttMessage(createPayload().toString().getBytes())); + + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage(); + log.info("Received telemetry: {}", actualLatestTelemetry); + wsClient.closeBlocking(); + + assertThat(actualLatestTelemetry.getData()).hasSize(4); + assertThat(actualLatestTelemetry.getLatestValues().keySet()).containsOnlyOnceElementsOf(Arrays.asList("booleanKey", "stringKey", "doubleKey", "longKey")); + + assertThat(actualLatestTelemetry.getDataValuesByKey("booleanKey").get(1)).isEqualTo(Boolean.TRUE.toString()); + assertThat(actualLatestTelemetry.getDataValuesByKey("stringKey").get(1)).isEqualTo("value1"); + assertThat(actualLatestTelemetry.getDataValuesByKey("doubleKey").get(1)).isEqualTo(Double.toString(42.0)); + assertThat(actualLatestTelemetry.getDataValuesByKey("longKey").get(1)).isEqualTo(Long.toString(73)); + + Awaitility + .await() + .alias("Get integration events") + .atMost(10, TimeUnit.SECONDS) + .until(() -> messageListener.getEvents().size() > 0); + + BlockingQueue events = messageListener.getEvents(); + JsonNode actual = JacksonUtil.toJsonNode(Objects.requireNonNull(events.poll()).message); + + assertThat(actual.get("stringKey").asText()).isEqualTo("value1"); + assertThat(actual.get("booleanKey").asBoolean()).isEqualTo(Boolean.TRUE); + assertThat(actual.get("doubleKey").asDouble()).isEqualTo(42.0); + assertThat(actual.get("longKey").asLong()).isEqualTo(73); + + testRestClient.setRootRuleChain(defaultRuleChainId); + } + + @Data + private class MqttMessageListener implements IMqttMessageListener { + private final BlockingQueue events; + + private MqttMessageListener() { + events = new ArrayBlockingQueue<>(100); + } + + @Override + public void messageArrived(String s, MqttMessage mqttMessage) { + log.info("MQTT message [{}], topic [{}]", mqttMessage.toString(), s); + events.add(new MqttEvent(s, mqttMessage.toString())); + } + + public BlockingQueue getEvents() { + return events; + } + } + + @Data + private class MqttEvent { + private final String topic; + private final String message; + } + + private RuleChainId getDefaultRuleChainId() { + PageData ruleChains = testRestClient.getRuleChains(new PageLink(40, 0)); + + Optional defaultRuleChain = ruleChains.getData() + .stream() + .filter(RuleChain::isRoot) + .findFirst(); + if (!defaultRuleChain.isPresent()) { + fail("Root rule chain wasn't found"); + } + return defaultRuleChain.get().getId(); + } + + protected RuleChainId createRootRuleChainWithTestNode(String ruleChainMetadataFile, String ruleNodeType, int eventsCount) throws Exception { + RuleChain newRuleChain = new RuleChain(); + newRuleChain.setName("testRuleChain"); + RuleChain ruleChain = testRestClient.postRuleChain(newRuleChain); + + JsonNode configuration = JacksonUtil.OBJECT_MAPPER.readTree(this.getClass().getClassLoader().getResourceAsStream(ruleChainMetadataFile)); + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + ruleChainMetaData.setFirstNodeIndex(configuration.get("firstNodeIndex").asInt()); + ruleChainMetaData.setNodes(Arrays.asList(JacksonUtil.OBJECT_MAPPER.treeToValue(configuration.get("nodes"), RuleNode[].class))); + ruleChainMetaData.setConnections(Arrays.asList(JacksonUtil.OBJECT_MAPPER.treeToValue(configuration.get("connections"), NodeConnectionInfo[].class))); + + ruleChainMetaData = testRestClient.postRuleChainMetadata(ruleChainMetaData); + + testRestClient.setRootRuleChain(ruleChain.getId()); + + RuleNode node = ruleChainMetaData.getNodes().stream().filter(ruleNode -> ruleNode.getType().equals(ruleNodeType)).findFirst().get(); + + Awaitility + .await() + .alias("Get events from rule chain") + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + PageData events = testRestClient.getEvents(node.getId(), EventType.LC_EVENT, ruleChain.getTenantId(), new TimePageLink(1024)); + List eventInfos = events.getData().stream().filter(eventInfo -> + "STARTED".equals(eventInfo.getBody().get("event").asText()) && + "true".equals(eventInfo.getBody().get("success").asText())) + .collect(Collectors.toList()); + + return eventInfos.size() == eventsCount; + }); + + return ruleChain.getId(); + } +} diff --git a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json new file mode 100644 index 0000000000..e6c9f5a53f --- /dev/null +++ b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json @@ -0,0 +1,79 @@ +{ + "firstNodeIndex": 2, + "nodes": [ + { + "additionalInfo": { + "description": "", + "layoutX": 626, + "layoutY": 152 + }, + "type": "org.thingsboard.rule.engine.mqtt.TbMqttNode", + "name": "test mqtt", + "debugMode": true, + "singletonMode": true, + "queueName": "HighPriority", + "configurationVersion": 0, + "configuration": { + "topicPattern": "tb/mqtt/device", + "host": "broker", + "port": 1883, + "connectTimeoutSec": 10, + "clientId": null, + "cleanSession": true, + "retainedMessage": false, + "ssl": false, + "credentials": { + "type": "anonymous" + } + }, + "externalId": null + }, + { + "additionalInfo": { + "description": "", + "layoutX": 949, + "layoutY": 153 + }, + "type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", + "name": "save timeseries", + "debugMode": true, + "singletonMode": false, + "configurationVersion": 0, + "configuration": { + "defaultTTL": 0, + "skipLatestPersistence": false, + "useServerTs": false + }, + "externalId": null + }, + { + "additionalInfo": { + "description": "", + "layoutX": 305, + "layoutY": 151 + }, + "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", + "name": "swatch", + "debugMode": false, + "singletonMode": false, + "configurationVersion": 0, + "configuration": { + "version": 0 + }, + "externalId": null + } + ], + "connections": [ + { + "fromIndex": 0, + "toIndex": 1, + "type": "Success" + }, + { + "fromIndex": 2, + "toIndex": 0, + "type": "Post telemetry" + } + ], + "ruleChainConnections": null +} \ No newline at end of file diff --git a/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml b/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml new file mode 100644 index 0000000000..10675c9a23 --- /dev/null +++ b/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml @@ -0,0 +1,25 @@ +# +# Copyright © 2016-2023 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +version: '3.0' +services: + broker: + image: eclipse-mosquitto + volumes: + - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf + ports: + - "1883" + restart: always diff --git a/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf b/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf new file mode 100644 index 0000000000..7a40d338fc --- /dev/null +++ b/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf @@ -0,0 +1,18 @@ +# +# Copyright © 2016-2023 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +listener 1883 +allow_anonymous true From 4101fc3963c7269455076fb6d83af16ba0cd7016 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 14 Dec 2023 21:14:31 +0100 Subject: [PATCH 06/91] added upgrade tests, and minor fixes --- .../install/ThingsboardInstallService.java | 1 - .../server/utils/TbNodeUpgradeUtils.java | 2 +- .../server/common/data/DataConstants.java | 1 + .../data/plugin/ComponentDescriptor.java | 2 +- .../resources/MqttRuleNodeTestMetadata.json | 4 +- .../rule/engine/api/util/TbNodeUtils.java | 2 - .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../deduplication/TbMsgDeduplicationNode.java | 4 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../engine/AbstractRuleNodeUpgradeTest.java | 52 ++++++++++++++++++ .../engine/debug/TbMsgGeneratorNodeTest.java | 53 ++++++++++++++++++ .../engine/flow/TbCheckpointNodeTest.java | 55 +++++++++++++++++++ .../telemetry/TbMsgAttributesNodeTest.java | 25 ++------- .../transform/TbMsgDeduplicationNodeTest.java | 35 +++++++++++- 14 files changed, 207 insertions(+), 33 deletions(-) create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 054c7a6751..4c9677494b 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -277,7 +277,6 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } - break; case "3.6.2": log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); diff --git a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java index 23c75b430b..e0ecfdd038 100644 --- a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java +++ b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.service.component.RuleNodeClassInfo; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j public class TbNodeUpgradeUtils { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index ca48ef364a..14142de3db 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -135,5 +135,6 @@ public class DataConstants { public static final String HP_QUEUE_TOPIC = "tb_rule_engine.hp"; public static final String SQ_QUEUE_NAME = "SequentialByOriginator"; public static final String SQ_QUEUE_TOPIC = "tb_rule_engine.sq"; + public static final String QUEUE_NAME = "queueName"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index 0e9b31ec09..1558080d42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -55,7 +55,7 @@ public class ComponentDescriptor extends BaseData { @Length(fieldName = "actions") @ApiModelProperty(position = 10, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; - @ApiModelProperty(position = 11, value = "Indicates that the RuleNode is support queue name.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") + @ApiModelProperty(position = 11, value = "Indicates that the RuleNode supports queue name configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") @Getter @Setter private boolean hasQueueName; public ComponentDescriptor() { diff --git a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json index e6c9f5a53f..7a5015add3 100644 --- a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json +++ b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json @@ -53,7 +53,7 @@ "layoutY": 151 }, "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", - "name": "swatch", + "name": "switch", "debugMode": false, "singletonMode": false, "configurationVersion": 0, @@ -76,4 +76,4 @@ } ], "ruleChainConnections": null -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java index cce5649336..7c3be84410 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java @@ -36,8 +36,6 @@ import java.util.stream.Collectors; */ public class TbNodeUtils { - public static final String QUEUE_NAME = "queueName"; - private static final Pattern DATA_PATTERN = Pattern.compile("(\\$\\[)(.*?)(])"); public static T convert(TbNodeConfiguration configuration, Class clazz) throws TbNodeException { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index cec7aca0a3..689e14429f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -47,7 +47,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j @RuleNode( diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index 17b72cd27a..dc7f2ee07f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @RuleNode( type = ComponentType.TRANSFORMATION, @@ -177,7 +177,7 @@ public class TbMsgDeduplicationNode implements TbNode { } if (resultMsg != null) { deduplicationResults.add(TbMsg.newMsg( - resultMsg.getQueueName(), + queueName, resultMsg.getType(), resultMsg.getOriginator(), resultMsg.getCustomerId(), diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index 9616d8a167..c7e775f5a4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j @RuleNode( diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java new file mode 100644 index 0000000000..6e665357bc --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java @@ -0,0 +1,52 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNode; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.util.TbPair; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.BDDMockito.willCallRealMethod; + +public abstract class AbstractRuleNodeUpgradeTest { + + protected abstract TbNode getTestNode(); + + @ParameterizedTest + @MethodSource + public void givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig(int givenVersion, String givenConfigStr, boolean hasChanges, String expectedConfigStr) throws TbNodeException { + // GIVEN + willCallRealMethod().given(getTestNode()).upgrade(anyInt(), any()); + JsonNode givenConfig = JacksonUtil.toJsonNode(givenConfigStr); + JsonNode expectedConfig = JacksonUtil.toJsonNode(expectedConfigStr); + + // WHEN + TbPair upgradeResult = getTestNode().upgrade(givenVersion, givenConfig); + + // THEN + assertThat(upgradeResult.getFirst()).isEqualTo(hasChanges); + ObjectNode upgradedConfig = (ObjectNode) upgradeResult.getSecond(); + assertThat(upgradedConfig).isEqualTo(expectedConfig); + } +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java new file mode 100644 index 0000000000..2e188bf002 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java @@ -0,0 +1,53 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.debug; + +import org.junit.jupiter.params.provider.Arguments; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; +import org.thingsboard.rule.engine.api.TbNode; + +import java.util.stream.Stream; + +import static org.mockito.Mockito.spy; + +public class TbMsgGeneratorNodeTest extends AbstractRuleNodeUpgradeTest { + + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"queueName\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + true, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"queueName\":\"Main\", \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + true, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + false, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}") + ); + } + + @Override + protected TbNode getTestNode() { + return spy(TbMsgGeneratorNode.class); + } +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java new file mode 100644 index 0000000000..edb7a7c3b1 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -0,0 +1,55 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.flow; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.params.provider.Arguments; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; +import org.thingsboard.rule.engine.api.TbNode; + +import java.util.stream.Stream; + +import static org.mockito.Mockito.spy; + +@Slf4j +public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { + + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"queueName\":null}", + true, + "{}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"queueName\":\"Main\"}", + true, + "{}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{}", + false, + "{}") + ); + } + + @Override + protected TbNode getTestNode() { + return spy(TbCheckpointNode.class); + } +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java index fe2edc941b..d59e416fcf 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.telemetry; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -25,8 +24,10 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.DataConstants; @@ -40,7 +41,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.msg.TbMsgType; -import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -53,7 +53,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; @@ -65,7 +64,7 @@ import static org.mockito.Mockito.when; import static org.thingsboard.server.common.data.DataConstants.NOTIFY_DEVICE_METADATA_KEY; @Slf4j -class TbMsgAttributesNodeTest { +class TbMsgAttributesNodeTest extends AbstractRuleNodeUpgradeTest { private TenantId tenantId; private DeviceId deviceId; @@ -223,21 +222,9 @@ class TbMsgAttributesNodeTest { ); } - @ParameterizedTest - @MethodSource - void givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig(int givenVersion, String givenConfigStr, boolean hasChanges, String expectedConfigStr) throws TbNodeException { - // GIVEN - willCallRealMethod().given(node).upgrade(anyInt(), any()); - JsonNode givenConfig = JacksonUtil.toJsonNode(givenConfigStr); - JsonNode expectedConfig = JacksonUtil.toJsonNode(expectedConfigStr); - - // WHEN - TbPair upgradeResult = node.upgrade(givenVersion, givenConfig); - - // THEN - assertThat(upgradeResult.getFirst()).isEqualTo(hasChanges); - ObjectNode upgradedConfig = (ObjectNode) upgradeResult.getSecond(); - assertThat(upgradedConfig).isEqualTo(expectedConfig); + @Override + protected TbNode getTestNode() { + return node; } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index 8e8340c713..b5bbcdc0fe 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -22,12 +22,15 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.deduplication.DeduplicationStrategy; @@ -40,7 +43,6 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; -import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -56,6 +58,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; +import java.util.stream.Stream; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -69,7 +72,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @Slf4j -public class TbMsgDeduplicationNodeTest { +public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { private TbContext ctx; @@ -293,7 +296,7 @@ public class TbMsgDeduplicationNodeTest { for (TbMsg msg : firstMsgPack) { node.onMsg(ctx, msg); } - long firstPackDeduplicationPackEndTs = firstMsgPack.get(0).getMetaDataTs() + TimeUnit.SECONDS.toMillis(deduplicationInterval); + long firstPackDeduplicationPackEndTs = firstMsgPack.get(0).getMetaDataTs() + TimeUnit.SECONDS.toMillis(deduplicationInterval); List secondMsgPack = getTbMsgs(deviceId, msgCount / 2, firstPackDeduplicationPackEndTs, 500); for (TbMsg msg : secondMsgPack) { @@ -386,6 +389,27 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(msgWithLatestTsInSecondPack.getType(), actualMsg.getType()); } + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3, \"queueName\":null}", + true, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3, \"queueName\":\"Main\"}", + true, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}", + false, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}") + ); + } + private TbMsg getMsgWithLatestTs(List firstMsgPack) { int indexOfLastMsgInArray = firstMsgPack.size() - 1; int indexToSetMaxTs = new Random().nextInt(indexOfLastMsgInArray) + 1; @@ -430,4 +454,9 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } + @Override + protected TbNode getTestNode() { + return node; + } + } From fe6ca79c4154cd16ff243a26a822beb1dbe07522 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 18 Dec 2023 15:31:23 +0100 Subject: [PATCH 07/91] minor improvements --- .../deduplication/TbMsgDeduplicationNode.java | 2 +- .../engine/debug/TbMsgGeneratorNodeTest.java | 2 +- .../engine/flow/TbCheckpointNodeTest.java | 2 +- .../transform/TbMsgDeduplicationNodeTest.java | 23 +++++++++++++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index dc7f2ee07f..4e83b1887b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -177,7 +177,7 @@ public class TbMsgDeduplicationNode implements TbNode { } if (resultMsg != null) { deduplicationResults.add(TbMsg.newMsg( - queueName, + queueName != null ? queueName : resultMsg.getQueueName(), resultMsg.getType(), resultMsg.getOriginator(), resultMsg.getCustomerId(), diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java index 2e188bf002..f0ba55e03b 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java @@ -50,4 +50,4 @@ public class TbMsgGeneratorNodeTest extends AbstractRuleNodeUpgradeTest { protected TbNode getTestNode() { return spy(TbMsgGeneratorNode.class); } -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java index edb7a7c3b1..c7d50528d5 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -52,4 +52,4 @@ public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { protected TbNode getTestNode() { return spy(TbCheckpointNode.class); } -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index b5bbcdc0fe..89eda98090 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -22,7 +22,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; @@ -143,13 +145,24 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { node.destroy(); } - @Test - public void given_100_messages_strategy_first_then_verifyOutput() throws TbNodeException, ExecutionException, InterruptedException { + private static Stream given_100_messages_strategy_first_then_verifyOutput() { + return Stream.of( + Arguments.of((String) null), + Arguments.of(DataConstants.MAIN_QUEUE_NAME), + Arguments.of(DataConstants.HP_QUEUE_NAME) + ); + } + + @ParameterizedTest + @MethodSource + public void given_100_messages_strategy_first_then_verifyOutput(String queueName) throws TbNodeException, ExecutionException, InterruptedException { int wantedNumberOfTellSelfInvocation = 2; int msgCount = 100; awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation); + when(ctx.getQueueName()).thenReturn(queueName); + config.setInterval(deduplicationInterval); config.setMaxPendingMsgs(msgCount); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); @@ -186,6 +199,12 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { Assertions.assertEquals(firstMsg.getData(), actualMsg.getData()); Assertions.assertEquals(firstMsg.getMetaData(), actualMsg.getMetaData()); Assertions.assertEquals(firstMsg.getType(), actualMsg.getType()); + + if (queueName == null) { + Assertions.assertEquals(firstMsg.getQueueName(), actualMsg.getQueueName()); + } else { + Assertions.assertEquals(ctx.getQueueName(), actualMsg.getQueueName()); + } } @Test From ace148884c1dbe993597e63029971d5395448aaf Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 26 Dec 2023 15:41:56 +0200 Subject: [PATCH 08/91] UI: Image Gallery: Hide overlay buttons from image card in selection mode. --- .../app/shared/components/image/image-gallery.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/shared/components/image/image-gallery.component.html b/ui-ngx/src/app/shared/components/image/image-gallery.component.html index 43a1b39a52..78d2e4b788 100644 --- a/ui-ngx/src/app/shared/components/image/image-gallery.component.html +++ b/ui-ngx/src/app/shared/components/image/image-gallery.component.html @@ -324,7 +324,7 @@
-
+
\n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class bt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(h),this.alarmSeverityTranslationMap=v,this.separatorKeysCodes=[xe,be,he],this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([_.required]),this.createAlarmConfigForm.get("severity").setValidators([_.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==b.TBEL||this.tbelEnabled||(r=b.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===b.JS?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===b.TBEL?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class ht extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[_.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==k.DEVICE&&t!==k.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([_.required,_.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([_.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",vt),vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,_.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,_.required]})}}e("DeviceProfileConfigComponent",Ct),Ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ct,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function",this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[_.required,_.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[_.required,_.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}var kt;e("GeneratorConfigComponent",Ft),Ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ft,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ke.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(kt||(kt={}));const Lt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer"],[kt.TENANT,"tb.rulenode.originator-tenant"],[kt.RELATED,"tb.rulenode.originator-related"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[kt.ENTITY,"tb.rulenode.originator-entity"]]),Tt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[kt.TENANT,"tb.rulenode.originator-tenant-desc"],[kt.RELATED,"tb.rulenode.originator-related-entity-desc"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[kt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),It=[L.createdTime,L.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},L.firstName,L.lastName,L.email,L.title,L.country,L.state,L.city,L.address,L.address2,L.zip,L.phone,L.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Nt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var St;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(St||(St={}));const qt=new Map([[St.CIRCLE,"tb.rulenode.perimeter-circle"],[St.POLYGON,"tb.rulenode.perimeter-polygon"]]);var At;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(At||(At={}));const Mt=new Map([[At.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[At.SECONDS,"tb.rulenode.time-unit-seconds"],[At.MINUTES,"tb.rulenode.time-unit-minutes"],[At.HOURS,"tb.rulenode.time-unit-hours"],[At.DAYS,"tb.rulenode.time-unit-days"]]);var Et;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(Et||(Et={}));const Gt=new Map([[Et.METER,"tb.rulenode.range-unit-meter"],[Et.KILOMETER,"tb.rulenode.range-unit-kilometer"],[Et.FOOT,"tb.rulenode.range-unit-foot"],[Et.MILE,"tb.rulenode.range-unit-mile"],[Et.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Dt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Dt||(Dt={}));const Vt=new Map([[Dt.ID,"tb.rulenode.entity-details-id"],[Dt.TITLE,"tb.rulenode.entity-details-title"],[Dt.COUNTRY,"tb.rulenode.entity-details-country"],[Dt.STATE,"tb.rulenode.entity-details-state"],[Dt.CITY,"tb.rulenode.entity-details-city"],[Dt.ZIP,"tb.rulenode.entity-details-zip"],[Dt.ADDRESS,"tb.rulenode.entity-details-address"],[Dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Dt.PHONE,"tb.rulenode.entity-details-phone"],[Dt.EMAIL,"tb.rulenode.entity-details-email"],[Dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var wt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(wt||(wt={}));const Pt=new Map([[wt.FIRST,"tb.rulenode.first"],[wt.LAST,"tb.rulenode.last"],[wt.ALL,"tb.rulenode.all"]]),Rt=new Map([[wt.FIRST,"tb.rulenode.first-mode-hint"],[wt.LAST,"tb.rulenode.last-mode-hint"],[wt.ALL,"tb.rulenode.all-mode-hint"]]);var Ot,_t;!function(e){e.ASC="ASC",e.DESC="DESC"}(Ot||(Ot={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(_t||(_t={}));const Bt=new Map([[_t.ATTRIBUTES,"tb.rulenode.attributes"],[_t.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[_t.FIELDS,"tb.rulenode.fields"]]),Kt=new Map([[_t.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[_t.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[_t.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),zt=new Map([[Ot.ASC,"tb.rulenode.ascending"],[Ot.DESC,"tb.rulenode.descending"]]);var Ut;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Ut||(Ut={}));const Ht=new Map([[Ut.STANDARD,"tb.rulenode.sqs-queue-standard"],[Ut.FIFO,"tb.rulenode.sqs-queue-fifo"]]),jt=["anonymous","basic","cert.PEM"],$t=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Qt=["sas","cert.PEM"],Jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Yt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Yt||(Yt={}));const Wt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Zt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Xt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Xt||(Xt={}));const en=new Map([[Xt.CUSTOM,{value:Xt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Xt.ADD,{value:Xt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Xt.SUB,{value:Xt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Xt.MULT,{value:Xt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Xt.DIV,{value:Xt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Xt.SIN,{value:Xt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.SINH,{value:Xt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Xt.COS,{value:Xt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.COSH,{value:Xt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Xt.TAN,{value:Xt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Xt.TANH,{value:Xt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ACOS,{value:Xt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Xt.ASIN,{value:Xt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN,{value:Xt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN2,{value:Xt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Xt.EXP,{value:Xt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Xt.EXPM1,{value:Xt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Xt.SQRT,{value:Xt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Xt.CBRT,{value:Xt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Xt.GET_EXP,{value:Xt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Xt.HYPOT,{value:Xt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Xt.LOG,{value:Xt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG10,{value:Xt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG1P,{value:Xt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Xt.CEIL,{value:Xt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR,{value:Xt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR_DIV,{value:Xt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Xt.FLOOR_MOD,{value:Xt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Xt.ABS,{value:Xt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Xt.MIN,{value:Xt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Xt.MAX,{value:Xt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Xt.POW,{value:Xt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Xt.SIGNUM,{value:Xt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Xt.RAD,{value:Xt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Xt.DEG,{value:Xt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var tn,nn,rn;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(tn||(tn={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(nn||(nn={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(rn||(rn={}));const on=new Map([[rn.DATA,"tb.rulenode.message-to-metadata"],[rn.METADATA,"tb.rulenode.metadata-to-message"]]),an=(new Map([[rn.DATA,"tb.rulenode.from-message"],[rn.METADATA,"tb.rulenode.from-metadata"]]),new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.metadata"]])),ln=new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.message-metadata"]]),sn=new Map([[tn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[tn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[tn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[tn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[tn.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),mn=new Map([[nn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[nn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[nn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[nn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),pn=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var un,dn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(un||(un={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(dn||(dn={}));const cn=new Map([[un.SHARED_SCOPE,"tb.rulenode.shared-scope"],[un.SERVER_SCOPE,"tb.rulenode.server-scope"],[un.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.keys(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.keys(Et),this.rangeUnitTranslationMap=Gt,this.timeUnits=Object.keys(At),this.timeUnitsTranslationMap=Mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[_.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[_.required]],perimeterType:[e?e.perimeterType:null,[_.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[_.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[_.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoActionConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([_.required])),t||n!==St.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gn extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[_.required,_.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[_.required]]})}}e("MsgCountConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([_.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([_.required,_.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToCloudConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class hn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToEdgeConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[_.required,_.min(0)]]})}}e("RpcRequestConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[_.required]],value:[e[n],[_.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[_.required]],value:["",[_.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ne.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[_.required,_.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[_.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ln extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[_.required,_.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],keys:[e?e.keys:null,[_.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Nn extends T{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=en,this.ArgumentType=tn,this.attributeScopeMap=cn,this.argumentTypeMap=sn,this.arguments=Object.values(tn),this.attributeScope=Object.values(un),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Xt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([_.minLength(this.minArgs),_.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===tn.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==tn.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(pn[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:qe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:qe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Ae.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Ae.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Ae.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Sn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...en.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(Me((e=>{let t;t="string"==typeof e&&Xt[e]?Xt[e]:null,this.updateView(t)})),Ee((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=en.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class qn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Xt,this.ArgumentTypeResult=nn,this.argumentTypeResultMap=mn,this.attributeScopeMap=cn,this.argumentsResult=Object.values(nn),this.attributeScopeResult=Object.values(dn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[_.required]],arguments:[e?e.arguments:null,[_.required]],customFunction:[e?e.customFunction:"",[_.required]],result:this.fb.group({type:[e?e.result.type:null,[_.required]],attributeScope:[e?e.result.attributeScope:null,[_.required]],key:[e?e.result.key:"",[_.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Xt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===nn.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Sn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class An{constructor(){this.textAlign="left"}}e("ExampleHintComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Mn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new Ke,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Mn.prototype,"disabled",void 0),Be([I()],Mn.prototype,"uniqueKeyValuePairValidator",void 0),Be([I()],Mn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class En extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.entityType=k,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],relationType:[null],deviceTypes:[null,[_.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Gn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Dn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[xe,be,he],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(N))this.messageTypesList.push({name:S.get(N[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ge(""),Ee((e=>e||"")),De((e=>this.fetchMessageTypes(e))),Ve())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ue(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ue(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,deps:[{token:R.Store},{token:X.TranslateService},{token:q.TruncatePipe},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Re.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:q.TruncatePipe},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class Vn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=jt,this.credentialsTypeTranslationsMap=$t,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[_.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){se(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([_.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[_.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(_.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:We.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const wn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Pn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new Ke,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[{token:t.NgZone},{token:$},{token:wn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Pn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[$]}]},{type:void 0,decorators:[{type:p},{type:m,args:[wn]}]}]}});class Rn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Pn}],target:t.ɵɵFactoryTarget.Directive}),Rn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Rn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,decorators:[{type:u,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Pn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:d}],cbOnError:[{type:d}]}});class On{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,deps:[{token:Pn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),On.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:On,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,decorators:[{type:u,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Pn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class _n{}_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),_n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,declarations:[Rn,On],imports:[Q],exports:[Rn,On]}),_n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,imports:[[Q]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,decorators:[{type:c,args:[{imports:[Q],declarations:[Rn,On],exports:[Rn,On]}]}]});class Bn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new Ke,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[_.required]],messageType:[{value:null,disabled:!0},[_.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(ze(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[_.required,_.maxLength(255)]:[_.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Rn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Bn.prototype,"disabled",void 0),Be([I()],Bn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.fb=e,this.translate=t,this.translation=an,this.propagateChange=()=>{},this.destroy$=new Ke,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder},{type:X.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class zn extends T{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ke,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(we(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)se(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(we(this.destroy$)).subscribe((t=>{const n=Nt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],zn.prototype,"disabled",void 0),Be([I()],zn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Un extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Un,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Hn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new Ke,this.separatorKeysCodes=[xe,be,he],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(_.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||se(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Hn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:X.TranslateService},{type:O.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class jn extends T{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new Ke,this.alarmStatus=A,this.alarmStatusTranslations=M}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class $n{}e("RulenodeCoreConfigCommonModule",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),$n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:$n,declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}),$n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,imports:[Q,E,_e]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:c,args:[{declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}]}]});class Qn{}e("RuleNodeCoreConfigActionModule",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Qn,declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}),Qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:c,args:[{declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}]}]});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[_.min(0),_.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:se(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:se(e?.outputValueKey)?e.outputValueKey:null,useCache:!se(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!se(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:se(e?.periodValueKey)?e.periodValueKey:null,round:se(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!se(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return me(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([_.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,me(e)}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[_.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:se(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!se(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:En,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Dt))this.predefinedValues.push({value:Dt[e],name:this.translate.instant(Vt.get(Dt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=se(e?.addToMetadata)?e.addToMetadata?rn.METADATA:rn.DATA:e?.fetchTo?e.fetchTo:rn.DATA,{detailsList:se(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he],this.aggregationTypes=G,this.aggregations=Object.values(G),this.aggregationTypesTranslations=D,this.fetchMode=wt,this.samplingOrders=Object.values(Ot),this.samplingOrdersTranslate=zt,this.timeUnits=Object.values(At),this.timeUnitsTranslationMap=Mt,this.deduplicationStrategiesHintTranslations=Rt,this.headerOptions=[],this.timeUnitMap={[At.MILLISECONDS]:1,[At.SECONDS]:1e3,[At.MINUTES]:6e4,[At.HOURS]:36e5,[At.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Pt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Pt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[_.required]],aggregation:[e.aggregation,[_.required]],fetchMode:[e.fetchMode,[_.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,me(e)}prepareInputConfig(e){return pe(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:se(e?.aggregation)?e.aggregation:G.NONE,fetchMode:se(e?.fetchMode)?e.fetchMode:wt.FIRST,orderBy:se(e?.orderBy)?e.orderBy:Ot.ASC,limit:se(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!se(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:se(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:se(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:At.MINUTES,endInterval:se(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:se(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:At.MINUTES},startIntervalPattern:se(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:se(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===wt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([_.required,_.min(2),_.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===wt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===G.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,tellFailureIfAbsent:!!se(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:se(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class tr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of It)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return me(e)}prepareInputConfig(e){return{dataMapping:se(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:se(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[_.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class nr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=_t,this.msgMetadataLabelTranslations=Kt,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(It))this.originatorFields.push({value:It[e].value,name:this.translate.instant(It[e].name)});for(const e of Bt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===_t.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,me(e)}prepareInputConfig(e){let t,n,r={[L.name.value]:`relatedEntity${this.translate.instant(L.name.name)}`},o={serialNumber:"sn"};return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,t===_t.FIELDS?r=n:o=n,{relationsQuery:se(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[_.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[_.required]],svMap:[e.svMap,[_.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===_t.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:nr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class rr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class ar{}e("RulenodeCoreConfigEnrichmentModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:ar,declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:c,args:[{declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}]}]});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Qt,this.azureIotHubCredentialsTypeTranslationsMap=Jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[_.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[_.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([_.required]);break;case"cert.PEM":t.get("privateKey").setValidators([_.required]),t.get("privateKeyFileName").setValidators([_.required]),t.get("cert").setValidators([_.required]),t.get("certFileName").setValidators([_.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:We.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Wt,this.ToByteStandartCharsetTypeTranslationMap=Zt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[_.required]],retries:[e?e.retries:null,[_.min(0)]],batchSize:[e?e.batchSize:null,[_.min(0)]],linger:[e?e.linger:null,[_.min(0)]],bufferMemory:[e?e.bufferMemory:null,[_.min(0)]],acks:[e?e.acks:null,[_.required]],keySerializer:[e?e.keySerializer:null,[_.required]],valueSerializer:[e?e.valueSerializer:null,[_.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([_.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ue(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){ue(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=V,this.entityType=k}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[_.required]],targets:[e?e.targets:[],[_.required]]})}}e("NotificationConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:rt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ot.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[_.required]],topicName:[e?e.topicName:null,[_.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[_.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[_.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[_.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[_.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Yt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[_.required]],requestMethod:[e?e.requestMethod:null,[_.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[_.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[_.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[_.required,_.min(1),_.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([_.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([_.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([_.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([_.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([_.required,_.min(1),_.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([_.required,_.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[_.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[_.required,_.min(1),_.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:at.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[_.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[_.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([_.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=P}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[_.required]],conversationType:[e?e.conversationType:null,[_.required]],conversation:[e?e.conversation:null,[_.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([_.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:lt.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:lt.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:st.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[_.required]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SnsConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Ut,this.sqsQueueTypes=Object.keys(Ut),this.sqsQueueTypeTranslationsMap=Ht}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[_.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[_.required]],delaySeconds:[e?e.delaySeconds:null,[_.min(0),_.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SqsConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class br{}e("RulenodeCoreConfigExternalModule",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:br,declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}),br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:c,args:[{declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}]}]});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:se(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[_.required]]})}}e("CheckAlarmStatusComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:jn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!se(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(_.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(C),this.entitySearchDirectionTranslationsMap=F}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!se(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:se(e?.direction)?e.direction:null,entityType:se(e?.entityType)?e.entityType:null,entityId:se(e?.entityId)?e.entityId:null,relationType:se(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[_.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[_.required]:[]],relationType:[e.relationType,[_.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.values(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.values(Et),this.rangeUnitTranslationMap=Gt,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:se(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:se(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:se(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!se(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:se(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:se(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:se(e?.centerLongitude)?e.centerLongitude:null,range:se(e?.range)?e.range:null,rangeUnit:se(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:se(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[_.required]],longitudeKeyName:[e.longitudeKeyName,[_.required]],perimeterType:[e.perimeterType,[_.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoFilterConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([_.required]),this.defaultPaddingEnable=!1),t||n!==St.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:se(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[_.required]]})}}e("MessageTypeConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Dn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.TENANT,k.CUSTOMER,k.USER,k.DASHBOARD,k.RULE_CHAIN,k.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:se(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[_.required]]})}}e("OriginatorTypeConfigComponent",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Lr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:pt.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Nr{}e("RuleNodeCoreConfigFilterModule",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Nr,declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}),Nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,decorators:[{type:c,args:[{declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}]}]});class Sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=kt,this.originatorSources=Object.keys(kt),this.originatorSourceTranslationMap=Lt,this.originatorSourceDescTranslationMap=Tt,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.USER,k.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===kt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([_.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===kt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([_.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class qr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[_.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,deps:[{token:R.Store},{token:O.FormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,u,d,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,V,w,P,R,O,_,B,z,K,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,ue,de,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,Ve,we,Pe,Re,Oe,_e,Be,ze,Ke,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt,ut,dt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,u=e.Directive,d=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ServiceType,b=e.ScriptLanguage,h=e.AlarmSeverity,v=e.alarmSeverityTranslations,C=e.EntitySearchDirection,F=e.entitySearchDirectionTranslations,k=e.EntityType,L=e.entityFields,T=e.PageComponent,I=e.coerceBoolean,N=e.MessageType,S=e.messageTypeNames,q=e,A=e.AlarmStatus,M=e.alarmStatusTranslations,E=e.SharedModule,G=e.AggregationType,D=e.aggregationTranslations,V=e.NotificationType,w=e.SlackChanelType,P=e.SlackChanelTypesTranslateMap},function(e){R=e},function(e){O=e,_=e.Validators,B=e.NgControl,z=e.NG_VALUE_ACCESSOR,K=e.NG_VALIDATORS,U=e.FormArray,H=e.FormGroup},function(e){j=e,$=e.DOCUMENT,Q=e.CommonModule},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e},function(e){ae=e.getCurrentAuthState,ie=e,le=e.isEqual,se=e.isDefinedAndNotNull,me=e.deepTrim,pe=e.isObject,ue=e.isNotEmptyStr},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.ENTER,be=e.COMMA,he=e.SEMICOLON},function(e){ve=e},function(e){Ce=e},function(e){Fe=e},function(e){ke=e},function(e){Le=e.coerceBooleanProperty,Te=e.coerceElement,Ie=e.coerceNumberProperty},function(e){Ne=e},function(e){Se=e},function(e){qe=e},function(e){Ae=e},function(e){Me=e.tap,Ee=e.map,Ge=e.startWith,De=e.mergeMap,Ve=e.share,we=e.takeUntil,Pe=e.auditTime},function(e){Re=e},function(e){Oe=e},function(e){_e=e.HomeComponentsModule},function(e){Be=e.__decorate},function(e){ze=e.Subject,Ke=e.takeUntil,Ue=e.of,He=e.EMPTY,je=e.fromEvent},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e},function(e){pt=e},function(e){ut=e.normalizePassiveListenerOptions,dt=e}],execute:function(){class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ft extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[_.required]]})}}e("CheckPointConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[_.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===b.JS?[_.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===b.TBEL?[_.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class bt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(h),this.alarmSeverityTranslationMap=v,this.separatorKeysCodes=[xe,be,he],this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([_.required]),this.createAlarmConfigForm.get("severity").setValidators([_.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==b.TBEL||this.tbelEnabled||(r=b.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===b.JS?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===b.TBEL?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class ht extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[_.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==k.DEVICE&&t!==k.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([_.required,_.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([_.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",vt),vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,_.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,_.required]})}}e("DeviceProfileConfigComponent",Ct),Ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ct,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function",this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[_.required,_.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[_.required,_.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}var kt;e("GeneratorConfigComponent",Ft),Ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ft,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ke.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(kt||(kt={}));const Lt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer"],[kt.TENANT,"tb.rulenode.originator-tenant"],[kt.RELATED,"tb.rulenode.originator-related"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[kt.ENTITY,"tb.rulenode.originator-entity"]]),Tt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[kt.TENANT,"tb.rulenode.originator-tenant-desc"],[kt.RELATED,"tb.rulenode.originator-related-entity-desc"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[kt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),It=[L.createdTime,L.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},L.firstName,L.lastName,L.email,L.title,L.country,L.state,L.city,L.address,L.address2,L.zip,L.phone,L.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Nt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var St;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(St||(St={}));const qt=new Map([[St.CIRCLE,"tb.rulenode.perimeter-circle"],[St.POLYGON,"tb.rulenode.perimeter-polygon"]]);var At;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(At||(At={}));const Mt=new Map([[At.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[At.SECONDS,"tb.rulenode.time-unit-seconds"],[At.MINUTES,"tb.rulenode.time-unit-minutes"],[At.HOURS,"tb.rulenode.time-unit-hours"],[At.DAYS,"tb.rulenode.time-unit-days"]]);var Et;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(Et||(Et={}));const Gt=new Map([[Et.METER,"tb.rulenode.range-unit-meter"],[Et.KILOMETER,"tb.rulenode.range-unit-kilometer"],[Et.FOOT,"tb.rulenode.range-unit-foot"],[Et.MILE,"tb.rulenode.range-unit-mile"],[Et.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Dt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Dt||(Dt={}));const Vt=new Map([[Dt.ID,"tb.rulenode.entity-details-id"],[Dt.TITLE,"tb.rulenode.entity-details-title"],[Dt.COUNTRY,"tb.rulenode.entity-details-country"],[Dt.STATE,"tb.rulenode.entity-details-state"],[Dt.CITY,"tb.rulenode.entity-details-city"],[Dt.ZIP,"tb.rulenode.entity-details-zip"],[Dt.ADDRESS,"tb.rulenode.entity-details-address"],[Dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Dt.PHONE,"tb.rulenode.entity-details-phone"],[Dt.EMAIL,"tb.rulenode.entity-details-email"],[Dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var wt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(wt||(wt={}));const Pt=new Map([[wt.FIRST,"tb.rulenode.first"],[wt.LAST,"tb.rulenode.last"],[wt.ALL,"tb.rulenode.all"]]),Rt=new Map([[wt.FIRST,"tb.rulenode.first-mode-hint"],[wt.LAST,"tb.rulenode.last-mode-hint"],[wt.ALL,"tb.rulenode.all-mode-hint"]]);var Ot,_t;!function(e){e.ASC="ASC",e.DESC="DESC"}(Ot||(Ot={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(_t||(_t={}));const Bt=new Map([[_t.ATTRIBUTES,"tb.rulenode.attributes"],[_t.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[_t.FIELDS,"tb.rulenode.fields"]]),zt=new Map([[_t.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[_t.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[_t.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),Kt=new Map([[Ot.ASC,"tb.rulenode.ascending"],[Ot.DESC,"tb.rulenode.descending"]]);var Ut;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Ut||(Ut={}));const Ht=new Map([[Ut.STANDARD,"tb.rulenode.sqs-queue-standard"],[Ut.FIFO,"tb.rulenode.sqs-queue-fifo"]]),jt=["anonymous","basic","cert.PEM"],$t=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Qt=["sas","cert.PEM"],Jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Yt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Yt||(Yt={}));const Wt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Zt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Xt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Xt||(Xt={}));const en=new Map([[Xt.CUSTOM,{value:Xt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Xt.ADD,{value:Xt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Xt.SUB,{value:Xt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Xt.MULT,{value:Xt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Xt.DIV,{value:Xt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Xt.SIN,{value:Xt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.SINH,{value:Xt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Xt.COS,{value:Xt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.COSH,{value:Xt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Xt.TAN,{value:Xt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Xt.TANH,{value:Xt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ACOS,{value:Xt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Xt.ASIN,{value:Xt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN,{value:Xt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN2,{value:Xt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Xt.EXP,{value:Xt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Xt.EXPM1,{value:Xt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Xt.SQRT,{value:Xt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Xt.CBRT,{value:Xt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Xt.GET_EXP,{value:Xt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Xt.HYPOT,{value:Xt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Xt.LOG,{value:Xt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG10,{value:Xt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG1P,{value:Xt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Xt.CEIL,{value:Xt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR,{value:Xt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR_DIV,{value:Xt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Xt.FLOOR_MOD,{value:Xt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Xt.ABS,{value:Xt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Xt.MIN,{value:Xt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Xt.MAX,{value:Xt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Xt.POW,{value:Xt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Xt.SIGNUM,{value:Xt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Xt.RAD,{value:Xt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Xt.DEG,{value:Xt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var tn,nn,rn;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(tn||(tn={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(nn||(nn={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(rn||(rn={}));const on=new Map([[rn.DATA,"tb.rulenode.message-to-metadata"],[rn.METADATA,"tb.rulenode.metadata-to-message"]]),an=(new Map([[rn.DATA,"tb.rulenode.from-message"],[rn.METADATA,"tb.rulenode.from-metadata"]]),new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.metadata"]])),ln=new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.message-metadata"]]),sn=new Map([[tn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[tn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[tn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[tn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[tn.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),mn=new Map([[nn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[nn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[nn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[nn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),pn=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var un,dn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(un||(un={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(dn||(dn={}));const cn=new Map([[un.SHARED_SCOPE,"tb.rulenode.shared-scope"],[un.SERVER_SCOPE,"tb.rulenode.server-scope"],[un.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.keys(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.keys(Et),this.rangeUnitTranslationMap=Gt,this.timeUnits=Object.keys(At),this.timeUnitsTranslationMap=Mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[_.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[_.required]],perimeterType:[e?e.perimeterType:null,[_.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[_.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[_.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoActionConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([_.required])),t||n!==St.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gn extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[_.required,_.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[_.required]]})}}e("MsgCountConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([_.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([_.required,_.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToCloudConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class hn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToEdgeConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[_.required,_.min(0)]]})}}e("RpcRequestConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[_.required]],value:[e[n],[_.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[_.required]],value:["",[_.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:z,useExisting:a((()=>Fn)),multi:!0},{provide:K,useExisting:a((()=>Fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ne.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:z,useExisting:a((()=>Fn)),multi:!0},{provide:K,useExisting:a((()=>Fn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[_.required,_.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[_.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ln extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[_.required,_.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],keys:[e?e.keys:null,[_.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Nn extends T{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=en,this.ArgumentType=tn,this.attributeScopeMap=cn,this.argumentTypeMap=sn,this.arguments=Object.values(tn),this.attributeScope=Object.values(un),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Xt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([_.minLength(this.minArgs),_.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===tn.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==tn.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(pn[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:z,useExisting:a((()=>Nn)),multi:!0},{provide:K,useExisting:a((()=>Nn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:qe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:qe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Ae.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Ae.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Ae.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:z,useExisting:a((()=>Nn)),multi:!0},{provide:K,useExisting:a((()=>Nn)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Sn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...en.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(Me((e=>{let t;t="string"==typeof e&&Xt[e]?Xt[e]:null,this.updateView(t)})),Ee((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=en.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:z,useExisting:a((()=>Sn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:z,useExisting:a((()=>Sn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class qn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Xt,this.ArgumentTypeResult=nn,this.argumentTypeResultMap=mn,this.attributeScopeMap=cn,this.argumentsResult=Object.values(nn),this.attributeScopeResult=Object.values(dn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[_.required]],arguments:[e?e.arguments:null,[_.required]],customFunction:[e?e.customFunction:"",[_.required]],result:this.fb.group({type:[e?e.result.type:null,[_.required]],attributeScope:[e?e.result.attributeScope:null,[_.required]],key:[e?e.result.key:"",[_.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Xt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===nn.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Sn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class An{constructor(){this.textAlign="left"}}e("ExampleHintComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Mn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new ze,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(Ke(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:z,useExisting:a((()=>Mn)),multi:!0},{provide:K,useExisting:a((()=>Mn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Mn.prototype,"disabled",void 0),Be([I()],Mn.prototype,"uniqueKeyValuePairValidator",void 0),Be([I()],Mn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:z,useExisting:a((()=>Mn)),multi:!0},{provide:K,useExisting:a((()=>Mn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class En extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.entityType=k,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],relationType:[null],deviceTypes:[null,[_.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:z,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:z,useExisting:a((()=>En)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Gn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:z,useExisting:a((()=>Gn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:z,useExisting:a((()=>Gn)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Dn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[xe,be,he],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(N))this.messageTypesList.push({name:S.get(N[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ge(""),Ee((e=>e||"")),De((e=>this.fetchMessageTypes(e))),Ve())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ue(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ue(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,deps:[{token:R.Store},{token:X.TranslateService},{token:q.TruncatePipe},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:z,useExisting:a((()=>Dn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Re.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:z,useExisting:a((()=>Dn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:q.TruncatePipe},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class Vn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=jt,this.credentialsTypeTranslationsMap=$t,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[_.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){se(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([_.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[_.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(_.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:z,useExisting:a((()=>Vn)),multi:!0},{provide:K,useExisting:a((()=>Vn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:We.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:z,useExisting:a((()=>Vn)),multi:!0},{provide:K,useExisting:a((()=>Vn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const wn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Pn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new ze,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[{token:t.NgZone},{token:$},{token:wn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Pn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[$]}]},{type:void 0,decorators:[{type:p},{type:m,args:[wn]}]}]}});class Rn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Pn}],target:t.ɵɵFactoryTarget.Directive}),Rn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Rn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,decorators:[{type:u,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Pn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:d}],cbOnError:[{type:d}]}});class On{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,deps:[{token:Pn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),On.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:On,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,decorators:[{type:u,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Pn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class _n{}_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),_n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,declarations:[Rn,On],imports:[Q],exports:[Rn,On]}),_n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,imports:[[Q]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,decorators:[{type:c,args:[{imports:[Q],declarations:[Rn,On],exports:[Rn,On]}]}]});class Bn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new ze,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[_.required]],messageType:[{value:null,disabled:!0},[_.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(Ke(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(Ke(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[_.required,_.maxLength(255)]:[_.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:z,useExisting:a((()=>Bn)),multi:!0},{provide:K,useExisting:a((()=>Bn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Rn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Bn.prototype,"disabled",void 0),Be([I()],Bn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:z,useExisting:a((()=>Bn)),multi:!0},{provide:K,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class zn{constructor(e,t){this.fb=e,this.translate=t,this.translation=an,this.propagateChange=()=>{},this.destroy$=new ze,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:z,useExisting:a((()=>zn)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:z,useExisting:a((()=>zn)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder},{type:X.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class Kn extends T{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new ze,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(we(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)se(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(we(this.destroy$)).subscribe((t=>{const n=Nt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:z,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:a((()=>Kn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Kn.prototype,"disabled",void 0),Be([I()],Kn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:z,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:a((()=>Kn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Un extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Un,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:z,useExisting:a((()=>Un)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:z,useExisting:a((()=>Un)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Hn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new ze,this.separatorKeysCodes=[xe,be,he],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(_.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||se(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Hn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:z,useExisting:a((()=>Hn)),multi:!0},{provide:K,useExisting:Hn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:z,useExisting:a((()=>Hn)),multi:!0},{provide:K,useExisting:Hn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:X.TranslateService},{type:O.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class jn extends T{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new ze,this.alarmStatus=A,this.alarmStatusTranslations=M}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-alarm-status-select",providers:[{provide:z,useExisting:a((()=>jn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:z,useExisting:a((()=>jn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class $n{}e("RulenodeCoreConfigCommonModule",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),$n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:$n,declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,zn,Kn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,zn,Kn,Un,Hn,jn,An]}),$n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,imports:[Q,E,_e]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:c,args:[{declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,zn,Kn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,zn,Kn,Un,Hn,jn,An]}]}]});class Qn{}e("RuleNodeCoreConfigActionModule",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Qn,declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}),Qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:c,args:[{declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}]}]});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[_.min(0),_.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:se(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:se(e?.outputValueKey)?e.outputValueKey:null,useCache:!se(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!se(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:se(e?.periodValueKey)?e.periodValueKey:null,round:se(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!se(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return me(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([_.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,me(e)}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[_.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:se(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!se(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:En,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Dt))this.predefinedValues.push({value:Dt[e],name:this.translate.instant(Vt.get(Dt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=se(e?.addToMetadata)?e.addToMetadata?rn.METADATA:rn.DATA:e?.fetchTo?e.fetchTo:rn.DATA,{detailsList:se(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he],this.aggregationTypes=G,this.aggregations=Object.values(G),this.aggregationTypesTranslations=D,this.fetchMode=wt,this.samplingOrders=Object.values(Ot),this.samplingOrdersTranslate=Kt,this.timeUnits=Object.values(At),this.timeUnitsTranslationMap=Mt,this.deduplicationStrategiesHintTranslations=Rt,this.headerOptions=[],this.timeUnitMap={[At.MILLISECONDS]:1,[At.SECONDS]:1e3,[At.MINUTES]:6e4,[At.HOURS]:36e5,[At.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Pt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Pt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[_.required]],aggregation:[e.aggregation,[_.required]],fetchMode:[e.fetchMode,[_.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,me(e)}prepareInputConfig(e){return pe(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:se(e?.aggregation)?e.aggregation:G.NONE,fetchMode:se(e?.fetchMode)?e.fetchMode:wt.FIRST,orderBy:se(e?.orderBy)?e.orderBy:Ot.ASC,limit:se(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!se(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:se(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:se(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:At.MINUTES,endInterval:se(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:se(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:At.MINUTES},startIntervalPattern:se(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:se(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===wt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([_.required,_.min(2),_.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===wt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===G.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,tellFailureIfAbsent:!!se(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:se(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class tr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of It)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return me(e)}prepareInputConfig(e){return{dataMapping:se(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:se(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[_.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class nr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=_t,this.msgMetadataLabelTranslations=zt,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(It))this.originatorFields.push({value:It[e].value,name:this.translate.instant(It[e].name)});for(const e of Bt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===_t.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,me(e)}prepareInputConfig(e){let t,n,r={[L.name.value]:`relatedEntity${this.translate.instant(L.name.name)}`},o={serialNumber:"sn"};return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,t===_t.FIELDS?r=n:o=n,{relationsQuery:se(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[_.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[_.required]],svMap:[e.svMap,[_.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===_t.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:nr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class rr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class ar{}e("RulenodeCoreConfigEnrichmentModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:ar,declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:c,args:[{declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}]}]});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Qt,this.azureIotHubCredentialsTypeTranslationsMap=Jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[_.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[_.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([_.required]);break;case"cert.PEM":t.get("privateKey").setValidators([_.required]),t.get("privateKeyFileName").setValidators([_.required]),t.get("cert").setValidators([_.required]),t.get("certFileName").setValidators([_.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:We.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Wt,this.ToByteStandartCharsetTypeTranslationMap=Zt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[_.required]],retries:[e?e.retries:null,[_.min(0)]],batchSize:[e?e.batchSize:null,[_.min(0)]],linger:[e?e.linger:null,[_.min(0)]],bufferMemory:[e?e.bufferMemory:null,[_.min(0)]],acks:[e?e.acks:null,[_.required]],keySerializer:[e?e.keySerializer:null,[_.required]],valueSerializer:[e?e.valueSerializer:null,[_.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([_.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ue(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){ue(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=V,this.entityType=k}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[_.required]],targets:[e?e.targets:[],[_.required]]})}}e("NotificationConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:rt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ot.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[_.required]],topicName:[e?e.topicName:null,[_.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[_.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[_.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[_.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[_.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Yt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[_.required]],requestMethod:[e?e.requestMethod:null,[_.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[_.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[_.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[_.required,_.min(1),_.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([_.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([_.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([_.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([_.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([_.required,_.min(1),_.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([_.required,_.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[_.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[_.required,_.min(1),_.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:at.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[_.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[_.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([_.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=P}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[_.required]],conversationType:[e?e.conversationType:null,[_.required]],conversation:[e?e.conversation:null,[_.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([_.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:lt.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:lt.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:st.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[_.required]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SnsConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Ut,this.sqsQueueTypes=Object.keys(Ut),this.sqsQueueTypeTranslationsMap=Ht}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[_.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[_.required]],delaySeconds:[e?e.delaySeconds:null,[_.min(0),_.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SqsConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class br{}e("RulenodeCoreConfigExternalModule",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:br,declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}),br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:c,args:[{declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}]}]});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:se(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[_.required]]})}}e("CheckAlarmStatusComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:jn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!se(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(_.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(C),this.entitySearchDirectionTranslationsMap=F}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!se(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:se(e?.direction)?e.direction:null,entityType:se(e?.entityType)?e.entityType:null,entityId:se(e?.entityId)?e.entityId:null,relationType:se(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[_.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[_.required]:[]],relationType:[e.relationType,[_.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.values(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.values(Et),this.rangeUnitTranslationMap=Gt,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:se(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:se(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:se(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!se(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:se(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:se(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:se(e?.centerLongitude)?e.centerLongitude:null,range:se(e?.range)?e.range:null,rangeUnit:se(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:se(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[_.required]],longitudeKeyName:[e.longitudeKeyName,[_.required]],perimeterType:[e.perimeterType,[_.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoFilterConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([_.required]),this.defaultPaddingEnable=!1),t||n!==St.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:se(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[_.required]]})}}e("MessageTypeConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Dn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.TENANT,k.CUSTOMER,k.USER,k.DASHBOARD,k.RULE_CHAIN,k.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:se(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[_.required]]})}}e("OriginatorTypeConfigComponent",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Lr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:pt.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Nr{}e("RuleNodeCoreConfigFilterModule",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Nr,declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}),Nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,decorators:[{type:c,args:[{declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}]}]});class Sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=kt,this.originatorSources=Object.keys(kt),this.originatorSourceTranslationMap=Lt,this.originatorSourceDescTranslationMap=Tt,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.USER,k.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===kt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([_.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===kt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([_.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class qr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[_.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,deps:[{token:R.Store},{token:O.FormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); /** * @license * Copyright Google LLC All Rights Reserved. @@ -6,7 +6,7 @@ System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/fo * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -const Ar=ut({passive:!0});class Mr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return He;const t=Te(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new Ke,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Ar),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Ar)}}),r}stopMonitoring(e){const t=Te(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[{token:dt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Mr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:dt.Platform},{type:t.NgZone}]}});class Er{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,deps:[{token:t.ElementRef},{token:Mr}],target:t.ɵɵFactoryTarget.Directive}),Er.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Er,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,decorators:[{type:u,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Mr}]},propDecorators:{cdkAutofill:[{type:d}]}}); +const Ar=ut({passive:!0});class Mr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return He;const t=Te(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new ze,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Ar),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Ar)}}),r}stopMonitoring(e){const t=Te(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[{token:dt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Mr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:dt.Platform},{type:t.NgZone}]}});class Er{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,deps:[{token:t.ElementRef},{token:Mr}],target:t.ɵɵFactoryTarget.Directive}),Er.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Er,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,decorators:[{type:u,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Mr}]},propDecorators:{cdkAutofill:[{type:d}]}}); /** * @license * Copyright Google LLC All Rights Reserved. @@ -14,7 +14,7 @@ const Ar=ut({passive:!0});class Mr{constructor(e,t){this._platform=e,this._ngZon * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -class Gr{get minRows(){return this._minRows}set minRows(e){this._minRows=Ie(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Ie(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Le(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new Ke,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();je(e,"resize").pipe(Pe(16),we(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,deps:[{token:t.ElementRef},{token:dt.Platform},{token:t.NgZone},{token:$,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Gr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,decorators:[{type:u,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:dt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[$]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); +class Gr{get minRows(){return this._minRows}set minRows(e){this._minRows=Ie(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Ie(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Le(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new ze,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();je(e,"resize").pipe(Pe(16),we(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,deps:[{token:t.ElementRef},{token:dt.Platform},{token:t.NgZone},{token:$,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Gr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,decorators:[{type:u,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:dt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[$]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); /** * @license * Copyright Google LLC All Rights Reserved. @@ -22,4 +22,4 @@ class Gr{get minRows(){return this._minRows}set minRows(e){this._minRows=Ie(e),t * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -class Dr{}Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Dr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,declarations:[Er,Gr],exports:[Er,Gr]}),Dr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,decorators:[{type:c,args:[{declarations:[Er,Gr],exports:[Er,Gr]}]}]});class Vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[_.required]],toTemplate:[e?e.toTemplate:null,[_.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[_.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[_.required]],bodyTemplate:[e?e.bodyTemplate:null,[_.required]]})}prepareInputConfig(e){return{fromTemplate:se(e?.fromTemplate)?e.fromTemplate:null,toTemplate:se(e?.toTemplate)?e.toTemplate:null,ccTemplate:se(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:se(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:se(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:se(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:se(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:se(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class wr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=on;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.copyFrom?rn.METADATA:rn.DATA:se(e?.copyFrom)?e.copyFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Pr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=ln;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[_.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.renameIn)?e?.renameIn:rn.DATA,{renameKeysMapping:se(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[_.required]]})}}e("NodeJsonPathConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Or extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=an;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.deleteFrom)?e?.deleteFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE,this.deduplicationStrategie=wt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Pt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[se(e?.interval)?e.interval:null,[_.required,_.min(1)]],strategy:[se(e?.strategy)?e.strategy:null,[_.required]],outMsgType:[se(e?.outMsgType)?e.outMsgType:null,[_.required]],queueName:[se(e?.queueName)?e.queueName:null,[_.required]],maxPendingMsgs:[se(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e3)]],maxRetries:[se(e?.maxRetries)?e.maxRetries:null,[_.required,_.min(0),_.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1})),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e}),this.deduplicationConfigForm.get("queueName").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Br{}e("RulenodeCoreConfigTransformModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}]}]});class Kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=k}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[_.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class zr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Ur,declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,decorators:[{type:c,args:[{declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}]}]});class Hr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one.","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,deps:[{token:X.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hr,declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,imports:[Q,E,Qn,Nr,ar,br,Br,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,decorators:[{type:c,args:[{declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}]}],ctorParameters:function(){return[{type:X.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +class Dr{}Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Dr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,declarations:[Er,Gr],exports:[Er,Gr]}),Dr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,decorators:[{type:c,args:[{declarations:[Er,Gr],exports:[Er,Gr]}]}]});class Vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[_.required]],toTemplate:[e?e.toTemplate:null,[_.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[_.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[_.required]],bodyTemplate:[e?e.bodyTemplate:null,[_.required]]})}prepareInputConfig(e){return{fromTemplate:se(e?.fromTemplate)?e.fromTemplate:null,toTemplate:se(e?.toTemplate)?e.toTemplate:null,ccTemplate:se(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:se(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:se(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:se(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:se(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:se(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class wr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=on;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.copyFrom?rn.METADATA:rn.DATA:se(e?.copyFrom)?e.copyFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Pr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=ln;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[_.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.renameIn)?e?.renameIn:rn.DATA,{renameKeysMapping:se(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[_.required]]})}}e("NodeJsonPathConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Or extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=an;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.deleteFrom)?e?.deleteFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:zn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE,this.deduplicationStrategie=wt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Pt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[se(e?.interval)?e.interval:null,[_.required,_.min(1)]],strategy:[se(e?.strategy)?e.strategy:null,[_.required]],outMsgType:[se(e?.outMsgType)?e.outMsgType:null,[_.required]],queueName:[se(e?.queueName)?e.queueName:null,[_.required]],maxPendingMsgs:[se(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e3)]],maxRetries:[se(e?.maxRetries)?e.maxRetries:null,[_.required,_.min(0),_.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1})),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e}),this.deduplicationConfigForm.get("queueName").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Br{}e("RulenodeCoreConfigTransformModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}]}]});class zr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=k}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[_.required]]})}}e("RuleChainInputComponent",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Ur,declarations:[zr,Kr],imports:[Q,E,$n],exports:[zr,Kr]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,decorators:[{type:c,args:[{declarations:[zr,Kr],imports:[Q,E,$n],exports:[zr,Kr]}]}]});class Hr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one.","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,deps:[{token:X.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hr,declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,imports:[Q,E,Qn,Nr,ar,br,Br,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,decorators:[{type:c,args:[{declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}]}],ctorParameters:function(){return[{type:X.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From c636ea2c0e5cb6247848ca11e4eeb3974ad6bc06 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 28 Dec 2023 14:51:45 +0200 Subject: [PATCH 18/91] fix_bug: TbDateTests -> JDK ver --- .../script/api/tbel/TbDateTest.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 120a776c1a..1f52ff73fb 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -177,8 +177,9 @@ class TbDateTest { * For Java 17: * `{ "AM", "PM" }` */ - s = "09:15:30 nachm., So. 10/09/2022"; - d = new TbDate(s, pattern, "de","Europe/Berlin"); + String s_ver = Runtime.version().feature() == 11 ? "09:15:30 nachm., So. 10/09/2022" : + "09:15:30 PM, So. 10/09/2022"; + d = new TbDate(s_ver, pattern, "de","Europe/Berlin"); Assert.assertEquals("2022-10-09T19:15:30Z", d.toISOString()); s = "02:15:30 пп, середа, 4 жовтня 2023 р."; @@ -295,7 +296,9 @@ class TbDateTest { Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("5\u200F/9\u200F/2023 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); + String expected_ver = Runtime.version().feature() == 11 ? "5\u200F/9\u200F/2023 9:04:05 م" : + "5\u200F/9\u200F/2023, 9:04:05 م"; + Assert.assertEquals(expected_ver, d.toLocaleString( "ar-EG", "America/New_York")); Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") @@ -311,8 +314,11 @@ class TbDateTest { .put("timeZone", "Europe/Kiev") .put("dateStyle", "full") .put("timeStyle", "full") - .toString())); - Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() + .toString())); + + expected_ver = Runtime.version().feature() == 11 ? "الثلاثاء، 5 سبتمبر 2023 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية" : + "الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية"; + Assert.assertEquals(expected_ver, d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") @@ -381,8 +387,9 @@ class TbDateTest { // With pattern + locale - ok String pattern = "hh:mm:ss a, EEE M/d/uuuu"; - stringDateRFC_1123 = "09:15:30 nachm., So. 10/09/2022"; - d = new TbDate(stringDateRFC_1123 , pattern, "de"); + String stringDate_ver_RFC_1123 = Runtime.version().feature() == 11 ? "09:15:30 nachm., So. 10/09/2022" : + "09:15:30 PM, So. 10/09/2022"; + d = new TbDate(stringDate_ver_RFC_1123 , pattern, "de"); Assert.assertEquals("2022-10-09 21:15:30", d.toLocaleString()); // failed TZ From abfcf32c54e2705171d93abbb563fbdec97def5d Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 28 Dec 2023 17:55:56 +0200 Subject: [PATCH 19/91] replaced slow query with multi-call of indexed query --- .../update/DefaultDataUpdateService.java | 10 +++++++++- .../server/dao/rule/RuleChainService.java | 4 ++++ .../server/dao/rule/BaseRuleChainService.java | 10 ++++++++++ .../server/dao/rule/RuleNodeDao.java | 2 ++ .../server/dao/service/Validator.java | 15 ++++++++++++++- .../server/dao/sql/rule/JpaRuleNodeDao.java | 10 ++++++++++ .../dao/sql/rule/RuleNodeRepository.java | 7 ++++++- .../dao/sql/rule/JpaRuleNodeDaoTest.java | 19 +++++++++++++++++++ 8 files changed, 74 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 7d08fdca00..d0f45ac06c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -313,9 +313,17 @@ public class DefaultDataUpdateService implements DataUpdateService { } private List getRuleNodesIdsWithTypeAndVersionLessThan(String type, int toVersion) { + var ruleNodeIds = new ArrayList(); + for (int v = toVersion - 1; v >= 0; v--) { + ruleNodeIds.addAll(getRuleNodesIdsWithTypeAndVersion(type, v)); + } + return ruleNodeIds; + } + + private List getRuleNodesIdsWithTypeAndVersion(String type, int version) { var ruleNodeIds = new ArrayList(); new PageDataIterable<>(pageLink -> - ruleChainService.findAllRuleNodeIdsByTypeAndVersionLessThan(type, toVersion, pageLink), DEFAULT_PAGE_SIZE + ruleChainService.findAllRuleNodeIdsByTypeAndVersion(type, version, pageLink), DEFAULT_PAGE_SIZE ).forEach(ruleNodeIds::add); return ruleNodeIds; } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 532da4ac00..03886bfecc 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -100,10 +100,14 @@ public interface RuleChainService extends EntityDaoService { PageData findAllRuleNodesByType(String type, PageLink pageLink); + @Deprecated(forRemoval = true, since = "3.6.3") PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink); + @Deprecated(forRemoval = true, since = "3.6.3") PageData findAllRuleNodeIdsByTypeAndVersionLessThan(String type, int version, PageLink pageLink); + PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink); + List findAllRuleNodesByIds(List ruleNodeIds); RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 6257bb0420..5a6d0c1d74 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -81,6 +81,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validatePositiveNumber; +import static org.thingsboard.server.dao.service.Validator.validateNonNegativeNumber; import static org.thingsboard.server.dao.service.Validator.validateString; /** @@ -737,6 +738,15 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return ruleNodeDao.findAllRuleNodeIdsByTypeAndVersionLessThan(type, version, pageLink); } + @Override + public PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink) { + log.trace("Executing findAllRuleNodeIdsByTypeAndVersion, type {}, pageLink {}, version {}", type, pageLink, version); + validateString(type, "Incorrect type of the rule node"); + validateNonNegativeNumber(version, "Incorrect version. Version should be non-negative!"); + validatePageLink(pageLink); + return ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion(type, version, pageLink); + } + @Override public List findAllRuleNodesByIds(List ruleNodeIds) { log.trace("Executing findAllRuleNodesByIds, ruleNodeIds {}", ruleNodeIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java index b6f2dd097e..4927f2d68d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java @@ -38,6 +38,8 @@ public interface RuleNodeDao extends Dao { PageData findAllRuleNodeIdsByTypeAndVersionLessThan(String type, int version, PageLink pageLink); + PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink); + List findAllRuleNodeByIds(List ruleNodeIds); List findByExternalIds(RuleChainId ruleChainId, List externalIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index d8c4ffddc9..a712f7c775 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -61,7 +61,7 @@ public class Validator { /** - * This method validate long value. If value isn't possitive than throw + * This method validate long value. If value isn't positive than throw * IncorrectParameterException exception * * @param val the val @@ -73,6 +73,19 @@ public class Validator { } } + /** + * This method validate long value. If value is negative than throw + * IncorrectParameterException exception + * + * @param val the val + * @param errorMessage the error message for exception + */ + public static void validateNonNegativeNumber(long val, String errorMessage) { + if (val < 0) { + throw new IncorrectParameterException(errorMessage); + } + } + /** * This method validate UUID id. If id is null than throw * IncorrectParameterException exception diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java index de5ff109d3..655a03caf3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java @@ -89,6 +89,16 @@ public class JpaRuleNodeDao extends JpaAbstractDao imp .mapData(RuleNodeId::new); } + @Override + public PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink) { + return DaoUtil.pageToPageData(ruleNodeRepository + .findAllRuleNodeIdsByTypeAndVersion( + type, + version, + DaoUtil.toPageable(pageLink))) + .mapData(RuleNodeId::new); + } + @Override public List findAllRuleNodeByIds(List ruleNodeIds) { return DaoUtil.convertDataList(ruleNodeRepository.findAllById( diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java index f02072b356..eaccf39072 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -43,7 +43,7 @@ public interface RuleNodeRepository extends JpaRepository Pageable pageable); @Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.type = :ruleType " + - " AND configuration_version < :version " + + " AND r.configuration_version < :version " + " AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))") Page findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType, @Param("version") int version, @@ -55,6 +55,11 @@ public interface RuleNodeRepository extends JpaRepository @Param("version") int version, Pageable pageable); + @Query("SELECT r.id FROM RuleNodeEntity r WHERE r.type = :ruleType AND r.configurationVersion = :version") + Page findAllRuleNodeIdsByTypeAndVersion(@Param("ruleType") String ruleType, + @Param("version") int version, + Pageable pageable); + List findRuleNodesByRuleChainIdAndExternalIdIn(UUID ruleChainId, List externalIds); @Transactional diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java index 2f1c73da01..8cb5974e7d 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java @@ -144,6 +144,25 @@ public class JpaRuleNodeDaoTest extends AbstractJpaDaoTest { assertEquals(10, ruleNodeIds.getData().size()); } + @Test + public void testFindRuleNodeIdsByTypeAndVersion() { + PageData ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0, PREFIX_FOR_RULE_NODE_NAME)); + assertEquals(20, ruleNodeIds.getTotalElements()); + assertEquals(2, ruleNodeIds.getTotalPages()); + assertEquals(10, ruleNodeIds.getData().size()); + + ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0)); + assertEquals(20, ruleNodeIds.getTotalElements()); + assertEquals(2, ruleNodeIds.getTotalPages()); + assertEquals(10, ruleNodeIds.getData().size()); + + // test - search text ignored + ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0, StringUtils.randomAlphabetic(5))); + assertEquals(20, ruleNodeIds.getTotalElements()); + assertEquals(2, ruleNodeIds.getTotalPages()); + assertEquals(10, ruleNodeIds.getData().size()); + } + @Test public void testFindAllRuleNodeByIds() { var fromUUIDs = ruleNodeIds.stream().map(RuleNodeId::new).collect(Collectors.toList()); From 7c42bb72138536c4f78351c1c992ec0d1780d8ea Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 29 Dec 2023 10:55:38 +0200 Subject: [PATCH 20/91] Change for loop to iterate forwards --- .../server/service/install/update/DefaultDataUpdateService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index d0f45ac06c..a973ec023b 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -314,7 +314,7 @@ public class DefaultDataUpdateService implements DataUpdateService { private List getRuleNodesIdsWithTypeAndVersionLessThan(String type, int toVersion) { var ruleNodeIds = new ArrayList(); - for (int v = toVersion - 1; v >= 0; v--) { + for (int v = 0; v < toVersion; v++) { ruleNodeIds.addAll(getRuleNodesIdsWithTypeAndVersion(type, v)); } return ruleNodeIds; From 5e471364de2ba0263d62a144376174bcd0176b26 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 2 Jan 2024 13:58:16 +0200 Subject: [PATCH 21/91] changed fixedPool to newWorkStealingPool --- .../java/org/thingsboard/server/queue/sqs/TbAwsSqsAdmin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsAdmin.java b/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsAdmin.java index 1c70302d00..3ccbc229a0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsAdmin.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsAdmin.java @@ -26,6 +26,8 @@ import com.amazonaws.services.sqs.model.CreateQueueRequest; import com.amazonaws.services.sqs.model.GetQueueUrlResult; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.common.util.ExecutorProvider; +import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.queue.TbQueueAdmin; import org.thingsboard.server.queue.util.PropertyUtils; @@ -55,7 +57,7 @@ public class TbAwsSqsAdmin implements TbQueueAdmin { AWSCredentials awsCredentials = new BasicAWSCredentials(sqsSettings.getAccessKeyId(), sqsSettings.getSecretAccessKey()); credentialsProvider = new AWSStaticCredentialsProvider(awsCredentials); } - producerExecutor = Executors.newFixedThreadPool(sqsSettings.getThreadPoolSize(), ThingsBoardThreadFactory.forName("aws-sqs-queue-executor")); + producerExecutor = ThingsBoardExecutors.newWorkStealingPool(sqsSettings.getThreadPoolSize(), "aws-sqs-queue-executor"); sqsClient = AmazonSQSClientBuilder.standard() .withCredentials(credentialsProvider) From 4a26fad0a53abb37cf6eaacd42a14d014619fb9a Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 2 Jan 2024 15:31:30 +0200 Subject: [PATCH 22/91] Revert "replaced slow query with multi-call of indexed query" This reverts commit abfcf32c54e2705171d93abbb563fbdec97def5d and 7c42bb72138536c4f78351c1c992ec0d1780d8ea. --- .../update/DefaultDataUpdateService.java | 10 +--------- .../server/dao/rule/RuleChainService.java | 4 ---- .../server/dao/rule/BaseRuleChainService.java | 10 ---------- .../server/dao/rule/RuleNodeDao.java | 2 -- .../server/dao/service/Validator.java | 15 +-------------- .../server/dao/sql/rule/JpaRuleNodeDao.java | 10 ---------- .../dao/sql/rule/RuleNodeRepository.java | 7 +------ .../dao/sql/rule/JpaRuleNodeDaoTest.java | 19 ------------------- 8 files changed, 3 insertions(+), 74 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index a973ec023b..7d08fdca00 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -313,17 +313,9 @@ public class DefaultDataUpdateService implements DataUpdateService { } private List getRuleNodesIdsWithTypeAndVersionLessThan(String type, int toVersion) { - var ruleNodeIds = new ArrayList(); - for (int v = 0; v < toVersion; v++) { - ruleNodeIds.addAll(getRuleNodesIdsWithTypeAndVersion(type, v)); - } - return ruleNodeIds; - } - - private List getRuleNodesIdsWithTypeAndVersion(String type, int version) { var ruleNodeIds = new ArrayList(); new PageDataIterable<>(pageLink -> - ruleChainService.findAllRuleNodeIdsByTypeAndVersion(type, version, pageLink), DEFAULT_PAGE_SIZE + ruleChainService.findAllRuleNodeIdsByTypeAndVersionLessThan(type, toVersion, pageLink), DEFAULT_PAGE_SIZE ).forEach(ruleNodeIds::add); return ruleNodeIds; } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 03886bfecc..532da4ac00 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -100,14 +100,10 @@ public interface RuleChainService extends EntityDaoService { PageData findAllRuleNodesByType(String type, PageLink pageLink); - @Deprecated(forRemoval = true, since = "3.6.3") PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink); - @Deprecated(forRemoval = true, since = "3.6.3") PageData findAllRuleNodeIdsByTypeAndVersionLessThan(String type, int version, PageLink pageLink); - PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink); - List findAllRuleNodesByIds(List ruleNodeIds); RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 5a6d0c1d74..6257bb0420 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -81,7 +81,6 @@ import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validatePositiveNumber; -import static org.thingsboard.server.dao.service.Validator.validateNonNegativeNumber; import static org.thingsboard.server.dao.service.Validator.validateString; /** @@ -738,15 +737,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return ruleNodeDao.findAllRuleNodeIdsByTypeAndVersionLessThan(type, version, pageLink); } - @Override - public PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink) { - log.trace("Executing findAllRuleNodeIdsByTypeAndVersion, type {}, pageLink {}, version {}", type, pageLink, version); - validateString(type, "Incorrect type of the rule node"); - validateNonNegativeNumber(version, "Incorrect version. Version should be non-negative!"); - validatePageLink(pageLink); - return ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion(type, version, pageLink); - } - @Override public List findAllRuleNodesByIds(List ruleNodeIds) { log.trace("Executing findAllRuleNodesByIds, ruleNodeIds {}", ruleNodeIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java index 4927f2d68d..b6f2dd097e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java @@ -38,8 +38,6 @@ public interface RuleNodeDao extends Dao { PageData findAllRuleNodeIdsByTypeAndVersionLessThan(String type, int version, PageLink pageLink); - PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink); - List findAllRuleNodeByIds(List ruleNodeIds); List findByExternalIds(RuleChainId ruleChainId, List externalIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index a712f7c775..d8c4ffddc9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -61,7 +61,7 @@ public class Validator { /** - * This method validate long value. If value isn't positive than throw + * This method validate long value. If value isn't possitive than throw * IncorrectParameterException exception * * @param val the val @@ -73,19 +73,6 @@ public class Validator { } } - /** - * This method validate long value. If value is negative than throw - * IncorrectParameterException exception - * - * @param val the val - * @param errorMessage the error message for exception - */ - public static void validateNonNegativeNumber(long val, String errorMessage) { - if (val < 0) { - throw new IncorrectParameterException(errorMessage); - } - } - /** * This method validate UUID id. If id is null than throw * IncorrectParameterException exception diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java index 655a03caf3..de5ff109d3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java @@ -89,16 +89,6 @@ public class JpaRuleNodeDao extends JpaAbstractDao imp .mapData(RuleNodeId::new); } - @Override - public PageData findAllRuleNodeIdsByTypeAndVersion(String type, int version, PageLink pageLink) { - return DaoUtil.pageToPageData(ruleNodeRepository - .findAllRuleNodeIdsByTypeAndVersion( - type, - version, - DaoUtil.toPageable(pageLink))) - .mapData(RuleNodeId::new); - } - @Override public List findAllRuleNodeByIds(List ruleNodeIds) { return DaoUtil.convertDataList(ruleNodeRepository.findAllById( diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java index eaccf39072..f02072b356 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -43,7 +43,7 @@ public interface RuleNodeRepository extends JpaRepository Pageable pageable); @Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.type = :ruleType " + - " AND r.configuration_version < :version " + + " AND configuration_version < :version " + " AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))") Page findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType, @Param("version") int version, @@ -55,11 +55,6 @@ public interface RuleNodeRepository extends JpaRepository @Param("version") int version, Pageable pageable); - @Query("SELECT r.id FROM RuleNodeEntity r WHERE r.type = :ruleType AND r.configurationVersion = :version") - Page findAllRuleNodeIdsByTypeAndVersion(@Param("ruleType") String ruleType, - @Param("version") int version, - Pageable pageable); - List findRuleNodesByRuleChainIdAndExternalIdIn(UUID ruleChainId, List externalIds); @Transactional diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java index 8cb5974e7d..2f1c73da01 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDaoTest.java @@ -144,25 +144,6 @@ public class JpaRuleNodeDaoTest extends AbstractJpaDaoTest { assertEquals(10, ruleNodeIds.getData().size()); } - @Test - public void testFindRuleNodeIdsByTypeAndVersion() { - PageData ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0, PREFIX_FOR_RULE_NODE_NAME)); - assertEquals(20, ruleNodeIds.getTotalElements()); - assertEquals(2, ruleNodeIds.getTotalPages()); - assertEquals(10, ruleNodeIds.getData().size()); - - ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0)); - assertEquals(20, ruleNodeIds.getTotalElements()); - assertEquals(2, ruleNodeIds.getTotalPages()); - assertEquals(10, ruleNodeIds.getData().size()); - - // test - search text ignored - ruleNodeIds = ruleNodeDao.findAllRuleNodeIdsByTypeAndVersion( "A", 0, new PageLink(10, 0, StringUtils.randomAlphabetic(5))); - assertEquals(20, ruleNodeIds.getTotalElements()); - assertEquals(2, ruleNodeIds.getTotalPages()); - assertEquals(10, ruleNodeIds.getData().size()); - } - @Test public void testFindAllRuleNodeByIds() { var fromUUIDs = ruleNodeIds.stream().map(RuleNodeId::new).collect(Collectors.toList()); From 360e32684ed8458de375a953998dd258100c92ea Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 2 Jan 2024 15:34:32 +0200 Subject: [PATCH 23/91] added new index for rule nodes ids search query and removed old one --- .../main/data/upgrade/3.6.2/schema_update.sql | 22 +++++++++++++++++++ .../install/SqlDatabaseUpgradeService.java | 3 +++ .../server/dao/rule/RuleChainService.java | 1 + .../server/dao/service/Validator.java | 2 +- .../dao/sql/rule/RuleNodeRepository.java | 2 +- .../resources/sql/schema-entities-idx.sql | 2 +- 6 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update.sql diff --git a/application/src/main/data/upgrade/3.6.2/schema_update.sql b/application/src/main/data/upgrade/3.6.2/schema_update.sql new file mode 100644 index 0000000000..fd64136852 --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update.sql @@ -0,0 +1,22 @@ +-- +-- Copyright © 2016-2023 The Thingsboard Authors +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +-- RULE NODE INDEXES UPDATE START + +DROP INDEX IF EXISTS idx_rule_node_type_configuration_version; +CREATE INDEX IF NOT EXISTS idx_rule_node_id_type_configuration_version ON rule_node(id, type, configuration_version); + +-- RULE NODE INDEXES UPDATE END diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index c2444390f6..4a96d0d2c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -772,6 +772,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } }); break; + case "3.6.2": + updateSchema("3.6.2", 3006002, "3.6.3", 3006003, null); + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 532da4ac00..a8a60bc565 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -100,6 +100,7 @@ public interface RuleChainService extends EntityDaoService { PageData findAllRuleNodesByType(String type, PageLink pageLink); + @Deprecated(forRemoval = true, since = "3.6.3") PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink); PageData findAllRuleNodeIdsByTypeAndVersionLessThan(String type, int version, PageLink pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index d8c4ffddc9..3c238305bd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -61,7 +61,7 @@ public class Validator { /** - * This method validate long value. If value isn't possitive than throw + * This method validate long value. If value isn't positive than throw * IncorrectParameterException exception * * @param val the val diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java index f02072b356..de61422527 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -43,7 +43,7 @@ public interface RuleNodeRepository extends JpaRepository Pageable pageable); @Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.type = :ruleType " + - " AND configuration_version < :version " + + " AND r.configuration_version < :version " + " AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))") Page findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType, @Param("version") int version, diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index df95a50d47..10678509b4 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -93,7 +93,7 @@ CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); -CREATE INDEX IF NOT EXISTS idx_rule_node_type_configuration_version ON rule_node(type, configuration_version); +CREATE INDEX IF NOT EXISTS idx_rule_node_id_type_configuration_version ON rule_node(id, type, configuration_version); CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); From f14e6cdfcae7caed69a70b7c362d6fc2c409e4f6 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 2 Jan 2024 15:56:37 +0200 Subject: [PATCH 24/91] added missing switch case to ThingsboardInstallService --- .../thingsboard/server/install/ThingsboardInstallService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 5ab3b7b28e..8b14d2d8b7 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -276,6 +276,9 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } + case "3.6.2": + log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: From 06e06797b3e0e7d6e638aca226bde98a095beb8b Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 2 Jan 2024 17:30:51 +0200 Subject: [PATCH 25/91] UI: Bar chart with labels widget --- .../json/system/widget_bundles/charts.json | 4 +- .../widget_types/bar_chart_with_labels.json | 30 + ui-ngx/src/app/core/services/time.service.ts | 2 +- ...ar-chart-with-labels-widget.component.html | 36 ++ ...ar-chart-with-labels-widget.component.scss | 105 ++++ .../bar-chart-with-labels-widget.component.ts | 540 ++++++++++++++++++ .../bar-chart-with-labels-widget.models.ts | 112 ++++ .../widget/widget-components.module.ts | 9 +- 8 files changed, 833 insertions(+), 5 deletions(-) create mode 100644 application/src/main/data/json/system/widget_types/bar_chart_with_labels.json create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index 14c09d3fc4..4a3240fdd2 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -2,10 +2,9 @@ "widgetsBundle": { "alias": "charts", "title": "Charts", - "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC91BMVEX////K5vz/wQchlvP0QzZgfYtMr1C20ujl5eUAAADi4uL/ySX9/v7/9+Dg4OA8o/TK2eT+6Ob1Wk7q9f7x8fHw8PHy8/L5+vn09PTT2t/p6ekznvRfs/b+wxHLy8v8/Pz/6KL///3+8/JRsVX6+/vq9uqTw+rn5+diuWVNq/bk5OTY2NjNzc2+vr6lzqfqop3u1Yr/wgzD4/w2oPSs2Pv4+Pnj4+S83/v8xBj/wgr0+v5itfdGqPX/1lv29vZUrvXHx8fH5fx2vvgunPTO5OvQ4+Oryd35xSG23fuRy/qAw/n39/jt7e3U4NK3t7eqqqprufdasfY/pPXL5PHu7u7r6+vf3t3/8srW3sjCwsK6urqxsbGw2vum1fuGxvn//fj/+urtzVf3/P/i8v6g0vvL5vqa0PqMyfns7Ozm5ubl1IL/333p0nLtz1/zyj/7/f/S6v17wfjM5fR4uevS0tJtiJX/3HLq0Wrxy0b1yTj/zDD/xhn9/v/u9/7/+PgpmvT//PPS4dj8w77/663c2qnm03yXzvpwu/dmt/fv7+/m6+2uz+ra4eX93tzV1dX/7LOurq6tra3g15j/4of/2WfvzFH1V0v/0kj0STz3yDH5xyjZ7f2gyerR4t7/9tzb3Nv/9dT61tPY3b/Z3Lrb27KMoavf2J92j5v/5JPrz2P2ZFn/xx++4fvr7/Dg6Ou+ztD8zcquvcT/8MKarbakpKSCmqT5n5iTz5Zmgo/5kIn3cWfpx0z1T0P/zz7U6/3P4+bO3ObO19vF0tq80dm6x82jtLz/7rni1YyJy4zc7/3O6Pz+7uz94d/Y7tm437qx3LPIz7P6sauo1ar/5pv6opuRkZHi1o97xH7aynr4gHdpvGzhymZbtl7zxC36wRC30ui30uTM1Njz69TM6M3F5cbC5MPDz7/p3bt/q52huI64wIf4gXjfzG67umTVvUDk8+Tm5N3a185yss2TwMjCz8T7ta/7s610qaWOr5PSy5H4hn33fnX3eG83NCs7AAAOvklEQVR42tzaSYyLYRzH8Z9SaV6P19a+7+u1VKmUWhJLK7baDpY2StKZCSNmwsFMHJDgYM84WGIZIUgkloMQYt8FsUessUWIiy0ODk4ccDDzvG2fvn3eeVvK+758LxKHJ/30eZ63/+kM/p+ICGVhHA5r9Gj0m7wQv1LlHiRrt8BZSae7kiSS+IWk55WhLXAWRIY4uW/fLaiHTFBsZdO9k5OOgRApJAiCCqm+78LTNZVQwoIQTcgoIlJfL/abPBpEEPYIf6kwiioeEqMpGbToQpLqGknjasWoj6D4BNhYUBVDMpqK+MSw8i9A4kLB1+kvExPE4ZBYOORHEUmiShwMkbmXZ0ZZ51QIUcUg8lPWb4hh2TAYlBDjjoTEREnvOnrs1JlFbre7Izo0b96p95qJQ5ZDlz+sOhCSEAhYwWunGgw0Ckk3YmazZfrzJTsM4hdSYB29pSkYhDVo0q5csCg5CiKLEWTbsN/NYhDW8LvIRjwJB0EiYpDtRobBQ1hTryCbqv5VyKpufKthnCISpIvfYgADCGssu/gpz9+EtHbxtYJhceboeMBtDmF1moBMXo8jIHLWQU5wCAbhGzsruyeqAyDBcj+0lP1uMwhf79lIV1ZjO4RkPwmOHHCbQ/gGZe+8R7Ib4lGgtX6RuxCEb9yY7PsRtBfiVZmjMIRvZbPsTbMVIovcuTKF8I2bz94SGyGZAxE84y4Owjcoc+PDEfsgUhm0TrmLhfD1ngWaX7QNQjKfIDfdxUP4xkKrxmcXJKSkL/r5kiDNh0BLJPZAiJj+94y7NEin5eyk2gFRFdCOuUuA0BY0uSVXO/ONLR1iuCGxRSVA0s0HzZuA1rTInul0+bbN+dr8YUiZBNoJd+mQztASQSt/LiWRtAoighZfVAIkW7Pc0xqsnC7Vo94iSCTENqR0yPDM9yp0Qyqfd7VuR2plNEYWlQJhzdZd900Nd6QcRBBuGM0Cwq/00QAyXhDC+SfrmvvPQOaAts4HliU7Ele5b35KgXSeARqJWg1RY0hHNtw6UBJk5fDBy9lGWw0RQVtVrQ0pJ8zHeFPFMO7qWQkRQOvmWtKNs/CQQgqWlLASwh6+I+n/P9UsR26e+QXIuClMwSJRayFeH2itXFqHD7bmLGaQTmOHzAMtRKBLtBaiRrQr4mIt3do6oFn2F4CMGNxhHpt0FOgSfhsS6G5QIYhA0FiFi8Ysu6lFub7/fFOQUUP0ByqmQleU/C6kXQu+9gUg7K7n12XuXmqJpS16yKgJwwpcCqgxOyBbXQYNWKxZ4m9Onc+FrB04CwD87849MPnZKSXZAVnsMm7otopA+hdX5zXIlGZUEXx37nXLlg9NID6vHZBtrqbbVlGlWdZj2Hx6ueX3dxoUDZ0zgUgpOyAjXaaNPFmFTPKHOz2oogBEqXEgpKEdt1c1Kh6+oIp0d0wgcdWZEJerNQDygikK7UjCaXck3UGgbgXkHrmQJ2Z3ZJ0dkLmFj1YAG3deAB7kQj6YQNZJdkAOFnJ0WYUVh1q0qAP650B6mkASiqUQEbTNhSAVwIWG9S61A3mVdbxCTsFa6ArJlkI8fjS2t4BjLlBHF7wYgJSFPOI/N1gCLIXUKNrA2cXUsSSAdpe0FZ8B79OOHhJy8sjQJVoJYQ/Jy6aQavgvZpY8DtwxeGZBhK0Qf5gbtvg2A2ezS27vDj8dUHrptkD2QJccshLC3rjbZgMKsK8F6yXwufFgPTCZ2oGEZDEkrN32qqYvyeEqdG+fu+hX4BGdfM1OlkCA2OnToX7TR1sD8fkKDSm7ge+6RXduBHnxiPstJA+TUn02JZG0AsIuyWaT0eRxC32HVsAPfSIB+K/GlUqyBfVWQNhLqFpqMprkL3sBeUkq9IUiAOTTHimpbgHxeq8bQbzGbTSAbPe+NYJ4vRIypbzcuMWNJlx10EXKidHDN9a3r6D0jYP4fIYQn3H7jCA+Q4jP50UmIoBW3cVkNNGljSq5qRL0KWVgWXS0EPU3Pcov1kYTvosBsGJh5BUO2gBRVG5LuNGE7xn/9wasoAAbIBBJU7ekGoH0aMK3jzkiyKs2bgOEfQasasWPJs+MDJlRRSss8X88DDsgbEtOmowmfC9B8/iQXyhmE0QJQWsxP5qY9AUAiXqRnyzAJgiiMmhVl/WjySdjARtVEFXAJcjFQnr24HtVCiQoQmv3UpPRhMVGFQIuSUXRkJZ8vUqBoMwHrYrMM/hyAPe50cR0VGEPYxshEGVorR6qfRNfDdz7VMCxvQ58Qgx2QvwiyUgGuBraisaOHzJhXDq7AnypGtgKgVKLrITOvLRA3cWmduPsPRgUEWAzBGoC6SoOL61Gto1n2/PPq5d1VTAqWE5sh6B2HdK1Pgld9x9/O7QzuxU/zh5fAeP85TLsh/xk545xGgaCAIr+Eo1GUzn2apsVkoUlF0Bjl1wASsgZnKOk4AZIKDfIPaDiBtyEDhdZkLPVRPKrd4uv3WKqYaz52/XH6+F4PHzmG+apy0OIWqDMfN9FCNpXlEv2gJMQ6CZKNdbgJ4S4U4rU1uIphGANBWKv+Aoh2abgW1XgLQSmMx9FozR4DKEdO2WxYDX4DIFgUcnJn/QbArXFtHTBgOsQCCKV8o+hs0nBfQjos437RI6GznYDcBEhQNr01k+hZaaP+87sZWAxFfm+OfUm77envmR7lyHb+wyRnuVSeLoy+TXGamC1Wq1WPxoFtAfR4rpyDpE6ugxDHZSIy4EBw1AHfaAYcQDHCCemLMcQEULij3pkUAiNeoR8odq04eERE2ljz2HgkZOBNrHmxkY09wgHBtCmppBZsXMxOzu7mvMBqhuvTc8Y6Q4K9GAEgULNfOI15u8zKU6vISpGtHUdSmhfIQq3G6cxQkGgF1Eaa43S2m3qg6yLNWWsiPGIhLa2ro4OjT1iIh3QzQgDRkEmBDQKm3ta8ztrdnilGDEysjsG2CQT4REdHm1dGsfIbHtNE0Z2RjgwkZ6NW2NyoWY9v0xhmwdUMUijl/Ep4jM7J608YhUnHQd2DwKkB1nh0lhg7BRrhFAJ1dgmHTPgxe8afhlzqHsQIMAaV5Eg3YasDq7RxDhuYD0i3M6fBncPAjhqtmHVaOIci6QKWaO5ZkDSAHkE0N7ZhTQVhnF879NFRcSCPoiOZxREMLKLbdHO2sbcV/uAlXOQm87VdHMwp+kMt5lR4lZCYmBJaFqhIklR0K2UQZDUVRBEEH1c9UVFX1DdtffMebZ5ds5ZlJT0v5j4+Pzf9/zeZ+/zvuzCdZ3f2SY1GuSIBQRZCT2LMVQ1goqAIHmZ7ujig6zx+nTpzkl3HVYQ1KhYW2g8dFKqZLIWGg1V59lnrP8jIA3WkNOoKLMHrrI9D6M23aF8426nU464QJCNkOPELfm9xKsm+n4XyO61Da16pbfuREhNEM62xuILy0iv8+WN1aA5qUeI21inCIhEq2+SQ9ozPZe24FpYK41Om5ynIq1r+UBslU6pRmxcdowQa3ROdaUh2/4FgKCr4hERo1sKuwCjtcrecwQyknX63377HMKF5wZpIKR93CCNGltj3U7rKZQrbhB3YpxZX+M9UVZywiZoBVzvAbSrXz3sOGeZwxnyh5Mf8RA1+z0Vkh0Lb7994vYy3S6ui+cpYs9yLPzKiDP0lQKYvp4NtYv75oYaMW7jMDJ6+RSefb+9YvvzdkLcvuPHu+kMzqfMN0tI0lpQkXqdAek1Po6KXHs9rUpMCFhFJmS2QIIEMuyaC/VWzr1FxV5OY1YDJAw5fAq7QmO3ZkvknkxN0Q8lkeCKFIJ09arRjOtUVV0RkAM92meA1TImHMQ0BC1RczOAJZkJyTUB3HYNGiUSAGLyA8SiCDW25Z02XHvk4N237+MWUD198noNC8iWGx1HMMMj84Al/eOBQJBoCwyZ8D5pSZscdMhKINFutU6OBIC4h4FKMiFukOPVPU3aThnQolT4dfjs5ku5IFuqO64AwIc3ZrqyYQpg0CEEJDgIFtqDgpMUqGImnBVQtEp79UzWneRUbDzKMlYwrIKWUSQIpOPcKsjI8uHdwNgMcj0Ix+k30BHt5eoDdNKlCM7pPLNHKs8WPEUCNHfzg8SAmgc2RWRADbzAx/UyO8rKMRun144cHDAXjGWOA6SCSBiICvdmbdPmahexc94Q/PJGe4Ue/VzT3TOdALCqqVrkFStzVjFCgmpqlAfkMZBuxMgRB3g6hpA+gGhFxyPDuJvGH4UTkFYi5Q4yY01QYBlHSCDIw9OZfxpzngjkGtSVXRc2n8UIuDbNN9I5rTQpM6w5JgNZZIYLZABUE/mRiWEAfwbfPOknAYCaSt7J/bU5acpsrgjA4AwSDJK9eYtteQa9LkQ3gNNNN7WnD6ygM04ULn93MwCZMhUFSapgsjAWfUy3YjdTAmzMK5AqPutY3p0A2SxCpYLsltoLDMrcJpz21Et9LMM6/ABU2MU+0xgJj1m2DW7FMmZTFBi7Z+P4jxYKht2oZJBDZZULDF5CngPS1dvLPiyNkjKxzOSgIMbeWN0JGI4lXcUe0TURswD4Tah0EINTv9AQUNxjQHxSfbFhx1pwVUyFM41awB9kB0HBbp52F3wwgVDpICGNnM0QqjqaBdkpVnIMOzYIQEbMuSF8oMejLI8oOCQMpEJS0T//cVCdWMluMOjqMyDPCS/3sG6M8sTMBFz0gf7nQTb09+8ol2AQfJ8dKXbx1JWtwLpNbOO96r6cBpA9yd5xX0yD5TpL1u8MbccgtfvnP6BrJeqKksulNtzSNO1ClszhV4Fs7rSfAqr7ty4//x5pUDRyGJRir6hLfVLgTI7mOZQIUG60yCAaH6fBS9y36/SCZ8IoqqkUyMbRYoPYeAwBY9XVUmYajeHzbBItOgivwWYtcabRCPkI/YUgvxAyoSUCgv6D/AdZEiB79y4REI9niYAsmYrQWvkPS5SvlSJW/SNZS1F4q/CrZoeApNr15fv5szySDQKmlJSXe0oD8QjKr60VkLR9fW0Nf9bGw+US/qxNnq2SP1KRGgFJF9d5BKTt6z+8jz+rQlJzmCflJ6e3vqMkTdRjAAAAAElFTkSuQmCC", + "image": "tb-image:Y2hhcnRzX3N5c3RlbV9idW5kbGVfaW1hZ2UucG5n:IkNoYXJ0cyIgc3lzdGVtIGJ1bmRsZSBpbWFnZQ==;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC91BMVEX////K5vz/wQchlvP0QzZgfYtMr1C20ujl5eUAAADi4uL/ySX9/v7/9+Dg4OA8o/TK2eT+6Ob1Wk7q9f7x8fHw8PHy8/L5+vn09PTT2t/p6ekznvRfs/b+wxHLy8v8/Pz/6KL///3+8/JRsVX6+/vq9uqTw+rn5+diuWVNq/bk5OTY2NjNzc2+vr6lzqfqop3u1Yr/wgzD4/w2oPSs2Pv4+Pnj4+S83/v8xBj/wgr0+v5itfdGqPX/1lv29vZUrvXHx8fH5fx2vvgunPTO5OvQ4+Oryd35xSG23fuRy/qAw/n39/jt7e3U4NK3t7eqqqprufdasfY/pPXL5PHu7u7r6+vf3t3/8srW3sjCwsK6urqxsbGw2vum1fuGxvn//fj/+urtzVf3/P/i8v6g0vvL5vqa0PqMyfns7Ozm5ubl1IL/333p0nLtz1/zyj/7/f/S6v17wfjM5fR4uevS0tJtiJX/3HLq0Wrxy0b1yTj/zDD/xhn9/v/u9/7/+PgpmvT//PPS4dj8w77/663c2qnm03yXzvpwu/dmt/fv7+/m6+2uz+ra4eX93tzV1dX/7LOurq6tra3g15j/4of/2WfvzFH1V0v/0kj0STz3yDH5xyjZ7f2gyerR4t7/9tzb3Nv/9dT61tPY3b/Z3Lrb27KMoavf2J92j5v/5JPrz2P2ZFn/xx++4fvr7/Dg6Ou+ztD8zcquvcT/8MKarbakpKSCmqT5n5iTz5Zmgo/5kIn3cWfpx0z1T0P/zz7U6/3P4+bO3ObO19vF0tq80dm6x82jtLz/7rni1YyJy4zc7/3O6Pz+7uz94d/Y7tm437qx3LPIz7P6sauo1ar/5pv6opuRkZHi1o97xH7aynr4gHdpvGzhymZbtl7zxC36wRC30ui30uTM1Njz69TM6M3F5cbC5MPDz7/p3bt/q52huI64wIf4gXjfzG67umTVvUDk8+Tm5N3a185yss2TwMjCz8T7ta/7s610qaWOr5PSy5H4hn33fnX3eG83NCs7AAAOvklEQVR42tzaSYyLYRzH8Z9SaV6P19a+7+u1VKmUWhJLK7baDpY2StKZCSNmwsFMHJDgYM84WGIZIUgkloMQYt8FsUessUWIiy0ODk4ccDDzvG2fvn3eeVvK+758LxKHJ/30eZ63/+kM/p+ICGVhHA5r9Gj0m7wQv1LlHiRrt8BZSae7kiSS+IWk55WhLXAWRIY4uW/fLaiHTFBsZdO9k5OOgRApJAiCCqm+78LTNZVQwoIQTcgoIlJfL/abPBpEEPYIf6kwiioeEqMpGbToQpLqGknjasWoj6D4BNhYUBVDMpqK+MSw8i9A4kLB1+kvExPE4ZBYOORHEUmiShwMkbmXZ0ZZ51QIUcUg8lPWb4hh2TAYlBDjjoTEREnvOnrs1JlFbre7Izo0b96p95qJQ5ZDlz+sOhCSEAhYwWunGgw0Ckk3YmazZfrzJTsM4hdSYB29pSkYhDVo0q5csCg5CiKLEWTbsN/NYhDW8LvIRjwJB0EiYpDtRobBQ1hTryCbqv5VyKpufKthnCISpIvfYgADCGssu/gpz9+EtHbxtYJhceboeMBtDmF1moBMXo8jIHLWQU5wCAbhGzsruyeqAyDBcj+0lP1uMwhf79lIV1ZjO4RkPwmOHHCbQ/gGZe+8R7Ib4lGgtX6RuxCEb9yY7PsRtBfiVZmjMIRvZbPsTbMVIovcuTKF8I2bz94SGyGZAxE84y4Owjcoc+PDEfsgUhm0TrmLhfD1ngWaX7QNQjKfIDfdxUP4xkKrxmcXJKSkL/r5kiDNh0BLJPZAiJj+94y7NEin5eyk2gFRFdCOuUuA0BY0uSVXO/ONLR1iuCGxRSVA0s0HzZuA1rTInul0+bbN+dr8YUiZBNoJd+mQztASQSt/LiWRtAoighZfVAIkW7Pc0xqsnC7Vo94iSCTENqR0yPDM9yp0Qyqfd7VuR2plNEYWlQJhzdZd900Nd6QcRBBuGM0Cwq/00QAyXhDC+SfrmvvPQOaAts4HliU7Ele5b35KgXSeARqJWg1RY0hHNtw6UBJk5fDBy9lGWw0RQVtVrQ0pJ8zHeFPFMO7qWQkRQOvmWtKNs/CQQgqWlLASwh6+I+n/P9UsR26e+QXIuClMwSJRayFeH2itXFqHD7bmLGaQTmOHzAMtRKBLtBaiRrQr4mIt3do6oFn2F4CMGNxhHpt0FOgSfhsS6G5QIYhA0FiFi8Ysu6lFub7/fFOQUUP0ByqmQleU/C6kXQu+9gUg7K7n12XuXmqJpS16yKgJwwpcCqgxOyBbXQYNWKxZ4m9Onc+FrB04CwD87849MPnZKSXZAVnsMm7otopA+hdX5zXIlGZUEXx37nXLlg9NID6vHZBtrqbbVlGlWdZj2Hx6ueX3dxoUDZ0zgUgpOyAjXaaNPFmFTPKHOz2oogBEqXEgpKEdt1c1Kh6+oIp0d0wgcdWZEJerNQDygikK7UjCaXck3UGgbgXkHrmQJ2Z3ZJ0dkLmFj1YAG3deAB7kQj6YQNZJdkAOFnJ0WYUVh1q0qAP650B6mkASiqUQEbTNhSAVwIWG9S61A3mVdbxCTsFa6ArJlkI8fjS2t4BjLlBHF7wYgJSFPOI/N1gCLIXUKNrA2cXUsSSAdpe0FZ8B79OOHhJy8sjQJVoJYQ/Jy6aQavgvZpY8DtwxeGZBhK0Qf5gbtvg2A2ezS27vDj8dUHrptkD2QJccshLC3rjbZgMKsK8F6yXwufFgPTCZ2oGEZDEkrN32qqYvyeEqdG+fu+hX4BGdfM1OlkCA2OnToX7TR1sD8fkKDSm7ge+6RXduBHnxiPstJA+TUn02JZG0AsIuyWaT0eRxC32HVsAPfSIB+K/GlUqyBfVWQNhLqFpqMprkL3sBeUkq9IUiAOTTHimpbgHxeq8bQbzGbTSAbPe+NYJ4vRIypbzcuMWNJlx10EXKidHDN9a3r6D0jYP4fIYQn3H7jCA+Q4jP50UmIoBW3cVkNNGljSq5qRL0KWVgWXS0EPU3Pcov1kYTvosBsGJh5BUO2gBRVG5LuNGE7xn/9wasoAAbIBBJU7ekGoH0aMK3jzkiyKs2bgOEfQasasWPJs+MDJlRRSss8X88DDsgbEtOmowmfC9B8/iQXyhmE0QJQWsxP5qY9AUAiXqRnyzAJgiiMmhVl/WjySdjARtVEFXAJcjFQnr24HtVCiQoQmv3UpPRhMVGFQIuSUXRkJZ8vUqBoMwHrYrMM/hyAPe50cR0VGEPYxshEGVorR6qfRNfDdz7VMCxvQ58Qgx2QvwiyUgGuBraisaOHzJhXDq7AnypGtgKgVKLrITOvLRA3cWmduPsPRgUEWAzBGoC6SoOL61Gto1n2/PPq5d1VTAqWE5sh6B2HdK1Pgld9x9/O7QzuxU/zh5fAeP85TLsh/xk545xGgaCAIr+Eo1GUzn2apsVkoUlF0Bjl1wASsgZnKOk4AZIKDfIPaDiBtyEDhdZkLPVRPKrd4uv3WKqYaz52/XH6+F4PHzmG+apy0OIWqDMfN9FCNpXlEv2gJMQ6CZKNdbgJ4S4U4rU1uIphGANBWKv+Aoh2abgW1XgLQSmMx9FozR4DKEdO2WxYDX4DIFgUcnJn/QbArXFtHTBgOsQCCKV8o+hs0nBfQjos437RI6GznYDcBEhQNr01k+hZaaP+87sZWAxFfm+OfUm77envmR7lyHb+wyRnuVSeLoy+TXGamC1Wq1WPxoFtAfR4rpyDpE6ugxDHZSIy4EBw1AHfaAYcQDHCCemLMcQEULij3pkUAiNeoR8odq04eERE2ljz2HgkZOBNrHmxkY09wgHBtCmppBZsXMxOzu7mvMBqhuvTc8Y6Q4K9GAEgULNfOI15u8zKU6vISpGtHUdSmhfIQq3G6cxQkGgF1Eaa43S2m3qg6yLNWWsiPGIhLa2ro4OjT1iIh3QzQgDRkEmBDQKm3ta8ztrdnilGDEysjsG2CQT4REdHm1dGsfIbHtNE0Z2RjgwkZ6NW2NyoWY9v0xhmwdUMUijl/Ep4jM7J608YhUnHQd2DwKkB1nh0lhg7BRrhFAJ1dgmHTPgxe8afhlzqHsQIMAaV5Eg3YasDq7RxDhuYD0i3M6fBncPAjhqtmHVaOIci6QKWaO5ZkDSAHkE0N7ZhTQVhnF879NFRcSCPoiOZxREMLKLbdHO2sbcV/uAlXOQm87VdHMwp+kMt5lR4lZCYmBJaFqhIklR0K2UQZDUVRBEEH1c9UVFX1DdtffMebZ5ds5ZlJT0v5j4+Pzf9/zeZ+/zvuzCdZ3f2SY1GuSIBQRZCT2LMVQ1goqAIHmZ7ujig6zx+nTpzkl3HVYQ1KhYW2g8dFKqZLIWGg1V59lnrP8jIA3WkNOoKLMHrrI9D6M23aF8426nU464QJCNkOPELfm9xKsm+n4XyO61Da16pbfuREhNEM62xuILy0iv8+WN1aA5qUeI21inCIhEq2+SQ9ozPZe24FpYK41Om5ynIq1r+UBslU6pRmxcdowQa3ROdaUh2/4FgKCr4hERo1sKuwCjtcrecwQyknX63377HMKF5wZpIKR93CCNGltj3U7rKZQrbhB3YpxZX+M9UVZywiZoBVzvAbSrXz3sOGeZwxnyh5Mf8RA1+z0Vkh0Lb7994vYy3S6ui+cpYs9yLPzKiDP0lQKYvp4NtYv75oYaMW7jMDJ6+RSefb+9YvvzdkLcvuPHu+kMzqfMN0tI0lpQkXqdAek1Po6KXHs9rUpMCFhFJmS2QIIEMuyaC/VWzr1FxV5OY1YDJAw5fAq7QmO3ZkvknkxN0Q8lkeCKFIJ09arRjOtUVV0RkAM92meA1TImHMQ0BC1RczOAJZkJyTUB3HYNGiUSAGLyA8SiCDW25Z02XHvk4N237+MWUD198noNC8iWGx1HMMMj84Al/eOBQJBoCwyZ8D5pSZscdMhKINFutU6OBIC4h4FKMiFukOPVPU3aThnQolT4dfjs5ku5IFuqO64AwIc3ZrqyYQpg0CEEJDgIFtqDgpMUqGImnBVQtEp79UzWneRUbDzKMlYwrIKWUSQIpOPcKsjI8uHdwNgMcj0Ix+k30BHt5eoDdNKlCM7pPLNHKs8WPEUCNHfzg8SAmgc2RWRADbzAx/UyO8rKMRun144cHDAXjGWOA6SCSBiICvdmbdPmahexc94Q/PJGe4Ue/VzT3TOdALCqqVrkFStzVjFCgmpqlAfkMZBuxMgRB3g6hpA+gGhFxyPDuJvGH4UTkFYi5Q4yY01QYBlHSCDIw9OZfxpzngjkGtSVXRc2n8UIuDbNN9I5rTQpM6w5JgNZZIYLZABUE/mRiWEAfwbfPOknAYCaSt7J/bU5acpsrgjA4AwSDJK9eYtteQa9LkQ3gNNNN7WnD6ygM04ULn93MwCZMhUFSapgsjAWfUy3YjdTAmzMK5AqPutY3p0A2SxCpYLsltoLDMrcJpz21Et9LMM6/ABU2MU+0xgJj1m2DW7FMmZTFBi7Z+P4jxYKht2oZJBDZZULDF5CngPS1dvLPiyNkjKxzOSgIMbeWN0JGI4lXcUe0TURswD4Tah0EINTv9AQUNxjQHxSfbFhx1pwVUyFM41awB9kB0HBbp52F3wwgVDpICGNnM0QqjqaBdkpVnIMOzYIQEbMuSF8oMejLI8oOCQMpEJS0T//cVCdWMluMOjqMyDPCS/3sG6M8sTMBFz0gf7nQTb09+8ol2AQfJ8dKXbx1JWtwLpNbOO96r6cBpA9yd5xX0yD5TpL1u8MbccgtfvnP6BrJeqKksulNtzSNO1ClszhV4Fs7rSfAqr7ty4//x5pUDRyGJRir6hLfVLgTI7mOZQIUG60yCAaH6fBS9y36/SCZ8IoqqkUyMbRYoPYeAwBY9XVUmYajeHzbBItOgivwWYtcabRCPkI/YUgvxAyoSUCgv6D/AdZEiB79y4REI9niYAsmYrQWvkPS5SvlSJW/SNZS1F4q/CrZoeApNr15fv5szySDQKmlJSXe0oD8QjKr60VkLR9fW0Nf9bGw+US/qxNnq2SP1KRGgFJF9d5BKTt6z+8jz+rQlJzmCflJ6e3vqMkTdRjAAAAAElFTkSuQmCC", "description": "Display time series data using customizable line and bar charts. Use various pie charts to display the latest values.", "order": 1000, - "externalId": null, "name": "Charts" }, "widgetTypeFqns": [ @@ -13,6 +12,7 @@ "charts.state_chart", "range_chart", "charts.timeseries_bars_flot", + "bar_chart_with_labels", "cards.aggregated_value_card", "charts.bars", "charts.pie", diff --git a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json new file mode 100644 index 0000000000..6120c4f1c5 --- /dev/null +++ b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json @@ -0,0 +1,30 @@ +{ + "fqn": "bar_chart_with_labels", + "name": "Bar chart with labels", + "deprecated": false, + "image": "tb-image:cmFuZ2VfY2hhcnRfc3lzdGVtX3dpZGdldF9pbWFnZS5wbmc=:IlJhbmdlIGNoYXJ0IiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC/VBMVEX////////8/PwAAAD///////+bsfP+wEzu7u73lkzz8/P1eWTT09PN1emRpeOcsvSxsbGQpeLc3NyXl5epqanjXHPLy8tti+OgoKD/wU26urr29vbts0fnkUf39/fIrYP4l02oqKjJroPl5eWUrPPDw8PCwsLJroSQqfKLpfKDn/HU1NSnu/X/tzD/pwNyku//vD//sB3m5ub2jj98mfB2lfD2hTD/rRPu8v3/3qD1fCD3+f7K1vnnjEf1eh30awSWrvOBnfFkhOLld1n1dRX0cxH/9N/1cVvld1jmjEf2izn/qQry9f2Yr/P/+u/+9u+RpuP82r//yGDdM1D3kEPzWD32gSixwfBWeN//2JDzY0v+vkf/siT+5+RBaNr7x6DbYWXxTC96mPD+7N+VqN35tID2emX3oWD3k0fm6/zc5PvV3vq2xveWrfL+8/Hd3d09ZNr/6b/6vZCPj4/2h3TfQl3bKkjaIUD/ujnxQCL0bwrC0PiWqN5Kbt3/79D6zMqGhob/0n/iUWn0aVH+vUPZGjr/tSuwwvZpiOLR0dH+2I97e3v1dWDkcV3fPVnxSCr/qw+Jo/F/m/GLoum3xOj64uZef+H41NoyW9hdfNbJycnxqLT7x5/4no/nb4P/zXDiVm3hS2TlcV3zXEPyUzj+uTTwRCbkbRB+mOaareN5k+FyjuBHbNw4YNn7xr3/47D70LD5t6zumqjngJH/2I+Ojo7lYnf4oWC+mF7utEj2iDTmfSrxRyrunw/kZwLL1vWWrfS/zPORqfP98fKjt/GGofHv7+/+7erK0umHnuKDm+Lf39/t5d7829bm2dT949Dzt8HqwLFse6r4raDsjJz3lIPopHzGpnT4q3DZVmXSNkvnj0LnjD7mgjbjWzHiSzHwRyrunQXv8/3+9POquOWot+Tu4s3u3b3rzrfUxrHu166boa6coK76uKzTvJvoppv6vpDuyYfdboDmkXH1fGffR2H3oV/kbVnnjkHtrTbOIDTiUiLhUCD/rhTuoROM0RHwAAAABXRSTlMg77MAvxFwlo8AAA5CSURBVHja1JtJaBNRGMfj8scXk8MwSYZxoiFhaC9FEQoRA7YHE6K9iMZ4KIoWcTkpqK3oRVH05HISwX1Db66guF48eHHFBfcFQUUQ933BL6PxZZyZRE2+of4aMhPyWvKb73vzf3nQQL9A/z743+lLGoE+Qlea0JLShVA0mFHFwP9Hn0CgL7QwdERgKnGlmY7QBYgNGwY2lleHBjLSNwAIpdlAFPRIQERBsIjcvDGQEUEimqLq0FFysUR4WLKiG5yQiKGiJGIqIJYCKQEGDhV6wAmJCD3VBDWqCxCmrjeBg+7tK06DkQD8Yd3C2ML1YMM/kY2FWM9GsOGfyLLuWOEg2PBPZMW22JotYMM3kYs9sdjbw2DDN5Eta2KxbQWw4ZtIYRmJrAAbfomsXxgjFq4DF36JXCmQB2eQ+CWybHuMKPAFiU8i61bESqy5Ai58EtnYY4l08wWJTyKHuy2R7d3gwieRnmWkwRok/ogsoc6y4FzI84tYsU4wBwm/iBXrP+i5CC74RcqxTnAu5C0RMypgppQ4lCaIlN6CxnKwUBZZcwhsWN/ZE4CeUA3TiCIiEImjoVCs/6T7MNggkXAk1YIo4lGoCaEDiQQIRRGN4fynaWVu3BRskIjRBJ0sbPtaDRR5fm/1jtWrV+/YsXrH+3uCDRJpDpNI5Me+VlwnMYFG8qYz9IvdZ8AFicQjioKmlC4A0JFeNJSuvBRZuxdcBEAIlGcGkUBDWdIVkuy6DCb4c+TqzpmhED0sipvBBL9IMU8WZToXgAd+kSknQhUs7wQP/CKXd1WK5E88BAv8IvnllSKruO6/7CJzFq0KVbJ2ClhgF9nbFbLRdQ4ssIss6LSLFJ+BBXaRYinWZ9LPT3YyBQmviIx19iCpS2QOanK1GCJ4g6R+kQVLUIvO5SE7+SLqgkWkmEcNptwP/c4i1AeDyIGu3VNqDSn+DyL5zp3VZ66M9Zm9WeTcfVpwVJvvtliXInNQBwwiFHU1UkHGOvcaRYqYKoSiAc0mEs2KwB8wZRFF3apdVa8vuRIzfRRZaiAiVMPUDOiq+KN9rQO7an/jo1h3cIJTxCgJIB5FWMR1wBSoTdGax/ku75LIWJ/pU0WEoRr4y32tS1/GjB4zevSYu9eEJ6/vjh5DY8pPNJ6ePl8SPARIIBqZr0ZKFQHiEUATtUXGHh87dtSosaPu7DkrvDh+ZxQNGVt6EHQsne15IngIgKCKGIaigaCDjppMXxz8SW6G55j2oAu58eDBEkGCZExYmCZqc6Qt+JOOHDzYRGOcZPeDgX/OkczEYLJ8iafCnWQ6SNA4G21T8Y9wiGzKyk/WkYE77bN/OPRmkcyx2s2yn2R7u8h4muqybTpa4casScEKkr1SZFbaPn/Hw4VMa9CNzAz8Exwi09sn2q71MbeSXKCquTGpF4lMbfutXxa7lORFeZAcm+xtInTvtZN2KUlrR4VE76zI1Jw9G4h2R0lkrCftKpNmwZ2qic8i0pp2XOtJrQ7brDSoHJ5MH/H6s+NQBQYRucySzHaUJFlhaxPyFMnMgycsIu9ss9irYXJyHtmF0h6tNa69FZ5wiIyjj+hWkun2hs86FX5WJAlXxufavXuLQ2Rqm3s8XIdExrq9raqsAzAvk/XuLQ6RTIcVCcnfS5IdB4kj1muLJI+lPXuLQ4SWWbUTm2I9+bci6dbZXr3FIkLLLHdm58ZV9Elb0FMk7T71KHfq6i1LZG6LQEJrAehovZA4cm62vffleZssiYx15xJlYsZjrlsLhDoo/9dbSjU0s8mAoqlV9rWut5UFHCoTqSQy1r1wisgaUm/VJ6LGof/Y12pW4zoQ9hJxLLNsRtlfJdmU/WsRus3V2VsBEIZm29fyZFMu6E0HlUTG+l+KpDvKi896RDQDKO9r6YDqua91+/iQKuwpb9btue096NYp4capD9Z7Z+va1zJ1VY0rYSoLoWtzI/AQefRgsIOj8vTjSWHx9KRzkDx7IFx4/ONXvr2sT0TTNBEPt8AirCXgwYSVA4hBA0rIM8mIkSixdfKAKgyDC/u+Wu8NHQ4XGp4j32kvYxWFgSiKVsOkVlnyVrARbJYJM1XID6QJWKQT/Qm7VAFBLLbKH1hZ2/iBq6s4WW/MDle8oCHeIeT47ry85MlW96pKyvy8zlntWcNA9rtfb5nMwXoDSOZ0W4Ik211hs7zoxhS5guQKZatbTRdgvQHEVfp/mSZp8yJ60QXSLC82kS0GZF30Acj9u7K9pF0gdaE1kS0SRIyWW0AQA+Mm8OtzkGOqNZEtDgSiT6qoFWhz63OQrXeAlM5v2HBh1dK1AtmDENkiQdwWk0SoE6SxmsgWB5KlQAAnLMg80ZrIFgdiDlw9EOSI/TD1NpmtOg8EqQstDAaudhlcfLHytnDZsqdAkNIE3St6ISBy8Gu5bM2TDEBCxiwuZfIMxNiz+VK21imAhIxZLBOAwF5n+9Z+FQiysp0DCfMkWW169jqbLVN9B4FkTeBtC5yBjyAL11oqTLbyRIeBWMO2KRSClDv9YrYy1wKZDM6f6HKcdIxZ0Hx7qiD35Pn/ua8iprpafLZK40GieBaf39PH0fBjOIUxC6YsXrtSPShZepfrW27rQT4HaqhmIxVHavoF67oKIFz/NY8gdeNn/tBs4evM6Q4SqdHlOAzovcKOKQACl6eytXB/QeLLMR7/kGoFK27DQDQXixzKTgVljxswKo6NwVBsCDgH5wMM/QbfNt18QU495Zz8RdkfyLEsLXT30OveSy+99Bs6ltWVlfHKMnoklhTNyPM0T5ITEtx8uNh7tYbt841vJyL0h4ep2qLfAj7/J/Lm7Y1Mxnv869a18bvWz3O4CBFRtJCIojAKQyyxjkVb7fqlTYTG2IVX7A/bZgc0wzq2n6O5icVza412yhvvc/4zn4Izuv+dBQrX7+aqlDw0kS9PV/xK4yO+OOftZ5xjo6tiwVWdKztdtl0vHY98buK+HUXZ8M7h6XEKjx/36PZ79BxZZRWTAEZBesaxFIGB24KOU2dlYMHWbB4SdLkbJXK3kfewRu1D5NNpYNR8H1ggSrO5dCKSVO7Bu1iK5GKivjOKWFg1su43y4y5EFnn03IBY927JCDzSbzq3KKtQ3YwUtpGCKNEkmU/CphIhHrAJZFGSDtpqCv52hJSbAyRHhkinY0mhAJ8clKZRH5lQwOARVvbhmWrPi/hQiSJjbmSF2dIB5KRJiDC0IBxbaUxO/XytSqYA5FtQe7hvXtlZO8kQ5naosfBMe1pZuNCRMSvSgd0050hECLVctiRaEsHbsoTYkLEkhAfgNG4JHISxMGureSBsf4iaXZAiVA5GsGAKvxOeOPUvs3IGFRbdG43697SH8/IqvCJWGvQbBcC8VVd4vw131hY5lYvkn3SOXybWRNCFzjVip0INVkqPMjrbsAEtLbo3NZyD2/656nEzJaQyvvJBEhiRmHVVir3KL1IyqymRKgTjdV/HwbHzwe1VSa7rnOzV0skZ5QI3bAnhEfU502tLsrBvRcky1QdQ0dKxJ4Qd4CfF32Wp09+epH8q+56WqSG4Wj98yCHlQ1JiCGBQhk6KONpQBD04pxH8DZ7moN4WfbgwF5d8Kh4c0XWb+Dfo2cRVARvfgdP+iH8pdlprKGtioudRztN8vq68zYv/ZPD9OKF1Ej+S4dUvbj9j68jsd4zqmhNs7V3uT7C5SshNVSMRgouHTOqBOe05ZKFB6qOR0KiThDbjWylNxpxkFx7VGeZjLAJrFjPaxUMogwPVPGovbeNrcZI8IeR206ylV7XfHdtN67Y62hJKAZZleKw+pP4n8BASrN16UPkbtwK/+1ohCuAjxpG8nCX34u/vW1Mm1IyZqvlNHp5dz1xEXvEiurXwiRCeaxpe/3LlzA/4xcqERqzNjdpJaZiq6Jv99TxZ2B9MWkKCgJRtTBUaLlZ0YF/+Zj9hMcviKlnmF48Di3rb+DHiFRqyykuQHBcWRD2vn8799/x/Ond27dp8bh79+mnJkctX2M9w4AxP7h/vsbOrMkdnT9/NI/1QRvBbCcaWS2a3MGTJ9Ha0I0slrWPJwdo4nDn4LCuDN3IfFln69UCTbxbrt7WlaEbidmarXZ/NXm0ipXBG6mz9epZwv08+gdvpM7W692EO3wfy4M3ss7WzrOUercXy8M3sliFDnmbUnNEDN8IZSs996YYvpGQreUC3dgAIz5bs94O2QAjPluvDtGDDTBC2Zod7aIHm2BksaJzbx82wch8+XoPfdgEI5jN0IuNMLJYoB/BCJNghpcYG+RGFQ6Dwhz9ODZSSIwFJLh1xTTMa93Z+m1o3cWWJyR98KBZ90a0Xs9r5fTxx/j4uYt9cELSq3mznnHFbDJBlx5y8MgAYe29CUXLgMAFhE72yjF4ZPBQcMcvdGSqMHmgcm/ojqAPR5RgDV1OznNrJlTUI6BEA3csMOGFI6kvpVJq1O1SoZRulzI+SqRdp1/B3wC2sN7dwwmsQM6Q534hWK6hRZVEte/8dsowBVglHVN9jK3SS8tKGtRuLUUuVYdUAO1SmSORdhkJ40VURsy+s4IZWzizfqWo1utdlOa0LTTXtI+K0ikXJFWGWTEqtGxKuVDtUlsY1ioV+7xMpL9rRAluBZ+CT41TiEYs84dkXPi/5YzjWkTpFh95KTPHUh6lYJapdinLmWmVagvjEunvGgGXgjNYIZSORuwEBMWclE6CGZgiSicY8Upa3hNcoJgKE6Vjy/dHHVLIVqkoyVkqzU6hFYrW0dgb4XBvxMgKRVtWH3LrnlJUo1VIioNkGPP4bbhvAFNUEUxyYh66WloRrdKy4JN2qeEGqTQ7i3+EPGnoZLvJvItlSMnTWbb57wJH9RLtM9lpbDpOnc3O/ACb/i1NA1ABvwAAAABJRU5ErkJggg==", + "description": "Displays changes to time-series data over time visualized with color ranges — for example, temperature or humidity readings.", + "descriptor": { + "type": "timeseries", + "sizeX": 8, + "sizeY": 5, + "resources": [], + "templateHtml": "\n", + "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.barChartWidget.onInit();\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.barChartWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '80%',\n embedTitlePanel: true,\n hasAdditionalLatestDataKeys: false,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n", + "settingsSchema": "{}", + "dataKeySettingsSchema": "{}", + "latestDataKeySettingsSchema": "{}", + "settingsDirective": "", + "dataKeySettingsDirective": "", + "latestDataKeySettingsDirective": "", + "hasBasicMode": false, + "basicModeDirective": "", + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2221714000,\"fixedTimewindow\":{\"startTimeMs\":1703599035699,\"endTimeMs\":1703685435699},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"thermostat\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"0px\"}" + }, + "tags": [ + "range", + "color range", + "line chart" + ] +} \ No newline at end of file diff --git a/ui-ngx/src/app/core/services/time.service.ts b/ui-ngx/src/app/core/services/time.service.ts index f9ab858b4f..421b81f8bc 100644 --- a/ui-ngx/src/app/core/services/time.service.ts +++ b/ui-ngx/src/app/core/services/time.service.ts @@ -38,7 +38,7 @@ export interface TimeInterval { const MIN_INTERVAL = SECOND; const MAX_INTERVAL = 365 * 20 * DAY; -const MIN_LIMIT = 7; +const MIN_LIMIT = 1; const MAX_DATAPOINTS_LIMIT = 500; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.html new file mode 100644 index 0000000000..b490802022 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.html @@ -0,0 +1,36 @@ + +
+
+ +
+
+
+
+
+
+
+
{{ legendItem.label }}
+
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss new file mode 100644 index 0000000000..6e57a12d6c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss @@ -0,0 +1,105 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.tb-bar-chart-panel { + width: 100%; + height: 100%; + position: relative; + display: flex; + flex-direction: column; + gap: 16px; + padding: 20px 24px 24px 24px; + > div:not(.tb-bar-chart-overlay) { + z-index: 1; + } + .tb-bar-chart-overlay { + position: absolute; + top: 12px; + left: 12px; + bottom: 12px; + right: 12px; + } + div.tb-widget-title { + padding: 0; + } + .tb-bar-chart-content { + flex: 1; + min-width: 0; + min-height: 0; + display: flex; + flex-direction: column; + gap: 16px; + &.legend-top { + flex-direction: column-reverse; + } + &.legend-right { + flex-direction: row; + } + &.legend-left { + flex-direction: row-reverse; + } + .tb-bar-chart-shape { + flex: 1; + min-width: 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + } + .tb-bar-chart-legend { + display: flex; + justify-content: center; + align-items: center; + align-self: stretch; + flex-wrap: wrap; + column-gap: 24px; + row-gap: 8px; + .tb-bar-chart-legend-item { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + user-select: none; + cursor: pointer; + .tb-bar-chart-legend-item-label { + display: flex; + align-items: center; + gap: 4px; + color: #ccc; + .tb-bar-chart-legend-item-label-circle { + width: 8px; + height: 8px; + border-radius: 50%; + background-color: #ccc; + } + } + } + } + &.legend-right, &.legend-left { + gap: 24px; + .tb-bar-chart-legend { + flex-direction: column-reverse; + justify-content: flex-end; + align-items: stretch; + .tb-bar-chart-legend-item { + flex-direction: row; + justify-content: space-between; + align-items: center; + } + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts new file mode 100644 index 0000000000..62c7209dbd --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -0,0 +1,540 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + Input, + OnDestroy, + OnInit, + Renderer2, + TemplateRef, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { WidgetContext } from '@home/models/widget-component.models'; +import { + backgroundStyle, + ComponentStyle, + DateFormatProcessor, + overlayStyle, + textStyle +} from '@shared/models/widget-settings.models'; +import { ResizeObserver } from '@juggle/resize-observer'; +import * as echarts from 'echarts/core'; +import { Axis } from 'echarts'; +import { formatValue } from '@core/utils'; +import { GridComponent, GridComponentOption, TooltipComponent, TooltipComponentOption } from 'echarts/components'; +import { LabelLayout } from 'echarts/features'; +import { BarChart, BarSeriesOption} from 'echarts/charts'; +import { CanvasRenderer } from 'echarts/renderers'; +import { DataKey, DataSet } from '@shared/models/widget.models'; +import { Observable } from 'rxjs'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import { + barChartWithLabelsDefaultSettings, + BarChartWithLabelsWidgetSettings +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; +import { LabelLayoutOptionCallback } from 'echarts/types/dist/shared'; +import BarSeriesModel from 'echarts/types/src/chart/bar/BarSeries'; + +const axisGetBandWidth = Axis.prototype.getBandWidth; + +Axis.prototype.getBandWidth = function(){ + const series: any[] = this.model?.parentModel?.getSeries(); + if (this.scale.type === 'time' && series?.length && series[0].type === 'series.bar') { + const barWidth = (series[0] as BarSeriesModel).getData().getLayout('size'); + return barWidth * (series.length + 1); + } else { + return axisGetBandWidth.call(this); + } +}; + +echarts.use([ + TooltipComponent, + GridComponent, + BarChart, + LabelLayout, + CanvasRenderer +]); + +type EChartsOption = echarts.ComposeOption< + | TooltipComponentOption + | GridComponentOption + | BarSeriesOption +>; + +type ECharts = echarts.ECharts; + +type NamedDataSet = {name: string; value: [number, any]}[]; + +type BarLabelOption = NonNullable; + +interface BarChartDataItem { + id: string; + dataKey: DataKey; + data: NamedDataSet; + enabled: boolean; +} + +interface BarChartLegendItem { + id: string; + color: string; + label: string; + enabled: boolean; +} + +const toNamedData = (data: DataSet): NamedDataSet => { + if (!data?.length) { + return []; + } else { + return data.map(d => ({ + name: d[0] + '', + value: d + })); + } +}; + +@Component({ + selector: 'tb-bar-chart-with-labels-widget', + templateUrl: './bar-chart-with-labels-widget.component.html', + styleUrls: ['./bar-chart-with-labels-widget.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, AfterViewInit { + + @ViewChild('chartShape', {static: false}) + chartShape: ElementRef; + + settings: BarChartWithLabelsWidgetSettings; + + @Input() + ctx: WidgetContext; + + @Input() + widgetTitlePanel: TemplateRef; + + showLegend: boolean; + legendClass: string; + + backgroundStyle$: Observable; + overlayStyle: ComponentStyle = {}; + + legendItems: BarChartLegendItem[]; + legendLabelStyle: ComponentStyle; + disabledLegendLabelStyle: ComponentStyle; + + private shapeResize$: ResizeObserver; + + private decimals = 0; + private units = ''; + + private dataItems: BarChartDataItem[] = []; + + private drawChartPending = false; + private barChart: ECharts; + private barChartOptions: EChartsOption; + + private tooltipDateFormat: DateFormatProcessor; + + private barLabelOptions: BarLabelOption; + private barLabelLayoutCallback: LabelLayoutOptionCallback; + + constructor(private imagePipe: ImagePipe, + private sanitizer: DomSanitizer, + private renderer: Renderer2, + private cd: ChangeDetectorRef) { + } + + ngOnInit(): void { + this.ctx.$scope.barChartWidget = this; + this.settings = {...barChartWithLabelsDefaultSettings, ...this.ctx.settings}; + + this.decimals = this.ctx.decimals; + this.units = this.ctx.units; + + this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); + this.overlayStyle = overlayStyle(this.settings.background.overlay); + + this.showLegend = this.settings.showLegend; + + if (this.showLegend) { + this.legendItems = []; + this.legendClass = `legend-${this.settings.legendPosition}`; + this.legendLabelStyle = textStyle(this.settings.legendLabelFont); + this.disabledLegendLabelStyle = textStyle(this.settings.legendLabelFont); + this.legendLabelStyle.color = this.settings.legendLabelColor; + } + let counter = 0; + if (this.ctx.datasources.length) { + for (const datasource of this.ctx.datasources) { + const dataKeys = datasource.dataKeys; + for (const dataKey of dataKeys) { + const id = counter++; + const datasourceData = this.ctx.data ? this.ctx.data.find(d => d.dataKey === dataKey) : null; + const namedData = datasourceData?.data ? toNamedData(datasourceData.data) : []; + this.dataItems.push({ + id: id+'', + dataKey, + data: namedData, + enabled: true + }); + if (this.showLegend) { + this.legendItems.push( + { + id: id+'', + label: dataKey.label, + color: dataKey.color, + enabled: true + } + ); + } + } + } + } + + if (this.settings.showTooltip && this.settings.tooltipShowDate) { + this.tooltipDateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.tooltipDateFormat); + } + + const barValueStyle: ComponentStyle = textStyle(this.settings.barValueFont); + delete barValueStyle.lineHeight; + barValueStyle.fontSize = this.settings.barValueFont.size; + barValueStyle.color = this.settings.barValueColor; + + const barLabelStyle: ComponentStyle = textStyle(this.settings.barLabelFont); + delete barLabelStyle.lineHeight; + barLabelStyle.fontSize = this.settings.barLabelFont.size; + barLabelStyle.color = this.settings.barLabelColor; + + this.barLabelOptions = { + show: this.settings.showBarLabel || this.settings.showBarValue, + position: 'insideBottom', + distance: 15, + align: 'left', + verticalAlign: 'middle', + rotate: 90, + formatter: (params) => { + const parts: string[] = []; + if (this.settings.showBarValue) { + const value = formatValue(params.value[1], this.decimals, '', false); + parts.push(`{value|${value}}`); + } + if (this.settings.showBarLabel) { + parts.push(`{label|${params.seriesName}}`); + } + return parts.join(' '); + }, + rich: { + value: barValueStyle, + label: barLabelStyle + } + }; + + this.barLabelLayoutCallback = (params) => { + if (params.rect.width - params.labelRect.width < 2) { + return { + y: '-100%' + }; + } else { + return { + hideOverlap: true + }; + } + }; + } + + ngAfterViewInit() { + if (this.drawChartPending) { + this.drawChart(); + } + } + + ngOnDestroy() { + if (this.shapeResize$) { + this.shapeResize$.disconnect(); + } + if (this.barChart) { + this.barChart.dispose(); + } + } + + public onInit() { + const borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; + if (this.chartShape) { + this.drawChart(); + } else { + this.drawChartPending = true; + } + this.cd.detectChanges(); + } + + public onDataUpdated() { + let minTime = this.ctx.defaultSubscription.timeWindow.minTime; + for (const item of this.dataItems) { + const datasourceData = this.ctx.data ? this.ctx.data.find(d => d.dataKey === item.dataKey) : null; + const namedData = datasourceData?.data ? toNamedData(datasourceData.data) : []; + item.data = namedData; + if (datasourceData.data.length) { + minTime = Math.min(datasourceData.data[0][0], minTime); + } + } + if (this.barChart) { + (this.barChartOptions.xAxis as any).min = minTime; + (this.barChartOptions.xAxis as any).max = this.ctx.defaultSubscription.timeWindow.maxTime; + this.barChartOptions.series = this.updateSeries(); + this.barChart.setOption(this.barChartOptions); + } + } + + private updateSeries(): Array { + const series: Array = []; + for (const item of this.dataItems) { + if (item.enabled) { + const seriesOption: BarSeriesOption = { + type: 'bar', + barGap: 0, + barMaxWidth: 40, + id: item.id, + name: item.dataKey.label, + label: this.barLabelOptions, + color: item.dataKey.color, + data: item.data, + emphasis: { + focus: 'series' + }, + labelLayout: this.barLabelLayoutCallback + }; + series.push(seriesOption); + } + } + return series; + } + + public onLegendItemEnter(item: BarChartLegendItem) { + this.barChart.dispatchAction({ + type: 'highlight', + seriesId: item.id + }); + } + + public onLegendItemLeave(item: BarChartLegendItem) { + this.barChart.dispatchAction({ + type: 'downplay', + seriesId: item.id + }); + } + + public toggleLegendItem(item: BarChartLegendItem) { + const enable = !item.enabled; + const dataItem = this.dataItems.find(d => d.id === item.id); + if (dataItem) { + dataItem.enabled = enable; + this.barChartOptions.series = this.updateSeries(); + this.barChart.setOption(this.barChartOptions, true); + item.enabled = enable; + if (enable) { + this.barChart.dispatchAction({ + type: 'highlight', + seriesId: item.id + }); + } else { + for (const otherItem of this.legendItems.filter(i => i.id !== item.id)) { + this.barChart.dispatchAction({ + type: 'highlight', + seriesId: otherItem.id + }); + } + } + } + } + + private drawChart() { + this.barChart = echarts.init(this.chartShape.nativeElement, null, { + renderer: 'canvas', + }); + this.barChartOptions = { + tooltip: { + trigger: 'none' + }, + grid: { + containLabel: true, + top: '30', + left: 0, + right: 0, + bottom: 0 + }, + xAxis: { + type: 'time', + axisTick: { + show: false + }, + axisLabel: { + hideOverlap: true, + fontSize: 10 + }, + axisLine: { + onZero: false + }, + min: this.ctx.defaultSubscription.timeWindow.minTime, + max: this.ctx.defaultSubscription.timeWindow.maxTime + }, + yAxis: { + type: 'value', + axisLabel: { + formatter: value => formatValue(value, this.decimals, this.units, false) + } + } + }; + + this.barChartOptions.series = this.updateSeries(); + + if (this.settings.showTooltip) { + this.barChartOptions.tooltip = { + trigger: 'axis', + axisPointer: { + type: 'shadow' + }, + formatter: (params: any[]) => { + if (!params.length || !params[0]) { + return null; + } + const tooltipElement: HTMLElement = this.renderer.createElement('div'); + this.renderer.setStyle(tooltipElement, 'display', 'flex'); + this.renderer.setStyle(tooltipElement, 'flex-direction', 'column'); + this.renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); + this.renderer.setStyle(tooltipElement, 'gap', '4px'); + if (this.settings.tooltipShowDate) { + const dateElement: HTMLElement = this.renderer.createElement('div'); + const ts = params[0].value[0]; + this.tooltipDateFormat.update(ts); + this.renderer.appendChild(dateElement, this.renderer.createText(this.tooltipDateFormat.formatted)); + this.renderer.setStyle(dateElement, 'font-family', this.settings.tooltipDateFont.family); + this.renderer.setStyle(dateElement, 'font-size', this.settings.tooltipDateFont.size + this.settings.tooltipDateFont.sizeUnit); + this.renderer.setStyle(dateElement, 'font-style', this.settings.tooltipDateFont.style); + this.renderer.setStyle(dateElement, 'font-weight', this.settings.tooltipDateFont.weight); + this.renderer.setStyle(dateElement, 'line-height', this.settings.tooltipDateFont.lineHeight); + this.renderer.setStyle(dateElement, 'color', this.settings.tooltipDateColor); + this.renderer.appendChild(tooltipElement, dateElement); + } + let seriesParams = null; + const focusedSeriesIndex = this.focusedSeriesIndex(); + if (focusedSeriesIndex > -1) { + seriesParams = params.find(param => param.seriesIndex === focusedSeriesIndex); + } + if (seriesParams) { + this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); + } else { + for (seriesParams of params) { + this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); + } + } + return tooltipElement; + }, + padding: [8, 12], + backgroundColor: this.settings.tooltipBackgroundColor, + extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` + }; + } + + this.barChart.setOption(this.barChartOptions); + + this.shapeResize$ = new ResizeObserver(() => { + this.onResize(); + }); + this.shapeResize$.observe(this.chartShape.nativeElement); + this.onResize(); + } + + private constructTooltipSeriesElement(seriesParams): HTMLElement { + const labelValueElement: HTMLElement = this.renderer.createElement('div'); + this.renderer.setStyle(labelValueElement, 'display', 'flex'); + this.renderer.setStyle(labelValueElement, 'flex-direction', 'row'); + this.renderer.setStyle(labelValueElement, 'align-items', 'center'); + this.renderer.setStyle(labelValueElement, 'align-self', 'stretch'); + this.renderer.setStyle(labelValueElement, 'gap', '12px'); + const labelElement: HTMLElement = this.renderer.createElement('div'); + this.renderer.setStyle(labelElement, 'display', 'flex'); + this.renderer.setStyle(labelElement, 'align-items', 'center'); + this.renderer.setStyle(labelElement, 'gap', '8px'); + this.renderer.appendChild(labelValueElement, labelElement); + const circleElement: HTMLElement = this.renderer.createElement('div'); + this.renderer.setStyle(circleElement, 'width', '8px'); + this.renderer.setStyle(circleElement, 'height', '8px'); + this.renderer.setStyle(circleElement, 'border-radius', '50%'); + this.renderer.setStyle(circleElement, 'background', seriesParams.color); + this.renderer.appendChild(labelElement, circleElement); + const labelTextElement: HTMLElement = this.renderer.createElement('div'); + this.renderer.appendChild(labelTextElement, this.renderer.createText(seriesParams.seriesName)); + this.renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); + this.renderer.setStyle(labelTextElement, 'font-size', '12px'); + this.renderer.setStyle(labelTextElement, 'font-style', 'normal'); + this.renderer.setStyle(labelTextElement, 'font-weight', '400'); + this.renderer.setStyle(labelTextElement, 'line-height', '16px'); + this.renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); + this.renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); + this.renderer.appendChild(labelElement, labelTextElement); + const valueElement: HTMLElement = this.renderer.createElement('div'); + const value = formatValue(seriesParams.value[1], this.decimals, this.units, false); + this.renderer.appendChild(valueElement, this.renderer.createText(value)); + this.renderer.setStyle(valueElement, 'flex', '1'); + this.renderer.setStyle(valueElement, 'text-align', 'end'); + this.renderer.setStyle(valueElement, 'font-family', this.settings.tooltipValueFont.family); + this.renderer.setStyle(valueElement, 'font-size', this.settings.tooltipValueFont.size + this.settings.tooltipValueFont.sizeUnit); + this.renderer.setStyle(valueElement, 'font-style', this.settings.tooltipValueFont.style); + this.renderer.setStyle(valueElement, 'font-weight', this.settings.tooltipValueFont.weight); + this.renderer.setStyle(valueElement, 'line-height', this.settings.tooltipValueFont.lineHeight); + this.renderer.setStyle(valueElement, 'color', this.settings.tooltipValueColor); + this.renderer.appendChild(labelValueElement, valueElement); + return labelValueElement; + } + + private focusedSeriesIndex(): number { + let index = - 1; + // @ts-ignore + const views: any[] = this.barChart._chartsViews; + if (views) { + const hasBlurredView = !!views.find(view => { + const graphicEls: any[] = view._data._graphicEls; + return !!graphicEls.find(el => el.currentStates.includes('blur')); + }); + if (hasBlurredView) { + const focusedView = views.find(view => { + const graphicEls: any[] = view._data._graphicEls; + return !!graphicEls.find(el => !el.currentStates.includes('blur')); + }); + if (focusedView) { + index = focusedView._model.seriesIndex; + } + } + } + return index; + } + + private onResize() { + const width = this.barChart.getWidth(); + const height = this.barChart.getHeight(); + const shapeWidth = this.chartShape.nativeElement.offsetWidth; + const shapeHeight = this.chartShape.nativeElement.offsetHeight; + if (width !== shapeWidth || height !== shapeHeight) { + this.barChart.resize(); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts new file mode 100644 index 0000000000..b56b2bc435 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts @@ -0,0 +1,112 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { + BackgroundSettings, + BackgroundType, customDateFormat, + DateFormatSettings, + Font +} from '@shared/models/widget-settings.models'; +import { LegendPosition } from '@shared/models/widget.models'; + +export interface BarChartWithLabelsWidgetSettings { + showBarLabel: boolean; + barLabelFont: Font; + barLabelColor: string; + showBarValue: boolean; + barValueFont: Font; + barValueColor: string; + showLegend: boolean; + legendPosition: LegendPosition; + legendLabelFont: Font; + legendLabelColor: string; + showTooltip: boolean; + tooltipValueFont: Font; + tooltipValueColor: string; + tooltipShowDate: boolean; + tooltipDateFormat: DateFormatSettings; + tooltipDateFont: Font; + tooltipDateColor: string; + tooltipBackgroundColor: string; + tooltipBackgroundBlur: number; + background: BackgroundSettings; +} + +export const barChartWithLabelsDefaultSettings: BarChartWithLabelsWidgetSettings = { + showBarLabel: true, + barLabelFont: { + family: 'Roboto', + size: 12, + sizeUnit: 'px', + style: 'normal', + weight: '400', + lineHeight: '12px' + }, + barLabelColor: 'rgba(0, 0, 0, 0.54)', + showBarValue: true, + barValueFont: { + family: 'Roboto', + size: 12, + sizeUnit: 'px', + style: 'normal', + weight: '700', + lineHeight: '12px' + }, + barValueColor: 'rgba(0, 0, 0, 0.76)', + showLegend: true, + legendPosition: LegendPosition.top, + legendLabelFont: { + family: 'Roboto', + size: 12, + sizeUnit: 'px', + style: 'normal', + weight: '400', + lineHeight: '16px' + }, + legendLabelColor: 'rgba(0, 0, 0, 0.76)', + showTooltip: true, + tooltipValueFont: { + family: 'Roboto', + size: 12, + sizeUnit: 'px', + style: 'normal', + weight: '500', + lineHeight: '16px' + }, + tooltipValueColor: 'rgba(0, 0, 0, 0.76)', + tooltipShowDate: true, + tooltipDateFormat: customDateFormat('MMMM y'), + tooltipDateFont: { + family: 'Roboto', + size: 11, + sizeUnit: 'px', + style: 'normal', + weight: '400', + lineHeight: '16px' + }, + tooltipDateColor: 'rgba(0, 0, 0, 0.76)', + tooltipBackgroundColor: 'rgba(255, 255, 255, 0.76)', + tooltipBackgroundBlur: 4, + background: { + type: BackgroundType.color, + color: '#fff', + overlay: { + enabled: false, + color: 'rgba(255,255,255,0.72)', + blur: 3 + } + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts index 6679ed0cca..15568db522 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts @@ -67,6 +67,9 @@ import { ProgressBarWidgetComponent } from '@home/components/widget/lib/cards/pr import { LiquidLevelWidgetComponent } from '@home/components/widget/lib/indicator/liquid-level-widget.component'; import { DoughnutWidgetComponent } from '@home/components/widget/lib/chart/doughnut-widget.component'; import { RangeChartWidgetComponent } from '@home/components/widget/lib/chart/range-chart-widget.component'; +import { + BarChartWithLabelsWidgetComponent +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.component'; @NgModule({ declarations: @@ -108,7 +111,8 @@ import { RangeChartWidgetComponent } from '@home/components/widget/lib/chart/ran ProgressBarWidgetComponent, LiquidLevelWidgetComponent, DoughnutWidgetComponent, - RangeChartWidgetComponent + RangeChartWidgetComponent, + BarChartWithLabelsWidgetComponent ], imports: [ CommonModule, @@ -154,7 +158,8 @@ import { RangeChartWidgetComponent } from '@home/components/widget/lib/chart/ran ProgressBarWidgetComponent, LiquidLevelWidgetComponent, DoughnutWidgetComponent, - RangeChartWidgetComponent + RangeChartWidgetComponent, + BarChartWithLabelsWidgetComponent ], providers: [ {provide: WIDGET_COMPONENTS_MODULE_TOKEN, useValue: WidgetComponentsModule } From 14b3dd4b57edaba259ec84494d4bf10011cfae8d Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 3 Jan 2024 10:36:08 +0200 Subject: [PATCH 26/91] updated columns order in index --- application/src/main/data/upgrade/3.6.2/schema_update.sql | 3 ++- dao/src/main/resources/sql/schema-entities-idx.sql | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/application/src/main/data/upgrade/3.6.2/schema_update.sql b/application/src/main/data/upgrade/3.6.2/schema_update.sql index fd64136852..4e62209ea8 100644 --- a/application/src/main/data/upgrade/3.6.2/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.2/schema_update.sql @@ -16,7 +16,8 @@ -- RULE NODE INDEXES UPDATE START +DROP INDEX IF EXISTS idx_rule_node_type; DROP INDEX IF EXISTS idx_rule_node_type_configuration_version; -CREATE INDEX IF NOT EXISTS idx_rule_node_id_type_configuration_version ON rule_node(id, type, configuration_version); +CREATE INDEX IF NOT EXISTS idx_rule_node_type_id_configuration_version ON rule_node(type, id, configuration_version); -- RULE NODE INDEXES UPDATE END diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index 10678509b4..6a95d9e346 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -91,9 +91,7 @@ CREATE INDEX IF NOT EXISTS idx_widgets_bundle_external_id ON widgets_bundle(tena CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, external_id); -CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); - -CREATE INDEX IF NOT EXISTS idx_rule_node_id_type_configuration_version ON rule_node(id, type, configuration_version); +CREATE INDEX IF NOT EXISTS idx_rule_node_type_id_configuration_version ON rule_node(type, id, configuration_version); CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); From 04cab4d5d1b801fc0ccdf1afeed5254dc8a7d8e8 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 4 Jan 2024 12:15:43 +0200 Subject: [PATCH 27/91] Monitoring service: notification message prefix; minor improvements --- .../config/transport/TransportInfo.java | 2 +- .../config/transport/TransportType.java | 9 +++++---- .../notification/NotificationService.java | 18 ++++++++++++------ .../channels/NotificationChannel.java | 4 +--- .../impl/SlackNotificationChannel.java | 11 +++-------- .../src/main/resources/tb-monitoring.yml | 3 ++- 6 files changed, 24 insertions(+), 23 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java index 6fb2e25ec9..85ecfb689d 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java @@ -25,7 +25,7 @@ public class TransportInfo { @Override public String toString() { - return String.format("%s transport (%s)", transportType, baseUrl); + return String.format("%s (%s)", transportType.getName(), baseUrl); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java index eeb085348b..122bddcd20 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java @@ -27,11 +27,12 @@ import org.thingsboard.monitoring.service.transport.impl.MqttTransportHealthChec @Getter public enum TransportType { - MQTT(MqttTransportHealthChecker.class), - COAP(CoapTransportHealthChecker.class), - HTTP(HttpTransportHealthChecker.class), - LWM2M(Lwm2mTransportHealthChecker.class); + MQTT("MQTT", MqttTransportHealthChecker.class), + COAP("CoAP",CoapTransportHealthChecker.class), + HTTP("HTTP", HttpTransportHealthChecker.class), + LWM2M("LwM2M", Lwm2mTransportHealthChecker.class); + private final String name; private final Class> serviceClass; } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java index f882105048..8d9cc6dc4d 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java @@ -17,6 +17,8 @@ package org.thingsboard.monitoring.notification; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.thingsboard.monitoring.data.notification.Notification; import org.thingsboard.monitoring.notification.channels.NotificationChannel; @@ -24,7 +26,6 @@ import org.thingsboard.monitoring.notification.channels.NotificationChannel; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.function.Consumer; @Component @RequiredArgsConstructor @@ -34,15 +35,20 @@ public class NotificationService { private final List notificationChannels; private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(); - public void sendNotification(Notification notification) { - forEachNotificationChannel(notificationChannel -> notificationChannel.sendNotification(notification)); - } + @Value("${monitoring.notifications.message_prefix}") + private String messagePrefix; - private void forEachNotificationChannel(Consumer function) { + public void sendNotification(Notification notification) { + String message; + if (StringUtils.isEmpty(messagePrefix)) { + message = notification.getText(); + } else { + message = messagePrefix + System.lineSeparator() + notification.getText(); + } notificationChannels.forEach(notificationChannel -> { notificationExecutor.submit(() -> { try { - function.accept(notificationChannel); + notificationChannel.sendNotification(message); } catch (Exception e) { log.error("Failed to send notification to {}", notificationChannel.getClass().getSimpleName(), e); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java index 6c1c23cc28..62171ec2af 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java @@ -15,10 +15,8 @@ */ package org.thingsboard.monitoring.notification.channels; -import org.thingsboard.monitoring.data.notification.Notification; - public interface NotificationChannel { - void sendNotification(Notification notification); + void sendNotification(String message); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java index 092ea0b8c6..bea712e4dc 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java @@ -21,7 +21,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; -import org.thingsboard.monitoring.data.notification.Notification; import org.thingsboard.monitoring.notification.channels.NotificationChannel; import javax.annotation.PostConstruct; @@ -29,11 +28,11 @@ import java.time.Duration; import java.util.Map; @Component -@ConditionalOnProperty(value = "monitoring.notification_channels.slack.enabled", havingValue = "true") +@ConditionalOnProperty(value = "monitoring.notifications.slack.enabled", havingValue = "true") @Slf4j public class SlackNotificationChannel implements NotificationChannel { - @Value("${monitoring.notification_channels.slack.webhook_url}") + @Value("${monitoring.notifications.slack.webhook_url}") private String webhookUrl; private RestTemplate restTemplate; @@ -47,11 +46,7 @@ public class SlackNotificationChannel implements NotificationChannel { } @Override - public void sendNotification(Notification notification) { - sendNotification(notification.getText()); - } - - private void sendNotification(String message) { + public void sendNotification(String message) { restTemplate.postForObject(webhookUrl, Map.of("text", message), String.class); } diff --git a/monitoring/src/main/resources/tb-monitoring.yml b/monitoring/src/main/resources/tb-monitoring.yml index 57b9b39ec0..9e3ee39425 100644 --- a/monitoring/src/main/resources/tb-monitoring.yml +++ b/monitoring/src/main/resources/tb-monitoring.yml @@ -97,7 +97,8 @@ monitoring: # To add more targets, use following environment variables: # monitoring.transports.lwm2m.targets[1].base_url, monitoring.transports.lwm2m.targets[2].base_url, etc. - notification_channels: + notifications: + message_prefix: '${NOTIFICATION_MESSAGE_PREFIX:}' slack: # Enable notifying via Slack enabled: '${SLACK_NOTIFICATION_CHANNEL_ENABLED:false}' From e9a7bc440e4153abd5a9ac7caf87f785fa13ec6b Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 4 Jan 2024 12:36:38 +0200 Subject: [PATCH 28/91] Monitoring alerts formatting improvements --- .../thingsboard/monitoring/config/transport/TransportInfo.java | 2 +- .../monitoring/data/notification/HighLatencyNotification.java | 2 +- monitoring/src/main/resources/tb-monitoring.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java index 85ecfb689d..63b7df07f1 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java @@ -25,7 +25,7 @@ public class TransportInfo { @Override public String toString() { - return String.format("%s (%s)", transportType.getName(), baseUrl); + return String.format("*%s* (%s)", transportType.getName(), baseUrl); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java index 5744e40d41..901a7c1310 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java @@ -34,7 +34,7 @@ public class HighLatencyNotification implements Notification { StringBuilder text = new StringBuilder(); text.append("Some of the latencies are higher than ").append(thresholdMs).append(" ms:\n"); highLatencies.forEach(latency -> { - text.append(String.format("[%s] %s\n", latency.getKey(), latency.getFormattedValue())); + text.append(String.format("[%s] *%s*\n", latency.getKey(), latency.getFormattedValue())); }); return text.toString(); } diff --git a/monitoring/src/main/resources/tb-monitoring.yml b/monitoring/src/main/resources/tb-monitoring.yml index 9e3ee39425..f7226b8374 100644 --- a/monitoring/src/main/resources/tb-monitoring.yml +++ b/monitoring/src/main/resources/tb-monitoring.yml @@ -38,7 +38,7 @@ monitoring: check_timeout_ms: '${CHECK_TIMEOUT_MS:5000}' # Failures threshold for notifying - failures_threshold: '${FAILURES_THRESHOLD:2}' + failures_threshold: '${FAILURES_THRESHOLD:1}' # Notify after each REPEATED_FAILURE_NOTIFICATION subsequent failures, 0 to notify only once on first failure repeated_failure_notification: '${REPEATED_FAILURE_NOTIFICATION:4}' From 05f5961face2c871efb34dd0ba4495711e10d50b Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 4 Jan 2024 14:50:15 +0200 Subject: [PATCH 29/91] Remove unnecessary isSupportedOriginator for TbPushNode in order not to support 2 places of possible types: there is check after fetching during processing edge events from db --- .../engine/edge/AbstractTbMsgPushNode.java | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java index 7888922dc6..b5f2b5e517 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java @@ -66,16 +66,10 @@ public abstract class AbstractTbMsgPushNode Date: Fri, 5 Jan 2024 11:28:45 +0200 Subject: [PATCH 30/91] Improve RPC device actor init to find edgeId by CONSTAINS_TYPE --- .../server/actors/ActorSystemContext.java | 2 +- .../device/DeviceActorMessageProcessor.java | 16 ++++++++-------- .../service/queue/DefaultTbClusterService.java | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index 09dcf3ca1e..2dc73c51c7 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -29,7 +29,6 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.NotificationCenter; import org.thingsboard.rule.engine.api.SmsService; @@ -101,6 +100,7 @@ import org.thingsboard.server.service.entitiy.entityview.TbEntityViewService; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.ExternalCallExecutorService; import org.thingsboard.server.service.executors.NotificationExecutorService; +import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider; import org.thingsboard.server.service.executors.SharedEventLoopGroupService; import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.profile.TbAssetProfileCache; diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 50e237ac73..aee8a33ab7 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -25,10 +25,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.LinkedHashMapRemoveEldest; -import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg; -import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg; -import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg; -import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; @@ -61,7 +57,14 @@ import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponseActorMsg; +import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg; import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; +import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg; +import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg; +import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg; +import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg; +import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; @@ -87,10 +90,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; -import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponseActorMsg; -import org.thingsboard.server.common.msg.rpc.RemoveRpcActorMsg; import org.thingsboard.server.service.rpc.RpcSubmitStrategy; -import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequestActorMsg; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; import javax.annotation.Nullable; @@ -173,7 +173,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private EdgeId findRelatedEdgeId() { List result = - systemContext.getRelationService().findByToAndType(tenantId, deviceId, EntityRelation.EDGE_TYPE, RelationTypeGroup.COMMON); + systemContext.getRelationService().findByToAndType(tenantId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON); if (result != null && result.size() > 0) { EntityRelation relationToEdge = result.get(0); if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) { diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java index 14930912d1..cfa87c0508 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java @@ -44,6 +44,8 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.msg.TbMsg; @@ -57,6 +59,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg; import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg; +import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; @@ -68,8 +71,8 @@ import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.MultipleTbQueueCallbackWrapper; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.discovery.PartitionService; +import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; @@ -77,6 +80,7 @@ import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -116,6 +120,7 @@ public class DefaultTbClusterService implements TbClusterService { private final TbDeviceProfileCache deviceProfileCache; private final TbAssetProfileCache assetProfileCache; private final GatewayNotificationsService gatewayNotificationsService; + private final EdgeService edgeService; @Override public void pushMsgToCore(TenantId tenantId, EntityId entityId, ToCoreMsg msg, TbQueueCallback callback) { @@ -546,11 +551,17 @@ public class DefaultTbClusterService implements TbClusterService { pushMsgToCore(new DeviceEdgeUpdateMsg(tenantId, new DeviceId(entityId.getId()), edgeId), null); break; case UNASSIGNED_FROM_EDGE: - pushMsgToCore(new DeviceEdgeUpdateMsg(tenantId, new DeviceId(entityId.getId()), null), null); + EdgeId relatedEdgeId = findRelatedEdgeEdgeIdIfAny(tenantId, entityId); + pushMsgToCore(new DeviceEdgeUpdateMsg(tenantId, new DeviceId(entityId.getId()), relatedEdgeId), null); break; } } + private EdgeId findRelatedEdgeEdgeIdIfAny(TenantId tenantId, EntityId entityId) { + PageData pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, new PageLink(1)); + return Optional.ofNullable(pageData).filter(pd -> pd.getTotalElements() == 1).map(pd -> pd.getData().get(0)).orElse(null); + } + @Override public void onQueueChange(Queue queue) { log.trace("[{}][{}] Processing queue change [{}] event", queue.getTenantId(), queue.getId(), queue.getName()); From a8e436c102983761a5b376d5a4c2470dbb30a611 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 5 Jan 2024 11:34:07 +0200 Subject: [PATCH 31/91] Improve naming for method findRelatedEdgeIdIfAny --- .../server/service/queue/DefaultTbClusterService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java index cfa87c0508..21d1d2022d 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java @@ -551,13 +551,13 @@ public class DefaultTbClusterService implements TbClusterService { pushMsgToCore(new DeviceEdgeUpdateMsg(tenantId, new DeviceId(entityId.getId()), edgeId), null); break; case UNASSIGNED_FROM_EDGE: - EdgeId relatedEdgeId = findRelatedEdgeEdgeIdIfAny(tenantId, entityId); + EdgeId relatedEdgeId = findRelatedEdgeIdIfAny(tenantId, entityId); pushMsgToCore(new DeviceEdgeUpdateMsg(tenantId, new DeviceId(entityId.getId()), relatedEdgeId), null); break; } } - private EdgeId findRelatedEdgeEdgeIdIfAny(TenantId tenantId, EntityId entityId) { + private EdgeId findRelatedEdgeIdIfAny(TenantId tenantId, EntityId entityId) { PageData pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, new PageLink(1)); return Optional.ofNullable(pageData).filter(pd -> pd.getTotalElements() == 1).map(pd -> pd.getData().get(0)).orElse(null); } From 17277284395f2bc4d70f74cdfeb7685eff4d86ff Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Fri, 5 Jan 2024 11:36:01 +0200 Subject: [PATCH 32/91] UI: Added queue for rule node --- .../rule-node-details.component.html | 22 ++++-- .../rulechain/rule-node-details.component.ts | 69 ++++++++++++++++--- .../rulechain/rulechain-page.component.ts | 7 +- .../models/component-descriptor.models.ts | 1 + .../src/app/shared/models/rule-node.models.ts | 2 + .../assets/locale/locale.constant-en_US.json | 4 +- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html index cf798bf33b..03d20eaca4 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html @@ -38,7 +38,7 @@ {{ 'rulenode.debug-mode' | translate }} - + {{ 'rulenode.singleton-mode' | translate }} @@ -52,10 +52,20 @@ (initRuleNode)="initRuleNode.emit($event)" (changeScript)="changeScript.emit($event)"> -
- - rulenode.rule-node-description - - + +
+ + +
+ + rulenode.rule-node-description + + +
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts index 5fce7f8e0b..dcd7655429 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts @@ -14,26 +14,38 @@ /// limitations under the License. /// -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, + SimpleChanges, + ViewChild +} from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models'; import { EntityType } from '@shared/models/entity-type.models'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; import { RuleNodeConfigComponent } from './rule-node-config.component'; import { Router } from '@angular/router'; import { RuleChainType } from '@app/shared/models/rule-chain.models'; import { ComponentClusteringMode } from '@shared/models/component-descriptor.models'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { ServiceType } from '@shared/models/queue.models'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'tb-rule-node', templateUrl: './rule-node-details.component.html', styleUrls: ['./rule-node-details.component.scss'] }) -export class RuleNodeDetailsComponent extends PageComponent implements OnInit, OnChanges { +export class RuleNodeDetailsComponent extends PageComponent implements OnInit, OnChanges, OnDestroy { @ViewChild('ruleNodeConfigComponent') ruleNodeConfigComponent: RuleNodeConfigComponent; @@ -63,9 +75,11 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O ruleNodeType = RuleNodeType; entityType = EntityType; + serviceType = ServiceType.TB_RULE_ENGINE; + ruleNodeFormGroup: UntypedFormGroup; - private ruleNodeFormSubscription: Subscription; + private destroy$ = new Subject(); constructor(protected store: Store, private fb: UntypedFormBuilder, @@ -75,10 +89,6 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } private buildForm() { - if (this.ruleNodeFormSubscription) { - this.ruleNodeFormSubscription.unsubscribe(); - this.ruleNodeFormSubscription = null; - } if (this.ruleNode) { this.ruleNodeFormGroup = this.fb.group({ name: [this.ruleNode.name, [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*'), Validators.maxLength(255)]], @@ -91,9 +101,32 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } ) }); - this.ruleNodeFormSubscription = this.ruleNodeFormGroup.valueChanges.subscribe(() => { - this.updateRuleNode(); - }); + + if (this.isAddQueue()) { + this.ruleNodeFormGroup.addControl('queueName', this.fb.control(this.ruleNode?.queueName ? this.ruleNode.queueName : null)); + if (this.isSingleton()) { + if (!this.isSingletonEditAllowed()) { + this.ruleNodeFormGroup.get('singletonMode').disable({emitEvent: false}); + } + if (!this.ruleNodeFormGroup.get('singletonMode').value) { + this.ruleNodeFormGroup.get('queueName').disable({emitEvent: false}); + } + this.ruleNodeFormGroup.get('singletonMode').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(value => { + if (value) { + this.ruleNodeFormGroup.get('queueName').enable({emitEvent: false}); + } else { + this.ruleNodeFormGroup.get('queueName').disable({emitEvent: false}); + } + }); + } + } + + this.ruleNodeFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => this.updateRuleNode()); + } else { this.ruleNodeFormGroup = this.fb.group({}); } @@ -114,6 +147,11 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } } + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + ngOnChanges(changes: SimpleChanges): void { for (const propName of Object.keys(changes)) { const change = changes[propName]; @@ -143,6 +181,15 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } } + isAddQueue() { + return this.isSingleton() || this.ruleNode.component.hasQueueName; + } + + isSingleton() { + return this.ruleNode.component.clusteringMode === ComponentClusteringMode.SINGLETON || + this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE; + } + isSingletonEditAllowed() { return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE; } diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 6f657f26c3..bea5fdc502 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -575,6 +575,7 @@ export class RuleChainPageComponent extends PageComponent configurationVersion: isDefinedAndNotNull(ruleNode.configurationVersion) ? ruleNode.configurationVersion : 0, debugMode: ruleNode.debugMode, singletonMode: ruleNode.singletonMode, + queueName: ruleNode.queueName, x: Math.round(ruleNode.additionalInfo.layoutX), y: Math.round(ruleNode.additionalInfo.layoutY), component, @@ -934,7 +935,8 @@ export class RuleChainPageComponent extends PageComponent configuration: deepClone(node.configuration), additionalInfo: node.additionalInfo ? deepClone(node.additionalInfo) : {}, debugMode: node.debugMode, - singletonMode: node.singletonMode + singletonMode: node.singletonMode, + queueName: node.queueName }; if (minX === null) { minX = node.x; @@ -1467,7 +1469,8 @@ export class RuleChainPageComponent extends PageComponent configuration: node.configuration, additionalInfo: node.additionalInfo ? node.additionalInfo : {}, debugMode: node.debugMode, - singletonMode: node.singletonMode + singletonMode: node.singletonMode, + queueName: node.queueName }; ruleNode.additionalInfo.layoutX = Math.round(node.x); ruleNode.additionalInfo.layoutY = Math.round(node.y); diff --git a/ui-ngx/src/app/shared/models/component-descriptor.models.ts b/ui-ngx/src/app/shared/models/component-descriptor.models.ts index 3ce15d15aa..35cdee95da 100644 --- a/ui-ngx/src/app/shared/models/component-descriptor.models.ts +++ b/ui-ngx/src/app/shared/models/component-descriptor.models.ts @@ -40,6 +40,7 @@ export interface ComponentDescriptor { type: ComponentType | RuleNodeType; scope?: ComponentScope; clusteringMode: ComponentClusteringMode; + hasQueueName?: boolean; name: string; clazz: string; configurationDescriptor?: any; diff --git a/ui-ngx/src/app/shared/models/rule-node.models.ts b/ui-ngx/src/app/shared/models/rule-node.models.ts index 4a40944c67..20cb4418b9 100644 --- a/ui-ngx/src/app/shared/models/rule-node.models.ts +++ b/ui-ngx/src/app/shared/models/rule-node.models.ts @@ -39,6 +39,7 @@ export interface RuleNode extends BaseData { name: string; debugMode: boolean; singletonMode: boolean; + queueName?: string; configurationVersion?: number; configuration: RuleNodeConfiguration; additionalInfo?: any; @@ -334,6 +335,7 @@ export interface RuleNodeComponentDescriptor extends ComponentDescriptor { export interface FcRuleNodeType extends FcNode { component?: RuleNodeComponentDescriptor; singletonMode?: boolean; + queueName?: string; nodeClass?: string; icon?: string; iconUrl?: string; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 1904cb796f..bf959462d2 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3841,7 +3841,9 @@ "test": "Test", "help": "Help", "reset-debug-mode": "Reset debug mode in all nodes", - "test-with-this-message": "{{test}} with this message" + "test-with-this-message": "{{test}} with this message", + "queue-hint": "Select a queue for message forwarding to another queue. 'Main' queue is used by default.", + "queue-singleton-hint": "Select a queue for message forwarding in multi-instance environments. 'Main' queue is used by default." }, "timezone": { "timezone": "Timezone", From e2b2dea9685b86c6416cf233a81cab46f950caa0 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 5 Jan 2024 12:31:43 +0200 Subject: [PATCH 33/91] Improve findRelatedEdgeIdIfAny to check for total elements > 0 --- .../server/service/queue/DefaultTbClusterService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java index 21d1d2022d..d567d1b447 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java @@ -559,7 +559,7 @@ public class DefaultTbClusterService implements TbClusterService { private EdgeId findRelatedEdgeIdIfAny(TenantId tenantId, EntityId entityId) { PageData pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, new PageLink(1)); - return Optional.ofNullable(pageData).filter(pd -> pd.getTotalElements() == 1).map(pd -> pd.getData().get(0)).orElse(null); + return Optional.ofNullable(pageData).filter(pd -> pd.getTotalElements() > 0).map(pd -> pd.getData().get(0)).orElse(null); } @Override From e227caac514e4fa5b117d59687419e0455a0ffcb Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 5 Jan 2024 14:27:36 +0200 Subject: [PATCH 34/91] Provide test for fixed bug --- .../server/edge/DeviceEdgeTest.java | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java index 7bb05cb4d5..c9a7a97c9a 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java @@ -25,8 +25,10 @@ import io.netty.handler.codec.mqtt.MqttQoS; import org.awaitility.Awaitility; import org.junit.Assert; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -44,15 +46,17 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.msg.session.FeatureType; -import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; @@ -86,6 +90,9 @@ public class DeviceEdgeTest extends AbstractEdgeTest { private static final String DEFAULT_DEVICE_TYPE = "default"; + @Autowired + protected EdgeService edgeService; + @Test public void testDevices() throws Exception { // create device and assign to edge; update device @@ -769,6 +776,45 @@ public class DeviceEdgeTest extends AbstractEdgeTest { } } + @Test + public void testVerifyProcessCorrectEdgeUpdateToDeviceActorOnUnassignFromDifferentEdge() throws Exception { + Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + // assign device to another edge + Edge tmpEdge = doPost("/api/edge", constructEdge("Test Tmp Edge", "test"), Edge.class); + doPost("/api/edge/" + tmpEdge.getUuidId() + + "/device/" + device.getUuidId(), Device.class); + List relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, device.getId()); + Assert.assertEquals(2, relatedEdgeIds.size()); + + // unassign device from edge + doDelete("/api/edge/" + edge.getUuidId() + + "/device/" + device.getUuidId(), Device.class); + relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, device.getId()); + Assert.assertEquals(1, relatedEdgeIds.size()); + Assert.assertEquals(tmpEdge.getId(), relatedEdgeIds.get(0)); + + // clean up stored edge events + edgeEventService.cleanupEvents(1); + + // perform rpc call to verify edgeId in DeviceActorMessageProcessor updated properly + doPostAsync( + "/api/rpc/oneway/" + device.getId().getId().toString(), + JacksonUtil.toString(createDefaultRpc()), + String.class, + status().isOk()); + + PageData result = edgeEventService.findEdgeEvents(tenantId, tmpEdge.getId(), 0L, null, new TimePageLink(1)); + EdgeEvent edgeEvent = result.getData().get(0); + Assert.assertEquals(EdgeEventActionType.RPC_CALL, edgeEvent.getAction()); + Assert.assertEquals(EdgeEventType.DEVICE, edgeEvent.getType()); + Assert.assertEquals(tmpEdge.getId(), edgeEvent.getEdgeId()); + Assert.assertEquals(device.getId().getId(), edgeEvent.getEntityId()); + + // clean up tmp edge + doDelete("/api/edge/" + tmpEdge.getId().getId().toString()).andExpect(status().isOk()); + } + private Device buildDeviceForUplinkMsg(String name, String type) { Device device = new Device(); device.setId(new DeviceId(UUID.randomUUID())); @@ -778,7 +824,6 @@ public class DeviceEdgeTest extends AbstractEdgeTest { return device; } - private DeviceCredentials buildDeviceCredentialsForUplinkMsg(DeviceId deviceId) { DeviceCredentials deviceCredentials = new DeviceCredentials(); deviceCredentials.setDeviceId(deviceId); @@ -786,4 +831,20 @@ public class DeviceEdgeTest extends AbstractEdgeTest { deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); return deviceCredentials; } + + private ObjectNode createDefaultRpc() { + ObjectNode rpc = JacksonUtil.newObjectNode(); + rpc.put("method", "setGpio"); + + ObjectNode params = JacksonUtil.newObjectNode(); + + params.put("pin", 7); + params.put("value", 1); + + rpc.set("params", params); + rpc.put("persistent", true); + rpc.put("timeout", 5000); + + return rpc; + } } From 6252433231c7bcb0c2258442994e87f7cc943926 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 5 Jan 2024 14:34:32 +0200 Subject: [PATCH 35/91] Fix DefaultTbClusterServiceTest --- .../server/service/queue/DefaultTbClusterServiceTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 233839bb5f..9d98ec25c7 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -29,11 +29,12 @@ import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.msg.queue.ServiceType; +import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.discovery.PartitionService; +import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; @@ -73,6 +74,8 @@ public class DefaultTbClusterServiceTest { @MockBean protected GatewayNotificationsService gatewayNotificationsService; @MockBean + protected EdgeService edgeService; + @MockBean protected PartitionService partitionService; @MockBean protected TbQueueProducerProvider producerProvider; From f15baf38ceea224d93c1bef1ebc5eb2ab154df4a Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 5 Jan 2024 15:09:30 +0200 Subject: [PATCH 36/91] Improve stability for testVerifyProcessCorrectEdgeUpdateToDeviceActorOnUnassignFromDifferentEdge --- .../org/thingsboard/server/edge/DeviceEdgeTest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java index c9a7a97c9a..e2bfee9aae 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java @@ -79,6 +79,7 @@ import java.util.Optional; import java.util.Random; import java.util.UUID; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -804,7 +805,16 @@ public class DeviceEdgeTest extends AbstractEdgeTest { String.class, status().isOk()); - PageData result = edgeEventService.findEdgeEvents(tenantId, tmpEdge.getId(), 0L, null, new TimePageLink(1)); + final AtomicReference> resultRef = new AtomicReference<>(); + Awaitility.await() + .atMost(TIMEOUT, TimeUnit.SECONDS) + .until(() -> { + PageData result = edgeEventService.findEdgeEvents(tenantId, tmpEdge.getId(), 0L, null, new TimePageLink(1)); + resultRef.set(result); + return result != null && result.getData().size() == 1; + }); + + PageData result = resultRef.get(); EdgeEvent edgeEvent = result.getData().get(0); Assert.assertEquals(EdgeEventActionType.RPC_CALL, edgeEvent.getAction()); Assert.assertEquals(EdgeEventType.DEVICE, edgeEvent.getType()); From 0812afd0da631fc2b15d4c3fa38eea842eff1ac0 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 5 Jan 2024 17:33:55 +0200 Subject: [PATCH 37/91] Monitoring: ability to specify used queue --- .../monitoring/config/MonitoringTarget.java | 4 + .../config/transport/TransportInfo.java | 7 +- .../transport/TransportMonitoringTarget.java | 1 + .../ServiceFailureNotification.java | 2 +- .../ServiceRecoveryNotification.java | 2 +- .../transport/TransportHealthChecker.java | 96 ++++++++++++------- .../src/main/resources/tb-monitoring.yml | 8 ++ 7 files changed, 81 insertions(+), 39 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java index 0176b14d54..b64131a4fd 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java @@ -23,6 +23,10 @@ public interface MonitoringTarget { String getBaseUrl(); + default String getQueue() { + return "Main"; + } + boolean isCheckDomainIps(); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java index 63b7df07f1..788e1100ba 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java @@ -22,10 +22,15 @@ public class TransportInfo { private final TransportType transportType; private final String baseUrl; + private final String queue; @Override public String toString() { - return String.format("*%s* (%s)", transportType.getName(), baseUrl); + if (queue.equals("Main")) { + return String.format("*%s* (%s)", transportType.getName(), baseUrl); + } else { + return String.format("*%s* (%s) _%s_", transportType.getName(), baseUrl, queue); + } } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java index e3277af0ff..a496be2dae 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java @@ -25,6 +25,7 @@ public class TransportMonitoringTarget implements MonitoringTarget { private String baseUrl; private DeviceConfig device; // set manually during initialization + private String queue; private boolean checkDomainIps; @Override diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java index 4b78d96a63..a14c1a1ffe 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java @@ -43,7 +43,7 @@ public class ServiceFailureNotification implements Notification { if (errorMsg == null) { errorMsg = error.getClass().getSimpleName(); } - return String.format("[%s] Failure: %s (number of subsequent failures: %s)", serviceKey, errorMsg, failuresCount); + return String.format("%s - Failure: %s (number of subsequent failures: %s)", serviceKey, errorMsg, failuresCount); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java index 44eaf093cc..96f979e4d1 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java @@ -25,7 +25,7 @@ public class ServiceRecoveryNotification implements Notification { @Override public String getText() { - return String.format("[%s] is OK", serviceKey); + return String.format("%s is OK", serviceKey); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java index c822720f23..5eec7f52bf 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java @@ -29,6 +29,8 @@ import org.thingsboard.monitoring.service.BaseHealthChecker; import org.thingsboard.monitoring.util.ResourceUtils; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.DeviceProfileType; +import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; @@ -38,6 +40,9 @@ import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.data.DeviceData; import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; @@ -45,27 +50,19 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType; @Slf4j public abstract class TransportHealthChecker extends BaseHealthChecker { - private static final String DEFAULT_DEVICE_NAME = "[Monitoring] %s transport (%s)"; - private static final String DEFAULT_PROFILE_NAME = "[Monitoring] %s"; - public TransportHealthChecker(C config, TransportMonitoringTarget target) { super(config, target); } @Override protected void initialize(TbClient tbClient) { - String deviceName = String.format(DEFAULT_DEVICE_NAME, config.getTransportType(), target.getBaseUrl()); - Device device = tbClient.getTenantDevice(deviceName) - .orElseGet(() -> { - log.info("Creating new device '{}'", deviceName); - return createDevice(config.getTransportType(), deviceName, tbClient); - }); + Device device = getOrCreateDevice(tbClient); DeviceCredentials credentials = tbClient.getDeviceCredentialsByDeviceId(device.getId()) .orElseThrow(() -> new IllegalArgumentException("No credentials found for device " + device.getId())); DeviceConfig deviceConfig = new DeviceConfig(); deviceConfig.setId(device.getId().toString()); - deviceConfig.setName(deviceName); + deviceConfig.setName(device.getName()); deviceConfig.setCredentials(credentials); target.setDevice(deviceConfig); } @@ -77,51 +74,43 @@ public abstract class TransportHealthChecker { - TbResource newResource = ResourceUtils.getResource("lwm2m/resource.json", TbResource.class); - log.info("Creating LwM2M resource"); - return tbClient.saveResource(newResource); - }); - String profileName = String.format(DEFAULT_PROFILE_NAME, transportType); - DeviceProfile profile = tbClient.getDeviceProfiles(new PageLink(1, 0, profileName)).getData() - .stream().findFirst() - .orElseGet(() -> { - DeviceProfile newProfile = ResourceUtils.getResource("lwm2m/device_profile.json", DeviceProfile.class); - newProfile.setName(profileName); - log.info("Creating LwM2M device profile"); - return tbClient.saveDeviceProfile(newProfile); - }); - device.setType(profileName); - device.setDeviceProfileId(profile.getId()); deviceData.setTransportConfiguration(new Lwm2mDeviceTransportConfiguration()); - credentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); LwM2MDeviceCredentials lwm2mCreds = new LwM2MDeviceCredentials(); NoSecClientCredential client = new NoSecClientCredential(); @@ -133,7 +122,42 @@ public abstract class TransportHealthChecker { + TbResource newResource = ResourceUtils.getResource("lwm2m/resource.json", TbResource.class); + log.info("Creating LwM2M resource"); + return tbClient.saveResource(newResource); + }); + deviceProfile = ResourceUtils.getResource("lwm2m/device_profile.json", DeviceProfile.class); + } + + deviceProfile.setName(profileName); + deviceProfile.setDefaultQueueName(target.getQueue()); + return tbClient.saveDeviceProfile(deviceProfile); + } + } diff --git a/monitoring/src/main/resources/tb-monitoring.yml b/monitoring/src/main/resources/tb-monitoring.yml index f7226b8374..99ba861c14 100644 --- a/monitoring/src/main/resources/tb-monitoring.yml +++ b/monitoring/src/main/resources/tb-monitoring.yml @@ -53,6 +53,8 @@ monitoring: targets: # MQTT transport base url, tcp://DOMAIN:1883 by default - base_url: '${MQTT_TRANSPORT_BASE_URL:tcp://${monitoring.domain}:1883}' + # Queue to use for target device + queue: '${MQTT_TRANSPORT_USED_QUEUE:Main}' # Whether to monitor IPs associated with the domain from base url check_domain_ips: '${MQTT_TRANSPORT_CHECK_DOMAIN_IPS:false}' # To add more targets, use following environment variables: @@ -66,6 +68,8 @@ monitoring: targets: # CoAP transport base url, coap://DOMAIN by default - base_url: '${COAP_TRANSPORT_BASE_URL:coap://${monitoring.domain}}' + # Queue to use for target device + queue: '${COAP_TRANSPORT_USED_QUEUE:Main}' # Whether to monitor IPs associated with the domain from base url check_domain_ips: '${COAP_TRANSPORT_CHECK_DOMAIN_IPS:false}' # To add more targets, use following environment variables: @@ -79,6 +83,8 @@ monitoring: targets: # HTTP transport base url, http://DOMAIN by default - base_url: '${HTTP_TRANSPORT_BASE_URL:http://${monitoring.domain}}' + # Queue to use for target device + queue: '${HTTP_TRANSPORT_USED_QUEUE:Main}' # Whether to monitor IPs associated with the domain from base url check_domain_ips: '${HTTP_TRANSPORT_CHECK_DOMAIN_IPS:false}' # To add more targets, use following environment variables: @@ -92,6 +98,8 @@ monitoring: targets: # LwM2M transport base url, coap://DOMAIN:5685 by default - base_url: '${LWM2M_TRANSPORT_BASE_URL:coap://${monitoring.domain}:5685}' + # Queue to use for target device + queue: '${LWM2M_TRANSPORT_USED_QUEUE:Main}' # Whether to monitor IPs associated with the domain from base url check_domain_ips: '${LWM2M_TRANSPORT_CHECK_DOMAIN_IPS:false}' # To add more targets, use following environment variables: From 07d3992da4652bcb356bdc73253d238483f1c824 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 5 Jan 2024 17:53:51 +0200 Subject: [PATCH 38/91] Monitoring: Main queue by default --- .../config/transport/TransportMonitoringTarget.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java index a496be2dae..6ea60759d1 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java @@ -16,6 +16,7 @@ package org.thingsboard.monitoring.config.transport; import lombok.Data; +import org.apache.commons.lang3.StringUtils; import org.thingsboard.monitoring.config.MonitoringTarget; import java.util.UUID; @@ -33,4 +34,8 @@ public class TransportMonitoringTarget implements MonitoringTarget { return device.getId(); } + public String getQueue() { + return StringUtils.defaultIfEmpty(queue, "Main"); + } + } From 09a270cf279f4d52ee6cc453a7b9f61ce63fe5cd Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 8 Jan 2024 14:10:07 +0200 Subject: [PATCH 39/91] UI: Update rule node core config --- .../static/rulenode/rulenode-core-config.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 2881f40df2..9b31fc9a13 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1,25 +1,25 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,u,d,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,V,w,P,R,O,_,B,K,z,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,ue,de,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,Ve,we,Pe,Re,Oe,_e,Be,Ke,ze,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt,ut,dt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,u=e.Directive,d=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ServiceType,b=e.ScriptLanguage,h=e.AlarmSeverity,v=e.alarmSeverityTranslations,C=e.EntitySearchDirection,F=e.entitySearchDirectionTranslations,k=e.EntityType,L=e.entityFields,T=e.PageComponent,I=e.coerceBoolean,N=e.MessageType,S=e.messageTypeNames,q=e,A=e.AlarmStatus,M=e.alarmStatusTranslations,E=e.SharedModule,G=e.AggregationType,D=e.aggregationTranslations,V=e.NotificationType,w=e.SlackChanelType,P=e.SlackChanelTypesTranslateMap},function(e){R=e},function(e){O=e,_=e.Validators,B=e.NgControl,K=e.NG_VALUE_ACCESSOR,z=e.NG_VALIDATORS,U=e.FormArray,H=e.FormGroup},function(e){j=e,$=e.DOCUMENT,Q=e.CommonModule},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e},function(e){ae=e.getCurrentAuthState,ie=e,le=e.isEqual,se=e.isDefinedAndNotNull,me=e.deepTrim,pe=e.isObject,ue=e.isNotEmptyStr},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.ENTER,be=e.COMMA,he=e.SEMICOLON},function(e){ve=e},function(e){Ce=e},function(e){Fe=e},function(e){ke=e},function(e){Le=e.coerceBooleanProperty,Te=e.coerceElement,Ie=e.coerceNumberProperty},function(e){Ne=e},function(e){Se=e},function(e){qe=e},function(e){Ae=e},function(e){Me=e.tap,Ee=e.map,Ge=e.startWith,De=e.mergeMap,Ve=e.share,we=e.takeUntil,Pe=e.auditTime},function(e){Re=e},function(e){Oe=e},function(e){_e=e.HomeComponentsModule},function(e){Be=e.__decorate},function(e){Ke=e.Subject,ze=e.takeUntil,Ue=e.of,He=e.EMPTY,je=e.fromEvent},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e},function(e){pt=e},function(e){ut=e.normalizePassiveListenerOptions,dt=e}],execute:function(){class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ft extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[_.required]]})}}e("CheckPointConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[_.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===b.JS?[_.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===b.TBEL?[_.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class bt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(h),this.alarmSeverityTranslationMap=v,this.separatorKeysCodes=[xe,be,he],this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([_.required]),this.createAlarmConfigForm.get("severity").setValidators([_.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==b.TBEL||this.tbelEnabled||(r=b.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===b.JS?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===b.TBEL?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class ht extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[_.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==k.DEVICE&&t!==k.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([_.required,_.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([_.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",vt),vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,_.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,_.required]})}}e("DeviceProfileConfigComponent",Ct),Ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ct,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function",this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[_.required,_.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[_.required,_.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}var kt;e("GeneratorConfigComponent",Ft),Ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ft,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ke.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(kt||(kt={}));const Lt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer"],[kt.TENANT,"tb.rulenode.originator-tenant"],[kt.RELATED,"tb.rulenode.originator-related"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[kt.ENTITY,"tb.rulenode.originator-entity"]]),Tt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[kt.TENANT,"tb.rulenode.originator-tenant-desc"],[kt.RELATED,"tb.rulenode.originator-related-entity-desc"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[kt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),It=[L.createdTime,L.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},L.firstName,L.lastName,L.email,L.title,L.country,L.state,L.city,L.address,L.address2,L.zip,L.phone,L.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Nt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var St;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(St||(St={}));const qt=new Map([[St.CIRCLE,"tb.rulenode.perimeter-circle"],[St.POLYGON,"tb.rulenode.perimeter-polygon"]]);var At;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(At||(At={}));const Mt=new Map([[At.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[At.SECONDS,"tb.rulenode.time-unit-seconds"],[At.MINUTES,"tb.rulenode.time-unit-minutes"],[At.HOURS,"tb.rulenode.time-unit-hours"],[At.DAYS,"tb.rulenode.time-unit-days"]]);var Et;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(Et||(Et={}));const Gt=new Map([[Et.METER,"tb.rulenode.range-unit-meter"],[Et.KILOMETER,"tb.rulenode.range-unit-kilometer"],[Et.FOOT,"tb.rulenode.range-unit-foot"],[Et.MILE,"tb.rulenode.range-unit-mile"],[Et.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Dt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Dt||(Dt={}));const Vt=new Map([[Dt.ID,"tb.rulenode.entity-details-id"],[Dt.TITLE,"tb.rulenode.entity-details-title"],[Dt.COUNTRY,"tb.rulenode.entity-details-country"],[Dt.STATE,"tb.rulenode.entity-details-state"],[Dt.CITY,"tb.rulenode.entity-details-city"],[Dt.ZIP,"tb.rulenode.entity-details-zip"],[Dt.ADDRESS,"tb.rulenode.entity-details-address"],[Dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Dt.PHONE,"tb.rulenode.entity-details-phone"],[Dt.EMAIL,"tb.rulenode.entity-details-email"],[Dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var wt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(wt||(wt={}));const Pt=new Map([[wt.FIRST,"tb.rulenode.first"],[wt.LAST,"tb.rulenode.last"],[wt.ALL,"tb.rulenode.all"]]),Rt=new Map([[wt.FIRST,"tb.rulenode.first-mode-hint"],[wt.LAST,"tb.rulenode.last-mode-hint"],[wt.ALL,"tb.rulenode.all-mode-hint"]]);var Ot,_t;!function(e){e.ASC="ASC",e.DESC="DESC"}(Ot||(Ot={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(_t||(_t={}));const Bt=new Map([[_t.ATTRIBUTES,"tb.rulenode.attributes"],[_t.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[_t.FIELDS,"tb.rulenode.fields"]]),Kt=new Map([[_t.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[_t.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[_t.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),zt=new Map([[Ot.ASC,"tb.rulenode.ascending"],[Ot.DESC,"tb.rulenode.descending"]]);var Ut;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Ut||(Ut={}));const Ht=new Map([[Ut.STANDARD,"tb.rulenode.sqs-queue-standard"],[Ut.FIFO,"tb.rulenode.sqs-queue-fifo"]]),jt=["anonymous","basic","cert.PEM"],$t=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Qt=["sas","cert.PEM"],Jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Yt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Yt||(Yt={}));const Wt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Zt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Xt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Xt||(Xt={}));const en=new Map([[Xt.CUSTOM,{value:Xt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Xt.ADD,{value:Xt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Xt.SUB,{value:Xt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Xt.MULT,{value:Xt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Xt.DIV,{value:Xt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Xt.SIN,{value:Xt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.SINH,{value:Xt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Xt.COS,{value:Xt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.COSH,{value:Xt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Xt.TAN,{value:Xt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Xt.TANH,{value:Xt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ACOS,{value:Xt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Xt.ASIN,{value:Xt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN,{value:Xt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN2,{value:Xt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Xt.EXP,{value:Xt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Xt.EXPM1,{value:Xt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Xt.SQRT,{value:Xt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Xt.CBRT,{value:Xt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Xt.GET_EXP,{value:Xt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Xt.HYPOT,{value:Xt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Xt.LOG,{value:Xt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG10,{value:Xt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG1P,{value:Xt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Xt.CEIL,{value:Xt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR,{value:Xt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR_DIV,{value:Xt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Xt.FLOOR_MOD,{value:Xt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Xt.ABS,{value:Xt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Xt.MIN,{value:Xt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Xt.MAX,{value:Xt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Xt.POW,{value:Xt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Xt.SIGNUM,{value:Xt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Xt.RAD,{value:Xt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Xt.DEG,{value:Xt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var tn,nn,rn;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(tn||(tn={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(nn||(nn={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(rn||(rn={}));const on=new Map([[rn.DATA,"tb.rulenode.message-to-metadata"],[rn.METADATA,"tb.rulenode.metadata-to-message"]]),an=(new Map([[rn.DATA,"tb.rulenode.from-message"],[rn.METADATA,"tb.rulenode.from-metadata"]]),new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.metadata"]])),ln=new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.message-metadata"]]),sn=new Map([[tn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[tn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[tn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[tn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[tn.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),mn=new Map([[nn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[nn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[nn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[nn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),pn=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var un,dn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(un||(un={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(dn||(dn={}));const cn=new Map([[un.SHARED_SCOPE,"tb.rulenode.shared-scope"],[un.SERVER_SCOPE,"tb.rulenode.server-scope"],[un.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.keys(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.keys(Et),this.rangeUnitTranslationMap=Gt,this.timeUnits=Object.keys(At),this.timeUnitsTranslationMap=Mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[_.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[_.required]],perimeterType:[e?e.perimeterType:null,[_.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[_.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[_.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoActionConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([_.required])),t||n!==St.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gn extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[_.required,_.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[_.required]]})}}e("MsgCountConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([_.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([_.required,_.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToCloudConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class hn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToEdgeConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[_.required,_.min(0)]]})}}e("RpcRequestConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[_.required]],value:[e[n],[_.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[_.required]],value:["",[_.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ne.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[_.required,_.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[_.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ln extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[_.required,_.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],keys:[e?e.keys:null,[_.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Nn extends T{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=en,this.ArgumentType=tn,this.attributeScopeMap=cn,this.argumentTypeMap=sn,this.arguments=Object.values(tn),this.attributeScope=Object.values(un),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Xt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([_.minLength(this.minArgs),_.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===tn.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==tn.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(pn[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:qe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:qe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Ae.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Ae.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Ae.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Sn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...en.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(Me((e=>{let t;t="string"==typeof e&&Xt[e]?Xt[e]:null,this.updateView(t)})),Ee((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=en.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class qn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Xt,this.ArgumentTypeResult=nn,this.argumentTypeResultMap=mn,this.attributeScopeMap=cn,this.argumentsResult=Object.values(nn),this.attributeScopeResult=Object.values(dn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[_.required]],arguments:[e?e.arguments:null,[_.required]],customFunction:[e?e.customFunction:"",[_.required]],result:this.fb.group({type:[e?e.result.type:null,[_.required]],attributeScope:[e?e.result.attributeScope:null,[_.required]],key:[e?e.result.key:"",[_.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Xt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===nn.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Sn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class An{constructor(){this.textAlign="left"}}e("ExampleHintComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Mn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new Ke,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Mn.prototype,"disabled",void 0),Be([I()],Mn.prototype,"uniqueKeyValuePairValidator",void 0),Be([I()],Mn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class En extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.entityType=k,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],relationType:[null],deviceTypes:[null,[_.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Gn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Dn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[xe,be,he],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(N))this.messageTypesList.push({name:S.get(N[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ge(""),Ee((e=>e||"")),De((e=>this.fetchMessageTypes(e))),Ve())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ue(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ue(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,deps:[{token:R.Store},{token:X.TranslateService},{token:q.TruncatePipe},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Re.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:q.TruncatePipe},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class Vn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=jt,this.credentialsTypeTranslationsMap=$t,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[_.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){se(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([_.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[_.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(_.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:We.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const wn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Pn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new Ke,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[{token:t.NgZone},{token:$},{token:wn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Pn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[$]}]},{type:void 0,decorators:[{type:p},{type:m,args:[wn]}]}]}});class Rn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Pn}],target:t.ɵɵFactoryTarget.Directive}),Rn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Rn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,decorators:[{type:u,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Pn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:d}],cbOnError:[{type:d}]}});class On{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,deps:[{token:Pn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),On.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:On,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,decorators:[{type:u,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Pn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class _n{}_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),_n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,declarations:[Rn,On],imports:[Q],exports:[Rn,On]}),_n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,imports:[[Q]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,decorators:[{type:c,args:[{imports:[Q],declarations:[Rn,On],exports:[Rn,On]}]}]});class Bn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new Ke,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[_.required]],messageType:[{value:null,disabled:!0},[_.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(ze(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[_.required,_.maxLength(255)]:[_.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Rn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Bn.prototype,"disabled",void 0),Be([I()],Bn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.fb=e,this.translate=t,this.translation=an,this.propagateChange=()=>{},this.destroy$=new Ke,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder},{type:X.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class zn extends T{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ke,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(we(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)se(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(we(this.destroy$)).subscribe((t=>{const n=Nt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],zn.prototype,"disabled",void 0),Be([I()],zn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Un extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Un,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Hn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new Ke,this.separatorKeysCodes=[xe,be,he],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(_.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||se(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Hn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:X.TranslateService},{type:O.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class jn extends T{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new Ke,this.alarmStatus=A,this.alarmStatusTranslations=M}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class $n{}e("RulenodeCoreConfigCommonModule",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),$n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:$n,declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}),$n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,imports:[Q,E,_e]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:c,args:[{declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}]}]});class Qn{}e("RuleNodeCoreConfigActionModule",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Qn,declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}),Qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:c,args:[{declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}]}]});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[_.min(0),_.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:se(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:se(e?.outputValueKey)?e.outputValueKey:null,useCache:!se(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!se(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:se(e?.periodValueKey)?e.periodValueKey:null,round:se(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!se(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return me(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([_.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,me(e)}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[_.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:se(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!se(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:En,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Dt))this.predefinedValues.push({value:Dt[e],name:this.translate.instant(Vt.get(Dt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=se(e?.addToMetadata)?e.addToMetadata?rn.METADATA:rn.DATA:e?.fetchTo?e.fetchTo:rn.DATA,{detailsList:se(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he],this.aggregationTypes=G,this.aggregations=Object.values(G),this.aggregationTypesTranslations=D,this.fetchMode=wt,this.samplingOrders=Object.values(Ot),this.samplingOrdersTranslate=zt,this.timeUnits=Object.values(At),this.timeUnitsTranslationMap=Mt,this.deduplicationStrategiesHintTranslations=Rt,this.headerOptions=[],this.timeUnitMap={[At.MILLISECONDS]:1,[At.SECONDS]:1e3,[At.MINUTES]:6e4,[At.HOURS]:36e5,[At.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Pt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Pt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[_.required]],aggregation:[e.aggregation,[_.required]],fetchMode:[e.fetchMode,[_.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,me(e)}prepareInputConfig(e){return pe(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:se(e?.aggregation)?e.aggregation:G.NONE,fetchMode:se(e?.fetchMode)?e.fetchMode:wt.FIRST,orderBy:se(e?.orderBy)?e.orderBy:Ot.ASC,limit:se(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!se(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:se(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:se(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:At.MINUTES,endInterval:se(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:se(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:At.MINUTES},startIntervalPattern:se(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:se(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===wt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([_.required,_.min(2),_.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===wt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===G.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,tellFailureIfAbsent:!!se(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:se(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class tr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of It)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return me(e)}prepareInputConfig(e){return{dataMapping:se(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:se(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[_.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class nr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=_t,this.msgMetadataLabelTranslations=Kt,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(It))this.originatorFields.push({value:It[e].value,name:this.translate.instant(It[e].name)});for(const e of Bt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===_t.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,me(e)}prepareInputConfig(e){let t,n,r={[L.name.value]:`relatedEntity${this.translate.instant(L.name.name)}`},o={serialNumber:"sn"};return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,t===_t.FIELDS?r=n:o=n,{relationsQuery:se(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[_.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[_.required]],svMap:[e.svMap,[_.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===_t.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:nr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class rr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class ar{}e("RulenodeCoreConfigEnrichmentModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:ar,declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:c,args:[{declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}]}]});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Qt,this.azureIotHubCredentialsTypeTranslationsMap=Jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[_.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[_.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([_.required]);break;case"cert.PEM":t.get("privateKey").setValidators([_.required]),t.get("privateKeyFileName").setValidators([_.required]),t.get("cert").setValidators([_.required]),t.get("certFileName").setValidators([_.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:We.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Wt,this.ToByteStandartCharsetTypeTranslationMap=Zt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[_.required]],retries:[e?e.retries:null,[_.min(0)]],batchSize:[e?e.batchSize:null,[_.min(0)]],linger:[e?e.linger:null,[_.min(0)]],bufferMemory:[e?e.bufferMemory:null,[_.min(0)]],acks:[e?e.acks:null,[_.required]],keySerializer:[e?e.keySerializer:null,[_.required]],valueSerializer:[e?e.valueSerializer:null,[_.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([_.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ue(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){ue(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=V,this.entityType=k}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[_.required]],targets:[e?e.targets:[],[_.required]]})}}e("NotificationConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:rt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ot.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[_.required]],topicName:[e?e.topicName:null,[_.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[_.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[_.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[_.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[_.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Yt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[_.required]],requestMethod:[e?e.requestMethod:null,[_.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[_.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[_.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[_.required,_.min(1),_.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([_.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([_.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([_.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([_.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([_.required,_.min(1),_.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([_.required,_.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[_.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[_.required,_.min(1),_.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:at.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[_.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[_.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([_.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=P}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[_.required]],conversationType:[e?e.conversationType:null,[_.required]],conversation:[e?e.conversation:null,[_.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([_.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:lt.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:lt.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:st.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[_.required]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SnsConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Ut,this.sqsQueueTypes=Object.keys(Ut),this.sqsQueueTypeTranslationsMap=Ht}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[_.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[_.required]],delaySeconds:[e?e.delaySeconds:null,[_.min(0),_.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SqsConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class br{}e("RulenodeCoreConfigExternalModule",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:br,declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}),br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:c,args:[{declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}]}]});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:se(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[_.required]]})}}e("CheckAlarmStatusComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:jn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!se(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(_.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(C),this.entitySearchDirectionTranslationsMap=F}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!se(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:se(e?.direction)?e.direction:null,entityType:se(e?.entityType)?e.entityType:null,entityId:se(e?.entityId)?e.entityId:null,relationType:se(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[_.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[_.required]:[]],relationType:[e.relationType,[_.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.values(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.values(Et),this.rangeUnitTranslationMap=Gt,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:se(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:se(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:se(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!se(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:se(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:se(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:se(e?.centerLongitude)?e.centerLongitude:null,range:se(e?.range)?e.range:null,rangeUnit:se(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:se(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[_.required]],longitudeKeyName:[e.longitudeKeyName,[_.required]],perimeterType:[e.perimeterType,[_.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoFilterConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([_.required]),this.defaultPaddingEnable=!1),t||n!==St.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:se(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[_.required]]})}}e("MessageTypeConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Dn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.TENANT,k.CUSTOMER,k.USER,k.DASHBOARD,k.RULE_CHAIN,k.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:se(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[_.required]]})}}e("OriginatorTypeConfigComponent",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Lr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:pt.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Nr{}e("RuleNodeCoreConfigFilterModule",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Nr,declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}),Nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,decorators:[{type:c,args:[{declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}]}]});class Sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=kt,this.originatorSources=Object.keys(kt),this.originatorSourceTranslationMap=Lt,this.originatorSourceDescTranslationMap=Tt,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.USER,k.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===kt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([_.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===kt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([_.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class qr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[_.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,deps:[{token:R.Store},{token:O.FormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -const Ar=ut({passive:!0});class Mr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return He;const t=Te(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new Ke,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Ar),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Ar)}}),r}stopMonitoring(e){const t=Te(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[{token:dt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Mr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:dt.Platform},{type:t.NgZone}]}});class Er{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,deps:[{token:t.ElementRef},{token:Mr}],target:t.ɵɵFactoryTarget.Directive}),Er.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Er,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,decorators:[{type:u,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Mr}]},propDecorators:{cdkAutofill:[{type:d}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -class Gr{get minRows(){return this._minRows}set minRows(e){this._minRows=Ie(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Ie(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Le(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new Ke,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();je(e,"resize").pipe(Pe(16),we(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,deps:[{token:t.ElementRef},{token:dt.Platform},{token:t.NgZone},{token:$,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Gr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,decorators:[{type:u,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:dt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[$]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -class Dr{}Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Dr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,declarations:[Er,Gr],exports:[Er,Gr]}),Dr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,decorators:[{type:c,args:[{declarations:[Er,Gr],exports:[Er,Gr]}]}]});class Vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[_.required]],toTemplate:[e?e.toTemplate:null,[_.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[_.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[_.required]],bodyTemplate:[e?e.bodyTemplate:null,[_.required]]})}prepareInputConfig(e){return{fromTemplate:se(e?.fromTemplate)?e.fromTemplate:null,toTemplate:se(e?.toTemplate)?e.toTemplate:null,ccTemplate:se(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:se(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:se(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:se(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:se(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:se(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class wr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=on;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.copyFrom?rn.METADATA:rn.DATA:se(e?.copyFrom)?e.copyFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Pr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=ln;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[_.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.renameIn)?e?.renameIn:rn.DATA,{renameKeysMapping:se(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[_.required]]})}}e("NodeJsonPathConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Or extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=an;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.deleteFrom)?e?.deleteFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE,this.deduplicationStrategie=wt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Pt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[se(e?.interval)?e.interval:null,[_.required,_.min(1)]],strategy:[se(e?.strategy)?e.strategy:null,[_.required]],outMsgType:[se(e?.outMsgType)?e.outMsgType:null,[_.required]],queueName:[se(e?.queueName)?e.queueName:null,[_.required]],maxPendingMsgs:[se(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e3)]],maxRetries:[se(e?.maxRetries)?e.maxRetries:null,[_.required,_.min(0),_.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1})),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e}),this.deduplicationConfigForm.get("queueName").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Br{}e("RulenodeCoreConfigTransformModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}]}]});class Kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=k}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[_.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class zr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Ur,declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,decorators:[{type:c,args:[{declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}]}]});class Hr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one.","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,deps:[{token:X.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hr,declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,imports:[Q,E,Qn,Nr,ar,br,Br,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,decorators:[{type:c,args:[{declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}]}],ctorParameters:function(){return[{type:X.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,d,u,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,w,V,P,R,O,_,B,K,z,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,de,ue,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,we,Ve,Pe,Re,Oe,_e,Be,Ke,ze,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,d=e.Directive,u=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ScriptLanguage,b=e.AlarmSeverity,h=e.alarmSeverityTranslations,v=e.EntitySearchDirection,C=e.entitySearchDirectionTranslations,F=e.EntityType,k=e.entityFields,L=e.PageComponent,T=e.coerceBoolean,I=e.MessageType,N=e.messageTypeNames,S=e,q=e.AlarmStatus,A=e.alarmStatusTranslations,M=e.SharedModule,E=e.AggregationType,G=e.aggregationTranslations,D=e.NotificationType,w=e.SlackChanelType,V=e.SlackChanelTypesTranslateMap},function(e){P=e},function(e){R=e,O=e.Validators,_=e.NgControl,B=e.NG_VALUE_ACCESSOR,K=e.NG_VALIDATORS,z=e.FormArray,U=e.FormGroup},function(e){H=e,j=e.DOCUMENT,$=e.CommonModule},function(e){Q=e},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e.getCurrentAuthState,oe=e,ae=e.isEqual,ie=e.isDefinedAndNotNull,le=e.deepTrim,se=e.isObject,me=e.isNotEmptyStr},function(e){pe=e},function(e){de=e},function(e){ue=e},function(e){ce=e},function(e){fe=e},function(e){ge=e.ENTER,ye=e.COMMA,xe=e.SEMICOLON},function(e){be=e},function(e){he=e},function(e){ve=e},function(e){Ce=e},function(e){Fe=e.coerceBooleanProperty,ke=e.coerceElement,Le=e.coerceNumberProperty},function(e){Te=e},function(e){Ie=e},function(e){Ne=e},function(e){Se=e},function(e){qe=e.tap,Ae=e.map,Me=e.startWith,Ee=e.mergeMap,Ge=e.share,De=e.takeUntil,we=e.auditTime},function(e){Ve=e},function(e){Pe=e},function(e){Re=e.HomeComponentsModule},function(e){Oe=e.__decorate},function(e){_e=e.Subject,Be=e.takeUntil,Ke=e.of,ze=e.EMPTY,Ue=e.fromEvent},function(e){He=e},function(e){je=e},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e.normalizePassiveListenerOptions,pt=e}],execute:function(){class dt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",dt),dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dt,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ut extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ut),ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ut,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[O.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===x.JS?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===x.TBEL?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class gt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(b),this.alarmSeverityTranslationMap=h,this.separatorKeysCodes=[ge,ye,xe],this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([O.required]),this.createAlarmConfigForm.get("severity").setValidators([O.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==x.TBEL||this.tbelEnabled||(r=x.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===x.JS?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===x.TBEL?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[O.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==F.DEVICE&&t!==F.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([O.required,O.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([O.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,O.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,O.required]})}}e("DeviceProfileConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ht extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function"}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[O.required,O.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[O.required,O.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}var vt;e("GeneratorConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ce.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(vt||(vt={}));const Ct=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer"],[vt.TENANT,"tb.rulenode.originator-tenant"],[vt.RELATED,"tb.rulenode.originator-related"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[vt.ENTITY,"tb.rulenode.originator-entity"]]),Ft=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[vt.TENANT,"tb.rulenode.originator-tenant-desc"],[vt.RELATED,"tb.rulenode.originator-related-entity-desc"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[vt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),kt=[k.createdTime,k.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},k.firstName,k.lastName,k.email,k.title,k.country,k.state,k.city,k.address,k.address2,k.zip,k.phone,k.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Lt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var Tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(Tt||(Tt={}));const It=new Map([[Tt.CIRCLE,"tb.rulenode.perimeter-circle"],[Tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var Nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(Nt||(Nt={}));const St=new Map([[Nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[Nt.SECONDS,"tb.rulenode.time-unit-seconds"],[Nt.MINUTES,"tb.rulenode.time-unit-minutes"],[Nt.HOURS,"tb.rulenode.time-unit-hours"],[Nt.DAYS,"tb.rulenode.time-unit-days"]]);var qt;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(qt||(qt={}));const At=new Map([[qt.METER,"tb.rulenode.range-unit-meter"],[qt.KILOMETER,"tb.rulenode.range-unit-kilometer"],[qt.FOOT,"tb.rulenode.range-unit-foot"],[qt.MILE,"tb.rulenode.range-unit-mile"],[qt.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Mt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Mt||(Mt={}));const Et=new Map([[Mt.ID,"tb.rulenode.entity-details-id"],[Mt.TITLE,"tb.rulenode.entity-details-title"],[Mt.COUNTRY,"tb.rulenode.entity-details-country"],[Mt.STATE,"tb.rulenode.entity-details-state"],[Mt.CITY,"tb.rulenode.entity-details-city"],[Mt.ZIP,"tb.rulenode.entity-details-zip"],[Mt.ADDRESS,"tb.rulenode.entity-details-address"],[Mt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Mt.PHONE,"tb.rulenode.entity-details-phone"],[Mt.EMAIL,"tb.rulenode.entity-details-email"],[Mt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var Gt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(Gt||(Gt={}));const Dt=new Map([[Gt.FIRST,"tb.rulenode.first"],[Gt.LAST,"tb.rulenode.last"],[Gt.ALL,"tb.rulenode.all"]]),wt=new Map([[Gt.FIRST,"tb.rulenode.first-mode-hint"],[Gt.LAST,"tb.rulenode.last-mode-hint"],[Gt.ALL,"tb.rulenode.all-mode-hint"]]);var Vt,Pt;!function(e){e.ASC="ASC",e.DESC="DESC"}(Vt||(Vt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(Pt||(Pt={}));const Rt=new Map([[Pt.ATTRIBUTES,"tb.rulenode.attributes"],[Pt.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[Pt.FIELDS,"tb.rulenode.fields"]]),Ot=new Map([[Pt.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[Pt.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[Pt.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),_t=new Map([[Vt.ASC,"tb.rulenode.ascending"],[Vt.DESC,"tb.rulenode.descending"]]);var Bt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Bt||(Bt={}));const Kt=new Map([[Bt.STANDARD,"tb.rulenode.sqs-queue-standard"],[Bt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),zt=["anonymous","basic","cert.PEM"],Ut=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Ht=["sas","cert.PEM"],jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var $t;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}($t||($t={}));const Qt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Jt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Yt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Yt||(Yt={}));const Wt=new Map([[Yt.CUSTOM,{value:Yt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Yt.ADD,{value:Yt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Yt.SUB,{value:Yt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Yt.MULT,{value:Yt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Yt.DIV,{value:Yt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Yt.SIN,{value:Yt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.SINH,{value:Yt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Yt.COS,{value:Yt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.COSH,{value:Yt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Yt.TAN,{value:Yt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Yt.TANH,{value:Yt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ACOS,{value:Yt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Yt.ASIN,{value:Yt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN,{value:Yt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN2,{value:Yt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Yt.EXP,{value:Yt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Yt.EXPM1,{value:Yt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Yt.SQRT,{value:Yt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Yt.CBRT,{value:Yt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Yt.GET_EXP,{value:Yt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Yt.HYPOT,{value:Yt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Yt.LOG,{value:Yt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG10,{value:Yt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG1P,{value:Yt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Yt.CEIL,{value:Yt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR,{value:Yt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR_DIV,{value:Yt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Yt.FLOOR_MOD,{value:Yt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Yt.ABS,{value:Yt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Yt.MIN,{value:Yt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Yt.MAX,{value:Yt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Yt.POW,{value:Yt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Yt.SIGNUM,{value:Yt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Yt.RAD,{value:Yt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Yt.DEG,{value:Yt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Zt,Xt,en;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(Zt||(Zt={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(Xt||(Xt={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(en||(en={}));const tn=new Map([[en.DATA,"tb.rulenode.message-to-metadata"],[en.METADATA,"tb.rulenode.metadata-to-message"]]),nn=(new Map([[en.DATA,"tb.rulenode.from-message"],[en.METADATA,"tb.rulenode.from-metadata"]]),new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.metadata"]])),rn=new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.message-metadata"]]),on=new Map([[Zt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[Zt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[Zt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[Zt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[Zt.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),an=new Map([[Xt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[Xt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[Xt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[Xt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),ln=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var sn,mn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(sn||(sn={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(mn||(mn={}));const pn=new Map([[sn.SHARED_SCOPE,"tb.rulenode.shared-scope"],[sn.SERVER_SCOPE,"tb.rulenode.server-scope"],[sn.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class dn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.keys(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.keys(qt),this.rangeUnitTranslationMap=At,this.timeUnits=Object.keys(Nt),this.timeUnitsTranslationMap=St}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[O.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[O.required]],perimeterType:[e?e.perimeterType:null,[O.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[O.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[O.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoActionConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([O.required])),t||n!==Tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class un extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:un,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[O.required,O.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[O.required]]})}}e("MsgCountConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([O.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([O.required,O.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToCloudConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToEdgeConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[O.required,O.min(0)]]})}}e("RpcRequestConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[O.required]],value:[e[n],[O.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[O.required]],value:["",[O.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Te.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[O.required,O.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[O.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[O.required,O.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],keys:[e?e.keys:null,[O.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Ln extends L{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=Wt,this.ArgumentType=Zt,this.attributeScopeMap=pn,this.argumentTypeMap=on,this.arguments=Object.values(Zt),this.attributeScope=Object.values(sn),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Yt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([O.minLength(this.minArgs),O.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Zt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Zt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(ln[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ne.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:Ne.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Se.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Se.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Se.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Tn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...Wt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(qe((e=>{let t;t="string"==typeof e&&Yt[e]?Yt[e]:null,this.updateView(t)})),Ae((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=Wt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Yt,this.ArgumentTypeResult=Xt,this.argumentTypeResultMap=an,this.attributeScopeMap=pn,this.argumentsResult=Object.values(Xt),this.attributeScopeResult=Object.values(mn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[O.required]],arguments:[e?e.arguments:null,[O.required]],customFunction:[e?e.customFunction:"",[O.required]],result:this.fb.group({type:[e?e.result.type:null,[O.required]],attributeScope:[e?e.result.attributeScope:null,[O.required]],key:[e?e.result.key:"",[O.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Yt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Xt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ln,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Tn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Nn{constructor(){this.textAlign="left"}}e("ExampleHintComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Sn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new _e,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Sn.prototype,"disabled",void 0),Oe([T()],Sn.prototype,"uniqueKeyValuePairValidator",void 0),Oe([T()],Sn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class qn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.entityType=F,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],relationType:[null],deviceTypes:[null,[O.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:je.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class An extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Mn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[ge,ye,xe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(I))this.messageTypesList.push({name:N.get(I[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Me(""),Ae((e=>e||"")),Ee((e=>this.fetchMessageTypes(e))),Ge())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:P.Store},{token:Z.TranslateService},{token:S.TruncatePipe},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:S.TruncatePipe},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class En extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=zt,this.credentialsTypeTranslationsMap=Ut,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[O.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){ie(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([O.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[O.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(O.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Je.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const Gn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Dn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new _e,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,deps:[{token:t.NgZone},{token:j},{token:Gn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Dn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[j]}]},{type:void 0,decorators:[{type:p},{type:m,args:[Gn]}]}]}});class wn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Dn}],target:t.ɵɵFactoryTarget.Directive}),wn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:wn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,decorators:[{type:d,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Dn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:u}],cbOnError:[{type:u}]}});class Vn{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,deps:[{token:Dn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),Vn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Vn,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,decorators:[{type:d,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Dn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class Pn{}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Pn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,declarations:[wn,Vn],imports:[$],exports:[wn,Vn]}),Pn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,imports:[[$]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:c,args:[{imports:[$],declarations:[wn,Vn],exports:[wn,Vn]}]}]});class Rn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new _e,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[O.required]],messageType:[{value:null,disabled:!0},[O.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(Be(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[O.required,O.maxLength(255)]:[O.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,deps:[{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:wn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Rn.prototype,"disabled",void 0),Oe([T()],Rn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class On{constructor(e,t){this.fb=e,this.translate=t,this.translation=nn,this.propagateChange=()=>{},this.destroy$=new _e,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,deps:[{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:On,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder},{type:Z.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class _n extends L{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new _e,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(De(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)ie(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(De(this.destroy$)).subscribe((t=>{const n=Lt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_n,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],_n.prototype,"disabled",void 0),Oe([T()],_n.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Bn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new _e,this.separatorKeysCodes=[ge,ye,xe],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(O.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||ie(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:Z.TranslateService},{type:R.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class zn extends L{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new _e,this.alarmStatus=q,this.alarmStatusTranslations=A}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Un{}e("RulenodeCoreConfigCommonModule",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Un.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Un,declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}),Un.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,imports:[$,M,Re]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:c,args:[{declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}]}]});class Hn{}e("RuleNodeCoreConfigActionModule",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hn,declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}),Hn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:c,args:[{declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}]}]});class jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[O.min(0),O.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:ie(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:ie(e?.outputValueKey)?e.outputValueKey:null,useCache:!ie(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!ie(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:ie(e?.periodValueKey)?e.periodValueKey:null,round:ie(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!ie(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return le(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([O.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class $n extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,le(e)}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:$n,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Qn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[O.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:ie(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!ie(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Qn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:qn,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Mt))this.predefinedValues.push({value:Mt[e],name:this.translate.instant(Et.get(Mt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=ie(e?.addToMetadata)?e.addToMetadata?en.METADATA:en.DATA:e?.fetchTo?e.fetchTo:en.DATA,{detailsList:ie(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe],this.aggregationTypes=E,this.aggregations=Object.values(E),this.aggregationTypesTranslations=G,this.fetchMode=Gt,this.samplingOrders=Object.values(Vt),this.samplingOrdersTranslate=_t,this.timeUnits=Object.values(Nt),this.timeUnitsTranslationMap=St,this.deduplicationStrategiesHintTranslations=wt,this.headerOptions=[],this.timeUnitMap={[Nt.MILLISECONDS]:1,[Nt.SECONDS]:1e3,[Nt.MINUTES]:6e4,[Nt.HOURS]:36e5,[Nt.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Dt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Dt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[O.required]],aggregation:[e.aggregation,[O.required]],fetchMode:[e.fetchMode,[O.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,le(e)}prepareInputConfig(e){return se(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:ie(e?.aggregation)?e.aggregation:E.NONE,fetchMode:ie(e?.fetchMode)?e.fetchMode:Gt.FIRST,orderBy:ie(e?.orderBy)?e.orderBy:Vt.ASC,limit:ie(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!ie(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:ie(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:ie(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:Nt.MINUTES,endInterval:ie(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:ie(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:Nt.MINUTES},startIntervalPattern:ie(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:ie(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===Gt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([O.required,O.min(2),O.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===Gt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===E.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,tellFailureIfAbsent:!!ie(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:ie(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of kt)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return le(e)}prepareInputConfig(e){return{dataMapping:ie(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:ie(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[O.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=Pt,this.msgMetadataLabelTranslations=Ot,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(kt))this.originatorFields.push({value:kt[e].value,name:this.translate.instant(kt[e].name)});for(const e of Rt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===Pt.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,le(e)}prepareInputConfig(e){let t,n,r={[k.name.value]:`relatedEntity${this.translate.instant(k.name.name)}`},o={serialNumber:"sn"};return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,t===Pt.FIELDS?r=n:o=n,{relationsQuery:ie(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[O.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[O.required]],svMap:[e.svMap,[O.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class nr{}e("RulenodeCoreConfigEnrichmentModule",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:nr,declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}),nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:c,args:[{declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}]}]});class rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Ht,this.azureIotHubCredentialsTypeTranslationsMap=jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[O.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[O.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([O.required]);break;case"cert.PEM":t.get("privateKey").setValidators([O.required]),t.get("privateKeyFileName").setValidators([O.required]),t.get("cert").setValidators([O.required]),t.get("certFileName").setValidators([O.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Je.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Qt,this.ToByteStandartCharsetTypeTranslationMap=Jt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[O.required]],retries:[e?e.retries:null,[O.min(0)]],batchSize:[e?e.batchSize:null,[O.min(0)]],linger:[e?e.linger:null,[O.min(0)]],bufferMemory:[e?e.bufferMemory:null,[O.min(0)]],acks:[e?e.acks:null,[O.required]],keySerializer:[e?e.keySerializer:null,[O.required]],valueSerializer:[e?e.valueSerializer:null,[O.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([O.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ar extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&me(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){me(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ar,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=D,this.entityType=F}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[O.required]],targets:[e?e.targets:[],[O.required]]})}}e("NotificationConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:tt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nt.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[O.required]],topicName:[e?e.topicName:null,[O.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[O.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[O.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[O.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[O.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys($t)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[O.required]],requestMethod:[e?e.requestMethod:null,[O.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[O.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[O.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[O.required,O.min(1),O.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([O.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([O.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([O.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([O.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([O.required,O.min(1),O.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([O.required,O.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[O.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[O.required,O.min(1),O.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:rt.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[O.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[O.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([O.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ot.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=V}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[O.required]],conversationType:[e?e.conversationType:null,[O.required]],conversation:[e?e.conversation:null,[O.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([O.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:at.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:at.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[O.required]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SnsConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Bt,this.sqsQueueTypes=Object.keys(Bt),this.sqsQueueTypeTranslationsMap=Kt}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[O.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[O.required]],delaySeconds:[e?e.delaySeconds:null,[O.min(0),O.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SqsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gr{}e("RulenodeCoreConfigExternalModule",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:gr,declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}),gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:c,args:[{declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}]}]});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:ie(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[O.required]]})}}e("CheckAlarmStatusComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:zn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!ie(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(O.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class br extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(v),this.entitySearchDirectionTranslationsMap=C}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!ie(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:ie(e?.direction)?e.direction:null,entityType:ie(e?.entityType)?e.entityType:null,entityId:ie(e?.entityId)?e.entityId:null,relationType:ie(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[O.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[O.required]:[]],relationType:[e.relationType,[O.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:br,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.values(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.values(qt),this.rangeUnitTranslationMap=At,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:ie(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:ie(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:ie(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!ie(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:ie(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:ie(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:ie(e?.centerLongitude)?e.centerLongitude:null,range:ie(e?.range)?e.range:null,rangeUnit:ie(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:ie(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[O.required]],longitudeKeyName:[e.longitudeKeyName,[O.required]],perimeterType:[e.perimeterType,[O.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoFilterConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([O.required]),this.defaultPaddingEnable=!1),t||n!==Tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:ie(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[O.required]]})}}e("MessageTypeConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Mn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.TENANT,F.CUSTOMER,F.USER,F.DASHBOARD,F.RULE_CHAIN,F.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:ie(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[O.required]]})}}e("OriginatorTypeConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:st.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class kr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Lr{}e("RuleNodeCoreConfigFilterModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Lr,declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:c,args:[{declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}]}]});class Tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=vt,this.originatorSources=Object.keys(vt),this.originatorSourceTranslationMap=Ct,this.originatorSourceDescTranslationMap=Ft,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.USER,F.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===vt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([O.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===vt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([O.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[O.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:P.Store},{token:R.FormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + const Nr=mt({passive:!0});class Sr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return ze;const t=ke(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new _e,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Nr),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Nr)}}),r}stopMonitoring(e){const t=ke(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,deps:[{token:pt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Sr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:pt.Platform},{type:t.NgZone}]}});class qr{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,deps:[{token:t.ElementRef},{token:Sr}],target:t.ɵɵFactoryTarget.Directive}),qr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:qr,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,decorators:[{type:d,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Sr}]},propDecorators:{cdkAutofill:[{type:u}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Ar{get minRows(){return this._minRows}set minRows(e){this._minRows=Le(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Le(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Fe(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new _e,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();Ue(e,"resize").pipe(we(16),De(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,deps:[{token:t.ElementRef},{token:pt.Platform},{token:t.NgZone},{token:j,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Ar.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,decorators:[{type:d,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:pt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[j]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Mr{}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,declarations:[qr,Ar],exports:[qr,Ar]}),Mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:c,args:[{declarations:[qr,Ar],exports:[qr,Ar]}]}]});class Er extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[O.required]],toTemplate:[e?e.toTemplate:null,[O.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[O.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[O.required]],bodyTemplate:[e?e.bodyTemplate:null,[O.required]]})}prepareInputConfig(e){return{fromTemplate:ie(e?.fromTemplate)?e.fromTemplate:null,toTemplate:ie(e?.toTemplate)?e.toTemplate:null,ccTemplate:ie(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:ie(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:ie(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:ie(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:ie(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:ie(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Gr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=tn;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.copyFrom?en.METADATA:en.DATA:ie(e?.copyFrom)?e.copyFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Dr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=rn;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[O.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.renameIn)?e?.renameIn:en.DATA,{renameKeysMapping:ie(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class wr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[O.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Vr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=nn;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.deleteFrom)?e?.deleteFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.deduplicationStrategie=Gt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Dt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[ie(e?.interval)?e.interval:null,[O.required,O.min(1)]],strategy:[ie(e?.strategy)?e.strategy:null,[O.required]],outMsgType:[ie(e?.outMsgType)?e.outMsgType:null,[O.required]],maxPendingMsgs:[ie(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e3)]],maxRetries:[ie(e?.maxRetries)?e.maxRetries:null,[O.required,O.min(0),O.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}):this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Rr{}e("RulenodeCoreConfigTransformModule",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Rr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Rr,declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}),Rr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:c,args:[{declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}]}]});class Or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=F}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[O.required]]})}}e("RuleChainInputComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Br{}e("RuleNodeCoreConfigFlowModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}]}]});class Kr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one.","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Kr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Kr,declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}),Kr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,imports:[$,M,Hn,Lr,nr,gr,Rr,Br]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:c,args:[{declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}]}],ctorParameters:function(){return[{type:Z.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From 83815dce301766165ca0700d7a7683fa5ce34b78 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 8 Jan 2024 16:50:47 +0100 Subject: [PATCH 40/91] set default device conncectivity params from yml for install --- .../DefaultSystemDataLoaderService.java | 48 ++----------------- .../DeviceConnectivityConfiguration.java | 3 +- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 63771f8165..7fea98e7dc 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -85,6 +85,7 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.device.DeviceConnectivityConfiguration; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; @@ -169,6 +170,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Autowired private TimeseriesService tsService; + @Autowired + private DeviceConnectivityConfiguration connectivityConfiguration; + @Value("${state.persistToTelemetry:false}") @Getter private boolean persistActivityToTelemetry; @@ -260,7 +264,6 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { ObjectNode node = JacksonUtil.newObjectNode(); node.put("baseUrl", "http://localhost:8080"); node.put("prohibitDifferentUrl", false); - node.set("connectivity", createDeviceConnectivityConfiguration()); generalSettings.setJsonValue(node); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, generalSettings); @@ -285,51 +288,10 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings connectivitySettings = new AdminSettings(); connectivitySettings.setTenantId(TenantId.SYS_TENANT_ID); connectivitySettings.setKey("connectivity"); - connectivitySettings.setJsonValue(createDeviceConnectivityConfiguration()); + connectivitySettings.setJsonValue(JacksonUtil.valueToTree(connectivityConfiguration.getConnectivity())); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, connectivitySettings); } - private ObjectNode createDeviceConnectivityConfiguration() { - ObjectNode config = JacksonUtil.newObjectNode(); - - ObjectNode http = JacksonUtil.newObjectNode(); - http.put("enabled", true); - http.put("host", ""); - http.put("port", 8080); - config.set("http", http); - - ObjectNode https = JacksonUtil.newObjectNode(); - https.put("enabled", false); - https.put("host", ""); - https.put("port", 443); - config.set("https", https); - - ObjectNode mqtt = JacksonUtil.newObjectNode(); - mqtt.put("enabled", true); - mqtt.put("host", ""); - mqtt.put("port", 1883); - config.set("mqtt", mqtt); - - ObjectNode mqtts = JacksonUtil.newObjectNode(); - mqtts.put("enabled", false); - mqtts.put("host", ""); - mqtts.put("port", 8883); - config.set("mqtts", mqtts); - - ObjectNode coap = JacksonUtil.newObjectNode(); - coap.put("enabled", true); - coap.put("host", ""); - coap.put("port", 5683); - config.set("coap", coap); - - ObjectNode coaps = JacksonUtil.newObjectNode(); - coaps.put("enabled", false); - coaps.put("host", ""); - coaps.put("port", 5684); - config.set("coaps", coaps); - return config; - } - @Override public void createRandomJwtSettings() throws Exception { jwtSettingsService.createRandomJwtSettings(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java index df55eee2e4..3e40450035 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java @@ -18,14 +18,15 @@ package org.thingsboard.server.dao.device; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import java.util.HashMap; import java.util.Map; +@Profile("install") @Configuration @ConfigurationProperties(prefix = "device") @Data -@Deprecated(since = "3.6.1") public class DeviceConnectivityConfiguration { private Map connectivity = new HashMap<>(); From f7fc127e3662501cd048e710926180391dd7b22e Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 8 Jan 2024 19:34:07 +0200 Subject: [PATCH 41/91] UI: Implement bar chart with labels widget. Improve echarts initialization. Improve timewindow component to set preferred aggregation interval for selected timewindow. Fix data aggregator to schedule interval with maximum allowed setTimeout delay. --- .../json/system/widget_bundles/charts.json | 2 +- .../widget_types/bar_chart_with_labels.json | 20 +- ui-ngx/src/app/core/api/data-aggregator.ts | 6 +- .../basic/basic-widget-config.module.ts | 12 +- ...rt-with-labels-basic-config.component.html | 248 ++++++++++++++ ...hart-with-labels-basic-config.component.ts | 323 ++++++++++++++++++ .../doughnut-basic-config.component.html | 16 +- .../chart/doughnut-basic-config.component.ts | 8 +- .../range-chart-basic-config.component.html | 14 +- ...ignal-strength-basic-config.component.html | 10 +- .../bar-chart-with-labels-widget.component.ts | 309 +++++++---------- .../bar-chart-with-labels-widget.models.ts | 19 +- .../lib/chart/doughnut-widget.component.ts | 22 +- .../lib/chart/doughnut-widget.models.ts | 23 +- .../widget/lib/chart/echarts-widget.models.ts | 214 ++++++++++++ .../lib/chart/range-chart-widget.component.ts | 127 +------ .../lib/chart/range-chart-widget.models.ts | 16 +- ...with-labels-widget-settings.component.html | 150 ++++++++ ...t-with-labels-widget-settings.component.ts | 170 +++++++++ .../doughnut-widget-settings.component.html | 16 +- .../doughnut-widget-settings.component.ts | 13 +- ...range-chart-widget-settings.component.html | 12 +- .../common/font-settings-panel.component.ts | 13 +- .../common/font-settings.component.ts | 8 +- ...al-strength-widget-settings.component.html | 10 +- .../lib/settings/widget-settings.module.ts | 12 +- .../components/time/timeinterval.component.ts | 12 +- .../assets/locale/locale.constant-en_US.json | 35 +- .../assets/locale/locale.constant-zh_CN.json | 29 +- 29 files changed, 1390 insertions(+), 479 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index 4a3240fdd2..07929028ff 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -11,8 +11,8 @@ "charts.basic_timeseries", "charts.state_chart", "range_chart", - "charts.timeseries_bars_flot", "bar_chart_with_labels", + "charts.timeseries_bars_flot", "cards.aggregated_value_card", "charts.bars", "charts.pie", diff --git a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json index 6120c4f1c5..06ee881c0a 100644 --- a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json +++ b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json @@ -2,8 +2,8 @@ "fqn": "bar_chart_with_labels", "name": "Bar chart with labels", "deprecated": false, - "image": "tb-image:cmFuZ2VfY2hhcnRfc3lzdGVtX3dpZGdldF9pbWFnZS5wbmc=:IlJhbmdlIGNoYXJ0IiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC/VBMVEX////////8/PwAAAD///////+bsfP+wEzu7u73lkzz8/P1eWTT09PN1emRpeOcsvSxsbGQpeLc3NyXl5epqanjXHPLy8tti+OgoKD/wU26urr29vbts0fnkUf39/fIrYP4l02oqKjJroPl5eWUrPPDw8PCwsLJroSQqfKLpfKDn/HU1NSnu/X/tzD/pwNyku//vD//sB3m5ub2jj98mfB2lfD2hTD/rRPu8v3/3qD1fCD3+f7K1vnnjEf1eh30awSWrvOBnfFkhOLld1n1dRX0cxH/9N/1cVvld1jmjEf2izn/qQry9f2Yr/P/+u/+9u+RpuP82r//yGDdM1D3kEPzWD32gSixwfBWeN//2JDzY0v+vkf/siT+5+RBaNr7x6DbYWXxTC96mPD+7N+VqN35tID2emX3oWD3k0fm6/zc5PvV3vq2xveWrfL+8/Hd3d09ZNr/6b/6vZCPj4/2h3TfQl3bKkjaIUD/ujnxQCL0bwrC0PiWqN5Kbt3/79D6zMqGhob/0n/iUWn0aVH+vUPZGjr/tSuwwvZpiOLR0dH+2I97e3v1dWDkcV3fPVnxSCr/qw+Jo/F/m/GLoum3xOj64uZef+H41NoyW9hdfNbJycnxqLT7x5/4no/nb4P/zXDiVm3hS2TlcV3zXEPyUzj+uTTwRCbkbRB+mOaareN5k+FyjuBHbNw4YNn7xr3/47D70LD5t6zumqjngJH/2I+Ojo7lYnf4oWC+mF7utEj2iDTmfSrxRyrunw/kZwLL1vWWrfS/zPORqfP98fKjt/GGofHv7+/+7erK0umHnuKDm+Lf39/t5d7829bm2dT949Dzt8HqwLFse6r4raDsjJz3lIPopHzGpnT4q3DZVmXSNkvnj0LnjD7mgjbjWzHiSzHwRyrunQXv8/3+9POquOWot+Tu4s3u3b3rzrfUxrHu166boa6coK76uKzTvJvoppv6vpDuyYfdboDmkXH1fGffR2H3oV/kbVnnjkHtrTbOIDTiUiLhUCD/rhTuoROM0RHwAAAABXRSTlMg77MAvxFwlo8AAA5CSURBVHja1JtJaBNRGMfj8scXk8MwSYZxoiFhaC9FEQoRA7YHE6K9iMZ4KIoWcTkpqK3oRVH05HISwX1Db66guF48eHHFBfcFQUUQ933BL6PxZZyZRE2+of4aMhPyWvKb73vzf3nQQL9A/z743+lLGoE+Qlea0JLShVA0mFHFwP9Hn0CgL7QwdERgKnGlmY7QBYgNGwY2lleHBjLSNwAIpdlAFPRIQERBsIjcvDGQEUEimqLq0FFysUR4WLKiG5yQiKGiJGIqIJYCKQEGDhV6wAmJCD3VBDWqCxCmrjeBg+7tK06DkQD8Yd3C2ML1YMM/kY2FWM9GsOGfyLLuWOEg2PBPZMW22JotYMM3kYs9sdjbw2DDN5Eta2KxbQWw4ZtIYRmJrAAbfomsXxgjFq4DF36JXCmQB2eQ+CWybHuMKPAFiU8i61bESqy5Ai58EtnYY4l08wWJTyKHuy2R7d3gwieRnmWkwRok/ogsoc6y4FzI84tYsU4wBwm/iBXrP+i5CC74RcqxTnAu5C0RMypgppQ4lCaIlN6CxnKwUBZZcwhsWN/ZE4CeUA3TiCIiEImjoVCs/6T7MNggkXAk1YIo4lGoCaEDiQQIRRGN4fynaWVu3BRskIjRBJ0sbPtaDRR5fm/1jtWrV+/YsXrH+3uCDRJpDpNI5Me+VlwnMYFG8qYz9IvdZ8AFicQjioKmlC4A0JFeNJSuvBRZuxdcBEAIlGcGkUBDWdIVkuy6DCb4c+TqzpmhED0sipvBBL9IMU8WZToXgAd+kSknQhUs7wQP/CKXd1WK5E88BAv8IvnllSKruO6/7CJzFq0KVbJ2ClhgF9nbFbLRdQ4ssIss6LSLFJ+BBXaRYinWZ9LPT3YyBQmviIx19iCpS2QOanK1GCJ4g6R+kQVLUIvO5SE7+SLqgkWkmEcNptwP/c4i1AeDyIGu3VNqDSn+DyL5zp3VZ66M9Zm9WeTcfVpwVJvvtliXInNQBwwiFHU1UkHGOvcaRYqYKoSiAc0mEs2KwB8wZRFF3apdVa8vuRIzfRRZaiAiVMPUDOiq+KN9rQO7an/jo1h3cIJTxCgJIB5FWMR1wBSoTdGax/ku75LIWJ/pU0WEoRr4y32tS1/GjB4zevSYu9eEJ6/vjh5DY8pPNJ6ePl8SPARIIBqZr0ZKFQHiEUATtUXGHh87dtSosaPu7DkrvDh+ZxQNGVt6EHQsne15IngIgKCKGIaigaCDjppMXxz8SW6G55j2oAu58eDBEkGCZExYmCZqc6Qt+JOOHDzYRGOcZPeDgX/OkczEYLJ8iafCnWQ6SNA4G21T8Y9wiGzKyk/WkYE77bN/OPRmkcyx2s2yn2R7u8h4muqybTpa4casScEKkr1SZFbaPn/Hw4VMa9CNzAz8Exwi09sn2q71MbeSXKCquTGpF4lMbfutXxa7lORFeZAcm+xtInTvtZN2KUlrR4VE76zI1Jw9G4h2R0lkrCftKpNmwZ2qic8i0pp2XOtJrQ7brDSoHJ5MH/H6s+NQBQYRucySzHaUJFlhaxPyFMnMgycsIu9ss9irYXJyHtmF0h6tNa69FZ5wiIyjj+hWkun2hs86FX5WJAlXxufavXuLQ2Rqm3s8XIdExrq9raqsAzAvk/XuLQ6RTIcVCcnfS5IdB4kj1muLJI+lPXuLQ4SWWbUTm2I9+bci6dbZXr3FIkLLLHdm58ZV9Elb0FMk7T71KHfq6i1LZG6LQEJrAehovZA4cm62vffleZssiYx15xJlYsZjrlsLhDoo/9dbSjU0s8mAoqlV9rWut5UFHCoTqSQy1r1wisgaUm/VJ6LGof/Y12pW4zoQ9hJxLLNsRtlfJdmU/WsRus3V2VsBEIZm29fyZFMu6E0HlUTG+l+KpDvKi896RDQDKO9r6YDqua91+/iQKuwpb9btue096NYp4capD9Z7Z+va1zJ1VY0rYSoLoWtzI/AQefRgsIOj8vTjSWHx9KRzkDx7IFx4/ONXvr2sT0TTNBEPt8AirCXgwYSVA4hBA0rIM8mIkSixdfKAKgyDC/u+Wu8NHQ4XGp4j32kvYxWFgSiKVsOkVlnyVrARbJYJM1XID6QJWKQT/Qm7VAFBLLbKH1hZ2/iBq6s4WW/MDle8oCHeIeT47ry85MlW96pKyvy8zlntWcNA9rtfb5nMwXoDSOZ0W4Ik211hs7zoxhS5guQKZatbTRdgvQHEVfp/mSZp8yJ60QXSLC82kS0GZF30Acj9u7K9pF0gdaE1kS0SRIyWW0AQA+Mm8OtzkGOqNZEtDgSiT6qoFWhz63OQrXeAlM5v2HBh1dK1AtmDENkiQdwWk0SoE6SxmsgWB5KlQAAnLMg80ZrIFgdiDlw9EOSI/TD1NpmtOg8EqQstDAaudhlcfLHytnDZsqdAkNIE3St6ISBy8Gu5bM2TDEBCxiwuZfIMxNiz+VK21imAhIxZLBOAwF5n+9Z+FQiysp0DCfMkWW169jqbLVN9B4FkTeBtC5yBjyAL11oqTLbyRIeBWMO2KRSClDv9YrYy1wKZDM6f6HKcdIxZ0Hx7qiD35Pn/ua8iprpafLZK40GieBaf39PH0fBjOIUxC6YsXrtSPShZepfrW27rQT4HaqhmIxVHavoF67oKIFz/NY8gdeNn/tBs4evM6Q4SqdHlOAzovcKOKQACl6eytXB/QeLLMR7/kGoFK27DQDQXixzKTgVljxswKo6NwVBsCDgH5wMM/QbfNt18QU495Zz8RdkfyLEsLXT30OveSy+99Bs6ltWVlfHKMnoklhTNyPM0T5ITEtx8uNh7tYbt841vJyL0h4ep2qLfAj7/J/Lm7Y1Mxnv869a18bvWz3O4CBFRtJCIojAKQyyxjkVb7fqlTYTG2IVX7A/bZgc0wzq2n6O5icVza412yhvvc/4zn4Izuv+dBQrX7+aqlDw0kS9PV/xK4yO+OOftZ5xjo6tiwVWdKztdtl0vHY98buK+HUXZ8M7h6XEKjx/36PZ79BxZZRWTAEZBesaxFIGB24KOU2dlYMHWbB4SdLkbJXK3kfewRu1D5NNpYNR8H1ggSrO5dCKSVO7Bu1iK5GKivjOKWFg1su43y4y5EFnn03IBY927JCDzSbzq3KKtQ3YwUtpGCKNEkmU/CphIhHrAJZFGSDtpqCv52hJSbAyRHhkinY0mhAJ8clKZRH5lQwOARVvbhmWrPi/hQiSJjbmSF2dIB5KRJiDC0IBxbaUxO/XytSqYA5FtQe7hvXtlZO8kQ5naosfBMe1pZuNCRMSvSgd0050hECLVctiRaEsHbsoTYkLEkhAfgNG4JHISxMGureSBsf4iaXZAiVA5GsGAKvxOeOPUvs3IGFRbdG43697SH8/IqvCJWGvQbBcC8VVd4vw131hY5lYvkn3SOXybWRNCFzjVip0INVkqPMjrbsAEtLbo3NZyD2/656nEzJaQyvvJBEhiRmHVVir3KL1IyqymRKgTjdV/HwbHzwe1VSa7rnOzV0skZ5QI3bAnhEfU502tLsrBvRcky1QdQ0dKxJ4Qd4CfF32Wp09+epH8q+56WqSG4Wj98yCHlQ1JiCGBQhk6KONpQBD04pxH8DZ7moN4WfbgwF5d8Kh4c0XWb+Dfo2cRVARvfgdP+iH8pdlprKGtioudRztN8vq68zYv/ZPD9OKF1Ej+S4dUvbj9j68jsd4zqmhNs7V3uT7C5SshNVSMRgouHTOqBOe05ZKFB6qOR0KiThDbjWylNxpxkFx7VGeZjLAJrFjPaxUMogwPVPGovbeNrcZI8IeR206ylV7XfHdtN67Y62hJKAZZleKw+pP4n8BASrN16UPkbtwK/+1ohCuAjxpG8nCX34u/vW1Mm1IyZqvlNHp5dz1xEXvEiurXwiRCeaxpe/3LlzA/4xcqERqzNjdpJaZiq6Jv99TxZ2B9MWkKCgJRtTBUaLlZ0YF/+Zj9hMcviKlnmF48Di3rb+DHiFRqyykuQHBcWRD2vn8799/x/Ond27dp8bh79+mnJkctX2M9w4AxP7h/vsbOrMkdnT9/NI/1QRvBbCcaWS2a3MGTJ9Ha0I0slrWPJwdo4nDn4LCuDN3IfFln69UCTbxbrt7WlaEbidmarXZ/NXm0ipXBG6mz9epZwv08+gdvpM7W692EO3wfy4M3ss7WzrOUercXy8M3sliFDnmbUnNEDN8IZSs996YYvpGQreUC3dgAIz5bs94O2QAjPluvDtGDDTBC2Zod7aIHm2BksaJzbx82wch8+XoPfdgEI5jN0IuNMLJYoB/BCJNghpcYG+RGFQ6Dwhz9ODZSSIwFJLh1xTTMa93Z+m1o3cWWJyR98KBZ90a0Xs9r5fTxx/j4uYt9cELSq3mznnHFbDJBlx5y8MgAYe29CUXLgMAFhE72yjF4ZPBQcMcvdGSqMHmgcm/ojqAPR5RgDV1OznNrJlTUI6BEA3csMOGFI6kvpVJq1O1SoZRulzI+SqRdp1/B3wC2sN7dwwmsQM6Q534hWK6hRZVEte/8dsowBVglHVN9jK3SS8tKGtRuLUUuVYdUAO1SmSORdhkJ40VURsy+s4IZWzizfqWo1utdlOa0LTTXtI+K0ikXJFWGWTEqtGxKuVDtUlsY1ioV+7xMpL9rRAluBZ+CT41TiEYs84dkXPi/5YzjWkTpFh95KTPHUh6lYJapdinLmWmVagvjEunvGgGXgjNYIZSORuwEBMWclE6CGZgiSicY8Upa3hNcoJgKE6Vjy/dHHVLIVqkoyVkqzU6hFYrW0dgb4XBvxMgKRVtWH3LrnlJUo1VIioNkGPP4bbhvAFNUEUxyYh66WloRrdKy4JN2qeEGqTQ7i3+EPGnoZLvJvItlSMnTWbb57wJH9RLtM9lpbDpOnc3O/ACb/i1NA1ABvwAAAABJRU5ErkJggg==", - "description": "Displays changes to time-series data over time visualized with color ranges — for example, temperature or humidity readings.", + "image": "tb-image:QmFyLWNoYXJ0LXdpdGgtbGFiZWxzLnN2Zw==:IkJhciBjaGFydCB3aXRoIGxhYmVscyIgc3lzdGVtIHdpZGdldCBpbWFnZQ==;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDEiIGhlaWdodD0iMTYwIiBmaWxsPSJub25lIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMi44IDQuM1YxMGgtLjdWNS4ybC0xLjQuNXYtLjZsMi0uOGguMVptNS45IDIuNHYuOWwtLjEgMS4yLS40LjdjLS4yLjItLjMuNC0uNi40YTIgMiAwIDAgMS0uNy4ybC0uNi0uMWMtLjIgMC0uNC0uMS0uNS0uMy0uMiAwLS4zLS4yLS40LS40bC0uMi0uOC0uMS0xdi0uOGwuMS0xLjIuNC0uN2MuMS0uMi4zLS40LjUtLjRsLjgtLjIuNi4xYTEuNCAxLjQgMCAwIDEgLjkuN2wuMi43djFabS0uNyAxVjUuOWwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNnYtLjhabTUuMy0xdjIuMWwtLjUuN2MtLjEuMi0uMy40LS41LjRhMiAyIDAgMCAxLS44LjJMMTEgMTBjLS4yIDAtLjMtLjEtLjUtLjNsLS4zLS40LS4zLS44di0zbC40LS43Yy4yLS4yLjQtLjQuNi0uNGwuNy0uMi42LjFhMS40IDEuNCAwIDAgMSAxIC43bC4xLjcuMSAxWm0tLjcgMVY1LjlsLS4yLS41YTEgMSAwIDAgMC0uMi0uM2wtLjMtLjJhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLS40IDBjLS4yIDAtLjMuMi0uNC4zbC0uMi42djIuNmwuMS41LjMuM2MwIC4xLjEuMi4zLjJoLjhsLjMtLjMuMi0uNi4xLS44Wm0xLjctMnYtLjNjMC0uMiAwLS40LjItLjYgMC0uMi4yLS4zLjQtLjRsLjYtLjJjLjMgMCAuNSAwIC42LjJsLjQuNC4yLjZ2LjNjMCAuMiAwIC40LS4yLjYgMCAuMi0uMi4zLS40LjRsLS42LjJjLS4yIDAtLjQgMC0uNi0uMmExIDEgMCAwIDEtLjQtLjRsLS4yLS42Wm0uNi0uM1Y2bC4zLjMuMy4xaC40TDE2IDZWNS4xYS42LjYgMCAwIDAtLjYtLjQuNi42IDAgMCAwLS41LjRsLS4xLjNaTTE3IDl2LS4zYzAtLjIgMC0uNC4yLS42IDAtLjIuMi0uMy40LS40bC42LS4yYy4yIDAgLjQgMCAuNi4ybC40LjQuMS42VjlsLS4xLjZjMCAuMi0uMi4zLS40LjRsLS42LjJjLS4zIDAtLjUgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMi0uNlptLjYtLjN2LjdsLjIuMi40LjFoLjNsLjItLjMuMS0uNHYtLjZhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjYuNHYuM1ptLjgtMy41LTIuOCA0LjUtLjQtLjNMMTggNWwuNC4yWk02IDM2YzAgLjQgMCAuNy0uMiAxbC0uNi41LTEgLjJjLS4zIDAtLjYgMC0uOS0uMi0uMi0uMS0uNS0uMy0uNi0uNi0uMi0uMi0uMy0uNS0uMy0uOGExLjUgMS41IDAgMCAxIDEuMS0xLjVsLjctLjFjLjQgMCAuNyAwIDEgLjIuMi4xLjUuMy42LjYuMi4yLjMuNS4zLjhabS0uNyAwLS4xLS41YTEgMSAwIDAgMC0uNC0uNGwtLjYtLjEtLjUuMWExIDEgMCAwIDAtLjQuNGwtLjEuNXYuNmwuNS40aDEuMWwuNC0uNC4xLS42Wm0uNi0yLjZjMCAuMyAwIC41LS4yLjctLjEuMy0uMy40LS42LjZsLS44LjJhMiAyIDAgMCAxLTEtLjJjLS4yLS4yLS40LS4zLS41LS42LS4yLS4yLS4yLS40LS4yLS43IDAtLjMgMC0uNi4yLS45LjEtLjIuMy0uNC42LS41bC44LS4yIDEgLjIuNS41Yy4yLjMuMi42LjIuOVptLS43IDAtLjEtLjVjLS4xLS4xLS4yLS4zLS40LS4zYTEgMSAwIDAgMC0uNS0uMiAxIDEgMCAwIDAtLjUuMWwtLjMuNC0uMS41LjEuNWMwIC4yLjIuMy40LjRoLjlsLjQtLjQuMS0uNVptNS41Ljl2LjlsLS4xIDEuMS0uNC44Yy0uMi4yLS4zLjQtLjYuNGEyIDIgMCAwIDEtLjcuMmwtLjYtLjFjLS4yIDAtLjQtLjEtLjUtLjMtLjIgMC0uMy0uMi0uNC0uNGwtLjItLjgtLjEtMXYtLjhsLjEtMS4yLjQtLjdjLjEtLjIuMy0uNC41LS40bC44LS4yLjYuMWExLjQgMS40IDAgMCAxIC45LjdsLjIuN3YxWm0tLjcgMXYtMS44bC0uMi0uNWExIDEgMCAwIDAtLjItLjNsLS4zLS4yYTEgMSAwIDAgMC0uNCAwIDEgMSAwIDAgMC0uNSAwbC0uMy4zLS4yLjZWMzZsLjEuNS4yLjMuMy4yaC45bC4zLS4zLjItLjZ2LS44Wm0xLjctMlYzM2wuMS0uNi40LS40LjctLjJjLjIgMCAuNCAwIC42LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNi4yYy0uMyAwLS41IDAtLjctLjJhMSAxIDAgMCAxLS40LS40bC0uMS0uNlptLjUtLjN2LjNsLjEuM2MwIC4yLjEuMi4yLjNsLjQuMWguM2wuMi0uNFYzMi43YS42LjYgMCAwIDAtLjUtLjQuNi42IDAgMCAwLS42LjR2LjNabTIuMyAzLjV2LS4zbC4xLS42LjQtLjQuNi0uMmMuMyAwIC41IDAgLjcuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS43LjJjLS4yIDAtLjQgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMS0uNlptLjUtLjN2LjdsLjMuMi4zLjFoLjRjMC0uMi4yLS4yLjItLjN2LTFhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjUuNHYuM1ptLjgtMy41TDEzIDM3LjJsLS40LS4zIDIuOC00LjQuNC4yWk01LjIgNTkuNWguMXYuNmMtLjQgMC0uOCAwLTEgLjItLjMuMS0uNS4zLS42LjVhMiAyIDAgMCAwLS40Ljd2Mi4zbC4zLjUuMy4zaC45bC4zLS4zLjItLjRhMS44IDEuOCAwIDAgMCAwLTFjMC0uMiAwLS4zLS4yLS40YTEgMSAwIDAgMC0uNy0uNGwtLjYuMS0uNC40YTEgMSAwIDAgMC0uMi41aC0uNGwuMi0uNy40LS41Yy4xLS4yLjMtLjMuNS0uM2ExLjkgMS45IDAgMCAxIDEuMyAwbC41LjVjLjIuMS4zLjMuMy42QTIuNCAyLjQgMCAwIDEgNiA2NGwtLjMuNi0uNi40LS44LjJjLS4zIDAtLjUgMC0uOC0uMmwtLjUtLjUtLjQtLjd2LTIuM2wuNS0xYy4yLS40LjQtLjYuOC0uOGEzIDMgMCAwIDEgMS4zLS4zWm01LjUgMi40di45bC0uMSAxLjItLjQuN2MtLjIuMi0uMy40LS42LjRhMiAyIDAgMCAxLS43LjJsLS42LS4xYy0uMiAwLS40LS4xLS41LS4zLS4yIDAtLjMtLjItLjQtLjRsLS4yLS44LS4xLTFWNjJsLjEtMS4yLjQtLjdjLjEtLjIuMy0uNC41LS40bC44LS4yLjYuMWExLjQgMS40IDAgMCAxIC45LjdsLjIuN3YxWm0tLjcgMVY2MWwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNlY2M1ptMS43LTJ2LS4zbC4xLS42LjQtLjQuNy0uMmMuMiAwIC40IDAgLjYuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS42LjJjLS4zIDAtLjUgMC0uNy0uMmExIDEgMCAwIDEtLjQtLjRsLS4xLS42Wm0uNS0uM3YuM2wuMS4zYzAgLjIuMS4yLjIuM2wuNC4xaC4zbC4yLS40VjYwLjNhLjYuNiAwIDAgMC0uNS0uNGwtLjQuMS0uMi4zdi4zWm0yLjMgMy41di0uM2wuMS0uNi40LS40LjYtLjJjLjMgMCAuNSAwIC43LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNy4yYy0uMiAwLS40IDAtLjYtLjItLjIgMC0uMy0uMi0uNC0uNGwtLjEtLjZabS41LS4zdi43bC4zLjIuMy4xaC40YzAtLjIuMi0uMi4yLS4zdi0xYS42LjYgMCAwIDAtLjYtLjQuNi42IDAgMCAwLS41LjR2LjNabS44LTMuNUwxMyA2NC44bC0uNC0uMyAyLjgtNC40LjQuMlpNNi4zIDkwLjl2LjZoLTRWOTFsMi41LTRoLjVsLS42IDEuMkwzIDkwLjloMy4zWk01LjUgODd2NS43aC0uN3YtNS43aC43Wm01LjIgMi40di45bC0uMSAxLjEtLjQuOGMtLjIuMi0uMy40LS42LjRhMiAyIDAgMCAxLS43LjJsLS42LS4xYy0uMiAwLS40LS4xLS41LS4zLS4yIDAtLjMtLjItLjQtLjRsLS4yLS44LS4xLTF2LS44bC4xLTEuMi40LS43Yy4xLS4yLjMtLjQuNS0uNEw5IDg3bC42LjFhMS40IDEuNCAwIDAgMSAuOS43bC4yLjd2MVptLS43IDF2LTEuOGwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNnYtLjhabTEuNy0ydi0uM2wuMS0uNi40LS40LjctLjJjLjIgMCAuNCAwIC42LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNi4yYy0uMyAwLS41IDAtLjctLjJhMSAxIDAgMCAxLS40LS40bC0uMS0uNlptLjUtLjN2LjNsLjEuM2MwIC4yLjEuMi4yLjNsLjQuMWguM2wuMi0uNFY4OGEuNi42IDAgMCAwLS41LS40bC0uNC4xLS4yLjN2LjNabTIuMyAzLjV2LS4zbC4xLS42LjQtLjQuNi0uMmMuMyAwIC41IDAgLjcuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS43LjJjLS4yIDAtLjQgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMS0uNlptLjUtLjN2LjdsLjMuMi4zLjFoLjRjMC0uMi4yLS4yLjItLjN2LTFhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjUuNHYuM1ptLjgtMy41TDEzIDkyLjRsLS40LS4zIDIuOC00LjQuNC4yWk02LjIgMTE5Ljh2LjZIMi41di0uNWwxLjgtMiAuNi0uNy4yLS41LjEtLjUtLjEtLjUtLjMtLjNhMSAxIDAgMCAwLS42LS4yYy0uMiAwLS40IDAtLjYuMmExIDEgMCAwIDAtLjQuNGwtLjEuNmgtLjdjMC0uMyAwLS42LjItLjkuMS0uMy4zLS41LjYtLjZhMiAyIDAgMCAxIDEtLjNsMSAuMmMuMi4yLjQuMy41LjYuMi4yLjIuNC4yLjh2LjVsLS4zLjVhNy44IDcuOCAwIDAgMS0uOCAxbC0xLjUgMS42aDIuOVptNC41LTIuN3YuOWwtLjEgMS4yLS40LjdjLS4yLjItLjMuNC0uNi40YTIgMiAwIDAgMS0uNy4ybC0uNi0uMWMtLjIgMC0uNC0uMS0uNS0uMy0uMiAwLS4zLS4yLS40LS40bC0uMi0uOC0uMS0xdi0uOGwuMS0xLjIuNC0uN2MuMS0uMi4zLS40LjUtLjRsLjgtLjIuNi4xYTEuNCAxLjQgMCAwIDEgLjkuN2wuMi43djFabS0uNyAxdi0xLjhsLS4yLS41YTEgMSAwIDAgMC0uMi0uM2wtLjMtLjJhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLS41IDBsLS4zLjMtLjIuNnYyLjZsLjEuNS4yLjMuMy4yaC45bC4zLS4zLjItLjZ2LS44Wm0xLjctMnYtLjNsLjEtLjYuNC0uNC43LS4yYy4yIDAgLjQgMCAuNi4ybC40LjQuMS42di4zbC0uMS42LS40LjQtLjYuMmMtLjMgMC0uNSAwLS43LS4yYTEgMSAwIDAgMS0uNC0uNGwtLjEtLjZabS41LS4zdi4zbC4xLjNjMCAuMi4xLjIuMi4zbC40LjFoLjNsLjItLjRWMTE1LjVhLjYuNiAwIDAgMC0uNS0uNC42LjYgMCAwIDAtLjYuNHYuM1ptMi4zIDMuNXYtLjNsLjEtLjYuNC0uNC42LS4yYy4zIDAgLjUgMCAuNy4ybC40LjQuMS42di4zbC0uMS42LS40LjQtLjcuMmMtLjIgMC0uNCAwLS42LS4yLS4yIDAtLjMtLjItLjQtLjRsLS4xLS42Wm0uNS0uM3YuN2wuMy4yLjMuMWguNGMwLS4yLjItLjIuMi0uM3YtMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNS40di4zWm0uOC0zLjVMMTMgMTIwbC0uNC0uMyAyLjgtNC40LjQuMlpNOC41IDE0NC43djIuMWwtLjQuN2MtLjIuMi0uNC40LS42LjRhMiAyIDAgMCAxLS44LjJsLS42LS4xLS41LS4zLS4zLS40LS4zLS44di0zbC40LS43Yy4yLS4yLjQtLjQuNi0uNGwuNy0uMi43LjFhMS40IDEuNCAwIDAgMSAuOC43bC4zLjd2MVptLS43IDF2LTEuOGwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjQgMGwtLjQuMy0uMi42djIuNmwuMi41YzAgLjEgMCAuMi4yLjNsLjMuMmguOGwuMy0uMy4zLS42di0uOFptMS44LTJ2LS4zbC4xLS42YzAtLjIuMi0uMy40LS40bC42LS4yYy4zIDAgLjUgMCAuNi4yLjIuMS40LjIuNC40bC4yLjZ2LjNjMCAuMiAwIC40LS4yLjYgMCAuMi0uMi4zLS40LjRsLS42LjJjLS4yIDAtLjQgMC0uNi0uMmExIDEgMCAwIDEtLjQtLjRsLS4xLS42Wm0uNS0uM3YuNmwuMy4zLjMuMWguNGwuMi0uNFYxNDMuMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNS40bC0uMS4zWm0yLjIgMy41di0uM2MwLS4yIDAtLjQuMi0uNiAwLS4yLjItLjMuNC0uNGwuNi0uMmMuMiAwIC40IDAgLjYuMmwuNC40LjIuNnYuM2MwIC4yIDAgLjQtLjIuNiAwIC4yLS4yLjMtLjQuNGwtLjYuMmMtLjIgMC0uNSAwLS42LS4yLS4yIDAtLjMtLjItLjQtLjRsLS4yLS42Wm0uNi0uM3YuN2wuMi4yLjQuMWguM2wuMy0uM3YtMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNi40di4zWm0uOC0zLjUtMi44IDQuNS0uNC0uMyAyLjgtNC40LjQuMloiLz48cGF0aCBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS1vcGFjaXR5PSIuMSIgc3Ryb2tlLXdpZHRoPSIuNCIgZD0iTTI0LjIgNi44aDE3NS42TTI0LjIgMzQuNmgxNzUuNk0yNC4yIDYyLjRoMTc1LjZNMjQuMiA5MC4yaDE3NS42TTI0LjIgMTE4aDE3NS42Ii8+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utb3BhY2l0eT0iLjUiIHN0cm9rZS13aWR0aD0iLjQiIGQ9Ik0yNC4yIDE0NS44aDE3NS42Ii8+PHBhdGggZmlsbD0iIzdEOEVGRiIgZD0iTTMwIDI1LjVoMTh2MTIwSDMweiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik00MC40IDEzNS40Yy40IDAgLjcgMCAxIC4ybC41LjcuMiAxYzAgLjMgMCAuNi0uMi45LS4xLjMtLjMuNS0uNi43bC0uOS4yYTEuNSAxLjUgMCAwIDEtMS0uNWwtLjQtLjYtLjEtLjhjMC0uMyAwLS43LjItMWwuNS0uNmMuMy0uMi41LS4yLjgtLjJabTAgLjlhMSAxIDAgMCAwLS41LjFsLS4zLjMtLjEuNXYuNWMuMS4yLjMuMy40LjNsLjUuMmMuMiAwIC40IDAgLjUtLjJsLjMtLjMuMS0uNXYtLjVsLS40LS4zYTEgMSAwIDAgMC0uNS0uMVptLTIuNi0uOGMuMyAwIC41IDAgLjguMmwuNS42LjIgMWMwIC4zIDAgLjYtLjIuOGwtLjUuNy0uOC4yYy0uMyAwLS42LS4xLS44LS4zLS4zLS4xLS41LS4zLS42LS42bC0uMi0uOS4yLS45LjYtLjYuOC0uMlptMCAxYTEgMSAwIDAgMC0uNCAwIC43LjcgMCAwIDAtLjQuN3YuNWwuNC4yLjQuMWguNWwuMy0uMy4xLS41LS4xLS40LS4zLS4zYTEgMSAwIDAgMC0uNSAwWm0xLjYtMy0uMi43LTIuOS0uM3YtM2guOHYyLjJsMS40LjJhMS44IDEuOCAwIDAgMS0uMi0xbC4xLS43YzAtLjIuMi0uNC40LS41LjEtLjIuMy0uMy42LS4zYTIuNSAyLjUgMCAwIDEgMS41IDBsLjYuMy40LjYuMi44LS4xLjctLjMuNmExLjYgMS42IDAgMCAxLTEuMi42di0xbC40LS4xYy4yIDAgLjMtLjIuMy0uM2wuMS0uNXYtLjRsLS4zLS4zYTEgMSAwIDAgMC0uNC0uMiAxLjggMS44IDAgMCAwLS45IDAgMSAxIDAgMCAwLS40LjJsLS4yLjR2LjlsLjMuM1oiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMzguOCAxMjMuOGguNnYzaC0uNnYtM1ptLTIuNSAzSDQydi43aC01Ljd2LS43Wm0wLTMuNkg0MnYuN2gtNS43di0uN1ptNC43LTRoLTMuMnYtLjdINDJ2LjdoLTFabS0uOSAwdi0uNGwuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDM3Ljh2LS43SDQxbC4zLS4yLjEtLjN2LS4ybC0uMS0uOGExIDEgMCAwIDAtLjUtLjRoLS43Wm0tMS41LTIuNkg0MnYuN2gtNC4ydi0uNmguOFptMS4xLjJ2LjNsLS44LS4xYTIgMiAwIDAgMS0uNi0uM2wtLjUtLjYtLjEtLjd2LS42YTEuMSAxLjEgMCAwIDEgLjgtLjdINDJ2LjZoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuNC0uMS40LjEuNi4zLjMuNS4yaC41Wm0tLjQtMi44LjIuNS0uNy0uMS0uNi0uMy0uNC0uNi0uMS0uN3YtLjZsLjQtLjQuNC0uM0g0MnYuNmgtMi44bC0uNS4xYy0uMi4xLS4zLjItLjMuNGExLjMgMS4zIDAgMCAwIDAgLjlsLjIuMy4zLjJoLjRabS0xLjUtNC42SDQydi44aC00LjJ2LS44Wm0tMS4xLjhoLS4zbC0uMi0uNGMwLS4xIDAtLjIuMi0uM2wuMy0uMWguMmwuMi40YzAgLjEgMCAuMi0uMi4zbC0uMi4xWm00LjUtNC43SDM2di0uN2g2di43aC0uOFptLTEuMyAyLjlhMyAzIDAgMCAxLTEtLjFsLS42LS40LS40LS41Yy0uMi0uMi0uMi0uNS0uMi0uN2wuMS0uNy40LS41Yy4yLS4xLjQtLjMuNy0uM2wuOC0uMmguNGMuMyAwIC42IDAgLjguMi4zIDAgLjUuMi42LjNsLjQuNWExLjcgMS43IDAgMCAxIDAgMS40YzAgLjItLjIuNC0uNC41bC0uNy40YTMgMyAwIDAgMS0uOSAwWm0wLS44aC42bC41LS4yYy4yLS4xLjMtLjIuMy0uNGwuMi0uNWMwLS4yIDAtLjQtLjItLjZsLS40LS4zLS41LS4zaC0xbC0uNC4yLS4zLjJhMSAxIDAgMCAwLS4zLjNsLS4xLjUuMS41LjQuNC41LjJoLjZabS0yLjEtNC44SDQydi43aC00LjJ2LS43Wm0tMS4xLjgtLjMtLjEtLjItLjNjMC0uMiAwLS4zLjItLjRoLjVsLjIuNHMwIC4yLS4yLjNoLS4yWm0xLTMuOGguNnYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdINDFsLjMtLjEuMS0uMnYtLjJhMS4yIDEuMiAwIDAgMCAwLS4zaC42djFsLS40LjRoLTQuOVptNC45LTMuNi0zLjgtMS4ydi0uOGw0LjkgMS43YTIuNyAyLjcgMCAwIDEgLjYuNCAxLjIgMS4yIDAgMCAxIC40Ljl2LjRINDNhMS43IDEuNyAwIDAgMCAwLS43bC0uMy0uMi0uNC0uMi0uOC0uM1ptLTMuOC44IDMuMy0xIC43LS4zLjMuNi00LjMgMS41di0uOFoiLz48cGF0aCBmaWxsPSIjRjk2RkZGIiBkPSJNNDggNDguNWgxOHY5N0g0OHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNNTQuMyAxMzUuM2guNWw1LjIgMi4zdjFsLTUtMi4zdjNoLS43di00Wm0yLjQtNC42aDFjLjQgMCAuNyAwIDEgLjIuNCAwIC42LjIuOC4zLjIuMi40LjQuNC42bC4yLjgtLjEuNmExLjUgMS41IDAgMCAxLS44IDFsLS42LjJoLTNhMiAyIDAgMCAxLS44LS41bC0uNC0uNS0uMi0uOC4xLS42YTEuNSAxLjUgMCAwIDEgLjgtMWwuNi0uMmgxWm0xIDFoLTEuMmE0IDQgMCAwIDAtLjYgMGwtLjQuMS0uMy4yLS4yLjN2LjdsLjMuMy41LjJoMi41bC41LS4xLjMtLjIuMi0uM3YtLjdsLS4zLS4zLS41LS4yYTQgNCAwIDAgMC0uOCAwWiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiIGQ9Ik01OC42IDEyNC41YTEgMSAwIDAgMC0uNCAwbC0uMy4zLS4yLjQtLjIuNi0uMy44LS40LjYtLjQuNGgtLjZhMS40IDEuNCAwIDAgMS0xLjEtLjRjLS4yLS4yLS4zLS40LS4zLS43bC0uMi0uN2MwLS41LjEtLjguMy0xLjEuMS0uMy40LS42LjYtLjcuMy0uMi42LS4yLjktLjJ2LjdsLS42LjFhMSAxIDAgMCAwLS40LjVsLS4xLjd2LjZsLjQuNC41LjFoLjNsLjMtLjMuMi0uNC4yLS42LjMtLjhjLjEtLjMuMi0uNS40LS42LjEtLjIuMy0uMy41LS4zbC42LS4yYy4yIDAgLjQgMCAuNi4yLjIgMCAuMy4yLjUuNGwuMy42YTMgMyAwIDAgMSAwIDEuNmwtLjQuNy0uNS41LS43LjJ2LS44aC41YzAtLjIuMi0uMy4zLS40bC4yLS41YTIuMiAyLjIgMCAwIDAgMC0xLjFsLS40LS41YS44LjggMCAwIDAtLjQtLjFabS0uNy0xLjUtLjktLjFhMiAyIDAgMCAxLS43LS40bC0uNC0uNi0uMi0uOGMwLS4zIDAtLjYuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNC44LS4xaC4xbC45LjEuNy40YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjdoLjZsLjUtLjMuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yLS42LS4xaC0uNmwtLjUuM2ExIDEgMCAwIDAtLjUuOWwuMS41LjQuNC41LjIuNS4xWm0tMi4xLTQuOUg2MHYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMiAwLS4zLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptLS43LTIuOGg2di44aC02di0uOFptMi42LTRINjB2LjhoLTQuMnYtLjdoLjhabTEuMS4ydi4zSDU3YTIgMiAwIDAgMS0uNi0uNGwtLjUtLjUtLjEtLjh2LS41YTEuMSAxLjEgMCAwIDEgLjgtLjdsLjctLjFINjB2LjdoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuMy0uMS41LjEuNWMwIC4yLjIuMy4zLjRsLjUuMmguNVptLS40LTIuNy4yLjVjLS4zIDAtLjUgMC0uNy0uMmwtLjYtLjMtLjQtLjUtLjEtLjd2LS42bC40LS41LjQtLjNINjB2LjdoLTIuOGwtLjUuMWMtLjIgMC0uMy4yLS4zLjNhMS4zIDEuMyAwIDAgMCAwIDFsLjIuMi4zLjJoLjRabS42LTMuNi0uOS0uMWEyIDIgMCAwIDEtLjctLjRsLS40LS42LS4yLS44YzAtLjMgMC0uNi4yLS44IDAtLjMuMi0uNS40LS42bC43LS40LjgtLjFoMWwuNy41YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNS0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjcuNi0uMS41LS4yLjQtLjR2LTFhMSAxIDAgMCAwLS40LS40bC0uNS0uMi0uNi0uMWgtLjZsLS41LjNhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yaC41Wm0tMi4xLTQuOUg2MHYuN2gtNC4ydi0uN1ptLTEuMS44LS4zLS4xLS4yLS4zYzAtLjIgMC0uMy4yLS40aC41bC4yLjRjMCAuMSAwIC4yLS4yLjNoLS4yWm00LjItNC41LS4zLjEtLjMuMy0uMi42LS4xLjYtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMEw1NiA5OGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLTFsLjUtLjUuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNGwuMy4zYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMnYtLjhsLjUtLjEuMi0uNGExLjUgMS41IDAgMCAwIDAtMWwtLjItLjNoLS4zWm0tMy4xLTMuNWguNXYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC41bC4xLS4ydi0uMmExLjIgMS4yIDAgMCAwIDAtLjRoLjZ2MS4xbC0uNC4zLS43LjFoLTQuMlptNC4yLTVoLTMuMnYtLjdINjB2LjdoLTFabS0uOSAwdi0uNGwuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDU1LjhWOTFINTlsLjMtLjIuMS0uM3YtLjNsLS4xLS43YTEgMSAwIDAgMC0uNS0uNGgtLjdabS0xLjctMi42SDYwdi44aC00LjJ2LS43aC42Wm0tLjYtMS4zaC42di44bC4zLjMuMy4zaC40bC4yLjMtLjgtLjFhMiAyIDAgMCAxLS41LS4zYy0uMiAwLS40LS4yLS41LS40YTEuMSAxLjEgMCAwIDEgMC0uOVptNC4zLTIuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMkg1OGMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4zaDEuNGwuNS0uMy4zLS40VjgybC0uNS0uNC40LS41LjQuNC4zLjV2LjdaIi8+PHBhdGggZmlsbD0iI0ZGQTM4OSIgZD0iTTY2IDM0LjVoMTh2MTExSDY2eiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik03Ni40IDEzNS40Yy40IDAgLjcgMCAxIC4ybC41LjcuMiAxYzAgLjMgMCAuNi0uMi45LS4xLjMtLjMuNS0uNi43bC0uOS4yYTEuNSAxLjUgMCAwIDEtMS0uNWwtLjQtLjYtLjEtLjhjMC0uMyAwLS43LjItMWwuNS0uNmMuMy0uMi41LS4yLjgtLjJabTAgLjlhMSAxIDAgMCAwLS41LjFsLS4zLjMtLjEuNXYuNWMuMS4yLjMuMy40LjNsLjUuMmMuMiAwIC40IDAgLjUtLjJsLjMtLjMuMS0uNXYtLjVsLS40LS4zYTEgMSAwIDAgMC0uNS0uMVptLTIuNi0uOGMuMyAwIC41IDAgLjguMmwuNS42LjIgMWMwIC4zIDAgLjYtLjIuOGwtLjUuNy0uOC4yYy0uMyAwLS42LS4xLS44LS4zLS4zLS4xLS41LS4zLS42LS42bC0uMi0uOS4yLS45LjYtLjYuOC0uMlptMCAxYTEgMSAwIDAgMC0uNCAwIC43LjcgMCAwIDAtLjQuN3YuNWwuNC4yLjQuMWguNWwuMy0uMy4xLS41LS4xLS40LS4zLS4zYTEgMSAwIDAgMC0uNSAwWm0uOS01LjhoMWMuNCAwIC43IDAgMSAuMi40IDAgLjYuMi44LjMuMi4yLjQuNC40LjZsLjIuOC0uMS42YTEuNSAxLjUgMCAwIDEtLjggMWwtLjYuMmgtM2EyIDIgMCAwIDEtLjgtLjVsLS40LS41LS4yLS44LjEtLjZhMS41IDEuNSAwIDAgMSAuOC0xbC42LS4yaDFabTEgMWgtMS4yYTQgNCAwIDAgMC0uNiAwbC0uNC4xLS4zLjItLjIuM3YuN2wuMy4zLjUuMmgyLjVsLjUtLjEuMy0uMi4yLS4zdi0uN2wtLjMtLjMtLjUtLjJhNCA0IDAgMCAwLS44IDBaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTc3LjQgMTI0aC42djNoLS42di0zWm0tNSAyLjhINzh2LjdoLTUuN3YtLjdabTUuNy01LjNjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjJINzZjLS40IDAtLjcgMC0xLS4yYTIgMiAwIDAgMS0uNi0uNCAxLjggMS44IDAgMCAxLS40LTJjMC0uMy4yLS41LjQtLjZsLjYtLjMuOS0uMWguM3YzLjFoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjMgMSAxIDAgMCAwLS4yLjYgMSAxIDAgMCAwIC40LjhsLjUuMi43LjFoLjdsLjUtLjNhMS4yIDEuMiAwIDAgMCAuNC0xYzAtLjIgMC0uNC0uMi0uNmwtLjQtLjQuNC0uNS40LjQuMy41di43Wm0tLjgtNWgtMi42Yy0uMi4xLS4zLjItLjMuNGwtLjEuNXYuNWwuMy4zaC4zdi44YTEgMSAwIDAgMS0uNC0uMWMtLjIgMC0uMy0uMi0uNC0uM2wtLjMtLjZhMiAyIDAgMCAxLS4xLS43YzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41LjItLjIuNS0uMi44LS4yaDIuNGwuNC0uMmguMXYuOGgtLjdabS0xLjktLjFoLjV2LjdsLjEuNS4xLjQuMy4zaC43bC4zLS4zdi0uNGExLjIgMS4yIDAgMCAwLS40LTEgLjcuNyAwIDAgMC0uNC0uMmwuMy0uMy40LjJhMS43IDEuNyAwIDAgMSAuOCAxLjRjMCAuMyAwIC41LS4yLjdsLS40LjUtLjcuMi0uNi0uMS0uNC0uNC0uMy0uNnYtMS42Wm0yLjYtM3YuOGgtNC43Yy0uMyAwLS41IDAtLjctLjItLjMgMC0uNC0uMi0uNS0uNGwtLjItLjhhMiAyIDAgMCAxIDAtLjVoLjd2LjlsLjMuMkg3OFptLTQuMi0uOGguNXYyLjNoLS41di0yLjNabTMuNS00LTMuNS0xdi0uNWguN2wzLjUgMS4ydi40aC0uOFptLTMuNS44IDMuNS0xaC43di40bC00LjIgMS4zdi0uN1ptMy41LTMuNC0zLjUtLjl2LS43bDQuMiAxLjJ2LjVoLS43Wm0tMy41IDEgMy40LTEuMS44LS4xdi40bC0zLjUgMS4yaC0uN3YtLjRabTQuMy01LjFjMCAuMyAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFINzZsLTEtLjFhMiAyIDAgMCAxLS42LS41IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4yLjItLjQuNC0uNmwuNi0uM2gxLjJ2M2gtLjZWMTAxbC0uNi4yYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjJoMS40bC41LS4yLjMtLjR2LTEuMmwtLjUtLjUuNC0uNC40LjNjMCAuMi4yLjMuMy41di44Wm0tNC4zLTQuM2guNXYyLjJoLS41di0yLjJabS0xIDEuNXYtLjhoNC41bC4xLS4yVjk4YTEuMiAxLjIgMCAwIDAgMC0uNGguNnYxLjFjLS4xLjEtLjIuMy0uNC4zbC0uNy4yaC00LjJabTEuOS0zLjJINzh2LjhoLTQuMlY5NmguOVptMSAuMnYuM2wtLjgtLjFhMiAyIDAgMCAxLS42LS40IDEuNiAxLjYgMCAwIDEtLjYtMS4yVjk0bC4zLS40LjUtLjNINzh2LjdoLTMuM2wtLjMuMy0uMS41YTEgMSAwIDAgMCAuNC45IDEuNiAxLjYgMCAwIDAgMSAuM1ptMi40LTUuN2MwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMkg3NmMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4zaDEuNGwuNS0uMy4zLS40di0xLjJsLS41LS40LjQtLjUuNC40LjMuNXYuN1ptLTEuMi01aC0uM2wtLjMuNC0uMi42LS4xLjYtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0xIDAtLjIuMy0uMy41LS41bC42LS4ydi44aC0uM2wtLjMuNC0uMS41di40bC4zLjNhLjYuNiAwIDAgMCAuNSAwbC4yLS4xLjEtLjMuMi0uNS4yLS44LjQtLjUuNi0uMmExLjEgMS4xIDAgMCAxIDEgLjRsLjIuNnYuNmwtLjEgMS0uNS42LS43LjJ2LS44bC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1ptMC00LjItLjMuMS0uMy4zLS4yLjYtLjEuNi0uMy41YTEgMSAwIDAgMS0uOC40IDEgMSAwIDAgMS0uNCAwbC0uNC0uNGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLS45IDAtLjIuMy0uNC41LS42bC42LS4xdi43aC0uM2wtLjMuNC0uMS41di41bC4zLjJhLjYuNiAwIDAgMCAuNSAwaC4ybC4xLS40LjItLjUuMi0uOC40LS41LjYtLjJhMS4xIDEuMSAwIDAgMSAxIC41bC4yLjV2LjZsLS4xIDEtLjUuNi0uNy4yVjgzbC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1oiLz48cGF0aCBmaWxsPSIjRkZFRDUzIiBkPSJNODQgNTYuNWgxOHY4OUg4NHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNOTAuMyAxMzYuMmguN2wuMi44YTEuNiAxLjYgMCAwIDAgMSAxbC44LjFoMS41bC41LS4zLjItLjMuMS0uNHYtLjNsLS4zLS4zLS40LS4yYTEuNyAxLjcgMCAwIDAtLjkgMGMtLjEgMC0uMyAwLS40LjJsLS4yLjItLjEuNC4xLjYuNC4zLjQuMi0uMS4zYTIgMiAwIDAgMS0uNy0uMWwtLjUtLjQtLjMtLjVWMTM2LjJsLjUtLjUuNi0uM2EyLjUgMi41IDAgMCAxIDEuNSAwYy4yIDAgLjQuMi42LjQuMi4xLjMuMy40LjZsLjIuN2MwIC4zIDAgLjYtLjIuOC0uMS4zLS4zLjUtLjUuNmwtLjcuNC0uOC4yaC0uNGwtMS4zLS4yYTMgMyAwIDAgMS0xLS41Yy0uMy0uMi0uNS0uNS0uNy0uOWEzIDMgMCAwIDEtLjItMS4zWm01LTUuNmguN3YzLjhoLS42bC0yLTEuOC0uNy0uNWEyIDIgMCAwIDAtLjQtLjIgMS4yIDEuMiAwIDAgMC0uOSAwbC0uMy4zLS4xLjQuMS42LjQuMy41LjF2MWwtLjktLjMtLjYtLjZhMiAyIDAgMCAxLS4zLTFsLjItMWMuMi0uMy4zLS41LjYtLjYuMi0uMi41LS4zLjgtLjNsLjUuMS42LjMuNS4zLjUuNSAxLjMgMS4ydi0yLjZaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTk0LjIgMTI0di0uN2MuNCAwIC43LjIgMSAuNC4yLjEuNS40LjYuNy4yLjMuMy42LjMgMS4xIDAgLjMgMCAuNi0uMiAxYTIgMiAwIDAgMS0uNS42Yy0uMy4yLS41LjQtLjkuNWwtMSAuMWgtLjZsLTEuMS0uMS0uOC0uNWEyIDIgMCAwIDEtLjYtLjdsLS4yLTFjMC0uNC4xLS44LjMtMSAuMS0uNC40LS42LjYtLjdsMS0uNHYuOGwtLjYuMmExIDEgMCAwIDAtLjUuNGwtLjEuNy4xLjdjMCAuMi4yLjQuNC41bC42LjNoMi4yYy4zIDAgLjUtLjIuNy0uM2wuNC0uNC4yLS43YzAtLjMgMC0uNi0uMi0uOGExIDEgMCAwIDAtLjQtLjRsLS43LS4yWm0tNC4yLTIuNGg2di43aC02di0uN1ptNC0xaC0uMmMtLjMgMC0uNSAwLS44LS4yYTIgMiAwIDAgMS0uNy0uNGMtLjItLjEtLjMtLjMtLjQtLjYtLjItLjItLjItLjUtLjItLjggMC0uMyAwLS41LjItLjggMC0uMi4yLS40LjQtLjZsLjctLjRoMS44bC43LjRhMS44IDEuOCAwIDAgMSAuNiAxLjRjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xLjEgMWwtLjkuMlptLS4yLS44aC43Yy4yIDAgLjQtLjIuNS0uMy4yIDAgLjMtLjIuNC0uM1YxMThhMSAxIDAgMCAwLS40LS40bC0uNS0uMmgtMS4ybC0uNS4yYTEgMSAwIDAgMC0uNS45bC4xLjYuNC4zLjUuM2guNVptMS4yLTYuNmgtMy4ydi0uOEg5NnYuN2gtMVptLS45LS4ydi0uM2wuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDkxLjh2LS43SDk1bC4zLS4yLjEtLjJ2LS4zbC0uMS0uOGExIDEgMCAwIDAtLjUtLjNsLS43LS4yWm0xLTQuNEg5MHYtLjdoNnYuN2gtLjhabS0xLjIgMi45YTMgMyAwIDAgMS0xLS4ybC0uNi0uMy0uNC0uNWMtLjItLjItLjItLjUtLjItLjdsLjEtLjcuNC0uNWMuMi0uMS40LS4zLjctLjNsLjgtLjJoLjRjLjMgMCAuNiAwIC44LjIuMyAwIC41LjIuNi4zbC40LjVhMS43IDEuNyAwIDAgMSAwIDEuNGMwIC4yLS4yLjQtLjQuNS0uMi4yLS41LjMtLjcuM2EzIDMgMCAwIDEtLjkuMlptMC0uOGguNmwuNS0uMmMuMi0uMS4zLS4yLjMtLjRsLjItLjVjMC0uMiAwLS40LS4yLS42bC0uNC0uMy0uNS0uM2gtMWEyIDIgMCAwIDAtLjQuMmwtLjMuMmExIDEgMCAwIDAtLjMuM2wtLjEuNS4xLjUuNC40LjUuMmguNlptMS42LTcuNy0uMS0uNWExIDEgMCAwIDAtLjMtLjMuOC44IDAgMCAwLS40LS4ydi0uN2wuNy4zYTEuNyAxLjcgMCAwIDEgLjcgMS40YzAgLjMgMCAuNi0uMi44LS4xLjMtLjMuNC0uNS42YTIgMiAwIDAgMS0uNi40SDkzYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZhMiAyIDAgMCAxLS4yLS44YzAtLjMgMC0uNi4yLS45bC41LS42LjgtLjJ2LjdhMSAxIDAgMCAwLS40LjEgMSAxIDAgMCAwLS41LjhsLjEuNi40LjQuNS4yaDEuMmwuNS0uMi40LS40di0uNVptLTEuNi0yLjQtLjktLjFhMiAyIDAgMCAxLS43LS40bC0uNC0uNmMtLjItLjItLjItLjUtLjItLjggMC0uMyAwLS42LjItLjggMC0uMi4yLS40LjQtLjZsLjctLjQuOC0uMWguMWwuOS4xLjcuNGExLjggMS44IDAgMCAxIC42IDEuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEuMSAxbC0uOS4xWm0wLS43aC42bC41LS4zYy4yIDAgLjMtLjIuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yLjUuMVptMS40LTUuMy0zLjUtMS4ydi0uN2w0LjIgMS41di41bC0uNy0uMVptLTMuNSAxIDMuNi0xLjIuNi0uMXYuNWwtNC4yIDEuNXYtLjdabTQuMy01LjNjMCAuMiAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFIOTRjLS40IDAtLjcgMC0xLS4yYTIgMiAwIDAgMS0uNi0uNCAxLjggMS44IDAgMCAxLS40LTJjMC0uMy4yLS40LjQtLjZsLjYtLjNoMS4ydjNoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjQgMSAxIDAgMCAwLS4yLjUgMSAxIDAgMCAwIC40LjlsLjUuMmgxLjRjLjIgMCAuMy0uMi41LS4zbC4zLS40di0xLjFsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFpNOTIuNCA4N0g5NnYuN2gtNC4yVjg3aC42Wm0tLjctMS4zaC43di44bC4zLjMuMy4yLjQuMS4yLjJoLS44YTIgMiAwIDAgMS0uNS0uM2wtLjUtLjRhMS4xIDEuMSAwIDAgMSAwLTFaIi8+PHBhdGggZmlsbD0iIzdEOEVGRiIgZD0iTTEyMyAzNi41aDE4djEwOWgtMTh6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuOSIgZD0iTTEyOS4zIDEzNS4zaC41bDUuMiAyLjN2MWwtNS0yLjN2M2gtLjd2LTRabTUtMS42di0uMWMwLS40IDAtLjctLjItLjlhMS40IDEuNCAwIDAgMC0xLS45aC0yLjNsLS41LjItLjIuMy0uMS40di4zbC4zLjMuNC4yYTEuOCAxLjggMCAwIDAgMSAwYy4xIDAgLjIgMCAuMy0uMmwuMy0uMi4xLS40YTEgMSAwIDAgMC0uMy0uOCAxLjEgMS4xIDAgMCAwLS43LS4zbC4xLS4zaC42YTEuOCAxLjggMCAwIDEgLjkgMWwuMS42LS4xLjctLjQuNS0uNy4zYTIuNSAyLjUgMCAwIDEtMS40IDAgMiAyIDAgMCAxLS43LS40Yy0uMi0uMS0uMy0uMy0uNC0uNmwtLjItLjdjMC0uNCAwLS42LjItLjlsLjUtLjUuNy0uNCAxLS4xaDEuM2wuOC40LjcuNS41LjguMSAxdi4yaC0uN1oiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTMxLjggMTIzLjhoLjZ2M2gtLjZ2LTNabS0yLjUgM2g1Ljd2LjdoLTUuN3YtLjdabTAtMy42aDUuN3YuN2gtNS43di0uN1ptNC43LTRoLTMuMnYtLjdoNC4ydi43aC0xWm0tLjkgMHYtLjRsLjguMS42LjMuNC41LjIuOC0uMS41YTEuMSAxLjEgMCAwIDEtLjguOEgxMzAuOHYtLjdoMy4ybC4zLS4yLjEtLjN2LS4ybC0uMS0uOGExIDEgMCAwIDAtLjUtLjRoLS43Wm0tMS41LTIuNmgzLjR2LjdoLTQuMnYtLjZoLjhabTEuMS4ydi4zbC0uOC0uMS0uNi0uMy0uNS0uNi0uMS0uN3YtLjZhMS4xIDEuMSAwIDAgMSAuOC0uN2gzLjV2LjZoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuNHYxbC4zLjMuNS4yaC41Wm0tLjQtMi44LjIuNS0uNy0uMS0uNi0uMy0uNC0uNi0uMS0uN3YtLjZsLjQtLjQuNC0uM2gzLjV2LjZoLTIuOGwtLjUuMWMtLjIuMS0uMy4yLS4zLjRhMS4yIDEuMiAwIDAgMCAwIC45bC4yLjNhMSAxIDAgMCAwIC43LjJabS0xLjUtNC42aDQuMnYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMSAwLS4yLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptNC41LTQuN0gxMjl2LS43aDZ2LjdoLS44Wm0tMS4zIDIuOWEzIDMgMCAwIDEtMS0uMWwtLjYtLjRhMS41IDEuNSAwIDAgMS0uNi0xLjJsLjEtLjcuNC0uNWMuMi0uMS40LS4zLjctLjNsLjgtLjJoLjRjLjMgMCAuNiAwIC44LjIuMyAwIC41LjIuNi4zbC40LjVhMS43IDEuNyAwIDAgMSAwIDEuNGMwIC4yLS4yLjQtLjQuNWwtLjcuNGEzIDMgMCAwIDEtLjkgMFptMC0uOGguNmwuNS0uMmMuMi0uMS4zLS4yLjMtLjRsLjItLjVhMSAxIDAgMCAwLS42LTFsLS41LS4yaC0xbC0uNC4yLS4zLjJhMSAxIDAgMCAwLS4zLjN2MWwuNC40LjUuMmguNlptLTIuMS00LjhoNC4ydi43aC00LjJ2LS43Wm0tMS4xLjgtLjMtLjEtLjItLjNjMC0uMiAwLS4zLjItLjRoLjVsLjIuNHMwIC4yLS4yLjNoLS4yWm0xLTMuOGguNnYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC4zbC4zLS4xLjEtLjJ2LS41aC42YTEuOCAxLjggMCAwIDEgMCAuNXYuNWwtLjQuNGgtNC45Wm00LjktMy42LTMuOC0xLjJ2LS44bDQuOSAxLjdhMi43IDIuNyAwIDAgMSAuNi40bC4zLjRhMSAxIDAgMCAxIDAgLjd2LjJoLS41YTEuOSAxLjkgMCAwIDAgMC0uN2wtLjMtLjItLjQtLjItLjgtLjNabS0zLjguOCAzLjMtMSAuNy0uMy4zLjYtNC4zIDEuNXYtLjhaIi8+PHBhdGggZmlsbD0iI0Y5NkZGRiIgZD0iTTE0MSA3Ny41aDE4djY4aC0xOHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJtMTUwLjQgMTM4LS4yLjgtMi45LS4zdi0zaC44djIuMmwxLjQuMmExLjggMS44IDAgMCAxLS4yLS45bC4xLS43YzAtLjIuMi0uNC40LS42bC42LS4zYTIuNSAyLjUgMCAwIDEgMS41IDBsLjYuMy40LjYuMi44LS4xLjctLjMuNi0uNS40LS43LjJ2LTFoLjRsLjMtLjQuMS0uNXYtLjRsLS4zLS4yYTEgMSAwIDAgMC0uNC0uMiAxLjggMS44IDAgMCAwLTEgMCAxIDEgMCAwIDAtLjMuMmwtLjIuM3YxbC4zLjNabS0uNy03LjNoMWMuNCAwIC43IDAgMSAuMi40IDAgLjYuMi44LjNsLjQuNi4yLjgtLjEuNmExLjUgMS41IDAgMCAxLS44IDFsLS42LjJoLTNhMiAyIDAgMCAxLS44LS41bC0uNC0uNS0uMi0uOC4xLS42YTEuNSAxLjUgMCAwIDEgLjgtMWwuNi0uMmgxWm0xIDFoLTEuMmE0IDQgMCAwIDAtLjYgMGwtLjQuMS0uMy4yLS4yLjN2LjdsLjMuMy41LjJoMi41bC41LS4xLjMtLjIuMi0uM3YtLjdsLS4zLS4zLS41LS4yYTQgNCAwIDAgMC0uOCAwWiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiIGQ9Ik0xNTEuNiAxMjQuNWExIDEgMCAwIDAtLjQgMGwtLjMuMy0uMi40LS4yLjYtLjMuOC0uNC42LS40LjRoLS42YTEuNCAxLjQgMCAwIDEtMS4xLS40Yy0uMi0uMi0uMy0uNC0uMy0uN2wtLjItLjdjMC0uNS4xLS44LjMtMS4xLjEtLjMuNC0uNi42LS43LjMtLjIuNi0uMi45LS4ydi43bC0uNi4xYTEgMSAwIDAgMC0uNC41bC0uMS43di42bC40LjQuNS4xaC4zbC4zLS4zLjItLjQuMi0uNi4zLS44Yy4xLS4zLjItLjUuNC0uNi4xLS4yLjMtLjMuNS0uM2wuNi0uMmMuMiAwIC40IDAgLjYuMi4yIDAgLjMuMi41LjRsLjMuNmEzIDMgMCAwIDEgMCAxLjZsLS40LjctLjUuNS0uNy4ydi0uOGguNWMwLS4yLjItLjMuMy0uNGwuMi0uNWEyLjIgMi4yIDAgMCAwIDAtMS4xbC0uNC0uNWEuOC44IDAgMCAwLS40LS4xWm0tLjctMS41LS45LS4xYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZjLS4yLS4yLS4yLS41LS4yLS44IDAtLjMgMC0uNi4yLS44IDAtLjIuMi0uNC40LS42bC43LS40LjgtLjFoLjFsLjkuMS43LjRhMS44IDEuOCAwIDAgMSAuNiAxLjRjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xLjEgMWwtLjkuMVptMC0uN2guNmwuNS0uMy40LS40di0xYTEgMSAwIDAgMC0uNC0uNGwtLjUtLjItLjYtLjFoLS42bC0uNS4zYTEgMSAwIDAgMC0uNS45bC4xLjUuNC40LjUuMi41LjFabS0yLjEtNC45aDQuMnYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMiAwLS4zLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptLS43LTIuOGg2di44aC02di0uOFptMi42LTRoMy40di44aC00LjJ2LS43aC44Wm0xLjEuMnYuM2gtLjhsLS42LS40LS41LS41LS4xLS44di0uNWExLjEgMS4xIDAgMCAxIC44LS43bC43LS4xaDIuOHYuN2gtMi44YTEgMSAwIDAgMC0uNS4xbC0uMy4zdjFjMCAuMi4yLjMuMy40bC41LjJoLjVabS0uNC0yLjcuMi41Yy0uMyAwLS41IDAtLjctLjJsLS42LS4zLS40LS41LS4xLS43di0uNmwuNC0uNS40LS4zaDMuNXYuN2gtMi44bC0uNS4xYy0uMiAwLS4zLjItLjMuM2ExLjIgMS4yIDAgMCAwIDAgMWwuMi4yLjMuMmguNFptLjYtMy42LS45LS4xYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZjLS4yLS4zLS4yLS41LS4yLS44IDAtLjMgMC0uNi4yLS44IDAtLjMuMi0uNS40LS42bC43LS40LjgtLjFoMWwuNy41YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNS0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjcuNi0uMS41LS4yLjQtLjR2LTFhMSAxIDAgMCAwLS40LS40bC0uNS0uMi0uNi0uMWgtLjZsLS41LjNhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yaC41Wm0tMi4xLTQuOWg0LjJ2LjdoLTQuMnYtLjdabS0xLjEuOC0uMy0uMS0uMi0uM2MwLS4yIDAtLjMuMi0uNGguNWwuMi40YzAgLjEgMCAuMi0uMi4zaC0uMlptNC4yLTQuNS0uMy4xLS4zLjMtLjIuNi0uMS42YzAgLjItLjIuNC0uMy41YTEgMSAwIDAgMS0uOC40IDEgMSAwIDAgMS0uNCAwbC0uNC0uNGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLTFsLjUtLjUuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNGwuMy4zYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMnYtLjhsLjUtLjEuMi0uNGExLjUgMS41IDAgMCAwIDAtMWwtLjItLjNoLS4zWm0tMy4xLTMuNWguNXYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC41bC4xLS4yVjkyLjVoLjZhMS44IDEuOCAwIDAgMSAwIC42di41bC0uNC4zLS43LjFoLTQuMlptNC4yLTVoLTMuMnYtLjdoNC4ydi43aC0xWm0tLjkgMHYtLjRsLjguMS42LjMuNC41LjIuOC0uMS41YTEuMSAxLjEgMCAwIDEtLjguOEgxNDguOFY5MWgzLjJsLjMtLjIuMS0uM3YtLjNsLS4xLS43YTEgMSAwIDAgMC0uNS0uNGgtLjdabS0xLjctMi42aDMuNnYuOGgtNC4ydi0uN2guNlptLS43LTEuM2guN3YuOGwuMy4zLjMuM2guNGwuMi4zLS44LS4xYTIgMiAwIDAgMS0uNi0uM2wtLjQtLjRhMS4xIDEuMSAwIDAgMSAwLS45Wm00LjQtMi40YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjYtMS4zYzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41bC42LS4zLjktLjFoLjN2My4xaC0uNnYtMi40bC0uNi4xYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjNoMS40bC41LS4zLjMtLjRWODJsLS41LS40LjQtLjUuNC40LjMuNXYuN1oiLz48cGF0aCBmaWxsPSIjRkZBMzg5IiBkPSJNMTU5IDQ3LjVoMTh2OThoLTE4eiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik0xNjUuMyAxMzUuM2guNWw1LjIgMi4zdjFsLTUtMi4zdjNoLS43di00Wm0yLjQtNC42aDFjLjQgMCAuNyAwIDEgLjIuNCAwIC42LjIuOC4zbC40LjYuMi44LS4xLjZhMS41IDEuNSAwIDAgMS0uOCAxbC0uNi4yaC0zYTIgMiAwIDAgMS0uOC0uNWwtLjQtLjUtLjItLjguMS0uNmExLjUgMS41IDAgMCAxIC44LTFsLjYtLjJoMVptMSAxaC0xLjJhNCA0IDAgMCAwLS42IDBsLS40LjEtLjMuMi0uMi4zdi43bC4zLjMuNS4yaDIuNWwuNS0uMS4zLS4yLjItLjN2LS43bC0uMy0uMy0uNS0uMmE0IDQgMCAwIDAtLjggMFoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTcwLjQgMTI0aC42djNoLS42di0zWm0tNSAyLjhoNS42di43aC01Ljd2LS43Wm01LjctNS4zYzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4yLjcuMWguN2wuNS0uMy4zLS40di0xLjJsLS41LS40LjQtLjUuNC40LjMuNXYuN1ptLS44LTVoLTIuNmMtLjIuMS0uMy4yLS4zLjRsLS4xLjV2LjVsLjMuM2guM3YuOGExIDEgMCAwIDEtLjQtLjFjLS4yIDAtLjMtLjItLjQtLjNsLS4zLS42YTIgMiAwIDAgMS0uMS0uN2MwLS4zIDAtLjUuMi0uOCAwLS4yLjItLjQuNC0uNS4yLS4yLjUtLjIuOC0uMmgyLjRsLjQtLjJoLjF2LjhoLS43Wm0tMS45LS4xaC41di43bC4xLjUuMS40LjMuM2guN2wuMy0uM3YtLjRhMS4yIDEuMiAwIDAgMC0uNC0xIC43LjcgMCAwIDAtLjQtLjJsLjMtLjMuNC4yYTEuNyAxLjcgMCAwIDEgLjYgMi4xbC0uNC41LS43LjItLjYtLjEtLjQtLjQtLjMtLjZ2LTEuNlptMi42LTN2LjhoLTQuN2MtLjMgMC0uNSAwLS43LS4yLS4zIDAtLjQtLjItLjUtLjRsLS4yLS44YTIgMiAwIDAgMSAwLS41aC43di45bC4zLjJIMTcxWm0tNC4yLS44aC41djIuM2gtLjV2LTIuM1ptMy40LTQtMy40LTF2LS41aC43bDMuNSAxLjJ2LjRoLS44Wm0tMy40LjggMy41LTFoLjd2LjRsLTQuMiAxLjN2LS43Wm0zLjUtMy40LTMuNS0uOXYtLjdsNC4yIDEuMnYuNWgtLjdabS0zLjUgMSAzLjQtMS4xLjgtLjF2LjRsLTMuNSAxLjJoLS43di0uNFptNC4zLTUuMWMwIC4zIDAgLjUtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMWgtLjFsLTEtLjFhMiAyIDAgMCAxLS42LS41IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4yLjItLjQuNC0uNmwuNi0uM2gxLjJ2M2gtLjZWMTAxbC0uNi4yYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjJoMS40bC41LS4yYzAtLjIuMi0uMy4zLS40di0xLjJsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFptLTQuMy00LjNoLjV2Mi4yaC0uNXYtMi4yWm0tMSAxLjV2LS44aDQuNWwuMS0uMlY5Ny41aC42YTEuOCAxLjggMCAwIDEgMCAuNnYuNWMtLjEuMS0uMi4zLS40LjNsLS43LjJoLTQuMlptMS45LTMuMmgzLjN2LjhoLTQuMlY5NmguOVptMSAuMnYuM2wtLjgtLjFhMiAyIDAgMCAxLS42LS40IDEuNiAxLjYgMCAwIDEtLjYtMS4yVjk0bC4zLS40LjUtLjNoMy41di43aC0zLjNsLS4zLjN2LjVhMSAxIDAgMCAwIC4zLjkgMS42IDEuNiAwIDAgMCAxIC4zWm0yLjQtNS43YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjYtMS4zYzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41bC42LS4zLjktLjFoLjN2My4xaC0uNnYtMi40bC0uNi4xYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjNoMS40bC41LS4zLjMtLjR2LTEuMmwtLjUtLjQuNC0uNS40LjQuMy41di43Wm0tMS4yLTVoLS4zbC0uMy40LS4yLjYtLjEuNmMwIC4yLS4yLjQtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0xIDAtLjIuMy0uMy41LS41bC42LS4ydi44aC0uM2wtLjMuNC0uMS41di40bC4zLjNhLjYuNiAwIDAgMCAuNSAwbC4yLS4xLjEtLjMuMi0uNS4yLS44LjQtLjUuNi0uMmExLjEgMS4xIDAgMCAxIDEgLjRsLjIuNnYuNmwtLjEgMS0uNS42LS43LjJ2LS44bC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1ptMC00LjItLjMuMS0uMy4zLS4yLjYtLjEuNmMwIC4yLS4yLjQtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0uOSAwLS4yLjMtLjQuNS0uNmwuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNWwuMy4yYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMlY4M2wuNS0uMS4yLS40YTEuNSAxLjUgMCAwIDAgMC0xbC0uMi0uM2gtLjNaIi8+PHBhdGggZmlsbD0iI0ZGRUQ1MyIgZD0iTTE3NyA2Mi41aDE4djgzaC0xOHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNMTgzLjMgMTM2LjJoLjdsLjIuOGExLjYgMS42IDAgMCAwIDEgMWwuOC4xaDEuNWwuNS0uMy4yLS4zLjEtLjR2LS4zbC0uMy0uMy0uNC0uMmExLjcgMS43IDAgMCAwLS45IDBjLS4xIDAtLjMgMC0uNC4ybC0uMi4yLS4xLjQuMS42LjQuMy40LjItLjEuM2EyIDIgMCAwIDEtLjctLjFsLS41LS40LS4zLS41VjEzNi4ybC41LS41LjYtLjNhMi41IDIuNSAwIDAgMSAxLjUgMGMuMiAwIC40LjIuNi40LjIuMS4zLjMuNC42bC4yLjdjMCAuMyAwIC42LS4yLjgtLjEuMy0uMy41LS41LjZsLS43LjQtLjguMmgtLjRsLTEuMy0uMmEzIDMgMCAwIDEtMS0uNWMtLjMtLjItLjUtLjUtLjctLjlhMyAzIDAgMCAxLS4yLTEuM1ptMi40LTUuNWgxYy40IDAgLjcgMCAxIC4yLjQgMCAuNi4yLjguM2wuNC42LjIuOC0uMS42YTEuNSAxLjUgMCAwIDEtLjggMWwtLjYuMmgtM2EyIDIgMCAwIDEtLjgtLjVsLS40LS41LS4yLS44LjEtLjZhMS41IDEuNSAwIDAgMSAuOC0xbC42LS4yaDFabTEgMWgtMS4yYTQgNCAwIDAgMC0uNiAwbC0uNC4xLS4zLjItLjIuM3YuN2wuMy4zLjUuMmgyLjVsLjUtLjEuMy0uMi4yLS4zdi0uN2wtLjMtLjMtLjUtLjJhNCA0IDAgMCAwLS44IDBaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTE4Ny4yIDEyNHYtLjdjLjQgMCAuNy4yIDEgLjQuMi4xLjUuNC42LjcuMi4zLjMuNi4zIDEuMSAwIC4zIDAgLjYtLjIgMWEyIDIgMCAwIDEtLjUuNmwtLjkuNS0xIC4xaC0uNmwtMS4xLS4xLS44LS41YTIgMiAwIDAgMS0uNi0uN2wtLjItMWMwLS40LjEtLjguMy0xIC4xLS40LjQtLjYuNi0uN2wxLS40di44bC0uNi4yYTEgMSAwIDAgMC0uNS40bC0uMS43LjEuN2MwIC4yLjIuNC40LjVsLjYuM2gyLjJjLjMgMCAuNS0uMi43LS4zbC40LS40LjItLjdjMC0uMyAwLS42LS4yLS44YTEgMSAwIDAgMC0uNC0uNGwtLjctLjJabS00LjItMi40aDZ2LjdoLTZ2LS43Wm00LTFoLS4yYy0uMyAwLS41IDAtLjgtLjJhMiAyIDAgMCAxLS43LS40Yy0uMi0uMS0uMy0uMy0uNC0uNi0uMi0uMi0uMi0uNS0uMi0uOCAwLS4zIDAtLjUuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNGgxLjhsLjcuNGExLjggMS44IDAgMCAxIC42IDEuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEuMSAxbC0uOS4yWm0tLjItLjhoLjdjLjIgMCAuNC0uMi41LS4zLjIgMCAuMy0uMi40LS4zVjExOGExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNi40LjMuNS4zaC41Wm0xLjItNi42aC0zLjJ2LS44aDQuMnYuN2gtMVptLS45LS4ydi0uM2wuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDE4NC44di0uN2gzLjJsLjMtLjIuMS0uMnYtLjNsLS4xLS44YTEgMSAwIDAgMC0uNS0uM2wtLjctLjJabTEtNC40SDE4M3YtLjdoNnYuN2gtLjhabS0xLjIgMi45YTMgMyAwIDAgMS0xLS4ybC0uNi0uM2ExLjUgMS41IDAgMCAxLS42LTEuMmwuMS0uNy40LS41Yy4yLS4xLjQtLjMuNy0uM2wuOC0uMmguNGMuMyAwIC42IDAgLjguMi4zIDAgLjUuMi42LjNsLjQuNWExLjcgMS43IDAgMCAxIDAgMS40YzAgLjItLjIuNC0uNC41LS4yLjItLjUuMy0uNy4zYTMgMyAwIDAgMS0uOS4yWm0wLS44aC42bC41LS4yYy4yLS4xLjMtLjIuMy0uNGwuMi0uNWExIDEgMCAwIDAtLjYtMWwtLjUtLjJoLTFhMiAyIDAgMCAwLS40LjJsLS4zLjJhMSAxIDAgMCAwLS40LjhsLjEuNS40LjQuNS4yaC42Wm0xLjYtNy43LS4xLS41YTEgMSAwIDAgMC0uMy0uMy44LjggMCAwIDAtLjQtLjJ2LS43bC43LjNhMS43IDEuNyAwIDAgMSAuNyAxLjRjMCAuMyAwIC42LS4yLjgtLjEuMy0uMy40LS41LjZhMiAyIDAgMCAxLS42LjRIMTg2YTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZhMiAyIDAgMCAxLS4yLS44YzAtLjMgMC0uNi4yLS45bC41LS42LjgtLjJ2LjdhMSAxIDAgMCAwLS40LjEgMSAxIDAgMCAwLS41LjhsLjEuNi40LjQuNS4yaDEuMmwuNS0uMmMuMiAwIC4zLS4yLjQtLjR2LS41Wm0tMS42LTIuNC0uOS0uMWEyIDIgMCAwIDEtLjctLjRsLS40LS42Yy0uMi0uMi0uMi0uNS0uMi0uOCAwLS4zIDAtLjYuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNC44LS4xaC4xbC45LjEuNy40YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNi0uMi44IDAgLjItLjIuNC0uNC42YTIgMiAwIDAgMS0uNy40bC0uOS4xWm0wLS43aC42bC41LS4zYy4yIDAgLjMtLjIuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yLjUuMVptMS40LTUuMy0zLjUtMS4ydi0uN2w0LjIgMS41di41bC0uNy0uMVptLTMuNSAxIDMuNi0xLjIuNi0uMXYuNWwtNC4yIDEuNXYtLjdabTQuMy01LjNjMCAuMiAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFoLS4xYy0uNCAwLS43IDAtMS0uMmEyIDIgMCAwIDEtLjYtLjQgMS44IDEuOCAwIDAgMS0uNi0xLjNjMC0uMyAwLS41LjItLjcgMC0uMy4yLS40LjQtLjZsLjYtLjNoMS4ydjNoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjQgMSAxIDAgMCAwLS4yLjUgMSAxIDAgMCAwIC40LjlsLjUuMmgxLjRjLjIgMCAuMy0uMi41LS4zbC4zLS40di0xLjFsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFptLTMuNy0zLjNoMy42di43aC00LjJWODdoLjZabS0uNy0xLjNoLjd2LjhsLjMuMy4zLjIuNC4xLjIuMmgtLjhhMiAyIDAgMCAxLS42LS4zbC0uNC0uNGExLjEgMS4xIDAgMCAxIDAtMVpNNjEuNSAxNTQuM3YtNGguOHY0YzAgLjQgMCAuNy0uMiAxbC0uNy42YTIgMiAwIDAgMS0uOS4yYy0uMyAwLS43IDAtMS0uMmwtLjYtLjUtLjItMWguOHYuNmwuNS40YTEuMyAxLjMgMCAwIDAgMSAwbC40LS40LjEtLjdabTQuNiAxVjE1M2wtLjEtLjRjMC0uMi0uMi0uMy0uMy0uM2ExIDEgMCAwIDAtLjUtLjFoLS41bC0uMy4zLS4xLjNoLS43di0uNGwuNC0uNC42LS4zLjctLjFjLjMgMCAuNSAwIC44LjIuMiAwIC40LjIuNS40LjIuMi4yLjUuMi44djIuNGwuMi40di4xaC0uOHYtLjNsLS4xLS40Wm0uMS0xLjl2LjVoLS43bC0uNS4xLS41LjEtLjIuM3YuN2wuMy4zaC40YTEuMiAxLjIgMCAwIDAgMS0uNGwuMi0uNC4zLjMtLjIuNGExLjcgMS43IDAgMCAxLS44LjdINjQuMmwtLjUtLjVjLS4yLS4yLS4yLS40LS4yLS43bC4xLS42LjQtLjQuNi0uM2gxLjZabTIuNi0uN3YzLjNoLS43di00LjJoLjd2LjlabS0uMSAxaC0uM3YtLjhsLjQtLjZhMS42IDEuNiAwIDAgMSAxLjMtLjZoLjVsLjUuMy4yLjUuMS43djIuOGgtLjd2LTMuM2wtLjQtLjNhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLTEgLjMgMS42IDEuNiAwIDAgMC0uMiAxWk0xNTQgMTUwLjN2NS43aC0uOHYtNS43aC43Wm0yLjMgMi42di42aC0yLjZ2LS42aDIuNlptLjQtMi42di42aC0zdi0uNmgzWm0yLjYgNS44YTEuOCAxLjggMCAwIDEtMS44LTEuMmwtLjItLjl2LS4xYzAtLjQgMC0uNy4yLTFsLjQtLjZhMS44IDEuOCAwIDAgMSAyLS40Yy4zIDAgLjUuMi42LjRsLjMuNi4xLjl2LjNoLTMuMXYtLjZoMi40bC0uMS0uNmExIDEgMCAwIDAtLjMtLjQgMSAxIDAgMCAwLS42LS4yIDEgMSAwIDAgMC0uOC40bC0uMi41LS4xLjd2LjdsLjMuNS40LjNoMS4ybC40LS41LjUuNC0uNC40LS41LjNhMiAyIDAgMCAxLS43IDBabTIuNi02LjFoLjd2NmgtLjd2LTZabTMuNiAzLjktLjEuOS0uMy43LS41LjQtLjcuMmMtLjMgMC0uNiAwLS44LS4yLS4yIDAtLjMtLjItLjUtLjRhMiAyIDAgMCAxLS4zLS42IDQgNCAwIDAgMS0uMi0uOHYtLjRsLjItLjhjMC0uMy4yLS41LjMtLjdsLjUtLjQuNy0uMWMuMyAwIC41IDAgLjguMi4yIDAgLjMuMi41LjRsLjMuNy4xLjlabS0uNyAwdi0uNmwtLjMtLjVhMSAxIDAgMCAwLS44LS41bC0uNS4xYTEgMSAwIDAgMC0uNC4zbC0uMi4zLS4xLjR2MWwuMi41YzAgLjIuMi4zLjQuNGwuNi4yYy4yIDAgLjMgMCAuNS0uMmwuMy0uMy4yLS41di0uNloiLz48L3N2Zz4=", + "description": "Displays changes to time-series data over time visualized with value bars and labels — for example, daily water consumption for the last month.", "descriptor": { "type": "timeseries", "sizeX": 8, @@ -11,20 +11,20 @@ "resources": [], "templateHtml": "\n", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.$scope.barChartWidget.onInit();\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.barChartWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '80%',\n embedTitlePanel: true,\n hasAdditionalLatestDataKeys: false,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.barChartWidget.onInit();\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.barChartWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '80%',\n embedTitlePanel: true,\n hasAdditionalLatestDataKeys: false,\n defaultDataKeysFunction: function() {\n return [{ name: 'humidity', label: 'Humidity', type: 'timeseries' }];\n }\n };\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "latestDataKeySettingsSchema": "{}", - "settingsDirective": "", + "settingsDirective": "tb-bar-chart-with-labels-widget-settings", "dataKeySettingsDirective": "", "latestDataKeySettingsDirective": "", - "hasBasicMode": false, - "basicModeDirective": "", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2221714000,\"fixedTimewindow\":{\"startTimeMs\":1703599035699,\"endTimeMs\":1703685435699},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"thermostat\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"0px\"}" + "hasBasicMode": true, + "basicModeDirective": "tb-bar-chart-with-labels-basic-config", + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2592000000,\"fixedTimewindow\":{\"startTimeMs\":1704293713163,\"endTimeMs\":1704380113163},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"showBarLabel\":true,\"barLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"12px\"},\"barLabelColor\":\"rgba(0, 0, 0, 0.54)\",\"showBarValue\":true,\"barValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"700\",\"lineHeight\":\"12px\"},\"barValueColor\":\"rgba(0, 0, 0, 0.76)\",\"showLegend\":true,\"legendPosition\":\"top\",\"legendLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"legendLabelColor\":\"rgba(0, 0, 0, 0.76)\",\"showTooltip\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipShowDate\":true,\"tooltipDateFormat\":{\"format\":\"MMMM y\",\"lastUpdateAgo\":false,\"custom\":true},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":11,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":4,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"public\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}" }, "tags": [ - "range", - "color range", - "line chart" + "bar chart", + "bar", + "bars" ] } \ No newline at end of file diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index 72a500e084..9351e410a8 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -136,6 +136,8 @@ const none: AggFunction = (aggData: AggData, value?: any) => { aggData.aggValue = value; }; +const MAX_INTERVAL_TIMEOUT = Math.pow(2,31)-1; + export class DataAggregator { constructor(private onDataCb: onAggregatedData, @@ -217,7 +219,7 @@ export class DataAggregator { this.aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(this.subsTw.aggregation.interval, 1000); this.resetPending = true; this.updatedData = false; - this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), this.aggregationTimeout); + this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), Math.min(this.aggregationTimeout, MAX_INTERVAL_TIMEOUT)); } public destroy() { @@ -313,7 +315,7 @@ export class DataAggregator { this.updatedData = false; } if (!history) { - this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), intervalTimeout); + this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), Math.min(intervalTimeout, MAX_INTERVAL_TIMEOUT)); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 5e95d162cd..95ce945259 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -88,6 +88,9 @@ import { import { RangeChartBasicConfigComponent } from '@home/components/widget/config/basic/chart/range-chart-basic-config.component'; +import { + BarChartWithLabelsBasicConfigComponent +} from '@home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component'; @NgModule({ declarations: [ @@ -115,7 +118,8 @@ import { CompassGaugeBasicConfigComponent, LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, - RangeChartBasicConfigComponent + RangeChartBasicConfigComponent, + BarChartWithLabelsBasicConfigComponent ], imports: [ CommonModule, @@ -147,7 +151,8 @@ import { CompassGaugeBasicConfigComponent, LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, - RangeChartBasicConfigComponent + RangeChartBasicConfigComponent, + BarChartWithLabelsBasicConfigComponent ] }) export class BasicWidgetConfigModule { @@ -173,5 +178,6 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type + + + + + + + +
+
widget-config.appearance
+
+ + {{ 'widget-config.title' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + + + + +
+
+
+
+
widgets.bar-chart.bar-appearance
+
+ + {{ 'widgets.bar-chart.label-on-bar' | translate }} + +
+ + + + +
+
+
+ + {{ 'widgets.bar-chart.value-on-bar' | translate }} + +
+ + + + +
+
+
+
widget-config.units-short
+ + +
+
+
widget-config.decimals-short
+ + + +
+
+
+ + + + + {{ 'widget-config.legend' | translate }} + + + + +
+
{{ 'legend.position' | translate }}
+ + + + {{ legendPositionTranslationMap.get(pos) | translate }} + + + +
+
+
{{ 'legend.label' | translate }}
+
+ + + + +
+
+
+
+
+
+ + + + + {{ 'widget-config.tooltip' | translate }} + + + + +
+
{{ 'tooltip.value' | translate }}
+
+ + + + +
+
+
+ + {{ 'tooltip.date' | translate }} + +
+ + + + + +
+
+
+
{{ 'tooltip.background-color' | translate }}
+ + +
+
+
{{ 'tooltip.background-blur' | translate }}
+ + +
px
+
+
+
+
+
+
+
widget-config.card-appearance
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
widget-config.show-card-buttons
+ + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts new file mode 100644 index 0000000000..6b6929a36f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts @@ -0,0 +1,323 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Injector } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + DataKey, + Datasource, + legendPositions, + legendPositionTranslationMap, + WidgetConfig, +} from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { + getTimewindowConfig, + setTimewindowConfig +} from '@home/components/widget/config/timewindow-config-panel.component'; +import { formatValue, isUndefined } from '@core/utils'; +import { + cssSizeToStrSize, + DateFormatProcessor, + DateFormatSettings, + resolveCssSize +} from '@shared/models/widget-settings.models'; +import { + barChartWithLabelsDefaultSettings, + BarChartWithLabelsWidgetSettings +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; + +@Component({ + selector: 'tb-bar-chart-with-labels-basic-config', + templateUrl: './bar-chart-with-labels-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class BarChartWithLabelsBasicConfigComponent extends BasicWidgetConfigComponent { + + public get datasource(): Datasource { + const datasources: Datasource[] = this.barChartWidgetConfigForm.get('datasources').value; + if (datasources && datasources.length) { + return datasources[0]; + } else { + return null; + } + } + + legendPositions = legendPositions; + + legendPositionTranslationMap = legendPositionTranslationMap; + + barChartWidgetConfigForm: UntypedFormGroup; + + tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); + + tooltipDatePreviewFn = this._tooltipDatePreviewFn.bind(this); + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private $injector: Injector, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.barChartWidgetConfigForm; + } + + protected defaultDataKeys(configData: WidgetConfigComponentData): DataKey[] { + return [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries }]; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: BarChartWithLabelsWidgetSettings = {...barChartWithLabelsDefaultSettings, ...(configData.config.settings || {})}; + const iconSize = resolveCssSize(configData.config.iconSize); + this.barChartWidgetConfigForm = this.fb.group({ + timewindowConfig: [getTimewindowConfig(configData.config), []], + datasources: [configData.config.datasources, []], + series: [this.getSeries(configData.config.datasources), []], + + showTitle: [configData.config.showTitle, []], + title: [configData.config.title, []], + titleFont: [configData.config.titleFont, []], + titleColor: [configData.config.titleColor, []], + + showIcon: [configData.config.showTitleIcon, []], + iconSize: [iconSize[0], [Validators.min(0)]], + iconSizeUnit: [iconSize[1], []], + icon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], + + showBarLabel: [settings.showBarLabel, []], + barLabelFont: [settings.barLabelFont, []], + barLabelColor: [settings.barLabelColor, []], + showBarValue: [settings.showBarValue, []], + barValueFont: [settings.barValueFont, []], + barValueColor: [settings.barValueColor, []], + + units: [configData.config.units, []], + decimals: [configData.config.decimals, []], + + showLegend: [settings.showLegend, []], + legendPosition: [settings.legendPosition, []], + legendLabelFont: [settings.legendLabelFont, []], + legendLabelColor: [settings.legendLabelColor, []], + + showTooltip: [settings.showTooltip, []], + tooltipValueFont: [settings.tooltipValueFont, []], + tooltipValueColor: [settings.tooltipValueColor, []], + tooltipShowDate: [settings.tooltipShowDate, []], + tooltipDateFormat: [settings.tooltipDateFormat, []], + tooltipDateFont: [settings.tooltipDateFont, []], + tooltipDateColor: [settings.tooltipDateColor, []], + tooltipBackgroundColor: [settings.tooltipBackgroundColor, []], + tooltipBackgroundBlur: [settings.tooltipBackgroundBlur, []], + + background: [settings.background, []], + + cardButtons: [this.getCardButtons(configData.config), []], + borderRadius: [configData.config.borderRadius, []], + + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig); + this.widgetConfig.config.datasources = config.datasources; + this.setSeries(config.series, this.widgetConfig.config.datasources); + + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.title = config.title; + this.widgetConfig.config.titleFont = config.titleFont; + this.widgetConfig.config.titleColor = config.titleColor; + + this.widgetConfig.config.showTitleIcon = config.showIcon; + this.widgetConfig.config.iconSize = cssSizeToStrSize(config.iconSize, config.iconSizeUnit); + this.widgetConfig.config.titleIcon = config.icon; + this.widgetConfig.config.iconColor = config.iconColor; + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.showBarLabel = config.showBarLabel; + this.widgetConfig.config.settings.barLabelFont = config.barLabelFont; + this.widgetConfig.config.settings.barLabelColor = config.barLabelColor; + this.widgetConfig.config.settings.showBarValue = config.showBarValue; + this.widgetConfig.config.settings.barValueFont = config.barValueFont; + this.widgetConfig.config.settings.barValueColor = config.barValueColor; + + this.widgetConfig.config.units = config.units; + this.widgetConfig.config.decimals = config.decimals; + + this.widgetConfig.config.settings.showLegend = config.showLegend; + this.widgetConfig.config.settings.legendPosition = config.legendPosition; + this.widgetConfig.config.settings.legendLabelFont = config.legendLabelFont; + this.widgetConfig.config.settings.legendLabelColor = config.legendLabelColor; + + this.widgetConfig.config.settings.showTooltip = config.showTooltip; + this.widgetConfig.config.settings.tooltipValueFont = config.tooltipValueFont; + this.widgetConfig.config.settings.tooltipValueColor = config.tooltipValueColor; + this.widgetConfig.config.settings.tooltipShowDate = config.tooltipShowDate; + this.widgetConfig.config.settings.tooltipDateFormat = config.tooltipDateFormat; + this.widgetConfig.config.settings.tooltipDateFont = config.tooltipDateFont; + this.widgetConfig.config.settings.tooltipDateColor = config.tooltipDateColor; + this.widgetConfig.config.settings.tooltipBackgroundColor = config.tooltipBackgroundColor; + this.widgetConfig.config.settings.tooltipBackgroundBlur = config.tooltipBackgroundBlur; + + this.widgetConfig.config.settings.background = config.background; + + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.borderRadius = config.borderRadius; + + this.widgetConfig.config.actions = config.actions; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showTitle', 'showIcon', 'showBarLabel', 'showBarValue', 'showLegend', 'showTooltip', 'tooltipShowDate']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.barChartWidgetConfigForm.get('showTitle').value; + const showIcon: boolean = this.barChartWidgetConfigForm.get('showIcon').value; + const showBarLabel: boolean = this.barChartWidgetConfigForm.get('showBarLabel').value; + const showBarValue: boolean = this.barChartWidgetConfigForm.get('showBarValue').value; + const showLegend: boolean = this.barChartWidgetConfigForm.get('showLegend').value; + const showTooltip: boolean = this.barChartWidgetConfigForm.get('showTooltip').value; + const tooltipShowDate: boolean = this.barChartWidgetConfigForm.get('tooltipShowDate').value; + + if (showTitle) { + this.barChartWidgetConfigForm.get('title').enable(); + this.barChartWidgetConfigForm.get('titleFont').enable(); + this.barChartWidgetConfigForm.get('titleColor').enable(); + this.barChartWidgetConfigForm.get('showIcon').enable({emitEvent: false}); + if (showIcon) { + this.barChartWidgetConfigForm.get('iconSize').enable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').enable(); + this.barChartWidgetConfigForm.get('icon').enable(); + this.barChartWidgetConfigForm.get('iconColor').enable(); + } else { + this.barChartWidgetConfigForm.get('iconSize').disable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').disable(); + this.barChartWidgetConfigForm.get('icon').disable(); + this.barChartWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.barChartWidgetConfigForm.get('title').disable(); + this.barChartWidgetConfigForm.get('titleFont').disable(); + this.barChartWidgetConfigForm.get('titleColor').disable(); + this.barChartWidgetConfigForm.get('showIcon').disable({emitEvent: false}); + this.barChartWidgetConfigForm.get('iconSize').disable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').disable(); + this.barChartWidgetConfigForm.get('icon').disable(); + this.barChartWidgetConfigForm.get('iconColor').disable(); + } + + if (showBarLabel) { + this.barChartWidgetConfigForm.get('barLabelFont').enable(); + this.barChartWidgetConfigForm.get('barLabelColor').enable(); + } else { + this.barChartWidgetConfigForm.get('barLabelFont').disable(); + this.barChartWidgetConfigForm.get('barLabelColor').disable(); + } + + if (showBarValue) { + this.barChartWidgetConfigForm.get('barValueFont').enable(); + this.barChartWidgetConfigForm.get('barValueColor').enable(); + } else { + this.barChartWidgetConfigForm.get('barValueFont').disable(); + this.barChartWidgetConfigForm.get('barValueColor').disable(); + } + + if (showLegend) { + this.barChartWidgetConfigForm.get('legendPosition').enable(); + this.barChartWidgetConfigForm.get('legendLabelFont').enable(); + this.barChartWidgetConfigForm.get('legendLabelColor').enable(); + } else { + this.barChartWidgetConfigForm.get('legendPosition').disable(); + this.barChartWidgetConfigForm.get('legendLabelFont').disable(); + this.barChartWidgetConfigForm.get('legendLabelColor').disable(); + } + + if (showTooltip) { + this.barChartWidgetConfigForm.get('tooltipValueFont').enable(); + this.barChartWidgetConfigForm.get('tooltipValueColor').enable(); + this.barChartWidgetConfigForm.get('tooltipShowDate').enable({emitEvent: false}); + this.barChartWidgetConfigForm.get('tooltipBackgroundColor').enable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundBlur').enable(); + if (tooltipShowDate) { + this.barChartWidgetConfigForm.get('tooltipDateFormat').enable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').enable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').enable(); + } else { + this.barChartWidgetConfigForm.get('tooltipDateFormat').disable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').disable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').disable(); + } + } else { + this.barChartWidgetConfigForm.get('tooltipValueFont').disable(); + this.barChartWidgetConfigForm.get('tooltipValueColor').disable(); + this.barChartWidgetConfigForm.get('tooltipShowDate').disable({emitEvent: false}); + this.barChartWidgetConfigForm.get('tooltipDateFormat').disable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').disable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').disable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundColor').disable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundBlur').disable(); + } + } + + private getSeries(datasources?: Datasource[]): DataKey[] { + if (datasources && datasources.length) { + return datasources[0].dataKeys || []; + } + return []; + } + + private setSeries(series: DataKey[], datasources?: Datasource[]) { + if (datasources && datasources.length) { + datasources[0].dataKeys = series; + } + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.enableFullscreen = buttons.includes('fullscreen'); + } + + private _tooltipValuePreviewFn(): string { + const units: string = this.barChartWidgetConfigForm.get('units').value; + const decimals: number = this.barChartWidgetConfigForm.get('decimals').value; + return formatValue(22, decimals, units, false); + } + + private _tooltipDatePreviewFn(): string { + const dateFormat: DateFormatSettings = this.barChartWidgetConfigForm.get('tooltipDateFormat').value; + const processor = DateFormatProcessor.fromSettings(this.$injector, dateFormat); + processor.update(Date.now()); + return processor.formatted; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html index 00c4929f3c..c12cf02299 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html @@ -145,14 +145,14 @@
{{ 'legend.position' | translate }}
- - {{ doughnutLegendPositionTranslationMap.get(pos) | translate }} + + {{ legendPositionTranslationMap.get(pos) | translate }}
-
{{ 'widgets.doughnut.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -164,7 +164,7 @@
-
{{ 'widgets.doughnut.legend-value' | translate }}
+
{{ 'legend.value' | translate }}
@@ -184,13 +184,13 @@ - {{ 'widgets.doughnut.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.doughnut.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -213,14 +213,14 @@
-
{{ 'widgets.doughnut.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.doughnut.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts index f8149bc97d..0ab89281bc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts @@ -25,6 +25,8 @@ import { Datasource, datasourcesHasAggregation, datasourcesHasOnlyComparisonAggregation, + legendPositions, + legendPositionTranslationMap, WidgetConfig } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; @@ -40,8 +42,6 @@ import { doughnutLayoutImages, doughnutLayouts, doughnutLayoutTranslations, - doughnutLegendPositions, - doughnutLegendPositionTranslations, DoughnutTooltipValueType, doughnutTooltipValueTypes, doughnutTooltipValueTypeTranslations, @@ -83,9 +83,9 @@ export class DoughnutBasicConfigComponent extends BasicWidgetConfigComponent { doughnutLayoutImageMap: Map; - doughnutLegendPositions = doughnutLegendPositions; + legendPositions = legendPositions; - doughnutLegendPositionTranslationMap = doughnutLegendPositionTranslations; + legendPositionTranslationMap = legendPositionTranslationMap; doughnutTooltipValueTypes = doughnutTooltipValueTypes; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html index 66b4054df1..391007d155 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html @@ -49,7 +49,7 @@
- {{ 'widgets.value-chart-card.icon' | translate }} + {{ 'widget-config.card-icon' | translate }}
@@ -127,7 +127,7 @@
-
{{ 'widgets.range-chart.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -147,13 +147,13 @@ - {{ 'widgets.range-chart.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.range-chart.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -166,7 +166,7 @@
- {{ 'widgets.range-chart.tooltip-date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -180,14 +180,14 @@
-
{{ 'widgets.range-chart.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.range-chart.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html index 4669bf5f82..9edf205d11 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html @@ -117,14 +117,14 @@ - {{ 'widgets.signal-strength.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
- {{ 'widgets.signal-strength.value' | translate }} + {{ 'tooltip.value' | translate }}
@@ -144,7 +144,7 @@
- {{ 'widgets.signal-strength.date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -158,13 +158,13 @@
-
{{ 'widgets.signal-strength.background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
widgets.signal-strength.background-blur
+
tooltip.background-blur
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts index 62c7209dbd..c325bb0e73 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -36,14 +36,8 @@ import { textStyle } from '@shared/models/widget-settings.models'; import { ResizeObserver } from '@juggle/resize-observer'; -import * as echarts from 'echarts/core'; -import { Axis } from 'echarts'; import { formatValue } from '@core/utils'; -import { GridComponent, GridComponentOption, TooltipComponent, TooltipComponentOption } from 'echarts/components'; -import { LabelLayout } from 'echarts/features'; -import { BarChart, BarSeriesOption} from 'echarts/charts'; -import { CanvasRenderer } from 'echarts/renderers'; -import { DataKey, DataSet } from '@shared/models/widget.models'; +import { DataKey } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; @@ -51,40 +45,19 @@ import { barChartWithLabelsDefaultSettings, BarChartWithLabelsWidgetSettings } from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; -import { LabelLayoutOptionCallback } from 'echarts/types/dist/shared'; -import BarSeriesModel from 'echarts/types/src/chart/bar/BarSeries'; - -const axisGetBandWidth = Axis.prototype.getBandWidth; - -Axis.prototype.getBandWidth = function(){ - const series: any[] = this.model?.parentModel?.getSeries(); - if (this.scale.type === 'time' && series?.length && series[0].type === 'series.bar') { - const barWidth = (series[0] as BarSeriesModel).getData().getLayout('size'); - return barWidth * (series.length + 1); - } else { - return axisGetBandWidth.call(this); - } -}; - -echarts.use([ - TooltipComponent, - GridComponent, - BarChart, - LabelLayout, - CanvasRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | GridComponentOption - | BarSeriesOption ->; - -type ECharts = echarts.ECharts; -type NamedDataSet = {name: string; value: [number, any]}[]; +import * as echarts from 'echarts/core'; +import { CustomSeriesOption } from 'echarts/charts'; +import { CallbackDataParams, CustomSeriesRenderItem, LabelLayoutOptionCallback } from 'echarts/types/dist/shared'; -type BarLabelOption = NonNullable; +import { + ECharts, + echartsModule, + EChartsOption, + echartsTooltipFormatter, + NamedDataSet, + toNamedData +} from '@home/components/widget/lib/chart/echarts-widget.models'; interface BarChartDataItem { id: string; @@ -100,17 +73,6 @@ interface BarChartLegendItem { enabled: boolean; } -const toNamedData = (data: DataSet): NamedDataSet => { - if (!data?.length) { - return []; - } else { - return data.map(d => ({ - name: d[0] + '', - value: d - })); - } -}; - @Component({ selector: 'tb-bar-chart-with-labels-widget', templateUrl: './bar-chart-with-labels-widget.component.html', @@ -153,7 +115,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft private tooltipDateFormat: DateFormatProcessor; - private barLabelOptions: BarLabelOption; + private barRenderItem: CustomSeriesRenderItem; private barLabelLayoutCallback: LabelLayoutOptionCallback; constructor(private imagePipe: ImagePipe, @@ -216,41 +178,85 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft const barValueStyle: ComponentStyle = textStyle(this.settings.barValueFont); delete barValueStyle.lineHeight; barValueStyle.fontSize = this.settings.barValueFont.size; - barValueStyle.color = this.settings.barValueColor; + barValueStyle.fill = this.settings.barValueColor; const barLabelStyle: ComponentStyle = textStyle(this.settings.barLabelFont); delete barLabelStyle.lineHeight; barLabelStyle.fontSize = this.settings.barLabelFont.size; - barLabelStyle.color = this.settings.barLabelColor; - - this.barLabelOptions = { - show: this.settings.showBarLabel || this.settings.showBarValue, - position: 'insideBottom', - distance: 15, - align: 'left', - verticalAlign: 'middle', - rotate: 90, - formatter: (params) => { - const parts: string[] = []; - if (this.settings.showBarValue) { - const value = formatValue(params.value[1], this.decimals, '', false); - parts.push(`{value|${value}}`); - } - if (this.settings.showBarLabel) { - parts.push(`{label|${params.seriesName}}`); - } - return parts.join(' '); - }, - rich: { - value: barValueStyle, - label: barLabelStyle + barLabelStyle.fill = this.settings.barLabelColor; + + this.barRenderItem = (params, api) => { + + const interval = this.ctx.defaultSubscription.timeWindow.interval; + const enabledDataItems = this.dataItems.filter(d => d.enabled); + const barInterval = interval / (enabledDataItems.length + 1); + const intervalGap = barInterval / 2; + + const index = enabledDataItems.findIndex(d => d.id === params.seriesId); + const time = api.value(0) as number; + const value = api.value(1); + const start = time - interval / 2; + const startTime = start + intervalGap + barInterval * index; + const delta = barInterval; + const lowerLeft = api.coord([startTime, value]); + const height = api.size([delta, value])[1]; + const width = api.size([delta, 10])[0]; + + const coordSys: {x: number; y: number; width: number; height: number} = params.coordSys as any; + + const rectShape = echarts.graphic.clipRectByRect({ + x: lowerLeft[0], + y: lowerLeft[1], + width, + height + }, { + x: coordSys.x, + y: coordSys.y, + width: coordSys.width, + height: coordSys.height + }); + + const zeroPos = api.coord([0, 0]); + const labelParts: string[] = []; + if (this.settings.showBarValue) { + const labelValue = formatValue(value, this.decimals, '', false); + labelParts.push(`{value|${labelValue}}`); } + if (this.settings.showBarLabel) { + labelParts.push(`{label|${params.seriesName}}`); + } + const barLabel = labelParts.join(' '); + return rectShape && { + type: 'rect', + id: time + '', + shape: rectShape, + style: { + fill: api.visual('color'), + text: barLabel, + textPosition: 'insideBottom', + textRotation: Math.PI / 2, + textDistance: 15, + textStrokeWidth: 0, + textAlign: 'left', + textVerticalAlign: 'middle', + rich: { + value: barValueStyle, + label: barLabelStyle + } + }, + focus: 'series', + transition: 'all', + enterFrom: { + style: { opacity: 0 }, + shape: { height: 0, y: zeroPos[1] } + } + }; }; this.barLabelLayoutCallback = (params) => { if (params.rect.width - params.labelRect.width < 2) { return { - y: '-100%' + y: '1000%', }; } else { return { @@ -288,38 +294,44 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft public onDataUpdated() { let minTime = this.ctx.defaultSubscription.timeWindow.minTime; + let maxTime = this.ctx.defaultSubscription.timeWindow.maxTime; + let dataMin = Number.MAX_VALUE; + let dataMax = Number.MIN_VALUE; for (const item of this.dataItems) { const datasourceData = this.ctx.data ? this.ctx.data.find(d => d.dataKey === item.dataKey) : null; - const namedData = datasourceData?.data ? toNamedData(datasourceData.data) : []; - item.data = namedData; + item.data = datasourceData?.data ? toNamedData(datasourceData.data) : []; if (datasourceData.data.length) { - minTime = Math.min(datasourceData.data[0][0], minTime); + dataMin = Math.min(datasourceData.data[0][0], dataMin); + dataMax = Math.max(datasourceData.data[datasourceData.data.length-1][0], dataMax); } } + if (dataMin !== Number.MAX_VALUE) { + minTime = dataMin - this.ctx.defaultSubscription.timeWindow.interval / 2; + } + if (dataMax !== Number.MIN_VALUE) { + dataMax = dataMax + this.ctx.defaultSubscription.timeWindow.interval / 2; + maxTime = Math.max(dataMax, maxTime); + } if (this.barChart) { (this.barChartOptions.xAxis as any).min = minTime; - (this.barChartOptions.xAxis as any).max = this.ctx.defaultSubscription.timeWindow.maxTime; + (this.barChartOptions.xAxis as any).max = maxTime; + (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; this.barChartOptions.series = this.updateSeries(); this.barChart.setOption(this.barChartOptions); } } - private updateSeries(): Array { - const series: Array = []; + private updateSeries(): Array { + const series: Array = []; for (const item of this.dataItems) { if (item.enabled) { - const seriesOption: BarSeriesOption = { - type: 'bar', - barGap: 0, - barMaxWidth: 40, + const seriesOption: CustomSeriesOption = { + type: 'custom', id: item.id, name: item.dataKey.label, - label: this.barLabelOptions, color: item.dataKey.color, data: item.data, - emphasis: { - focus: 'series' - }, + renderItem: this.barRenderItem, labelLayout: this.barLabelLayoutCallback }; series.push(seriesOption); @@ -328,6 +340,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft return series; } + public onLegendItemEnter(item: BarChartLegendItem) { this.barChart.dispatchAction({ type: 'highlight', @@ -347,26 +360,26 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft const dataItem = this.dataItems.find(d => d.id === item.id); if (dataItem) { dataItem.enabled = enable; + if (!enable) { + this.barChart.dispatchAction({ + type: 'downplay', + seriesId: item.id + }); + } this.barChartOptions.series = this.updateSeries(); - this.barChart.setOption(this.barChartOptions, true); + this.barChart.setOption(this.barChartOptions, {replaceMerge: ['series']}); item.enabled = enable; if (enable) { this.barChart.dispatchAction({ type: 'highlight', seriesId: item.id }); - } else { - for (const otherItem of this.legendItems.filter(i => i.id !== item.id)) { - this.barChart.dispatchAction({ - type: 'highlight', - seriesId: otherItem.id - }); - } } } } private drawChart() { + echartsModule.init(); this.barChart = echarts.init(this.chartShape.nativeElement, null, { renderer: 'canvas', }); @@ -383,6 +396,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft }, xAxis: { type: 'time', + scale: true, axisTick: { show: false }, @@ -393,17 +407,19 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft axisLine: { onZero: false }, - min: this.ctx.defaultSubscription.timeWindow.minTime, - max: this.ctx.defaultSubscription.timeWindow.maxTime + min: this.ctx.defaultSubscription.timeWindow.minTime - this.ctx.defaultSubscription.timeWindow.interval / 2, + max: this.ctx.defaultSubscription.timeWindow.maxTime + this.ctx.defaultSubscription.timeWindow.interval / 2 }, yAxis: { type: 'value', axisLabel: { - formatter: value => formatValue(value, this.decimals, this.units, false) + formatter: (value: any) => formatValue(value, this.decimals, this.units, false) } } }; + (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; + this.barChartOptions.series = this.updateSeries(); if (this.settings.showTooltip) { @@ -412,44 +428,14 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft axisPointer: { type: 'shadow' }, - formatter: (params: any[]) => { - if (!params.length || !params[0]) { - return null; - } - const tooltipElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(tooltipElement, 'display', 'flex'); - this.renderer.setStyle(tooltipElement, 'flex-direction', 'column'); - this.renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); - this.renderer.setStyle(tooltipElement, 'gap', '4px'); - if (this.settings.tooltipShowDate) { - const dateElement: HTMLElement = this.renderer.createElement('div'); - const ts = params[0].value[0]; - this.tooltipDateFormat.update(ts); - this.renderer.appendChild(dateElement, this.renderer.createText(this.tooltipDateFormat.formatted)); - this.renderer.setStyle(dateElement, 'font-family', this.settings.tooltipDateFont.family); - this.renderer.setStyle(dateElement, 'font-size', this.settings.tooltipDateFont.size + this.settings.tooltipDateFont.sizeUnit); - this.renderer.setStyle(dateElement, 'font-style', this.settings.tooltipDateFont.style); - this.renderer.setStyle(dateElement, 'font-weight', this.settings.tooltipDateFont.weight); - this.renderer.setStyle(dateElement, 'line-height', this.settings.tooltipDateFont.lineHeight); - this.renderer.setStyle(dateElement, 'color', this.settings.tooltipDateColor); - this.renderer.appendChild(tooltipElement, dateElement); - } - let seriesParams = null; + formatter: (params: CallbackDataParams[]) => { const focusedSeriesIndex = this.focusedSeriesIndex(); - if (focusedSeriesIndex > -1) { - seriesParams = params.find(param => param.seriesIndex === focusedSeriesIndex); - } - if (seriesParams) { - this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); - } else { - for (seriesParams of params) { - this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); - } - } - return tooltipElement; + return echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, focusedSeriesIndex); }, padding: [8, 12], backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }; } @@ -463,65 +449,22 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft this.onResize(); } - private constructTooltipSeriesElement(seriesParams): HTMLElement { - const labelValueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelValueElement, 'display', 'flex'); - this.renderer.setStyle(labelValueElement, 'flex-direction', 'row'); - this.renderer.setStyle(labelValueElement, 'align-items', 'center'); - this.renderer.setStyle(labelValueElement, 'align-self', 'stretch'); - this.renderer.setStyle(labelValueElement, 'gap', '12px'); - const labelElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelElement, 'display', 'flex'); - this.renderer.setStyle(labelElement, 'align-items', 'center'); - this.renderer.setStyle(labelElement, 'gap', '8px'); - this.renderer.appendChild(labelValueElement, labelElement); - const circleElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(circleElement, 'width', '8px'); - this.renderer.setStyle(circleElement, 'height', '8px'); - this.renderer.setStyle(circleElement, 'border-radius', '50%'); - this.renderer.setStyle(circleElement, 'background', seriesParams.color); - this.renderer.appendChild(labelElement, circleElement); - const labelTextElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(labelTextElement, this.renderer.createText(seriesParams.seriesName)); - this.renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); - this.renderer.setStyle(labelTextElement, 'font-size', '12px'); - this.renderer.setStyle(labelTextElement, 'font-style', 'normal'); - this.renderer.setStyle(labelTextElement, 'font-weight', '400'); - this.renderer.setStyle(labelTextElement, 'line-height', '16px'); - this.renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); - this.renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); - this.renderer.appendChild(labelElement, labelTextElement); - const valueElement: HTMLElement = this.renderer.createElement('div'); - const value = formatValue(seriesParams.value[1], this.decimals, this.units, false); - this.renderer.appendChild(valueElement, this.renderer.createText(value)); - this.renderer.setStyle(valueElement, 'flex', '1'); - this.renderer.setStyle(valueElement, 'text-align', 'end'); - this.renderer.setStyle(valueElement, 'font-family', this.settings.tooltipValueFont.family); - this.renderer.setStyle(valueElement, 'font-size', this.settings.tooltipValueFont.size + this.settings.tooltipValueFont.sizeUnit); - this.renderer.setStyle(valueElement, 'font-style', this.settings.tooltipValueFont.style); - this.renderer.setStyle(valueElement, 'font-weight', this.settings.tooltipValueFont.weight); - this.renderer.setStyle(valueElement, 'line-height', this.settings.tooltipValueFont.lineHeight); - this.renderer.setStyle(valueElement, 'color', this.settings.tooltipValueColor); - this.renderer.appendChild(labelValueElement, valueElement); - return labelValueElement; - } - private focusedSeriesIndex(): number { let index = - 1; - // @ts-ignore - const views: any[] = this.barChart._chartsViews; + const views: any[] = (this.barChart as any)._chartsViews; if (views) { const hasBlurredView = !!views.find(view => { const graphicEls: any[] = view._data._graphicEls; - return !!graphicEls.find(el => el.currentStates.includes('blur')); + return !!graphicEls.find(el => el?.currentStates.includes('blur')); }); if (hasBlurredView) { const focusedView = views.find(view => { const graphicEls: any[] = view._data._graphicEls; - return !!graphicEls.find(el => !el.currentStates.includes('blur')); + return !!graphicEls.find(el => !el?.currentStates.includes('blur')); }); if (focusedView) { - index = focusedView._model.seriesIndex; + index = !!focusedView._model ? + focusedView._model.seriesIndex : (!!focusedView.__model ? focusedView.__model.seriesIndex : -1); } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts index b56b2bc435..ecb5e8a667 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts @@ -14,15 +14,11 @@ /// limitations under the License. /// -import { - BackgroundSettings, - BackgroundType, customDateFormat, - DateFormatSettings, - Font -} from '@shared/models/widget-settings.models'; +import { BackgroundSettings, BackgroundType, customDateFormat, Font } from '@shared/models/widget-settings.models'; import { LegendPosition } from '@shared/models/widget.models'; +import { EChartsTooltipWidgetSettings } from '@home/components/widget/lib/chart/echarts-widget.models'; -export interface BarChartWithLabelsWidgetSettings { +export interface BarChartWithLabelsWidgetSettings extends EChartsTooltipWidgetSettings { showBarLabel: boolean; barLabelFont: Font; barLabelColor: string; @@ -33,15 +29,6 @@ export interface BarChartWithLabelsWidgetSettings { legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; - showTooltip: boolean; - tooltipValueFont: Font; - tooltipValueColor: string; - tooltipShowDate: boolean; - tooltipDateFormat: DateFormatSettings; - tooltipDateFont: Font; - tooltipDateColor: string; - tooltipBackgroundColor: string; - tooltipBackgroundBlur: number; background: BackgroundSettings; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts index 928445d316..28550c339e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts @@ -30,7 +30,6 @@ import { import { doughnutDefaultSettings, DoughnutLayout, - DoughnutLegendPosition, DoughnutTooltipValueType, DoughnutWidgetSettings } from '@home/components/widget/lib/chart/doughnut-widget.models'; @@ -49,25 +48,11 @@ import { TranslateService } from '@ngx-translate/core'; import { PieDataItemOption } from 'echarts/types/src/chart/pie/PieSeries'; import { formatValue, isDefinedAndNotNull, isNumeric } from '@core/utils'; import { SVG, Svg, Text } from '@svgdotjs/svg.js'; -import { DataKey } from '@shared/models/widget.models'; -import { TooltipComponent, TooltipComponentOption } from 'echarts/components'; -import { PieChart, PieSeriesOption } from 'echarts/charts'; -import { SVGRenderer } from 'echarts/renderers'; +import { DataKey, LegendPosition } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; - -echarts.use([ - TooltipComponent, - PieChart, - SVGRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | PieSeriesOption ->; -type ECharts = echarts.ECharts; +import { ECharts, echartsModule, EChartsOption } from '@home/components/widget/lib/chart/echarts-widget.models'; const shapeSize = 134; const shapeSegmentWidth = 13.4; @@ -178,7 +163,7 @@ export class DoughnutWidgetComponent implements OnInit, OnDestroy, AfterViewInit if (this.showLegend) { this.legendItems = []; this.legendClass = `legend-${this.settings.legendPosition}`; - this.legendHorizontal = [DoughnutLegendPosition.left, DoughnutLegendPosition.right].includes(this.settings.legendPosition); + this.legendHorizontal = [LegendPosition.left, LegendPosition.right].includes(this.settings.legendPosition); this.legendLabelStyle = textStyle(this.settings.legendLabelFont); this.disabledLegendLabelStyle = textStyle(this.settings.legendLabelFont); this.legendLabelStyle.color = this.settings.legendLabelColor; @@ -387,6 +372,7 @@ export class DoughnutWidgetComponent implements OnInit, OnDestroy, AfterViewInit } private drawDoughnut() { + echartsModule.init(); const shapeWidth = this.doughnutShape.nativeElement.getBoundingClientRect().width; const shapeHeight = this.doughnutShape.nativeElement.getBoundingClientRect().height; const size = this.settings.autoScale ? shapeSize : Math.min(shapeWidth, shapeHeight); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts index 1771dbbb8a..52507dc2b5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts @@ -21,6 +21,7 @@ import { constantColor, Font } from '@shared/models/widget-settings.models'; +import { LegendPosition } from '@shared/models/widget.models'; export enum DoughnutLayout { default = 'default', @@ -50,24 +51,6 @@ export const horizontalDoughnutLayoutImages = new Map( ] ); -export enum DoughnutLegendPosition { - top = 'top', - bottom = 'bottom', - left = 'left', - right = 'right' -} - -export const doughnutLegendPositions = Object.keys(DoughnutLegendPosition) as DoughnutLegendPosition[]; - -export const doughnutLegendPositionTranslations = new Map( - [ - [DoughnutLegendPosition.top, 'widgets.doughnut.legend-position-top'], - [DoughnutLegendPosition.bottom, 'widgets.doughnut.legend-position-bottom'], - [DoughnutLegendPosition.left, 'widgets.doughnut.legend-position-left'], - [DoughnutLegendPosition.right, 'widgets.doughnut.legend-position-right'] - ] -); - export enum DoughnutTooltipValueType { absolute = 'absolute', percentage = 'percentage' @@ -90,7 +73,7 @@ export interface DoughnutWidgetSettings { totalValueFont: Font; totalValueColor: ColorSettings; showLegend: boolean; - legendPosition: DoughnutLegendPosition; + legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; legendValueFont: Font; @@ -120,7 +103,7 @@ export const doughnutDefaultSettings = (horizontal: boolean): DoughnutWidgetSett }, totalValueColor: constantColor('rgba(0, 0, 0, 0.87)'), showLegend: true, - legendPosition: horizontal ? DoughnutLegendPosition.right : DoughnutLegendPosition.bottom, + legendPosition: horizontal ? LegendPosition.right : LegendPosition.bottom, legendLabelFont: { family: 'Roboto', size: 12, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts new file mode 100644 index 0000000000..3587a246ae --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts @@ -0,0 +1,214 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import * as echarts from 'echarts/core'; +import { Axis } from 'echarts'; +import AxisModel from 'echarts/types/src/coord/cartesian/AxisModel'; +import { formatValue, isNumber } from '@core/utils'; +import TimeScale from 'echarts/types/src/scale/Time'; +import { + DataZoomComponent, DataZoomComponentOption, + GridComponent, GridComponentOption, + MarkLineComponent, MarkLineComponentOption, + TooltipComponent, TooltipComponentOption, + VisualMapComponent, VisualMapComponentOption +} from 'echarts/components'; +import { + BarChart, + LineChart, + CustomChart, + CustomSeriesOption, + LineSeriesOption, + BarSeriesOption, PieSeriesOption, PieChart +} from 'echarts/charts'; +import { LabelLayout } from 'echarts/features'; +import { CanvasRenderer, SVGRenderer } from 'echarts/renderers'; +import { DataSet } from '@shared/models/widget.models'; +import { CallbackDataParams } from 'echarts/types/dist/shared'; +import { Renderer2 } from '@angular/core'; +import { DateFormatProcessor, DateFormatSettings, Font } from '@shared/models/widget-settings.models'; + +class EChartsModule { + private initialized = false; + + init() { + if (!this.initialized) { + const axisGetBandWidth = Axis.prototype.getBandWidth; + + Axis.prototype.getBandWidth = function(){ + const model: AxisModel = this.model; + const axisOption = model.option; + const tbTimewindowInterval = (axisOption as any).tbTimewindowInterval; + if (this.scale.type === 'time' && isNumber(tbTimewindowInterval)) { + const timeScale: TimeScale = this.scale; + const axisExtent: [number, number] = this._extent; + const dataExtent = timeScale.getExtent(); + const size = Math.abs(axisExtent[1] - axisExtent[0]); + return tbTimewindowInterval * (size / (dataExtent[1] - dataExtent[0])); + } else { + return axisGetBandWidth.call(this); + } + }; + + echarts.use([ + TooltipComponent, + GridComponent, + VisualMapComponent, + DataZoomComponent, + MarkLineComponent, + LineChart, + BarChart, + PieChart, + CustomChart, + LabelLayout, + CanvasRenderer, + SVGRenderer + ]); + + this.initialized = true; + } + } +} + +export const echartsModule = new EChartsModule(); + +export type EChartsOption = echarts.ComposeOption< + | TooltipComponentOption + | GridComponentOption + | VisualMapComponentOption + | DataZoomComponentOption + | MarkLineComponentOption + | LineSeriesOption + | CustomSeriesOption + | BarSeriesOption + | PieSeriesOption +>; + +export type ECharts = echarts.ECharts; + +export type NamedDataSet = {name: string; value: [number, any]}[]; + +export const toNamedData = (data: DataSet): NamedDataSet => { + if (!data?.length) { + return []; + } else { + return data.map(d => ({ + name: d[0] + '', + value: d + })); + } +}; + +export interface EChartsTooltipWidgetSettings { + showTooltip: boolean; + tooltipValueFont: Font; + tooltipValueColor: string; + tooltipShowDate: boolean; + tooltipDateFormat: DateFormatSettings; + tooltipDateFont: Font; + tooltipDateColor: string; + tooltipBackgroundColor: string; + tooltipBackgroundBlur: number; +} + +export const echartsTooltipFormatter = (renderer: Renderer2, + tooltipDateFormat: DateFormatProcessor, + settings: EChartsTooltipWidgetSettings, + params: CallbackDataParams[], + decimals: number, + units: string, + focusedSeriesIndex: number): null | HTMLElement => { + if (!params.length || !params[0]) { + return null; + } + const tooltipElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(tooltipElement, 'display', 'flex'); + renderer.setStyle(tooltipElement, 'flex-direction', 'column'); + renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); + renderer.setStyle(tooltipElement, 'gap', '4px'); + if (settings.tooltipShowDate) { + const dateElement: HTMLElement = renderer.createElement('div'); + const ts = params[0].value[0]; + tooltipDateFormat.update(ts); + renderer.appendChild(dateElement, renderer.createText(tooltipDateFormat.formatted)); + renderer.setStyle(dateElement, 'font-family', settings.tooltipDateFont.family); + renderer.setStyle(dateElement, 'font-size', settings.tooltipDateFont.size + settings.tooltipDateFont.sizeUnit); + renderer.setStyle(dateElement, 'font-style', settings.tooltipDateFont.style); + renderer.setStyle(dateElement, 'font-weight', settings.tooltipDateFont.weight); + renderer.setStyle(dateElement, 'line-height', settings.tooltipDateFont.lineHeight); + renderer.setStyle(dateElement, 'color', settings.tooltipDateColor); + renderer.appendChild(tooltipElement, dateElement); + } + let seriesParams: CallbackDataParams = null; + if (focusedSeriesIndex > -1) { + seriesParams = params.find(param => param.seriesIndex === focusedSeriesIndex); + } + if (seriesParams) { + renderer.appendChild(tooltipElement, constructEchartsTooltipSeriesElement(renderer, settings, seriesParams, decimals, units)); + } else { + for (seriesParams of params) { + renderer.appendChild(tooltipElement, constructEchartsTooltipSeriesElement(renderer, settings, seriesParams, decimals, units)); + } + } + return tooltipElement; +}; + +const constructEchartsTooltipSeriesElement = (renderer: Renderer2, + settings: EChartsTooltipWidgetSettings, + seriesParams: CallbackDataParams, + decimals: number, + units: string): HTMLElement => { + const labelValueElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(labelValueElement, 'display', 'flex'); + renderer.setStyle(labelValueElement, 'flex-direction', 'row'); + renderer.setStyle(labelValueElement, 'align-items', 'center'); + renderer.setStyle(labelValueElement, 'align-self', 'stretch'); + renderer.setStyle(labelValueElement, 'gap', '12px'); + const labelElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(labelElement, 'display', 'flex'); + renderer.setStyle(labelElement, 'align-items', 'center'); + renderer.setStyle(labelElement, 'gap', '8px'); + renderer.appendChild(labelValueElement, labelElement); + const circleElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(circleElement, 'width', '8px'); + renderer.setStyle(circleElement, 'height', '8px'); + renderer.setStyle(circleElement, 'border-radius', '50%'); + renderer.setStyle(circleElement, 'background', seriesParams.color); + renderer.appendChild(labelElement, circleElement); + const labelTextElement: HTMLElement = renderer.createElement('div'); + renderer.appendChild(labelTextElement, renderer.createText(seriesParams.seriesName)); + renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); + renderer.setStyle(labelTextElement, 'font-size', '12px'); + renderer.setStyle(labelTextElement, 'font-style', 'normal'); + renderer.setStyle(labelTextElement, 'font-weight', '400'); + renderer.setStyle(labelTextElement, 'line-height', '16px'); + renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); + renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); + renderer.appendChild(labelElement, labelTextElement); + const valueElement: HTMLElement = renderer.createElement('div'); + const value = formatValue(seriesParams.value[1], decimals, units, false); + renderer.appendChild(valueElement, renderer.createText(value)); + renderer.setStyle(valueElement, 'flex', '1'); + renderer.setStyle(valueElement, 'text-align', 'end'); + renderer.setStyle(valueElement, 'font-family', settings.tooltipValueFont.family); + renderer.setStyle(valueElement, 'font-size', settings.tooltipValueFont.size + settings.tooltipValueFont.sizeUnit); + renderer.setStyle(valueElement, 'font-style', settings.tooltipValueFont.style); + renderer.setStyle(valueElement, 'font-weight', settings.tooltipValueFont.weight); + renderer.setStyle(valueElement, 'line-height', settings.tooltipValueFont.lineHeight); + renderer.setStyle(valueElement, 'color', settings.tooltipValueColor); + renderer.appendChild(labelValueElement, valueElement); + return labelValueElement; +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts index 4625e4a2a9..4ff9c53a71 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts @@ -32,7 +32,8 @@ import { backgroundStyle, ColorRange, ComponentStyle, - DateFormatProcessor, filterIncludingColorRanges, + DateFormatProcessor, + filterIncludingColorRanges, getDataKey, overlayStyle, sortedColorRange, @@ -41,46 +42,18 @@ import { import { ResizeObserver } from '@juggle/resize-observer'; import * as echarts from 'echarts/core'; import { formatValue, isDefinedAndNotNull, isNumber } from '@core/utils'; -import { - DataZoomComponent, - DataZoomComponentOption, - GridComponent, - GridComponentOption, - MarkLineComponent, - MarkLineComponentOption, - TooltipComponent, - TooltipComponentOption, - VisualMapComponent, - VisualMapComponentOption -} from 'echarts/components'; -import { LineChart, LineSeriesOption, } from 'echarts/charts'; -import { CanvasRenderer } from 'echarts/renderers'; import { rangeChartDefaultSettings, RangeChartWidgetSettings } from './range-chart-widget.models'; -import { DataSet } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; - -echarts.use([ - TooltipComponent, - GridComponent, - VisualMapComponent, - DataZoomComponent, - MarkLineComponent, - LineChart, - CanvasRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | GridComponentOption - | VisualMapComponentOption - | DataZoomComponentOption - | MarkLineComponentOption - | LineSeriesOption ->; - -type ECharts = echarts.ECharts; +import { + ECharts, + echartsModule, + EChartsOption, + echartsTooltipFormatter, + toNamedData +} from '@home/components/widget/lib/chart/echarts-widget.models'; +import { CallbackDataParams } from 'echarts/types/dist/shared'; interface VisualPiece { lt?: number; @@ -180,17 +153,6 @@ const toRangeItems = (colorRanges: Array): RangeItem[] => { return rangeItems; }; -const toNamedData = (data: DataSet): {name: string; value: [number, any]}[] => { - if (!data?.length) { - return []; - } else { - return data.map(d => ({ - name: d[0] + '', - value: d - })); - } -}; - const getMarkPoints = (ranges: Array): number[] => { const points = new Set(); for (const range of ranges) { @@ -346,6 +308,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn } private drawChart() { + echartsModule.init(); const dataKey = getDataKey(this.ctx.datasources); this.rangeChart = echarts.init(this.chartShape.nativeElement, null, { renderer: 'canvas', @@ -379,7 +342,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn yAxis: { type: 'value', axisLabel: { - formatter: value => formatValue(value, this.decimals, this.units, false) + formatter: (value: any) => formatValue(value, this.decimals, this.units, false) } }, series: [{ @@ -442,71 +405,11 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn if (this.settings.showTooltip) { this.rangeChartOptions.tooltip = { trigger: 'axis', - formatter: (params) => { - if (!params.length || !params[0]) { - return null; - } - const seriesParams = params[0]; - const value = formatValue(seriesParams.value[1], this.decimals, this.units, false); - const tooltipElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(tooltipElement, 'display', 'flex'); - this.renderer.setStyle(tooltipElement, 'flex-direction', 'column'); - this.renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); - this.renderer.setStyle(tooltipElement, 'gap', '4px'); - if (this.settings.tooltipShowDate) { - const dateElement: HTMLElement = this.renderer.createElement('div'); - const ts = seriesParams.value[0]; - this.tooltipDateFormat.update(ts); - this.renderer.appendChild(dateElement, this.renderer.createText(this.tooltipDateFormat.formatted)); - this.renderer.setStyle(dateElement, 'font-family', this.settings.tooltipDateFont.family); - this.renderer.setStyle(dateElement, 'font-size', this.settings.tooltipDateFont.size + this.settings.tooltipDateFont.sizeUnit); - this.renderer.setStyle(dateElement, 'font-style', this.settings.tooltipDateFont.style); - this.renderer.setStyle(dateElement, 'font-weight', this.settings.tooltipDateFont.weight); - this.renderer.setStyle(dateElement, 'line-height', this.settings.tooltipDateFont.lineHeight); - this.renderer.setStyle(dateElement, 'color', this.settings.tooltipDateColor); - this.renderer.appendChild(tooltipElement, dateElement); - } - const labelValueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelValueElement, 'display', 'flex'); - this.renderer.setStyle(labelValueElement, 'flex-direction', 'row'); - this.renderer.setStyle(labelValueElement, 'align-items', 'center'); - this.renderer.setStyle(labelValueElement, 'align-self', 'stretch'); - this.renderer.setStyle(labelValueElement, 'gap', '12px'); - this.renderer.appendChild(tooltipElement, labelValueElement); - const labelElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelElement, 'display', 'flex'); - this.renderer.setStyle(labelElement, 'align-items', 'center'); - this.renderer.setStyle(labelElement, 'gap', '8px'); - this.renderer.appendChild(labelValueElement, labelElement); - const circleElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(circleElement, 'width', '8px'); - this.renderer.setStyle(circleElement, 'height', '8px'); - this.renderer.setStyle(circleElement, 'border-radius', '50%'); - this.renderer.setStyle(circleElement, 'background', seriesParams.color); - this.renderer.appendChild(labelElement, circleElement); - const labelTextElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(labelTextElement, this.renderer.createText(seriesParams.seriesName)); - this.renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); - this.renderer.setStyle(labelTextElement, 'font-size', '12px'); - this.renderer.setStyle(labelTextElement, 'font-style', 'normal'); - this.renderer.setStyle(labelTextElement, 'font-weight', '400'); - this.renderer.setStyle(labelTextElement, 'line-height', '16px'); - this.renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); - this.renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); - this.renderer.appendChild(labelElement, labelTextElement); - const valueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(valueElement, this.renderer.createText(value)); - this.renderer.setStyle(valueElement, 'font-family', this.settings.tooltipValueFont.family); - this.renderer.setStyle(valueElement, 'font-size', this.settings.tooltipValueFont.size + this.settings.tooltipValueFont.sizeUnit); - this.renderer.setStyle(valueElement, 'font-style', this.settings.tooltipValueFont.style); - this.renderer.setStyle(valueElement, 'font-weight', this.settings.tooltipValueFont.weight); - this.renderer.setStyle(valueElement, 'line-height', this.settings.tooltipValueFont.lineHeight); - this.renderer.setStyle(valueElement, 'color', this.settings.tooltipValueColor); - this.renderer.appendChild(labelValueElement, valueElement); - return tooltipElement; - }, + formatter: (params: CallbackDataParams[]) => echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, 0), padding: [8, 12], backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts index 6bcd0c1497..0c8bb73150 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts @@ -18,12 +18,13 @@ import { BackgroundSettings, BackgroundType, ColorRange, - DateFormatSettings, - Font, simpleDateFormat + Font, + simpleDateFormat } from '@shared/models/widget-settings.models'; import { LegendPosition } from '@shared/models/widget.models'; +import { EChartsTooltipWidgetSettings } from '@home/components/widget/lib/chart/echarts-widget.models'; -export interface RangeChartWidgetSettings { +export interface RangeChartWidgetSettings extends EChartsTooltipWidgetSettings { dataZoom: boolean; rangeColors: Array; outOfRangeColor: string; @@ -32,15 +33,6 @@ export interface RangeChartWidgetSettings { legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; - showTooltip: boolean; - tooltipValueFont: Font; - tooltipValueColor: string; - tooltipShowDate: boolean; - tooltipDateFormat: DateFormatSettings; - tooltipDateFont: Font; - tooltipDateColor: string; - tooltipBackgroundColor: string; - tooltipBackgroundBlur: number; background: BackgroundSettings; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html new file mode 100644 index 0000000000..5652d626ee --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html @@ -0,0 +1,150 @@ + + +
+
widgets.bar-chart.bar-chart-card-style
+
+ + {{ 'widgets.bar-chart.label-on-bar' | translate }} + +
+ + + + +
+
+
+ + {{ 'widgets.bar-chart.value-on-bar' | translate }} + +
+ + + + +
+
+
+ + + + + {{ 'widget-config.legend' | translate }} + + + + +
+
{{ 'legend.position' | translate }}
+ + + + {{ legendPositionTranslationMap.get(pos) | translate }} + + + +
+
+
{{ 'legend.label' | translate }}
+
+ + + + +
+
+
+
+
+
+ + + + + {{ 'widget-config.tooltip' | translate }} + + + + +
+
{{ 'tooltip.value' | translate }}
+
+ + + + +
+
+
+ + {{ 'tooltip.date' | translate }} + +
+ + + + + +
+
+
+
{{ 'tooltip.background-color' | translate }}
+ + +
+
+
{{ 'tooltip.background-blur' | translate }}
+ + +
px
+
+
+
+
+
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts new file mode 100644 index 0000000000..3eee431476 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts @@ -0,0 +1,170 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Injector } from '@angular/core'; +import { + legendPositions, + legendPositionTranslationMap, + WidgetSettings, + WidgetSettingsComponent +} from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { formatValue } from '@core/utils'; +import { DateFormatProcessor, DateFormatSettings } from '@shared/models/widget-settings.models'; +import { + barChartWithLabelsDefaultSettings +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; + +@Component({ + selector: 'tb-bar-chart-with-labels-widget-settings', + templateUrl: './bar-chart-with-labels-widget-settings.component.html', + styleUrls: [] +}) +export class BarChartWithLabelsWidgetSettingsComponent extends WidgetSettingsComponent { + + legendPositions = legendPositions; + + legendPositionTranslationMap = legendPositionTranslationMap; + + barChartWidgetSettingsForm: UntypedFormGroup; + + tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); + + tooltipDatePreviewFn = this._tooltipDatePreviewFn.bind(this); + + constructor(protected store: Store, + private $injector: Injector, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.barChartWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...barChartWithLabelsDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.barChartWidgetSettingsForm = this.fb.group({ + + showBarLabel: [settings.showBarLabel, []], + barLabelFont: [settings.barLabelFont, []], + barLabelColor: [settings.barLabelColor, []], + showBarValue: [settings.showBarValue, []], + barValueFont: [settings.barValueFont, []], + barValueColor: [settings.barValueColor, []], + + showLegend: [settings.showLegend, []], + legendPosition: [settings.legendPosition, []], + legendLabelFont: [settings.legendLabelFont, []], + legendLabelColor: [settings.legendLabelColor, []], + + showTooltip: [settings.showTooltip, []], + tooltipValueFont: [settings.tooltipValueFont, []], + tooltipValueColor: [settings.tooltipValueColor, []], + tooltipShowDate: [settings.tooltipShowDate, []], + tooltipDateFormat: [settings.tooltipDateFormat, []], + tooltipDateFont: [settings.tooltipDateFont, []], + tooltipDateColor: [settings.tooltipDateColor, []], + tooltipBackgroundColor: [settings.tooltipBackgroundColor, []], + tooltipBackgroundBlur: [settings.tooltipBackgroundBlur, []], + + background: [settings.background, []] + }); + } + + protected validatorTriggers(): string[] { + return ['showBarLabel', 'showBarValue', 'showLegend', 'showTooltip', 'tooltipShowDate']; + } + + protected updateValidators(emitEvent: boolean) { + const showBarLabel: boolean = this.barChartWidgetSettingsForm.get('showBarLabel').value; + const showBarValue: boolean = this.barChartWidgetSettingsForm.get('showBarValue').value; + const showLegend: boolean = this.barChartWidgetSettingsForm.get('showLegend').value; + const showTooltip: boolean = this.barChartWidgetSettingsForm.get('showTooltip').value; + const tooltipShowDate: boolean = this.barChartWidgetSettingsForm.get('tooltipShowDate').value; + + if (showBarLabel) { + this.barChartWidgetSettingsForm.get('barLabelFont').enable(); + this.barChartWidgetSettingsForm.get('barLabelColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('barLabelFont').disable(); + this.barChartWidgetSettingsForm.get('barLabelColor').disable(); + } + + if (showBarValue) { + this.barChartWidgetSettingsForm.get('barValueFont').enable(); + this.barChartWidgetSettingsForm.get('barValueColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('barValueFont').disable(); + this.barChartWidgetSettingsForm.get('barValueColor').disable(); + } + + if (showLegend) { + this.barChartWidgetSettingsForm.get('legendPosition').enable(); + this.barChartWidgetSettingsForm.get('legendLabelFont').enable(); + this.barChartWidgetSettingsForm.get('legendLabelColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('legendPosition').disable(); + this.barChartWidgetSettingsForm.get('legendLabelFont').disable(); + this.barChartWidgetSettingsForm.get('legendLabelColor').disable(); + } + + if (showTooltip) { + this.barChartWidgetSettingsForm.get('tooltipValueFont').enable(); + this.barChartWidgetSettingsForm.get('tooltipValueColor').enable(); + this.barChartWidgetSettingsForm.get('tooltipShowDate').enable({emitEvent: false}); + this.barChartWidgetSettingsForm.get('tooltipBackgroundColor').enable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundBlur').enable(); + if (tooltipShowDate) { + this.barChartWidgetSettingsForm.get('tooltipDateFormat').enable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').enable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('tooltipDateFormat').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').disable(); + } + } else { + this.barChartWidgetSettingsForm.get('tooltipValueFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipValueColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipShowDate').disable({emitEvent: false}); + this.barChartWidgetSettingsForm.get('tooltipDateFormat').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundBlur').disable(); + } + } + + private _tooltipValuePreviewFn(): string { + const units: string = this.widgetConfig.config.units; + const decimals: number = this.widgetConfig.config.decimals; + return formatValue(22, decimals, units, false); + } + + private _tooltipDatePreviewFn(): string { + const dateFormat: DateFormatSettings = this.barChartWidgetSettingsForm.get('tooltipDateFormat').value; + const processor = DateFormatProcessor.fromSettings(this.$injector, dateFormat); + processor.update(Date.now()); + return processor.formatted; + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html index a0e76da09c..3975ee5f98 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html @@ -70,14 +70,14 @@
{{ 'legend.position' | translate }}
- - {{ doughnutLegendPositionTranslationMap.get(pos) | translate }} + + {{ legendPositionTranslationMap.get(pos) | translate }}
-
{{ 'widgets.doughnut.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -89,7 +89,7 @@
-
{{ 'widgets.doughnut.legend-value' | translate }}
+
{{ 'legend.value' | translate }}
@@ -109,13 +109,13 @@ - {{ 'widgets.doughnut.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.doughnut.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -138,14 +138,14 @@
-
{{ 'widgets.doughnut.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.doughnut.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts index 220fc7c320..e9ad95be1b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts @@ -15,7 +15,12 @@ /// import { Component } from '@angular/core'; -import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { + legendPositions, + legendPositionTranslationMap, + WidgetSettings, + WidgetSettingsComponent +} from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -26,8 +31,6 @@ import { doughnutLayoutImages, doughnutLayouts, doughnutLayoutTranslations, - doughnutLegendPositions, - doughnutLegendPositionTranslations, DoughnutTooltipValueType, doughnutTooltipValueTypes, doughnutTooltipValueTypeTranslations, @@ -55,9 +58,9 @@ export class DoughnutWidgetSettingsComponent extends WidgetSettingsComponent { doughnutLayoutImageMap: Map; - doughnutLegendPositions = doughnutLegendPositions; + legendPositions = legendPositions; - doughnutLegendPositionTranslationMap = doughnutLegendPositionTranslations; + legendPositionTranslationMap = legendPositionTranslationMap; doughnutTooltipValueTypes = doughnutTooltipValueTypes; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html index 155d09f53f..e3ce71491c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html @@ -62,7 +62,7 @@
-
{{ 'widgets.range-chart.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -82,13 +82,13 @@ - {{ 'widgets.range-chart.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.range-chart.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -101,7 +101,7 @@
- {{ 'widgets.range-chart.tooltip-date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -115,14 +115,14 @@
-
{{ 'widgets.range-chart.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.range-chart.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts index 562001e3c4..3e7d328adf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts @@ -27,7 +27,7 @@ import { import { PageComponent } from '@shared/components/page.component'; import { commonFonts, - ComponentStyle, + ComponentStyle, cssUnit, Font, fontStyles, fontStyleTranslations, @@ -73,6 +73,9 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit @coerceBoolean() disabledLineHeight = false; + @Input() + forceSizeUnit: cssUnit; + @Input() popover: TbPopoverComponent; @@ -106,7 +109,8 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit this.fontFormGroup = this.fb.group( { size: [{value: this.font?.size, disabled: this.autoScale}, [Validators.min(0)]], - sizeUnit: [{ value: (this.font?.sizeUnit || 'px'), disabled: this.autoScale}, []], + sizeUnit: [{ value: (!!this.forceSizeUnit ? + this.forceSizeUnit : (this.font?.sizeUnit || 'px')), disabled: this.autoScale || !!this.forceSizeUnit}, []], family: [this.font?.family, []], weight: [this.font?.weight, []], style: [this.font?.style, []], @@ -150,11 +154,14 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit } clearFont() { - this.fontFormGroup.reset({sizeUnit: 'px'}); + this.fontFormGroup.reset({sizeUnit: this.forceSizeUnit || 'px'}); this.fontFormGroup.markAsDirty(); } private updatePreviewStyle(font: Font) { + if (!!this.forceSizeUnit) { + font = {...font, ...{sizeUnit: this.forceSizeUnit}}; + } this.previewStyle = {...(this.initialPreviewStyle || {}), ...textStyle(font)}; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts index 0fc3b20da1..0530519c2d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts @@ -16,7 +16,7 @@ import { Component, forwardRef, Input, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { ComponentStyle, Font } from '@shared/models/widget-settings.models'; +import { ComponentStyle, cssUnit, Font } from '@shared/models/widget-settings.models'; import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { FontSettingsPanelComponent } from '@home/components/widget/lib/settings/common/font-settings-panel.component'; @@ -58,6 +58,9 @@ export class FontSettingsComponent implements OnInit, ControlValueAccessor { @coerceBoolean() disabledLineHeight = false; + @Input() + forceSizeUnit: cssUnit; + private modelValue: Font; private propagateChange = null; @@ -97,7 +100,8 @@ export class FontSettingsComponent implements OnInit, ControlValueAccessor { initialPreviewStyle: this.initialPreviewStyle, clearButton: this.clearButton, autoScale: this.autoScale, - disabledLineHeight: this.disabledLineHeight + disabledLineHeight: this.disabledLineHeight, + forceSizeUnit: this.forceSizeUnit }; if (isDefinedAndNotNull(this.previewText)) { const previewText = typeof this.previewText === 'string' ? this.previewText : this.previewText(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html index 808bbe11d9..19d3d98d5d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html @@ -70,14 +70,14 @@ - {{ 'widgets.signal-strength.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
- {{ 'widgets.signal-strength.value' | translate }} + {{ 'tooltip.value' | translate }}
- {{ 'widgets.signal-strength.date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -105,13 +105,13 @@
-
{{ 'widgets.signal-strength.background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
widgets.signal-strength.background-blur
+
tooltip.background-blur
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 5d1bce1745..ed53f82ffd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -308,6 +308,9 @@ import { import { RangeChartWidgetSettingsComponent } from '@home/components/widget/lib/settings/chart/range-chart-widget-settings.component'; +import { + BarChartWithLabelsWidgetSettingsComponent +} from '@home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component'; @NgModule({ declarations: [ @@ -420,7 +423,8 @@ import { ProgressBarWidgetSettingsComponent, LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, - RangeChartWidgetSettingsComponent + RangeChartWidgetSettingsComponent, + BarChartWithLabelsWidgetSettingsComponent ], imports: [ CommonModule, @@ -538,7 +542,8 @@ import { ProgressBarWidgetSettingsComponent, LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, - RangeChartWidgetSettingsComponent + RangeChartWidgetSettingsComponent, + BarChartWithLabelsWidgetSettingsComponent ] }) export class WidgetSettingsModule { @@ -622,5 +627,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type max) { - newIntervalMs = max; + } else if (newIntervalMs >= max && updateToPreferred) { + newIntervalMs = this.timeService.boundMaxInterval(max / 7); } if (!this.advanced) { newIntervalMs = this.timeService.boundToPredefinedInterval(min, max, newIntervalMs); @@ -159,7 +159,7 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { } } - updateView() { + updateView(updateToPreferred = false) { if (!this.rendered) { return; } @@ -178,7 +178,7 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { } this.modelValue = value; this.propagateChange(this.modelValue); - this.boundInterval(); + this.boundInterval(updateToPreferred); } calculateIntervalMs(): number { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 12de697bc8..de8d7706d5 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3159,7 +3159,9 @@ "weeks": "(week ago)", "months": "(month ago)", "years": "(year ago)" - } + }, + "label": "Label", + "value": "Value" }, "login": { "login": "Login", @@ -4276,6 +4278,12 @@ "displayTypePrefix": "Display Realtime/History prefix", "preview": "Preview" }, + "tooltip": { + "value": "Value", + "date": "Date", + "background-color": "Background color", + "background-blur": "Background blur" + }, "unit": { "millimeter": "Millimeter", "centimeter": "Centimeter", @@ -5152,6 +5160,12 @@ "blur": "Blur", "preview": "Preview" }, + "bar-chart": { + "bar-appearance": "Bar appearance", + "label-on-bar": "Label on bar", + "value-on-bar": "Value on bar", + "bar-chart-card-style": "Bar chart card style" + }, "battery-level": { "layout": "Layout", "layout-vertical-solid": "Vertical. Solid", @@ -5177,9 +5191,6 @@ "date": "Date", "active-bars-color": "Active signal bars color", "inactive-bars-color": "Inactive signal bars color", - "tooltip": "Tooltip", - "background-color": "Background color", - "background-blur": "Background blur", "signal-strength-card-style": "Signal strength card style" }, "chart": { @@ -5422,18 +5433,8 @@ "clockwise-layout": "Clockwise layout", "sort-series": "Sort series by label", "central-total-value": "Central total value", - "legend-position-top": "Top", - "legend-position-bottom": "Bottom", - "legend-position-left": "Left", - "legend-position-right": "Right", - "legend-label": "Label", - "legend-value": "Value", - "tooltip": "Tooltip", - "tooltip-value": "Value", "tooltip-value-type-absolute": "Absolute", "tooltip-value-type-percentage": "Percentage", - "tooltip-background-color": "Background color", - "tooltip-background-blur": "Background blur", "doughnut-card-style": "Doughnut card style" }, "entities-hierarchy": { @@ -5915,12 +5916,6 @@ "range-colors": "Range colors", "out-of-range-color": "Out of range color", "fill-area": "Fill area", - "legend-label": "Label", - "tooltip": "Tooltip", - "tooltip-value": "Value", - "tooltip-date": "Date", - "tooltip-background-color": "Background color", - "tooltip-background-blur": "Background blur", "range-chart-card-style": "Range chart card style" }, "rpc": { diff --git a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json index f0d07fa506..28c4d20f59 100644 --- a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json +++ b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json @@ -3087,7 +3087,9 @@ "weeks": "(一周前)", "months": "(一个月前)", "years": "(一年前)" - } + }, + "label": "标签", + "value": "值" }, "login": { "login": "登录", @@ -4197,6 +4199,12 @@ "displayTypePrefix": "显示实时/历史前缀", "preview": "预览" }, + "tooltip": { + "value": "值", + "date": "日期", + "background-color": "背景颜色", + "background-blur": "背景模糊" + }, "unit": { "millimeter": "mm", "centimeter": "cm", @@ -5082,9 +5090,6 @@ "date": "日期", "active-bars-color": "活动信号条颜色", "inactive-bars-color": "非活动信号条颜色", - "tooltip": "文字提示", - "background-color": "背景颜色", - "background-blur": "背景模糊", "signal-strength-card-style": "信号强度卡片样式" }, "chart": { @@ -5327,18 +5332,8 @@ "clockwise-layout": "顺时针布局", "sort-series": "按标签对系列排序", "central-total-value": "中央总计值", - "legend-position-top": "顶部", - "legend-position-bottom": "底部", - "legend-position-left": "左侧", - "legend-position-right": "右侧", - "legend-label": "标签", - "legend-value": "值", - "tooltip": "文字提示", - "tooltip-value": "值", "tooltip-value-type-absolute": "绝对值", "tooltip-value-type-percentage": "百分比", - "tooltip-background-color": "背景颜色", - "tooltip-background-blur": "背景模糊", "doughnut-card-style": "圆环样式" }, "entities-hierarchy": { @@ -5820,12 +5815,6 @@ "range-colors": "范围颜色", "out-of-range-color": "超出范围颜色", "fill-area": "填充区域", - "legend-label": "标签", - "tooltip": "文字提示", - "tooltip-value": "值", - "tooltip-date": "日期", - "tooltip-background-color": "背景颜色", - "tooltip-background-blur": "背景模糊", "range-chart-card-style": "范围图表卡片样式" }, "rpc": { From c5a72ed8dfc6d857521d270f43227eea14aae72c Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 9 Jan 2024 10:46:16 +0200 Subject: [PATCH 42/91] Update license header to 2024 year. --- .github/release.yml | 2 +- .github/workflows/check-configuration-files.yml | 2 +- application/pom.xml | 2 +- application/src/main/conf/logback.xml | 2 +- application/src/main/conf/thingsboard.conf | 2 +- .../main/data/upgrade/1.3.0/schema_update.cql | 2 +- .../main/data/upgrade/1.3.1/schema_update.sql | 2 +- .../main/data/upgrade/1.4.0/schema_update.cql | 2 +- .../main/data/upgrade/1.4.0/schema_update.sql | 2 +- .../main/data/upgrade/2.0.0/schema_update.cql | 2 +- .../main/data/upgrade/2.0.0/schema_update.sql | 2 +- .../main/data/upgrade/2.1.1/schema_update.cql | 2 +- .../main/data/upgrade/2.1.1/schema_update.sql | 2 +- .../main/data/upgrade/2.1.2/schema_update.cql | 2 +- .../main/data/upgrade/2.1.2/schema_update.sql | 2 +- .../main/data/upgrade/2.2.0/schema_update.sql | 2 +- .../main/data/upgrade/2.3.1/schema_update.sql | 2 +- .../main/data/upgrade/2.4.0/schema_update.sql | 2 +- .../main/data/upgrade/2.4.2/schema_update.sql | 2 +- .../2.4.3/schema_update_psql_drop_partitions.sql | 2 +- .../data/upgrade/2.4.3/schema_update_psql_ts.sql | 2 +- .../upgrade/2.4.3/schema_update_timescale_ts.sql | 2 +- .../data/upgrade/2.4.3/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.0.1/schema_ts_latest.sql | 2 +- .../data/upgrade/3.0.1/schema_update_to_uuid.sql | 2 +- .../main/data/upgrade/3.1.0/schema_update.sql | 2 +- .../data/upgrade/3.1.1/schema_update_after.sql | 2 +- .../data/upgrade/3.1.1/schema_update_before.sql | 2 +- .../main/data/upgrade/3.2.1/schema_update.sql | 2 +- .../data/upgrade/3.2.1/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.2.2/schema_update.sql | 2 +- .../data/upgrade/3.2.2/schema_update_event.sql | 2 +- .../data/upgrade/3.2.2/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.3.2/schema_update.sql | 2 +- .../3.3.2/schema_update_lwm2m_bootstrap.sql | 2 +- .../upgrade/3.3.3/schema_event_ttl_procedure.sql | 2 +- .../main/data/upgrade/3.3.3/schema_update.sql | 2 +- .../main/data/upgrade/3.3.4/schema_update.sql | 2 +- .../main/data/upgrade/3.4.0/schema_update.sql | 2 +- .../main/data/upgrade/3.4.1/schema_update.sql | 2 +- .../data/upgrade/3.4.1/schema_update_after.sql | 2 +- .../data/upgrade/3.4.1/schema_update_before.sql | 2 +- .../main/data/upgrade/3.4.4/schema_update.sql | 2 +- .../main/data/upgrade/3.5.0/schema_update.sql | 2 +- .../main/data/upgrade/3.5.1/schema_update.sql | 2 +- .../main/data/upgrade/3.6.0/schema_update.sql | 2 +- .../3.6.1/save_attributes_node_update.sql | 2 +- .../main/data/upgrade/3.6.1/schema_update.sql | 2 +- .../main/data/upgrade/3.6.2/schema_update.sql | 2 +- .../server/ThingsboardInstallApplication.java | 2 +- .../server/ThingsboardServerApplication.java | 2 +- .../server/actors/ActorSystemContext.java | 2 +- .../actors/TbEntityTypeActorIdPredicate.java | 2 +- .../thingsboard/server/actors/app/AppActor.java | 2 +- .../server/actors/app/AppInitMsg.java | 2 +- .../server/actors/device/DeviceActor.java | 2 +- .../server/actors/device/DeviceActorCreator.java | 2 +- .../device/DeviceActorMessageProcessor.java | 2 +- .../server/actors/device/SessionInfo.java | 2 +- .../actors/device/SessionInfoMetaData.java | 2 +- .../actors/device/SessionTimeoutCheckMsg.java | 2 +- .../device/ToDeviceRpcRequestMetadata.java | 2 +- .../device/ToServerRpcRequestMetadata.java | 2 +- .../actors/ruleChain/DefaultTbContext.java | 2 +- .../server/actors/ruleChain/RuleChainActor.java | 2 +- .../RuleChainActorMessageProcessor.java | 2 +- .../actors/ruleChain/RuleChainInputMsg.java | 2 +- .../actors/ruleChain/RuleChainManagerActor.java | 2 +- .../actors/ruleChain/RuleChainOutputMsg.java | 2 +- .../ruleChain/RuleChainToRuleChainMsg.java | 2 +- .../actors/ruleChain/RuleChainToRuleNodeMsg.java | 2 +- .../ruleChain/RuleEngineComponentActor.java | 2 +- .../server/actors/ruleChain/RuleNodeActor.java | 2 +- .../ruleChain/RuleNodeActorMessageProcessor.java | 2 +- .../server/actors/ruleChain/RuleNodeCtx.java | 2 +- .../actors/ruleChain/RuleNodeRelation.java | 2 +- .../RuleNodeToRuleChainTellNextMsg.java | 2 +- .../actors/ruleChain/RuleNodeToSelfMsg.java | 2 +- .../actors/ruleChain/TbToRuleChainActorMsg.java | 2 +- .../actors/ruleChain/TbToRuleNodeActorMsg.java | 2 +- .../server/actors/service/ActorService.java | 2 +- .../server/actors/service/ComponentActor.java | 2 +- .../server/actors/service/ContextAwareActor.java | 2 +- .../actors/service/ContextBasedCreator.java | 2 +- .../actors/service/DefaultActorService.java | 2 +- .../shared/AbstractContextAwareMsgProcessor.java | 2 +- .../actors/shared/ActorTerminationMsg.java | 2 +- .../actors/shared/ComponentMsgProcessor.java | 2 +- .../actors/shared/RuleChainErrorActor.java | 2 +- .../server/actors/stats/StatsActor.java | 2 +- .../server/actors/stats/StatsPersistMsg.java | 2 +- .../server/actors/stats/StatsPersistTick.java | 2 +- .../server/actors/tenant/DebugTbRateLimits.java | 2 +- .../server/actors/tenant/TenantActor.java | 2 +- .../thingsboard/server/config/CryptoConfig.java | 2 +- ...CustomOAuth2AuthorizationRequestResolver.java | 2 +- .../server/config/MvcCorsProperties.java | 2 +- .../server/config/RateLimitProcessingFilter.java | 2 +- .../server/config/SchedulingConfiguration.java | 2 +- .../server/config/SwaggerConfiguration.java | 2 +- .../TbRuleEngineSecurityConfiguration.java | 2 +- .../config/ThingsboardMessageConfiguration.java | 2 +- .../config/ThingsboardSecurityConfiguration.java | 2 +- .../org/thingsboard/server/config/WebConfig.java | 2 +- .../server/config/WebSocketConfiguration.java | 2 +- .../server/controller/AbstractRpcController.java | 2 +- .../server/controller/AdminController.java | 2 +- .../controller/AlarmCommentController.java | 2 +- .../server/controller/AlarmController.java | 2 +- .../server/controller/AssetController.java | 2 +- .../controller/AssetProfileController.java | 2 +- .../server/controller/AuditLogController.java | 2 +- .../server/controller/AuthController.java | 2 +- .../server/controller/AutoCommitController.java | 2 +- .../server/controller/BaseController.java | 2 +- .../ComponentDescriptorController.java | 2 +- .../server/controller/ControllerConstants.java | 2 +- .../server/controller/CustomerController.java | 2 +- .../server/controller/DashboardController.java | 2 +- .../controller/DeviceConnectivityController.java | 2 +- .../server/controller/DeviceController.java | 2 +- .../controller/DeviceProfileController.java | 2 +- .../server/controller/EdgeController.java | 2 +- .../server/controller/EdgeEventController.java | 2 +- .../EntitiesVersionControlController.java | 2 +- .../server/controller/EntityQueryController.java | 2 +- .../controller/EntityRelationController.java | 2 +- .../server/controller/EntityViewController.java | 2 +- .../server/controller/EventController.java | 2 +- .../controller/HttpValidationCallback.java | 2 +- .../server/controller/ImageController.java | 2 +- .../server/controller/Lwm2mController.java | 2 +- .../controller/MailConfigTemplateController.java | 2 +- .../controller/NotificationController.java | 2 +- .../controller/NotificationRuleController.java | 2 +- .../controller/NotificationTargetController.java | 2 +- .../NotificationTemplateController.java | 2 +- .../OAuth2ConfigTemplateController.java | 2 +- .../server/controller/OAuth2Controller.java | 2 +- .../server/controller/OtaPackageController.java | 2 +- .../server/controller/QueueController.java | 2 +- .../server/controller/RpcV1Controller.java | 2 +- .../server/controller/RpcV2Controller.java | 2 +- .../server/controller/RuleChainController.java | 2 +- .../server/controller/SystemInfoController.java | 2 +- .../server/controller/TbResourceController.java | 2 +- .../server/controller/TbUrlConstants.java | 2 +- .../server/controller/TelemetryController.java | 2 +- .../server/controller/TenantController.java | 2 +- .../controller/TenantProfileController.java | 2 +- .../TwoFactorAuthConfigController.java | 2 +- .../controller/TwoFactorAuthController.java | 2 +- .../server/controller/UiSettingsController.java | 2 +- .../server/controller/UsageInfoController.java | 2 +- .../server/controller/UserController.java | 2 +- .../server/controller/WidgetTypeController.java | 2 +- .../controller/WidgetsBundleController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 2 +- .../server/controller/plugin/TbWebSocketMsg.java | 2 +- .../controller/plugin/TbWebSocketMsgType.java | 2 +- .../controller/plugin/TbWebSocketPingMsg.java | 2 +- .../controller/plugin/TbWebSocketTextMsg.java | 2 +- .../server/exception/AccessDeniedException.java | 2 +- .../exception/EntityNotFoundException.java | 2 +- .../server/exception/InternalErrorException.java | 2 +- .../exception/InvalidParametersException.java | 2 +- .../ThingsboardCredentialsExpiredResponse.java | 2 +- .../ThingsboardCredentialsViolationResponse.java | 2 +- .../exception/ThingsboardErrorResponse.java | 2 +- .../ThingsboardErrorResponseHandler.java | 2 +- .../server/exception/ToErrorResponseEntity.java | 2 +- .../server/exception/UnauthorizedException.java | 2 +- .../server/exception/UncheckedApiException.java | 2 +- .../install/ThingsboardInstallConfiguration.java | 2 +- .../install/ThingsboardInstallException.java | 2 +- .../install/ThingsboardInstallService.java | 2 +- .../service/action/EntityActionService.java | 2 +- .../service/apiusage/BaseApiUsageState.java | 2 +- .../service/apiusage/CustomerApiUsageState.java | 2 +- .../apiusage/DefaultTbApiUsageStateService.java | 2 +- .../service/apiusage/TbApiUsageStateService.java | 2 +- .../service/apiusage/TenantApiUsageState.java | 2 +- .../service/asset/AssetBulkImportService.java | 2 +- .../AnnotationComponentDiscoveryService.java | 2 +- .../component/ComponentDiscoveryService.java | 2 +- .../service/component/RuleNodeClassInfo.java | 2 +- .../service/device/ClaimDevicesServiceImpl.java | 2 +- .../service/device/DeviceBulkImportService.java | 2 +- .../device/DeviceProvisionServiceImpl.java | 2 +- .../edge/DefaultEdgeNotificationService.java | 2 +- .../service/edge/EdgeBulkImportService.java | 2 +- .../service/edge/EdgeContextComponent.java | 2 +- .../service/edge/EdgeEventSourcingListener.java | 2 +- .../service/edge/EdgeNotificationService.java | 2 +- .../DefaultEdgeInstallInstructionsService.java | 2 +- .../DefaultEdgeUpgradeInstructionsService.java | 2 +- .../EdgeInstallInstructionsService.java | 2 +- .../EdgeUpgradeInstructionsService.java | 2 +- .../edge/rpc/EdgeEventStorageSettings.java | 2 +- .../server/service/edge/rpc/EdgeGrpcService.java | 2 +- .../server/service/edge/rpc/EdgeGrpcSession.java | 2 +- .../server/service/edge/rpc/EdgeRpcService.java | 2 +- .../service/edge/rpc/EdgeSessionState.java | 2 +- .../server/service/edge/rpc/EdgeSyncCursor.java | 2 +- .../constructor/BaseMsgConstructorFactory.java | 2 +- .../edge/rpc/constructor/MsgConstructor.java | 2 +- .../constructor/alarm/AlarmMsgConstructor.java | 2 +- .../alarm/AlarmMsgConstructorFactory.java | 2 +- .../constructor/alarm/AlarmMsgConstructorV1.java | 2 +- .../constructor/alarm/AlarmMsgConstructorV2.java | 2 +- .../constructor/asset/AssetMsgConstructor.java | 2 +- .../asset/AssetMsgConstructorFactory.java | 2 +- .../constructor/asset/AssetMsgConstructorV1.java | 2 +- .../constructor/asset/AssetMsgConstructorV2.java | 2 +- .../asset/BaseAssetMsgConstructor.java | 2 +- .../customer/BaseCustomerMsgConstructor.java | 2 +- .../customer/CustomerMsgConstructor.java | 2 +- .../customer/CustomerMsgConstructorFactory.java | 2 +- .../customer/CustomerMsgConstructorV1.java | 2 +- .../customer/CustomerMsgConstructorV2.java | 2 +- .../dashboard/BaseDashboardMsgConstructor.java | 2 +- .../dashboard/DashboardMsgConstructor.java | 2 +- .../DashboardMsgConstructorFactory.java | 2 +- .../dashboard/DashboardMsgConstructorV1.java | 2 +- .../dashboard/DashboardMsgConstructorV2.java | 2 +- .../device/BaseDeviceMsgConstructor.java | 2 +- .../constructor/device/DeviceMsgConstructor.java | 2 +- .../device/DeviceMsgConstructorFactory.java | 2 +- .../device/DeviceMsgConstructorV1.java | 2 +- .../device/DeviceMsgConstructorV2.java | 2 +- .../rpc/constructor/edge/EdgeMsgConstructor.java | 2 +- .../entityview/BaseEntityViewMsgConstructor.java | 2 +- .../entityview/EntityViewMsgConstructor.java | 2 +- .../EntityViewMsgConstructorFactory.java | 2 +- .../entityview/EntityViewMsgConstructorV1.java | 2 +- .../entityview/EntityViewMsgConstructorV2.java | 2 +- .../ota/BaseOtaPackageMsgConstructor.java | 2 +- .../ota/OtaPackageMsgConstructor.java | 2 +- .../ota/OtaPackageMsgConstructorFactory.java | 2 +- .../ota/OtaPackageMsgConstructorV1.java | 2 +- .../ota/OtaPackageMsgConstructorV2.java | 2 +- .../queue/BaseQueueMsgConstructor.java | 2 +- .../constructor/queue/QueueMsgConstructor.java | 2 +- .../queue/QueueMsgConstructorFactory.java | 2 +- .../constructor/queue/QueueMsgConstructorV1.java | 2 +- .../constructor/queue/QueueMsgConstructorV2.java | 2 +- .../relation/RelationMsgConstructor.java | 2 +- .../relation/RelationMsgConstructorFactory.java | 2 +- .../relation/RelationMsgConstructorV1.java | 2 +- .../relation/RelationMsgConstructorV2.java | 2 +- .../resource/BaseResourceMsgConstructor.java | 2 +- .../resource/ResourceMsgConstructor.java | 2 +- .../resource/ResourceMsgConstructorFactory.java | 2 +- .../resource/ResourceMsgConstructorV1.java | 2 +- .../resource/ResourceMsgConstructorV2.java | 2 +- .../rule/BaseRuleChainMetadataConstructor.java | 2 +- .../rule/BaseRuleChainMsgConstructor.java | 2 +- .../rule/RuleChainMetadataConstructor.java | 2 +- .../RuleChainMetadataConstructorFactory.java | 2 +- .../rule/RuleChainMetadataConstructorV330.java | 2 +- .../rule/RuleChainMetadataConstructorV340.java | 2 +- .../rule/RuleChainMetadataConstructorV362.java | 2 +- .../rule/RuleChainMsgConstructor.java | 2 +- .../rule/RuleChainMsgConstructorFactory.java | 2 +- .../rule/RuleChainMsgConstructorV1.java | 2 +- .../rule/RuleChainMsgConstructorV2.java | 2 +- .../settings/AdminSettingsMsgConstructor.java | 2 +- .../AdminSettingsMsgConstructorFactory.java | 2 +- .../settings/AdminSettingsMsgConstructorV1.java | 2 +- .../settings/AdminSettingsMsgConstructorV2.java | 2 +- .../telemetry/EntityDataMsgConstructor.java | 2 +- .../constructor/tenant/TenantMsgConstructor.java | 2 +- .../tenant/TenantMsgConstructorFactory.java | 2 +- .../tenant/TenantMsgConstructorV1.java | 2 +- .../tenant/TenantMsgConstructorV2.java | 2 +- .../constructor/user/BaseUserMsgConstructor.java | 2 +- .../rpc/constructor/user/UserMsgConstructor.java | 2 +- .../user/UserMsgConstructorFactory.java | 2 +- .../constructor/user/UserMsgConstructorV1.java | 2 +- .../constructor/user/UserMsgConstructorV2.java | 2 +- .../widget/BaseWidgetMsgConstructor.java | 2 +- .../constructor/widget/WidgetMsgConstructor.java | 2 +- .../widget/WidgetMsgConstructorFactory.java | 2 +- .../widget/WidgetMsgConstructorV1.java | 2 +- .../widget/WidgetMsgConstructorV2.java | 2 +- .../rpc/fetch/AdminSettingsEdgeEventFetcher.java | 2 +- .../rpc/fetch/AssetProfilesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/AssetsEdgeEventFetcher.java | 2 +- .../rpc/fetch/BasePageableEdgeEventFetcher.java | 2 +- .../rpc/fetch/BaseUsersEdgeEventFetcher.java | 2 +- .../fetch/BaseWidgetTypesEdgeEventFetcher.java | 2 +- .../BaseWidgetsBundlesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/CustomerEdgeEventFetcher.java | 2 +- .../rpc/fetch/CustomerUsersEdgeEventFetcher.java | 2 +- .../rpc/fetch/DashboardsEdgeEventFetcher.java | 2 +- .../fetch/DefaultProfilesEdgeEventFetcher.java | 2 +- .../fetch/DeviceProfilesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/DevicesEdgeEventFetcher.java | 2 +- .../service/edge/rpc/fetch/EdgeEventFetcher.java | 2 +- .../rpc/fetch/EntityViewsEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/GeneralEdgeEventFetcher.java | 2 +- .../rpc/fetch/OtaPackagesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/QueuesEdgeEventFetcher.java | 2 +- .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 2 +- .../fetch/SystemWidgetTypesEdgeEventFetcher.java | 2 +- .../SystemWidgetsBundlesEdgeEventFetcher.java | 2 +- .../fetch/TenantAdminUsersEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/TenantEdgeEventFetcher.java | 2 +- .../fetch/TenantResourcesEdgeEventFetcher.java | 2 +- .../fetch/TenantWidgetTypesEdgeEventFetcher.java | 2 +- .../TenantWidgetsBundlesEdgeEventFetcher.java | 2 +- .../edge/rpc/processor/BaseEdgeProcessor.java | 2 +- .../rpc/processor/BaseEdgeProcessorFactory.java | 2 +- .../edge/rpc/processor/EdgeProcessor.java | 2 +- .../rpc/processor/alarm/AlarmEdgeProcessor.java | 2 +- .../alarm/AlarmEdgeProcessorFactory.java | 2 +- .../processor/alarm/AlarmEdgeProcessorV1.java | 2 +- .../processor/alarm/AlarmEdgeProcessorV2.java | 2 +- .../edge/rpc/processor/alarm/AlarmProcessor.java | 2 +- .../rpc/processor/alarm/BaseAlarmProcessor.java | 2 +- .../rpc/processor/asset/AssetEdgeProcessor.java | 2 +- .../asset/AssetEdgeProcessorFactory.java | 2 +- .../processor/asset/AssetEdgeProcessorV1.java | 2 +- .../processor/asset/AssetEdgeProcessorV2.java | 2 +- .../edge/rpc/processor/asset/AssetProcessor.java | 2 +- .../rpc/processor/asset/BaseAssetProcessor.java | 2 +- .../asset/profile/AssetProfileEdgeProcessor.java | 2 +- .../AssetProfileEdgeProcessorFactory.java | 2 +- .../profile/AssetProfileEdgeProcessorV1.java | 2 +- .../profile/AssetProfileEdgeProcessorV2.java | 2 +- .../asset/profile/AssetProfileProcessor.java | 2 +- .../asset/profile/BaseAssetProfileProcessor.java | 2 +- .../customer/CustomerEdgeProcessor.java | 2 +- .../dashboard/BaseDashboardProcessor.java | 2 +- .../dashboard/DashboardEdgeProcessor.java | 2 +- .../dashboard/DashboardEdgeProcessorFactory.java | 2 +- .../dashboard/DashboardEdgeProcessorV1.java | 2 +- .../dashboard/DashboardEdgeProcessorV2.java | 2 +- .../processor/dashboard/DashboardProcessor.java | 2 +- .../processor/device/BaseDeviceProcessor.java | 2 +- .../processor/device/DeviceEdgeProcessor.java | 2 +- .../device/DeviceEdgeProcessorFactory.java | 2 +- .../processor/device/DeviceEdgeProcessorV1.java | 2 +- .../processor/device/DeviceEdgeProcessorV2.java | 2 +- .../rpc/processor/device/DeviceProcessor.java | 2 +- .../profile/BaseDeviceProfileProcessor.java | 2 +- .../profile/DeviceProfileEdgeProcessor.java | 2 +- .../DeviceProfileEdgeProcessorFactory.java | 2 +- .../profile/DeviceProfileEdgeProcessorV1.java | 2 +- .../profile/DeviceProfileEdgeProcessorV2.java | 2 +- .../device/profile/DeviceProfileProcessor.java | 2 +- .../edge/rpc/processor/edge/EdgeProcessor.java | 2 +- .../entityview/BaseEntityViewProcessor.java | 2 +- .../entityview/EntityViewEdgeProcessor.java | 2 +- .../entityview/EntityViewProcessor.java | 2 +- .../entityview/EntityViewProcessorFactory.java | 2 +- .../entityview/EntityViewProcessorV1.java | 2 +- .../entityview/EntityViewProcessorV2.java | 2 +- .../processor/ota/OtaPackageEdgeProcessor.java | 2 +- .../rpc/processor/queue/QueueEdgeProcessor.java | 2 +- .../relation/BaseRelationProcessor.java | 2 +- .../relation/RelationEdgeProcessor.java | 2 +- .../relation/RelationEdgeProcessorFactory.java | 2 +- .../relation/RelationEdgeProcessorV1.java | 2 +- .../relation/RelationEdgeProcessorV2.java | 2 +- .../processor/relation/RelationProcessor.java | 2 +- .../resource/BaseResourceProcessor.java | 2 +- .../resource/ResourceEdgeProcessor.java | 2 +- .../resource/ResourceEdgeProcessorFactory.java | 2 +- .../resource/ResourceEdgeProcessorV1.java | 2 +- .../resource/ResourceEdgeProcessorV2.java | 2 +- .../processor/resource/ResourceProcessor.java | 2 +- .../processor/rule/RuleChainEdgeProcessor.java | 2 +- .../settings/AdminSettingsEdgeProcessor.java | 2 +- .../telemetry/BaseTelemetryProcessor.java | 2 +- .../telemetry/TelemetryEdgeProcessor.java | 2 +- .../processor/tenant/TenantEdgeProcessor.java | 2 +- .../tenant/TenantProfileEdgeProcessor.java | 2 +- .../rpc/processor/user/UserEdgeProcessor.java | 2 +- .../widget/WidgetBundleEdgeProcessor.java | 2 +- .../widget/WidgetTypeEdgeProcessor.java | 2 +- .../rpc/sync/DefaultEdgeRequestsService.java | 2 +- .../edge/rpc/sync/EdgeRequestsService.java | 2 +- .../service/edge/rpc/utils/EdgeVersionUtils.java | 2 +- .../service/entitiy/AbstractTbEntityService.java | 2 +- .../DefaultTbNotificationEntityService.java | 2 +- .../service/entitiy/SimpleTbEntityService.java | 2 +- .../entitiy/TbNotificationEntityService.java | 2 +- .../alarm/DefaultTbAlarmCommentService.java | 2 +- .../entitiy/alarm/DefaultTbAlarmService.java | 2 +- .../entitiy/alarm/TbAlarmCommentService.java | 2 +- .../service/entitiy/alarm/TbAlarmService.java | 2 +- .../entitiy/asset/DefaultTbAssetService.java | 2 +- .../service/entitiy/asset/TbAssetService.java | 2 +- .../profile/DefaultTbAssetProfileService.java | 2 +- .../asset/profile/TbAssetProfileService.java | 2 +- .../customer/DefaultTbCustomerService.java | 2 +- .../entitiy/customer/TbCustomerService.java | 2 +- .../dashboard/DefaultTbDashboardService.java | 2 +- .../entitiy/dashboard/TbDashboardService.java | 2 +- .../entitiy/device/DefaultTbDeviceService.java | 2 +- .../service/entitiy/device/TbDeviceService.java | 2 +- .../profile/DefaultTbDeviceProfileService.java | 2 +- .../device/profile/TbDeviceProfileService.java | 2 +- .../entitiy/edge/DefaultTbEdgeService.java | 2 +- .../service/entitiy/edge/TbEdgeService.java | 2 +- .../relation/DefaultTbEntityRelationService.java | 2 +- .../entity/relation/TbEntityRelationService.java | 2 +- .../entityview/DefaultTbEntityViewService.java | 2 +- .../entitiy/entityview/TbEntityViewService.java | 2 +- .../entitiy/ota/DefaultTbOtaPackageService.java | 2 +- .../service/entitiy/ota/TbOtaPackageService.java | 2 +- .../entitiy/queue/DefaultTbQueueService.java | 2 +- .../service/entitiy/queue/TbQueueService.java | 2 +- .../entitiy/tenant/DefaultTbTenantService.java | 2 +- .../service/entitiy/tenant/TbTenantService.java | 2 +- .../profile/DefaultTbTenantProfileService.java | 2 +- .../tenant/profile/TbTenantProfileService.java | 2 +- .../user/DefaultTbUserSettingsService.java | 2 +- .../service/entitiy/user/DefaultUserService.java | 2 +- .../service/entitiy/user/TbUserService.java | 2 +- .../entitiy/user/TbUserSettingsService.java | 2 +- .../bundle/DefaultWidgetsBundleService.java | 2 +- .../widgets/bundle/TbWidgetsBundleService.java | 2 +- .../widgets/type/DefaultWidgetTypeService.java | 2 +- .../widgets/type/TbWidgetTypeService.java | 2 +- .../executors/DbCallbackExecutorService.java | 2 +- .../executors/ExternalCallExecutorService.java | 2 +- .../executors/GrpcCallbackExecutorService.java | 2 +- .../executors/NotificationExecutorService.java | 2 +- .../PubSubRuleNodeExecutorProvider.java | 2 +- .../executors/SharedEventLoopGroupService.java | 2 +- .../executors/VersionControlExecutor.java | 2 +- .../DefaultGatewayNotificationsService.java | 2 +- .../GatewayNotificationsService.java | 2 +- .../InMemoryHouseKeeperServiceService.java | 2 +- .../AbstractCassandraDatabaseUpgradeService.java | 2 +- .../AbstractSqlTsDatabaseUpgradeService.java | 2 +- .../CassandraAbstractDatabaseSchemaService.java | 2 +- .../install/CassandraKeyspaceService.java | 2 +- .../CassandraTsDatabaseSchemaService.java | 2 +- .../CassandraTsDatabaseUpgradeService.java | 2 +- .../CassandraTsLatestDatabaseSchemaService.java | 2 +- .../install/DatabaseEntitiesUpgradeService.java | 2 +- .../server/service/install/DatabaseHelper.java | 2 +- .../service/install/DatabaseSchemaService.java | 2 +- .../install/DatabaseTsUpgradeService.java | 2 +- .../install/DbUpgradeExecutorService.java | 2 +- .../install/DefaultSystemDataLoaderService.java | 2 +- .../install/EntityDatabaseSchemaService.java | 2 +- .../server/service/install/InstallScripts.java | 2 +- .../service/install/NoSqlKeyspaceService.java | 2 +- .../SqlAbstractDatabaseSchemaService.java | 2 +- .../install/SqlDatabaseUpgradeService.java | 2 +- .../install/SqlEntityDatabaseSchemaService.java | 2 +- .../install/SqlTsDatabaseSchemaService.java | 2 +- .../install/SqlTsDatabaseUpgradeService.java | 2 +- .../service/install/SystemDataLoaderService.java | 2 +- .../install/TbRuleEngineQueueConfigService.java | 2 +- .../TimescaleTsDatabaseSchemaService.java | 2 +- .../TimescaleTsDatabaseUpgradeService.java | 2 +- .../service/install/TsDatabaseSchemaService.java | 2 +- .../install/TsLatestDatabaseSchemaService.java | 2 +- .../service/install/cql/CQLStatementsParser.java | 2 +- .../service/install/cql/CassandraDbHelper.java | 2 +- .../CassandraEntitiesToSqlMigrateService.java | 2 +- .../install/migrate/CassandraToSqlColumn.java | 2 +- .../migrate/CassandraToSqlColumnData.java | 2 +- .../migrate/CassandraToSqlColumnType.java | 2 +- .../migrate/CassandraToSqlEventTsColumn.java | 2 +- .../install/migrate/CassandraToSqlTable.java | 2 +- .../CassandraTsLatestToSqlMigrateService.java | 2 +- .../install/migrate/EntitiesMigrateService.java | 2 +- .../install/migrate/TsLatestMigrateService.java | 2 +- .../server/service/install/sql/SqlDbHelper.java | 2 +- .../install/update/CacheCleanupService.java | 2 +- .../install/update/DataUpdateService.java | 2 +- .../update/DefaultCacheCleanupService.java | 2 +- .../install/update/DefaultDataUpdateService.java | 2 +- .../service/install/update/ImagesUpdater.java | 2 +- .../service/install/update/PaginatedUpdater.java | 2 +- .../install/update/RateLimitsUpdater.java | 2 +- .../server/service/lwm2m/LwM2MService.java | 2 +- .../server/service/lwm2m/LwM2MServiceImpl.java | 2 +- .../server/service/mail/DefaultMailService.java | 2 +- .../mail/DefaultTbMailConfigTemplateService.java | 2 +- .../server/service/mail/MailExecutorService.java | 2 +- .../mail/PasswordResetExecutorService.java | 2 +- .../mail/RefreshTokenExpCheckService.java | 2 +- .../mail/TbMailConfigTemplateService.java | 2 +- .../service/mail/TbMailContextComponent.java | 2 +- .../server/service/mail/TbMailSender.java | 2 +- .../notification/DefaultNotificationCenter.java | 2 +- .../DefaultNotificationSchedulerService.java | 2 +- .../NotificationProcessingContext.java | 2 +- .../NotificationSchedulerService.java | 2 +- .../channels/EmailNotificationChannel.java | 2 +- .../MicrosoftTeamsNotificationChannel.java | 2 +- .../channels/NotificationChannel.java | 2 +- .../channels/SlackNotificationChannel.java | 2 +- .../channels/SmsNotificationChannel.java | 2 +- .../rule/DefaultNotificationRuleProcessor.java | 2 +- .../cache/DefaultNotificationRulesCache.java | 2 +- .../rule/cache/NotificationRulesCache.java | 2 +- .../trigger/AlarmAssignmentTriggerProcessor.java | 2 +- .../trigger/AlarmCommentTriggerProcessor.java | 2 +- .../rule/trigger/AlarmTriggerProcessor.java | 2 +- .../trigger/ApiUsageLimitTriggerProcessor.java | 2 +- .../trigger/DeviceActivityTriggerProcessor.java | 2 +- .../trigger/EntitiesLimitTriggerProcessor.java | 2 +- .../trigger/EntityActionTriggerProcessor.java | 2 +- .../NewPlatformVersionTriggerProcessor.java | 2 +- .../NotificationRuleTriggerProcessor.java | 2 +- .../rule/trigger/RateLimitsTriggerProcessor.java | 2 +- ...eComponentLifecycleEventTriggerProcessor.java | 2 +- .../ota/DefaultOtaPackageStateService.java | 2 +- .../service/ota/OtaPackageStateService.java | 2 +- .../partition/AbstractPartitionBasedService.java | 2 +- .../service/partition/TbCoreStartupService.java | 2 +- .../profile/DefaultTbAssetProfileCache.java | 2 +- .../profile/DefaultTbDeviceProfileCache.java | 2 +- .../service/profile/TbAssetProfileCache.java | 2 +- .../service/profile/TbDeviceProfileCache.java | 2 +- .../service/query/DefaultEntityQueryService.java | 2 +- .../server/service/query/EntityQueryService.java | 2 +- .../queue/DefaultQueueRoutingInfoService.java | 2 +- .../service/queue/DefaultTbClusterService.java | 2 +- .../queue/DefaultTbCoreConsumerService.java | 2 +- .../DefaultTbRuleEngineConsumerService.java | 2 +- .../queue/DefaultTenantRoutingInfoService.java | 2 +- .../service/queue/TbCoreConsumerService.java | 2 +- .../service/queue/TbCoreConsumerStats.java | 2 +- .../server/service/queue/TbMsgPackCallback.java | 2 +- .../queue/TbMsgPackProcessingContext.java | 2 +- .../server/service/queue/TbMsgProfilerInfo.java | 2 +- .../server/service/queue/TbPackCallback.java | 2 +- .../service/queue/TbPackProcessingContext.java | 2 +- .../queue/TbRuleEngineConsumerService.java | 2 +- .../service/queue/TbRuleEngineConsumerStats.java | 2 +- .../service/queue/TbRuleNodeProfilerInfo.java | 2 +- .../service/queue/TbTenantRuleEngineStats.java | 2 +- .../queue/TbTopicWithConsumerPerPartition.java | 2 +- .../processing/AbstractConsumerService.java | 2 +- .../AbstractTbRuleEngineSubmitStrategy.java | 2 +- .../BatchTbRuleEngineSubmitStrategy.java | 2 +- .../BurstTbRuleEngineSubmitStrategy.java | 2 +- .../service/queue/processing/IdMsgPair.java | 2 +- ...tialByEntityIdTbRuleEngineSubmitStrategy.java | 2 +- ...ByOriginatorIdTbRuleEngineSubmitStrategy.java | 2 +- ...tialByTenantIdTbRuleEngineSubmitStrategy.java | 2 +- .../SequentialTbRuleEngineSubmitStrategy.java | 2 +- .../TbRuleEngineProcessingDecision.java | 2 +- .../processing/TbRuleEngineProcessingResult.java | 2 +- .../TbRuleEngineProcessingStrategy.java | 2 +- .../TbRuleEngineProcessingStrategyFactory.java | 2 +- .../processing/TbRuleEngineSubmitStrategy.java | 2 +- .../TbRuleEngineSubmitStrategyFactory.java | 2 +- .../service/queue/ruleengine/QueueEvent.java | 2 +- .../ruleengine/TbQueueConsumerManagerTask.java | 2 +- .../queue/ruleengine/TbQueueConsumerTask.java | 2 +- .../ruleengine/TbRuleEngineConsumerContext.java | 2 +- .../TbRuleEngineQueueConsumerManager.java | 2 +- .../service/resource/DefaultTbImageService.java | 2 +- .../resource/DefaultTbResourceService.java | 2 +- .../server/service/resource/TbImageService.java | 2 +- .../service/resource/TbResourceService.java | 2 +- .../rpc/DefaultTbCoreDeviceRpcService.java | 2 +- .../rpc/DefaultTbRuleEngineRpcService.java | 2 +- .../server/service/rpc/LocalRequestMetaData.java | 2 +- .../server/service/rpc/RpcSubmitStrategy.java | 2 +- .../service/rpc/TbCoreDeviceRpcService.java | 2 +- .../server/service/rpc/TbRpcService.java | 2 +- .../rpc/TbRuleEngineDeviceRpcService.java | 2 +- .../service/rule/DefaultTbRuleChainService.java | 2 +- .../server/service/rule/TbRuleChainService.java | 2 +- .../service/script/RuleNodeJsScriptEngine.java | 2 +- .../service/script/RuleNodeScriptEngine.java | 2 +- .../service/script/RuleNodeTbelScriptEngine.java | 2 +- .../server/service/security/AccessValidator.java | 2 +- .../service/security/ValidationCallback.java | 2 +- .../service/security/ValidationResult.java | 2 +- .../service/security/ValidationResultCode.java | 2 +- .../auth/AbstractJwtAuthenticationToken.java | 2 +- .../auth/DefaultTokenOutdatingService.java | 2 +- .../security/auth/JwtAuthenticationToken.java | 2 +- .../security/auth/MfaAuthenticationToken.java | 2 +- .../auth/RefreshAuthenticationToken.java | 2 +- .../security/auth/TokenOutdatingService.java | 2 +- .../auth/jwt/JwtAuthenticationProvider.java | 2 +- .../JwtTokenAuthenticationProcessingFilter.java | 2 +- .../jwt/RefreshTokenAuthenticationProvider.java | 2 +- .../auth/jwt/RefreshTokenProcessingFilter.java | 2 +- .../security/auth/jwt/RefreshTokenRequest.java | 2 +- .../auth/jwt/SkipPathRequestMatcher.java | 2 +- .../jwt/extractor/JwtHeaderTokenExtractor.java | 2 +- .../jwt/extractor/JwtQueryTokenExtractor.java | 2 +- .../auth/jwt/extractor/TokenExtractor.java | 2 +- .../jwt/settings/DefaultJwtSettingsService.java | 2 +- .../settings/DefaultJwtSettingsValidator.java | 2 +- .../settings/InstallJwtSettingsValidator.java | 2 +- .../auth/jwt/settings/JwtSettingsService.java | 2 +- .../auth/jwt/settings/JwtSettingsValidator.java | 2 +- .../auth/mfa/DefaultTwoFactorAuthService.java | 2 +- .../security/auth/mfa/TwoFactorAuthService.java | 2 +- .../mfa/config/DefaultTwoFaConfigManager.java | 2 +- .../auth/mfa/config/TwoFaConfigManager.java | 2 +- .../auth/mfa/provider/TwoFaProvider.java | 2 +- .../provider/impl/BackupCodeTwoFaProvider.java | 2 +- .../mfa/provider/impl/EmailTwoFaProvider.java | 2 +- .../mfa/provider/impl/OtpBasedTwoFaProvider.java | 2 +- .../auth/mfa/provider/impl/SmsTwoFaProvider.java | 2 +- .../mfa/provider/impl/TotpTwoFaProvider.java | 2 +- .../auth/oauth2/AbstractOAuth2ClientMapper.java | 2 +- .../auth/oauth2/AppleOAuth2ClientMapper.java | 2 +- .../security/auth/oauth2/BasicMapperUtils.java | 2 +- .../auth/oauth2/BasicOAuth2ClientMapper.java | 2 +- .../security/auth/oauth2/CookieUtils.java | 2 +- .../auth/oauth2/CustomOAuth2ClientMapper.java | 2 +- .../auth/oauth2/GithubOAuth2ClientMapper.java | 2 +- ...okieOAuth2AuthorizationRequestRepository.java | 2 +- .../security/auth/oauth2/OAuth2ClientMapper.java | 2 +- .../auth/oauth2/OAuth2ClientMapperProvider.java | 2 +- .../Oauth2AuthenticationFailureHandler.java | 2 +- .../Oauth2AuthenticationSuccessHandler.java | 2 +- .../auth/oauth2/TbOAuth2ParameterNames.java | 2 +- .../service/security/auth/rest/LoginRequest.java | 2 +- .../security/auth/rest/LoginResponse.java | 2 +- .../security/auth/rest/PublicLoginRequest.java | 2 +- .../auth/rest/RestAuthenticationDetails.java | 2 +- .../rest/RestAuthenticationDetailsSource.java | 2 +- .../auth/rest/RestAuthenticationProvider.java | 2 +- .../RestAwareAuthenticationFailureHandler.java | 2 +- .../RestAwareAuthenticationSuccessHandler.java | 2 +- .../auth/rest/RestLoginProcessingFilter.java | 2 +- .../rest/RestPublicLoginProcessingFilter.java | 2 +- .../device/DefaultDeviceAuthService.java | 2 +- .../AuthMethodNotSupportedException.java | 2 +- .../exception/JwtExpiredTokenException.java | 2 +- .../exception/UserPasswordExpiredException.java | 2 +- .../exception/UserPasswordNotValidException.java | 2 +- .../security/model/ActivateUserRequest.java | 2 +- .../security/model/ChangePasswordRequest.java | 2 +- .../model/ResetPasswordEmailRequest.java | 2 +- .../security/model/ResetPasswordRequest.java | 2 +- .../service/security/model/SecurityUser.java | 2 +- .../service/security/model/UserPrincipal.java | 2 +- .../security/model/token/AccessJwtToken.java | 2 +- .../security/model/token/JwtTokenFactory.java | 2 +- .../model/token/OAuth2AppTokenFactory.java | 2 +- .../security/model/token/RawAccessJwtToken.java | 2 +- .../security/permission/AbstractPermissions.java | 2 +- .../permission/AccessControlService.java | 2 +- .../permission/CustomerUserPermissions.java | 2 +- .../permission/DefaultAccessControlService.java | 2 +- .../service/security/permission/Operation.java | 2 +- .../security/permission/PermissionChecker.java | 2 +- .../service/security/permission/Permissions.java | 2 +- .../service/security/permission/Resource.java | 2 +- .../security/permission/SysAdminPermissions.java | 2 +- .../permission/TenantAdminPermissions.java | 2 +- .../system/DefaultSystemSecurityService.java | 2 +- .../security/system/SystemSecurityService.java | 2 +- .../DefaultDeviceSessionCacheService.java | 2 +- .../session/DeviceSessionCacheService.java | 2 +- .../service/session/SessionCaffeineCache.java | 2 +- .../service/session/SessionRedisCache.java | 2 +- .../service/slack/DefaultSlackService.java | 2 +- .../server/service/sms/AbstractSmsSender.java | 2 +- .../service/sms/DefaultSmsSenderFactory.java | 2 +- .../server/service/sms/DefaultSmsService.java | 2 +- .../server/service/sms/SmsExecutorService.java | 2 +- .../server/service/sms/aws/AwsSmsSender.java | 2 +- .../server/service/sms/smpp/SmppSmsSender.java | 2 +- .../service/sms/twilio/TwilioSmsSender.java | 2 +- .../service/state/DefaultDeviceStateService.java | 2 +- .../server/service/state/DeviceState.java | 2 +- .../server/service/state/DeviceStateData.java | 2 +- .../server/service/state/DeviceStateService.java | 2 +- .../service/stats/DefaultJsInvokeStats.java | 2 +- .../DefaultRuleEngineStatisticsService.java | 2 +- .../stats/RuleEngineStatisticsService.java | 2 +- .../DefaultSubscriptionManagerService.java | 2 +- .../DefaultTbEntityDataSubscriptionService.java | 2 +- .../DefaultTbLocalSubscriptionService.java | 2 +- .../service/subscription/ReadTsKvQueryInfo.java | 2 +- .../subscription/SubscriptionErrorCode.java | 2 +- .../subscription/SubscriptionManagerService.java | 2 +- .../SubscriptionSchedulerComponent.java | 2 +- .../SubscriptionServiceStatistics.java | 2 +- .../subscription/TbAbstractDataSubCtx.java | 2 +- .../service/subscription/TbAbstractSubCtx.java | 2 +- .../service/subscription/TbAlarmCountSubCtx.java | 2 +- .../service/subscription/TbAlarmDataSubCtx.java | 2 +- .../subscription/TbAlarmsSubscription.java | 2 +- .../subscription/TbAttributeSubscription.java | 2 +- .../TbAttributeSubscriptionScope.java | 2 +- .../subscription/TbEntityCountSubCtx.java | 2 +- .../service/subscription/TbEntityDataSubCtx.java | 2 +- .../TbEntityDataSubscriptionService.java | 2 +- .../subscription/TbEntityLocalSubsInfo.java | 2 +- .../subscription/TbEntityRemoteSubsInfo.java | 2 +- .../service/subscription/TbEntitySubEvent.java | 2 +- .../subscription/TbEntityUpdatesInfo.java | 2 +- .../subscription/TbLocalSubscriptionService.java | 2 +- .../service/subscription/TbSubscription.java | 2 +- .../service/subscription/TbSubscriptionType.java | 2 +- .../subscription/TbSubscriptionUtils.java | 2 +- .../subscription/TbSubscriptionsInfo.java | 2 +- .../subscription/TbTimeSeriesSubscription.java | 2 +- .../ie/DefaultEntitiesExportImportService.java | 2 +- .../sync/ie/EntitiesExportImportService.java | 2 +- .../DefaultExportableEntitiesService.java | 2 +- .../sync/ie/exporting/EntityExportService.java | 2 +- .../ie/exporting/ExportableEntitiesService.java | 2 +- .../ie/exporting/impl/AssetExportService.java | 2 +- .../impl/AssetProfileExportService.java | 2 +- .../exporting/impl/BaseEntityExportService.java | 2 +- .../exporting/impl/DashboardExportService.java | 2 +- .../impl/DefaultEntityExportService.java | 2 +- .../ie/exporting/impl/DeviceExportService.java | 2 +- .../impl/DeviceProfileExportService.java | 2 +- .../exporting/impl/EntityViewExportService.java | 2 +- .../impl/NotificationRuleExportService.java | 2 +- .../impl/NotificationTargetExportService.java | 2 +- .../impl/NotificationTemplateExportService.java | 2 +- .../ie/exporting/impl/ResourceExportService.java | 2 +- .../exporting/impl/RuleChainExportService.java | 2 +- .../exporting/impl/WidgetTypeExportService.java | 2 +- .../impl/WidgetsBundleExportService.java | 2 +- .../sync/ie/importing/EntityImportService.java | 2 +- .../importing/csv/AbstractBulkImportService.java | 2 +- .../ie/importing/csv/ImportedEntityInfo.java | 2 +- .../ie/importing/impl/AssetImportService.java | 2 +- .../impl/AssetProfileImportService.java | 2 +- .../importing/impl/BaseEntityImportService.java | 2 +- .../ie/importing/impl/CustomerImportService.java | 2 +- .../importing/impl/DashboardImportService.java | 2 +- .../ie/importing/impl/DeviceImportService.java | 2 +- .../impl/DeviceProfileImportService.java | 2 +- .../importing/impl/EntityViewImportService.java | 2 +- .../importing/impl/ImportServiceException.java | 2 +- .../importing/impl/MissingEntityException.java | 2 +- .../impl/NotificationRuleImportService.java | 2 +- .../impl/NotificationTargetImportService.java | 2 +- .../impl/NotificationTemplateImportService.java | 2 +- .../ie/importing/impl/ResourceImportService.java | 2 +- .../importing/impl/RuleChainImportService.java | 2 +- .../importing/impl/WidgetTypeImportService.java | 2 +- .../impl/WidgetsBundleImportService.java | 2 +- .../vc/DefaultEntitiesVersionControlService.java | 2 +- .../vc/DefaultGitVersionControlQueueService.java | 2 +- .../sync/vc/EntitiesVersionControlService.java | 2 +- .../sync/vc/GitVersionControlQueueService.java | 2 +- .../service/sync/vc/LoadEntityException.java | 2 +- .../TbAbstractVersionControlSettingsService.java | 2 +- .../sync/vc/VersionControlTaskCacheEntry.java | 2 +- .../sync/vc/VersionControlTaskCaffeineCache.java | 2 +- .../sync/vc/VersionControlTaskRedisCache.java | 2 +- .../AutoCommitSettingsCaffeineCache.java | 2 +- .../autocommit/AutoCommitSettingsRedisCache.java | 2 +- .../DefaultTbAutoCommitSettingsService.java | 2 +- .../autocommit/TbAutoCommitSettingsService.java | 2 +- .../sync/vc/data/ClearRepositoryGitRequest.java | 2 +- .../service/sync/vc/data/CommitGitRequest.java | 2 +- .../sync/vc/data/ComplexEntitiesExportCtx.java | 2 +- .../sync/vc/data/ContentsDiffGitRequest.java | 2 +- .../sync/vc/data/EntitiesContentGitRequest.java | 2 +- .../service/sync/vc/data/EntitiesExportCtx.java | 2 +- .../service/sync/vc/data/EntitiesImportCtx.java | 2 +- .../sync/vc/data/EntityContentGitRequest.java | 2 +- .../sync/vc/data/EntityTypeExportCtx.java | 2 +- .../sync/vc/data/ListBranchesGitRequest.java | 2 +- .../sync/vc/data/ListEntitiesGitRequest.java | 2 +- .../sync/vc/data/ListVersionsGitRequest.java | 2 +- .../service/sync/vc/data/PendingGitRequest.java | 2 +- .../service/sync/vc/data/ReimportTask.java | 2 +- .../sync/vc/data/SimpleEntitiesExportCtx.java | 2 +- .../sync/vc/data/VersionsDiffGitRequest.java | 2 +- .../service/sync/vc/data/VoidGitRequest.java | 2 +- .../DefaultTbRepositorySettingsService.java | 2 +- .../RepositorySettingsCaffeineCache.java | 2 +- .../repository/RepositorySettingsRedisCache.java | 2 +- .../repository/TbRepositorySettingsService.java | 2 +- .../service/system/DefaultSystemInfoService.java | 2 +- .../server/service/system/SystemInfoService.java | 2 +- .../telemetry/AbstractSubscriptionService.java | 2 +- .../telemetry/AlarmSubscriptionService.java | 2 +- .../server/service/telemetry/AttributeData.java | 2 +- .../DefaultAlarmSubscriptionService.java | 2 +- .../DefaultTelemetrySubscriptionService.java | 2 +- .../telemetry/InternalTelemetryService.java | 2 +- .../telemetry/TelemetrySubscriptionService.java | 2 +- .../server/service/telemetry/TsData.java | 2 +- .../BasicCredentialsValidationResult.java | 2 +- .../DefaultTbCoreToTransportService.java | 2 +- .../transport/DefaultTransportApiService.java | 2 +- .../transport/TbCoreToTransportService.java | 2 +- .../transport/TbCoreTransportApiService.java | 2 +- .../service/transport/TransportApiService.java | 2 +- .../msg/TransportToDeviceActorMsgWrapper.java | 2 +- .../service/ttl/AbstractCleanUpService.java | 2 +- .../server/service/ttl/AlarmsCleanUpService.java | 2 +- .../service/ttl/AuditLogsCleanUpService.java | 2 +- .../service/ttl/EdgeEventsCleanUpService.java | 2 +- .../server/service/ttl/EventsCleanUpService.java | 2 +- .../service/ttl/NotificationsCleanUpService.java | 2 +- .../service/ttl/TimeseriesCleanUpService.java | 2 +- .../service/ttl/rpc/RpcCleanUpService.java | 2 +- .../service/update/DefaultUpdateService.java | 2 +- .../server/service/update/UpdateService.java | 2 +- .../thingsboard/server/service/ws/AuthCmd.java | 2 +- .../service/ws/DefaultWebSocketService.java | 2 +- .../server/service/ws/SessionEvent.java | 2 +- .../server/service/ws/WebSocketMsgEndpoint.java | 2 +- .../server/service/ws/WebSocketService.java | 2 +- .../server/service/ws/WebSocketSessionRef.java | 2 +- .../server/service/ws/WebSocketSessionType.java | 2 +- .../org/thingsboard/server/service/ws/WsCmd.java | 2 +- .../thingsboard/server/service/ws/WsCmdType.java | 2 +- .../server/service/ws/WsCommandsWrapper.java | 2 +- .../server/service/ws/WsSessionMetaData.java | 2 +- .../DefaultNotificationCommandsHandler.java | 2 +- .../NotificationCommandsHandler.java | 2 +- .../cmd/MarkAllNotificationsAsReadCmd.java | 2 +- .../cmd/MarkNotificationsAsReadCmd.java | 2 +- .../cmd/NotificationCmdsWrapper.java | 2 +- .../cmd/NotificationsCountSubCmd.java | 2 +- .../ws/notification/cmd/NotificationsSubCmd.java | 2 +- .../notification/cmd/NotificationsUnsubCmd.java | 2 +- .../cmd/UnreadNotificationsCountUpdate.java | 2 +- .../cmd/UnreadNotificationsUpdate.java | 2 +- .../sub/NotificationRequestUpdate.java | 2 +- .../ws/notification/sub/NotificationUpdate.java | 2 +- .../sub/NotificationsCountSubscription.java | 2 +- .../sub/NotificationsSubscription.java | 2 +- .../sub/NotificationsSubscriptionUpdate.java | 2 +- .../service/ws/telemetry/TelemetryFeature.java | 2 +- .../ws/telemetry/TelemetryWebSocketTextMsg.java | 2 +- .../ws/telemetry/cmd/TelemetryCmdsWrapper.java | 2 +- .../cmd/v1/AttributesSubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v1/GetHistoryCmd.java | 2 +- .../ws/telemetry/cmd/v1/SubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v1/TelemetryPluginCmd.java | 2 +- .../cmd/v1/TimeseriesSubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v2/AggHistoryCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/AggKey.java | 2 +- .../ws/telemetry/cmd/v2/AggTimeSeriesCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmCountCmd.java | 2 +- .../cmd/v2/AlarmCountUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmCountUpdate.java | 2 +- .../ws/telemetry/cmd/v2/AlarmDataCmd.java | 2 +- .../cmd/v2/AlarmDataUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmDataUpdate.java | 2 +- .../service/ws/telemetry/cmd/v2/CmdUpdate.java | 2 +- .../ws/telemetry/cmd/v2/CmdUpdateType.java | 2 +- .../service/ws/telemetry/cmd/v2/DataCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/DataUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityCountCmd.java | 2 +- .../cmd/v2/EntityCountUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/EntityCountUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityDataCmd.java | 2 +- .../cmd/v2/EntityDataUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/EntityDataUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityHistoryCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 2 +- .../ws/telemetry/cmd/v2/LatestValueCmd.java | 2 +- .../ws/telemetry/cmd/v2/TimeSeriesCmd.java | 2 +- .../ws/telemetry/cmd/v2/UnsubscribeCmd.java | 2 +- .../telemetry/sub/AlarmSubscriptionUpdate.java | 2 +- .../ws/telemetry/sub/SubscriptionState.java | 2 +- .../sub/TelemetrySubscriptionUpdate.java | 2 +- ...pringfoxHandlerProviderBeanPostProcessor.java | 2 +- .../org/thingsboard/server/utils/CsvUtils.java | 2 +- .../server/utils/LwM2mObjectModelUtils.java | 2 +- .../org/thingsboard/server/utils/MiscUtils.java | 2 +- .../server/utils/TbNodeUpgradeUtils.java | 2 +- application/src/main/resources/logback.xml | 2 +- .../templates/2fa.verification.code.ftl | 2 +- .../resources/templates/account.activated.ftl | 2 +- .../main/resources/templates/account.lockout.ftl | 2 +- .../src/main/resources/templates/activation.ftl | 2 +- .../resources/templates/password.was.reset.ftl | 2 +- .../main/resources/templates/reset.password.ftl | 2 +- .../main/resources/templates/state.disabled.ftl | 2 +- .../main/resources/templates/state.enabled.ftl | 2 +- .../main/resources/templates/state.warning.ftl | 2 +- .../src/main/resources/templates/test.ftl | 2 +- application/src/main/resources/thingsboard.yml | 2 +- .../device/DeviceActorMessageProcessorTest.java | 2 +- .../server/actors/stats/StatsActorTest.java | 2 +- .../server/actors/stats/StatsPersistMsgTest.java | 2 +- .../CaffeineCacheDefaultConfigurationTest.java | 2 +- .../controller/AbstractControllerTest.java | 2 +- .../controller/AbstractInMemoryStorageTest.java | 2 +- .../controller/AbstractNotifyEntityTest.java | 2 +- .../AbstractRuleEngineControllerTest.java | 2 +- .../server/controller/AbstractWebTest.java | 2 +- .../server/controller/AdminControllerTest.java | 2 +- .../controller/AlarmCommentControllerTest.java | 2 +- .../server/controller/AlarmControllerTest.java | 2 +- .../server/controller/AssetControllerTest.java | 2 +- .../controller/AssetProfileControllerTest.java | 2 +- .../controller/AuditLogControllerTest.java | 2 +- .../server/controller/AuthControllerTest.java | 2 +- .../controller/BaseQueueControllerTest.java | 2 +- .../ComponentDescriptorControllerTest.java | 2 +- .../controller/CustomerControllerTest.java | 2 +- .../controller/DashboardControllerTest.java | 2 +- .../DeviceConnectivityControllerTest.java | 2 +- .../server/controller/DeviceControllerTest.java | 2 +- .../controller/DeviceProfileControllerTest.java | 2 +- .../server/controller/EdgeControllerTest.java | 2 +- .../controller/EdgeEventControllerTest.java | 2 +- .../controller/EntityQueryControllerTest.java | 2 +- .../controller/EntityRelationControllerTest.java | 2 +- .../controller/EntityViewControllerTest.java | 2 +- .../server/controller/HomePageApiTest.java | 2 +- .../server/controller/ImageControllerTest.java | 2 +- .../controller/OtaPackageControllerTest.java | 2 +- .../server/controller/RpcControllerTest.java | 2 +- .../controller/RuleChainControllerTest.java | 2 +- .../controller/TbResourceControllerTest.java | 2 +- .../server/controller/TbTestWebSocketClient.java | 2 +- .../controller/TelemetryControllerTest.java | 2 +- .../server/controller/TenantControllerTest.java | 2 +- .../controller/TenantProfileControllerTest.java | 2 +- .../controller/TwoFactorAuthConfigTest.java | 2 +- .../server/controller/TwoFactorAuthTest.java | 2 +- .../server/controller/UserControllerTest.java | 2 +- .../server/controller/WebsocketApiTest.java | 2 +- .../controller/WidgetTypeControllerTest.java | 2 +- .../controller/WidgetsBundleControllerTest.java | 2 +- .../plugin/TbWebSocketHandlerTest.java | 2 +- .../server/edge/AbstractEdgeTest.java | 2 +- .../thingsboard/server/edge/AlarmEdgeTest.java | 2 +- .../thingsboard/server/edge/AssetEdgeTest.java | 2 +- .../server/edge/AssetProfileEdgeTest.java | 2 +- .../server/edge/CustomerEdgeTest.java | 2 +- .../server/edge/DashboardEdgeTest.java | 2 +- .../thingsboard/server/edge/DeviceEdgeTest.java | 2 +- .../server/edge/DeviceProfileEdgeTest.java | 2 +- .../org/thingsboard/server/edge/EdgeTest.java | 2 +- .../server/edge/EntityViewEdgeTest.java | 2 +- .../server/edge/OtaPackageEdgeTest.java | 2 +- .../thingsboard/server/edge/QueueEdgeTest.java | 2 +- .../server/edge/RelationEdgeTest.java | 2 +- .../server/edge/ResourceEdgeTest.java | 2 +- .../server/edge/RuleChainEdgeTest.java | 2 +- .../server/edge/TelemetryEdgeTest.java | 2 +- .../thingsboard/server/edge/TenantEdgeTest.java | 2 +- .../server/edge/TenantProfileEdgeTest.java | 2 +- .../thingsboard/server/edge/UserEdgeTest.java | 2 +- .../thingsboard/server/edge/WidgetEdgeTest.java | 2 +- .../server/edge/imitator/EdgeImitator.java | 2 +- .../discovery/HashPartitionServiceTest.java | 2 +- .../AbstractRuleEngineFlowIntegrationTest.java | 2 +- .../sql/RuleEngineFlowSqlIntegrationTest.java | 2 +- ...stractRuleEngineLifecycleIntegrationTest.java | 2 +- .../RuleEngineLifecycleSqlIntegrationTest.java | 2 +- .../DefaultTbApiUsageStateServiceTest.java | 2 +- .../provision/DeviceProvisionServiceTest.java | 2 +- .../constructor/RuleChainMsgConstructorTest.java | 2 +- .../rpc/processor/BaseEdgeProcessorTest.java | 2 +- .../asset/AbstractAssetProcessorTest.java | 2 +- .../processor/asset/AssetEdgeProcessorTest.java | 2 +- .../asset/AssetProfileEdgeProcessorTest.java | 2 +- .../device/AbstractDeviceProcessorTest.java | 2 +- .../device/DeviceEdgeProcessorTest.java | 2 +- .../device/DeviceProfileEdgeProcessorTest.java | 2 +- .../telemetry/TelemetryEdgeProcessorTest.java | 2 +- .../entitiy/alarm/DefaultTbAlarmServiceTest.java | 2 +- .../DefaultTbAlarmCommentServiceTest.java | 2 +- .../service/install/InstallScriptsTest.java | 2 +- .../SqlEntityDatabaseSchemaServiceTest.java | 2 +- .../update/DefaultDataUpdateServiceTest.java | 2 +- .../service/limits/RateLimitServiceTest.java | 2 +- .../server/service/mail/TbMailSenderTest.java | 2 +- .../AbstractNotificationApiTest.java | 2 +- .../notification/NotificationApiTest.java | 2 +- .../notification/NotificationApiWsClient.java | 2 +- .../notification/NotificationRuleApiTest.java | 2 +- .../notification/NotificationTargetApiTest.java | 2 +- .../NotificationTemplateApiTest.java | 2 +- .../TestNotificationSettingsService.java | 2 +- .../queue/DefaultTbClusterServiceTest.java | 2 +- .../service/queue/TbMsgPackCallbackTest.java | 2 +- .../queue/TbMsgPackProcessingContextTest.java | 2 +- .../TbRuleEngineQueueConsumerManagerTest.java | 2 +- .../resource/sql/BaseTbResourceServiceTest.java | 2 +- .../service/rpc/RpcSubmitStrategyTest.java | 2 +- .../service/script/MockJsInvokeService.java | 2 +- .../script/NashornJsInvokeServiceTest.java | 2 +- .../script/RemoteJsInvokeServiceTest.java | 2 +- .../service/script/TbelInvokeServiceTest.java | 2 +- .../security/auth/JwtTokenFactoryTest.java | 2 +- .../security/auth/TokenOutdatingTest.java | 2 +- .../security/auth/oauth2/CookieUtilsTest.java | 2 +- .../Oauth2AuthenticationSuccessHandlerTest.java | 2 +- .../service/sms/DefaultSmsServiceTest.java | 2 +- .../service/sms/smpp/SmppSmsSenderTest.java | 2 +- .../sql/SequentialTimeseriesPersistenceTest.java | 2 +- .../state/DefaultDeviceStateServiceTest.java | 2 +- .../service/stats/DevicesStatisticsTest.java | 2 +- .../sync/ie/BaseExportImportServiceTest.java | 2 +- .../sync/ie/ExportImportServiceSqlTest.java | 2 +- .../DefaultTransportApiServiceTest.java | 2 +- .../service/ttl/AlarmsCleanUpServiceTest.java | 2 +- .../service/ttl/EventsCleanUpServiceTest.java | 2 +- .../server/system/BaseHttpDeviceApiTest.java | 2 +- .../server/system/BaseRestApiLimitsTest.java | 2 +- .../system/RestTemplateConvertersTest.java | 2 +- .../server/system/sql/DeviceApiSqlTest.java | 2 +- .../server/system/sql/RestApiLimitsSqlTest.java | 2 +- .../AbstractTransportIntegrationTest.java | 2 +- .../transport/TransportNoSqlTestSuite.java | 2 +- .../coap/AbstractCoapIntegrationTest.java | 2 +- .../server/transport/coap/CoapTestCallback.java | 2 +- .../server/transport/coap/CoapTestClient.java | 2 +- .../transport/coap/CoapTestConfigProperties.java | 2 +- .../AbstractCoapAttributesIntegrationTest.java | 2 +- .../CoapAttributesRequestIntegrationTest.java | 2 +- ...CoapAttributesRequestJsonIntegrationTest.java | 2 +- ...oapAttributesRequestProtoIntegrationTest.java | 2 +- .../CoapAttributesUpdatesIntegrationTest.java | 2 +- ...CoapAttributesUpdatesJsonIntegrationTest.java | 2 +- ...oapAttributesUpdatesProtoIntegrationTest.java | 2 +- .../coap/claim/CoapClaimDeviceTest.java | 2 +- .../coap/claim/CoapClaimJsonDeviceTest.java | 2 +- .../coap/claim/CoapClaimProtoDeviceTest.java | 2 +- .../coap/client/CoapClientIntegrationTest.java | 2 +- .../provision/CoapProvisionJsonDeviceTest.java | 2 +- .../provision/CoapProvisionProtoDeviceTest.java | 2 +- ...AbstractCoapServerSideRpcIntegrationTest.java | 2 +- .../CoapServerSideRpcDefaultIntegrationTest.java | 2 +- .../CoapServerSideRpcJsonIntegrationTest.java | 2 +- .../CoapServerSideRpcProtoIntegrationTest.java | 2 +- .../CoapAttributesIntegrationTest.java | 2 +- .../CoapAttributesJsonIntegrationTest.java | 2 +- .../CoapAttributesProtoIntegrationTest.java | 2 +- .../AbstractCoapTimeseriesIntegrationTest.java | 2 +- ...bstractCoapTimeseriesJsonIntegrationTest.java | 2 +- ...stractCoapTimeseriesProtoIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlJsonIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlProtoIntegrationTest.java | 2 +- .../sql/CoapTimeseriesSqlIntegrationTest.java | 2 +- .../CoapTimeseriesSqlJsonIntegrationTest.java | 2 +- .../CoapTimeseriesSqlProtoIntegrationTest.java | 2 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 2 +- .../server/transport/lwm2m/Lwm2mTestHelper.java | 2 +- .../transport/lwm2m/client/FwLwM2MDevice.java | 2 +- .../lwm2m/client/LwM2MLocationParams.java | 2 +- .../transport/lwm2m/client/LwM2MTestClient.java | 2 +- .../client/LwM2mBinaryAppDataContainer.java | 2 +- .../transport/lwm2m/client/LwM2mLocation.java | 2 +- .../lwm2m/client/LwM2mTemperatureSensor.java | 2 +- .../transport/lwm2m/client/Lwm2mServer.java | 2 +- .../lwm2m/client/SimpleLwM2MDevice.java | 2 +- .../transport/lwm2m/client/SwLwM2MDevice.java | 2 +- .../ota/AbstractOtaLwM2MIntegrationTest.java | 2 +- .../lwm2m/ota/sql/OtaLwM2MIntegrationTest.java | 2 +- .../rpc/AbstractRpcLwM2MIntegrationTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationCreateTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationDeleteTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationDiscoverTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationExecuteTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationObserveTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationReadTest.java | 2 +- .../RpcLwm2mIntegrationWriteAttributesTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationWriteTest.java | 2 +- .../AbstractSecurityLwM2MIntegrationTest.java | 2 +- .../security/sql/NoSecLwM2MIntegrationTest.java | 2 +- .../security/sql/PskLwm2mIntegrationTest.java | 2 +- .../security/sql/RpkLwM2MIntegrationTest.java | 2 +- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 2 +- .../sql/X509_TrustLwM2MIntegrationTest.java | 2 +- .../server/LwM2mTransportServerHelperTest.java | 2 +- .../mqtt/AbstractMqttIntegrationTest.java | 2 +- .../transport/mqtt/MqttTestConfigProperties.java | 2 +- .../transport/mqtt/mqttv3/MqttTestCallback.java | 2 +- .../transport/mqtt/mqttv3/MqttTestClient.java | 2 +- .../mqttv3/MqttTestSubscribeOnTopicCallback.java | 2 +- .../AbstractMqttAttributesIntegrationTest.java | 2 +- ...uestBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttAttributesRequestIntegrationTest.java | 2 +- ...MqttAttributesRequestJsonIntegrationTest.java | 2 +- ...qttAttributesRequestProtoIntegrationTest.java | 2 +- ...atesBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttAttributesUpdatesIntegrationTest.java | 2 +- ...MqttAttributesUpdatesJsonIntegrationTest.java | 2 +- ...qttAttributesUpdatesProtoIntegrationTest.java | 2 +- ...MqttClaimBackwardCompatibilityDeviceTest.java | 2 +- .../mqtt/mqttv3/claim/MqttClaimDeviceTest.java | 2 +- .../mqttv3/claim/MqttClaimJsonDeviceTest.java | 2 +- .../mqttv3/claim/MqttClaimProtoDeviceTest.java | 2 +- .../client/AbstractMqttClientConnectionTest.java | 2 +- .../mqttv3/client/MqttClientConnectionTest.java | 2 +- .../credentials/BasicMqttCredentialsTest.java | 2 +- .../provision/MqttProvisionJsonDeviceTest.java | 2 +- .../provision/MqttProvisionProtoDeviceTest.java | 2 +- ...AbstractMqttServerSideRpcIntegrationTest.java | 2 +- ...eRpcBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttServerSideRpcDefaultIntegrationTest.java | 2 +- .../MqttServerSideRpcJsonIntegrationTest.java | 2 +- .../MqttServerSideRpcProtoIntegrationTest.java | 2 +- ...erverSideRpcSequenceOnAckIntegrationTest.java | 2 +- ...SideRpcSequenceOnResponseIntegrationTest.java | 2 +- .../MqttAttributesIntegrationTest.java | 2 +- .../MqttAttributesJsonIntegrationTest.java | 2 +- .../MqttAttributesProtoIntegrationTest.java | 2 +- .../AbstractMqttTimeseriesIntegrationTest.java | 2 +- ...bstractMqttTimeseriesJsonIntegrationTest.java | 2 +- ...stractMqttTimeseriesProtoIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlJsonIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlProtoIntegrationTest.java | 2 +- .../sql/MqttTimeseriesSqlIntegrationTest.java | 2 +- .../MqttTimeseriesSqlJsonIntegrationTest.java | 2 +- .../MqttTimeseriesSqlProtoIntegrationTest.java | 2 +- .../mqtt/mqttv5/AbstractMqttV5Test.java | 2 +- .../mqtt/mqttv5/MqttV5TestCallback.java | 2 +- .../transport/mqtt/mqttv5/MqttV5TestClient.java | 2 +- .../attributes/AbstractAttributesMqttV5Test.java | 2 +- .../updates/AttributesUpdatesTest.java | 2 +- .../attributes/upload/AttributesPublishTest.java | 2 +- .../mqttv5/claim/AbstractMqttV5ClaimTest.java | 2 +- .../mqtt/mqttv5/claim/MqttV5ClaimTest.java | 2 +- .../AbstractMqttV5ClientConnectionTest.java | 2 +- .../connection/MqttV5ClientConnectionTest.java | 2 +- .../publish/AbstractMqttV5ClientPublishTest.java | 2 +- .../client/publish/MqttV5ClientPublishTest.java | 2 +- .../AbstractMqttV5ClientSubscriptionTest.java | 2 +- .../subscribe/MqttV5ClientSubscriptionTest.java | 2 +- .../AbstractMqttV5ClientUnsubscribeTest.java | 2 +- .../unsubscribe/MqttV5ClientUnsubscribeTest.java | 2 +- .../provision/MqttV5ProvisionDeviceTest.java | 2 +- .../mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java | 2 +- .../transport/mqtt/mqttv5/rpc/MqttV5RpcTest.java | 2 +- .../timeseries/AbstractMqttV5TimeseriesTest.java | 2 +- .../mqttv5/timeseries/MqttV5TimeseriesTest.java | 2 +- .../AbstractMqttV5ClientSparkplugTest.java | 2 +- ...tractMqttV5ClientSparkplugAttributesTest.java | 2 +- ...5ClientSparkplugBAttributesInProfileTest.java | 2 +- .../MqttV5ClientSparkplugBAttributesTest.java | 2 +- ...tractMqttV5ClientSparkplugConnectionTest.java | 2 +- .../MqttV5ClientSparkplugBConnectionTest.java | 2 +- .../rpc/AbstractMqttV5RpcSparkplugTest.java | 2 +- .../sparkplug/rpc/MqttV5RpcSparkplugTest.java | 2 +- ...stractMqttV5ClientSparkplugTelemetryTest.java | 2 +- .../MqttV5ClientSparkplugBTelemetryTest.java | 2 +- .../server/utils/TbNodeUpgradeUtilsTest.java | 2 +- build_proto.sh | 2 +- common/actor/pom.xml | 2 +- .../server/actors/AbstractTbActor.java | 2 +- .../server/actors/DefaultTbActorSystem.java | 2 +- .../thingsboard/server/actors/Dispatcher.java | 2 +- .../server/actors/InitFailureStrategy.java | 2 +- .../thingsboard/server/actors/JsInvokeStats.java | 2 +- .../server/actors/ProcessFailureStrategy.java | 2 +- .../org/thingsboard/server/actors/TbActor.java | 2 +- .../server/actors/TbActorCreator.java | 2 +- .../thingsboard/server/actors/TbActorCtx.java | 2 +- .../server/actors/TbActorException.java | 2 +- .../org/thingsboard/server/actors/TbActorId.java | 2 +- .../server/actors/TbActorMailbox.java | 2 +- .../actors/TbActorNotRegisteredException.java | 2 +- .../thingsboard/server/actors/TbActorRef.java | 2 +- .../thingsboard/server/actors/TbActorSystem.java | 2 +- .../server/actors/TbActorSystemSettings.java | 2 +- .../server/actors/TbEntityActorId.java | 2 +- .../server/actors/TbRuleNodeUpdateException.java | 2 +- .../server/actors/TbStringActorId.java | 2 +- .../server/actors/ActorSystemTest.java | 2 +- .../thingsboard/server/actors/ActorTestCtx.java | 2 +- .../server/actors/FailedToInitActor.java | 2 +- .../thingsboard/server/actors/IntTbActorMsg.java | 2 +- .../server/actors/SlowCreateActor.java | 2 +- .../thingsboard/server/actors/SlowInitActor.java | 2 +- .../thingsboard/server/actors/TestRootActor.java | 2 +- common/cache/pom.xml | 2 +- .../org/thingsboard/server/cache/CacheSpecs.java | 2 +- .../thingsboard/server/cache/CacheSpecsMap.java | 2 +- .../server/cache/CaffeineTbCacheTransaction.java | 2 +- .../cache/CaffeineTbTransactionalCache.java | 2 +- .../server/cache/RedisTbCacheTransaction.java | 2 +- .../server/cache/RedisTbTransactionalCache.java | 2 +- .../server/cache/SimpleTbCacheValueWrapper.java | 2 +- .../server/cache/TBRedisCacheConfiguration.java | 2 +- .../cache/TBRedisClusterConfiguration.java | 2 +- .../cache/TBRedisSentinelConfiguration.java | 2 +- .../cache/TBRedisStandaloneConfiguration.java | 2 +- .../server/cache/TbCacheTransaction.java | 2 +- .../server/cache/TbCacheValueWrapper.java | 2 +- .../cache/TbCaffeineCacheConfiguration.java | 2 +- .../server/cache/TbFSTRedisSerializer.java | 2 +- .../server/cache/TbRedisSerializer.java | 2 +- .../server/cache/TbTransactionalCache.java | 2 +- .../cache/device/DeviceCacheEvictEvent.java | 2 +- .../server/cache/device/DeviceCacheKey.java | 2 +- .../server/cache/device/DeviceCaffeineCache.java | 2 +- .../server/cache/device/DeviceRedisCache.java | 2 +- .../cache/ota/CaffeineOtaPackageCache.java | 2 +- .../server/cache/ota/OtaPackageDataCache.java | 2 +- .../cache/ota/RedisOtaPackageDataCache.java | 2 +- .../cache/resourceInfo/ResourceInfoCacheKey.java | 2 +- .../resourceInfo/ResourceInfoCaffeineCache.java | 2 +- .../resourceInfo/ResourceInfoEvictEvent.java | 2 +- .../resourceInfo/ResourceInfoRedisCache.java | 2 +- .../UsersSessionInvalidationCaffeineCache.java | 2 +- .../UsersSessionInvalidationRedisCache.java | 2 +- .../server/cache/CacheSpecsMapTest.java | 2 +- common/cluster-api/pom.xml | 2 +- .../server/cluster/TbClusterService.java | 2 +- .../thingsboard/server/queue/TbQueueAdmin.java | 2 +- .../server/queue/TbQueueCallback.java | 2 +- .../server/queue/TbQueueClusterService.java | 2 +- .../server/queue/TbQueueConsumer.java | 2 +- .../thingsboard/server/queue/TbQueueHandler.java | 2 +- .../org/thingsboard/server/queue/TbQueueMsg.java | 2 +- .../server/queue/TbQueueMsgDecoder.java | 2 +- .../server/queue/TbQueueMsgHeaders.java | 2 +- .../server/queue/TbQueueMsgMetadata.java | 2 +- .../server/queue/TbQueueProducer.java | 2 +- .../server/queue/TbQueueRequestTemplate.java | 2 +- .../server/queue/TbQueueResponseTemplate.java | 2 +- common/coap-server/pom.xml | 2 +- .../server/coapserver/CoapServerContext.java | 2 +- .../server/coapserver/CoapServerService.java | 2 +- .../coapserver/DefaultCoapServerService.java | 2 +- .../TbCoapDtlsCertificateVerifier.java | 2 +- .../TbCoapDtlsSessionInMemoryStorage.java | 2 +- .../server/coapserver/TbCoapDtlsSessionInfo.java | 2 +- .../server/coapserver/TbCoapDtlsSettings.java | 2 +- .../server/coapserver/TbCoapServerComponent.java | 2 +- .../coapserver/TbCoapServerMessageDeliverer.java | 2 +- common/dao-api/pom.xml | 2 +- .../server/dao/alarm/AlarmCommentService.java | 2 +- .../server/dao/alarm/AlarmService.java | 2 +- .../server/dao/asset/AssetProfileService.java | 2 +- .../server/dao/asset/AssetService.java | 2 +- .../server/dao/attributes/AttributesService.java | 2 +- .../server/dao/audit/AuditLogService.java | 2 +- .../dao/cassandra/AbstractCassandraCluster.java | 2 +- .../server/dao/cassandra/CassandraCluster.java | 2 +- .../dao/cassandra/CassandraDriverOptions.java | 2 +- .../dao/cassandra/CassandraInstallCluster.java | 2 +- .../dao/cassandra/guava/DefaultGuavaSession.java | 2 +- .../dao/cassandra/guava/GuavaDriverContext.java | 2 +- .../cassandra/guava/GuavaMultiPageResultSet.java | 2 +- .../guava/GuavaRequestAsyncProcessor.java | 2 +- .../server/dao/cassandra/guava/GuavaSession.java | 2 +- .../dao/cassandra/guava/GuavaSessionBuilder.java | 2 +- .../dao/cassandra/guava/GuavaSessionUtils.java | 2 +- .../component/ComponentDescriptorService.java | 2 +- .../server/dao/customer/CustomerService.java | 2 +- .../server/dao/dashboard/DashboardService.java | 2 +- .../server/dao/device/ClaimDevicesService.java | 2 +- .../dao/device/DeviceConnectivityService.java | 2 +- .../dao/device/DeviceCredentialsService.java | 2 +- .../server/dao/device/DeviceProfileService.java | 2 +- .../dao/device/DeviceProvisionService.java | 2 +- .../server/dao/device/DeviceService.java | 2 +- .../server/dao/device/claim/ClaimData.java | 2 +- .../server/dao/device/claim/ClaimResponse.java | 2 +- .../server/dao/device/claim/ClaimResult.java | 2 +- .../server/dao/device/claim/ReclaimResult.java | 2 +- .../provision/ProvisionFailedException.java | 2 +- .../dao/device/provision/ProvisionRequest.java | 2 +- .../dao/device/provision/ProvisionResponse.java | 2 +- .../provision/ProvisionResponseStatus.java | 2 +- .../server/dao/edge/EdgeEventService.java | 2 +- .../thingsboard/server/dao/edge/EdgeService.java | 2 +- .../dao/edge/EdgeSynchronizationManager.java | 2 +- .../server/dao/entity/EntityCountService.java | 2 +- .../server/dao/entity/EntityDaoService.java | 2 +- .../server/dao/entity/EntityService.java | 2 +- .../server/dao/entity/EntityServiceRegistry.java | 2 +- .../server/dao/entityview/EntityViewService.java | 2 +- .../server/dao/event/EventService.java | 2 +- .../dao/housekeeper/HouseKeeperService.java | 2 +- .../server/dao/nosql/CassandraStatementTask.java | 2 +- .../server/dao/nosql/TbResultSet.java | 2 +- .../server/dao/nosql/TbResultSetFuture.java | 2 +- .../notification/NotificationRequestService.java | 2 +- .../notification/NotificationRuleService.java | 2 +- .../dao/notification/NotificationService.java | 2 +- .../NotificationSettingsService.java | 2 +- .../notification/NotificationTargetService.java | 2 +- .../NotificationTemplateService.java | 2 +- .../dao/oauth2/OAuth2ConfigTemplateService.java | 2 +- .../server/dao/oauth2/OAuth2Service.java | 2 +- .../server/dao/oauth2/OAuth2User.java | 2 +- .../server/dao/ota/OtaPackageService.java | 2 +- .../server/dao/queue/QueueService.java | 2 +- .../server/dao/relation/RelationService.java | 2 +- .../server/dao/resource/ImageService.java | 2 +- .../server/dao/resource/ResourceService.java | 2 +- .../thingsboard/server/dao/rpc/RpcService.java | 2 +- .../server/dao/rule/RuleChainService.java | 2 +- .../server/dao/rule/RuleNodeStateService.java | 2 +- .../dao/settings/AdminSettingsService.java | 2 +- .../server/dao/tenant/TbTenantProfileCache.java | 2 +- .../server/dao/tenant/TenantProfileService.java | 2 +- .../server/dao/tenant/TenantService.java | 2 +- .../server/dao/timeseries/TimeseriesService.java | 2 +- .../server/dao/usage/UsageInfoService.java | 2 +- .../server/dao/usagerecord/ApiLimitService.java | 2 +- .../dao/usagerecord/ApiUsageStateService.java | 2 +- .../thingsboard/server/dao/user/UserService.java | 2 +- .../server/dao/user/UserSettingsService.java | 2 +- .../thingsboard/server/dao/util/AsyncTask.java | 2 +- .../server/dao/util/DbTypeInfoComponent.java | 2 +- .../dao/util/DefaultDbTypeInfoComponent.java | 2 +- .../thingsboard/server/dao/util/NoSqlAnyDao.java | 2 +- .../server/dao/util/NoSqlAnyDaoNonCloud.java | 2 +- .../thingsboard/server/dao/util/NoSqlTsDao.java | 2 +- .../server/dao/util/NoSqlTsLatestDao.java | 2 +- .../org/thingsboard/server/dao/util/SqlDao.java | 2 +- .../thingsboard/server/dao/util/SqlTsDao.java | 2 +- .../server/dao/util/SqlTsLatestAnyDao.java | 2 +- .../server/dao/util/SqlTsLatestDao.java | 2 +- .../server/dao/util/SqlTsOrTsLatestAnyDao.java | 2 +- .../server/dao/util/TbAutoConfiguration.java | 2 +- .../server/dao/util/TimescaleDBTsDao.java | 2 +- .../server/dao/util/TimescaleDBTsLatestDao.java | 2 +- .../dao/util/TimescaleDBTsOrTsLatestDao.java | 2 +- .../server/dao/widget/WidgetTypeService.java | 2 +- .../server/dao/widget/WidgetsBundleService.java | 2 +- common/data/pom.xml | 2 +- .../server/common/data/AdminSettings.java | 2 +- .../server/common/data/ApiFeature.java | 2 +- .../server/common/data/ApiUsageRecordKey.java | 2 +- .../server/common/data/ApiUsageRecordState.java | 2 +- .../server/common/data/ApiUsageState.java | 2 +- .../server/common/data/ApiUsageStateValue.java | 2 +- .../thingsboard/server/common/data/BaseData.java | 2 +- .../common/data/BaseDataWithAdditionalInfo.java | 2 +- .../server/common/data/CacheConstants.java | 2 +- .../server/common/data/ClaimRequest.java | 2 +- .../server/common/data/CoapDeviceType.java | 2 +- .../server/common/data/ContactBased.java | 2 +- .../thingsboard/server/common/data/Customer.java | 2 +- .../server/common/data/Dashboard.java | 2 +- .../server/common/data/DashboardInfo.java | 2 +- .../server/common/data/DataConstants.java | 2 +- .../thingsboard/server/common/data/Device.java | 2 +- .../server/common/data/DeviceIdInfo.java | 2 +- .../server/common/data/DeviceInfo.java | 2 +- .../server/common/data/DeviceInfoFilter.java | 2 +- .../server/common/data/DeviceProfile.java | 2 +- .../server/common/data/DeviceProfileInfo.java | 2 +- .../common/data/DeviceProfileProvisionType.java | 2 +- .../server/common/data/DeviceProfileType.java | 2 +- .../server/common/data/DeviceTransportType.java | 2 +- .../server/common/data/DynamicProtoUtils.java | 2 +- .../server/common/data/EdgeUpgradeInfo.java | 2 +- .../server/common/data/EdgeUpgradeMessage.java | 2 +- .../server/common/data/EdgeUtils.java | 2 +- .../server/common/data/EntityFieldsData.java | 2 +- .../server/common/data/EntityInfo.java | 2 +- .../server/common/data/EntitySubtype.java | 2 +- .../server/common/data/EntityType.java | 2 +- .../server/common/data/EntityView.java | 2 +- .../server/common/data/EntityViewInfo.java | 2 +- .../server/common/data/EventInfo.java | 2 +- .../server/common/data/ExportableEntity.java | 2 +- .../thingsboard/server/common/data/FSTUtils.java | 2 +- .../server/common/data/FeaturesInfo.java | 2 +- .../server/common/data/FstStatsService.java | 2 +- .../server/common/data/HasAdditionalInfo.java | 2 +- .../server/common/data/HasCustomerId.java | 2 +- .../thingsboard/server/common/data/HasEmail.java | 2 +- .../thingsboard/server/common/data/HasImage.java | 2 +- .../thingsboard/server/common/data/HasLabel.java | 2 +- .../thingsboard/server/common/data/HasName.java | 2 +- .../server/common/data/HasOtaPackage.java | 2 +- .../server/common/data/HasRuleEngineProfile.java | 2 +- .../server/common/data/HasTenantId.java | 2 +- .../thingsboard/server/common/data/HasTitle.java | 2 +- .../server/common/data/HomeDashboard.java | 2 +- .../server/common/data/HomeDashboardInfo.java | 2 +- .../server/common/data/ImageDescriptor.java | 2 +- .../server/common/data/ImageExportData.java | 2 +- .../server/common/data/OtaPackage.java | 2 +- .../server/common/data/OtaPackageInfo.java | 2 +- .../server/common/data/ResourceType.java | 2 +- .../server/common/data/ResourceUtils.java | 2 +- .../data/SaveDeviceWithCredentialsRequest.java | 2 +- .../common/data/SaveOtaPackageInfoRequest.java | 2 +- .../server/common/data/ShortCustomerInfo.java | 2 +- .../server/common/data/StringUtils.java | 2 +- .../server/common/data/SystemInfo.java | 2 +- .../server/common/data/SystemInfoData.java | 2 +- .../server/common/data/SystemParams.java | 2 +- .../server/common/data/TbImageDeleteResult.java | 2 +- .../server/common/data/TbProperty.java | 2 +- .../server/common/data/TbResource.java | 2 +- .../server/common/data/TbResourceInfo.java | 2 +- .../server/common/data/TbResourceInfoFilter.java | 2 +- .../server/common/data/TbTransportService.java | 2 +- .../thingsboard/server/common/data/Tenant.java | 2 +- .../server/common/data/TenantInfo.java | 2 +- .../server/common/data/TenantProfile.java | 2 +- .../server/common/data/TenantProfileType.java | 2 +- .../server/common/data/TransportPayloadType.java | 2 +- .../server/common/data/UUIDConverter.java | 2 +- .../server/common/data/UpdateMessage.java | 2 +- .../server/common/data/UsageInfo.java | 2 +- .../org/thingsboard/server/common/data/User.java | 2 +- .../server/common/data/UserEmailInfo.java | 2 +- .../server/common/data/alarm/Alarm.java | 2 +- .../common/data/alarm/AlarmApiCallResult.java | 2 +- .../server/common/data/alarm/AlarmAssignee.java | 2 +- .../common/data/alarm/AlarmAssigneeUpdate.java | 2 +- .../server/common/data/alarm/AlarmComment.java | 2 +- .../common/data/alarm/AlarmCommentInfo.java | 2 +- .../common/data/alarm/AlarmCommentType.java | 2 +- .../alarm/AlarmCreateOrUpdateActiveRequest.java | 2 +- .../server/common/data/alarm/AlarmInfo.java | 2 +- .../data/alarm/AlarmModificationRequest.java | 2 +- .../common/data/alarm/AlarmPropagationInfo.java | 2 +- .../server/common/data/alarm/AlarmQuery.java | 2 +- .../server/common/data/alarm/AlarmQueryV2.java | 2 +- .../common/data/alarm/AlarmSearchStatus.java | 2 +- .../server/common/data/alarm/AlarmSeverity.java | 2 +- .../server/common/data/alarm/AlarmStatus.java | 2 +- .../common/data/alarm/AlarmStatusFilter.java | 2 +- .../common/data/alarm/AlarmUpdateRequest.java | 2 +- .../server/common/data/alarm/EntityAlarm.java | 2 +- .../server/common/data/asset/Asset.java | 2 +- .../server/common/data/asset/AssetInfo.java | 2 +- .../server/common/data/asset/AssetProfile.java | 2 +- .../common/data/asset/AssetProfileInfo.java | 2 +- .../common/data/asset/AssetSearchQuery.java | 2 +- .../server/common/data/audit/ActionStatus.java | 2 +- .../server/common/data/audit/ActionType.java | 2 +- .../server/common/data/audit/AuditLog.java | 2 +- .../common/data/device/DeviceSearchQuery.java | 2 +- .../device/credentials/BasicMqttCredentials.java | 2 +- .../ProvisionDeviceCredentialsData.java | 2 +- ...ctLwM2MBootstrapClientCredentialWithKeys.java | 2 +- .../lwm2m/AbstractLwM2MClientCredential.java | 2 +- .../AbstractLwM2MClientSecurityCredential.java | 2 +- .../lwm2m/LwM2MBootstrapClientCredential.java | 2 +- .../lwm2m/LwM2MBootstrapClientCredentials.java | 2 +- .../credentials/lwm2m/LwM2MClientCredential.java | 2 +- .../lwm2m/LwM2MDeviceCredentials.java | 2 +- .../credentials/lwm2m/LwM2MSecurityMode.java | 2 +- .../lwm2m/NoSecBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/NoSecClientCredential.java | 2 +- .../lwm2m/PSKBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/PSKClientCredential.java | 2 +- .../lwm2m/RPKBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/RPKClientCredential.java | 2 +- .../lwm2m/X509BootstrapClientCredential.java | 2 +- .../credentials/lwm2m/X509ClientCredential.java | 2 +- .../data/CoapDeviceTransportConfiguration.java | 2 +- .../device/data/DefaultDeviceConfiguration.java | 2 +- .../DefaultDeviceTransportConfiguration.java | 2 +- .../data/device/data/DeviceConfiguration.java | 2 +- .../common/data/device/data/DeviceData.java | 2 +- .../data/DeviceTransportConfiguration.java | 2 +- .../data/Lwm2mDeviceTransportConfiguration.java | 2 +- .../data/MqttDeviceTransportConfiguration.java | 2 +- .../common/data/device/data/PowerMode.java | 2 +- .../device/data/PowerSavingConfiguration.java | 2 +- .../data/SnmpDeviceTransportConfiguration.java | 2 +- .../data/device/profile/AlarmCondition.java | 2 +- .../device/profile/AlarmConditionFilter.java | 2 +- .../device/profile/AlarmConditionFilterKey.java | 2 +- .../device/profile/AlarmConditionKeyType.java | 2 +- .../data/device/profile/AlarmConditionSpec.java | 2 +- .../device/profile/AlarmConditionSpecType.java | 2 +- .../common/data/device/profile/AlarmRule.java | 2 +- .../data/device/profile/AlarmSchedule.java | 2 +- .../data/device/profile/AlarmScheduleType.java | 2 +- ...vicesDeviceProfileProvisionConfiguration.java | 2 +- .../data/device/profile/AnyTimeSchedule.java | 2 +- ...vicesDeviceProfileProvisionConfiguration.java | 2 +- .../CoapDeviceProfileTransportConfiguration.java | 2 +- .../profile/CoapDeviceTypeConfiguration.java | 2 +- .../data/device/profile/CustomTimeSchedule.java | 2 +- .../device/profile/CustomTimeScheduleItem.java | 2 +- .../DefaultCoapDeviceTypeConfiguration.java | 2 +- .../DefaultDeviceProfileConfiguration.java | 2 +- ...faultDeviceProfileTransportConfiguration.java | 2 +- .../data/device/profile/DeviceProfileAlarm.java | 2 +- .../profile/DeviceProfileConfiguration.java | 2 +- .../data/device/profile/DeviceProfileData.java | 2 +- .../DeviceProfileProvisionConfiguration.java | 2 +- .../DeviceProfileTransportConfiguration.java | 2 +- ...abledDeviceProfileProvisionConfiguration.java | 2 +- .../profile/DurationAlarmConditionSpec.java | 2 +- .../EfentoCoapDeviceTypeConfiguration.java | 2 +- .../JsonTransportPayloadConfiguration.java | 2 +- ...Lwm2mDeviceProfileTransportConfiguration.java | 2 +- .../MqttDeviceProfileTransportConfiguration.java | 2 +- .../common/data/device/profile/MqttTopics.java | 2 +- .../ProtoTransportPayloadConfiguration.java | 2 +- .../ProvisionDeviceProfileCredentials.java | 2 +- .../profile/RepeatingAlarmConditionSpec.java | 2 +- .../device/profile/SimpleAlarmConditionSpec.java | 2 +- .../SnmpDeviceProfileTransportConfiguration.java | 2 +- .../device/profile/SpecificTimeSchedule.java | 2 +- .../TransportPayloadTypeConfiguration.java | 2 +- ...09CertificateChainProvisionConfiguration.java | 3 +-- .../device/profile/lwm2m/ObjectAttributes.java | 2 +- .../device/profile/lwm2m/OtherConfiguration.java | 2 +- .../lwm2m/TelemetryMappingConfiguration.java | 2 +- .../AbstractLwM2MBootstrapServerCredential.java | 2 +- .../LwM2MBootstrapServerCredential.java | 2 +- .../bootstrap/LwM2MServerSecurityConfig.java | 2 +- .../LwM2MServerSecurityConfigDefault.java | 2 +- .../NoSecLwM2MBootstrapServerCredential.java | 2 +- .../PSKLwM2MBootstrapServerCredential.java | 2 +- .../RPKLwM2MBootstrapServerCredential.java | 2 +- .../X509LwM2MBootstrapServerCredential.java | 2 +- .../server/common/data/edge/Edge.java | 2 +- .../server/common/data/edge/EdgeEvent.java | 2 +- .../common/data/edge/EdgeEventActionType.java | 2 +- .../server/common/data/edge/EdgeEventType.java | 2 +- .../server/common/data/edge/EdgeInfo.java | 2 +- .../common/data/edge/EdgeInstructions.java | 2 +- .../server/common/data/edge/EdgeSearchQuery.java | 2 +- .../data/entityview/EntityViewSearchQuery.java | 2 +- .../common/data/event/DebugEventFilter.java | 2 +- .../server/common/data/event/ErrorEvent.java | 2 +- .../common/data/event/ErrorEventFilter.java | 2 +- .../server/common/data/event/Event.java | 2 +- .../server/common/data/event/EventFilter.java | 2 +- .../server/common/data/event/EventType.java | 2 +- .../common/data/event/LifeCycleEventFilter.java | 2 +- .../server/common/data/event/LifecycleEvent.java | 2 +- .../common/data/event/RuleChainDebugEvent.java | 2 +- .../data/event/RuleChainDebugEventFilter.java | 2 +- .../common/data/event/RuleNodeDebugEvent.java | 2 +- .../data/event/RuleNodeDebugEventFilter.java | 2 +- .../common/data/event/StatisticsEvent.java | 2 +- .../common/data/event/StatisticsEventFilter.java | 2 +- .../exception/AbstractRateLimitException.java | 2 +- .../ApiUsageLimitsExceededException.java | 2 +- .../data/exception/TenantNotFoundException.java | 2 +- .../TenantProfileNotFoundException.java | 2 +- .../data/exception/ThingsboardErrorCode.java | 2 +- .../data/exception/ThingsboardException.java | 2 +- .../exception/ThingsboardKafkaClientError.java | 2 +- .../server/common/data/id/AdminSettingsId.java | 2 +- .../server/common/data/id/AlarmCommentId.java | 2 +- .../server/common/data/id/AlarmId.java | 2 +- .../server/common/data/id/ApiUsageStateId.java | 2 +- .../server/common/data/id/AssetId.java | 2 +- .../server/common/data/id/AssetProfileId.java | 2 +- .../server/common/data/id/AuditLogId.java | 2 +- .../common/data/id/ComponentDescriptorId.java | 2 +- .../server/common/data/id/CustomerId.java | 2 +- .../server/common/data/id/DashboardId.java | 2 +- .../common/data/id/DeviceCredentialsId.java | 2 +- .../server/common/data/id/DeviceId.java | 2 +- .../server/common/data/id/DeviceProfileId.java | 2 +- .../server/common/data/id/EdgeEventId.java | 2 +- .../server/common/data/id/EdgeId.java | 2 +- .../server/common/data/id/EntityId.java | 2 +- .../common/data/id/EntityIdDeserializer.java | 2 +- .../server/common/data/id/EntityIdFactory.java | 2 +- .../common/data/id/EntityIdSerializer.java | 2 +- .../server/common/data/id/EntityViewId.java | 2 +- .../server/common/data/id/EventId.java | 2 +- .../thingsboard/server/common/data/id/HasId.java | 2 +- .../server/common/data/id/HasUUID.java | 2 +- .../server/common/data/id/IdBased.java | 2 +- .../data/id/NameLabelAndCustomerDetails.java | 2 +- .../server/common/data/id/NodeId.java | 2 +- .../server/common/data/id/NotificationId.java | 2 +- .../common/data/id/NotificationRequestId.java | 2 +- .../common/data/id/NotificationRuleId.java | 2 +- .../common/data/id/NotificationTargetId.java | 2 +- .../common/data/id/NotificationTemplateId.java | 2 +- .../id/OAuth2ClientRegistrationTemplateId.java | 2 +- .../server/common/data/id/OAuth2DomainId.java | 2 +- .../server/common/data/id/OAuth2MobileId.java | 2 +- .../server/common/data/id/OAuth2ParamsId.java | 2 +- .../common/data/id/OAuth2RegistrationId.java | 2 +- .../server/common/data/id/OtaPackageId.java | 2 +- .../server/common/data/id/QueueId.java | 2 +- .../thingsboard/server/common/data/id/RpcId.java | 2 +- .../server/common/data/id/RuleChainId.java | 2 +- .../server/common/data/id/RuleNodeId.java | 2 +- .../server/common/data/id/RuleNodeStateId.java | 2 +- .../server/common/data/id/TbResourceId.java | 2 +- .../server/common/data/id/TenantId.java | 2 +- .../server/common/data/id/TenantProfileId.java | 2 +- .../server/common/data/id/UUIDBased.java | 2 +- .../common/data/id/UserAuthSettingsId.java | 2 +- .../server/common/data/id/UserCredentialsId.java | 2 +- .../server/common/data/id/UserId.java | 2 +- .../server/common/data/id/WidgetTypeId.java | 2 +- .../server/common/data/id/WidgetsBundleId.java | 2 +- .../server/common/data/kv/AggTsKvEntry.java | 2 +- .../server/common/data/kv/Aggregation.java | 2 +- .../server/common/data/kv/AttributeKey.java | 2 +- .../server/common/data/kv/AttributeKvEntry.java | 2 +- .../common/data/kv/BaseAttributeKvEntry.java | 2 +- .../common/data/kv/BaseDeleteTsKvQuery.java | 2 +- .../server/common/data/kv/BaseReadTsKvQuery.java | 2 +- .../server/common/data/kv/BaseTsKvQuery.java | 2 +- .../server/common/data/kv/BasicKvEntry.java | 2 +- .../server/common/data/kv/BasicTsKvEntry.java | 2 +- .../server/common/data/kv/BooleanDataEntry.java | 2 +- .../server/common/data/kv/DataType.java | 2 +- .../server/common/data/kv/DeleteTsKvQuery.java | 2 +- .../server/common/data/kv/DoubleDataEntry.java | 2 +- .../server/common/data/kv/JsonDataEntry.java | 2 +- .../server/common/data/kv/KvEntry.java | 2 +- .../server/common/data/kv/LongDataEntry.java | 2 +- .../server/common/data/kv/ReadTsKvQuery.java | 2 +- .../common/data/kv/ReadTsKvQueryResult.java | 2 +- .../server/common/data/kv/StringDataEntry.java | 2 +- .../server/common/data/kv/TsKvEntry.java | 2 +- .../common/data/kv/TsKvEntryAggWrapper.java | 2 +- .../common/data/kv/TsKvLatestRemovingResult.java | 2 +- .../server/common/data/kv/TsKvQuery.java | 2 +- .../server/common/data/limit/LimitedApi.java | 2 +- .../server/common/data/lwm2m/LwM2mConstants.java | 2 +- .../server/common/data/lwm2m/LwM2mInstance.java | 2 +- .../server/common/data/lwm2m/LwM2mObject.java | 2 +- .../common/data/lwm2m/LwM2mResourceObserve.java | 2 +- .../common/data/mail/MailOauth2Provider.java | 2 +- .../server/common/data/msg/TbMsgType.java | 2 +- .../common/data/msg/TbNodeConnectionType.java | 2 +- .../data/notification/AlreadySentException.java | 2 +- .../common/data/notification/Notification.java | 2 +- .../notification/NotificationDeliveryMethod.java | 2 +- .../data/notification/NotificationRequest.java | 2 +- .../notification/NotificationRequestConfig.java | 2 +- .../notification/NotificationRequestInfo.java | 2 +- .../notification/NotificationRequestPreview.java | 2 +- .../notification/NotificationRequestStats.java | 2 +- .../notification/NotificationRequestStatus.java | 2 +- .../data/notification/NotificationStatus.java | 2 +- .../data/notification/NotificationType.java | 2 +- .../info/AlarmAssignmentNotificationInfo.java | 2 +- .../info/AlarmCommentNotificationInfo.java | 2 +- .../notification/info/AlarmNotificationInfo.java | 2 +- .../info/ApiUsageLimitNotificationInfo.java | 2 +- .../info/DeviceActivityNotificationInfo.java | 2 +- .../info/EntitiesLimitNotificationInfo.java | 2 +- .../info/EntityActionNotificationInfo.java | 2 +- .../info/NewPlatformVersionNotificationInfo.java | 2 +- .../data/notification/info/NotificationInfo.java | 2 +- .../info/RateLimitsNotificationInfo.java | 2 +- ...eComponentLifecycleEventNotificationInfo.java | 2 +- .../RuleEngineOriginatedNotificationInfo.java | 2 +- .../info/RuleOriginatedNotificationInfo.java | 2 +- .../DefaultNotificationRuleRecipientsConfig.java | 2 +- ...scalatedNotificationRuleRecipientsConfig.java | 2 +- .../data/notification/rule/NotificationRule.java | 2 +- .../rule/NotificationRuleConfig.java | 2 +- .../notification/rule/NotificationRuleInfo.java | 2 +- .../rule/NotificationRuleRecipientsConfig.java | 2 +- .../rule/trigger/AlarmAssignmentTrigger.java | 2 +- .../rule/trigger/AlarmCommentTrigger.java | 2 +- .../notification/rule/trigger/AlarmTrigger.java | 2 +- .../rule/trigger/ApiUsageLimitTrigger.java | 2 +- .../rule/trigger/DeviceActivityTrigger.java | 2 +- .../rule/trigger/EntitiesLimitTrigger.java | 2 +- .../rule/trigger/EntityActionTrigger.java | 2 +- .../rule/trigger/NewPlatformVersionTrigger.java | 2 +- .../rule/trigger/NotificationRuleTrigger.java | 2 +- .../rule/trigger/RateLimitsTrigger.java | 2 +- ...RuleEngineComponentLifecycleEventTrigger.java | 2 +- ...mAssignmentNotificationRuleTriggerConfig.java | 2 +- ...larmCommentNotificationRuleTriggerConfig.java | 2 +- .../AlarmNotificationRuleTriggerConfig.java | 2 +- ...iUsageLimitNotificationRuleTriggerConfig.java | 2 +- ...iceActivityNotificationRuleTriggerConfig.java | 2 +- ...titiesLimitNotificationRuleTriggerConfig.java | 2 +- ...ntityActionNotificationRuleTriggerConfig.java | 2 +- ...formVersionNotificationRuleTriggerConfig.java | 2 +- .../config/NotificationRuleTriggerConfig.java | 2 +- .../config/NotificationRuleTriggerType.java | 2 +- .../RateLimitsNotificationRuleTriggerConfig.java | 2 +- ...ecycleEventNotificationRuleTriggerConfig.java | 2 +- .../settings/AccountNotificationSettings.java | 2 +- .../NotificationDeliveryMethodConfig.java | 2 +- .../settings/NotificationSettings.java | 2 +- .../SlackNotificationDeliveryMethodConfig.java | 2 +- .../settings/UserNotificationSettings.java | 2 +- .../MicrosoftTeamsNotificationTargetConfig.java | 2 +- .../targets/NotificationRecipient.java | 2 +- .../notification/targets/NotificationTarget.java | 2 +- .../targets/NotificationTargetConfig.java | 2 +- .../targets/NotificationTargetType.java | 2 +- .../AffectedTenantAdministratorsFilter.java | 2 +- .../targets/platform/AffectedUserFilter.java | 2 +- .../targets/platform/AllUsersFilter.java | 2 +- .../targets/platform/CustomerUsersFilter.java | 2 +- .../OriginatorEntityOwnerUsersFilter.java | 2 +- .../PlatformUsersNotificationTargetConfig.java | 2 +- .../platform/SystemAdministratorsFilter.java | 2 +- .../platform/TenantAdministratorsFilter.java | 2 +- .../targets/platform/UserListFilter.java | 2 +- .../targets/platform/UsersFilter.java | 2 +- .../targets/platform/UsersFilterType.java | 2 +- .../targets/slack/SlackConversation.java | 2 +- .../targets/slack/SlackConversationType.java | 2 +- .../slack/SlackNotificationTargetConfig.java | 2 +- .../DeliveryMethodNotificationTemplate.java | 2 +- .../EmailDeliveryMethodNotificationTemplate.java | 2 +- .../data/notification/template/HasSubject.java | 2 +- ...tTeamsDeliveryMethodNotificationTemplate.java | 2 +- .../template/NotificationTemplate.java | 2 +- .../template/NotificationTemplateConfig.java | 2 +- .../SlackDeliveryMethodNotificationTemplate.java | 2 +- .../SmsDeliveryMethodNotificationTemplate.java | 2 +- .../notification/template/TemplatableValue.java | 2 +- .../WebDeliveryMethodNotificationTemplate.java | 2 +- .../server/common/data/oauth2/MapperType.java | 2 +- .../data/oauth2/OAuth2BasicMapperConfig.java | 2 +- .../common/data/oauth2/OAuth2ClientInfo.java | 2 +- .../oauth2/OAuth2ClientRegistrationTemplate.java | 2 +- .../data/oauth2/OAuth2CustomMapperConfig.java | 2 +- .../server/common/data/oauth2/OAuth2Domain.java | 2 +- .../common/data/oauth2/OAuth2DomainInfo.java | 2 +- .../server/common/data/oauth2/OAuth2Info.java | 2 +- .../common/data/oauth2/OAuth2MapperConfig.java | 2 +- .../server/common/data/oauth2/OAuth2Mobile.java | 2 +- .../common/data/oauth2/OAuth2MobileInfo.java | 2 +- .../server/common/data/oauth2/OAuth2Params.java | 2 +- .../common/data/oauth2/OAuth2ParamsInfo.java | 2 +- .../common/data/oauth2/OAuth2Registration.java | 2 +- .../data/oauth2/OAuth2RegistrationInfo.java | 2 +- .../server/common/data/oauth2/PlatformType.java | 2 +- .../server/common/data/oauth2/SchemeType.java | 2 +- .../data/oauth2/TenantNameStrategyType.java | 2 +- .../data/objects/AttributesEntityView.java | 2 +- .../common/data/objects/TelemetryEntityView.java | 2 +- .../common/data/ota/ChecksumAlgorithm.java | 2 +- .../server/common/data/ota/OtaPackageKey.java | 2 +- .../server/common/data/ota/OtaPackageType.java | 2 +- .../common/data/ota/OtaPackageUpdateStatus.java | 2 +- .../server/common/data/ota/OtaPackageUtil.java | 2 +- .../common/data/page/BasePageDataIterable.java | 2 +- .../server/common/data/page/PageData.java | 2 +- .../common/data/page/PageDataIterable.java | 2 +- .../data/page/PageDataIterableByTenant.java | 2 +- .../page/PageDataIterableByTenantIdEntityId.java | 2 +- .../server/common/data/page/PageLink.java | 2 +- .../server/common/data/page/SortOrder.java | 2 +- .../server/common/data/page/TimePageLink.java | 2 +- .../data/plugin/ComponentClusteringMode.java | 2 +- .../common/data/plugin/ComponentDescriptor.java | 2 +- .../data/plugin/ComponentLifecycleEvent.java | 2 +- .../data/plugin/ComponentLifecycleState.java | 2 +- .../common/data/plugin/ComponentScope.java | 2 +- .../server/common/data/plugin/ComponentType.java | 2 +- .../common/data/query/AbstractDataQuery.java | 2 +- .../common/data/query/AlarmCountQuery.java | 2 +- .../server/common/data/query/AlarmData.java | 2 +- .../common/data/query/AlarmDataPageLink.java | 2 +- .../server/common/data/query/AlarmDataQuery.java | 2 +- .../common/data/query/ApiUsageStateFilter.java | 2 +- .../data/query/AssetSearchQueryFilter.java | 2 +- .../common/data/query/AssetTypeFilter.java | 2 +- .../data/query/BooleanFilterPredicate.java | 2 +- .../common/data/query/ComparisonTsValue.java | 2 +- .../data/query/ComplexFilterPredicate.java | 2 +- .../data/query/DeviceSearchQueryFilter.java | 2 +- .../common/data/query/DeviceTypeFilter.java | 2 +- .../server/common/data/query/DynamicValue.java | 2 +- .../data/query/DynamicValueSourceType.java | 2 +- .../common/data/query/EdgeSearchQueryFilter.java | 2 +- .../server/common/data/query/EdgeTypeFilter.java | 2 +- .../common/data/query/EntityCountQuery.java | 2 +- .../server/common/data/query/EntityData.java | 2 +- .../common/data/query/EntityDataPageLink.java | 2 +- .../common/data/query/EntityDataQuery.java | 2 +- .../common/data/query/EntityDataSortOrder.java | 2 +- .../server/common/data/query/EntityFilter.java | 2 +- .../common/data/query/EntityFilterType.java | 2 +- .../server/common/data/query/EntityKey.java | 2 +- .../server/common/data/query/EntityKeyType.java | 2 +- .../common/data/query/EntityKeyValueType.java | 2 +- .../common/data/query/EntityListFilter.java | 2 +- .../common/data/query/EntityNameFilter.java | 2 +- .../data/query/EntitySearchQueryFilter.java | 2 +- .../common/data/query/EntityTypeFilter.java | 2 +- .../data/query/EntityViewSearchQueryFilter.java | 2 +- .../common/data/query/EntityViewTypeFilter.java | 2 +- .../common/data/query/FilterPredicateType.java | 2 +- .../common/data/query/FilterPredicateValue.java | 2 +- .../server/common/data/query/KeyFilter.java | 2 +- .../common/data/query/KeyFilterPredicate.java | 2 +- .../data/query/NumericFilterPredicate.java | 2 +- .../common/data/query/RelationsQueryFilter.java | 2 +- .../data/query/SimpleKeyFilterPredicate.java | 2 +- .../common/data/query/SingleEntityFilter.java | 2 +- .../common/data/query/StringFilterPredicate.java | 2 +- .../server/common/data/query/TsValue.java | 2 +- .../common/data/queue/ProcessingStrategy.java | 2 +- .../data/queue/ProcessingStrategyType.java | 2 +- .../server/common/data/queue/Queue.java | 2 +- .../server/common/data/queue/SubmitStrategy.java | 2 +- .../common/data/queue/SubmitStrategyType.java | 2 +- .../common/data/relation/EntityRelation.java | 2 +- .../common/data/relation/EntityRelationInfo.java | 2 +- .../data/relation/EntityRelationsQuery.java | 2 +- .../data/relation/EntitySearchDirection.java | 2 +- .../data/relation/RelationEntityTypeFilter.java | 2 +- .../common/data/relation/RelationTypeGroup.java | 2 +- .../data/relation/RelationsSearchParameters.java | 2 +- .../thingsboard/server/common/data/rpc/Rpc.java | 2 +- .../server/common/data/rpc/RpcError.java | 2 +- .../server/common/data/rpc/RpcStatus.java | 2 +- .../common/data/rpc/ToDeviceRpcRequestBody.java | 2 +- .../data/rule/DefaultRuleChainCreateRequest.java | 2 +- .../common/data/rule/NodeConnectionInfo.java | 2 +- .../server/common/data/rule/RuleChain.java | 2 +- .../data/rule/RuleChainConnectionInfo.java | 2 +- .../server/common/data/rule/RuleChainData.java | 2 +- .../common/data/rule/RuleChainImportResult.java | 2 +- .../common/data/rule/RuleChainMetaData.java | 2 +- .../data/rule/RuleChainOutputLabelsUsage.java | 2 +- .../server/common/data/rule/RuleChainType.java | 2 +- .../common/data/rule/RuleChainUpdateResult.java | 2 +- .../server/common/data/rule/RuleNode.java | 2 +- .../server/common/data/rule/RuleNodeState.java | 2 +- .../common/data/rule/RuleNodeUpdateResult.java | 2 +- .../server/common/data/rule/RuleType.java | 2 +- .../server/common/data/rule/Scope.java | 2 +- .../common/data/script/ScriptLanguage.java | 2 +- .../server/common/data/security/Authority.java | 2 +- .../common/data/security/DeviceCredentials.java | 2 +- .../data/security/DeviceCredentialsFilter.java | 2 +- .../data/security/DeviceCredentialsType.java | 2 +- .../data/security/DeviceTokenCredentials.java | 2 +- .../data/security/DeviceX509Credentials.java | 2 +- .../common/data/security/UserAuthSettings.java | 2 +- .../common/data/security/UserCredentials.java | 2 +- .../security/event/UserAuthDataChangedEvent.java | 2 +- .../event/UserCredentialsInvalidationEvent.java | 2 +- .../event/UserSessionInvalidationEvent.java | 2 +- .../common/data/security/model/JwtPair.java | 2 +- .../common/data/security/model/JwtSettings.java | 2 +- .../common/data/security/model/JwtToken.java | 2 +- .../data/security/model/SecuritySettings.java | 2 +- .../data/security/model/UserPasswordPolicy.java | 2 +- .../model/mfa/PlatformTwoFaSettings.java | 2 +- .../model/mfa/account/AccountTwoFaSettings.java | 2 +- .../account/BackupCodeTwoFaAccountConfig.java | 2 +- .../mfa/account/EmailTwoFaAccountConfig.java | 2 +- .../mfa/account/OtpBasedTwoFaAccountConfig.java | 2 +- .../model/mfa/account/SmsTwoFaAccountConfig.java | 2 +- .../mfa/account/TotpTwoFaAccountConfig.java | 2 +- .../model/mfa/account/TwoFaAccountConfig.java | 2 +- .../provider/BackupCodeTwoFaProviderConfig.java | 2 +- .../mfa/provider/EmailTwoFaProviderConfig.java | 2 +- .../provider/OtpBasedTwoFaProviderConfig.java | 2 +- .../mfa/provider/SmsTwoFaProviderConfig.java | 2 +- .../mfa/provider/TotpTwoFaProviderConfig.java | 2 +- .../model/mfa/provider/TwoFaProviderConfig.java | 2 +- .../model/mfa/provider/TwoFaProviderType.java | 2 +- .../data/settings/AbstractUserDashboardInfo.java | 2 +- .../data/settings/LastVisitedDashboardInfo.java | 2 +- .../data/settings/StarredDashboardInfo.java | 2 +- .../data/settings/UserDashboardAction.java | 2 +- .../common/data/settings/UserDashboardsInfo.java | 2 +- .../common/data/settings/UserSettings.java | 2 +- .../data/settings/UserSettingsCompositeKey.java | 2 +- .../common/data/settings/UserSettingsType.java | 2 +- .../config/AwsSnsSmsProviderConfiguration.java | 2 +- .../sms/config/SmppSmsProviderConfiguration.java | 2 +- .../sms/config/SmsProviderConfiguration.java | 2 +- .../common/data/sms/config/SmsProviderType.java | 2 +- .../common/data/sms/config/TestSmsRequest.java | 2 +- .../config/TwilioSmsProviderConfiguration.java | 2 +- .../server/common/data/sync/JsonTbEntity.java | 2 +- .../common/data/sync/ie/AttributeExportData.java | 2 +- .../common/data/sync/ie/DeviceExportData.java | 2 +- .../common/data/sync/ie/EntityExportData.java | 2 +- .../data/sync/ie/EntityExportSettings.java | 2 +- .../common/data/sync/ie/EntityImportResult.java | 2 +- .../data/sync/ie/EntityImportSettings.java | 2 +- .../common/data/sync/ie/RuleChainExportData.java | 2 +- .../data/sync/ie/WidgetTypeExportData.java | 2 +- .../data/sync/ie/WidgetsBundleExportData.java | 2 +- .../ie/importing/csv/BulkImportColumnType.java | 2 +- .../sync/ie/importing/csv/BulkImportRequest.java | 2 +- .../sync/ie/importing/csv/BulkImportResult.java | 2 +- .../common/data/sync/vc/AutoCommitSettings.java | 2 +- .../server/common/data/sync/vc/BranchInfo.java | 2 +- .../common/data/sync/vc/EntityDataDiff.java | 2 +- .../common/data/sync/vc/EntityDataInfo.java | 2 +- .../common/data/sync/vc/EntityLoadError.java | 2 +- .../data/sync/vc/EntityTypeLoadResult.java | 2 +- .../common/data/sync/vc/EntityVersion.java | 2 +- .../common/data/sync/vc/EntityVersionsDiff.java | 2 +- .../data/sync/vc/RepositoryAuthMethod.java | 2 +- .../common/data/sync/vc/RepositorySettings.java | 2 +- .../data/sync/vc/RepositorySettingsInfo.java | 2 +- .../server/common/data/sync/vc/VcUtils.java | 2 +- .../data/sync/vc/VersionCreationResult.java | 2 +- .../common/data/sync/vc/VersionLoadResult.java | 2 +- .../common/data/sync/vc/VersionedEntityInfo.java | 2 +- .../request/create/AutoVersionCreateConfig.java | 2 +- .../create/ComplexVersionCreateRequest.java | 2 +- .../create/EntityTypeVersionCreateConfig.java | 2 +- .../create/SingleEntityVersionCreateRequest.java | 2 +- .../sync/vc/request/create/SyncStrategy.java | 2 +- .../vc/request/create/VersionCreateConfig.java | 2 +- .../vc/request/create/VersionCreateRequest.java | 2 +- .../request/create/VersionCreateRequestType.java | 2 +- .../load/EntityTypeVersionLoadConfig.java | 2 +- .../load/EntityTypeVersionLoadRequest.java | 2 +- .../load/SingleEntityVersionLoadRequest.java | 2 +- .../sync/vc/request/load/VersionLoadConfig.java | 2 +- .../sync/vc/request/load/VersionLoadRequest.java | 2 +- .../vc/request/load/VersionLoadRequestType.java | 2 +- .../DefaultTenantProfileConfiguration.java | 2 +- .../profile/TenantProfileConfiguration.java | 2 +- .../data/tenant/profile/TenantProfileData.java | 2 +- .../profile/TenantProfileQueueConfiguration.java | 2 +- .../data/transport/resource/ResourceType.java | 2 +- .../transport/snmp/AuthenticationProtocol.java | 2 +- .../data/transport/snmp/PrivacyProtocol.java | 2 +- .../transport/snmp/SnmpCommunicationSpec.java | 2 +- .../common/data/transport/snmp/SnmpMapping.java | 2 +- .../common/data/transport/snmp/SnmpMethod.java | 2 +- .../data/transport/snmp/SnmpProtocolVersion.java | 2 +- .../MultipleMappingsSnmpCommunicationConfig.java | 2 +- ...RepeatingQueryingSnmpCommunicationConfig.java | 2 +- .../snmp/config/SnmpCommunicationConfig.java | 2 +- ...oServerRpcRequestSnmpCommunicationConfig.java | 2 +- ...ttributesQueryingSnmpCommunicationConfig.java | 2 +- ...AttributesSettingSnmpCommunicationConfig.java | 2 +- ...TelemetryQueryingSnmpCommunicationConfig.java | 2 +- ...oDeviceRpcRequestSnmpCommunicationConfig.java | 2 +- .../server/common/data/util/CollectionsUtil.java | 2 +- .../server/common/data/util/ReflectionUtils.java | 2 +- .../server/common/data/util/TbDDFFileParser.java | 2 +- .../server/common/data/util/TbPair.java | 2 +- .../server/common/data/util/TemplateUtils.java | 2 +- .../common/data/util/ThrowingBiFunction.java | 2 +- .../common/data/util/ThrowingRunnable.java | 2 +- .../common/data/util/ThrowingSupplier.java | 2 +- .../server/common/data/util/TypeCastUtil.java | 2 +- .../server/common/data/validation/Length.java | 2 +- .../server/common/data/validation/NoXss.java | 2 +- .../common/data/widget/BaseWidgetType.java | 2 +- .../common/data/widget/DeprecatedFilter.java | 2 +- .../server/common/data/widget/WidgetType.java | 2 +- .../common/data/widget/WidgetTypeDetails.java | 2 +- .../common/data/widget/WidgetTypeInfo.java | 2 +- .../server/common/data/widget/WidgetsBundle.java | 2 +- .../common/data/widget/WidgetsBundleWidget.java | 2 +- .../common/data/DynamicProtoUtilsTest.java | 2 +- .../server/common/data/EntityTypeTest.java | 2 +- .../server/common/data/StringUtilsTest.java | 2 +- .../server/common/data/UUIDConverterTest.java | 2 +- .../server/common/data/audit/ActionTypeTest.java | 2 +- .../server/common/data/id/EntityIdTest.java | 2 +- .../server/common/data/msg/TbMsgTypeTest.java | 2 +- .../server/common/data/rpc/RpcStatusTest.java | 2 +- common/edge-api/pom.xml | 2 +- .../edge/exception/EdgeConnectionException.java | 2 +- .../org/thingsboard/edge/rpc/EdgeGrpcClient.java | 2 +- .../org/thingsboard/edge/rpc/EdgeRpcClient.java | 2 +- common/edge-api/src/main/proto/edge.proto | 2 +- common/message/pom.xml | 2 +- .../server/common/msg/EncryptionUtil.java | 2 +- .../thingsboard/server/common/msg/MsgType.java | 2 +- .../server/common/msg/TbActorError.java | 2 +- .../server/common/msg/TbActorMsg.java | 2 +- .../server/common/msg/TbActorStopReason.java | 2 +- .../org/thingsboard/server/common/msg/TbMsg.java | 2 +- .../server/common/msg/TbMsgDataType.java | 2 +- .../server/common/msg/TbMsgMetaData.java | 2 +- .../server/common/msg/TbMsgProcessingCtx.java | 2 +- .../common/msg/TbMsgProcessingStackItem.java | 2 +- .../server/common/msg/TbRuleEngineActorMsg.java | 2 +- .../common/msg/ToDeviceActorNotificationMsg.java | 2 +- .../common/msg/aware/CustomerAwareMsg.java | 2 +- .../server/common/msg/aware/DeviceAwareMsg.java | 2 +- .../server/common/msg/aware/NodeAwareMsg.java | 2 +- .../common/msg/aware/RuleChainAwareMsg.java | 2 +- .../server/common/msg/aware/TenantAwareMsg.java | 2 +- .../server/common/msg/cluster/ToAllNodesMsg.java | 2 +- .../common/msg/edge/EdgeEventUpdateMsg.java | 2 +- .../server/common/msg/edge/EdgeSessionMsg.java | 2 +- .../common/msg/edge/FromEdgeSyncResponse.java | 2 +- .../common/msg/edge/ToEdgeSyncRequest.java | 2 +- .../notification/NotificationRuleProcessor.java | 2 +- .../msg/plugin/ComponentLifecycleListener.java | 2 +- .../common/msg/plugin/ComponentLifecycleMsg.java | 2 +- .../common/msg/plugin/RuleNodeUpdatedMsg.java | 2 +- .../common/msg/queue/PartitionChangeMsg.java | 2 +- .../common/msg/queue/QueueToRuleEngineMsg.java | 2 +- .../common/msg/queue/RuleEngineException.java | 2 +- .../common/msg/queue/RuleNodeException.java | 2 +- .../server/common/msg/queue/RuleNodeInfo.java | 2 +- .../server/common/msg/queue/ServiceType.java | 2 +- .../server/common/msg/queue/TbCallback.java | 2 +- .../server/common/msg/queue/TbMsgCallback.java | 2 +- .../common/msg/queue/TopicPartitionInfo.java | 2 +- .../common/msg/rpc/FromDeviceRpcResponse.java | 2 +- .../msg/rpc/FromDeviceRpcResponseActorMsg.java | 2 +- .../server/common/msg/rpc/RemoveRpcActorMsg.java | 2 +- .../common/msg/rpc/ToDeviceRpcRequest.java | 2 +- .../msg/rpc/ToDeviceRpcRequestActorMsg.java | 2 +- .../common/msg/rule/engine/DeviceAttributes.java | 2 +- .../DeviceAttributesEventNotificationMsg.java | 2 +- .../DeviceCredentialsUpdateNotificationMsg.java | 2 +- .../common/msg/rule/engine/DeviceDeleteMsg.java | 2 +- .../msg/rule/engine/DeviceEdgeUpdateMsg.java | 2 +- .../common/msg/rule/engine/DeviceMetaData.java | 2 +- .../rule/engine/DeviceNameOrTypeUpdateMsg.java | 2 +- .../server/common/msg/session/FeatureType.java | 2 +- .../common/msg/session/SessionMsgType.java | 2 +- .../session/ex/ProcessingTimeoutException.java | 2 +- .../msg/session/ex/SessionAuthException.java | 2 +- .../common/msg/session/ex/SessionException.java | 2 +- .../DeviceActorServerSideRpcTimeoutMsg.java | 2 +- .../server/common/msg/timeout/TimeoutMsg.java | 2 +- .../server/common/msg/tools/SchedulerUtils.java | 2 +- .../server/common/msg/tools/TbRateLimits.java | 2 +- .../common/msg/tools/TbRateLimitsException.java | 2 +- common/message/src/main/proto/tbmsg.proto | 2 +- .../server/common/msg/TbMsgMetaDataTest.java | 2 +- .../common/msg/TbMsgProcessingStackItemTest.java | 2 +- .../common/msg/queue/TopicPartitionInfoTest.java | 2 +- .../server/common/msg/tools/RateLimitsTest.java | 2 +- common/pom.xml | 2 +- common/proto/pom.xml | 2 +- .../server/common/adaptor/AdaptorException.java | 2 +- .../server/common/adaptor/JsonConverter.java | 2 +- .../common/adaptor/JsonConverterConfig.java | 2 +- .../server/common/adaptor/ProtoConverter.java | 2 +- .../server/common/util/ProtoUtils.java | 2 +- common/proto/src/main/proto/jsinvoke.proto | 2 +- common/proto/src/main/proto/queue.proto | 2 +- common/proto/src/main/proto/transport.proto | 2 +- .../server/common/adaptor/JsonConverterTest.java | 2 +- .../server/common/util/ProtoUtilsTest.java | 2 +- common/queue/pom.xml | 2 +- .../queue/RuleEngineTbQueueAdminFactory.java | 2 +- .../azure/servicebus/TbServiceBusAdmin.java | 2 +- .../servicebus/TbServiceBusConsumerTemplate.java | 2 +- .../servicebus/TbServiceBusProducerTemplate.java | 2 +- .../servicebus/TbServiceBusQueueConfigs.java | 2 +- .../azure/servicebus/TbServiceBusSettings.java | 2 +- .../AbstractParallelTbQueueConsumerTemplate.java | 2 +- .../common/AbstractTbQueueConsumerTemplate.java | 2 +- .../queue/common/AbstractTbQueueTemplate.java | 2 +- .../queue/common/AsyncCallbackTemplate.java | 2 +- .../server/queue/common/DefaultTbQueueMsg.java | 2 +- .../queue/common/DefaultTbQueueMsgHeaders.java | 2 +- .../common/DefaultTbQueueRequestTemplate.java | 2 +- .../common/DefaultTbQueueResponseTemplate.java | 2 +- .../common/MultipleTbQueueCallbackWrapper.java | 2 +- .../MultipleTbQueueTbMsgCallbackWrapper.java | 2 +- .../server/queue/common/TbProtoJsQueueMsg.java | 2 +- .../server/queue/common/TbProtoQueueMsg.java | 2 +- .../common/TbQueueTbMsgCallbackWrapper.java | 2 +- .../queue/discovery/ConsistentHashCircle.java | 2 +- .../discovery/DefaultTbServiceInfoProvider.java | 2 +- .../server/queue/discovery/DiscoveryService.java | 2 +- .../queue/discovery/DummyDiscoveryService.java | 2 +- .../queue/discovery/HashPartitionService.java | 2 +- .../server/queue/discovery/PartitionService.java | 2 +- .../server/queue/discovery/QueueKey.java | 2 +- .../server/queue/discovery/QueueRoutingInfo.java | 2 +- .../queue/discovery/QueueRoutingInfoService.java | 2 +- .../discovery/TbApplicationEventListener.java | 2 +- .../queue/discovery/TbServiceInfoProvider.java | 2 +- .../queue/discovery/TenantRoutingInfo.java | 2 +- .../discovery/TenantRoutingInfoService.java | 2 +- .../server/queue/discovery/TopicService.java | 2 +- .../queue/discovery/ZkDiscoveryService.java | 2 +- .../event/ClusterTopologyChangeEvent.java | 2 +- .../event/OtherServiceShutdownEvent.java | 2 +- .../discovery/event/PartitionChangeEvent.java | 2 +- .../discovery/event/ServiceListChangedEvent.java | 2 +- .../discovery/event/TbApplicationEvent.java | 2 +- .../queue/environment/EnvironmentLogService.java | 2 +- .../server/queue/kafka/KafkaTbQueueMsg.java | 2 +- .../queue/kafka/KafkaTbQueueMsgMetadata.java | 2 +- .../server/queue/kafka/TbKafkaAdmin.java | 2 +- .../kafka/TbKafkaConsumerStatisticConfig.java | 2 +- .../queue/kafka/TbKafkaConsumerStatsService.java | 2 +- .../queue/kafka/TbKafkaConsumerTemplate.java | 2 +- .../server/queue/kafka/TbKafkaDecoder.java | 2 +- .../server/queue/kafka/TbKafkaEncoder.java | 2 +- .../queue/kafka/TbKafkaProducerTemplate.java | 2 +- .../server/queue/kafka/TbKafkaSettings.java | 2 +- .../server/queue/kafka/TbKafkaTopicConfigs.java | 2 +- .../queue/memory/DefaultInMemoryStorage.java | 2 +- .../server/queue/memory/InMemoryStorage.java | 2 +- .../queue/memory/InMemoryTbQueueConsumer.java | 2 +- .../queue/memory/InMemoryTbQueueProducer.java | 2 +- .../DefaultNotificationDeduplicationService.java | 2 +- .../NotificationDeduplicationService.java | 2 +- .../RemoteNotificationRuleProcessor.java | 2 +- .../provider/AwsSqsMonolithQueueFactory.java | 2 +- .../queue/provider/AwsSqsTbCoreQueueFactory.java | 2 +- .../provider/AwsSqsTbRuleEngineQueueFactory.java | 2 +- .../AwsSqsTbVersionControlQueueFactory.java | 2 +- .../provider/AwsSqsTransportQueueFactory.java | 2 +- .../provider/InMemoryMonolithQueueFactory.java | 2 +- .../InMemoryTbTransportQueueFactory.java | 2 +- .../provider/KafkaMonolithQueueFactory.java | 2 +- .../queue/provider/KafkaTbCoreQueueFactory.java | 2 +- .../provider/KafkaTbRuleEngineQueueFactory.java | 2 +- .../provider/KafkaTbTransportQueueFactory.java | 2 +- .../KafkaTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubMonolithQueueFactory.java | 2 +- .../queue/provider/PubSubTbCoreQueueFactory.java | 2 +- .../provider/PubSubTbRuleEngineQueueFactory.java | 2 +- .../PubSubTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubTransportQueueFactory.java | 2 +- .../provider/RabbitMqMonolithQueueFactory.java | 2 +- .../provider/RabbitMqTbCoreQueueFactory.java | 2 +- .../RabbitMqTbRuleEngineQueueFactory.java | 2 +- .../RabbitMqTbVersionControlQueueFactory.java | 2 +- .../provider/RabbitMqTransportQueueFactory.java | 2 +- .../provider/ServiceBusMonolithQueueFactory.java | 2 +- .../provider/ServiceBusTbCoreQueueFactory.java | 2 +- .../ServiceBusTbRuleEngineQueueFactory.java | 2 +- .../ServiceBusTbVersionControlQueueFactory.java | 2 +- .../ServiceBusTransportQueueFactory.java | 2 +- .../queue/provider/TbCoreQueueFactory.java | 2 +- .../provider/TbCoreQueueProducerProvider.java | 2 +- .../queue/provider/TbQueueProducerProvider.java | 2 +- .../provider/TbRuleEngineProducerProvider.java | 2 +- .../queue/provider/TbRuleEngineQueueFactory.java | 2 +- .../queue/provider/TbTransportQueueFactory.java | 2 +- .../TbTransportQueueProducerProvider.java | 2 +- .../provider/TbUsageStatsClientQueueFactory.java | 2 +- .../TbVersionControlProducerProvider.java | 2 +- .../provider/TbVersionControlQueueFactory.java | 2 +- .../server/queue/pubsub/TbPubSubAdmin.java | 2 +- .../queue/pubsub/TbPubSubConsumerTemplate.java | 2 +- .../queue/pubsub/TbPubSubProducerTemplate.java | 2 +- .../server/queue/pubsub/TbPubSubSettings.java | 2 +- .../pubsub/TbPubSubSubscriptionSettings.java | 2 +- .../server/queue/rabbitmq/TbRabbitMqAdmin.java | 2 +- .../rabbitmq/TbRabbitMqConsumerTemplate.java | 2 +- .../rabbitmq/TbRabbitMqProducerTemplate.java | 2 +- .../queue/rabbitmq/TbRabbitMqQueueArguments.java | 2 +- .../queue/rabbitmq/TbRabbitMqSettings.java | 2 +- .../scheduler/DefaultSchedulerComponent.java | 2 +- .../queue/scheduler/SchedulerComponent.java | 2 +- .../queue/settings/TbQueueCoreSettings.java | 2 +- .../settings/TbQueueRemoteJsInvokeSettings.java | 2 +- .../settings/TbQueueRuleEngineSettings.java | 2 +- .../settings/TbQueueTransportApiSettings.java | 2 +- .../TbQueueTransportNotificationSettings.java | 2 +- .../settings/TbQueueVersionControlSettings.java | 2 +- ...bRuleEngineQueueAckStrategyConfiguration.java | 2 +- .../settings/TbRuleEngineQueueConfiguration.java | 2 +- ...leEngineQueueSubmitStrategyConfiguration.java | 2 +- .../queue/sqs/AwsSqsTbQueueMsgMetadata.java | 2 +- .../server/queue/sqs/TbAwsSqsAdmin.java | 2 +- .../queue/sqs/TbAwsSqsConsumerTemplate.java | 2 +- .../queue/sqs/TbAwsSqsProducerTemplate.java | 2 +- .../queue/sqs/TbAwsSqsQueueAttributes.java | 2 +- .../server/queue/sqs/TbAwsSqsSettings.java | 2 +- .../DefaultTbApiUsageReportClient.java | 2 +- .../server/queue/util/AfterContextReady.java | 2 +- .../server/queue/util/AfterStartUp.java | 2 +- .../queue/util/DataDecodingEncodingService.java | 2 +- .../server/queue/util/PropertyUtils.java | 2 +- .../server/queue/util/ProtoWithFSTService.java | 2 +- .../server/queue/util/TbCoreComponent.java | 2 +- .../util/TbLwM2mBootstrapTransportComponent.java | 2 +- .../queue/util/TbLwM2mTransportComponent.java | 2 +- .../server/queue/util/TbRuleEngineComponent.java | 2 +- .../queue/util/TbSnmpTransportComponent.java | 2 +- .../server/queue/util/TbTransportComponent.java | 2 +- .../queue/util/TbVersionControlComponent.java | 2 +- .../DefaultTbQueueRequestTemplateTest.java | 2 +- .../server/queue/discovery/QueueKeyTest.java | 2 +- .../queue/discovery/ZkDiscoveryServiceTest.java | 2 +- .../queue/kafka/TbKafkaProducerTemplateTest.java | 2 +- .../server/queue/kafka/TbKafkaSettingsTest.java | 2 +- .../queue/memory/DefaultInMemoryStorageTest.java | 2 +- .../server/queue/util/PropertyUtilsTest.java | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- .../server/service/script/JsExecutorService.java | 2 +- .../service/script/RemoteJsInvokeService.java | 2 +- .../service/script/RemoteJsRequestEncoder.java | 2 +- .../service/script/RemoteJsResponseDecoder.java | 2 +- common/script/script-api/pom.xml | 2 +- .../script/api/AbstractScriptInvokeService.java | 2 +- .../script/api/BlockedScriptInfo.java | 2 +- .../script/api/RuleNodeScriptFactory.java | 2 +- .../script/api/ScriptInvokeService.java | 2 +- .../script/api/ScriptStatCallback.java | 2 +- .../org/thingsboard/script/api/ScriptType.java | 2 +- .../script/api/TbScriptException.java | 2 +- .../script/api/TbScriptExecutionTask.java | 2 +- .../script/api/js/AbstractJsInvokeService.java | 2 +- .../script/api/js/JsInvokeService.java | 2 +- .../script/api/js/JsScriptExecutionTask.java | 2 +- .../thingsboard/script/api/js/JsScriptInfo.java | 2 +- .../script/api/js/NashornJsInvokeService.java | 2 +- .../script/api/tbel/DateTimeFormatOptions.java | 2 +- .../api/tbel/DefaultTbelInvokeService.java | 2 +- .../org/thingsboard/script/api/tbel/TbDate.java | 2 +- .../org/thingsboard/script/api/tbel/TbJson.java | 2 +- .../org/thingsboard/script/api/tbel/TbUtils.java | 2 +- .../script/api/tbel/TbelInvokeService.java | 2 +- .../thingsboard/script/api/tbel/TbelScript.java | 2 +- .../script/api/tbel/TbelScriptExecutionTask.java | 2 +- .../script/api/tbel/TbDateConstructorTest.java | 2 +- .../thingsboard/script/api/tbel/TbDateTest.java | 2 +- .../script/api/tbel/TbDateTestEntity.java | 2 +- .../thingsboard/script/api/tbel/TbUtilsTest.java | 2 +- common/stats/pom.xml | 2 +- .../server/common/stats/DefaultCounter.java | 2 +- .../common/stats/DefaultMessagesStats.java | 2 +- .../server/common/stats/DefaultStatsFactory.java | 2 +- .../server/common/stats/FstStatsServiceImpl.java | 2 +- .../server/common/stats/MessagesStats.java | 2 +- .../server/common/stats/StatsCounter.java | 2 +- .../server/common/stats/StatsFactory.java | 2 +- .../server/common/stats/StatsType.java | 2 +- .../common/stats/TbApiUsageReportClient.java | 2 +- .../common/stats/TbApiUsageStateClient.java | 2 +- common/transport/coap/pom.xml | 2 +- .../coap/AbstractCoapTransportResource.java | 2 +- .../transport/coap/CoapSessionMsgType.java | 2 +- .../transport/coap/CoapTransportContext.java | 2 +- .../transport/coap/CoapTransportResource.java | 2 +- .../transport/coap/CoapTransportService.java | 2 +- .../coap/OtaPackageTransportResource.java | 2 +- .../transport/coap/TbCoapMessageObserver.java | 2 +- .../coap/TransportConfigurationContainer.java | 2 +- .../coap/adaptors/CoapAdaptorUtils.java | 2 +- .../coap/adaptors/CoapTransportAdaptor.java | 2 +- .../transport/coap/adaptors/JsonCoapAdaptor.java | 2 +- .../coap/adaptors/ProtoCoapAdaptor.java | 2 +- .../callback/AbstractSyncSessionCallback.java | 2 +- .../coap/callback/CoapDeviceAuthCallback.java | 2 +- .../coap/callback/CoapEfentoCallback.java | 2 +- .../coap/callback/CoapNoOpCallback.java | 2 +- .../transport/coap/callback/CoapOkCallback.java | 2 +- .../GetAttributesSyncSessionCallback.java | 2 +- .../callback/ToServerRpcSyncSessionCallback.java | 2 +- .../transport/coap/client/CoapClientContext.java | 2 +- .../coap/client/DefaultCoapClientContext.java | 2 +- .../transport/coap/client/NoSecClient.java | 2 +- .../coap/client/NoSecObserveClient.java | 2 +- .../coap/client/SecureClientNoAuth.java | 2 +- .../transport/coap/client/SecureClientX509.java | 2 +- .../transport/coap/client/TbCoapClientState.java | 2 +- .../coap/client/TbCoapContentFormatUtil.java | 2 +- .../coap/client/TbCoapObservationState.java | 2 +- .../coap/efento/CoapEfentoTransportResource.java | 2 +- .../coap/efento/adaptor/EfentoCoapAdaptor.java | 2 +- .../coap/efento/utils/CoapEfentoUtils.java | 2 +- .../src/main/proto/efento/proto_config.proto | 2 +- .../main/proto/efento/proto_device_info.proto | 2 +- .../proto/efento/proto_measurement_types.proto | 2 +- .../main/proto/efento/proto_measurements.proto | 2 +- .../coap/src/main/proto/efento/proto_rule.proto | 2 +- .../coap/CoapTransportResourceTest.java | 2 +- common/transport/http/pom.xml | 2 +- .../transport/http/DeviceApiController.java | 2 +- .../transport/http/HttpTransportContext.java | 2 +- common/transport/lwm2m/pom.xml | 2 +- .../LwM2MTransportBootstrapService.java | 2 +- .../bootstrap/secure/LwM2MBootstrapConfig.java | 2 +- .../bootstrap/secure/LwM2MBootstrapServers.java | 2 +- .../bootstrap/secure/LwM2MServerBootstrap.java | 2 +- .../LwM2mDefaultBootstrapSessionManager.java | 2 +- .../TbLwM2MDtlsBootstrapCertificateVerifier.java | 2 +- .../store/LwM2MBootstrapClientInstanceIds.java | 2 +- .../LwM2MBootstrapConfigStoreTaskProvider.java | 2 +- .../store/LwM2MBootstrapSecurityStore.java | 2 +- .../store/LwM2MBootstrapTaskProvider.java | 2 +- .../store/LwM2MConfigurationChecker.java | 2 +- .../store/LwM2MInMemoryBootstrapConfigStore.java | 2 +- .../lwm2m/config/LwM2MSecureServerConfig.java | 2 +- .../config/LwM2MTransportBootstrapConfig.java | 2 +- .../lwm2m/config/LwM2MTransportServerConfig.java | 2 +- .../transport/lwm2m/config/TbLwM2mVersion.java | 2 +- .../LwM2mCredentialsSecurityInfoValidator.java | 2 +- .../lwm2m/secure/LwM2mRPkCredentials.java | 2 +- .../lwm2m/secure/TbLwM2MAuthorizer.java | 2 +- .../secure/TbLwM2MDtlsCertificateVerifier.java | 2 +- .../lwm2m/secure/TbLwM2MSecurityInfo.java | 2 +- .../lwm2m/secure/TbX509DtlsSessionInfo.java | 2 +- .../credentials/LwM2MClientCredentials.java | 2 +- .../server/AbstractLwM2mTransportResource.java | 2 +- .../server/DefaultLwM2mTransportService.java | 2 +- .../lwm2m/server/LwM2MNetworkConfig.java | 2 +- .../lwm2m/server/LwM2MOperationType.java | 2 +- .../lwm2m/server/LwM2MTransportService.java | 2 +- .../transport/lwm2m/server/LwM2mOtaConvert.java | 2 +- .../lwm2m/server/LwM2mQueuedRequest.java | 2 +- .../lwm2m/server/LwM2mServerListener.java | 2 +- .../lwm2m/server/LwM2mSessionMsgListener.java | 2 +- .../lwm2m/server/LwM2mTransportCoapResource.java | 2 +- .../lwm2m/server/LwM2mTransportContext.java | 2 +- .../lwm2m/server/LwM2mTransportServerHelper.java | 2 +- .../server/LwM2mVersionedModelProvider.java | 2 +- .../lwm2m/server/adaptors/LwM2MJsonAdaptor.java | 2 +- .../server/adaptors/LwM2MTransportAdaptor.java | 2 +- .../DefaultLwM2MAttributesService.java | 2 +- .../attributes/LwM2MAttributesService.java | 2 +- .../lwm2m/server/client/LwM2MAuthException.java | 2 +- .../lwm2m/server/client/LwM2MClientState.java | 2 +- .../server/client/LwM2MClientStateException.java | 2 +- .../lwm2m/server/client/LwM2mClient.java | 2 +- .../lwm2m/server/client/LwM2mClientContext.java | 2 +- .../server/client/LwM2mClientContextImpl.java | 2 +- .../lwm2m/server/client/ModelObject.java | 2 +- .../server/client/ParametersAnalyzeResult.java | 2 +- .../lwm2m/server/client/ResourceValue.java | 2 +- .../server/client/ResultsAddKeyValueProto.java | 2 +- .../server/common/LwM2MExecutorAwareService.java | 2 +- .../downlink/AbstractTbLwM2MRequestCallback.java | 2 +- .../AbstractTbLwM2MTargetedDownlinkRequest.java | 2 +- .../downlink/DefaultLwM2mDownlinkMsgHandler.java | 2 +- .../server/downlink/DownlinkRequestCallback.java | 2 +- .../lwm2m/server/downlink/HasContentFormat.java | 2 +- .../lwm2m/server/downlink/HasVersionedId.java | 2 +- .../lwm2m/server/downlink/HasVersionedIds.java | 2 +- .../server/downlink/LwM2mDownlinkMsgHandler.java | 2 +- .../TbLwM2MCancelAllObserveCallback.java | 2 +- .../server/downlink/TbLwM2MCancelAllRequest.java | 2 +- .../downlink/TbLwM2MCancelObserveCallback.java | 2 +- .../downlink/TbLwM2MCancelObserveRequest.java | 2 +- .../server/downlink/TbLwM2MCreateRequest.java | 2 +- .../downlink/TbLwM2MCreateResponseCallback.java | 2 +- .../server/downlink/TbLwM2MDeleteCallback.java | 2 +- .../server/downlink/TbLwM2MDeleteRequest.java | 2 +- .../downlink/TbLwM2MDiscoverAllRequest.java | 2 +- .../server/downlink/TbLwM2MDiscoverCallback.java | 2 +- .../server/downlink/TbLwM2MDiscoverRequest.java | 2 +- .../server/downlink/TbLwM2MDownlinkRequest.java | 2 +- .../server/downlink/TbLwM2MExecuteCallback.java | 2 +- .../server/downlink/TbLwM2MExecuteRequest.java | 2 +- .../server/downlink/TbLwM2MLatchCallback.java | 2 +- .../downlink/TbLwM2MObserveAllRequest.java | 2 +- .../server/downlink/TbLwM2MObserveCallback.java | 2 +- .../server/downlink/TbLwM2MObserveRequest.java | 2 +- .../server/downlink/TbLwM2MReadCallback.java | 2 +- .../server/downlink/TbLwM2MReadRequest.java | 2 +- .../server/downlink/TbLwM2MTargetedCallback.java | 2 +- .../downlink/TbLwM2MUplinkTargetedCallback.java | 2 +- .../downlink/TbLwM2MWriteAttributesCallback.java | 2 +- .../downlink/TbLwM2MWriteAttributesRequest.java | 2 +- .../downlink/TbLwM2MWriteReplaceRequest.java | 2 +- .../downlink/TbLwM2MWriteResponseCallback.java | 2 +- .../downlink/TbLwM2MWriteUpdateRequest.java | 2 +- ...tTbLwM2MTargetedDownlinkCompositeRequest.java | 2 +- .../composite/TbLwM2MReadCompositeCallback.java | 2 +- .../composite/TbLwM2MReadCompositeRequest.java | 2 +- .../composite/TbLwM2MWriteCompositeRequest.java | 2 +- .../TbLwM2MWriteResponseCompositeCallback.java | 2 +- .../log/DefaultLwM2MTelemetryLogService.java | 2 +- .../server/log/LwM2MTelemetryLogService.java | 2 +- .../lwm2m/server/model/LwM2MModelConfig.java | 2 +- .../server/model/LwM2MModelConfigService.java | 2 +- .../model/LwM2MModelConfigServiceImpl.java | 2 +- .../server/ota/DefaultLwM2MOtaUpdateService.java | 2 +- .../lwm2m/server/ota/LwM2MClientOtaInfo.java | 2 +- .../lwm2m/server/ota/LwM2MClientOtaState.java | 2 +- .../lwm2m/server/ota/LwM2MOtaUpdateService.java | 2 +- .../ota/firmware/FirmwareDeliveryMethod.java | 2 +- .../ota/firmware/FirmwareUpdateResult.java | 2 +- .../server/ota/firmware/FirmwareUpdateState.java | 2 +- .../ota/firmware/LwM2MClientFwOtaInfo.java | 2 +- .../firmware/LwM2MFirmwareUpdateStrategy.java | 2 +- .../ota/software/LwM2MClientSwOtaInfo.java | 2 +- .../software/LwM2MSoftwareUpdateStrategy.java | 2 +- .../ota/software/SoftwareUpdateResult.java | 2 +- .../server/ota/software/SoftwareUpdateState.java | 2 +- .../rpc/DefaultLwM2MRpcRequestHandler.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcRequestHandler.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcRequestHeader.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcResponseBody.java | 2 +- .../server/rpc/RpcCancelAllObserveCallback.java | 2 +- .../server/rpc/RpcCancelObserveCallback.java | 2 +- .../lwm2m/server/rpc/RpcCreateRequest.java | 2 +- .../server/rpc/RpcCreateResponseCallback.java | 2 +- .../lwm2m/server/rpc/RpcDiscoverCallback.java | 2 +- .../rpc/RpcDownlinkRequestCallbackProxy.java | 2 +- .../server/rpc/RpcEmptyResponseCallback.java | 2 +- .../lwm2m/server/rpc/RpcLinkSetCallback.java | 2 +- .../server/rpc/RpcLwM2MDownlinkCallback.java | 2 +- .../server/rpc/RpcReadResponseCallback.java | 2 +- .../server/rpc/RpcWriteAttributesRequest.java | 2 +- .../lwm2m/server/rpc/RpcWriteReplaceRequest.java | 2 +- .../lwm2m/server/rpc/RpcWriteUpdateRequest.java | 2 +- .../rpc/composite/RpcReadCompositeRequest.java | 2 +- .../RpcReadResponseCompositeCallback.java | 2 +- .../rpc/composite/RpcWriteCompositeRequest.java | 2 +- .../session/DefaultLwM2MSessionManager.java | 2 +- .../server/session/LwM2MSessionManager.java | 2 +- .../store/TbDummyLwM2MClientOtaInfoStore.java | 2 +- .../server/store/TbDummyLwM2MClientStore.java | 2 +- .../store/TbDummyLwM2MModelConfigStore.java | 2 +- .../server/store/TbEditableSecurityStore.java | 2 +- .../server/store/TbInMemorySecurityStore.java | 2 +- .../store/TbL2M2MDtlsSessionInMemoryStore.java | 2 +- .../server/store/TbLwM2MClientOtaInfoStore.java | 2 +- .../lwm2m/server/store/TbLwM2MClientStore.java | 2 +- .../store/TbLwM2MDtlsSessionRedisStore.java | 2 +- .../server/store/TbLwM2MDtlsSessionStore.java | 2 +- .../server/store/TbLwM2MModelConfigStore.java | 2 +- .../store/TbLwM2mRedisClientOtaInfoStore.java | 2 +- .../store/TbLwM2mRedisRegistrationStore.java | 2 +- .../server/store/TbLwM2mRedisSecurityStore.java | 2 +- .../lwm2m/server/store/TbLwM2mSecurityStore.java | 2 +- .../lwm2m/server/store/TbLwM2mStoreFactory.java | 2 +- .../lwm2m/server/store/TbMainSecurityStore.java | 2 +- .../server/store/TbRedisLwM2MClientStore.java | 2 +- .../store/TbRedisLwM2MModelConfigStore.java | 2 +- .../lwm2m/server/store/TbSecurityStore.java | 2 +- .../server/store/util/LwM2MClientSerDes.java | 2 +- .../uplink/DefaultLwM2mUplinkMsgHandler.java | 2 +- .../lwm2m/server/uplink/LwM2mTypeServer.java | 2 +- .../server/uplink/LwM2mUplinkMsgHandler.java | 2 +- .../lwm2m/utils/LwM2MTransportUtil.java | 2 +- .../lwm2m/utils/LwM2mValueConverterImpl.java | 2 +- .../model/LwM2MModelConfigServiceImplTest.java | 2 +- .../lwm2m/server/client/LwM2mClientTest.java | 2 +- .../server/store/util/LwM2MClientSerDesTest.java | 2 +- common/transport/mqtt/pom.xml | 2 +- .../transport/mqtt/MqttSslHandlerProvider.java | 2 +- .../transport/mqtt/MqttTransportContext.java | 2 +- .../transport/mqtt/MqttTransportHandler.java | 2 +- .../mqtt/MqttTransportServerInitializer.java | 2 +- .../transport/mqtt/MqttTransportService.java | 2 +- .../server/transport/mqtt/TopicType.java | 2 +- .../adaptors/BackwardCompatibilityAdaptor.java | 2 +- .../transport/mqtt/adaptors/JsonMqttAdaptor.java | 2 +- .../mqtt/adaptors/MqttTransportAdaptor.java | 2 +- .../mqtt/adaptors/ProtoMqttAdaptor.java | 2 +- .../server/transport/mqtt/limits/IpFilter.java | 2 +- .../transport/mqtt/limits/ProxyIpFilter.java | 2 +- .../AbstractGatewayDeviceSessionContext.java | 2 +- .../session/AbstractGatewaySessionHandler.java | 2 +- .../transport/mqtt/session/DeviceSessionCtx.java | 2 +- .../session/GatewayDeviceSessionContext.java | 2 +- .../mqtt/session/GatewaySessionHandler.java | 2 +- .../session/MqttDeviceAwareSessionContext.java | 2 +- .../transport/mqtt/session/MqttTopicMatcher.java | 2 +- .../session/SparkplugDeviceSessionContext.java | 2 +- .../session/SparkplugNodeSessionHandler.java | 2 +- .../mqtt/util/AlwaysTrueTopicFilter.java | 2 +- .../transport/mqtt/util/EqualsTopicFilter.java | 2 +- .../transport/mqtt/util/MqttTopicFilter.java | 2 +- .../mqtt/util/MqttTopicFilterFactory.java | 2 +- .../transport/mqtt/util/RegexTopicFilter.java | 2 +- .../server/transport/mqtt/util/ReturnCode.java | 2 +- .../transport/mqtt/util/ReturnCodeResolver.java | 2 +- .../mqtt/util/sparkplug/MetricDataType.java | 2 +- .../util/sparkplug/SparkplugConnectionState.java | 2 +- .../util/sparkplug/SparkplugMessageType.java | 2 +- .../mqtt/util/sparkplug/SparkplugMetricUtil.java | 2 +- .../sparkplug/SparkplugRpcRequestHeader.java | 2 +- .../util/sparkplug/SparkplugRpcResponseBody.java | 2 +- .../mqtt/util/sparkplug/SparkplugTopic.java | 2 +- .../mqtt/util/sparkplug/SparkplugTopicUtil.java | 2 +- .../mqtt/src/main/proto/sparkplug.proto | 2 +- .../transport/mqtt/MqttTransportHandlerTest.java | 2 +- .../mqtt/session/GatewaySessionHandlerTest.java | 2 +- .../mqtt/util/MqttTopicFilterFactoryTest.java | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- .../transport/snmp/SnmpTransportContext.java | 2 +- .../event/ServiceListChangedEventListener.java | 2 +- .../event/SnmpTransportListChangedEvent.java | 2 +- .../SnmpTransportListChangedEventListener.java | 2 +- .../transport/snmp/service/PduService.java | 2 +- .../service/ProtoTransportEntityService.java | 2 +- .../transport/snmp/service/SnmpAuthService.java | 2 +- .../service/SnmpTransportBalancingService.java | 2 +- .../snmp/service/SnmpTransportService.java | 2 +- .../snmp/session/DeviceSessionContext.java | 2 +- .../transport/snmp/SnmpDeviceSimulatorV2.java | 2 +- .../transport/snmp/SnmpDeviceSimulatorV3.java | 2 +- .../server/transport/snmp/SnmpTestV2.java | 2 +- .../server/transport/snmp/SnmpTestV3.java | 2 +- common/transport/transport-api/pom.xml | 2 +- .../common/transport/DeviceDeletedEvent.java | 2 +- .../transport/DeviceProfileUpdatedEvent.java | 2 +- .../common/transport/DeviceUpdatedEvent.java | 2 +- .../common/transport/SessionMsgListener.java | 2 +- .../common/transport/TransportAdaptor.java | 2 +- .../common/transport/TransportContext.java | 2 +- .../transport/TransportDeviceProfileCache.java | 2 +- .../common/transport/TransportResourceCache.java | 2 +- .../common/transport/TransportService.java | 2 +- .../transport/TransportServiceCallback.java | 2 +- .../transport/TransportTenantProfileCache.java | 2 +- .../common/transport/auth/DeviceAuthResult.java | 2 +- .../common/transport/auth/DeviceAuthService.java | 2 +- .../transport/auth/DeviceProfileAware.java | 2 +- .../GetOrCreateDeviceFromGatewayResponse.java | 2 +- .../transport/auth/SessionInfoCreator.java | 2 +- .../transport/auth/TransportDeviceInfo.java | 2 +- .../auth/ValidateDeviceCredentialsResponse.java | 2 +- .../config/ssl/AbstractSslCredentials.java | 2 +- .../config/ssl/KeystoreSslCredentials.java | 2 +- .../transport/config/ssl/PemSslCredentials.java | 2 +- .../transport/config/ssl/SslCredentials.java | 2 +- .../config/ssl/SslCredentialsConfig.java | 2 +- .../transport/config/ssl/SslCredentialsType.java | 2 +- .../ssl/SslCredentialsWebServerCustomizer.java | 2 +- .../limits/DefaultEntityLimitsCache.java | 2 +- .../limits/DefaultTransportRateLimitService.java | 2 +- .../limits/DummyTransportRateLimit.java | 2 +- .../common/transport/limits/EntityLimitKey.java | 2 +- .../transport/limits/EntityLimitsCache.java | 2 +- .../limits/EntityTransportRateLimits.java | 2 +- .../limits/InetAddressRateLimitStats.java | 2 +- .../limits/SimpleTransportRateLimit.java | 2 +- .../transport/limits/TransportRateLimit.java | 2 +- .../limits/TransportRateLimitService.java | 2 +- .../profile/TenantProfileUpdateResult.java | 2 +- .../DefaultTransportDeviceProfileCache.java | 2 +- .../service/DefaultTransportResourceCache.java | 2 +- .../service/DefaultTransportService.java | 2 +- .../DefaultTransportTenantProfileCache.java | 2 +- .../transport/service/RpcRequestMetadata.java | 2 +- .../transport/service/SessionActivityData.java | 2 +- .../transport/service/SessionMetaData.java | 2 +- .../service/ToRuleEngineMsgEncoder.java | 2 +- .../service/ToTransportMsgResponseDecoder.java | 2 +- .../service/TransportApiRequestEncoder.java | 2 +- .../service/TransportApiResponseDecoder.java | 2 +- .../TransportQueueRoutingInfoService.java | 2 +- .../TransportTenantRoutingInfoService.java | 2 +- .../session/DeviceAwareSessionContext.java | 2 +- .../common/transport/session/SessionContext.java | 2 +- .../server/common/transport/util/JsonUtils.java | 2 +- .../server/common/transport/util/SslUtil.java | 2 +- common/util/pom.xml | 2 +- .../common/util/AbstractListeningExecutor.java | 2 +- .../thingsboard/common/util/AzureIotHubUtil.java | 2 +- .../thingsboard/common/util/DonAsynchron.java | 2 +- .../thingsboard/common/util/ExceptionUtil.java | 2 +- .../common/util/ExecutorProvider.java | 2 +- .../org/thingsboard/common/util/JacksonUtil.java | 2 +- .../java/org/thingsboard/common/util/KvUtil.java | 2 +- .../common/util/LinkedHashMapRemoveEldest.java | 2 +- .../common/util/ListeningExecutor.java | 2 +- .../org/thingsboard/common/util/RegexUtils.java | 2 +- .../org/thingsboard/common/util/SslUtil.java | 2 +- .../org/thingsboard/common/util/SystemUtil.java | 2 +- .../org/thingsboard/common/util/TbStopWatch.java | 2 +- .../common/util/ThingsBoardExecutors.java | 2 +- .../ThingsBoardForkJoinWorkerThreadFactory.java | 2 +- .../common/util/ThingsBoardThreadFactory.java | 2 +- .../common/util/ExceptionUtilTest.java | 2 +- .../thingsboard/common/util/JacksonUtilTest.java | 2 +- .../util/LinkedHashMapRemoveEldestTest.java | 2 +- common/version-control/pom.xml | 2 +- .../sync/vc/ClusterVersionControlService.java | 2 +- .../vc/DefaultClusterVersionControlService.java | 2 +- .../sync/vc/DefaultGitRepositoryService.java | 2 +- .../server/service/sync/vc/GitRepository.java | 2 +- .../service/sync/vc/GitRepositoryService.java | 2 +- .../server/service/sync/vc/PendingCommit.java | 2 +- .../sync/vc/VersionControlRequestCtx.java | 2 +- dao/pom.xml | 2 +- .../java/org/thingsboard/server/dao/Dao.java | 2 +- .../java/org/thingsboard/server/dao/DaoUtil.java | 2 +- .../server/dao/ExportableEntityDao.java | 2 +- .../server/dao/ExportableEntityRepository.java | 2 +- .../server/dao/ImageContainerDao.java | 2 +- .../org/thingsboard/server/dao/JpaDaoConfig.java | 2 +- .../server/dao/SqlTimeseriesDaoConfig.java | 2 +- .../thingsboard/server/dao/SqlTsDaoConfig.java | 2 +- .../server/dao/SqlTsLatestDaoConfig.java | 2 +- .../thingsboard/server/dao/TenantEntityDao.java | 2 +- .../server/dao/TenantEntityWithDataDao.java | 2 +- .../server/dao/ThingsboardPostgreSQLDialect.java | 2 +- .../server/dao/TimescaleDaoConfig.java | 2 +- .../server/dao/TimescaleTsLatestDaoConfig.java | 2 +- .../server/dao/alarm/AlarmCommentDao.java | 2 +- .../thingsboard/server/dao/alarm/AlarmDao.java | 2 +- .../dao/alarm/AlarmTypesCacheEvictEvent.java | 2 +- .../dao/alarm/AlarmTypesCaffeineCache.java | 2 +- .../server/dao/alarm/AlarmTypesRedisCache.java | 2 +- .../dao/alarm/BaseAlarmCommentService.java | 2 +- .../server/dao/alarm/BaseAlarmService.java | 2 +- .../server/dao/aspect/DbCallStats.java | 2 +- .../server/dao/aspect/DbCallStatsSnapshot.java | 2 +- .../server/dao/aspect/MethodCallStats.java | 2 +- .../dao/aspect/MethodCallStatsSnapshot.java | 2 +- .../server/dao/aspect/SqlDaoCallsAspect.java | 2 +- .../server/dao/asset/AssetCacheEvictEvent.java | 2 +- .../server/dao/asset/AssetCacheKey.java | 2 +- .../server/dao/asset/AssetCaffeineCache.java | 2 +- .../thingsboard/server/dao/asset/AssetDao.java | 2 +- .../server/dao/asset/AssetProfileCacheKey.java | 2 +- .../dao/asset/AssetProfileCaffeineCache.java | 2 +- .../server/dao/asset/AssetProfileDao.java | 2 +- .../server/dao/asset/AssetProfileEvictEvent.java | 2 +- .../server/dao/asset/AssetProfileRedisCache.java | 2 +- .../dao/asset/AssetProfileServiceImpl.java | 2 +- .../server/dao/asset/AssetRedisCache.java | 2 +- .../server/dao/asset/AssetTypeFilter.java | 2 +- .../server/dao/asset/BaseAssetService.java | 2 +- .../server/dao/attributes/AttributeCacheKey.java | 2 +- .../dao/attributes/AttributeCaffeineCache.java | 2 +- .../dao/attributes/AttributeRedisCache.java | 2 +- .../server/dao/attributes/AttributeUtils.java | 2 +- .../server/dao/attributes/AttributesDao.java | 2 +- .../dao/attributes/BaseAttributesService.java | 2 +- .../dao/attributes/CachedAttributesService.java | 2 +- .../server/dao/audit/AuditLogDao.java | 2 +- .../server/dao/audit/AuditLogLevelFilter.java | 2 +- .../server/dao/audit/AuditLogLevelMask.java | 2 +- .../dao/audit/AuditLogLevelProperties.java | 2 +- .../server/dao/audit/AuditLogServiceImpl.java | 2 +- .../dao/audit/DummyAuditLogServiceImpl.java | 2 +- .../server/dao/audit/sink/AuditLogSink.java | 2 +- .../server/dao/audit/sink/DummyAuditLogSink.java | 2 +- .../audit/sink/ElasticsearchAuditLogSink.java | 2 +- .../server/dao/cache/CacheExecutorService.java | 2 +- .../BaseComponentDescriptorService.java | 2 +- .../dao/component/ComponentDescriptorDao.java | 2 +- .../server/dao/customer/CustomerDao.java | 2 +- .../server/dao/customer/CustomerServiceImpl.java | 2 +- .../server/dao/dashboard/DashboardDao.java | 2 +- .../server/dao/dashboard/DashboardInfoDao.java | 2 +- .../dao/dashboard/DashboardServiceImpl.java | 2 +- .../dao/dashboard/DashboardTitleEvictEvent.java | 2 +- .../dashboard/DashboardTitlesCaffeineCache.java | 2 +- .../dao/dashboard/DashboardTitlesRedisCache.java | 2 +- .../server/dao/device/ClaimDataInfo.java | 2 +- .../device/DeviceConnectivityConfiguration.java | 2 +- .../dao/device/DeviceConnectivityInfo.java | 2 +- .../device/DeviceConnectivityServiceImpl.java | 2 +- .../device/DeviceCredentialsCaffeineCache.java | 2 +- .../server/dao/device/DeviceCredentialsDao.java | 2 +- .../dao/device/DeviceCredentialsEvictEvent.java | 2 +- .../dao/device/DeviceCredentialsRedisCache.java | 2 +- .../dao/device/DeviceCredentialsServiceImpl.java | 2 +- .../thingsboard/server/dao/device/DeviceDao.java | 2 +- .../server/dao/device/DeviceProfileCacheKey.java | 2 +- .../dao/device/DeviceProfileCaffeineCache.java | 2 +- .../server/dao/device/DeviceProfileDao.java | 2 +- .../dao/device/DeviceProfileEvictEvent.java | 2 +- .../dao/device/DeviceProfileRedisCache.java | 2 +- .../dao/device/DeviceProfileServiceImpl.java | 2 +- .../server/dao/device/DeviceServiceImpl.java | 2 +- .../server/dao/edge/BaseEdgeEventService.java | 2 +- .../edge/DefaultEdgeSynchronizationManager.java | 2 +- .../server/dao/edge/EdgeCacheEvictEvent.java | 2 +- .../server/dao/edge/EdgeCacheKey.java | 2 +- .../server/dao/edge/EdgeCaffeineCache.java | 2 +- .../org/thingsboard/server/dao/edge/EdgeDao.java | 2 +- .../server/dao/edge/EdgeEventDao.java | 2 +- .../server/dao/edge/EdgeRedisCache.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../dao/entity/AbstractCachedEntityService.java | 2 +- .../server/dao/entity/AbstractCachedService.java | 2 +- .../server/dao/entity/AbstractEntityService.java | 2 +- .../dao/entity/BaseEntityCountService.java | 2 +- .../server/dao/entity/BaseEntityService.java | 2 +- .../dao/entity/DefaultEntityServiceRegistry.java | 2 +- .../dao/entity/EntityCountCacheEvictEvent.java | 2 +- .../server/dao/entity/EntityCountCacheKey.java | 2 +- .../server/dao/entity/EntityQueryDao.java | 2 +- .../entity/count/EntityCountCaffeineCache.java | 2 +- .../dao/entity/count/EntityCountRedisCache.java | 2 +- .../dao/entityview/EntityViewCacheKey.java | 2 +- .../dao/entityview/EntityViewCacheValue.java | 2 +- .../dao/entityview/EntityViewCaffeineCache.java | 2 +- .../server/dao/entityview/EntityViewDao.java | 2 +- .../dao/entityview/EntityViewEvictEvent.java | 2 +- .../dao/entityview/EntityViewRedisCache.java | 2 +- .../dao/entityview/EntityViewServiceImpl.java | 2 +- .../server/dao/event/BaseEventService.java | 2 +- .../thingsboard/server/dao/event/EventDao.java | 2 +- .../dao/eventsourcing/ActionEntityEvent.java | 2 +- .../dao/eventsourcing/DeleteEntityEvent.java | 2 +- .../dao/eventsourcing/RelationActionEvent.java | 2 +- .../dao/eventsourcing/SaveEntityEvent.java | 2 +- .../dao/exception/BufferLimitException.java | 2 +- .../dao/exception/DataValidationException.java | 2 +- .../server/dao/exception/DatabaseException.java | 2 +- .../DeviceCredentialsValidationException.java | 2 +- .../dao/exception/EntitiesLimitException.java | 2 +- .../exception/IncorrectParameterException.java | 2 +- .../thingsboard/server/dao/model/BaseEntity.java | 2 +- .../server/dao/model/BaseSqlEntity.java | 2 +- .../server/dao/model/ModelConstants.java | 2 +- .../org/thingsboard/server/dao/model/ToData.java | 2 +- .../model/sql/AbstractAlarmCommentEntity.java | 2 +- .../dao/model/sql/AbstractAlarmEntity.java | 2 +- .../dao/model/sql/AbstractAssetEntity.java | 2 +- .../dao/model/sql/AbstractDeviceEntity.java | 2 +- .../server/dao/model/sql/AbstractEdgeEntity.java | 2 +- .../dao/model/sql/AbstractEntityViewEntity.java | 2 +- .../dao/model/sql/AbstractTenantEntity.java | 2 +- .../server/dao/model/sql/AbstractTsKvEntity.java | 2 +- .../dao/model/sql/AbstractWidgetTypeEntity.java | 2 +- .../dao/model/sql/AdminSettingsEntity.java | 2 +- .../server/dao/model/sql/AlarmCommentEntity.java | 2 +- .../dao/model/sql/AlarmCommentInfoEntity.java | 2 +- .../server/dao/model/sql/AlarmEntity.java | 2 +- .../server/dao/model/sql/AlarmInfoEntity.java | 2 +- .../dao/model/sql/ApiUsageStateEntity.java | 2 +- .../server/dao/model/sql/AssetEntity.java | 2 +- .../server/dao/model/sql/AssetInfoEntity.java | 2 +- .../server/dao/model/sql/AssetProfileEntity.java | 2 +- .../dao/model/sql/AttributeKvCompositeKey.java | 2 +- .../server/dao/model/sql/AttributeKvEntity.java | 2 +- .../server/dao/model/sql/AuditLogEntity.java | 2 +- .../dao/model/sql/ComponentDescriptorEntity.java | 2 +- .../server/dao/model/sql/CustomerEntity.java | 2 +- .../server/dao/model/sql/DashboardEntity.java | 2 +- .../dao/model/sql/DashboardInfoEntity.java | 2 +- .../dao/model/sql/DeviceCredentialsEntity.java | 2 +- .../server/dao/model/sql/DeviceEntity.java | 2 +- .../server/dao/model/sql/DeviceInfoEntity.java | 2 +- .../dao/model/sql/DeviceProfileEntity.java | 2 +- .../server/dao/model/sql/EdgeEntity.java | 2 +- .../server/dao/model/sql/EdgeEventEntity.java | 2 +- .../server/dao/model/sql/EdgeInfoEntity.java | 2 +- .../dao/model/sql/EntityAlarmCompositeKey.java | 2 +- .../server/dao/model/sql/EntityAlarmEntity.java | 2 +- .../server/dao/model/sql/EntityViewEntity.java | 2 +- .../dao/model/sql/EntityViewInfoEntity.java | 2 +- .../server/dao/model/sql/ErrorEventEntity.java | 2 +- .../server/dao/model/sql/EventEntity.java | 2 +- .../dao/model/sql/LifecycleEventEntity.java | 2 +- .../server/dao/model/sql/NotificationEntity.java | 2 +- .../dao/model/sql/NotificationRequestEntity.java | 2 +- .../model/sql/NotificationRequestInfoEntity.java | 2 +- .../dao/model/sql/NotificationRuleEntity.java | 2 +- .../model/sql/NotificationRuleInfoEntity.java | 2 +- .../dao/model/sql/NotificationTargetEntity.java | 2 +- .../model/sql/NotificationTemplateEntity.java | 2 +- .../OAuth2ClientRegistrationTemplateEntity.java | 2 +- .../server/dao/model/sql/OAuth2DomainEntity.java | 2 +- .../server/dao/model/sql/OAuth2MobileEntity.java | 2 +- .../server/dao/model/sql/OAuth2ParamsEntity.java | 2 +- .../dao/model/sql/OAuth2RegistrationEntity.java | 2 +- .../server/dao/model/sql/OtaPackageEntity.java | 2 +- .../dao/model/sql/OtaPackageInfoEntity.java | 2 +- .../server/dao/model/sql/QueueEntity.java | 2 +- .../dao/model/sql/RelationCompositeKey.java | 2 +- .../server/dao/model/sql/RelationEntity.java | 2 +- .../server/dao/model/sql/RpcEntity.java | 2 +- .../dao/model/sql/RuleChainDebugEventEntity.java | 2 +- .../server/dao/model/sql/RuleChainEntity.java | 2 +- .../dao/model/sql/RuleNodeDebugEventEntity.java | 2 +- .../server/dao/model/sql/RuleNodeEntity.java | 2 +- .../dao/model/sql/RuleNodeStateEntity.java | 2 +- .../dao/model/sql/StatisticsEventEntity.java | 2 +- .../server/dao/model/sql/TbResourceEntity.java | 2 +- .../dao/model/sql/TbResourceInfoEntity.java | 2 +- .../server/dao/model/sql/TenantEntity.java | 2 +- .../server/dao/model/sql/TenantInfoEntity.java | 2 +- .../dao/model/sql/TenantProfileEntity.java | 2 +- .../dao/model/sql/UserAuthSettingsEntity.java | 2 +- .../dao/model/sql/UserCredentialsEntity.java | 2 +- .../server/dao/model/sql/UserEntity.java | 2 +- .../server/dao/model/sql/UserSettingsEntity.java | 2 +- .../dao/model/sql/WidgetTypeDetailsEntity.java | 2 +- .../server/dao/model/sql/WidgetTypeEntity.java | 2 +- .../dao/model/sql/WidgetTypeIdFqnEntity.java | 2 +- .../dao/model/sql/WidgetTypeInfoEntity.java | 2 +- .../dao/model/sql/WidgetsBundleEntity.java | 2 +- .../sql/WidgetsBundleWidgetCompositeKey.java | 2 +- .../dao/model/sql/WidgetsBundleWidgetEntity.java | 2 +- .../model/sqlts/dictionary/TsKvDictionary.java | 2 +- .../dictionary/TsKvDictionaryCompositeKey.java | 2 +- .../sqlts/latest/TsKvLatestCompositeKey.java | 2 +- .../dao/model/sqlts/latest/TsKvLatestEntity.java | 2 +- .../timescale/ts/TimescaleTsKvCompositeKey.java | 2 +- .../sqlts/timescale/ts/TimescaleTsKvEntity.java | 2 +- .../dao/model/sqlts/ts/TsKvCompositeKey.java | 2 +- .../server/dao/model/sqlts/ts/TsKvEntity.java | 2 +- .../dao/nosql/CassandraAbstractAsyncDao.java | 2 +- .../server/dao/nosql/CassandraAbstractDao.java | 2 +- .../nosql/CassandraBufferedRateReadExecutor.java | 2 +- .../CassandraBufferedRateWriteExecutor.java | 2 +- .../DefaultNotificationRequestService.java | 2 +- .../DefaultNotificationRuleService.java | 2 +- .../notification/DefaultNotificationService.java | 2 +- .../DefaultNotificationSettingsService.java | 2 +- .../DefaultNotificationTargetService.java | 2 +- .../DefaultNotificationTemplateService.java | 2 +- .../dao/notification/DefaultNotifications.java | 2 +- .../server/dao/notification/NotificationDao.java | 2 +- .../dao/notification/NotificationRequestDao.java | 2 +- .../dao/notification/NotificationRuleDao.java | 2 +- .../dao/notification/NotificationTargetDao.java | 2 +- .../notification/NotificationTemplateDao.java | 2 +- .../HybridClientRegistrationRepository.java | 2 +- .../OAuth2ClientRegistrationTemplateDao.java | 2 +- .../oauth2/OAuth2ConfigTemplateServiceImpl.java | 2 +- .../server/dao/oauth2/OAuth2Configuration.java | 2 +- .../server/dao/oauth2/OAuth2DomainDao.java | 2 +- .../server/dao/oauth2/OAuth2MobileDao.java | 2 +- .../server/dao/oauth2/OAuth2ParamsDao.java | 2 +- .../server/dao/oauth2/OAuth2RegistrationDao.java | 2 +- .../server/dao/oauth2/OAuth2ServiceImpl.java | 2 +- .../server/dao/oauth2/OAuth2Utils.java | 2 +- .../server/dao/ota/BaseOtaPackageService.java | 2 +- .../dao/ota/OtaPackageCacheEvictEvent.java | 2 +- .../server/dao/ota/OtaPackageCacheKey.java | 2 +- .../server/dao/ota/OtaPackageCaffeineCache.java | 2 +- .../server/dao/ota/OtaPackageDao.java | 2 +- .../server/dao/ota/OtaPackageInfoDao.java | 2 +- .../server/dao/ota/OtaPackageRedisCache.java | 2 +- .../server/dao/queue/BaseQueueService.java | 2 +- .../thingsboard/server/dao/queue/QueueDao.java | 2 +- .../server/dao/relation/BaseRelationService.java | 2 +- .../server/dao/relation/EntityRelationEvent.java | 2 +- .../server/dao/relation/RelationCacheKey.java | 2 +- .../server/dao/relation/RelationCacheValue.java | 2 +- .../dao/relation/RelationCaffeineCache.java | 2 +- .../server/dao/relation/RelationDao.java | 2 +- .../server/dao/relation/RelationRedisCache.java | 2 +- .../server/dao/resource/BaseImageService.java | 2 +- .../server/dao/resource/BaseResourceService.java | 2 +- .../server/dao/resource/ImageCacheKey.java | 2 +- .../server/dao/resource/TbResourceDao.java | 2 +- .../server/dao/resource/TbResourceInfoDao.java | 2 +- .../server/dao/rpc/BaseRpcService.java | 2 +- .../org/thingsboard/server/dao/rpc/RpcDao.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 2 +- .../dao/rule/BaseRuleNodeStateService.java | 2 +- .../server/dao/rule/RuleChainDao.java | 2 +- .../thingsboard/server/dao/rule/RuleNodeDao.java | 2 +- .../server/dao/rule/RuleNodeStateDao.java | 2 +- .../server/dao/service/ConstraintValidator.java | 2 +- .../server/dao/service/DataValidator.java | 2 +- .../server/dao/service/NoXssValidator.java | 2 +- .../server/dao/service/PaginatedRemover.java | 2 +- .../dao/service/StringLengthValidator.java | 2 +- .../server/dao/service/TimePaginatedRemover.java | 2 +- .../server/dao/service/Validator.java | 2 +- .../AbstractHasOtaPackageValidator.java | 2 +- .../validator/AdminSettingsDataValidator.java | 2 +- .../validator/AlarmCommentDataValidator.java | 2 +- .../service/validator/AlarmDataValidator.java | 2 +- .../service/validator/ApiUsageDataValidator.java | 2 +- .../service/validator/AssetDataValidator.java | 2 +- .../validator/AssetProfileDataValidator.java | 2 +- .../service/validator/AuditLogDataValidator.java | 2 +- .../validator/BaseOtaPackageDataValidator.java | 2 +- .../ClientRegistrationTemplateDataValidator.java | 2 +- .../ComponentDescriptorDataValidator.java | 2 +- .../service/validator/CustomerDataValidator.java | 2 +- .../validator/DashboardDataValidator.java | 2 +- .../DeviceCredentialsDataValidator.java | 2 +- .../service/validator/DeviceDataValidator.java | 2 +- .../validator/DeviceProfileDataValidator.java | 2 +- .../dao/service/validator/EdgeDataValidator.java | 2 +- .../validator/EdgeEventDataValidator.java | 2 +- .../validator/EntityViewDataValidator.java | 2 +- .../service/validator/EventDataValidator.java | 2 +- .../validator/OtaPackageDataValidator.java | 2 +- .../validator/OtaPackageInfoDataValidator.java | 2 +- .../dao/service/validator/QueueValidator.java | 2 +- .../service/validator/ResourceDataValidator.java | 2 +- .../validator/RuleChainDataValidator.java | 2 +- .../service/validator/TenantDataValidator.java | 2 +- .../validator/TenantProfileDataValidator.java | 2 +- .../validator/UserCredentialsDataValidator.java | 2 +- .../dao/service/validator/UserDataValidator.java | 2 +- .../validator/WidgetTypeDataValidator.java | 2 +- .../validator/WidgetsBundleDataValidator.java | 2 +- .../server/dao/settings/AdminSettingsDao.java | 2 +- .../dao/settings/AdminSettingsServiceImpl.java | 2 +- .../server/dao/sql/JpaAbstractDao.java | 2 +- .../JpaAbstractDaoListeningExecutorService.java | 2 +- .../server/dao/sql/JpaExecutorService.java | 2 +- .../dao/sql/ScheduledLogExecutorComponent.java | 2 +- .../server/dao/sql/TbSqlBlockingQueue.java | 2 +- .../server/dao/sql/TbSqlBlockingQueueParams.java | 2 +- .../dao/sql/TbSqlBlockingQueueWrapper.java | 2 +- .../thingsboard/server/dao/sql/TbSqlQueue.java | 2 +- .../server/dao/sql/TbSqlQueueElement.java | 2 +- .../dao/sql/alarm/AlarmCommentRepository.java | 2 +- .../server/dao/sql/alarm/AlarmRepository.java | 2 +- .../dao/sql/alarm/EntityAlarmRepository.java | 2 +- .../server/dao/sql/alarm/JpaAlarmCommentDao.java | 2 +- .../server/dao/sql/alarm/JpaAlarmDao.java | 2 +- .../dao/sql/asset/AssetProfileRepository.java | 2 +- .../server/dao/sql/asset/AssetRepository.java | 2 +- .../server/dao/sql/asset/JpaAssetDao.java | 2 +- .../server/dao/sql/asset/JpaAssetProfileDao.java | 2 +- .../attributes/AttributeKvInsertRepository.java | 2 +- .../sql/attributes/AttributeKvRepository.java | 2 +- .../dao/sql/attributes/JpaAttributeDao.java | 2 +- .../SqlAttributesInsertRepository.java | 2 +- .../server/dao/sql/audit/AuditLogRepository.java | 2 +- .../server/dao/sql/audit/JpaAuditLogDao.java | 2 +- ...tractComponentDescriptorInsertRepository.java | 2 +- .../ComponentDescriptorInsertRepository.java | 2 +- .../component/ComponentDescriptorRepository.java | 2 +- .../component/JpaBaseComponentDescriptorDao.java | 2 +- .../SqlComponentDescriptorInsertRepository.java | 2 +- .../dao/sql/customer/CustomerRepository.java | 2 +- .../server/dao/sql/customer/JpaCustomerDao.java | 2 +- .../sql/dashboard/DashboardInfoRepository.java | 2 +- .../dao/sql/dashboard/DashboardRepository.java | 2 +- .../dao/sql/dashboard/JpaDashboardDao.java | 2 +- .../dao/sql/dashboard/JpaDashboardInfoDao.java | 2 +- .../device/DefaultNativeDeviceRepository.java | 2 +- .../sql/device/DeviceCredentialsRepository.java | 2 +- .../dao/sql/device/DeviceProfileRepository.java | 2 +- .../server/dao/sql/device/DeviceRepository.java | 2 +- .../dao/sql/device/JpaDeviceCredentialsDao.java | 2 +- .../server/dao/sql/device/JpaDeviceDao.java | 2 +- .../dao/sql/device/JpaDeviceProfileDao.java | 2 +- .../dao/sql/device/NativeDeviceRepository.java | 2 +- .../dao/sql/edge/EdgeEventInsertRepository.java | 2 +- .../server/dao/sql/edge/EdgeEventRepository.java | 2 +- .../server/dao/sql/edge/EdgeRepository.java | 2 +- .../server/dao/sql/edge/JpaBaseEdgeEventDao.java | 2 +- .../server/dao/sql/edge/JpaEdgeDao.java | 2 +- .../dao/sql/entityview/EntityViewRepository.java | 2 +- .../dao/sql/entityview/JpaEntityViewDao.java | 2 +- .../dao/sql/event/ErrorEventRepository.java | 2 +- .../dao/sql/event/EventCleanupRepository.java | 2 +- .../dao/sql/event/EventInsertRepository.java | 2 +- .../sql/event/EventPartitionConfiguration.java | 2 +- .../server/dao/sql/event/EventRepository.java | 2 +- .../server/dao/sql/event/JpaBaseEventDao.java | 2 +- .../dao/sql/event/LifecycleEventRepository.java | 2 +- .../sql/event/RuleChainDebugEventRepository.java | 2 +- .../sql/event/RuleNodeDebugEventRepository.java | 2 +- .../dao/sql/event/SqlEventCleanupRepository.java | 2 +- .../dao/sql/event/StatisticsEventRepository.java | 2 +- .../dao/sql/notification/JpaNotificationDao.java | 2 +- .../notification/JpaNotificationRequestDao.java | 2 +- .../sql/notification/JpaNotificationRuleDao.java | 2 +- .../notification/JpaNotificationTargetDao.java | 2 +- .../notification/JpaNotificationTemplateDao.java | 2 +- .../sql/notification/NotificationRepository.java | 2 +- .../NotificationRequestRepository.java | 2 +- .../notification/NotificationRuleRepository.java | 2 +- .../NotificationTargetRepository.java | 2 +- .../NotificationTemplateRepository.java | 2 +- .../JpaOAuth2ClientRegistrationTemplateDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2DomainDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2MobileDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2ParamsDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2RegistrationDao.java | 2 +- ...uth2ClientRegistrationTemplateRepository.java | 2 +- .../dao/sql/oauth2/OAuth2DomainRepository.java | 2 +- .../dao/sql/oauth2/OAuth2MobileRepository.java | 2 +- .../dao/sql/oauth2/OAuth2ParamsRepository.java | 2 +- .../sql/oauth2/OAuth2RegistrationRepository.java | 2 +- .../server/dao/sql/ota/JpaOtaPackageDao.java | 2 +- .../server/dao/sql/ota/JpaOtaPackageInfoDao.java | 2 +- .../dao/sql/ota/OtaPackageInfoRepository.java | 2 +- .../server/dao/sql/ota/OtaPackageRepository.java | 2 +- .../server/dao/sql/query/AlarmDataAdapter.java | 2 +- .../dao/sql/query/AlarmQueryRepository.java | 2 +- .../sql/query/DefaultAlarmQueryRepository.java | 2 +- .../sql/query/DefaultEntityQueryRepository.java | 2 +- .../dao/sql/query/DefaultQueryLogComponent.java | 2 +- .../server/dao/sql/query/EntityDataAdapter.java | 2 +- .../server/dao/sql/query/EntityKeyMapping.java | 2 +- .../dao/sql/query/EntityQueryRepository.java | 2 +- .../server/dao/sql/query/JpaEntityQueryDao.java | 2 +- .../server/dao/sql/query/QueryContext.java | 2 +- .../server/dao/sql/query/QueryLogComponent.java | 2 +- .../dao/sql/query/QuerySecurityContext.java | 2 +- .../server/dao/sql/queue/JpaQueueDao.java | 2 +- .../server/dao/sql/queue/QueueRepository.java | 2 +- .../server/dao/sql/relation/JpaRelationDao.java | 2 +- .../JpaRelationQueryExecutorService.java | 2 +- .../sql/relation/RelationInsertRepository.java | 2 +- .../dao/sql/relation/RelationRepository.java | 2 +- .../relation/SqlRelationInsertRepository.java | 2 +- .../dao/sql/resource/JpaTbResourceDao.java | 2 +- .../dao/sql/resource/JpaTbResourceInfoDao.java | 2 +- .../sql/resource/TbResourceInfoRepository.java | 2 +- .../dao/sql/resource/TbResourceRepository.java | 2 +- .../server/dao/sql/rpc/JpaRpcDao.java | 2 +- .../server/dao/sql/rpc/RpcRepository.java | 2 +- .../server/dao/sql/rule/JpaRuleChainDao.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeDao.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeStateDao.java | 2 +- .../server/dao/sql/rule/RuleChainRepository.java | 2 +- .../server/dao/sql/rule/RuleNodeRepository.java | 2 +- .../dao/sql/rule/RuleNodeStateRepository.java | 2 +- .../sql/settings/AdminSettingsRepository.java | 2 +- .../dao/sql/settings/JpaAdminSettingsDao.java | 2 +- .../server/dao/sql/tenant/JpaTenantDao.java | 2 +- .../dao/sql/tenant/JpaTenantProfileDao.java | 2 +- .../dao/sql/tenant/TenantProfileRepository.java | 2 +- .../server/dao/sql/tenant/TenantRepository.java | 2 +- .../sql/usagerecord/ApiUsageStateRepository.java | 2 +- .../dao/sql/usagerecord/JpaApiUsageStateDao.java | 2 +- .../dao/sql/user/JpaUserAuthSettingsDao.java | 2 +- .../dao/sql/user/JpaUserCredentialsDao.java | 2 +- .../server/dao/sql/user/JpaUserDao.java | 2 +- .../server/dao/sql/user/JpaUserSettingsDao.java | 2 +- .../dao/sql/user/UserAuthSettingsRepository.java | 2 +- .../dao/sql/user/UserCredentialsRepository.java | 2 +- .../server/dao/sql/user/UserRepository.java | 2 +- .../dao/sql/user/UserSettingsRepository.java | 2 +- .../server/dao/sql/widget/JpaWidgetTypeDao.java | 2 +- .../dao/sql/widget/JpaWidgetsBundleDao.java | 2 +- .../dao/sql/widget/WidgetTypeInfoRepository.java | 2 +- .../dao/sql/widget/WidgetTypeRepository.java | 2 +- .../dao/sql/widget/WidgetsBundleRepository.java | 2 +- .../widget/WidgetsBundleWidgetRepository.java | 2 +- .../AbstractChunkedAggregationTimeseriesDao.java | 2 +- .../dao/sqlts/AbstractSqlTimeseriesDao.java | 2 +- .../dao/sqlts/AggregationTimeseriesDao.java | 2 +- .../dao/sqlts/BaseAbstractSqlTimeseriesDao.java | 2 +- .../server/dao/sqlts/EntityContainer.java | 2 +- .../server/dao/sqlts/SqlTimeseriesLatestDao.java | 2 +- .../org/thingsboard/server/dao/sqlts/TsKey.java | 2 +- .../dictionary/TsKvDictionaryRepository.java | 2 +- .../sqlts/insert/AbstractInsertRepository.java | 2 +- .../dao/sqlts/insert/InsertTsRepository.java | 2 +- .../insert/latest/InsertLatestTsRepository.java | 2 +- .../latest/sql/SqlLatestInsertTsRepository.java | 2 +- .../sqlts/insert/sql/SqlInsertTsRepository.java | 2 +- .../insert/sql/SqlPartitioningRepository.java | 2 +- .../timescale/TimescaleInsertTsRepository.java | 2 +- .../sqlts/latest/SearchTsKvLatestRepository.java | 2 +- .../dao/sqlts/latest/TsKvLatestRepository.java | 2 +- .../dao/sqlts/sql/JpaSqlTimeseriesDao.java | 2 +- .../sqlts/timescale/AggregationRepository.java | 2 +- .../sqlts/timescale/TimescaleTimeseriesDao.java | 2 +- .../sqlts/timescale/TsKvTimescaleRepository.java | 2 +- .../server/dao/sqlts/ts/TsKvRepository.java | 2 +- .../dao/tenant/DefaultTbTenantProfileCache.java | 2 +- .../server/dao/tenant/TenantCaffeineCache.java | 2 +- .../thingsboard/server/dao/tenant/TenantDao.java | 2 +- .../server/dao/tenant/TenantEvictEvent.java | 2 +- .../dao/tenant/TenantExistsCaffeineCache.java | 2 +- .../dao/tenant/TenantExistsRedisCache.java | 2 +- .../server/dao/tenant/TenantProfileCacheKey.java | 2 +- .../dao/tenant/TenantProfileCaffeineCache.java | 2 +- .../server/dao/tenant/TenantProfileDao.java | 2 +- .../dao/tenant/TenantProfileEvictEvent.java | 2 +- .../dao/tenant/TenantProfileRedisCache.java | 2 +- .../dao/tenant/TenantProfileServiceImpl.java | 2 +- .../server/dao/tenant/TenantRedisCache.java | 2 +- .../server/dao/tenant/TenantServiceImpl.java | 2 +- .../AbstractCassandraBaseTimeseriesDao.java | 2 +- .../timeseries/AggregatePartitionsFunction.java | 2 +- .../dao/timeseries/BaseTimeseriesService.java | 2 +- .../timeseries/CassandraBaseTimeseriesDao.java | 2 +- .../CassandraBaseTimeseriesLatestDao.java | 2 +- .../timeseries/CassandraPartitionCacheKey.java | 2 +- .../timeseries/CassandraTsPartitionsCache.java | 2 +- .../dao/timeseries/NoSqlTsPartitionDate.java | 2 +- .../server/dao/timeseries/QueryCursor.java | 2 +- .../dao/timeseries/SimpleListenableFuture.java | 2 +- .../server/dao/timeseries/SqlPartition.java | 2 +- .../dao/timeseries/SqlTsPartitionDate.java | 2 +- .../server/dao/timeseries/TimeseriesDao.java | 2 +- .../dao/timeseries/TimeseriesLatestDao.java | 2 +- .../dao/timeseries/TsInsertExecutorType.java | 2 +- .../server/dao/timeseries/TsKvQueryCursor.java | 2 +- .../server/dao/usage/BasicUsageInfoService.java | 2 +- .../server/dao/usagerecord/ApiUsageStateDao.java | 2 +- .../usagerecord/ApiUsageStateServiceImpl.java | 2 +- .../dao/usagerecord/DefaultApiLimitService.java | 2 +- .../server/dao/user/UserAuthSettingsDao.java | 2 +- .../server/dao/user/UserCredentialsDao.java | 2 +- .../org/thingsboard/server/dao/user/UserDao.java | 2 +- .../server/dao/user/UserServiceImpl.java | 2 +- .../dao/user/UserSettingsCaffeineCache.java | 2 +- .../server/dao/user/UserSettingsDao.java | 2 +- .../server/dao/user/UserSettingsEvictEvent.java | 2 +- .../server/dao/user/UserSettingsRedisCache.java | 2 +- .../server/dao/user/UserSettingsServiceImpl.java | 2 +- .../dao/util/AbstractBufferedRateExecutor.java | 2 +- .../server/dao/util/AsyncRateLimiter.java | 2 +- .../server/dao/util/AsyncTaskContext.java | 2 +- .../server/dao/util/BufferedRateExecutor.java | 2 +- .../dao/util/BufferedRateExecutorStats.java | 2 +- .../server/dao/util/DeviceConnectivityUtil.java | 2 +- .../thingsboard/server/dao/util/ImageUtils.java | 2 +- .../server/dao/util/JsonNodeProcessingTask.java | 2 +- .../server/dao/util/JsonPathProcessingTask.java | 2 +- .../org/thingsboard/server/dao/util/KvUtils.java | 2 +- .../dao/util/TenantRateLimitException.java | 2 +- .../dao/util/limits/DefaultRateLimitService.java | 2 +- .../server/dao/util/limits/RateLimitService.java | 2 +- .../mapping/AbstractJsonSqlTypeDescriptor.java | 2 +- .../mapping/JsonBinarySqlTypeDescriptor.java | 2 +- .../server/dao/util/mapping/JsonBinaryType.java | 2 +- .../mapping/JsonStringSqlTypeDescriptor.java | 2 +- .../server/dao/util/mapping/JsonStringType.java | 2 +- .../dao/util/mapping/JsonTypeDescriptor.java | 2 +- .../server/dao/widget/WidgetTypeDao.java | 2 +- .../server/dao/widget/WidgetTypeServiceImpl.java | 2 +- .../server/dao/widget/WidgetsBundleDao.java | 2 +- .../dao/widget/WidgetsBundleServiceImpl.java | 2 +- .../main/resources/cassandra/schema-keyspace.cql | 2 +- .../resources/cassandra/schema-ts-latest.cql | 2 +- dao/src/main/resources/cassandra/schema-ts.cql | 2 +- .../sql/schema-entities-idx-psql-addon.sql | 2 +- .../main/resources/sql/schema-entities-idx.sql | 2 +- dao/src/main/resources/sql/schema-entities.sql | 2 +- dao/src/main/resources/sql/schema-timescale.sql | 2 +- dao/src/main/resources/sql/schema-ts-psql.sql | 2 +- .../resources/sql/schema-views-and-functions.sql | 2 +- dao/src/main/resources/xss-policy.xml | 2 +- .../server/dao/AbstractDaoServiceTest.java | 2 +- .../server/dao/AbstractJpaDaoTest.java | 2 +- .../server/dao/AbstractNoSqlContainer.java | 3 +-- .../server/dao/AbstractRedisContainer.java | 2 +- .../server/dao/NoSqlDaoServiceTestSuite.java | 2 +- .../server/dao/PostgreSqlInitializer.java | 2 +- .../server/dao/RedisSqlTestSuite.java | 2 +- .../server/dao/TimescaleDaoServiceTestSuite.java | 2 +- .../server/dao/TimescaleSqlInitializer.java | 2 +- .../dao/eventsourcing/DeleteEntityEventTest.java | 2 +- .../dao/nosql/CassandraPartitionsCacheTest.java | 2 +- .../server/dao/service/AbstractServiceTest.java | 2 +- .../dao/service/AdminSettingsServiceTest.java | 2 +- .../dao/service/AlarmCommentServiceTest.java | 2 +- .../server/dao/service/AlarmServiceTest.java | 2 +- .../dao/service/ApiUsageStateServiceTest.java | 2 +- .../dao/service/AssetProfileServiceTest.java | 2 +- .../server/dao/service/AssetServiceTest.java | 2 +- .../dao/service/ConstraintValidatorTest.java | 2 +- .../server/dao/service/CustomerServiceTest.java | 2 +- .../server/dao/service/DaoNoSqlTest.java | 2 +- .../server/dao/service/DaoSqlTest.java | 2 +- .../server/dao/service/DaoTimescaleTest.java | 2 +- .../server/dao/service/DashboardServiceTest.java | 2 +- .../server/dao/service/DataValidatorTest.java | 2 +- .../dao/service/DeviceCredentialsCacheTest.java | 2 +- .../service/DeviceCredentialsServiceTest.java | 2 +- .../dao/service/DeviceProfileServiceTest.java | 2 +- .../server/dao/service/DeviceServiceTest.java | 2 +- .../server/dao/service/EdgeEventServiceTest.java | 2 +- .../server/dao/service/EdgeServiceTest.java | 2 +- .../dao/service/EntityServiceRegistryTest.java | 2 +- .../server/dao/service/EntityServiceTest.java | 2 +- .../server/dao/service/NoXssValidatorTest.java | 2 +- .../service/OAuth2ConfigTemplateServiceTest.java | 2 +- .../server/dao/service/OAuth2ServiceTest.java | 2 +- .../dao/service/OtaPackageServiceTest.java | 2 +- .../server/dao/service/QueueServiceTest.java | 2 +- .../server/dao/service/RelationCacheTest.java | 2 +- .../server/dao/service/RelationServiceTest.java | 2 +- .../server/dao/service/RuleChainServiceTest.java | 2 +- .../dao/service/TbCacheSerializationTest.java | 2 +- .../dao/service/TenantProfileServiceTest.java | 2 +- .../server/dao/service/TenantServiceTest.java | 2 +- .../server/dao/service/UserServiceTest.java | 2 +- .../dao/service/WidgetTypeServiceTest.java | 2 +- .../dao/service/WidgetsBundleServiceTest.java | 2 +- .../attributes/BaseAttributesServiceTest.java | 2 +- .../attributes/sql/AttributesServiceSqlTest.java | 2 +- .../dao/service/event/BaseEventServiceTest.java | 2 +- .../service/event/sql/EventServiceSqlTest.java | 2 +- .../install/sql/EntitiesSchemaSqlTest.java | 2 +- .../timeseries/BaseTimeseriesServiceTest.java | 2 +- .../nosql/TimeseriesServiceNoSqlTest.java | 2 +- .../nosql/TimeseriesServiceTimescaleTest.java | 2 +- .../timeseries/sql/TimeseriesServiceSqlTest.java | 2 +- .../AdminSettingsDataValidatorTest.java | 2 +- .../validator/AlarmDataValidatorTest.java | 2 +- .../validator/AssetDataValidatorTest.java | 2 +- .../validator/AssetProfileDataValidatorTest.java | 2 +- .../BaseOtaPackageDataValidatorTest.java | 2 +- .../ComponentDescriptorDataValidatorTest.java | 2 +- .../validator/CustomerDataValidatorTest.java | 2 +- .../validator/DashboardDataValidatorTest.java | 2 +- .../validator/DeviceDataValidatorTest.java | 2 +- .../DeviceProfileDataValidatorTest.java | 2 +- .../service/validator/EdgeDataValidatorTest.java | 2 +- .../validator/EntityViewDataValidatorTest.java | 2 +- .../validator/ResourceDataValidatorTest.java | 2 +- .../validator/RuleChainDataValidatorTest.java | 2 +- .../validator/TenantDataValidatorTest.java | 2 +- .../TenantProfileDataValidatorTest.java | 2 +- .../validator/WidgetTypeDataValidatorTest.java | 2 +- .../WidgetsBundleDataValidatorTest.java | 2 +- .../dao/sql/alarm/JpaAlarmCommentDaoTest.java | 2 +- .../server/dao/sql/alarm/JpaAlarmDaoTest.java | 2 +- .../server/dao/sql/asset/JpaAssetDaoTest.java | 2 +- .../server/dao/sql/audit/JpaAuditLogDaoTest.java | 2 +- .../JpaBaseComponentDescriptorDaoTest.java | 2 +- .../dao/sql/customer/JpaCustomerDaoTest.java | 2 +- .../sql/dashboard/JpaDashboardInfoDaoTest.java | 2 +- .../sql/device/JpaDeviceCredentialsDaoTest.java | 2 +- .../server/dao/sql/device/JpaDeviceDaoTest.java | 2 +- .../dao/sql/event/JpaBaseEventDaoTest.java | 2 +- .../query/DefaultEntityQueryRepositoryTest.java | 2 +- .../sql/query/DefaultQueryLogComponentTest.java | 2 +- .../dao/sql/query/EntityDataAdapterTest.java | 2 +- .../dao/sql/query/EntityKeyMappingTest.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeDaoTest.java | 2 +- .../server/dao/sql/tenant/JpaTenantDaoTest.java | 2 +- .../dao/sql/user/JpaUserCredentialsDaoTest.java | 2 +- .../server/dao/sql/user/JpaUserDaoTest.java | 2 +- .../dao/sql/user/JpaUserSettingsDaoTest.java | 2 +- .../dao/sql/widget/JpaWidgetTypeDaoTest.java | 2 +- .../dao/sql/widget/JpaWidgetsBundleDaoTest.java | 2 +- ...tractChunkedAggregationTimeseriesDaoTest.java | 2 +- ...eriesDaoPartitioningDaysAlwaysExistsTest.java | 2 +- ...riesDaoPartitioningHoursAlwaysExistsTest.java | 2 +- ...aoPartitioningIndefiniteAlwaysExistsTest.java | 2 +- ...esDaoPartitioningMinutesAlwaysExistsTest.java | 2 +- ...iesDaoPartitioningMonthsAlwaysExistsTest.java | 2 +- ...riesDaoPartitioningYearsAlwaysExistsTest.java | 2 +- .../dao/util/DeviceConnectivityUtilTest.java | 2 +- docker/compose-utils.sh | 2 +- docker/docker-check-log-folders.sh | 2 +- docker/docker-compose.aws-sqs.yml | 2 +- docker/docker-compose.cassandra.volumes.yml | 2 +- docker/docker-compose.confluent.yml | 2 +- docker/docker-compose.hybrid.yml | 2 +- docker/docker-compose.kafka.yml | 2 +- docker/docker-compose.postgres.volumes.yml | 2 +- docker/docker-compose.postgres.yml | 2 +- docker/docker-compose.prometheus-grafana.yml | 2 +- docker/docker-compose.pubsub.yml | 2 +- docker/docker-compose.rabbitmq.yml | 2 +- docker/docker-compose.redis-cluster.volumes.yml | 2 +- docker/docker-compose.redis-cluster.yml | 2 +- docker/docker-compose.redis-sentinel.volumes.yml | 2 +- docker/docker-compose.redis-sentinel.yml | 2 +- docker/docker-compose.redis.volumes.yml | 2 +- docker/docker-compose.redis.yml | 2 +- docker/docker-compose.service-bus.yml | 2 +- docker/docker-compose.volumes.yml | 2 +- docker/docker-compose.yml | 2 +- docker/docker-create-log-folders.sh | 2 +- docker/docker-install-tb.sh | 2 +- docker/docker-remove-services.sh | 2 +- docker/docker-start-services.sh | 2 +- docker/docker-stop-services.sh | 2 +- docker/docker-update-service.sh | 2 +- docker/docker-upgrade-tb.sh | 2 +- .../provisioning/dashboards/dashboard.yml | 2 +- .../provisioning/datasources/datasource.yml | 2 +- docker/monitoring/prometheus/prometheus.yml | 2 +- docker/tb-transports/coap/conf/logback.xml | 2 +- .../coap/conf/tb-coap-transport.conf | 2 +- docker/tb-transports/http/conf/logback.xml | 2 +- .../http/conf/tb-http-transport.conf | 2 +- docker/tb-transports/lwm2m/conf/logback.xml | 2 +- .../lwm2m/conf/tb-lwm2m-transport.conf | 2 +- docker/tb-transports/mqtt/conf/logback.xml | 2 +- .../mqtt/conf/tb-mqtt-transport.conf | 2 +- docker/tb-transports/snmp/conf/logback.xml | 2 +- .../snmp/conf/tb-snmp-transport.conf | 2 +- docker/tb-vc-executor/conf/logback.xml | 2 +- docker/tb-vc-executor/conf/tb-vc-executor.conf | 2 +- license-header-template.txt | 2 +- monitoring/pom.xml | 2 +- monitoring/src/main/conf/logback.xml | 2 +- monitoring/src/main/conf/tb-monitoring.conf | 2 +- .../ThingsboardMonitoringApplication.java | 2 +- .../monitoring/client/Lwm2mClient.java | 2 +- .../thingsboard/monitoring/client/TbClient.java | 2 +- .../thingsboard/monitoring/client/WsClient.java | 2 +- .../monitoring/client/WsClientFactory.java | 2 +- .../monitoring/config/MonitoringConfig.java | 2 +- .../monitoring/config/MonitoringTarget.java | 2 +- .../transport/CoapTransportMonitoringConfig.java | 2 +- .../config/transport/DeviceConfig.java | 2 +- .../transport/HttpTransportMonitoringConfig.java | 2 +- .../Lwm2mTransportMonitoringConfig.java | 2 +- .../transport/MqttTransportMonitoringConfig.java | 2 +- .../config/transport/TransportInfo.java | 2 +- .../transport/TransportMonitoringConfig.java | 2 +- .../transport/TransportMonitoringTarget.java | 2 +- .../config/transport/TransportType.java | 2 +- .../thingsboard/monitoring/data/Latencies.java | 2 +- .../org/thingsboard/monitoring/data/Latency.java | 2 +- .../monitoring/data/MonitoredServiceKey.java | 2 +- .../monitoring/data/ServiceFailureException.java | 2 +- .../monitoring/data/cmd/CmdsWrapper.java | 2 +- .../monitoring/data/cmd/EntityDataCmd.java | 2 +- .../monitoring/data/cmd/EntityDataUpdate.java | 2 +- .../monitoring/data/cmd/LatestValueCmd.java | 2 +- .../notification/HighLatencyNotification.java | 2 +- .../data/notification/Notification.java | 2 +- .../notification/ServiceFailureNotification.java | 2 +- .../ServiceRecoveryNotification.java | 2 +- .../notification/NotificationService.java | 2 +- .../channels/NotificationChannel.java | 2 +- .../channels/impl/SlackNotificationChannel.java | 2 +- .../monitoring/service/BaseHealthChecker.java | 2 +- .../service/BaseMonitoringService.java | 2 +- .../monitoring/service/MonitoringReporter.java | 2 +- .../transport/TransportHealthChecker.java | 2 +- .../transport/TransportsMonitoringService.java | 2 +- .../impl/CoapTransportHealthChecker.java | 2 +- .../impl/HttpTransportHealthChecker.java | 2 +- .../impl/Lwm2mTransportHealthChecker.java | 2 +- .../impl/MqttTransportHealthChecker.java | 2 +- .../monitoring/util/ResourceUtils.java | 2 +- .../thingsboard/monitoring/util/TbStopWatch.java | 2 +- monitoring/src/main/resources/logback.xml | 2 +- monitoring/src/main/resources/lwm2m/models/0.xml | 2 +- monitoring/src/main/resources/lwm2m/models/1.xml | 2 +- monitoring/src/main/resources/lwm2m/models/2.xml | 2 +- .../main/resources/lwm2m/models/test-model.xml | 2 +- monitoring/src/main/resources/tb-monitoring.yml | 2 +- msa/black-box-tests/pom.xml | 2 +- .../server/msa/AbstractContainerTest.java | 2 +- .../server/msa/ContainerTestSuite.java | 2 +- .../server/msa/DisableUIListeners.java | 2 +- .../server/msa/DockerComposeExecutor.java | 2 +- .../server/msa/SeleniumRemoteWebDriverTest.java | 2 +- .../thingsboard/server/msa/TestCoapClient.java | 2 +- .../server/msa/TestCoapClientCallback.java | 2 +- .../org/thingsboard/server/msa/TestListener.java | 2 +- .../thingsboard/server/msa/TestProperties.java | 2 +- .../thingsboard/server/msa/TestRestClient.java | 2 +- .../server/msa/ThingsBoardDbInstaller.java | 2 +- .../org/thingsboard/server/msa/WsClient.java | 2 +- .../server/msa/connectivity/CoapClientTest.java | 2 +- .../server/msa/connectivity/HttpClientTest.java | 2 +- .../server/msa/connectivity/MqttClientTest.java | 2 +- .../msa/connectivity/MqttGatewayClientTest.java | 2 +- .../server/msa/mapper/AttributesResponse.java | 2 +- .../server/msa/mapper/WsTelemetryResponse.java | 2 +- .../server/msa/prototypes/DevicePrototypes.java | 2 +- .../server/msa/ui/base/AbstractBasePage.java | 2 +- .../msa/ui/base/AbstractDriverBaseTest.java | 2 +- .../server/msa/ui/listeners/RetryAnalyzer.java | 2 +- .../msa/ui/listeners/RetryTestListener.java | 2 +- .../ui/pages/AlarmDetailsEntityTabElements.java | 2 +- .../ui/pages/AlarmDetailsEntityTabHelper.java | 2 +- .../msa/ui/pages/AlarmDetailsViewElements.java | 2 +- .../msa/ui/pages/AlarmDetailsViewHelper.java | 2 +- .../server/msa/ui/pages/AlarmWidgetElements.java | 2 +- .../server/msa/ui/pages/AssetPageElements.java | 2 +- .../server/msa/ui/pages/AssetPageHelper.java | 2 +- .../msa/ui/pages/CreateWidgetPopupElements.java | 2 +- .../msa/ui/pages/CreateWidgetPopupHelper.java | 2 +- .../msa/ui/pages/CustomerPageElements.java | 2 +- .../server/msa/ui/pages/CustomerPageHelper.java | 2 +- .../msa/ui/pages/DashboardPageElements.java | 2 +- .../server/msa/ui/pages/DashboardPageHelper.java | 2 +- .../server/msa/ui/pages/DevicePageElements.java | 2 +- .../server/msa/ui/pages/DevicePageHelper.java | 2 +- .../msa/ui/pages/EntityViewPageElements.java | 2 +- .../msa/ui/pages/EntityViewPageHelper.java | 2 +- .../server/msa/ui/pages/LoginPageElements.java | 2 +- .../server/msa/ui/pages/LoginPageHelper.java | 2 +- .../msa/ui/pages/OpenRuleChainPageElements.java | 2 +- .../msa/ui/pages/OpenRuleChainPageHelper.java | 2 +- .../server/msa/ui/pages/OtherPageElements.java | 2 +- .../msa/ui/pages/OtherPageElementsHelper.java | 2 +- .../msa/ui/pages/ProfilesPageElements.java | 2 +- .../server/msa/ui/pages/ProfilesPageHelper.java | 2 +- .../msa/ui/pages/RuleChainsPageElements.java | 2 +- .../msa/ui/pages/RuleChainsPageHelper.java | 2 +- .../msa/ui/pages/SideBarMenuViewElements.java | 2 +- .../msa/ui/pages/SideBarMenuViewHelper.java | 2 +- .../msa/ui/tabs/AssignDeviceTabElements.java | 2 +- .../msa/ui/tabs/AssignDeviceTabHelper.java | 2 +- .../msa/ui/tabs/CreateDeviceTabElements.java | 2 +- .../msa/ui/tabs/CreateDeviceTabHelper.java | 2 +- .../tests/alarmassignee/AbstractAssignTest.java | 2 +- .../AssignDetailsTabAssignTest.java | 2 +- .../AssignDetailsTabFromCustomerAssignTest.java | 2 +- .../alarmassignee/AssignFromAlarmWidgetTest.java | 2 +- .../AssetProfileEditMenuTest.java | 2 +- .../CreateAssetProfileImportTest.java | 2 +- .../CreateAssetProfileTest.java | 2 +- .../DeleteAssetProfileTest.java | 2 +- .../DeleteSeveralAssetProfilesTest.java | 2 +- .../MakeAssetProfileDefaultTest.java | 2 +- .../SearchAssetProfileTest.java | 2 +- .../tests/assetProfileSmoke/SortByNameTest.java | 2 +- .../tests/customerSmoke/CreateCustomerTest.java | 2 +- .../customerSmoke/CustomerEditMenuTest.java | 2 +- .../tests/customerSmoke/DeleteCustomerTest.java | 2 +- .../customerSmoke/DeleteSeveralCustomerTest.java | 2 +- .../customerSmoke/ManageCustomersAssetsTest.java | 2 +- .../ManageCustomersDashboardsTest.java | 2 +- .../ManageCustomersDevicesTest.java | 2 +- .../customerSmoke/ManageCustomersEdgesTest.java | 2 +- .../customerSmoke/ManageCustomersUsersTest.java | 2 +- .../tests/customerSmoke/SearchCustomerTest.java | 2 +- .../ui/tests/customerSmoke/SortByNameTest.java | 2 +- .../CreateDeviceProfileImportTest.java | 2 +- .../CreateDeviceProfileTest.java | 2 +- .../DeleteDeviceProfileTest.java | 2 +- .../DeleteSeveralDeviceProfilesTest.java | 2 +- .../DeviceProfileEditMenuTest.java | 2 +- .../MakeDeviceProfileDefaultTest.java | 2 +- .../SearchDeviceProfileTest.java | 2 +- .../tests/deviceProfileSmoke/SortByNameTest.java | 2 +- .../tests/devicessmoke/AbstractDeviceTest.java | 2 +- .../tests/devicessmoke/AssignToCustomerTest.java | 2 +- .../ui/tests/devicessmoke/CreateDeviceTest.java | 2 +- .../ui/tests/devicessmoke/DeleteDeviceTest.java | 2 +- .../devicessmoke/DeleteSeveralDevicesTest.java | 2 +- .../ui/tests/devicessmoke/DeviceFilterTest.java | 2 +- .../ui/tests/devicessmoke/EditDeviceTest.java | 2 +- .../devicessmoke/MakeDevicePrivateTest.java | 2 +- .../tests/devicessmoke/MakeDevicePublicTest.java | 2 +- .../rulechainssmoke/AbstractRuleChainTest.java | 2 +- .../CreateRuleChainImportTest.java | 2 +- .../rulechainssmoke/CreateRuleChainTest.java | 2 +- .../rulechainssmoke/DeleteRuleChainTest.java | 2 +- .../DeleteSeveralRuleChainsTest.java | 2 +- .../rulechainssmoke/MakeRuleChainRootTest.java | 2 +- .../tests/rulechainssmoke/OpenRuleChainTest.java | 2 +- .../rulechainssmoke/RuleChainEditMenuTest.java | 2 +- .../rulechainssmoke/SearchRuleChainTest.java | 2 +- .../ui/tests/rulechainssmoke/SortByNameTest.java | 2 +- .../ui/tests/rulechainssmoke/SortByTimeTest.java | 2 +- .../thingsboard/server/msa/ui/utils/Const.java | 2 +- .../msa/ui/utils/DataProviderCredential.java | 2 +- .../server/msa/ui/utils/EntityPrototypes.java | 2 +- .../src/test/resources/alarmAssignee.xml | 2 +- msa/black-box-tests/src/test/resources/all.xml | 2 +- .../src/test/resources/connectivity.xml | 2 +- .../docker-compose.hybrid-test-extras.yml | 2 +- .../docker-compose.postgres-test-extras.yml | 2 +- .../resources/docker-compose.rabbitmq-server.yml | 2 +- .../src/test/resources/docker-selenium.yml | 2 +- .../src/test/resources/forImport.txt | 2 +- .../src/test/resources/logback.xml | 2 +- .../src/test/resources/smokeDevices.xml | 2 +- .../src/test/resources/smokesCustomer.xml | 2 +- .../src/test/resources/smokesProfiles.xml | 2 +- .../src/test/resources/smokesRuleChain.xml | 2 +- .../src/test/resources/tb-node/conf/logback.xml | 2 +- .../tb-transports/coap/conf/logback.xml | 2 +- .../tb-transports/http/conf/logback.xml | 2 +- .../tb-transports/mqtt/conf/logback.xml | 2 +- .../src/test/resources/uiTests.xml | 2 +- msa/js-executor/api/httpServer.ts | 2 +- msa/js-executor/api/jsExecutor.models.ts | 2 +- msa/js-executor/api/jsExecutor.ts | 2 +- msa/js-executor/api/jsInvokeMessageProcessor.ts | 2 +- msa/js-executor/api/utils.ts | 2 +- .../config/custom-environment-variables.yml | 2 +- msa/js-executor/config/default.yml | 2 +- msa/js-executor/config/logger.ts | 2 +- msa/js-executor/config/tb-js-executor.conf | 2 +- msa/js-executor/docker/Dockerfile | 2 +- msa/js-executor/docker/start-js-executor.sh | 2 +- msa/js-executor/install.js | 2 +- msa/js-executor/pom.xml | 2 +- msa/js-executor/queue/awsSqsTemplate.ts | 2 +- msa/js-executor/queue/kafkaTemplate.ts | 2 +- msa/js-executor/queue/pubSubTemplate.ts | 2 +- msa/js-executor/queue/queue.models.ts | 2 +- msa/js-executor/queue/rabbitmqTemplate.ts | 2 +- msa/js-executor/queue/serviceBusTemplate.ts | 2 +- msa/js-executor/server.ts | 2 +- msa/monitoring/docker/Dockerfile | 2 +- msa/monitoring/docker/start-tb-monitoring.sh | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/docker/Dockerfile | 2 +- msa/tb-node/docker/start-tb-node.sh | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-cassandra/start-db.sh | 2 +- msa/tb/docker-cassandra/stop-db.sh | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- msa/tb/docker-postgres/start-db.sh | 2 +- msa/tb/docker-postgres/stop-db.sh | 2 +- msa/tb/docker/install-tb.sh | 2 +- msa/tb/docker/logback.xml | 2 +- msa/tb/docker/start-tb.sh | 2 +- msa/tb/docker/thingsboard.conf | 2 +- msa/tb/docker/upgrade-tb.sh | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/docker/Dockerfile | 2 +- .../coap/docker/start-tb-coap-transport.sh | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/docker/Dockerfile | 2 +- .../http/docker/start-tb-http-transport.sh | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/docker/Dockerfile | 2 +- .../lwm2m/docker/start-tb-lwm2m-transport.sh | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/docker/Dockerfile | 2 +- .../mqtt/docker/start-tb-mqtt-transport.sh | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/docker/Dockerfile | 2 +- .../snmp/docker/start-tb-snmp-transport.sh | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/docker/Dockerfile | 2 +- .../docker/start-tb-vc-executor.sh | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/vc-executor/src/main/conf/logback.xml | 2 +- .../src/main/conf/tb-vc-executor.conf | 2 +- ...gsboardVersionControlExecutorApplication.java | 2 +- .../VersionControlQueueRoutingInfoService.java | 2 +- .../VersionControlTenantRoutingInfoService.java | 2 +- msa/vc-executor/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-vc-executor.yml | 2 +- .../config/custom-environment-variables.yml | 2 +- msa/web-ui/config/default.yml | 2 +- msa/web-ui/config/logger.ts | 2 +- msa/web-ui/config/tb-web-ui.conf | 2 +- msa/web-ui/docker/Dockerfile | 2 +- msa/web-ui/docker/start-web-ui.sh | 2 +- msa/web-ui/install.js | 2 +- msa/web-ui/pom.xml | 2 +- msa/web-ui/server.ts | 2 +- netty-mqtt/pom.xml | 2 +- .../thingsboard/mqtt/ChannelClosedException.java | 2 +- .../org/thingsboard/mqtt/MqttChannelHandler.java | 2 +- .../java/org/thingsboard/mqtt/MqttClient.java | 2 +- .../org/thingsboard/mqtt/MqttClientCallback.java | 2 +- .../org/thingsboard/mqtt/MqttClientConfig.java | 2 +- .../org/thingsboard/mqtt/MqttClientImpl.java | 2 +- .../org/thingsboard/mqtt/MqttConnectResult.java | 2 +- .../java/org/thingsboard/mqtt/MqttHandler.java | 2 +- .../mqtt/MqttIncomingQos2Publish.java | 2 +- .../java/org/thingsboard/mqtt/MqttLastWill.java | 2 +- .../org/thingsboard/mqtt/MqttPendingPublish.java | 2 +- .../mqtt/MqttPendingSubscription.java | 2 +- .../mqtt/MqttPendingUnsubscription.java | 2 +- .../org/thingsboard/mqtt/MqttPingHandler.java | 2 +- .../org/thingsboard/mqtt/MqttSubscription.java | 2 +- .../org/thingsboard/mqtt/PendingOperation.java | 2 +- .../thingsboard/mqtt/RetransmissionHandler.java | 2 +- .../thingsboard/mqtt/MqttPingHandlerTest.java | 2 +- .../mqtt/integration/IntegrationTestSuite.java | 2 +- .../mqtt/integration/MqttIntegrationTest.java | 2 +- .../mqtt/integration/server/MqttServer.java | 2 +- .../integration/server/MqttTransportHandler.java | 2 +- packaging/java/assembly/windows.xml | 2 +- packaging/java/build.gradle | 2 +- packaging/java/scripts/install/install.sh | 2 +- packaging/java/scripts/install/install_dev_db.sh | 2 +- packaging/java/scripts/install/logback.xml | 2 +- packaging/java/scripts/install/upgrade.sh | 2 +- packaging/java/scripts/install/upgrade_dev_db.sh | 2 +- packaging/js/assembly/windows.xml | 2 +- packaging/js/build.gradle | 2 +- pom.xml | 2 +- rest-client/pom.xml | 2 +- .../org/thingsboard/rest/client/RestClient.java | 2 +- .../rest/client/utils/RestJsonConverter.java | 2 +- rest-client/src/main/resources/logback.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- .../rule/engine/api/EmptyNodeConfiguration.java | 2 +- .../thingsboard/rule/engine/api/MailService.java | 2 +- .../rule/engine/api/NodeConfiguration.java | 2 +- .../rule/engine/api/NodeDefinition.java | 2 +- .../rule/engine/api/NotificationCenter.java | 2 +- .../rule/engine/api/RuleEngineAlarmService.java | 2 +- .../api/RuleEngineApiUsageStateService.java | 2 +- .../engine/api/RuleEngineAssetProfileCache.java | 2 +- .../engine/api/RuleEngineDeviceProfileCache.java | 2 +- .../engine/api/RuleEngineDeviceRpcRequest.java | 2 +- .../engine/api/RuleEngineDeviceRpcResponse.java | 2 +- .../rule/engine/api/RuleEngineRpcService.java | 2 +- .../engine/api/RuleEngineTelemetryService.java | 2 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 +- .../rule/engine/api/ScriptEngine.java | 2 +- .../thingsboard/rule/engine/api/SmsService.java | 2 +- .../thingsboard/rule/engine/api/TbContext.java | 2 +- .../org/thingsboard/rule/engine/api/TbEmail.java | 2 +- .../org/thingsboard/rule/engine/api/TbNode.java | 2 +- .../rule/engine/api/TbNodeConfiguration.java | 2 +- .../rule/engine/api/TbNodeException.java | 2 +- .../thingsboard/rule/engine/api/TbNodeState.java | 2 +- .../rule/engine/api/slack/SlackService.java | 2 +- .../rule/engine/api/sms/SmsSender.java | 2 +- .../rule/engine/api/sms/SmsSenderFactory.java | 2 +- .../engine/api/sms/exception/SmsException.java | 2 +- .../api/sms/exception/SmsParseException.java | 2 +- .../api/sms/exception/SmsSendException.java | 2 +- .../rule/engine/api/util/TbNodeUtils.java | 2 +- .../rule/engine/api/util/TbNodeUtilsTest.java | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- .../rule/engine/action/TbAbstractAlarmNode.java | 2 +- .../action/TbAbstractAlarmNodeConfiguration.java | 2 +- .../action/TbAbstractCustomerActionNode.java | 2 +- ...bAbstractCustomerActionNodeConfiguration.java | 2 +- .../action/TbAbstractRelationActionNode.java | 2 +- ...bAbstractRelationActionNodeConfiguration.java | 2 +- .../rule/engine/action/TbAlarmResult.java | 2 +- .../engine/action/TbAssignToCustomerNode.java | 2 +- .../TbAssignToCustomerNodeConfiguration.java | 2 +- .../rule/engine/action/TbClearAlarmNode.java | 2 +- .../action/TbClearAlarmNodeConfiguration.java | 2 +- .../action/TbCopyAttributesToEntityViewNode.java | 2 +- .../rule/engine/action/TbCreateAlarmNode.java | 2 +- .../action/TbCreateAlarmNodeConfiguration.java | 2 +- .../rule/engine/action/TbCreateRelationNode.java | 2 +- .../TbCreateRelationNodeConfiguration.java | 2 +- .../rule/engine/action/TbDeleteRelationNode.java | 2 +- .../TbDeleteRelationNodeConfiguration.java | 2 +- .../rule/engine/action/TbLogNode.java | 2 +- .../engine/action/TbLogNodeConfiguration.java | 2 +- .../rule/engine/action/TbMsgCountNode.java | 2 +- .../action/TbMsgCountNodeConfiguration.java | 2 +- .../action/TbSaveToCustomCassandraTableNode.java | 2 +- ...eToCustomCassandraTableNodeConfiguration.java | 2 +- .../action/TbUnassignFromCustomerNode.java | 2 +- .../TbUnassignFromCustomerNodeConfiguration.java | 2 +- .../rule/engine/aws/sns/TbSnsNode.java | 2 +- .../engine/aws/sns/TbSnsNodeConfiguration.java | 2 +- .../rule/engine/aws/sqs/TbSqsNode.java | 2 +- .../engine/aws/sqs/TbSqsNodeConfiguration.java | 2 +- .../engine/credentials/AnonymousCredentials.java | 2 +- .../engine/credentials/BasicCredentials.java | 2 +- .../engine/credentials/CertPemCredentials.java | 2 +- .../engine/credentials/ClientCredentials.java | 2 +- .../rule/engine/credentials/CredentialsType.java | 2 +- .../rule/engine/data/DeviceRelationsQuery.java | 2 +- .../rule/engine/data/RelationsQuery.java | 2 +- .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../debug/TbMsgGeneratorNodeConfiguration.java | 2 +- .../engine/deduplication/DeduplicationData.java | 2 +- .../engine/deduplication/DeduplicationId.java | 2 +- .../deduplication/DeduplicationStrategy.java | 2 +- .../deduplication/TbMsgDeduplicationNode.java | 2 +- .../TbMsgDeduplicationNodeConfiguration.java | 2 +- .../rule/engine/delay/TbMsgDelayNode.java | 2 +- .../delay/TbMsgDelayNodeConfiguration.java | 2 +- .../rule/engine/edge/AbstractTbMsgPushNode.java | 2 +- .../edge/BaseTbMsgPushNodeConfiguration.java | 2 +- .../rule/engine/edge/TbMsgPushToCloudNode.java | 2 +- .../edge/TbMsgPushToCloudNodeConfiguration.java | 2 +- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 2 +- .../edge/TbMsgPushToEdgeNodeConfiguration.java | 2 +- .../engine/external/TbAbstractExternalNode.java | 2 +- .../engine/filter/TbAbstractTypeSwitchNode.java | 2 +- .../engine/filter/TbAssetTypeSwitchNode.java | 2 +- .../engine/filter/TbCheckAlarmStatusNode.java | 2 +- .../filter/TbCheckAlarmStatusNodeConfig.java | 2 +- .../rule/engine/filter/TbCheckMessageNode.java | 2 +- .../filter/TbCheckMessageNodeConfiguration.java | 2 +- .../rule/engine/filter/TbCheckRelationNode.java | 2 +- .../filter/TbCheckRelationNodeConfiguration.java | 2 +- .../engine/filter/TbDeviceTypeSwitchNode.java | 2 +- .../rule/engine/filter/TbJsFilterNode.java | 2 +- .../filter/TbJsFilterNodeConfiguration.java | 2 +- .../rule/engine/filter/TbJsSwitchNode.java | 2 +- .../filter/TbJsSwitchNodeConfiguration.java | 2 +- .../rule/engine/filter/TbMsgTypeFilterNode.java | 2 +- .../filter/TbMsgTypeFilterNodeConfiguration.java | 2 +- .../rule/engine/filter/TbMsgTypeSwitchNode.java | 2 +- .../filter/TbOriginatorTypeFilterNode.java | 2 +- .../TbOriginatorTypeFilterNodeConfiguration.java | 2 +- .../filter/TbOriginatorTypeSwitchNode.java | 2 +- .../thingsboard/rule/engine/flow/TbAckNode.java | 2 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../flow/TbCheckpointNodeConfiguration.java | 2 +- .../rule/engine/flow/TbRuleChainInputNode.java | 2 +- .../flow/TbRuleChainInputNodeConfiguration.java | 2 +- .../rule/engine/flow/TbRuleChainOutputNode.java | 2 +- .../rule/engine/gcp/pubsub/TbPubSubNode.java | 2 +- .../gcp/pubsub/TbPubSubNodeConfiguration.java | 2 +- .../rule/engine/geo/AbstractGeofencingNode.java | 2 +- .../thingsboard/rule/engine/geo/Coordinates.java | 2 +- .../rule/engine/geo/EntityGeofencingState.java | 2 +- .../org/thingsboard/rule/engine/geo/GeoUtil.java | 2 +- .../thingsboard/rule/engine/geo/Perimeter.java | 2 +- .../rule/engine/geo/PerimeterType.java | 2 +- .../thingsboard/rule/engine/geo/RangeUnit.java | 2 +- .../engine/geo/TbGpsGeofencingActionNode.java | 2 +- .../TbGpsGeofencingActionNodeConfiguration.java | 2 +- .../engine/geo/TbGpsGeofencingFilterNode.java | 2 +- .../TbGpsGeofencingFilterNodeConfiguration.java | 2 +- .../rule/engine/kafka/TbKafkaNode.java | 2 +- .../engine/kafka/TbKafkaNodeConfiguration.java | 2 +- .../rule/engine/mail/TbMsgToEmailNode.java | 2 +- .../mail/TbMsgToEmailNodeConfiguration.java | 2 +- .../rule/engine/mail/TbSendEmailNode.java | 2 +- .../mail/TbSendEmailNodeConfiguration.java | 2 +- .../rule/engine/math/TbMathArgument.java | 2 +- .../rule/engine/math/TbMathArgumentType.java | 2 +- .../rule/engine/math/TbMathArgumentValue.java | 2 +- .../thingsboard/rule/engine/math/TbMathNode.java | 2 +- .../engine/math/TbMathNodeConfiguration.java | 2 +- .../rule/engine/math/TbMathResult.java | 2 +- .../engine/math/TbRuleNodeMathFunctionType.java | 2 +- .../rule/engine/metadata/CalculateDeltaNode.java | 2 +- .../CalculateDeltaNodeConfiguration.java | 2 +- .../rule/engine/metadata/DataToFetch.java | 2 +- .../TbAbstractFetchToNodeConfiguration.java | 2 +- .../metadata/TbAbstractGetAttributesNode.java | 2 +- .../metadata/TbAbstractGetEntityDataNode.java | 2 +- .../metadata/TbAbstractGetEntityDetailsNode.java | 2 +- ...bstractGetEntityDetailsNodeConfiguration.java | 2 +- .../metadata/TbAbstractGetMappedDataNode.java | 2 +- .../metadata/TbAbstractNodeWithFetchTo.java | 2 +- .../metadata/TbFetchDeviceCredentialsNode.java | 2 +- ...bFetchDeviceCredentialsNodeConfiguration.java | 2 +- .../engine/metadata/TbGetAttributesNode.java | 2 +- .../TbGetAttributesNodeConfiguration.java | 2 +- .../metadata/TbGetCustomerAttributeNode.java | 2 +- .../metadata/TbGetCustomerDetailsNode.java | 2 +- .../TbGetCustomerDetailsNodeConfiguration.java | 2 +- .../engine/metadata/TbGetDeviceAttrNode.java | 2 +- .../TbGetDeviceAttrNodeConfiguration.java | 2 +- .../TbGetEntityDataNodeConfiguration.java | 2 +- .../TbGetMappedDataNodeConfiguration.java | 2 +- .../TbGetOriginatorFieldsConfiguration.java | 2 +- .../metadata/TbGetOriginatorFieldsNode.java | 2 +- .../metadata/TbGetRelatedAttributeNode.java | 2 +- .../TbGetRelatedDataNodeConfiguration.java | 2 +- .../rule/engine/metadata/TbGetTelemetryNode.java | 2 +- .../TbGetTelemetryNodeConfiguration.java | 2 +- .../metadata/TbGetTenantAttributeNode.java | 2 +- .../engine/metadata/TbGetTenantDetailsNode.java | 2 +- .../TbGetTenantDetailsNodeConfiguration.java | 2 +- .../thingsboard/rule/engine/mqtt/TbMqttNode.java | 2 +- .../engine/mqtt/TbMqttNodeConfiguration.java | 2 +- .../mqtt/azure/AzureIotHubSasCredentials.java | 2 +- .../engine/mqtt/azure/TbAzureIotHubNode.java | 2 +- .../azure/TbAzureIotHubNodeConfiguration.java | 2 +- .../engine/notification/TbNotificationNode.java | 2 +- .../TbNotificationNodeConfiguration.java | 2 +- .../rule/engine/notification/TbSlackNode.java | 2 +- .../notification/TbSlackNodeConfiguration.java | 2 +- .../rule/engine/profile/AlarmEvalResult.java | 2 +- .../rule/engine/profile/AlarmRuleState.java | 2 +- .../rule/engine/profile/AlarmState.java | 2 +- .../engine/profile/AlarmStateUpdateResult.java | 2 +- .../rule/engine/profile/DataSnapshot.java | 2 +- .../rule/engine/profile/DeviceState.java | 2 +- .../engine/profile/DynamicPredicateValueCtx.java | 2 +- .../profile/DynamicPredicateValueCtxImpl.java | 2 +- .../rule/engine/profile/EntityKeyValue.java | 2 +- .../engine/profile/NumericParseException.java | 2 +- .../rule/engine/profile/ProfileState.java | 2 +- .../rule/engine/profile/SnapshotUpdate.java | 2 +- .../rule/engine/profile/TbDeviceProfileNode.java | 2 +- .../TbDeviceProfileNodeConfiguration.java | 2 +- .../profile/state/PersistedAlarmRuleState.java | 2 +- .../profile/state/PersistedAlarmState.java | 2 +- .../profile/state/PersistedDeviceState.java | 2 +- .../rule/engine/rabbitmq/TbRabbitMqNode.java | 2 +- .../rabbitmq/TbRabbitMqNodeConfiguration.java | 2 +- .../rule/engine/rest/TbHttpClient.java | 2 +- .../rule/engine/rest/TbRestApiCallNode.java | 2 +- .../rest/TbRestApiCallNodeConfiguration.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNode.java | 2 +- .../rule/engine/rpc/TbSendRPCRequestNode.java | 2 +- .../rpc/TbSendRpcReplyNodeConfiguration.java | 2 +- .../rpc/TbSendRpcRequestNodeConfiguration.java | 2 +- .../rule/engine/sms/TbSendSmsNode.java | 2 +- .../engine/sms/TbSendSmsNodeConfiguration.java | 2 +- .../telemetry/AttributesDeleteNodeCallback.java | 2 +- .../telemetry/AttributesUpdateNodeCallback.java | 2 +- .../engine/telemetry/TbMsgAttributesNode.java | 2 +- .../TbMsgAttributesNodeConfiguration.java | 2 +- .../telemetry/TbMsgDeleteAttributesNode.java | 2 +- .../TbMsgDeleteAttributesNodeConfiguration.java | 2 +- .../engine/telemetry/TbMsgTimeseriesNode.java | 2 +- .../TbMsgTimeseriesNodeConfiguration.java | 2 +- .../engine/telemetry/TelemetryNodeCallback.java | 2 +- .../transaction/TbSynchronizationBeginNode.java | 2 +- .../transaction/TbSynchronizationEndNode.java | 2 +- .../transform/MultipleTbMsgsCallbackWrapper.java | 2 +- .../transform/TbAbstractTransformNode.java | 2 +- .../TbAbstractTransformNodeWithTbMsgSource.java | 2 +- .../engine/transform/TbChangeOriginatorNode.java | 2 +- .../TbChangeOriginatorNodeConfiguration.java | 2 +- .../rule/engine/transform/TbCopyKeysNode.java | 2 +- .../transform/TbCopyKeysNodeConfiguration.java | 2 +- .../rule/engine/transform/TbDeleteKeysNode.java | 2 +- .../transform/TbDeleteKeysNodeConfiguration.java | 2 +- .../rule/engine/transform/TbJsonPathNode.java | 2 +- .../transform/TbJsonPathNodeConfiguration.java | 2 +- .../engine/transform/TbMsgCallbackWrapper.java | 2 +- .../rule/engine/transform/TbRenameKeysNode.java | 2 +- .../transform/TbRenameKeysNodeConfiguration.java | 2 +- .../engine/transform/TbSplitArrayMsgNode.java | 2 +- .../engine/transform/TbTransformMsgNode.java | 2 +- .../TbTransformMsgNodeConfiguration.java | 2 +- .../engine/util/ContactBasedEntityDetails.java | 2 +- .../EntitiesAlarmOriginatorIdAsyncLoader.java | 2 +- .../engine/util/EntitiesByNameAndTypeLoader.java | 2 +- .../util/EntitiesCustomerIdAsyncLoader.java | 2 +- .../engine/util/EntitiesFieldsAsyncLoader.java | 2 +- .../util/EntitiesRelatedDeviceIdAsyncLoader.java | 2 +- .../util/EntitiesRelatedEntityIdAsyncLoader.java | 2 +- .../rule/engine/util/EntityContainer.java | 2 +- .../rule/engine/util/TbMsgSource.java | 2 +- .../rule/engine/util/TenantIdLoader.java | 2 +- .../rule/engine/TestDbCallbackExecutor.java | 2 +- .../rule/engine/action/TbAlarmNodeTest.java | 2 +- .../engine/action/TbCreateRelationNodeTest.java | 2 +- .../rule/engine/action/TbLogNodeTest.java | 2 +- .../credentials/CertPemCredentialsTest.java | 2 +- .../engine/edge/TbMsgPushToEdgeNodeTest.java | 2 +- .../engine/filter/TbAssetTypeSwitchNodeTest.java | 2 +- .../filter/TbCheckAlarmStatusNodeTest.java | 2 +- .../engine/filter/TbCheckMessageNodeTest.java | 2 +- .../engine/filter/TbCheckRelationNodeTest.java | 2 +- .../filter/TbDeviceTypeSwitchNodeTest.java | 2 +- .../rule/engine/filter/TbJsFilterNodeTest.java | 2 +- .../rule/engine/filter/TbJsSwitchNodeTest.java | 2 +- .../engine/filter/TbMsgTypeFilterNodeTest.java | 2 +- .../engine/filter/TbMsgTypeSwitchNodeTest.java | 2 +- .../filter/TbOriginatorTypeFilterNodeTest.java | 2 +- .../filter/TbOriginatorTypeSwitchNodeTest.java | 2 +- .../thingsboard/rule/engine/geo/GeoUtilTest.java | 2 +- .../geo/TbGpsGeofencingFilterNodeTest.java | 2 +- .../rule/engine/mail/TbMsgToEmailNodeTest.java | 2 +- .../engine/math/TbMathArgumentValueTest.java | 2 +- .../rule/engine/math/TbMathNodeTest.java | 2 +- .../engine/metadata/CalculateDeltaNodeTest.java | 2 +- .../TbFetchDeviceCredentialsNodeTest.java | 2 +- .../engine/metadata/TbGetAttributesNodeTest.java | 2 +- .../metadata/TbGetCustomerAttributeNodeTest.java | 2 +- .../metadata/TbGetCustomerDetailsNodeTest.java | 2 +- .../engine/metadata/TbGetDeviceAttrNodeTest.java | 2 +- .../metadata/TbGetOriginatorFieldsNodeTest.java | 2 +- .../metadata/TbGetRelatedAttributeNodeTest.java | 2 +- .../engine/metadata/TbGetTelemetryNodeTest.java | 2 +- .../metadata/TbGetTenantAttributeNodeTest.java | 2 +- .../metadata/TbGetTenantDetailsNodeTest.java | 2 +- .../rule/engine/profile/AlarmStateTest.java | 2 +- .../rule/engine/profile/DeviceStateTest.java | 2 +- .../engine/profile/TbDeviceProfileNodeTest.java | 2 +- .../rule/engine/rest/TbHttpClientTest.java | 2 +- .../rule/engine/rest/TbRestApiCallNodeTest.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNodeTest.java | 2 +- .../TbMsgAttributesNodeConfigurationTest.java | 2 +- .../telemetry/TbMsgAttributesNodeTest.java | 2 +- .../telemetry/TbMsgDeleteAttributesNodeTest.java | 2 +- .../transform/TbChangeOriginatorNodeTest.java | 2 +- .../engine/transform/TbCopyKeysNodeTest.java | 2 +- .../engine/transform/TbDeleteKeysNodeTest.java | 2 +- .../engine/transform/TbJsonPathNodeTest.java | 2 +- .../transform/TbMsgDeduplicationNodeTest.java | 2 +- .../engine/transform/TbRenameKeysNodeTest.java | 2 +- .../transform/TbSplitArrayMsgNodeTest.java | 2 +- .../engine/transform/TbTransformMsgNodeTest.java | 2 +- .../util/EntitiesCustomerIdAsyncLoaderTest.java | 2 +- .../util/EntitiesFieldsAsyncLoaderTest.java | 2 +- .../EntitiesRelatedDeviceIdAsyncLoaderTest.java | 2 +- .../EntitiesRelatedEntityIdAsyncLoaderTest.java | 2 +- .../rule/engine/util/TenantIdLoaderTest.java | 2 +- tools/pom.xml | 2 +- .../thingsboard/client/tools/MqttSslClient.java | 2 +- .../client/tools/migrator/DictionaryParser.java | 2 +- .../client/tools/migrator/MigratorTool.java | 2 +- .../client/tools/migrator/PgCaMigrator.java | 2 +- .../tools/migrator/RelatedEntitiesParser.java | 2 +- .../client/tools/migrator/WriterBuilder.java | 2 +- tools/src/main/python/check_yml_file.py | 2 +- tools/src/main/python/mqtt-send-telemetry.py | 2 +- tools/src/main/python/one-way-ssl-mqtt-client.py | 2 +- tools/src/main/python/simple-mqtt-client.py | 2 +- tools/src/main/python/two-way-ssl-mqtt-client.py | 2 +- tools/src/main/shell/client.keygen.sh | 2 +- .../lwm2m/lwM2M_cfssl_chain_clients_for_test.sh | 2 +- .../lwm2m/lwm2m_cfssl_chain_all_for_test.sh | 2 +- .../lwm2m/lwm2m_cfssl_chain_server_for_test.sh | 2 +- tools/src/main/shell/server.keygen.sh | 2 +- transport/coap/pom.xml | 2 +- transport/coap/src/main/conf/logback.xml | 2 +- .../coap/src/main/conf/tb-coap-transport.conf | 2 +- .../ThingsboardCoapTransportApplication.java | 2 +- transport/coap/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-coap-transport.yml | 2 +- transport/http/pom.xml | 2 +- transport/http/src/main/conf/logback.xml | 2 +- .../http/src/main/conf/tb-http-transport.conf | 2 +- .../ThingsboardHttpTransportApplication.java | 2 +- transport/http/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-http-transport.yml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/lwm2m/src/main/conf/logback.xml | 2 +- .../lwm2m/src/main/conf/tb-lwm2m-transport.conf | 2 +- .../ThingsboardLwm2mTransportApplication.java | 2 +- transport/lwm2m/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-lwm2m-transport.yml | 2 +- transport/mqtt/pom.xml | 2 +- transport/mqtt/src/main/conf/logback.xml | 2 +- .../mqtt/src/main/conf/tb-mqtt-transport.conf | 2 +- .../ThingsboardMqttTransportApplication.java | 2 +- transport/mqtt/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-mqtt-transport.yml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- transport/snmp/src/main/conf/logback.xml | 2 +- .../snmp/src/main/conf/tb-snmp-transport.conf | 2 +- .../ThingsboardSnmpTransportApplication.java | 2 +- transport/snmp/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-snmp-transport.yml | 2 +- ui-ngx/.editorconfig | 2 +- ui-ngx/e2e/protractor.conf.js | 2 +- ui-ngx/e2e/src/app.e2e-spec.ts | 2 +- ui-ngx/e2e/src/app.po.ts | 2 +- ui-ngx/extra-webpack.config.js | 2 +- ui-ngx/generate-types.js | 2 +- ui-ngx/pom.xml | 2 +- ui-ngx/proxy.conf.js | 2 +- ui-ngx/src/app/app-routing.module.ts | 2 +- ui-ngx/src/app/app.component.html | 2 +- ui-ngx/src/app/app.component.scss | 2 +- ui-ngx/src/app/app.component.ts | 2 +- ui-ngx/src/app/app.module.ts | 2 +- .../src/app/core/api/alarm-data-subscription.ts | 2 +- ui-ngx/src/app/core/api/alarm-data.service.ts | 2 +- ui-ngx/src/app/core/api/alias-controller.ts | 2 +- ui-ngx/src/app/core/api/data-aggregator.ts | 2 +- .../src/app/core/api/entity-data-subscription.ts | 2 +- ui-ngx/src/app/core/api/entity-data.service.ts | 2 +- ui-ngx/src/app/core/api/public-api.ts | 2 +- ui-ngx/src/app/core/api/widget-api.models.ts | 2 +- ui-ngx/src/app/core/api/widget-subscription.ts | 2 +- ui-ngx/src/app/core/auth/auth.actions.ts | 2 +- ui-ngx/src/app/core/auth/auth.effects.ts | 2 +- ui-ngx/src/app/core/auth/auth.models.ts | 2 +- ui-ngx/src/app/core/auth/auth.reducer.ts | 2 +- ui-ngx/src/app/core/auth/auth.selectors.ts | 2 +- ui-ngx/src/app/core/auth/auth.service.spec.ts | 2 +- ui-ngx/src/app/core/auth/auth.service.ts | 2 +- ui-ngx/src/app/core/auth/public-api.ts | 2 +- ui-ngx/src/app/core/core.module.ts | 2 +- ui-ngx/src/app/core/core.state.ts | 2 +- ui-ngx/src/app/core/css/css.js | 2 +- ui-ngx/src/app/core/guards/auth.guard.ts | 2 +- .../src/app/core/guards/confirm-on-exit.guard.ts | 2 +- ui-ngx/src/app/core/http/admin.service.ts | 2 +- .../src/app/core/http/alarm-comment.service.ts | 2 +- ui-ngx/src/app/core/http/alarm.service.ts | 2 +- .../src/app/core/http/asset-profile.service.ts | 2 +- ui-ngx/src/app/core/http/asset.service.ts | 2 +- ui-ngx/src/app/core/http/attribute.service.ts | 2 +- ui-ngx/src/app/core/http/audit-log.service.ts | 2 +- .../core/http/component-descriptor.service.ts | 2 +- ui-ngx/src/app/core/http/customer.service.ts | 2 +- ui-ngx/src/app/core/http/dashboard.service.ts | 2 +- .../src/app/core/http/device-profile.service.ts | 2 +- ui-ngx/src/app/core/http/device.service.ts | 2 +- ui-ngx/src/app/core/http/edge.service.ts | 2 +- .../http/entities-version-control.service.ts | 2 +- .../src/app/core/http/entity-relation.service.ts | 2 +- ui-ngx/src/app/core/http/entity-view.service.ts | 2 +- ui-ngx/src/app/core/http/entity.service.ts | 2 +- ui-ngx/src/app/core/http/event.service.ts | 2 +- ui-ngx/src/app/core/http/http-utils.ts | 2 +- ui-ngx/src/app/core/http/image.service.ts | 2 +- ui-ngx/src/app/core/http/notification.service.ts | 2 +- ui-ngx/src/app/core/http/oauth2.service.ts | 2 +- ui-ngx/src/app/core/http/ota-package.service.ts | 2 +- ui-ngx/src/app/core/http/public-api.ts | 2 +- ui-ngx/src/app/core/http/queue.service.ts | 2 +- ui-ngx/src/app/core/http/resource.service.ts | 2 +- ui-ngx/src/app/core/http/rule-chain.service.ts | 2 +- .../src/app/core/http/tenant-profile.service.ts | 2 +- ui-ngx/src/app/core/http/tenant.service.ts | 2 +- .../http/two-factor-authentication.service.ts | 2 +- ui-ngx/src/app/core/http/ui-settings.service.ts | 2 +- ui-ngx/src/app/core/http/usage-info.service.ts | 2 +- .../src/app/core/http/user-settings.service.ts | 2 +- ui-ngx/src/app/core/http/user.service.ts | 2 +- ui-ngx/src/app/core/http/widget.service.ts | 2 +- .../core/interceptors/global-http-interceptor.ts | 2 +- .../app/core/interceptors/interceptor-config.ts | 2 +- .../core/interceptors/interceptor-http-params.ts | 2 +- ui-ngx/src/app/core/interceptors/load.actions.ts | 2 +- ui-ngx/src/app/core/interceptors/load.models.ts | 2 +- ui-ngx/src/app/core/interceptors/load.reducer.ts | 2 +- .../src/app/core/interceptors/load.selectors.ts | 2 +- .../core/local-storage/local-storage.service.ts | 2 +- .../src/app/core/meta-reducers/debug.reducer.ts | 2 +- .../init-state-from-local-storage.reducer.ts | 2 +- .../core/notification/notification.actions.ts | 2 +- .../core/notification/notification.effects.ts | 2 +- .../app/core/notification/notification.models.ts | 2 +- .../core/notification/notification.reducer.ts | 2 +- ui-ngx/src/app/core/operator/enterZone.ts | 2 +- ui-ngx/src/app/core/public-api.ts | 2 +- .../core/services/active-component.service.ts | 2 +- ui-ngx/src/app/core/services/broadcast.models.ts | 2 +- .../src/app/core/services/broadcast.service.ts | 2 +- .../app/core/services/dashboard-utils.service.ts | 2 +- ui-ngx/src/app/core/services/dialog.service.ts | 2 +- .../dynamic-component-factory.service.ts | 2 +- ui-ngx/src/app/core/services/help.service.ts | 2 +- .../src/app/core/services/item-buffer.service.ts | 2 +- ui-ngx/src/app/core/services/menu.models.ts | 2 +- ui-ngx/src/app/core/services/menu.service.ts | 2 +- ui-ngx/src/app/core/services/mobile.service.ts | 2 +- ui-ngx/src/app/core/services/public-api.ts | 2 +- ui-ngx/src/app/core/services/raf.service.ts | 2 +- .../src/app/core/services/resources.service.ts | 2 +- .../services/script/node-script-test.service.ts | 2 +- ui-ngx/src/app/core/services/time.service.ts | 2 +- ui-ngx/src/app/core/services/title.service.ts | 2 +- .../core/services/toast-notification.service.ts | 2 +- ui-ngx/src/app/core/services/utils.service.ts | 2 +- ui-ngx/src/app/core/services/window.service.ts | 2 +- ui-ngx/src/app/core/settings/settings.actions.ts | 2 +- ui-ngx/src/app/core/settings/settings.effects.ts | 2 +- ui-ngx/src/app/core/settings/settings.models.ts | 2 +- ui-ngx/src/app/core/settings/settings.reducer.ts | 2 +- .../src/app/core/settings/settings.selectors.ts | 2 +- ui-ngx/src/app/core/settings/settings.utils.ts | 2 +- .../core/translate/missing-translate-handler.ts | 2 +- .../core/translate/translate-default-compiler.ts | 2 +- .../core/translate/translate-default-parser.ts | 2 +- ui-ngx/src/app/core/utils.ts | 2 +- .../core/ws/notification-websocket.service.ts | 2 +- ui-ngx/src/app/core/ws/public-api.ts | 2 +- .../app/core/ws/telemetry-websocket.service.ts | 2 +- ui-ngx/src/app/core/ws/websocket.service.ts | 2 +- .../src/app/modules/common/modules-map.models.ts | 2 +- ui-ngx/src/app/modules/common/modules-map.ts | 2 +- .../modules/dashboard/dashboard-pages.module.ts | 2 +- .../dashboard/dashboard-pages.routing.module.ts | 2 +- .../dashboard/dashboard-routing.module.ts | 2 +- .../alarm/alarm-assignee-panel.component.html | 2 +- .../alarm/alarm-assignee-panel.component.scss | 3 +-- .../alarm/alarm-assignee-panel.component.ts | 2 +- .../alarm-assignee-select-panel.component.ts | 2 +- .../alarm/alarm-assignee-select.component.html | 2 +- .../alarm/alarm-assignee-select.component.ts | 2 +- .../alarm/alarm-assignee.component.html | 3 +-- .../alarm/alarm-assignee.component.scss | 3 +-- .../components/alarm/alarm-assignee.component.ts | 2 +- .../alarm/alarm-comment-dialog.component.html | 2 +- .../alarm/alarm-comment-dialog.component.ts | 2 +- .../alarm/alarm-comment.component.html | 3 +-- .../alarm/alarm-comment.component.scss | 2 +- .../components/alarm/alarm-comment.component.ts | 2 +- .../alarm/alarm-details-dialog.component.html | 2 +- .../alarm/alarm-details-dialog.component.scss | 3 +-- .../alarm/alarm-details-dialog.component.ts | 2 +- .../alarm/alarm-filter-config.component.html | 2 +- .../alarm/alarm-filter-config.component.scss | 2 +- .../alarm/alarm-filter-config.component.ts | 2 +- .../home/components/alarm/alarm-table-config.ts | 2 +- .../alarm/alarm-table-header.component.html | 2 +- .../alarm/alarm-table-header.component.scss | 2 +- .../alarm/alarm-table-header.component.ts | 2 +- .../components/alarm/alarm-table.component.html | 2 +- .../components/alarm/alarm-table.component.scss | 2 +- .../components/alarm/alarm-table.component.ts | 2 +- .../aliases-entity-autocomplete.component.html | 2 +- .../aliases-entity-autocomplete.component.ts | 2 +- .../aliases-entity-select-panel.component.html | 2 +- .../aliases-entity-select-panel.component.scss | 2 +- .../aliases-entity-select-panel.component.ts | 2 +- .../alias/aliases-entity-select.component.html | 2 +- .../alias/aliases-entity-select.component.scss | 2 +- .../alias/aliases-entity-select.component.ts | 2 +- .../alias/entity-alias-dialog.component.html | 2 +- .../alias/entity-alias-dialog.component.scss | 2 +- .../alias/entity-alias-dialog.component.ts | 2 +- .../alias/entity-alias-select.component.html | 2 +- .../entity-alias-select.component.models.ts | 2 +- .../alias/entity-alias-select.component.scss | 2 +- .../alias/entity-alias-select.component.ts | 2 +- .../alias/entity-aliases-dialog.component.html | 2 +- .../alias/entity-aliases-dialog.component.scss | 2 +- .../alias/entity-aliases-dialog.component.ts | 2 +- .../add-attribute-dialog.component.html | 2 +- .../attribute/add-attribute-dialog.component.ts | 2 +- ...add-widget-to-dashboard-dialog.component.html | 2 +- ...add-widget-to-dashboard-dialog.component.scss | 2 +- .../add-widget-to-dashboard-dialog.component.ts | 2 +- .../attribute/attribute-table.component.html | 2 +- .../attribute/attribute-table.component.scss | 2 +- .../attribute/attribute-table.component.ts | 2 +- .../delete-timeseries-panel.component.html | 3 +-- .../delete-timeseries-panel.component.scss | 2 +- .../delete-timeseries-panel.component.ts | 2 +- .../edit-attribute-value-panel.component.html | 2 +- .../edit-attribute-value-panel.component.scss | 2 +- .../edit-attribute-value-panel.component.ts | 2 +- .../audit-log-details-dialog.component.html | 2 +- .../audit-log-details-dialog.component.scss | 2 +- .../audit-log-details-dialog.component.ts | 2 +- .../audit-log/audit-log-table-config.ts | 2 +- .../audit-log/audit-log-table.component.html | 2 +- .../audit-log/audit-log-table.component.scss | 2 +- .../audit-log/audit-log-table.component.ts | 2 +- .../add-widget-dialog.component.html | 2 +- .../add-widget-dialog.component.scss | 2 +- .../add-widget-dialog.component.ts | 2 +- .../dashboard-image-dialog.component.html | 2 +- .../dashboard-image-dialog.component.scss | 2 +- .../dashboard-image-dialog.component.ts | 2 +- .../dashboard-page/dashboard-page.component.html | 2 +- .../dashboard-page/dashboard-page.component.scss | 2 +- .../dashboard-page/dashboard-page.component.ts | 2 +- .../dashboard-page/dashboard-page.models.ts | 2 +- .../dashboard-settings-dialog.component.html | 2 +- .../dashboard-settings-dialog.component.scss | 2 +- .../dashboard-settings-dialog.component.ts | 2 +- .../dashboard-state.component.html | 2 +- .../dashboard-state.component.scss | 2 +- .../dashboard-page/dashboard-state.component.ts | 2 +- .../dashboard-toolbar.component.html | 2 +- .../dashboard-toolbar.component.scss | 2 +- .../dashboard-toolbar.component.ts | 2 +- .../dashboard-widget-select.component.html | 2 +- .../dashboard-widget-select.component.scss | 3 +-- .../dashboard-widget-select.component.ts | 2 +- .../dashboard-page/edit-widget.component.html | 2 +- .../dashboard-page/edit-widget.component.scss | 2 +- .../dashboard-page/edit-widget.component.ts | 2 +- .../layout/dashboard-layout.component.html | 2 +- .../layout/dashboard-layout.component.scss | 2 +- .../layout/dashboard-layout.component.ts | 2 +- .../dashboard-page/layout/layout.models.ts | 2 +- ...anage-dashboard-layouts-dialog.component.html | 2 +- ...anage-dashboard-layouts-dialog.component.scss | 2 +- .../manage-dashboard-layouts-dialog.component.ts | 2 +- .../states/dashboard-state-dialog.component.html | 2 +- .../states/dashboard-state-dialog.component.ts | 2 +- .../default-state-controller.component.html | 2 +- .../default-state-controller.component.scss | 2 +- .../states/default-state-controller.component.ts | 2 +- .../entity-state-controller.component.html | 2 +- .../entity-state-controller.component.scss | 2 +- .../states/entity-state-controller.component.ts | 2 +- ...manage-dashboard-states-dialog.component.html | 2 +- ...e-dashboard-states-dialog.component.models.ts | 2 +- ...manage-dashboard-states-dialog.component.scss | 2 +- .../manage-dashboard-states-dialog.component.ts | 2 +- .../states/state-controller.component.ts | 2 +- .../states/state-controller.models.ts | 2 +- .../states/states-component.directive.ts | 2 +- .../states/states-controller.module.ts | 2 +- .../states/states-controller.service.ts | 2 +- .../widget-types-panel.component.html | 2 +- .../widget-types-panel.component.scss | 2 +- .../widget-types-panel.component.ts | 2 +- .../dashboard/dashboard.component.html | 2 +- .../dashboard/dashboard.component.scss | 2 +- .../components/dashboard/dashboard.component.ts | 2 +- .../home/components/dashboard/layout-button.scss | 2 +- .../select-target-layout-dialog.component.html | 2 +- .../select-target-layout-dialog.component.ts | 2 +- .../select-target-state-dialog.component.html | 2 +- .../select-target-state-dialog.component.ts | 2 +- .../home/components/details-panel.component.html | 2 +- .../home/components/details-panel.component.scss | 2 +- .../home/components/details-panel.component.ts | 2 +- .../copy-device-credentials.component.html | 2 +- .../device/copy-device-credentials.component.ts | 2 +- ...evice-credentials-lwm2m-server.component.html | 2 +- .../device-credentials-lwm2m-server.component.ts | 2 +- .../device-credentials-lwm2m.component.html | 2 +- .../device-credentials-lwm2m.component.scss | 2 +- .../device/device-credentials-lwm2m.component.ts | 2 +- .../device-credentials-mqtt-basic.component.html | 2 +- .../device-credentials-mqtt-basic.component.ts | 2 +- .../device/device-credentials.component.html | 2 +- .../device/device-credentials.component.scss | 2 +- .../device/device-credentials.component.ts | 2 +- .../device/device-credentials.module.ts | 2 +- .../device/device-info-filter.component.html | 2 +- .../device/device-info-filter.component.scss | 2 +- .../device/device-info-filter.component.ts | 2 +- .../edge/edge-downlink-table-config.ts | 2 +- .../edge-downlink-table-header.component.html | 2 +- .../edge-downlink-table-header.component.scss | 2 +- .../edge/edge-downlink-table-header.component.ts | 2 +- .../edge/edge-downlink-table.component.html | 2 +- .../edge/edge-downlink-table.component.scss | 2 +- .../edge/edge-downlink-table.component.ts | 2 +- .../entity/add-entity-dialog.component.html | 2 +- .../entity/add-entity-dialog.component.scss | 2 +- .../entity/add-entity-dialog.component.ts | 2 +- .../components/entity/contact-based.component.ts | 2 +- .../entity/entities-table.component.html | 2 +- .../entity/entities-table.component.scss | 2 +- .../entity/entities-table.component.ts | 2 +- .../entity/entity-details-page.component.html | 2 +- .../entity/entity-details-page.component.scss | 2 +- .../entity/entity-details-page.component.ts | 2 +- .../entity/entity-details-panel.component.html | 2 +- .../entity/entity-details-panel.component.scss | 2 +- .../entity/entity-details-panel.component.ts | 2 +- .../entity/entity-filter-view.component.html | 2 +- .../entity/entity-filter-view.component.scss | 2 +- .../entity/entity-filter-view.component.ts | 2 +- .../entity/entity-filter.component.html | 2 +- .../entity/entity-filter.component.scss | 2 +- .../components/entity/entity-filter.component.ts | 2 +- .../entity/entity-table-header.component.ts | 2 +- .../components/entity/entity-tabs.component.ts | 2 +- .../home/components/entity/entity.component.ts | 2 +- .../event/event-content-dialog.component.html | 2 +- .../event/event-content-dialog.component.scss | 2 +- .../event/event-content-dialog.component.ts | 2 +- .../event/event-filter-panel.component.html | 2 +- .../event/event-filter-panel.component.scss | 2 +- .../event/event-filter-panel.component.ts | 2 +- .../home/components/event/event-table-config.ts | 2 +- .../event/event-table-header.component.html | 2 +- .../event/event-table-header.component.scss | 2 +- .../event/event-table-header.component.ts | 2 +- .../components/event/event-table.component.html | 2 +- .../components/event/event-table.component.scss | 2 +- .../components/event/event-table.component.ts | 2 +- .../boolean-filter-predicate.component.html | 2 +- .../filter/boolean-filter-predicate.component.ts | 2 +- ...omplex-filter-predicate-dialog.component.html | 2 +- .../complex-filter-predicate-dialog.component.ts | 2 +- .../complex-filter-predicate.component.html | 2 +- .../filter/complex-filter-predicate.component.ts | 2 +- .../components/filter/filter-component.models.ts | 2 +- .../filter/filter-dialog.component.html | 2 +- .../filter/filter-dialog.component.scss | 2 +- .../components/filter/filter-dialog.component.ts | 2 +- .../filter/filter-predicate-list.component.html | 2 +- .../filter/filter-predicate-list.component.scss | 2 +- .../filter/filter-predicate-list.component.ts | 2 +- .../filter/filter-predicate-value.component.html | 2 +- .../filter/filter-predicate-value.component.ts | 2 +- .../filter/filter-predicate.component.html | 2 +- .../filter/filter-predicate.component.ts | 2 +- .../home/components/filter/filter-predicate.scss | 2 +- .../filter/filter-select.component.html | 2 +- .../filter/filter-select.component.models.ts | 2 +- .../components/filter/filter-select.component.ts | 2 +- .../components/filter/filter-text.component.html | 2 +- .../components/filter/filter-text.component.scss | 2 +- .../components/filter/filter-text.component.ts | 2 +- .../filter-user-info-dialog.component.html | 2 +- .../filter/filter-user-info-dialog.component.ts | 2 +- .../filter/filter-user-info.component.html | 2 +- .../filter/filter-user-info.component.ts | 2 +- .../filter/filters-dialog.component.html | 2 +- .../filter/filters-dialog.component.scss | 2 +- .../filter/filters-dialog.component.ts | 2 +- .../filter/filters-edit-panel.component.html | 2 +- .../filter/filters-edit-panel.component.scss | 2 +- .../filter/filters-edit-panel.component.ts | 2 +- .../filter/filters-edit.component.html | 2 +- .../filter/filters-edit.component.scss | 2 +- .../components/filter/filters-edit.component.ts | 2 +- .../filter/key-filter-dialog.component.html | 2 +- .../filter/key-filter-dialog.component.scss | 2 +- .../filter/key-filter-dialog.component.ts | 2 +- .../filter/key-filter-list.component.html | 2 +- .../filter/key-filter-list.component.scss | 2 +- .../filter/key-filter-list.component.ts | 2 +- .../numeric-filter-predicate.component.html | 2 +- .../filter/numeric-filter-predicate.component.ts | 2 +- .../string-filter-predicate.component.html | 2 +- .../filter/string-filter-predicate.component.ts | 2 +- .../filter/user-filter-dialog.component.html | 2 +- .../filter/user-filter-dialog.component.ts | 2 +- .../home/components/home-components.module.ts | 2 +- .../notification-bell.component.html | 2 +- .../notification/notification-bell.component.ts | 2 +- .../send-notification-button.component.html | 2 +- .../send-notification-button.component.ts | 2 +- .../show-notification-popover.component.html | 2 +- .../show-notification-popover.component.ts | 2 +- .../add-device-profile-dialog.component.html | 2 +- .../add-device-profile-dialog.component.scss | 2 +- .../add-device-profile-dialog.component.ts | 2 +- ...alarm-duration-predicate-value.component.html | 2 +- .../alarm-duration-predicate-value.component.ts | 2 +- .../alarm/alarm-dynamic-value.component.html | 2 +- .../alarm/alarm-dynamic-value.component.ts | 2 +- .../alarm-rule-condition-dialog.component.html | 2 +- .../alarm-rule-condition-dialog.component.scss | 2 +- .../alarm-rule-condition-dialog.component.ts | 2 +- .../alarm/alarm-rule-condition.component.html | 2 +- .../alarm/alarm-rule-condition.component.scss | 2 +- .../alarm/alarm-rule-condition.component.ts | 2 +- .../profile/alarm/alarm-rule.component.html | 2 +- .../profile/alarm/alarm-rule.component.scss | 2 +- .../profile/alarm/alarm-rule.component.ts | 2 +- .../alarm/alarm-schedule-dialog.component.html | 2 +- .../alarm/alarm-schedule-dialog.component.ts | 2 +- .../alarm/alarm-schedule-info.component.html | 2 +- .../alarm/alarm-schedule-info.component.scss | 2 +- .../alarm/alarm-schedule-info.component.ts | 2 +- .../profile/alarm/alarm-schedule.component.html | 2 +- .../profile/alarm/alarm-schedule.component.scss | 2 +- .../profile/alarm/alarm-schedule.component.ts | 2 +- .../alarm/create-alarm-rules.component.html | 2 +- .../alarm/create-alarm-rules.component.scss | 2 +- .../alarm/create-alarm-rules.component.ts | 2 +- .../alarm/device-profile-alarm.component.html | 2 +- .../alarm/device-profile-alarm.component.scss | 2 +- .../alarm/device-profile-alarm.component.ts | 2 +- .../alarm/device-profile-alarms.component.html | 2 +- .../alarm/device-profile-alarms.component.scss | 2 +- .../alarm/device-profile-alarms.component.ts | 2 +- .../edit-alarm-details-dialog.component.html | 2 +- .../alarm/edit-alarm-details-dialog.component.ts | 2 +- .../asset-profile-autocomplete.component.html | 2 +- .../asset-profile-autocomplete.component.scss | 2 +- .../asset-profile-autocomplete.component.ts | 2 +- .../profile/asset-profile-dialog.component.html | 2 +- .../profile/asset-profile-dialog.component.ts | 2 +- .../profile/asset-profile.component.html | 2 +- .../profile/asset-profile.component.ts | 2 +- .../device-profile-autocomplete.component.html | 2 +- .../device-profile-autocomplete.component.scss | 2 +- .../device-profile-autocomplete.component.ts | 2 +- .../profile/device-profile-dialog.component.html | 2 +- .../profile/device-profile-dialog.component.ts | 2 +- ...rofile-provision-configuration.component.html | 2 +- ...-profile-provision-configuration.component.ts | 2 +- .../profile/device-profile.component.html | 2 +- .../profile/device-profile.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../common/device-profile-common.module.ts | 2 +- .../common/power-mode-setting.component.html | 2 +- .../common/power-mode-setting.component.ts | 2 +- .../common/time-unit-select.component.html | 2 +- .../device/common/time-unit-select.component.ts | 2 +- ...t-device-profile-configuration.component.html | 2 +- ...ult-device-profile-configuration.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../device-profile-configuration.component.html | 2 +- .../device-profile-configuration.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../lwm2m/lwm2m-attributes-dialog.component.html | 2 +- .../lwm2m/lwm2m-attributes-dialog.component.ts | 2 +- .../lwm2m-attributes-key-list.component.html | 2 +- .../lwm2m-attributes-key-list.component.scss | 2 +- .../lwm2m/lwm2m-attributes-key-list.component.ts | 2 +- .../device/lwm2m/lwm2m-attributes.component.html | 2 +- .../device/lwm2m/lwm2m-attributes.component.ts | 2 +- ...strap-add-config-server-dialog.component.html | 2 +- ...otstrap-add-config-server-dialog.component.ts | 2 +- ...lwm2m-bootstrap-config-servers.component.html | 2 +- .../lwm2m-bootstrap-config-servers.component.ts | 2 +- .../lwm2m-device-config-server.component.html | 2 +- .../lwm2m-device-config-server.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- ...2m-object-add-instances-dialog.component.html | 2 +- ...wm2m-object-add-instances-dialog.component.ts | 2 +- ...wm2m-object-add-instances-list.component.html | 2 +- .../lwm2m-object-add-instances-list.component.ts | 2 +- .../lwm2m/lwm2m-object-list.component.html | 2 +- .../device/lwm2m/lwm2m-object-list.component.ts | 2 +- ...serve-attr-telemetry-instances.component.html | 2 +- ...serve-attr-telemetry-instances.component.scss | 2 +- ...observe-attr-telemetry-instances.component.ts | 2 +- ...serve-attr-telemetry-resources.component.html | 2 +- ...serve-attr-telemetry-resources.component.scss | 2 +- ...observe-attr-telemetry-resources.component.ts | 2 +- .../lwm2m-observe-attr-telemetry.component.html | 2 +- .../lwm2m-observe-attr-telemetry.component.scss | 2 +- .../lwm2m-observe-attr-telemetry.component.ts | 2 +- .../lwm2m/lwm2m-profile-components.module.ts | 2 +- .../device/lwm2m/lwm2m-profile-config.models.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- ...e-profile-communication-config.component.html | 2 +- ...e-profile-communication-config.component.scss | 2 +- ...ice-profile-communication-config.component.ts | 2 +- .../snmp-device-profile-mapping.component.html | 2 +- .../snmp-device-profile-mapping.component.scss | 2 +- .../snmp-device-profile-mapping.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../snmp/snmp-device-profile-transport.module.ts | 2 +- .../queue/tenant-profile-queues.component.html | 2 +- .../queue/tenant-profile-queues.component.scss | 2 +- .../queue/tenant-profile-queues.component.ts | 2 +- .../tenant-profile-autocomplete.component.html | 2 +- .../tenant-profile-autocomplete.component.scss | 2 +- .../tenant-profile-autocomplete.component.ts | 2 +- .../profile/tenant-profile-data.component.html | 2 +- .../profile/tenant-profile-data.component.ts | 2 +- .../profile/tenant-profile-dialog.component.html | 2 +- .../profile/tenant-profile-dialog.component.scss | 2 +- .../profile/tenant-profile-dialog.component.ts | 2 +- .../profile/tenant-profile.component.html | 2 +- .../profile/tenant-profile.component.scss | 2 +- .../profile/tenant-profile.component.ts | 2 +- ...t-tenant-profile-configuration.component.html | 2 +- ...t-tenant-profile-configuration.component.scss | 2 +- ...ult-tenant-profile-configuration.component.ts | 2 +- .../rate-limits-details-dialog.component.html | 2 +- .../rate-limits-details-dialog.component.ts | 2 +- .../rate-limits/rate-limits-list.component.html | 2 +- .../rate-limits/rate-limits-list.component.scss | 2 +- .../rate-limits/rate-limits-list.component.ts | 2 +- .../rate-limits/rate-limits-text.component.html | 2 +- .../rate-limits/rate-limits-text.component.scss | 2 +- .../rate-limits/rate-limits-text.component.ts | 2 +- .../rate-limits/rate-limits.component.html | 2 +- .../rate-limits/rate-limits.component.scss | 2 +- .../tenant/rate-limits/rate-limits.component.ts | 2 +- .../tenant/rate-limits/rate-limits.models.ts | 2 +- .../tenant-profile-configuration.component.html | 2 +- .../tenant-profile-configuration.component.ts | 2 +- .../app/modules/home/components/public-api.ts | 2 +- .../components/queue/queue-form.component.html | 2 +- .../components/queue/queue-form.component.scss | 2 +- .../components/queue/queue-form.component.ts | 2 +- .../relation/relation-dialog.component.html | 2 +- .../relation/relation-dialog.component.scss | 2 +- .../relation/relation-dialog.component.ts | 2 +- .../relation/relation-filters.component.html | 2 +- .../relation/relation-filters.component.scss | 2 +- .../relation/relation-filters.component.ts | 2 +- .../relation/relation-table.component.html | 2 +- .../relation/relation-table.component.scss | 2 +- .../relation/relation-table.component.ts | 2 +- .../home/components/router-tabs.component.html | 2 +- .../home/components/router-tabs.component.scss | 2 +- .../home/components/router-tabs.component.ts | 2 +- .../rule-chain-autocomplete.component.html | 2 +- .../rule-chain-autocomplete.component.ts | 2 +- .../components/shared-home-components.module.ts | 2 +- ...aws-sns-provider-configuration.component.html | 2 +- .../aws-sns-provider-configuration.component.ts | 2 +- ...mpp-sms-provider-configuration.component.html | 2 +- .../smpp-sms-provider-configuration.component.ts | 2 +- .../sms-provider-configuration.component.html | 2 +- .../sms/sms-provider-configuration.component.ts | 2 +- ...lio-sms-provider-configuration.component.html | 2 +- ...wilio-sms-provider-configuration.component.ts | 2 +- ui-ngx/src/app/modules/home/components/tokens.ts | 2 +- .../vc/auto-commit-settings.component.html | 2 +- .../vc/auto-commit-settings.component.scss | 2 +- .../vc/auto-commit-settings.component.ts | 2 +- .../vc/complex-version-create.component.html | 2 +- .../vc/complex-version-create.component.ts | 2 +- .../vc/complex-version-load.component.html | 2 +- .../vc/complex-version-load.component.ts | 2 +- .../entity-types-version-create.component.html | 2 +- .../vc/entity-types-version-create.component.ts | 2 +- .../vc/entity-types-version-load.component.html | 2 +- .../vc/entity-types-version-load.component.ts | 2 +- .../vc/entity-types-version.component.scss | 2 +- .../vc/entity-version-create.component.html | 2 +- .../vc/entity-version-create.component.ts | 2 +- .../vc/entity-version-diff.component.html | 2 +- .../vc/entity-version-diff.component.scss | 2 +- .../vc/entity-version-diff.component.ts | 2 +- .../vc/entity-version-restore.component.html | 2 +- .../vc/entity-version-restore.component.ts | 2 +- .../vc/entity-versions-table.component.html | 2 +- .../vc/entity-versions-table.component.scss | 2 +- .../vc/entity-versions-table.component.ts | 2 +- .../remove-other-entities-confirm.component.html | 2 +- .../remove-other-entities-confirm.component.ts | 2 +- .../vc/repository-settings.component.html | 2 +- .../vc/repository-settings.component.scss | 2 +- .../vc/repository-settings.component.ts | 2 +- .../components/vc/version-control.component.html | 2 +- .../components/vc/version-control.component.scss | 2 +- .../components/vc/version-control.component.ts | 2 +- .../home/components/vc/version-control.scss | 2 +- .../custom-action-pretty-editor.component.html | 2 +- .../custom-action-pretty-editor.component.scss | 2 +- .../custom-action-pretty-editor.component.ts | 2 +- ...m-action-pretty-resources-tabs.component.html | 2 +- ...m-action-pretty-resources-tabs.component.scss | 2 +- ...tom-action-pretty-resources-tabs.component.ts | 2 +- .../widget/action/custom-action.models.ts | 2 +- .../manage-widget-actions-dialog.component.html | 2 +- .../manage-widget-actions-dialog.component.ts | 2 +- .../action/manage-widget-actions.component.html | 2 +- .../manage-widget-actions.component.models.ts | 2 +- .../action/manage-widget-actions.component.scss | 2 +- .../action/manage-widget-actions.component.ts | 2 +- .../action/mobile-action-editor.component.html | 2 +- .../action/mobile-action-editor.component.ts | 2 +- .../widget/action/mobile-action-editor.models.ts | 2 +- .../action/widget-action-dialog.component.html | 2 +- .../action/widget-action-dialog.component.ts | 2 +- .../alarm-count-basic-config.component.html | 2 +- .../alarm/alarm-count-basic-config.component.ts | 2 +- .../alarms-table-basic-config.component.html | 2 +- .../alarm/alarms-table-basic-config.component.ts | 2 +- .../widget/config/basic/basic-config.scss | 3 +-- .../config/basic/basic-widget-config.module.ts | 2 +- .../cards/aggregated-data-key-row.component.html | 2 +- .../cards/aggregated-data-key-row.component.scss | 3 +-- .../cards/aggregated-data-key-row.component.ts | 2 +- .../aggregated-data-keys-panel.component.html | 2 +- .../aggregated-data-keys-panel.component.scss | 3 +-- .../aggregated-data-keys-panel.component.ts | 2 +- ...egated-value-card-basic-config.component.html | 2 +- ...gregated-value-card-basic-config.component.ts | 2 +- .../progress-bar-basic-config.component.html | 2 +- .../cards/progress-bar-basic-config.component.ts | 2 +- .../simple-card-basic-config.component.html | 2 +- .../cards/simple-card-basic-config.component.ts | 2 +- .../timeseries-table-basic-config.component.html | 2 +- .../timeseries-table-basic-config.component.ts | 2 +- .../cards/value-card-basic-config.component.html | 2 +- .../cards/value-card-basic-config.component.ts | 2 +- .../value-chart-card-basic-config.component.html | 2 +- .../value-chart-card-basic-config.component.ts | 2 +- ...chart-with-labels-basic-config.component.html | 2 +- ...r-chart-with-labels-basic-config.component.ts | 2 +- .../chart/doughnut-basic-config.component.html | 2 +- .../chart/doughnut-basic-config.component.ts | 2 +- .../basic/chart/flot-basic-config.component.html | 2 +- .../basic/chart/flot-basic-config.component.ts | 2 +- .../range-chart-basic-config.component.html | 2 +- .../chart/range-chart-basic-config.component.ts | 2 +- .../basic/common/data-key-row.component.html | 2 +- .../basic/common/data-key-row.component.scss | 3 +-- .../basic/common/data-key-row.component.ts | 2 +- .../basic/common/data-keys-panel.component.html | 2 +- .../basic/common/data-keys-panel.component.scss | 3 +-- .../basic/common/data-keys-panel.component.ts | 2 +- .../common/widget-actions-panel.component.html | 2 +- .../common/widget-actions-panel.component.ts | 2 +- .../entities-table-basic-config.component.html | 2 +- .../entities-table-basic-config.component.ts | 2 +- .../entity-count-basic-config.component.html | 2 +- .../entity-count-basic-config.component.ts | 2 +- .../analog-gauge-basic-config.component.html | 2 +- .../gauge/analog-gauge-basic-config.component.ts | 2 +- .../compass-gauge-basic-config.component.html | 2 +- .../compass-gauge-basic-config.component.ts | 2 +- .../gauge/radial-gauge-basic-config.component.ts | 2 +- ...mometer-scale-gauge-basic-config.component.ts | 2 +- .../battery-level-basic-config.component.html | 2 +- .../battery-level-basic-config.component.ts | 2 +- ...liquid-level-card-basic-config.component.html | 2 +- .../liquid-level-card-basic-config.component.ts | 2 +- .../signal-strength-basic-config.component.html | 2 +- .../signal-strength-basic-config.component.ts | 2 +- ...d-speed-direction-basic-config.component.html | 2 +- ...ind-speed-direction-basic-config.component.ts | 2 +- .../config/data-key-config-dialog.component.html | 2 +- .../config/data-key-config-dialog.component.scss | 2 +- .../config/data-key-config-dialog.component.ts | 2 +- .../widget/config/data-key-config.component.html | 2 +- .../widget/config/data-key-config.component.ts | 2 +- .../widget/config/data-keys.component.html | 2 +- .../widget/config/data-keys.component.models.ts | 2 +- .../widget/config/data-keys.component.scss | 3 +-- .../widget/config/data-keys.component.ts | 2 +- .../widget/config/datasource.component.html | 2 +- .../widget/config/datasource.component.models.ts | 2 +- .../widget/config/datasource.component.scss | 2 +- .../widget/config/datasource.component.ts | 2 +- .../widget/config/datasources.component.html | 2 +- .../widget/config/datasources.component.scss | 2 +- .../widget/config/datasources.component.ts | 2 +- .../timewindow-config-panel.component.html | 2 +- .../config/timewindow-config-panel.component.ts | 2 +- .../config/timewindow-style-panel.component.html | 2 +- .../config/timewindow-style-panel.component.scss | 3 +-- .../config/timewindow-style-panel.component.ts | 2 +- .../config/timewindow-style.component.html | 2 +- .../widget/config/timewindow-style.component.ts | 2 +- .../config/widget-config-components.module.ts | 2 +- .../config/widget-config.component.models.ts | 2 +- .../widget/config/widget-settings.component.html | 2 +- .../widget/config/widget-settings.component.scss | 2 +- .../widget/config/widget-settings.component.ts | 2 +- .../dialog/custom-dialog-container.component.ts | 2 +- .../widget/dialog/custom-dialog.component.ts | 2 +- .../widget/dialog/custom-dialog.service.ts | 2 +- .../dialog/embed-dashboard-dialog-token.ts | 2 +- .../dialog/embed-dashboard-dialog.component.html | 2 +- .../dialog/embed-dashboard-dialog.component.scss | 2 +- .../dialog/embed-dashboard-dialog.component.ts | 2 +- .../widget/dynamic-widget.component.ts | 2 +- .../lib/alarm/alarms-table-widget.component.html | 2 +- .../lib/alarm/alarms-table-widget.component.scss | 2 +- .../lib/alarm/alarms-table-widget.component.ts | 2 +- .../widget/lib/analogue-compass.models.ts | 2 +- .../components/widget/lib/analogue-compass.ts | 2 +- .../widget/lib/analogue-gauge.models.ts | 2 +- .../widget/lib/analogue-linear-gauge.models.ts | 2 +- .../widget/lib/analogue-linear-gauge.ts | 2 +- .../widget/lib/analogue-radial-gauge.models.ts | 2 +- .../widget/lib/analogue-radial-gauge.ts | 2 +- .../widget/lib/canvas-digital-gauge.ts | 2 +- .../aggregated-value-card-widget.component.html | 2 +- .../aggregated-value-card-widget.component.scss | 2 +- .../aggregated-value-card-widget.component.ts | 2 +- .../lib/cards/aggregated-value-card.models.ts | 2 +- .../lib/cards/progress-bar-widget.component.html | 2 +- .../lib/cards/progress-bar-widget.component.scss | 2 +- .../lib/cards/progress-bar-widget.component.ts | 2 +- .../lib/cards/progress-bar-widget.models.ts | 2 +- .../lib/cards/value-card-widget.component.html | 2 +- .../lib/cards/value-card-widget.component.scss | 2 +- .../lib/cards/value-card-widget.component.ts | 2 +- .../widget/lib/cards/value-card-widget.models.ts | 2 +- .../cards/value-chart-card-widget.component.html | 2 +- .../cards/value-chart-card-widget.component.scss | 2 +- .../cards/value-chart-card-widget.component.ts | 2 +- .../lib/cards/value-chart-card-widget.models.ts | 2 +- .../bar-chart-with-labels-widget.component.html | 2 +- .../bar-chart-with-labels-widget.component.scss | 3 +-- .../bar-chart-with-labels-widget.component.ts | 2 +- .../chart/bar-chart-with-labels-widget.models.ts | 2 +- .../lib/chart/doughnut-widget.component.html | 2 +- .../lib/chart/doughnut-widget.component.scss | 3 +-- .../lib/chart/doughnut-widget.component.ts | 2 +- .../widget/lib/chart/doughnut-widget.models.ts | 2 +- .../widget/lib/chart/echarts-widget.models.ts | 2 +- .../lib/chart/range-chart-widget.component.html | 2 +- .../lib/chart/range-chart-widget.component.scss | 3 +-- .../lib/chart/range-chart-widget.component.ts | 2 +- .../lib/chart/range-chart-widget.models.ts | 2 +- .../widget/lib/count/count-widget.component.html | 2 +- .../widget/lib/count/count-widget.component.scss | 2 +- .../widget/lib/count/count-widget.component.ts | 2 +- .../widget/lib/count/count-widget.models.ts | 2 +- .../date-range-navigator-panel.component.html | 2 +- .../date-range-navigator-panel.component.scss | 2 +- .../date-range-navigator.component.html | 2 +- .../date-range-navigator.component.scss | 2 +- .../date-range-navigator.component.ts | 2 +- .../date-range-navigator.models.ts | 2 +- .../widget/lib/digital-gauge.models.ts | 2 +- .../home/components/widget/lib/digital-gauge.ts | 2 +- .../lib/display-columns-panel.component.html | 2 +- .../lib/display-columns-panel.component.scss | 2 +- .../lib/display-columns-panel.component.ts | 2 +- .../lib/edges-overview-widget.component.html | 2 +- .../lib/edges-overview-widget.component.scss | 2 +- .../lib/edges-overview-widget.component.ts | 2 +- .../widget/lib/edges-overview-widget.models.ts | 2 +- .../entities-hierarchy-widget.component.html | 2 +- .../entities-hierarchy-widget.component.scss | 2 +- .../entities-hierarchy-widget.component.ts | 2 +- .../entity/entities-hierarchy-widget.models.ts | 2 +- .../entity/entities-table-widget.component.html | 2 +- .../entity/entities-table-widget.component.scss | 2 +- .../entity/entities-table-widget.component.ts | 2 +- .../widget/lib/flot-widget.component.html | 2 +- .../widget/lib/flot-widget.component.ts | 2 +- .../components/widget/lib/flot-widget.models.ts | 2 +- .../home/components/widget/lib/flot-widget.ts | 2 +- .../device-gateway-command.component.html | 2 +- .../device-gateway-command.component.scss | 2 +- .../gateway/device-gateway-command.component.ts | 2 +- .../gateway/gateway-configuration.component.html | 2 +- .../gateway/gateway-configuration.component.scss | 2 +- .../gateway/gateway-configuration.component.ts | 2 +- .../gateway/gateway-connectors.component.html | 2 +- .../gateway/gateway-connectors.component.scss | 2 +- .../lib/gateway/gateway-connectors.component.ts | 2 +- .../lib/gateway/gateway-form.component.html | 2 +- .../lib/gateway/gateway-form.component.scss | 2 +- .../widget/lib/gateway/gateway-form.component.ts | 2 +- .../widget/lib/gateway/gateway-form.models.ts | 2 +- .../lib/gateway/gateway-logs.component.html | 2 +- .../lib/gateway/gateway-logs.component.scss | 2 +- .../widget/lib/gateway/gateway-logs.component.ts | 2 +- .../gateway-remote-configuration-dialog.html | 2 +- .../gateway-remote-configuration-dialog.ts | 2 +- .../gateway/gateway-service-rpc.component.html | 2 +- .../gateway/gateway-service-rpc.component.scss | 2 +- .../lib/gateway/gateway-service-rpc.component.ts | 2 +- .../gateway/gateway-statistics.component.html | 3 +-- .../gateway/gateway-statistics.component.scss | 2 +- .../lib/gateway/gateway-statistics.component.ts | 2 +- .../widget/lib/gateway/gateway-widget.models.ts | 2 +- .../home-page/add-doc-link-dialog.component.html | 2 +- .../home-page/add-doc-link-dialog.component.scss | 2 +- .../home-page/add-doc-link-dialog.component.ts | 2 +- .../add-quick-link-dialog.component.html | 2 +- .../add-quick-link-dialog.component.scss | 2 +- .../home-page/add-quick-link-dialog.component.ts | 2 +- .../home-page/cluster-info-table.component.html | 2 +- .../home-page/cluster-info-table.component.scss | 2 +- .../home-page/cluster-info-table.component.ts | 2 +- .../home-page/configured-features.component.html | 2 +- .../home-page/configured-features.component.scss | 3 +-- .../home-page/configured-features.component.ts | 2 +- .../widget/lib/home-page/doc-link.component.html | 2 +- .../widget/lib/home-page/doc-link.component.ts | 2 +- .../home-page/doc-links-widget.component.html | 2 +- .../lib/home-page/doc-links-widget.component.ts | 2 +- .../home-page/edit-links-dialog.component.html | 2 +- .../home-page/edit-links-dialog.component.scss | 2 +- .../lib/home-page/edit-links-dialog.component.ts | 2 +- ...tting-started-completed-dialog.component.html | 2 +- ...tting-started-completed-dialog.component.scss | 2 +- ...getting-started-completed-dialog.component.ts | 2 +- .../getting-started-widget.component.html | 2 +- .../getting-started-widget.component.scss | 3 +-- .../getting-started-widget.component.ts | 2 +- .../widget/lib/home-page/home-page-widget.scss | 2 +- .../lib/home-page/home-page-widgets.module.ts | 2 +- .../widget/lib/home-page/home-page.scss | 3 +-- .../widget/lib/home-page/link.component.scss | 2 +- .../lib/home-page/links-widget.component.scss | 3 +-- .../lib/home-page/quick-link.component.html | 2 +- .../widget/lib/home-page/quick-link.component.ts | 2 +- .../home-page/quick-links-widget.component.html | 2 +- .../home-page/quick-links-widget.component.ts | 2 +- .../recent-dashboards-widget.component.html | 2 +- .../recent-dashboards-widget.component.scss | 2 +- .../recent-dashboards-widget.component.ts | 2 +- .../home-page/usage-info-widget.component.html | 2 +- .../home-page/usage-info-widget.component.scss | 2 +- .../lib/home-page/usage-info-widget.component.ts | 2 +- .../lib/home-page/version-info.component.html | 2 +- .../lib/home-page/version-info.component.scss | 3 +-- .../lib/home-page/version-info.component.ts | 2 +- .../battery-level-widget.component.html | 2 +- .../battery-level-widget.component.scss | 2 +- .../indicator/battery-level-widget.component.ts | 2 +- .../lib/indicator/battery-level-widget.models.ts | 2 +- .../indicator/liquid-level-widget.component.html | 2 +- .../indicator/liquid-level-widget.component.scss | 2 +- .../indicator/liquid-level-widget.component.ts | 2 +- .../lib/indicator/liquid-level-widget.models.ts | 2 +- .../signal-strength-widget.component.html | 2 +- .../signal-strength-widget.component.scss | 2 +- .../signal-strength-widget.component.ts | 16 ++++++++++++++++ .../indicator/signal-strength-widget.models.ts | 2 +- .../widget/lib/json-input-widget.component.html | 2 +- .../widget/lib/json-input-widget.component.scss | 2 +- .../widget/lib/json-input-widget.component.ts | 2 +- .../components/widget/lib/legend.component.html | 2 +- .../components/widget/lib/legend.component.scss | 2 +- .../components/widget/lib/legend.component.ts | 2 +- .../home/components/widget/lib/maps/circle.ts | 2 +- .../widget/lib/maps/common-maps-utils.ts | 2 +- .../dialogs/select-entity-dialog.component.html | 2 +- .../dialogs/select-entity-dialog.component.scss | 2 +- .../dialogs/select-entity-dialog.component.ts | 2 +- .../components/widget/lib/maps/leaflet-map.ts | 2 +- .../components/widget/lib/maps/map-models.ts | 2 +- .../widget/lib/maps/map-widget.interface.ts | 2 +- .../components/widget/lib/maps/map-widget2.ts | 2 +- .../components/widget/lib/maps/maps-utils.ts | 2 +- .../home/components/widget/lib/maps/markers.scss | 2 +- .../home/components/widget/lib/maps/markers.ts | 2 +- .../home/components/widget/lib/maps/polygon.ts | 2 +- .../home/components/widget/lib/maps/polyline.ts | 2 +- .../widget/lib/maps/providers/google-map.ts | 2 +- .../widget/lib/maps/providers/here-map.ts | 2 +- .../widget/lib/maps/providers/image-map.ts | 2 +- .../widget/lib/maps/providers/index.ts | 2 +- .../widget/lib/maps/providers/openstreet-map.ts | 2 +- .../widget/lib/maps/providers/tencent-map.ts | 2 +- .../widget/lib/markdown-widget.component.html | 2 +- .../widget/lib/markdown-widget.component.ts | 2 +- .../lib/multiple-input-widget.component.html | 2 +- .../lib/multiple-input-widget.component.scss | 2 +- .../lib/multiple-input-widget.component.ts | 2 +- .../lib/navigation-card-widget.component.html | 2 +- .../lib/navigation-card-widget.component.scss | 2 +- .../lib/navigation-card-widget.component.ts | 2 +- .../lib/navigation-cards-widget.component.html | 2 +- .../lib/navigation-cards-widget.component.scss | 2 +- .../lib/navigation-cards-widget.component.ts | 2 +- .../widget/lib/photo-camera-input.component.html | 2 +- .../widget/lib/photo-camera-input.component.scss | 2 +- .../widget/lib/photo-camera-input.component.ts | 2 +- .../widget/lib/qrcode-widget.component.html | 2 +- .../widget/lib/qrcode-widget.component.ts | 2 +- .../widget/lib/rpc/knob.component.html | 2 +- .../widget/lib/rpc/knob.component.scss | 2 +- .../components/widget/lib/rpc/knob.component.ts | 2 +- .../widget/lib/rpc/led-indicator.component.html | 2 +- .../widget/lib/rpc/led-indicator.component.scss | 2 +- .../widget/lib/rpc/led-indicator.component.ts | 2 +- .../lib/rpc/persistent-add-dialog.component.html | 2 +- .../lib/rpc/persistent-add-dialog.component.scss | 2 +- .../lib/rpc/persistent-add-dialog.component.ts | 2 +- .../rpc/persistent-details-dialog.component.html | 2 +- .../rpc/persistent-details-dialog.component.scss | 2 +- .../rpc/persistent-details-dialog.component.ts | 2 +- .../rpc/persistent-filter-panel.component.html | 2 +- .../rpc/persistent-filter-panel.component.scss | 2 +- .../lib/rpc/persistent-filter-panel.component.ts | 2 +- .../lib/rpc/persistent-table.component.html | 2 +- .../lib/rpc/persistent-table.component.scss | 2 +- .../widget/lib/rpc/persistent-table.component.ts | 2 +- .../widget/lib/rpc/round-switch.component.html | 2 +- .../widget/lib/rpc/round-switch.component.scss | 2 +- .../widget/lib/rpc/round-switch.component.ts | 2 +- .../widget/lib/rpc/rpc-widgets.module.ts | 2 +- .../widget/lib/rpc/switch.component.html | 2 +- .../widget/lib/rpc/switch.component.scss | 2 +- .../widget/lib/rpc/switch.component.ts | 2 +- .../components/widget/lib/settings.models.ts | 2 +- .../alarm-count-widget-settings.component.html | 2 +- .../alarm-count-widget-settings.component.ts | 2 +- .../alarms-table-key-settings.component.html | 2 +- .../alarm/alarms-table-key-settings.component.ts | 2 +- .../alarms-table-widget-settings.component.html | 2 +- .../alarms-table-widget-settings.component.ts | 2 +- ...egated-value-card-key-settings.component.html | 2 +- ...gregated-value-card-key-settings.component.ts | 2 +- ...ted-value-card-widget-settings.component.html | 2 +- ...gated-value-card-widget-settings.component.ts | 2 +- ...ashboard-state-widget-settings.component.html | 2 +- .../dashboard-state-widget-settings.component.ts | 2 +- ...quick-overview-widget-settings.component.html | 2 +- ...e-quick-overview-widget-settings.component.ts | 2 +- .../html-card-widget-settings.component.html | 2 +- .../cards/html-card-widget-settings.component.ts | 2 +- .../cards/label-widget-label.component.html | 2 +- .../cards/label-widget-label.component.scss | 2 +- .../cards/label-widget-label.component.ts | 2 +- .../cards/label-widget-settings.component.html | 2 +- .../cards/label-widget-settings.component.ts | 2 +- .../markdown-widget-settings.component.html | 2 +- .../cards/markdown-widget-settings.component.ts | 2 +- .../progress-bar-widget-settings.component.html | 2 +- .../progress-bar-widget-settings.component.ts | 2 +- .../cards/qrcode-widget-settings.component.html | 2 +- .../cards/qrcode-widget-settings.component.ts | 2 +- .../simple-card-widget-settings.component.html | 2 +- .../simple-card-widget-settings.component.ts | 2 +- .../timeseries-table-key-settings.component.html | 2 +- .../timeseries-table-key-settings.component.ts | 2 +- ...ries-table-latest-key-settings.component.html | 2 +- ...series-table-latest-key-settings.component.ts | 2 +- ...meseries-table-widget-settings.component.html | 2 +- ...timeseries-table-widget-settings.component.ts | 2 +- .../value-card-widget-settings.component.html | 2 +- .../value-card-widget-settings.component.ts | 2 +- ...lue-chart-card-widget-settings.component.html | 2 +- ...value-chart-card-widget-settings.component.ts | 2 +- ...rt-with-labels-widget-settings.component.html | 2 +- ...hart-with-labels-widget-settings.component.ts | 2 +- .../chart/chart-widget-settings.component.html | 2 +- .../chart/chart-widget-settings.component.ts | 2 +- ...doughnut-chart-widget-settings.component.html | 2 +- .../doughnut-chart-widget-settings.component.ts | 2 +- .../doughnut-widget-settings.component.html | 2 +- .../chart/doughnut-widget-settings.component.ts | 2 +- .../chart/flot-bar-key-settings.component.html | 2 +- .../chart/flot-bar-key-settings.component.ts | 2 +- .../flot-bar-widget-settings.component.html | 2 +- .../chart/flot-bar-widget-settings.component.ts | 2 +- .../chart/flot-key-settings.component.html | 2 +- .../chart/flot-key-settings.component.ts | 2 +- .../flot-latest-key-settings.component.html | 2 +- .../chart/flot-latest-key-settings.component.ts | 2 +- .../chart/flot-line-key-settings.component.html | 2 +- .../chart/flot-line-key-settings.component.ts | 2 +- .../flot-line-widget-settings.component.html | 2 +- .../chart/flot-line-widget-settings.component.ts | 2 +- .../chart/flot-pie-key-settings.component.html | 2 +- .../chart/flot-pie-key-settings.component.ts | 2 +- .../flot-pie-widget-settings.component.html | 2 +- .../chart/flot-pie-widget-settings.component.ts | 2 +- .../settings/chart/flot-threshold.component.html | 2 +- .../settings/chart/flot-threshold.component.scss | 3 +-- .../settings/chart/flot-threshold.component.ts | 2 +- .../chart/flot-widget-settings.component.html | 2 +- .../chart/flot-widget-settings.component.ts | 2 +- .../settings/chart/label-data-key.component.html | 2 +- .../settings/chart/label-data-key.component.scss | 2 +- .../settings/chart/label-data-key.component.ts | 2 +- .../range-chart-widget-settings.component.html | 2 +- .../range-chart-widget-settings.component.ts | 2 +- .../background-settings-panel.component.html | 2 +- .../background-settings-panel.component.scss | 3 +-- .../background-settings-panel.component.ts | 2 +- .../common/background-settings.component.html | 2 +- .../common/background-settings.component.scss | 2 +- .../common/background-settings.component.ts | 2 +- .../common/color-range-list.component.html | 2 +- .../common/color-range-list.component.ts | 2 +- .../common/color-range-panel.component.html | 2 +- .../common/color-range-panel.component.ts | 2 +- .../common/color-range-settings.component.html | 2 +- .../common/color-range-settings.component.ts | 2 +- .../common/color-settings-panel.component.html | 2 +- .../common/color-settings-panel.component.scss | 3 +-- .../common/color-settings-panel.component.ts | 2 +- .../common/color-settings.component.html | 2 +- .../settings/common/color-settings.component.ts | 2 +- .../common/count-widget-settings.component.html | 2 +- .../common/count-widget-settings.component.ts | 2 +- .../common/css-unit-select.component.html | 2 +- .../settings/common/css-unit-select.component.ts | 2 +- .../common/date-format-select.component.html | 2 +- .../common/date-format-select.component.ts | 2 +- .../date-format-settings-panel.component.html | 2 +- .../date-format-settings-panel.component.scss | 3 +-- .../date-format-settings-panel.component.ts | 2 +- .../common/font-settings-panel.component.html | 2 +- .../common/font-settings-panel.component.scss | 2 +- .../common/font-settings-panel.component.ts | 2 +- .../settings/common/font-settings.component.html | 2 +- .../settings/common/font-settings.component.ts | 2 +- .../common/image-cards-select.component.html | 2 +- .../common/image-cards-select.component.scss | 2 +- .../common/image-cards-select.component.ts | 2 +- .../settings/common/legend-config.component.html | 2 +- .../settings/common/legend-config.component.ts | 2 +- .../settings/common/value-source.component.html | 2 +- .../settings/common/value-source.component.ts | 2 +- .../settings/common/widget-font.component.html | 2 +- .../lib/settings/common/widget-font.component.ts | 2 +- .../common/widget-settings-common.module.ts | 2 +- .../device-key-autocomplete.component.html | 2 +- .../control/device-key-autocomplete.component.ts | 2 +- .../knob-control-widget-settings.component.html | 2 +- .../knob-control-widget-settings.component.ts | 2 +- .../led-indicator-widget-settings.component.html | 2 +- .../led-indicator-widget-settings.component.ts | 2 +- ...rsistent-table-widget-settings.component.html | 2 +- ...persistent-table-widget-settings.component.ts | 2 +- .../round-switch-widget-settings.component.html | 2 +- .../round-switch-widget-settings.component.ts | 2 +- .../control/rpc-button-style.component.html | 2 +- .../control/rpc-button-style.component.ts | 2 +- .../rpc-shell-widget-settings.component.html | 2 +- .../rpc-shell-widget-settings.component.ts | 2 +- .../rpc-terminal-widget-settings.component.html | 2 +- .../rpc-terminal-widget-settings.component.ts | 2 +- .../send-rpc-widget-settings.component.html | 2 +- .../send-rpc-widget-settings.component.ts | 2 +- .../slide-toggle-widget-settings.component.html | 2 +- .../slide-toggle-widget-settings.component.ts | 2 +- ...switch-control-widget-settings.component.html | 2 +- .../switch-control-widget-settings.component.ts | 2 +- .../control/switch-rpc-settings.component.html | 2 +- .../control/switch-rpc-settings.component.ts | 2 +- ...vice-attribute-widget-settings.component.html | 2 +- ...device-attribute-widget-settings.component.ts | 2 +- ...ange-navigator-widget-settings.component.html | 2 +- ...-range-navigator-widget-settings.component.ts | 2 +- ...ties-hierarchy-widget-settings.component.html | 2 +- ...tities-hierarchy-widget-settings.component.ts | 2 +- .../entities-table-key-settings.component.html | 2 +- .../entities-table-key-settings.component.ts | 2 +- ...entities-table-widget-settings.component.html | 2 +- .../entities-table-widget-settings.component.ts | 2 +- .../entity-count-widget-settings.component.html | 2 +- .../entity-count-widget-settings.component.ts | 2 +- ...-single-device-widget-settings.component.html | 2 +- ...ig-single-device-widget-settings.component.ts | 2 +- ...gateway-config-widget-settings.component.html | 2 +- .../gateway-config-widget-settings.component.ts | 2 +- ...gateway-events-widget-settings.component.html | 2 +- .../gateway-events-widget-settings.component.ts | 2 +- .../gateway/gateway-logs-settings.component.html | 2 +- .../gateway/gateway-logs-settings.component.ts | 2 +- .../gateway-service-rpc-settings.component.html | 2 +- .../gateway-service-rpc-settings.component.ts | 2 +- ...alogue-compass-widget-settings.component.html | 2 +- ...analogue-compass-widget-settings.component.ts | 2 +- ...analogue-gauge-widget-settings.component.html | 2 +- .../analogue-gauge-widget-settings.component.ts | 2 +- ...gue-linear-gauge-widget-settings.component.ts | 2 +- ...gue-radial-gauge-widget-settings.component.ts | 2 +- .../digital-gauge-widget-settings.component.html | 2 +- .../digital-gauge-widget-settings.component.ts | 2 +- .../gauge/fixed-color-level.component.html | 2 +- .../gauge/fixed-color-level.component.scss | 2 +- .../gauge/fixed-color-level.component.ts | 2 +- .../lib/settings/gauge/tick-value.component.html | 2 +- .../lib/settings/gauge/tick-value.component.scss | 2 +- .../lib/settings/gauge/tick-value.component.ts | 2 +- .../gpio-control-widget-settings.component.html | 2 +- .../gpio-control-widget-settings.component.ts | 2 +- .../lib/settings/gpio/gpio-item.component.html | 2 +- .../lib/settings/gpio/gpio-item.component.scss | 2 +- .../lib/settings/gpio/gpio-item.component.ts | 2 +- .../gpio-panel-widget-settings.component.html | 2 +- .../gpio/gpio-panel-widget-settings.component.ts | 2 +- .../doc-links-widget-settings.component.html | 2 +- .../doc-links-widget-settings.component.ts | 2 +- .../quick-links-widget-settings.component.html | 2 +- .../quick-links-widget-settings.component.ts | 2 +- .../battery-level-widget-settings.component.html | 2 +- .../battery-level-widget-settings.component.ts | 2 +- ...uid-level-card-widget-settings.component.html | 2 +- ...iquid-level-card-widget-settings.component.ts | 2 +- ...ignal-strength-widget-settings.component.html | 2 +- .../signal-strength-widget-settings.component.ts | 2 +- .../input/datakey-select-option.component.html | 2 +- .../input/datakey-select-option.component.scss | 2 +- .../input/datakey-select-option.component.ts | 2 +- ...evice-claiming-widget-settings.component.html | 2 +- .../device-claiming-widget-settings.component.ts | 2 +- ...o-camera-input-widget-settings.component.html | 2 +- ...oto-camera-input-widget-settings.component.ts | 2 +- ...ate-attribute-general-settings.component.html | 2 +- ...pdate-attribute-general-settings.component.ts | 2 +- ...lean-attribute-widget-settings.component.html | 2 +- ...oolean-attribute-widget-settings.component.ts | 2 +- ...date-attribute-widget-settings.component.html | 2 +- ...e-date-attribute-widget-settings.component.ts | 2 +- ...uble-attribute-widget-settings.component.html | 2 +- ...double-attribute-widget-settings.component.ts | 2 +- ...mage-attribute-widget-settings.component.html | 2 +- ...-image-attribute-widget-settings.component.ts | 2 +- ...eger-attribute-widget-settings.component.html | 2 +- ...nteger-attribute-widget-settings.component.ts | 2 +- ...json-attribute-widget-settings.component.html | 2 +- ...e-json-attribute-widget-settings.component.ts | 2 +- ...tion-attribute-widget-settings.component.html | 2 +- ...cation-attribute-widget-settings.component.ts | 2 +- ...ltiple-attributes-key-settings.component.html | 2 +- ...multiple-attributes-key-settings.component.ts | 2 +- ...ple-attributes-widget-settings.component.html | 2 +- ...tiple-attributes-widget-settings.component.ts | 2 +- ...ring-attribute-widget-settings.component.html | 2 +- ...string-attribute-widget-settings.component.ts | 2 +- .../settings/map/circle-settings.component.html | 2 +- .../settings/map/circle-settings.component.ts | 2 +- .../map/common-map-settings.component.html | 2 +- .../map/common-map-settings.component.ts | 2 +- .../datasources-key-autocomplete.component.html | 2 +- .../datasources-key-autocomplete.component.ts | 2 +- .../google-map-provider-settings.component.html | 2 +- .../google-map-provider-settings.component.ts | 2 +- .../here-map-provider-settings.component.html | 2 +- .../map/here-map-provider-settings.component.ts | 2 +- .../image-map-provider-settings.component.html | 2 +- .../map/image-map-provider-settings.component.ts | 2 +- .../map/map-editor-settings.component.html | 2 +- .../map/map-editor-settings.component.ts | 2 +- .../map/map-provider-settings.component.html | 2 +- .../map/map-provider-settings.component.ts | 2 +- .../lib/settings/map/map-settings.component.html | 2 +- .../lib/settings/map/map-settings.component.ts | 2 +- .../map/map-widget-settings.component.html | 2 +- .../map/map-widget-settings.component.ts | 2 +- .../marker-clustering-settings.component.html | 2 +- .../map/marker-clustering-settings.component.ts | 2 +- .../settings/map/markers-settings.component.html | 2 +- .../settings/map/markers-settings.component.ts | 2 +- ...enstreet-map-provider-settings.component.html | 2 +- ...openstreet-map-provider-settings.component.ts | 2 +- .../settings/map/polygon-settings.component.html | 2 +- .../settings/map/polygon-settings.component.ts | 2 +- .../map/route-map-settings.component.html | 2 +- .../settings/map/route-map-settings.component.ts | 2 +- .../map/route-map-widget-settings.component.html | 2 +- .../map/route-map-widget-settings.component.ts | 2 +- .../tencent-map-provider-settings.component.html | 2 +- .../tencent-map-provider-settings.component.ts | 2 +- ...trip-animation-common-settings.component.html | 2 +- .../trip-animation-common-settings.component.ts | 2 +- ...trip-animation-marker-settings.component.html | 2 +- .../trip-animation-marker-settings.component.ts | 2 +- .../trip-animation-path-settings.component.html | 2 +- .../trip-animation-path-settings.component.ts | 2 +- .../trip-animation-point-settings.component.html | 2 +- .../trip-animation-point-settings.component.ts | 2 +- ...trip-animation-widget-settings.component.html | 2 +- .../trip-animation-widget-settings.component.ts | 2 +- ...avigation-card-widget-settings.component.html | 2 +- .../navigation-card-widget-settings.component.ts | 2 +- ...vigation-cards-widget-settings.component.html | 2 +- ...navigation-cards-widget-settings.component.ts | 2 +- ...peed-direction-widget-settings.component.html | 2 +- ...-speed-direction-widget-settings.component.ts | 2 +- .../lib/settings/widget-settings.module.ts | 2 +- .../widget/lib/settings/widget-settings.scss | 2 +- .../components/widget/lib/table-widget.models.ts | 2 +- .../home/components/widget/lib/table-widget.scss | 2 +- .../lib/timeseries-table-widget.component.html | 2 +- .../lib/timeseries-table-widget.component.scss | 2 +- .../lib/timeseries-table-widget.component.ts | 2 +- .../trip-animation/trip-animation.component.html | 2 +- .../trip-animation/trip-animation.component.scss | 2 +- .../trip-animation/trip-animation.component.ts | 2 +- .../wind-speed-direction-widget.component.html | 2 +- .../wind-speed-direction-widget.component.scss | 2 +- .../wind-speed-direction-widget.component.ts | 2 +- .../wind-speed-direction-widget.models.ts | 2 +- .../widget/widget-component.service.ts | 2 +- .../widget/widget-components.module.ts | 2 +- .../widget/widget-config.component.html | 2 +- .../widget/widget-config.component.scss | 3 +-- .../components/widget/widget-config.component.ts | 2 +- .../widget/widget-container.component.html | 2 +- .../widget/widget-container.component.scss | 3 +-- .../widget/widget-container.component.ts | 2 +- .../widget/widget-preview.component.html | 2 +- .../widget/widget-preview.component.scss | 2 +- .../widget/widget-preview.component.ts | 2 +- .../home/components/widget/widget.component.html | 2 +- .../home/components/widget/widget.component.scss | 2 +- .../home/components/widget/widget.component.ts | 2 +- .../wizard/device-wizard-dialog.component.html | 2 +- .../wizard/device-wizard-dialog.component.scss | 2 +- .../wizard/device-wizard-dialog.component.ts | 2 +- ...dd-entities-to-customer-dialog.component.html | 2 +- .../add-entities-to-customer-dialog.component.ts | 2 +- .../add-entities-to-edge-dialog.component.html | 2 +- .../add-entities-to-edge-dialog.component.ts | 2 +- .../assign-to-customer-dialog.component.html | 2 +- .../assign-to-customer-dialog.component.ts | 2 +- .../modules/home/dialogs/home-dialogs.module.ts | 2 +- .../modules/home/dialogs/home-dialogs.service.ts | 2 +- .../src/app/modules/home/home-routing.module.ts | 2 +- ui-ngx/src/app/modules/home/home.component.html | 2 +- ui-ngx/src/app/modules/home/home.component.scss | 2 +- ui-ngx/src/app/modules/home/home.component.ts | 2 +- ui-ngx/src/app/modules/home/home.module.ts | 2 +- .../modules/home/menu/menu-link.component.html | 2 +- .../modules/home/menu/menu-link.component.scss | 2 +- .../app/modules/home/menu/menu-link.component.ts | 2 +- .../modules/home/menu/menu-toggle.component.html | 2 +- .../modules/home/menu/menu-toggle.component.scss | 2 +- .../modules/home/menu/menu-toggle.component.ts | 2 +- .../modules/home/menu/side-menu.component.html | 2 +- .../modules/home/menu/side-menu.component.scss | 2 +- .../app/modules/home/menu/side-menu.component.ts | 2 +- .../app/modules/home/models/contact.models.ts | 2 +- .../home/models/dashboard-component.models.ts | 2 +- .../models/datasource/attribute-datasource.ts | 2 +- .../home/models/datasource/entity-datasource.ts | 2 +- .../models/datasource/relation-datasource.ts | 2 +- .../entity/entities-table-config.models.ts | 2 +- .../models/entity/entity-component.models.ts | 2 +- .../entity-details-page-component.models.ts | 2 +- .../entity/entity-table-component.models.ts | 2 +- .../home/models/searchable-component.models.ts | 2 +- .../src/app/modules/home/models/services.map.ts | 2 +- .../home/models/widget-component.models.ts | 2 +- .../home/pages/account/account-routing.module.ts | 2 +- .../modules/home/pages/account/account.module.ts | 2 +- .../home/pages/admin/admin-routing.module.ts | 2 +- .../app/modules/home/pages/admin/admin.module.ts | 2 +- .../auto-commit-admin-settings.component.html | 2 +- .../auto-commit-admin-settings.component.ts | 2 +- .../pages/admin/general-settings.component.html | 2 +- .../pages/admin/general-settings.component.scss | 2 +- .../pages/admin/general-settings.component.ts | 2 +- .../pages/admin/home-settings.component.html | 2 +- .../pages/admin/home-settings.component.scss | 2 +- .../home/pages/admin/home-settings.component.ts | 2 +- .../home/pages/admin/mail-server.component.html | 2 +- .../home/pages/admin/mail-server.component.scss | 2 +- .../home/pages/admin/mail-server.component.ts | 2 +- .../pages/admin/oauth2-settings.component.html | 2 +- .../pages/admin/oauth2-settings.component.scss | 2 +- .../pages/admin/oauth2-settings.component.ts | 2 +- .../home/pages/admin/queue/queue.component.html | 2 +- .../home/pages/admin/queue/queue.component.ts | 2 +- .../admin/queue/queues-table-config.resolver.ts | 2 +- .../repository-admin-settings.component.html | 2 +- .../admin/repository-admin-settings.component.ts | 2 +- .../resources-library-table-config.resolve.ts | 2 +- .../resource/resources-library.component.html | 2 +- .../resource/resources-library.component.ts | 2 +- .../resources-table-header.component.html | 2 +- .../resource/resources-table-header.component.ts | 2 +- .../pages/admin/security-settings.component.html | 2 +- .../pages/admin/security-settings.component.scss | 2 +- .../pages/admin/security-settings.component.ts | 2 +- .../admin/send-test-sms-dialog.component.html | 2 +- .../admin/send-test-sms-dialog.component.ts | 2 +- .../modules/home/pages/admin/settings-card.scss | 2 +- .../home/pages/admin/sms-provider.component.html | 2 +- .../home/pages/admin/sms-provider.component.scss | 2 +- .../home/pages/admin/sms-provider.component.ts | 2 +- .../two-factor-auth-settings.component.html | 2 +- .../two-factor-auth-settings.component.scss | 2 +- .../admin/two-factor-auth-settings.component.ts | 2 +- .../home/pages/alarm/alarm-routing.module.ts | 2 +- .../app/modules/home/pages/alarm/alarm.module.ts | 2 +- .../pages/api-usage/api-usage-routing.module.ts | 2 +- .../pages/api-usage/api-usage.component.html | 2 +- .../pages/api-usage/api-usage.component.scss | 2 +- .../home/pages/api-usage/api-usage.component.ts | 2 +- .../home/pages/api-usage/api-usage.module.ts | 2 +- .../asset-profile-routing.module.ts | 2 +- .../asset-profile-tabs.component.html | 2 +- .../asset-profile-tabs.component.ts | 2 +- .../pages/asset-profile/asset-profile.module.ts | 2 +- .../asset-profiles-table-config.resolver.ts | 2 +- .../home/pages/asset/asset-routing.module.ts | 2 +- .../asset/asset-table-header.component.html | 2 +- .../pages/asset/asset-table-header.component.ts | 2 +- .../home/pages/asset/asset-tabs.component.html | 2 +- .../home/pages/asset/asset-tabs.component.ts | 2 +- .../home/pages/asset/asset.component.html | 2 +- .../home/pages/asset/asset.component.scss | 2 +- .../modules/home/pages/asset/asset.component.ts | 2 +- .../app/modules/home/pages/asset/asset.module.ts | 2 +- .../pages/asset/assets-table-config.resolver.ts | 2 +- .../pages/audit-log/audit-log-routing.module.ts | 2 +- .../home/pages/audit-log/audit-log.module.ts | 2 +- .../pages/customer/customer-routing.module.ts | 2 +- .../pages/customer/customer-tabs.component.html | 2 +- .../pages/customer/customer-tabs.component.ts | 2 +- .../home/pages/customer/customer.component.html | 2 +- .../home/pages/customer/customer.component.scss | 2 +- .../home/pages/customer/customer.component.ts | 2 +- .../home/pages/customer/customer.module.ts | 2 +- .../customer/customers-table-config.resolver.ts | 2 +- .../dashboard/dashboard-form.component.html | 2 +- .../dashboard/dashboard-form.component.scss | 2 +- .../pages/dashboard/dashboard-form.component.ts | 2 +- .../pages/dashboard/dashboard-routing.module.ts | 2 +- .../dashboard/dashboard-tabs.component.html | 2 +- .../pages/dashboard/dashboard-tabs.component.ts | 2 +- .../home/pages/dashboard/dashboard.module.ts | 2 +- .../dashboards-table-config.resolver.ts | 2 +- .../make-dashboard-public-dialog.component.html | 2 +- .../make-dashboard-public-dialog.component.ts | 2 +- ...age-dashboard-customers-dialog.component.html | 2 +- ...anage-dashboard-customers-dialog.component.ts | 2 +- .../device-profile-routing.module.ts | 2 +- .../device-profile-tabs.component.html | 2 +- .../device-profile-tabs.component.ts | 2 +- .../device-profile/device-profile.module.ts | 2 +- .../device-profiles-table-config.resolver.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...p-device-transport-configuration.component.ts | 2 +- .../default-device-configuration.component.html | 2 +- .../default-device-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...t-device-transport-configuration.component.ts | 2 +- .../data/device-configuration.component.html | 2 +- .../data/device-configuration.component.ts | 2 +- .../pages/device/data/device-data.component.html | 2 +- .../pages/device/data/device-data.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- .../device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...m-device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...t-device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...p-device-transport-configuration.component.ts | 2 +- ...vice-check-connectivity-dialog.component.html | 2 +- ...vice-check-connectivity-dialog.component.scss | 3 +-- ...device-check-connectivity-dialog.component.ts | 2 +- .../device-credentials-dialog.component.html | 2 +- .../device-credentials-dialog.component.scss | 2 +- .../device-credentials-dialog.component.ts | 2 +- .../home/pages/device/device-routing.module.ts | 2 +- .../device/device-table-header.component.html | 2 +- .../device/device-table-header.component.ts | 2 +- .../home/pages/device/device-tabs.component.html | 2 +- .../home/pages/device/device-tabs.component.ts | 2 +- .../home/pages/device/device.component.html | 2 +- .../home/pages/device/device.component.scss | 2 +- .../home/pages/device/device.component.ts | 2 +- .../modules/home/pages/device/device.module.ts | 2 +- .../device/devices-table-config.resolver.ts | 2 +- .../edge/edge-instructions-dialog.component.html | 2 +- .../edge/edge-instructions-dialog.component.scss | 3 +-- .../edge/edge-instructions-dialog.component.ts | 2 +- .../home/pages/edge/edge-routing.module.ts | 2 +- .../pages/edge/edge-table-header.component.html | 2 +- .../pages/edge/edge-table-header.component.ts | 2 +- .../home/pages/edge/edge-tabs.component.html | 2 +- .../home/pages/edge/edge-tabs.component.ts | 2 +- .../modules/home/pages/edge/edge.component.html | 2 +- .../modules/home/pages/edge/edge.component.scss | 2 +- .../modules/home/pages/edge/edge.component.ts | 2 +- .../app/modules/home/pages/edge/edge.module.ts | 2 +- .../pages/edge/edges-table-config.resolver.ts | 2 +- .../pages/entities/entities-routing.module.ts | 2 +- .../home/pages/entities/entities.module.ts | 2 +- .../entity-view/entity-view-routing.module.ts | 2 +- .../entity-view-table-header.component.html | 2 +- .../entity-view-table-header.component.ts | 2 +- .../entity-view/entity-view-tabs.component.html | 2 +- .../entity-view/entity-view-tabs.component.ts | 2 +- .../pages/entity-view/entity-view.component.html | 2 +- .../pages/entity-view/entity-view.component.scss | 2 +- .../pages/entity-view/entity-view.component.ts | 2 +- .../home/pages/entity-view/entity-view.module.ts | 2 +- .../entity-views-table-config.resolver.ts | 2 +- .../pages/features/features-routing.module.ts | 2 +- .../home/pages/features/features.module.ts | 2 +- .../home-links/home-links-routing.module.ts | 2 +- .../pages/home-links/home-links.component.html | 2 +- .../pages/home-links/home-links.component.scss | 2 +- .../pages/home-links/home-links.component.ts | 2 +- .../home/pages/home-links/home-links.module.ts | 2 +- .../app/modules/home/pages/home-pages.models.ts | 2 +- .../app/modules/home/pages/home-pages.module.ts | 2 +- .../inbox-notification-dialog.component.html | 2 +- .../inbox-notification-dialog.component.scss | 2 +- .../inbox/inbox-notification-dialog.component.ts | 2 +- .../inbox/inbox-table-config.resolver.ts | 2 +- .../inbox/inbox-table-header.component.html | 2 +- .../inbox/inbox-table-header.component.scss | 2 +- .../inbox/inbox-table-header.component.ts | 2 +- .../notification/notification-routing.module.ts | 2 +- .../pages/notification/notification.module.ts | 2 +- .../recipient-notification-dialog.component.html | 2 +- .../recipient-notification-dialog.component.scss | 2 +- .../recipient-notification-dialog.component.ts | 2 +- .../recipient/recipient-table-config.resolver.ts | 2 +- .../recipient-table-header.component.html | 2 +- .../recipient-table-header.component.scss | 2 +- .../recipient-table-header.component.ts | 2 +- .../rule/escalation-form.component.html | 2 +- .../rule/escalation-form.component.scss | 2 +- .../rule/escalation-form.component.ts | 2 +- .../notification/rule/escalations.component.html | 2 +- .../notification/rule/escalations.component.ts | 2 +- .../rule/rule-notification-dialog.component.html | 2 +- .../rule/rule-notification-dialog.component.scss | 2 +- .../rule/rule-notification-dialog.component.ts | 2 +- .../rule/rule-table-config.resolver.ts | 2 +- .../rule/rule-table-header.component.html | 2 +- .../rule/rule-table-header.component.scss | 2 +- .../rule/rule-table-header.component.ts | 2 +- .../sent/sent-error-dialog.component.html | 2 +- .../sent/sent-error-dialog.component.scss | 2 +- .../sent/sent-error-dialog.component.ts | 2 +- .../sent/sent-notification-dialog.component.html | 2 +- .../sent/sent-notification-dialog.component.scss | 2 +- .../sent/sent-notification-dialog.componet.ts | 2 +- .../sent/sent-table-config.resolver.ts | 2 +- .../notification-setting-form.component.html | 2 +- .../notification-setting-form.component.scss | 2 +- .../notification-setting-form.component.ts | 2 +- .../notification-settings-routing.modules.ts | 2 +- .../notification-settings.component.html | 2 +- .../notification-settings.component.scss | 2 +- .../settings/notification-settings.component.ts | 2 +- .../template/template-configuration.ts | 2 +- .../template-notification-dialog.component.html | 2 +- .../template-notification-dialog.component.scss | 2 +- .../template-notification-dialog.component.ts | 2 +- .../template/template-table-config.resolver.ts | 2 +- .../template-table-header.component.html | 2 +- .../template-table-header.component.scss | 2 +- .../template/template-table-header.component.ts | 2 +- .../ota-update/ota-update-routing.module.ts | 2 +- .../ota-update-table-config.resolve.ts | 2 +- .../pages/ota-update/ota-update.component.html | 2 +- .../pages/ota-update/ota-update.component.ts | 2 +- .../home/pages/ota-update/ota-update.module.ts | 2 +- .../home/pages/profile/profile-routing.module.ts | 2 +- .../home/pages/profile/profile.component.html | 2 +- .../home/pages/profile/profile.component.scss | 2 +- .../home/pages/profile/profile.component.ts | 2 +- .../modules/home/pages/profile/profile.module.ts | 2 +- .../pages/profiles/profiles-routing.module.ts | 2 +- .../home/pages/profiles/profiles.module.ts | 2 +- ui-ngx/src/app/modules/home/pages/public-api.ts | 2 +- .../add-rule-node-dialog.component.html | 2 +- .../add-rule-node-dialog.component.scss | 2 +- .../add-rule-node-link-dialog.component.html | 2 +- .../add-rule-node-link-dialog.component.scss | 2 +- ...create-nested-rulechain-dialog.component.html | 2 +- .../pages/rulechain/link-labels.component.html | 2 +- .../pages/rulechain/link-labels.component.ts | 2 +- .../home/pages/rulechain/rule-node-colors.scss | 2 +- .../rulechain/rule-node-config.component.html | 2 +- .../rulechain/rule-node-config.component.scss | 2 +- .../rulechain/rule-node-config.component.ts | 2 +- .../rulechain/rule-node-details.component.html | 2 +- .../rulechain/rule-node-details.component.scss | 2 +- .../rulechain/rule-node-details.component.ts | 2 +- .../rulechain/rule-node-link.component.html | 2 +- .../pages/rulechain/rule-node-link.component.ts | 2 +- .../rulechain/rulechain-page.component.html | 2 +- .../rulechain/rulechain-page.component.scss | 2 +- .../pages/rulechain/rulechain-page.component.ts | 2 +- .../pages/rulechain/rulechain-page.models.ts | 2 +- .../pages/rulechain/rulechain-routing.module.ts | 2 +- .../rulechain/rulechain-tabs.component.html | 2 +- .../pages/rulechain/rulechain-tabs.component.ts | 2 +- .../pages/rulechain/rulechain.component.html | 2 +- .../pages/rulechain/rulechain.component.scss | 2 +- .../home/pages/rulechain/rulechain.component.ts | 2 +- .../home/pages/rulechain/rulechain.module.ts | 2 +- .../rulechains-table-config.resolver.ts | 2 +- .../home/pages/rulechain/rulenode.component.html | 2 +- .../home/pages/rulechain/rulenode.component.scss | 2 +- .../home/pages/rulechain/rulenode.component.ts | 2 +- .../authentication-dialog.component.scss | 2 +- .../authentication-dialog.map.ts | 2 +- .../backup-code-auth-dialog.component.html | 2 +- .../backup-code-auth-dialog.component.ts | 2 +- .../email-auth-dialog.component.html | 2 +- .../email-auth-dialog.component.ts | 2 +- .../sms-auth-dialog.component.html | 2 +- .../sms-auth-dialog.component.ts | 2 +- .../totp-auth-dialog.component.html | 2 +- .../totp-auth-dialog.component.ts | 2 +- .../pages/security/security-routing.module.ts | 2 +- .../home/pages/security/security.component.html | 2 +- .../home/pages/security/security.component.scss | 2 +- .../home/pages/security/security.component.ts | 2 +- .../home/pages/security/security.module.ts | 2 +- .../tenant-profile-routing.module.ts | 2 +- .../tenant-profile-tabs.component.html | 2 +- .../tenant-profile-tabs.component.ts | 2 +- .../tenant-profile/tenant-profile.module.ts | 2 +- .../tenant-profiles-table-config.resolver.ts | 2 +- .../home/pages/tenant/tenant-routing.module.ts | 2 +- .../home/pages/tenant/tenant-tabs.component.html | 2 +- .../home/pages/tenant/tenant-tabs.component.ts | 2 +- .../home/pages/tenant/tenant.component.html | 2 +- .../home/pages/tenant/tenant.component.scss | 2 +- .../home/pages/tenant/tenant.component.ts | 2 +- .../modules/home/pages/tenant/tenant.module.ts | 2 +- .../tenant/tenants-table-config.resolver.ts | 2 +- .../user/activation-link-dialog.component.html | 2 +- .../user/activation-link-dialog.component.ts | 2 +- .../pages/user/add-user-dialog.component.html | 2 +- .../pages/user/add-user-dialog.component.scss | 2 +- .../home/pages/user/add-user-dialog.component.ts | 2 +- .../home/pages/user/user-routing.module.ts | 2 +- .../home/pages/user/user-tabs.component.html | 2 +- .../home/pages/user/user-tabs.component.ts | 2 +- .../modules/home/pages/user/user.component.html | 2 +- .../modules/home/pages/user/user.component.scss | 2 +- .../modules/home/pages/user/user.component.ts | 2 +- .../app/modules/home/pages/user/user.module.ts | 2 +- .../pages/user/users-table-config.resolver.ts | 2 +- .../modules/home/pages/vc/vc-routing.module.ts | 2 +- .../src/app/modules/home/pages/vc/vc.module.ts | 2 +- .../save-widget-type-as-dialog.component.html | 2 +- .../save-widget-type-as-dialog.component.ts | 2 +- .../select-widget-type-dialog.component.html | 2 +- .../select-widget-type-dialog.component.scss | 2 +- .../select-widget-type-dialog.component.ts | 2 +- .../pages/widget/widget-editor.component.html | 2 +- .../pages/widget/widget-editor.component.scss | 2 +- .../home/pages/widget/widget-editor.component.ts | 2 +- .../home/pages/widget/widget-editor.models.ts | 2 +- .../widget/widget-library-routing.module.ts | 2 +- .../home/pages/widget/widget-library.module.ts | 2 +- .../widget-type-autocomplete.component.html | 2 +- .../widget-type-autocomplete.component.scss | 2 +- .../widget/widget-type-autocomplete.component.ts | 2 +- .../pages/widget/widget-type-tabs.component.html | 2 +- .../pages/widget/widget-type-tabs.component.ts | 2 +- .../home/pages/widget/widget-type.component.html | 2 +- .../home/pages/widget/widget-type.component.ts | 2 +- .../widget/widget-types-table-config.resolver.ts | 2 +- .../widget/widgets-bundle-tabs.component.html | 2 +- .../widget/widgets-bundle-tabs.component.ts | 2 +- .../widget/widgets-bundle-widgets.component.html | 2 +- .../widget/widgets-bundle-widgets.component.scss | 2 +- .../widget/widgets-bundle-widgets.component.ts | 2 +- .../pages/widget/widgets-bundle.component.html | 2 +- .../pages/widget/widgets-bundle.component.scss | 2 +- .../pages/widget/widgets-bundle.component.ts | 2 +- .../widgets-bundles-table-config.resolver.ts | 2 +- ui-ngx/src/app/modules/home/public-api.ts | 2 +- .../app/modules/login/login-routing.module.ts | 2 +- ui-ngx/src/app/modules/login/login.module.ts | 2 +- .../pages/login/create-password.component.html | 2 +- .../pages/login/create-password.component.scss | 2 +- .../pages/login/create-password.component.ts | 2 +- .../login/pages/login/login.component.html | 2 +- .../login/pages/login/login.component.scss | 2 +- .../modules/login/pages/login/login.component.ts | 2 +- .../login/reset-password-request.component.html | 2 +- .../login/reset-password-request.component.scss | 2 +- .../login/reset-password-request.component.ts | 2 +- .../pages/login/reset-password.component.html | 2 +- .../pages/login/reset-password.component.scss | 2 +- .../pages/login/reset-password.component.ts | 2 +- .../login/two-factor-auth-login.component.html | 2 +- .../login/two-factor-auth-login.component.scss | 2 +- .../login/two-factor-auth-login.component.ts | 2 +- .../shared/adapter/custom-datatime-adapter.ts | 2 +- .../animations/speed-dial-fab.animations.ts | 2 +- .../shared/components/breadcrumb.component.html | 2 +- .../shared/components/breadcrumb.component.scss | 2 +- .../shared/components/breadcrumb.component.ts | 2 +- ui-ngx/src/app/shared/components/breadcrumb.ts | 2 +- .../components/button/copy-button.component.html | 2 +- .../components/button/copy-button.component.scss | 2 +- .../components/button/copy-button.component.ts | 2 +- .../button/toggle-password.component.html | 2 +- .../button/toggle-password.component.ts | 2 +- .../shared/components/cheatsheet.component.ts | 2 +- .../components/circular-progress.directive.ts | 2 +- .../shared/components/color-input.component.html | 2 +- .../shared/components/color-input.component.scss | 3 +-- .../shared/components/color-input.component.ts | 2 +- .../color-picker-panel.component.html | 2 +- .../color-picker-panel.component.scss | 2 +- .../color-picker/color-picker-panel.component.ts | 2 +- .../color-picker/color-picker.component.html | 2 +- .../color-picker/color-picker.component.scss | 2 +- .../color-picker/color-picker.component.ts | 2 +- .../app/shared/components/contact.component.html | 2 +- .../app/shared/components/contact.component.ts | 2 +- .../src/app/shared/components/css.component.html | 2 +- .../src/app/shared/components/css.component.scss | 2 +- .../src/app/shared/components/css.component.ts | 2 +- .../dashboard-autocomplete.component.html | 2 +- .../dashboard-autocomplete.component.ts | 2 +- .../dashboard-select-panel.component.html | 2 +- .../dashboard-select-panel.component.scss | 2 +- .../dashboard-select-panel.component.ts | 2 +- .../components/dashboard-select.component.html | 2 +- .../components/dashboard-select.component.scss | 2 +- .../components/dashboard-select.component.ts | 2 +- .../dashboard-state-autocomplete.component.html | 2 +- .../dashboard-state-autocomplete.component.ts | 2 +- .../app/shared/components/dialog.component.ts | 2 +- .../dialog/alert-dialog.component.html | 2 +- .../dialog/alert-dialog.component.scss | 2 +- .../components/dialog/alert-dialog.component.ts | 2 +- .../dialog/color-picker-dialog.component.html | 2 +- .../dialog/color-picker-dialog.component.scss | 2 +- .../dialog/color-picker-dialog.component.ts | 2 +- .../dialog/confirm-dialog.component.html | 2 +- .../dialog/confirm-dialog.component.scss | 2 +- .../dialog/confirm-dialog.component.ts | 2 +- .../dialog/error-alert-dialog.component.html | 2 +- .../dialog/error-alert-dialog.component.scss | 2 +- .../dialog/error-alert-dialog.component.ts | 2 +- .../json-object-edit-dialog.component.html | 2 +- .../dialog/json-object-edit-dialog.component.ts | 2 +- .../dialog/material-icons-dialog.component.html | 2 +- .../dialog/material-icons-dialog.component.scss | 2 +- .../dialog/material-icons-dialog.component.ts | 2 +- .../node-script-test-dialog.component.html | 2 +- .../node-script-test-dialog.component.scss | 2 +- .../dialog/node-script-test-dialog.component.ts | 2 +- .../components/dialog/todo-dialog.component.html | 2 +- .../components/dialog/todo-dialog.component.scss | 2 +- .../components/dialog/todo-dialog.component.ts | 2 +- .../directives/component-outlet.directive.ts | 2 +- .../sring-template-outlet.directive.ts | 2 +- .../directives/tb-json-to-string.directive.ts | 2 +- .../entity/entity-autocomplete.component.html | 2 +- .../entity/entity-autocomplete.component.ts | 2 +- .../entity/entity-gateway-select.component.html | 2 +- .../entity/entity-gateway-select.component.ts | 2 +- .../entity/entity-keys-list.component.html | 2 +- .../entity/entity-keys-list.component.ts | 2 +- .../entity/entity-list-select.component.html | 2 +- .../entity/entity-list-select.component.scss | 2 +- .../entity/entity-list-select.component.ts | 2 +- .../components/entity/entity-list.component.html | 2 +- .../components/entity/entity-list.component.ts | 2 +- .../entity/entity-select.component.html | 2 +- .../entity/entity-select.component.scss | 2 +- .../components/entity/entity-select.component.ts | 2 +- .../entity-subtype-autocomplete.component.html | 2 +- .../entity-subtype-autocomplete.component.ts | 2 +- .../entity/entity-subtype-list.component.html | 2 +- .../entity/entity-subtype-list.component.ts | 2 +- .../entity/entity-subtype-select.component.html | 2 +- .../entity/entity-subtype-select.component.scss | 2 +- .../entity/entity-subtype-select.component.ts | 2 +- .../entity/entity-type-list.component.html | 2 +- .../entity/entity-type-list.component.ts | 2 +- .../entity/entity-type-select.component.html | 2 +- .../entity/entity-type-select.component.scss | 2 +- .../entity/entity-type-select.component.ts | 2 +- .../shared/components/fab-toolbar.component.html | 2 +- .../shared/components/fab-toolbar.component.scss | 2 +- .../shared/components/fab-toolbar.component.ts | 2 +- .../shared/components/file-input.component.html | 2 +- .../shared/components/file-input.component.scss | 2 +- .../shared/components/file-input.component.ts | 2 +- .../components/footer-fab-buttons.component.html | 2 +- .../components/footer-fab-buttons.component.scss | 2 +- .../components/footer-fab-buttons.component.ts | 2 +- .../app/shared/components/footer.component.html | 2 +- .../app/shared/components/footer.component.scss | 2 +- .../app/shared/components/footer.component.ts | 2 +- .../shared/components/fullscreen.directive.ts | 2 +- .../components/grid/scroll-grid-datasource.ts | 2 +- .../components/grid/scroll-grid.component.html | 2 +- .../components/grid/scroll-grid.component.scss | 2 +- .../components/grid/scroll-grid.component.ts | 2 +- .../components/help-markdown.component.html | 2 +- .../components/help-markdown.component.scss | 2 +- .../shared/components/help-markdown.component.ts | 2 +- .../shared/components/help-popup.component.html | 2 +- .../shared/components/help-popup.component.scss | 2 +- .../shared/components/help-popup.component.ts | 2 +- .../app/shared/components/help.component.html | 2 +- .../src/app/shared/components/help.component.ts | 2 +- .../components/hint-tooltip-icon.component.html | 2 +- .../components/hint-tooltip-icon.component.scss | 2 +- .../components/hint-tooltip-icon.component.ts | 2 +- .../app/shared/components/hotkeys.directive.ts | 2 +- .../app/shared/components/html.component.html | 2 +- .../app/shared/components/html.component.scss | 2 +- .../src/app/shared/components/html.component.ts | 2 +- .../src/app/shared/components/icon.component.ts | 2 +- .../shared/components/image-input.component.html | 2 +- .../shared/components/image-input.component.scss | 2 +- .../shared/components/image-input.component.ts | 2 +- .../image/embed-image-dialog.component.html | 2 +- .../image/embed-image-dialog.component.scss | 2 +- .../image/embed-image-dialog.component.ts | 2 +- .../image/gallery-image-input.component.html | 2 +- .../image/gallery-image-input.component.scss | 3 +-- .../image/gallery-image-input.component.ts | 2 +- .../components/image/image-dialog.component.html | 2 +- .../components/image/image-dialog.component.scss | 3 +-- .../components/image/image-dialog.component.ts | 2 +- .../image/image-gallery.component.html | 2 +- .../image/image-gallery.component.scss | 3 +-- .../components/image/image-gallery.component.ts | 2 +- .../image/image-references.component.html | 2 +- .../image/image-references.component.scss | 2 +- .../image/image-references.component.ts | 2 +- .../shared/components/image/images-datasource.ts | 2 +- .../image/images-in-use-dialog.component.html | 2 +- .../image/images-in-use-dialog.component.scss | 2 +- .../image/images-in-use-dialog.component.ts | 2 +- .../multiple-gallery-image-input.component.html | 2 +- .../multiple-gallery-image-input.component.scss | 2 +- .../multiple-gallery-image-input.component.ts | 2 +- .../image/upload-image-dialog.component.html | 2 +- .../image/upload-image-dialog.component.ts | 2 +- .../app/shared/components/js-func.component.html | 2 +- .../app/shared/components/js-func.component.scss | 2 +- .../app/shared/components/js-func.component.ts | 2 +- .../components/json-content.component.html | 2 +- .../components/json-content.component.scss | 2 +- .../shared/components/json-content.component.ts | 2 +- .../json-form/json-form-component.models.ts | 2 +- .../json-form/json-form.component.html | 2 +- .../json-form/json-form.component.scss | 2 +- .../components/json-form/json-form.component.ts | 2 +- .../json-form/react/json-form-ace-editor.tsx | 2 +- .../json-form/react/json-form-array.tsx | 2 +- .../json-form/react/json-form-base-component.tsx | 2 +- .../json-form/react/json-form-checkbox.tsx | 2 +- .../json-form/react/json-form-color.tsx | 2 +- .../components/json-form/react/json-form-css.tsx | 2 +- .../json-form/react/json-form-date.tsx | 2 +- .../json-form/react/json-form-fieldset.tsx | 2 +- .../json-form/react/json-form-help.tsx | 2 +- .../json-form/react/json-form-html.tsx | 2 +- .../json-form/react/json-form-icon.tsx | 2 +- .../json-form/react/json-form-image.tsx | 2 +- .../json-form/react/json-form-javascript.tsx | 2 +- .../json-form/react/json-form-json.tsx | 2 +- .../json-form/react/json-form-markdown.tsx | 2 +- .../json-form/react/json-form-number.tsx | 2 +- .../json-form/react/json-form-radios.tsx | 2 +- .../json-form/react/json-form-rc-select.tsx | 2 +- .../json-form/react/json-form-react.tsx | 2 +- .../json-form/react/json-form-schema-form.tsx | 2 +- .../json-form/react/json-form-select.tsx | 2 +- .../json-form/react/json-form-text.tsx | 2 +- .../json-form/react/json-form-utils.ts | 2 +- .../json-form/react/json-form.models.ts | 2 +- .../components/json-form/react/json-form.scss | 2 +- .../json-form/react/styles/thingsboardTheme.ts | 2 +- .../components/json-object-edit.component.html | 2 +- .../components/json-object-edit.component.scss | 2 +- .../components/json-object-edit.component.ts | 2 +- .../components/json-object-view.component.html | 2 +- .../components/json-object-view.component.scss | 2 +- .../components/json-object-view.component.ts | 2 +- .../app/shared/components/kv-map.component.html | 2 +- .../app/shared/components/kv-map.component.scss | 2 +- .../app/shared/components/kv-map.component.ts | 2 +- .../shared/components/led-light.component.html | 2 +- .../app/shared/components/led-light.component.ts | 2 +- .../app/shared/components/logo.component.html | 2 +- .../app/shared/components/logo.component.scss | 2 +- .../src/app/shared/components/logo.component.ts | 2 +- .../components/markdown-editor.component.html | 2 +- .../components/markdown-editor.component.scss | 2 +- .../components/markdown-editor.component.ts | 2 +- .../shared/components/markdown.component.html | 2 +- .../shared/components/markdown.component.scss | 3 +-- .../app/shared/components/markdown.component.ts | 2 +- .../shared/components/marked-options.service.ts | 2 +- .../material-icon-select.component.html | 2 +- .../material-icon-select.component.scss | 2 +- .../components/material-icon-select.component.ts | 2 +- .../components/material-icons.component.html | 2 +- .../components/material-icons.component.scss | 2 +- .../components/material-icons.component.ts | 2 +- .../message-type-autocomplete.component.html | 2 +- .../message-type-autocomplete.component.ts | 2 +- .../multiple-image-input.component.html | 2 +- .../multiple-image-input.component.scss | 2 +- .../components/multiple-image-input.component.ts | 2 +- .../shared/components/nav-tree.component.html | 2 +- .../shared/components/nav-tree.component.scss | 2 +- .../app/shared/components/nav-tree.component.ts | 2 +- .../notification/notification.component.html | 2 +- .../notification/notification.component.scss | 2 +- .../notification/notification.component.ts | 2 +- .../template-autocomplete.component.html | 2 +- .../template-autocomplete.component.scss | 2 +- .../template-autocomplete.component.ts | 2 +- .../ota-package-autocomplete.component.html | 2 +- .../ota-package-autocomplete.component.scss | 2 +- .../ota-package-autocomplete.component.ts | 2 +- .../src/app/shared/components/page.component.ts | 2 +- .../shared/components/phone-input.component.html | 2 +- .../shared/components/phone-input.component.scss | 2 +- .../shared/components/phone-input.component.ts | 2 +- .../app/shared/components/popover.component.scss | 2 +- .../app/shared/components/popover.component.ts | 2 +- .../src/app/shared/components/popover.models.ts | 2 +- .../src/app/shared/components/popover.service.ts | 2 +- .../components/protobuf-content.component.html | 2 +- .../components/protobuf-content.component.scss | 2 +- .../components/protobuf-content.component.ts | 2 +- ui-ngx/src/app/shared/components/public-api.ts | 2 +- .../queue/queue-autocomplete.component.html | 2 +- .../queue/queue-autocomplete.component.scss | 2 +- .../queue/queue-autocomplete.component.ts | 2 +- .../relation-type-autocomplete.component.html | 2 +- .../relation-type-autocomplete.component.ts | 2 +- .../resource-autocomplete.component.html | 2 +- .../resource/resource-autocomplete.component.ts | 2 +- .../rule-chain/rule-chain-select.component.html | 2 +- .../rule-chain/rule-chain-select.component.scss | 2 +- .../rule-chain/rule-chain-select.component.ts | 2 +- .../shared/components/script-lang.component.html | 2 +- .../shared/components/script-lang.component.scss | 2 +- .../shared/components/script-lang.component.ts | 2 +- ...lack-conversation-autocomplete.component.html | 2 +- ...lack-conversation-autocomplete.component.scss | 2 +- .../slack-conversation-autocomplete.component.ts | 2 +- .../shared/components/snack-bar-component.html | 2 +- .../shared/components/snack-bar-component.scss | 2 +- .../components/socialshare-panel.component.html | 2 +- .../components/socialshare-panel.component.scss | 2 +- .../components/socialshare-panel.component.ts | 2 +- .../string-autocomplete.component.html | 2 +- .../string-autocomplete.component.scss | 2 +- .../components/string-autocomplete.component.ts | 2 +- .../components/string-items-list.component.html | 2 +- .../components/string-items-list.component.ts | 2 +- .../app/shared/components/tb-anchor.component.ts | 2 +- .../shared/components/tb-checkbox.component.html | 2 +- .../shared/components/tb-checkbox.component.ts | 2 +- .../app/shared/components/tb-error.component.ts | 2 +- .../time/datetime-period.component.html | 2 +- .../time/datetime-period.component.scss | 2 +- .../components/time/datetime-period.component.ts | 2 +- .../components/time/datetime.component.html | 2 +- .../shared/components/time/datetime.component.ts | 2 +- .../history-selector.component.html | 2 +- .../history-selector.component.scss | 2 +- .../history-selector.component.ts | 2 +- .../time/quick-time-interval.component.html | 2 +- .../time/quick-time-interval.component.scss | 2 +- .../time/quick-time-interval.component.ts | 2 +- .../components/time/timeinterval.component.html | 2 +- .../components/time/timeinterval.component.scss | 2 +- .../components/time/timeinterval.component.ts | 2 +- .../time/timewindow-panel.component.html | 2 +- .../time/timewindow-panel.component.scss | 2 +- .../time/timewindow-panel.component.ts | 2 +- .../components/time/timewindow.component.html | 2 +- .../components/time/timewindow.component.scss | 2 +- .../components/time/timewindow.component.ts | 2 +- .../time/timezone-select.component.html | 2 +- .../components/time/timezone-select.component.ts | 2 +- .../src/app/shared/components/toast.directive.ts | 2 +- .../components/toggle-header.component.html | 2 +- .../components/toggle-header.component.scss | 3 +-- .../shared/components/toggle-header.component.ts | 2 +- .../components/toggle-select.component.html | 2 +- .../shared/components/toggle-select.component.ts | 2 +- ui-ngx/src/app/shared/components/tokens.ts | 2 +- .../shared/components/unit-input.component.html | 2 +- .../shared/components/unit-input.component.scss | 2 +- .../shared/components/unit-input.component.ts | 2 +- .../shared/components/user-menu.component.html | 2 +- .../shared/components/user-menu.component.scss | 2 +- .../app/shared/components/user-menu.component.ts | 2 +- .../shared/components/value-input.component.html | 2 +- .../shared/components/value-input.component.scss | 2 +- .../shared/components/value-input.component.ts | 2 +- .../vc/branch-autocomplete.component.html | 2 +- .../vc/branch-autocomplete.component.scss | 2 +- .../vc/branch-autocomplete.component.ts | 2 +- .../widgets-bundle-search.component.html | 2 +- .../widgets-bundle-search.component.scss | 2 +- .../widgets-bundle-search.component.ts | 2 +- .../widgets-bundle-select.component.html | 2 +- .../widgets-bundle-select.component.scss | 2 +- .../widgets-bundle-select.component.ts | 2 +- ui-ngx/src/app/shared/decorators/coercion.ts | 2 +- ui-ngx/src/app/shared/decorators/enumerable.ts | 2 +- ui-ngx/src/app/shared/decorators/public-api.ts | 2 +- ui-ngx/src/app/shared/decorators/tb-inject.ts | 2 +- .../export-widgets-bundle-dialog.component.html | 2 +- .../export-widgets-bundle-dialog.component.ts | 2 +- .../import-dialog-csv.component.html | 2 +- .../import-dialog-csv.component.scss | 2 +- .../import-export/import-dialog-csv.component.ts | 2 +- .../import-export/import-dialog.component.html | 2 +- .../import-export/import-dialog.component.ts | 2 +- .../shared/import-export/import-export.models.ts | 2 +- .../import-export/import-export.service.ts | 2 +- .../table-columns-assignment.component.html | 2 +- .../table-columns-assignment.component.scss | 2 +- .../table-columns-assignment.component.ts | 2 +- .../src/app/shared/layout/layout.directives.ts | 2 +- ui-ngx/src/app/shared/models/ace/ace.models.ts | 2 +- .../app/shared/models/ace/completion.models.ts | 2 +- .../models/ace/service-completion.models.ts | 2 +- .../src/app/shared/models/ace/tbel/mode-tbel.js | 2 +- .../app/shared/models/ace/tbel/worker-tbel.js | 2 +- .../models/ace/widget-completion.models.ts | 2 +- ui-ngx/src/app/shared/models/alarm.models.ts | 2 +- ui-ngx/src/app/shared/models/alias.models.ts | 2 +- ui-ngx/src/app/shared/models/api-usage.models.ts | 2 +- ui-ngx/src/app/shared/models/asset.models.ts | 2 +- ui-ngx/src/app/shared/models/audit-log.models.ts | 2 +- ui-ngx/src/app/shared/models/authority.enum.ts | 2 +- ui-ngx/src/app/shared/models/base-data.ts | 2 +- ui-ngx/src/app/shared/models/beautify.models.ts | 2 +- .../shared/models/component-descriptor.models.ts | 2 +- ui-ngx/src/app/shared/models/constants.ts | 2 +- .../src/app/shared/models/contact-based.model.ts | 2 +- ui-ngx/src/app/shared/models/country.models.ts | 2 +- ui-ngx/src/app/shared/models/customer.model.ts | 2 +- ui-ngx/src/app/shared/models/dashboard.models.ts | 2 +- ui-ngx/src/app/shared/models/device.models.ts | 2 +- ui-ngx/src/app/shared/models/edge.models.ts | 2 +- .../src/app/shared/models/entity-type.models.ts | 2 +- .../src/app/shared/models/entity-view.models.ts | 2 +- ui-ngx/src/app/shared/models/entity.models.ts | 2 +- ui-ngx/src/app/shared/models/error.models.ts | 2 +- ui-ngx/src/app/shared/models/event.models.ts | 2 +- ui-ngx/src/app/shared/models/icon.models.ts | 2 +- .../src/app/shared/models/id/alarm-comment-id.ts | 2 +- ui-ngx/src/app/shared/models/id/alarm-id.ts | 2 +- ui-ngx/src/app/shared/models/id/asset-id.ts | 2 +- .../src/app/shared/models/id/asset-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/audit-log-id.ts | 2 +- ui-ngx/src/app/shared/models/id/customer-id.ts | 2 +- ui-ngx/src/app/shared/models/id/dashboard-id.ts | 2 +- .../shared/models/id/device-credentials-id.ts | 2 +- ui-ngx/src/app/shared/models/id/device-id.ts | 2 +- .../app/shared/models/id/device-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/edge-id.ts | 2 +- ui-ngx/src/app/shared/models/id/entity-id.ts | 2 +- .../src/app/shared/models/id/entity-view-id.ts | 2 +- ui-ngx/src/app/shared/models/id/event-id.ts | 2 +- ui-ngx/src/app/shared/models/id/has-uuid.ts | 2 +- .../src/app/shared/models/id/notification-id.ts | 2 +- .../shared/models/id/notification-request-id.ts | 2 +- .../app/shared/models/id/notification-rule-id.ts | 2 +- .../shared/models/id/notification-target-id.ts | 2 +- .../shared/models/id/notification-template-id.ts | 2 +- .../src/app/shared/models/id/ota-package-id.ts | 2 +- ui-ngx/src/app/shared/models/id/public-api.ts | 2 +- ui-ngx/src/app/shared/models/id/queue-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rpc-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rule-chain-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rule-node-id.ts | 2 +- .../src/app/shared/models/id/tb-resource-id.ts | 2 +- ui-ngx/src/app/shared/models/id/tenant-id.ts | 2 +- .../app/shared/models/id/tenant-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/user-id.ts | 2 +- .../src/app/shared/models/id/widget-type-id.ts | 2 +- .../app/shared/models/id/widgets-bundle-id.ts | 2 +- .../src/app/shared/models/limited-api.models.ts | 2 +- ui-ngx/src/app/shared/models/login.models.ts | 2 +- .../models/lwm2m-security-config.models.ts | 2 +- ui-ngx/src/app/shared/models/material.models.ts | 2 +- .../src/app/shared/models/notification.models.ts | 2 +- ui-ngx/src/app/shared/models/oauth2.models.ts | 2 +- .../src/app/shared/models/ota-package.models.ts | 2 +- ui-ngx/src/app/shared/models/overlay.models.ts | 2 +- ui-ngx/src/app/shared/models/page/page-data.ts | 2 +- ui-ngx/src/app/shared/models/page/page-link.ts | 2 +- ui-ngx/src/app/shared/models/page/public-api.ts | 2 +- ui-ngx/src/app/shared/models/page/sort-order.ts | 2 +- ui-ngx/src/app/shared/models/public-api.ts | 2 +- .../src/app/shared/models/query/query.models.ts | 2 +- ui-ngx/src/app/shared/models/queue.models.ts | 2 +- ui-ngx/src/app/shared/models/relation.models.ts | 2 +- ui-ngx/src/app/shared/models/resource.models.ts | 2 +- ui-ngx/src/app/shared/models/rpc.models.ts | 2 +- .../src/app/shared/models/rule-chain.models.ts | 2 +- ui-ngx/src/app/shared/models/rule-node.models.ts | 2 +- ui-ngx/src/app/shared/models/settings.models.ts | 2 +- .../shared/models/telemetry/telemetry.models.ts | 2 +- ui-ngx/src/app/shared/models/tenant.model.ts | 2 +- ui-ngx/src/app/shared/models/time/time.models.ts | 2 +- .../app/shared/models/two-factor-auth.models.ts | 2 +- ui-ngx/src/app/shared/models/unit.models.ts | 2 +- ui-ngx/src/app/shared/models/usage.models.ts | 2 +- .../app/shared/models/user-settings.models.ts | 2 +- ui-ngx/src/app/shared/models/user.model.ts | 2 +- ui-ngx/src/app/shared/models/vc.models.ts | 2 +- .../shared/models/websocket/websocket.models.ts | 2 +- .../app/shared/models/widget-settings.models.ts | 2 +- ui-ngx/src/app/shared/models/widget.models.ts | 2 +- .../app/shared/models/widgets-bundle.model.ts | 2 +- .../app/shared/models/window-message.model.ts | 2 +- ui-ngx/src/app/shared/pipe/date-ago.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/enum-to-array.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/file-size.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/highlight.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/image.pipe.ts | 2 +- .../app/shared/pipe/keyboard-shortcut.pipe.ts | 2 +- .../pipe/milliseconds-to-time-string.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/nospace.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/public-api.ts | 2 +- ui-ngx/src/app/shared/pipe/safe.pipe.ts | 2 +- .../app/shared/pipe/selectable-columns.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/short-number.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/tbJson.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/truncate.pipe.ts | 2 +- ui-ngx/src/app/shared/public-api.ts | 2 +- .../app/shared/services/custom-paginator-intl.ts | 2 +- ui-ngx/src/app/shared/shared.module.ts | 2 +- ui-ngx/src/assets/fonts/material-icons.css | 2 +- ui-ngx/src/environments/environment.prod.ts | 2 +- ui-ngx/src/environments/environment.ts | 2 +- ui-ngx/src/form.scss | 3 +-- ui-ngx/src/index.html | 2 +- ui-ngx/src/karma.conf.js | 2 +- ui-ngx/src/main.ts | 2 +- ui-ngx/src/polyfills.ts | 2 +- ui-ngx/src/scss/animations.scss | 2 +- ui-ngx/src/scss/constants.scss | 2 +- ui-ngx/src/scss/fonts.scss | 2 +- ui-ngx/src/scss/mixins.scss | 2 +- ui-ngx/src/styles.scss | 2 +- ui-ngx/src/test.ts | 2 +- ui-ngx/src/theme-overwrites.scss | 2 +- ui-ngx/src/theme.scss | 2 +- ui-ngx/src/theme/datepicker-theme.scss | 2 +- ui-ngx/src/typings/jquery.flot.typings.d.ts | 2 +- ui-ngx/src/typings/jquery.jstree.typings.d.ts | 2 +- ui-ngx/src/typings/jquery.typings.d.ts | 2 +- ui-ngx/src/typings/leaflet-extend-tb.d.ts | 2 +- ui-ngx/src/typings/leaflet-geoman-extend.d.ts | 2 +- ui-ngx/src/typings/rawloader.typings.d.ts | 2 +- ui-ngx/src/typings/split.js.typings.d.ts | 2 +- ui-ngx/src/typings/utils.d.ts | 2 +- ui-ngx/src/zone-flags.ts | 2 +- 5946 files changed, 5961 insertions(+), 5985 deletions(-) diff --git a/.github/release.yml b/.github/release.yml index 1d760fe7bf..5e0ddc4300 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,5 +1,5 @@ # -# Copyright © 2016-2023 The Thingsboard Authors +# Copyright © 2016-2024 The Thingsboard Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/check-configuration-files.yml b/.github/workflows/check-configuration-files.yml index 0b292ded79..94bfc85ce3 100644 --- a/.github/workflows/check-configuration-files.yml +++ b/.github/workflows/check-configuration-files.yml @@ -1,5 +1,5 @@ # -# Copyright © 2016-2023 The Thingsboard Authors +# Copyright © 2016-2024 The Thingsboard Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/application/pom.xml b/application/pom.xml index 076676ae81..aaa8a1f447 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -1,6 +1,6 @@ - diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss index 3aed0ccb5e..505db79a36 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 The Thingsboard Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - .user-avatar { display: inline-flex; justify-content: center; diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts index 1fb1d3f689..0fc489fbfe 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 The Thingsboard Authors /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html index 8618592ae0..8145c31b06 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html @@ -1,6 +1,6 @@ -
-

{{ "attribute.delete-timeseries.delete-strategy" | translate }}

diff --git a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss index b0c0ec0621..b6fac754b7 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 The Thingsboard Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts index df2eb931df..a6ae799198 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 The Thingsboard Authors /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html index 2ec3455adf..6725b36960 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html @@ -1,6 +1,6 @@ -
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss index e704120560..cd7722d12d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 The Thingsboard Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts index 503f5643bf..a3cb79e125 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 The Thingsboard Authors /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts index d58c33079a..603b06cc01 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 The Thingsboard Authors /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html index 1eaf791577..7f86897f7e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html @@ -1,6 +1,6 @@ + diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss new file mode 100644 index 0000000000..ac49971339 --- /dev/null +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss @@ -0,0 +1,32 @@ +@import '../../../../scss/constants'; + +:host { + .tb-image-gallery-dialog { + position: relative; + padding: 24px 32px 16px 32px; + width: 100vw; + height: 100vh; + max-height: 100vh; + @media #{$mat-gt-xs} { + width: 80vw; + height: 80vh; + max-height: 80vh; + } + @media #{$mat-gt-sm} { + width: 700px; + } + @media #{$mat-gt-md} { + width: 900px; + } + @media #{$mat-gt-xl} { + width: 900px; + } + .tb-image-gallery-close { + position: absolute; + top: 12px; + right: 12px; + z-index: 1; + color: rgba(0, 0, 0, 0.38); + } + } +} diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts new file mode 100644 index 0000000000..482fbe76a5 --- /dev/null +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts @@ -0,0 +1,62 @@ +/// +/// Copyright © 2016-2024 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; +import { ErrorStateMatcher } from '@angular/material/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { Router } from '@angular/router'; +import { ImageService } from '@core/http/image.service'; +import { ImageResourceInfo, imageResourceType } from '@shared/models/resource.models'; +import { + UploadImageDialogComponent, + UploadImageDialogData +} from '@shared/components/image/upload-image-dialog.component'; +import { UrlHolder } from '@shared/pipe/image.pipe'; +import { ImportExportService } from '@shared/import-export/import-export.service'; +import { EmbedImageDialogComponent, EmbedImageDialogData } from '@shared/components/image/embed-image-dialog.component'; + +@Component({ + selector: 'tb-image-gallery-dialog', + templateUrl: './image-gallery-dialog.component.html', + styleUrls: ['./image-gallery-dialog.component.scss'] +}) +export class ImageGalleryDialogComponent extends + DialogComponent implements OnInit { + + constructor(protected store: Store, + protected router: Router, + private imageService: ImageService, + private dialog: MatDialog, + public dialogRef: MatDialogRef) { + super(store, router, dialogRef); + } + + ngOnInit(): void { + } + + cancel(): void { + this.dialogRef.close(null); + } + + imageSelected(image: ImageResourceInfo): void { + this.dialogRef.close(image); + } + +} diff --git a/ui-ngx/src/app/shared/components/image/image-gallery.component.html b/ui-ngx/src/app/shared/components/image/image-gallery.component.html index 3e357a21b3..21b10e8c66 100644 --- a/ui-ngx/src/app/shared/components/image/image-gallery.component.html +++ b/ui-ngx/src/app/shared/components/image/image-gallery.component.html @@ -15,11 +15,11 @@ limitations under the License. --> -
+
+ fxLayout.lt-lg="column" fxLayoutAlign.lt-lg="start stretch" + [fxShow]="!textSearchMode && (mode === 'grid' || dataSource?.selection.isEmpty())" [ngClass.lt-lg]="{'multi-row': !isSysAdmin}">
image.gallery @@ -44,11 +44,11 @@
{{ 'image.include-system-images' | translate }}
-
+
- {{ 'image.include-system-images' | translate }} @@ -293,7 +293,7 @@ [hidePageSize]="hidePageSize" showFirstLastButtons>
-
+
Date: Tue, 9 Jan 2024 14:54:32 +0200 Subject: [PATCH 47/91] Update license header --- .../image/image-gallery-dialog.component.scss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss index ac49971339..6ebda09fb5 100644 --- a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ @import '../../../../scss/constants'; :host { From 523651b71cb77eb53b049431e015d642e1384ced Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 9 Jan 2024 16:52:50 +0200 Subject: [PATCH 48/91] overload saveWidgetType, getWidgetTypes, getBundleWidgetTypesInfos methods --- .../org/thingsboard/rest/client/RestClient.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index c950febfa7..10d3863a2a 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2767,13 +2767,24 @@ public class RestClient implements Closeable { } public WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetTypeDetails) { - return restTemplate.postForEntity(baseURL + "/api/widgetType", widgetTypeDetails, WidgetTypeDetails.class).getBody(); + return saveWidgetType(widgetTypeDetails, null); + } + + public WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetTypeDetails, Boolean updateExistingByFqn) { + if (updateExistingByFqn == null) { + return restTemplate.postForEntity(baseURL + "/api/widgetType", widgetTypeDetails, WidgetTypeDetails.class).getBody(); + } + return restTemplate.postForEntity(baseURL + "/api/widgetType?updateExistingByFqn={updateExistingByFqn}", widgetTypeDetails, WidgetTypeDetails.class, updateExistingByFqn).getBody(); } public void deleteWidgetType(WidgetTypeId widgetTypeId) { restTemplate.delete(baseURL + "/api/widgetType/{widgetTypeId}", widgetTypeId.getId()); } + public PageData getWidgetTypes(PageLink pageLink) { + return getWidgetTypes(pageLink, null, null, null, null); + } + public PageData getWidgetTypes(PageLink pageLink, Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { Map params = new HashMap<>(); @@ -2856,6 +2867,10 @@ public class RestClient implements Closeable { bundleAlias).getBody(); } + public PageData getBundleWidgetTypesInfos(WidgetsBundleId widgetsBundleId, PageLink pageLink) { + return getBundleWidgetTypesInfos(widgetsBundleId, pageLink, null, null, null, null); + } + public PageData getBundleWidgetTypesInfos(WidgetsBundleId widgetsBundleId, PageLink pageLink, Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { From e3041adc42d71a3751823b42113be69eaef02299 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 9 Jan 2024 18:18:10 +0200 Subject: [PATCH 49/91] Grouping interval structures --- .../server/ThingsboardServerApplication.java | 6 ++++- .../ws/telemetry/cmd/v2/EntityHistoryCmd.java | 3 +++ .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 5 +++++ .../ws/telemetry/cmd/v2/TimeSeriesCmd.java | 3 +++ .../server/common/data/kv/IntervalType.java | 22 +++++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java index 60f69cd8a7..77442e53a8 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java @@ -21,6 +21,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; +import java.time.ZoneId; import java.util.Arrays; @SpringBootConfiguration @@ -33,7 +34,10 @@ public class ThingsboardServerApplication { private static final String DEFAULT_SPRING_CONFIG_PARAM = SPRING_CONFIG_NAME_KEY + "=" + "thingsboard"; public static void main(String[] args) { - SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); + + ZoneId.getAvailableZoneIds().stream().sorted().forEach(System.out::println); + +// SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); } private static String[] updateArguments(String[] args) { diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java index 6ae9a03ff8..3b3dd0d55d 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import lombok.Data; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -26,7 +27,9 @@ public class EntityHistoryCmd implements GetTsCmd { private List keys; private long startTs; private long endTs; + private IntervalType intervalType; private long interval; + private String timeZoneId; private int limit; private Aggregation agg; private boolean fetchLatestPreviousPoint; diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java index 039873bb18..80a749fbe7 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -27,8 +28,12 @@ public interface GetTsCmd { List getKeys(); + IntervalType getIntervalType(); + long getInterval(); + String getTimeZoneId(); + int getLimit(); Aggregation getAgg(); diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java index e7a9e03d17..3c3d53e426 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -27,7 +28,9 @@ public class TimeSeriesCmd implements GetTsCmd { private List keys; private long startTs; private long timeWindow; + private IntervalType intervalType; private long interval; + private String timeZoneId; private int limit; private Aggregation agg; private boolean fetchLatestPreviousPoint; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java new file mode 100644 index 0000000000..e5ebb7f1a1 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java @@ -0,0 +1,22 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.kv; + +public enum IntervalType { + + MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER + +} From 29289baeb49cbe5bc48baa97baacf00c52210547 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 10 Jan 2024 12:42:53 +0200 Subject: [PATCH 50/91] added missing WidgetsBundleController APIs to RestClient --- .../thingsboard/rest/client/RestClient.java | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index 10d3863a2a..0f982c3ff0 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2715,15 +2715,33 @@ public class RestClient implements Closeable { return restTemplate.postForEntity(baseURL + "/api/widgetsBundle", widgetsBundle, WidgetsBundle.class).getBody(); } + public void updateWidgetsBundleWidgetTypes(WidgetsBundleId widgetsBundleId, List widgetTypeIds) { + var httpEntity = new HttpEntity<>(widgetTypeIds.stream() + .map(widgetTypeId -> widgetTypeId.getId().toString()) + .collect(Collectors.toList())); + restTemplate.exchange(baseURL + "/api/widgetsBundle/{widgetsBundleId}/widgetTypes", + HttpMethod.POST, httpEntity, Void.class, widgetsBundleId.getId()); + } + + public void updateWidgetsBundleWidgetFqns(WidgetsBundleId widgetsBundleId, List widgetTypeFqns) { + restTemplate.exchange(baseURL + "/api/widgetsBundle/{widgetsBundleId}/widgetTypeFqns", + HttpMethod.POST, new HttpEntity<>(widgetTypeFqns), Void.class, widgetsBundleId.getId()); + } + public void deleteWidgetsBundle(WidgetsBundleId widgetsBundleId) { restTemplate.delete(baseURL + "/api/widgetsBundle/{widgetsBundleId}", widgetsBundleId.getId()); } public PageData getWidgetsBundles(PageLink pageLink) { + return getWidgetsBundles(pageLink, null, null); + } + + public PageData getWidgetsBundles(PageLink pageLink, Boolean tenantOnly, Boolean fullSearch) { Map params = new HashMap<>(); addPageLinkToParam(params, pageLink); + addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); return restTemplate.exchange( - baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink), + baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getWidgetsBundlePageRequestUrlParams(tenantOnly, fullSearch), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference>() { @@ -3758,6 +3776,17 @@ public class RestClient implements Closeable { return urlParams; } + private String getWidgetsBundlePageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch) { + String urlParams = ""; + if (tenantOnly != null) { + urlParams = "&tenantOnly={tenantOnly}"; + } + if (fullSearch != null) { + urlParams += "&fullSearch={fullSearch}"; + } + return urlParams; + } + private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { @@ -3801,12 +3830,7 @@ public class RestClient implements Closeable { private void addWidgetInfoFiltersToParams(Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList, Map params) { - if (tenantOnly != null) { - params.put("tenantOnly", tenantOnly.toString()); - } - if (fullSearch != null) { - params.put("fullSearch", fullSearch.toString()); - } + addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); if (deprecatedFilter != null) { params.put("deprecatedFilter", deprecatedFilter.name()); } @@ -3815,6 +3839,15 @@ public class RestClient implements Closeable { } } + private void addTenantOnlyAndFullSearchToParams(Boolean tenantOnly, Boolean fullSearch, Map params) { + if (tenantOnly != null) { + params.put("tenantOnly", tenantOnly.toString()); + } + if (fullSearch != null) { + params.put("fullSearch", fullSearch.toString()); + } + } + private String listToString(List list) { return String.join(",", list); } From 4155fcd03fa2d08b2d583cb464ddaa631e5f0e72 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 10 Jan 2024 13:07:19 +0200 Subject: [PATCH 51/91] Minor refactoring of private method after self review --- .../thingsboard/rest/client/RestClient.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index 0f982c3ff0..4c03bb1847 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2741,7 +2741,7 @@ public class RestClient implements Closeable { addPageLinkToParam(params, pageLink); addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); return restTemplate.exchange( - baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getWidgetsBundlePageRequestUrlParams(tenantOnly, fullSearch), + baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getTenantOnlyAndFullSearchUrlParams(tenantOnly, fullSearch), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference>() { @@ -3776,20 +3776,20 @@ public class RestClient implements Closeable { return urlParams; } - private String getWidgetsBundlePageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch) { - String urlParams = ""; - if (tenantOnly != null) { - urlParams = "&tenantOnly={tenantOnly}"; + private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, + DeprecatedFilter deprecatedFilter, + List widgetTypeList) { + String urlParams = getTenantOnlyAndFullSearchUrlParams(tenantOnly, fullSearch); + if (deprecatedFilter != null) { + urlParams += "&deprecatedFilter={deprecatedFilter}"; } - if (fullSearch != null) { - urlParams += "&fullSearch={fullSearch}"; + if (!CollectionUtils.isEmpty(widgetTypeList)) { + urlParams += "&widgetTypeList={widgetTypeList}"; } return urlParams; } - private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, - DeprecatedFilter deprecatedFilter, - List widgetTypeList) { + private String getTenantOnlyAndFullSearchUrlParams(Boolean tenantOnly, Boolean fullSearch) { String urlParams = ""; if (tenantOnly != null) { urlParams = "&tenantOnly={tenantOnly}"; @@ -3797,12 +3797,6 @@ public class RestClient implements Closeable { if (fullSearch != null) { urlParams += "&fullSearch={fullSearch}"; } - if (deprecatedFilter != null) { - urlParams += "&deprecatedFilter={deprecatedFilter}"; - } - if (!CollectionUtils.isEmpty(widgetTypeList)) { - urlParams += "&widgetTypeList={widgetTypeList}"; - } return urlParams; } From 7fc22311898196f5758630a80bbf33b029c47c3c Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 11 Jan 2024 12:40:50 +0200 Subject: [PATCH 52/91] Interval types back-end implementation --- .../controller/TelemetryController.java | 21 ++++- ...efaultTbEntityDataSubscriptionService.java | 7 +- .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 13 +++ .../controller/TelemetryControllerTest.java | 59 ++++++++++++ .../common/data/kv/AggregationParams.java | 92 +++++++++++++++++++ .../common/data/kv/BaseReadTsKvQuery.java | 26 ++++-- .../server/common/data/kv/IntervalType.java | 2 +- .../server/common/data/kv/ReadTsKvQuery.java | 12 ++- ...stractChunkedAggregationTimeseriesDao.java | 23 ++++- .../timescale/TimescaleTimeseriesDao.java | 24 ++++- .../CassandraBaseTimeseriesDao.java | 18 +++- .../dao/timeseries/TsKvQueryCursor.java | 2 +- .../server/dao/util/TimeUtils.java | 45 +++++++++ .../server/dao/util/TimeUtilsTest.java | 60 ++++++++++++ 14 files changed, 370 insertions(+), 34 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java create mode 100644 dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 295b8cad99..288828f046 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -45,6 +45,8 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.kv.AggregationParams; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; @@ -310,8 +312,12 @@ public class TelemetryController extends BaseController { @RequestParam(name = "startTs") Long startTs, @ApiParam(value = "A long value representing the end timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "endTs") Long endTs, + @ApiParam(value = "A string value representing the type fo the interval.", allowableValues = "MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER") + @RequestParam(name = "intervalType", required = false) IntervalType intervalType, @ApiParam(value = "A long value representing the aggregation interval range in milliseconds.") @RequestParam(name = "interval", defaultValue = "0") Long interval, + @ApiParam(value = "A string value representing the timezone that will be used to calculate exact timestamps for 'WEEK', 'WEEK_ISO', 'MONTH' and 'QUARTER' interval types.") + @RequestParam(name = "timeZone", required = false) String timeZone, @ApiParam(value = "An integer value that represents a max number of timeseries data points to fetch." + " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", defaultValue = "100") @RequestParam(name = "limit", defaultValue = "100") Integer limit, @@ -325,11 +331,16 @@ public class TelemetryController extends BaseController { @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> { - // If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted - Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr); - List queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg, orderBy)) - .collect(Collectors.toList()); - + AggregationParams params; + Aggregation agg = Aggregation.valueOf(aggStr); + if (Aggregation.NONE.equals(agg)) { + params = AggregationParams.none(); + } else if (intervalType == null || IntervalType.MILLISECONDS.equals(intervalType)) { + params = interval == 0L ? AggregationParams.none() : AggregationParams.milliseconds(agg, interval); + } else { + params = AggregationParams.calendar(agg, intervalType, timeZone); + } + List queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, params, limit, orderBy)).collect(Collectors.toList()); Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor()); }); } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java index 5251ee72f6..6e31a24275 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java @@ -560,17 +560,14 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc List keys = cmd.getKeys(); List finalTsKvQueryList; List tsKvQueryList = keys.stream().map(key -> { - var query = new BaseReadTsKvQuery( - key, cmd.getStartTs(), cmd.getEndTs(), cmd.getInterval(), getLimit(cmd.getLimit()), cmd.getAgg() - ); + var query = new BaseReadTsKvQuery(key, cmd.getStartTs(), cmd.getEndTs(), cmd.toAggregationParams(), getLimit(cmd.getLimit())); queriesKeys.put(query.getId(), query.getKey()); return query; }).collect(Collectors.toList()); if (cmd.isFetchLatestPreviousPoint()) { finalTsKvQueryList = new ArrayList<>(tsKvQueryList); finalTsKvQueryList.addAll(keys.stream().map(key -> { - var query = new BaseReadTsKvQuery( - key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.getInterval(), 1, cmd.getAgg()); + var query = new BaseReadTsKvQuery(key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.toAggregationParams(), 1); queriesKeys.put(query.getId(), query.getKey()); return query; } diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java index 80a749fbe7..ef5d9efb96 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.AggregationParams; import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -40,4 +41,16 @@ public interface GetTsCmd { boolean isFetchLatestPreviousPoint(); + default AggregationParams toAggregationParams() { + var agg = getAgg(); + var intervalType = getIntervalType(); + if (agg == null || Aggregation.NONE.equals(agg)) { + return AggregationParams.none(); + } else if (intervalType == null || IntervalType.MILLISECONDS.equals(intervalType)) { + return AggregationParams.milliseconds(agg, getInterval()); + } else { + return AggregationParams.calendar(agg, intervalType, getTimeZoneId()); + } + } + } diff --git a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java index 8061cf0eab..98fbffaee5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java @@ -15,12 +15,17 @@ */ package org.thingsboard.server.controller; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Assert; import org.junit.Test; import org.springframework.test.context.TestPropertySource; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; +import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.SingleEntityFilter; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -28,6 +33,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.List; +import java.util.concurrent.TimeUnit; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.query.EntityKeyType.TIME_SERIES; @@ -51,6 +57,59 @@ public class TelemetryControllerTest extends AbstractControllerTest { doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", invalidRequestBody, String.class, status().isBadRequest()); } + @Test + public void testTelemetryRequests() throws Exception { + loginTenantAdmin(); + Device device = createDevice(); + + var startTs = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + var endOfWeek1Ts = 1705269600000L; // Monday, January 15, 2024 0:00:00 GMT+02:00 + var endOfWeek2Ts = 1705874400000L; // Monday, January 22, 2024 0:00:00 GMT+02:00 + var endTs = endOfWeek2Ts + TimeUnit.DAYS.toMillis(1) + TimeUnit.HOURS.toMillis(1); // Monday, January 23, 2024 1:00:00 GMT+02:00 + + var firstIntervalTs = startTs + (endOfWeek1Ts - startTs) / 2; + var secondIntervalTs = endOfWeek1Ts + (endOfWeek2Ts - endOfWeek1Ts) / 2; + var thirdIntervalTs = endOfWeek2Ts + (endTs - endOfWeek2Ts) / 2; + + var middleOfTheInterval = startTs + (endTs - startTs) / 2; + + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899728000L, new LongDataEntry("t", 1L))); // Wednesday, January 10 15:15:28 GMT + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899729000L, new LongDataEntry("t", 3L))); // Wednesday, January 10 15:15:29 GMT + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek1Ts + 1000, new LongDataEntry("t", 7L))); // Monday, January 15, 2024 0:00:01 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek2Ts + 1000, new LongDataEntry("t", 11L))); // Monday, January 22, 2024 0:00:01 GMT+02:00 + + ObjectNode result = doGetAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + + "/values/timeseries?keys=t&startTs={startTs}&endTs={endTs}&agg={agg}&intervalType={intervalType}&timeZone={timeZone}", + ObjectNode.class, startTs, endTs, "SUM", "WEEK_ISO", "Europe/Kyiv"); + Assert.assertNotNull(result); + Assert.assertNotNull(result.get("t")); + Assert.assertEquals(3, result.get("t").size()); + + var firstIntervalResult = result.get("t").get(0); + Assert.assertEquals(4L, firstIntervalResult.get("value").asLong()); + Assert.assertEquals(firstIntervalTs, firstIntervalResult.get("ts").asLong()); + + var secondIntervalResult = result.get("t").get(1); + Assert.assertEquals(7L, secondIntervalResult.get("value").asLong()); + Assert.assertEquals(secondIntervalTs, secondIntervalResult.get("ts").asLong()); + + var thirdIntervalResult = result.get("t").get(2); + Assert.assertEquals(11L, thirdIntervalResult.get("value").asLong()); + Assert.assertEquals(thirdIntervalTs, thirdIntervalResult.get("ts").asLong()); + + result = doGetAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + + "/values/timeseries?keys=t&startTs={startTs}&endTs={endTs}&agg={agg}&intervalType={intervalType}&timeZone={timeZone}", + ObjectNode.class, startTs, endTs, "SUM", "MONTH", "Europe/Kyiv"); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.get("t")); + Assert.assertEquals(1, result.get("t").size()); + + var monthResult = result.get("t").get(0); + Assert.assertEquals(22L, monthResult.get("value").asLong()); + Assert.assertEquals(middleOfTheInterval, monthResult.get("ts").asLong()); + } + @Test public void testDeleteAllTelemetryWithLatest() throws Exception { loginTenantAdmin(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java new file mode 100644 index 0000000000..9d7470b676 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java @@ -0,0 +1,92 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.kv; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.thingsboard.server.common.data.StringUtils; + +import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.zone.ZoneRulesException; +import java.util.concurrent.TimeUnit; + +@AllArgsConstructor +@EqualsAndHashCode +@Slf4j +public class AggregationParams { + @Getter + private final Aggregation aggregation; + @Getter + private final IntervalType intervalType; + @Getter + private final ZoneId tzId; + + private final long interval; + + public static AggregationParams none() { + return new AggregationParams(Aggregation.NONE, null, null, 0L); + } + + public static AggregationParams milliseconds(Aggregation aggregationType, long aggregationIntervalMs) { + return new AggregationParams(aggregationType, IntervalType.MILLISECONDS, null, aggregationIntervalMs); + } + + public static AggregationParams calendar(Aggregation aggregationType, IntervalType intervalType, String tzIdStr) { + return calendar(aggregationType, intervalType, getZoneId(tzIdStr)); + } + + public static AggregationParams calendar(Aggregation aggregationType, IntervalType intervalType, ZoneId tzId) { + return new AggregationParams(aggregationType, intervalType, tzId, 0L); + } + + public static AggregationParams of(Aggregation aggregation, IntervalType intervalType, ZoneId tzId, long interval) { + return new AggregationParams(aggregation, intervalType, tzId, interval); + } + + public long getInterval() { + if (intervalType == null) { + return 0L; + } else { + switch (intervalType) { + case WEEK: + case WEEK_ISO: + return TimeUnit.DAYS.toMillis(7); + case MONTH: + return TimeUnit.DAYS.toMillis(30); + case QUARTER: + return TimeUnit.DAYS.toMillis(90); + default: + return interval; + } + } + } + + private static ZoneId getZoneId(String tzIdStr) { + if (StringUtils.isEmpty(tzIdStr)) { + return ZoneId.systemDefault(); + } + try { + return ZoneId.of(tzIdStr); + } catch (DateTimeException e) { + log.warn("[{}] Failed to convert the time zone. Fallback to default.", tzIdStr); + return ZoneId.systemDefault(); + } + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java index 54b3a15bd2..09d52e46a1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java @@ -18,41 +18,47 @@ package org.thingsboard.server.common.data.kv; import lombok.Data; import lombok.EqualsAndHashCode; +import java.time.ZoneId; + @Data @EqualsAndHashCode(callSuper = true) public class BaseReadTsKvQuery extends BaseTsKvQuery implements ReadTsKvQuery { - private final long interval; + private final AggregationParams aggParameters; private final int limit; - private final Aggregation aggregation; private final String order; public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation) { this(key, startTs, endTs, interval, limit, aggregation, "DESC"); } - public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation, String order) { + public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation, String descOrder) { + this(key, startTs, endTs, AggregationParams.of(aggregation, IntervalType.MILLISECONDS, ZoneId.systemDefault(), interval), limit, descOrder); + } + + public BaseReadTsKvQuery(String key, long startTs, long endTs, AggregationParams parameters, int limit) { + this(key, startTs, endTs, parameters, limit, "DESC"); + } + + public BaseReadTsKvQuery(String key, long startTs, long endTs, AggregationParams parameters, int limit, String order) { super(key, startTs, endTs); - this.interval = interval; + this.aggParameters = parameters; this.limit = limit; - this.aggregation = aggregation; this.order = order; } public BaseReadTsKvQuery(String key, long startTs, long endTs) { - this(key, startTs, endTs, endTs - startTs, 1, Aggregation.AVG, "DESC"); + this(key, startTs, endTs, AggregationParams.milliseconds(Aggregation.AVG, endTs - startTs), 1, "DESC"); } public BaseReadTsKvQuery(String key, long startTs, long endTs, int limit, String order) { - this(key, startTs, endTs, endTs - startTs, limit, Aggregation.NONE, order); + this(key, startTs, endTs, AggregationParams.none(), limit, order); } public BaseReadTsKvQuery(ReadTsKvQuery query, long startTs, long endTs) { super(query.getId(), query.getKey(), startTs, endTs); - this.interval = query.getInterval(); + this.aggParameters = query.getAggParameters(); this.limit = query.getLimit(); - this.aggregation = query.getAggregation(); this.order = query.getOrder(); } - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java index e5ebb7f1a1..121b5993e0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java @@ -17,6 +17,6 @@ package org.thingsboard.server.common.data.kv; public enum IntervalType { - MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER + MILLISECONDS, WEEK/*Sunday-Saturday*/, WEEK_ISO/*Monday-Sunday*/, MONTH, QUARTER } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java index e979ec665a..776179967f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java @@ -17,11 +17,17 @@ package org.thingsboard.server.common.data.kv; public interface ReadTsKvQuery extends TsKvQuery { - long getInterval(); + AggregationParams getAggParameters(); - int getLimit(); + default long getInterval(){ + return getAggParameters().getInterval(); + } + + default Aggregation getAggregation() { + return getAggParameters().getAggregation(); + } - Aggregation getAggregation(); + int getLimit(); String getOrder(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java index 96e87e954e..6c22935b61 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -37,9 +38,18 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.sqlts.ts.TsKvRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; +import org.thingsboard.server.dao.util.TimeUtils; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.IsoFields; +import java.time.temporal.TemporalUnit; +import java.time.temporal.WeekFields; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -112,16 +122,23 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { - if (query.getAggregation() == Aggregation.NONE) { + var aggParams = query.getAggParameters(); + if (Aggregation.NONE.equals(aggParams.getAggregation())) { return Futures.immediateFuture(findAllAsyncWithLimit(entityId, query)); } else { List>> futures = new ArrayList<>(); + var intervalType = aggParams.getIntervalType(); long startPeriod = query.getStartTs(); long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); - long step = query.getInterval(); while (startPeriod < endPeriod) { long startTs = startPeriod; - long endTs = Math.min(startPeriod + step, endPeriod); + long endTs; + if (IntervalType.MILLISECONDS.equals(intervalType)) { + endTs = startPeriod + aggParams.getInterval(); + } else { + endTs = TimeUtils.calculateIntervalEnd(startTs, intervalType, aggParams.getTzId()); + } + endTs = Math.min(endTs, endPeriod); long ts = startTs + (endTs - startTs) / 2; ListenableFuture> aggregateTsKvEntry = findAndAggregateAsync(entityId, query.getKey(), startTs, endTs, ts, query.getAggregation()); futures.add(aggregateTsKvEntry); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java index 6f1d569730..bb0ce06026 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -35,11 +37,13 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; +import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; +import org.thingsboard.server.dao.util.TimeUtils; import org.thingsboard.server.dao.util.TimescaleDBTsDao; import javax.annotation.PostConstruct; @@ -143,14 +147,28 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { + var aggParams = query.getAggParameters(); + var intervalType = aggParams.getIntervalType(); if (query.getAggregation() == Aggregation.NONE) { return Futures.immediateFuture(findAllAsyncWithLimit(entityId, query)); - } else { + } else if (IntervalType.MILLISECONDS.equals(intervalType)) { long startTs = query.getStartTs(); long endTs = Math.max(query.getStartTs() + 1, query.getEndTs()); long timeBucket = query.getInterval(); List> data = findAllAndAggregateAsync(entityId, query.getKey(), startTs, endTs, timeBucket, query.getAggregation()); return getReadTsKvQueryResultFuture(query, Futures.immediateFuture(data)); + } else { + //TODO: @dshvaika improve according to native capabilities of Timescale. + long startPeriod = query.getStartTs(); + long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); + List timescaleTsKvEntities = new ArrayList<>(); + while (startPeriod < endPeriod) { + long startTs = startPeriod; + long endTs = Math.min(TimeUtils.calculateIntervalEnd(startTs, intervalType, aggParams.getTzId()), endPeriod); + timescaleTsKvEntities.addAll(switchAggregation(query.getKey(), startTs, endTs, endTs - startTs, query.getAggregation(), entityId.getId())); + startPeriod = endTs; + } + return getReadTsKvQueryResultFuture(query, Futures.immediateFuture(toResultList(entityId, query.getKey(), timescaleTsKvEntities))); } } @@ -187,6 +205,10 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements timescaleTsKvEntities.addAll(switchAggregation(key, startTs + interval, endTs, remainingPart, aggregation, entityId.getId())); } + return toResultList(entityId, key, timescaleTsKvEntities); + } + + private static List> toResultList(EntityId entityId, String key, List timescaleTsKvEntities) { if (!CollectionUtils.isEmpty(timescaleTsKvEntities)) { List> result = new ArrayList<>(); timescaleTsKvEntities.forEach(entity -> { diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 71541962ec..31e29434e8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.DataType; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; @@ -51,6 +52,7 @@ import org.thingsboard.server.dao.nosql.TbResultSet; import org.thingsboard.server.dao.nosql.TbResultSetFuture; import org.thingsboard.server.dao.sqlts.AggregationTimeseriesDao; import org.thingsboard.server.dao.util.NoSqlTsDao; +import org.thingsboard.server.dao.util.TimeUtils; import javax.annotation.Nullable; import javax.annotation.PostConstruct; @@ -227,18 +229,24 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { - if (query.getAggregation() == Aggregation.NONE) { + var aggParams = query.getAggParameters(); + if (Aggregation.NONE.equals(aggParams.getAggregation())) { return findAllAsyncWithLimit(tenantId, entityId, query); } else { long startPeriod = query.getStartTs(); long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); - long step = Math.max(query.getInterval(), MIN_AGGREGATION_STEP_MS); List>> futures = new ArrayList<>(); + var intervalType = aggParams.getIntervalType(); while (startPeriod < endPeriod) { long startTs = startPeriod; - long endTs = Math.min(startPeriod + step, endPeriod); - long ts = endTs - startTs; - ReadTsKvQuery subQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, ts, 1, query.getAggregation(), query.getOrder()); + long endTs; + if (IntervalType.MILLISECONDS.equals(intervalType)) { + endTs = startPeriod + Math.max(query.getInterval(), MIN_AGGREGATION_STEP_MS); + } else { + endTs = TimeUtils.calculateIntervalEnd(startTs, aggParams.getIntervalType(), aggParams.getTzId()); + } + endTs = Math.min(endTs, endPeriod); + ReadTsKvQuery subQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1, query.getAggregation(), query.getOrder()); futures.add(findAndAggregateAsync(tenantId, entityId, subQuery, toPartitionTs(startTs), toPartitionTs(endTs))); startPeriod = endTs; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java index 9c302be53d..8ab9a2c4da 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java @@ -33,7 +33,7 @@ public class TsKvQueryCursor extends QueryCursor { @Getter private final List data; @Getter - private String orderBy; + private final String orderBy; private int partitionIndex; private int currentLimit; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java b/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java new file mode 100644 index 0000000000..3a768673b8 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.util; + +import org.thingsboard.server.common.data.kv.IntervalType; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.IsoFields; +import java.time.temporal.WeekFields; + +public class TimeUtils { + + public static long calculateIntervalEnd(long startTs, IntervalType intervalType, ZoneId tzId) { + var startTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(startTs), tzId); + switch (intervalType) { + case WEEK: + return startTime.truncatedTo(ChronoUnit.DAYS).with(WeekFields.SUNDAY_START.dayOfWeek(), 1).plusDays(7).toInstant().toEpochMilli(); + case WEEK_ISO: + return startTime.truncatedTo(ChronoUnit.DAYS).with(WeekFields.ISO.dayOfWeek(), 1).plusDays(7).toInstant().toEpochMilli(); + case MONTH: + return startTime.truncatedTo(ChronoUnit.DAYS).withDayOfMonth(1).plusMonths(1).toInstant().toEpochMilli(); + case QUARTER: + return startTime.truncatedTo(ChronoUnit.DAYS).with(IsoFields.DAY_OF_QUARTER, 1).plusMonths(3).toInstant().toEpochMilli(); + default: + throw new RuntimeException("Not supported!"); + } + } + +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java b/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java new file mode 100644 index 0000000000..a3df974236 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java @@ -0,0 +1,60 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.util; + +import org.junit.jupiter.api.Test; +import org.thingsboard.server.common.data.kv.IntervalType; + +import java.time.ZoneId; + +import static org.assertj.core.api.Assertions.assertThat; + +class TimeUtilsTest { + + @Test + void testWeekEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705183200000L); // Sunday, January 14, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705269600000L); // Monday, January 15, 2024 0:00:00 GMT+02:00 + + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1705186800000L); // Sunday, January 14, 2024 0:00:00 GMT+01:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1705273200000L); // Monday, January 15, 2024 0:00:00 GMT+01:00 + + ts = 1704621600000L; // Sunday, January 7, 2024 12:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705183200000L); // Sunday, January 14, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Kyiv"))).isEqualTo(1704664800000L); // Monday, January 8, 2024 0:00:00 GMT+02:00 + } + + + @Test + void testMonthEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.MONTH, ZoneId.of("Europe/Kyiv"))).isEqualTo(1706738400000L); // Thursday, February 1, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.MONTH, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1706742000000L); // Monday, January 15, 2024 0:00:00 GMT+02:00 + } + + @Test + void testQuarterEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Kyiv"))).isEqualTo(1711918800000L); // Monday, April 1, 2024 0:00:00 GMT+03:00 DST + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1711922400000L); // Monday, April 1, 2024 1:00:00 GMT+03:00 DST + + ts = 1711929600000L; // Monday, April 1, 2024 3:00:00 GMT+03:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Kyiv"))).isEqualTo(1719781200000L); // Monday, July 1, 2024 0:00:00 GMT+03:00 DST + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("America/New_York"))).isEqualTo(1711944000000L); // Monday, April 1, 2024 7:00:00 GMT+03:00 DST + } + +} From ee08f33d98faa42045366229af338ac03684cd4d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 11 Jan 2024 12:51:52 +0200 Subject: [PATCH 53/91] TimeZone name links --- .../server/common/data/kv/AggregationParams.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java index 9d7470b676..6c85cfb3c0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java @@ -19,18 +19,18 @@ import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; import org.thingsboard.server.common.data.StringUtils; import java.time.DateTimeException; import java.time.ZoneId; -import java.time.zone.ZoneRulesException; +import java.util.Map; import java.util.concurrent.TimeUnit; @AllArgsConstructor @EqualsAndHashCode @Slf4j public class AggregationParams { + private static final Map TZ_LINKS = Map.of("EST", "America/New_York", "GMT+0", "GMT", "GMT-0", "GMT", "HST", "US/Hawaii", "MST", "America/Phoenix", "ROC", "Asia/Taipei"); @Getter private final Aggregation aggregation; @Getter @@ -83,7 +83,7 @@ public class AggregationParams { return ZoneId.systemDefault(); } try { - return ZoneId.of(tzIdStr); + return ZoneId.of(tzIdStr, TZ_LINKS); } catch (DateTimeException e) { log.warn("[{}] Failed to convert the time zone. Fallback to default.", tzIdStr); return ZoneId.systemDefault(); From 1498741abf840a00fff118fb0c70b6768662e238 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 11 Jan 2024 15:12:50 +0200 Subject: [PATCH 54/91] Hidded "/widgetType?fqn" from swagger doc as this api was created for UI needs only and require specific prefixed added to fqn --- .../org/thingsboard/server/controller/WidgetTypeController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index c623ac5eb2..915c697e59 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -369,7 +369,7 @@ public class WidgetTypeController extends AutoCommitController { } @ApiOperation(value = "Get Widget Type (getWidgetType)", - notes = "Get the Widget Type by FQN. " + WIDGET_TYPE_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER) + notes = "Get the Widget Type by FQN. " + WIDGET_TYPE_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER, hidden = true) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/widgetType", params = {"fqn"}, method = RequestMethod.GET) @ResponseBody From 5c35a858bb7c63e5eb32e73d1d7991ee9d3b465c Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Nov 2023 15:39:02 +0200 Subject: [PATCH 55/91] [WIP] Initial implementation for "first and last" strategy in transport service --- .../service/DefaultTransportService.java | 239 +++++++++++++++++- 1 file changed, 230 insertions(+), 9 deletions(-) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 37b77a5268..0ece919d7b 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -52,7 +52,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; -import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -96,9 +95,9 @@ import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.TbQueueRequestTemplate; import org.thingsboard.server.queue.common.AsyncCallbackTemplate; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; +import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.provider.TbTransportQueueFactory; import org.thingsboard.server.queue.scheduler.SchedulerComponent; @@ -113,6 +112,7 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Random; import java.util.Set; @@ -125,6 +125,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; /** @@ -139,7 +141,7 @@ public class DefaultTransportService implements TransportService { public static final String SESSION_EXPIRED_MESSAGE = "Session has expired due to last activity time!"; public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_OPEN = getSessionEventMsg(TransportProtos.SessionEvent.OPEN); public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_CLOSED = getSessionEventMsg(TransportProtos.SessionEvent.CLOSED); - public static final TransportProtos.SessionCloseNotificationProto SESSION_CLOSE_NOTIFICATION_PROTO = TransportProtos.SessionCloseNotificationProto.newBuilder() + public static final TransportProtos.SessionCloseNotificationProto SESSION_EXPIRED_NOTIFICATION_PROTO = TransportProtos.SessionCloseNotificationProto.newBuilder() .setMessage(SESSION_EXPIRED_MESSAGE).build(); public static final TransportProtos.SubscribeToAttributeUpdatesMsg SUBSCRIBE_TO_ATTRIBUTE_UPDATES_ASYNC_MSG = TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder() .setSessionType(TransportProtos.SessionType.ASYNC).build(); @@ -202,7 +204,7 @@ public class DefaultTransportService implements TransportService { private ExecutorService mainConsumerExecutor; public final ConcurrentMap sessions = new ConcurrentHashMap<>(); - private final ConcurrentMap sessionsActivity = new ConcurrentHashMap<>(); + private final ActivityStateManager activityStateManager; private final Map toServerRpcPendingMap = new ConcurrentHashMap<>(); private volatile boolean stopped = false; @@ -234,6 +236,7 @@ public class DefaultTransportService implements TransportService { this.eventPublisher = eventPublisher; this.notificationRuleProcessor = notificationRuleProcessor; this.entityLimitsCache = entityLimitsCache; + activityStateManager = new ActivityStateManager(); } @PostConstruct @@ -242,7 +245,7 @@ public class DefaultTransportService implements TransportService { this.tbCoreProducerStats = statsFactory.createMessagesStats(StatsType.CORE.getName() + ".producer"); this.transportApiStats = statsFactory.createMessagesStats(StatsType.TRANSPORT.getName() + ".producer"); this.transportCallbackExecutor = ThingsBoardExecutors.newWorkStealingPool(20, getClass()); - this.scheduler.scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS); + activityStateManager.init(); this.scheduler.scheduleAtFixedRate(this::invalidateRateLimits, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS); transportApiRequestTemplate = queueProvider.createTransportApiRequestTemplate(); transportApiRequestTemplate.setMessagesStats(transportApiStats); @@ -785,11 +788,10 @@ public class DefaultTransportService implements TransportService { } private void reportActivityInternal(TransportProtos.SessionInfoProto sessionInfo) { - UUID sessionId = toSessionId(sessionInfo); - SessionActivityData sessionMetaData = sessionsActivity.computeIfAbsent(sessionId, id -> new SessionActivityData(sessionInfo)); - sessionMetaData.updateLastActivityTime(); + activityStateManager.recordActivity(sessionInfo); } + /* private void checkInactivityAndReportActivity() { long expTime = System.currentTimeMillis() - sessionInactivityTimeout; Set sessionsToRemove = new HashSet<>(); @@ -819,7 +821,7 @@ public class DefaultTransportService implements TransportService { sessions.remove(uuid); sessionsToRemove.add(uuid); process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMD.getListener().onRemoteSessionCloseCommand(uuid, SESSION_CLOSE_NOTIFICATION_PROTO); + sessionMD.getListener().onRemoteSessionCloseCommand(uuid, SESSION_EXPIRED_NOTIFICATION_PROTO); } } else { if (lastActivityTime > sessionAD.getLastReportedActivityTime()) { @@ -844,6 +846,225 @@ public class DefaultTransportService implements TransportService { // Removes all closed or short-lived sessions. sessionsToRemove.forEach(sessionsActivity::remove); } + */ + + + // TODO: how can I get access to sessions if activity management logic is implemented as a separate service (class) + + // TODO: why sessions and session activities are managed in a separate maps? maybe it is better to manage in a single map + // (eg. we can check if we had sent last activity event when deregistering session) + + // TODO: currently if activity event is received between precise session expiration time and reportLastEventAndStartNewPeriod() call + // we will "resurrect" this session meaning that + + // TODO: I optimistically set alreadyBeenReported status to true to avoid reporting several activity events if they arrive in rapid succession + // this can cause lost activity updates if first event that got reported failed to enqueue in Kafka and next reporting period is already started + // (maybe having a queue of "first" events will help with this, queue will be cleared once event was successfully queued or later time was reported by event in next period) + // setting alreadyBeenReported status in callbacks ensures that events are reported but can cause several "first" events to be reported + + // TODO: currently activity states are reported on per session basis, but one physical device can have several sessions + // maybe it is a good idea to manage activity state on per device basis + + private final class ActivityStateManager { + + private final ConcurrentMap sessionActivityStates = new ConcurrentHashMap<>(); + + @lombok.Value + // TODO: I chose to have immutable objects for concurrency considerations, + // but it can possibly create a performance issue with creating large amounts of new objects + // maybe mutable objects with volatile fields is better + private class ActivityState { + + TransportProtos.SessionInfoProto sessionInfo; + long lastActivityTime; + boolean alreadyBeenReported; + long lastReportedTime; + + ActivityState withSessionInfo(TransportProtos.SessionInfoProto sessionInfo) { + return new ActivityState(sessionInfo, getLastActivityTime(), isAlreadyBeenReported(), getLastReportedTime()); + } + + ActivityState withLastActivityTime(long lastActivityTime) { + return new ActivityState(getSessionInfo(), lastActivityTime, isAlreadyBeenReported(), getLastReportedTime()); + } + + ActivityState withReportedStatus(boolean hasAlreadyBeenReported) { + return new ActivityState(getSessionInfo(), getLastActivityTime(), hasAlreadyBeenReported, getLastReportedTime()); + } + + ActivityState withLastReportedTime(long lastReportedTime) { + return new ActivityState(getSessionInfo(), getLastActivityTime(), isAlreadyBeenReported(), lastReportedTime); + } + + } + + // TODO: maybe CAS-based synchronization policy will perform better? + // locks can put threads to sleep which introduces scheduling overhead (it is up to JVM to device if a thread will go to sleep or will be spin-waiting) + // activity management tasks are short lived so scheduling overhead may be significant, so CAS can be better since it does not put threads to sleep (always spin-waiting) + // Compare ReadWriteLock to CAS + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final AtomicInteger currentPeriodId = new AtomicInteger(); + + private void init() { + scheduler.scheduleAtFixedRate(this::reportLastEventAndStartNewPeriod, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS); + } + + private void recordActivity(TransportProtos.SessionInfoProto sessionInfo) { + long newLastActivityTime = System.currentTimeMillis(); + var sessionId = toSessionId(sessionInfo); + lock.readLock().lock(); + try { + sessionActivityStates.compute(sessionId, (id, currentActivityState) -> { + log.info("------------------------------------------------------------------------------------------------------------------------"); + log.info("Record activity: entered compute! Session id: [{}]", sessionId); + var activityState = Objects.requireNonNullElseGet(currentActivityState, () -> new ActivityState(sessionInfo, newLastActivityTime, false, 0L)); + if (activityState.isAlreadyBeenReported()) { // update the last activity time + log.info("------------------------------------------------------------------------------------------------------------------------"); + return activityState.withLastActivityTime(newLastActivityTime); + } + int capturedPeriodId = currentPeriodId.get(); + reportActivityStateToCore(activityState.getSessionInfo(), newLastActivityTime, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + // Success, the optimistic assumption was correct: update last reported time if it is newer + log.info("Record activity: successful callback received! Session id: [{}]", sessionId); + lock.readLock().lock(); + try { + updateLastReportedTime(sessionId, newLastActivityTime); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public void onError(Throwable e) { + // Error: revert alreadyBeenReported to false + log.info("Record activity: failed callback received! Session id: [{}]", sessionId); + log.debug("[{}] Failed to report last activity time!", sessionId, e); + lock.readLock().lock(); + try { + sessionActivityStates.computeIfPresent(sessionId, (__, activityState) -> { + boolean updatedReportedStatus = activityState.isAlreadyBeenReported(); + if (capturedPeriodId == currentPeriodId.get() && activityState.getLastReportedTime() < newLastActivityTime) { + updatedReportedStatus = false; + } + return activityState.withReportedStatus(updatedReportedStatus); + }); + } finally { + lock.readLock().unlock(); + } + } + }); + log.info("------------------------------------------------------------------------------------------------------------------------"); + // Optimistically set hasAlreadyBeenReported to true + return new ActivityState(sessionInfo, newLastActivityTime, true, activityState.getLastReportedTime()); + }); + } finally { + lock.readLock().unlock(); + } + } + + private void reportLastEventAndStartNewPeriod() { + lock.writeLock().lock(); + // log.info("------------------------------------------------------------------------------------------------------------------------"); + // log.info("Period change start! Current period id: [{}], activity states: {}", currentPeriodId.get(), sessionActivityStates.keySet()); + try { + Set activityStatesToRemove = new HashSet<>(); + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + for (Map.Entry entry : sessionActivityStates.entrySet()) { + var sessionId = entry.getKey(); + var activityState = entry.getValue(); + + long lastActivityTime = activityState.getLastActivityTime(); + + // TODO: why this update is needed? if gateway session is present but this session is already gone we will not check if gateway's last activity time is greater than this one + SessionMetaData sessionMetaData = sessions.get(sessionId); + if (sessionMetaData != null) { + activityState = activityState.withSessionInfo(sessionMetaData.getSessionInfo()); + entry.setValue(activityState); + } else { + // log.info("Removing activity state! Session id: [{}]", sessionId); + activityStatesToRemove.add(sessionId); + } + // TODO: ask about this part end + + TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfo(); + + if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSessionMetaData = sessions.get(gwSessionId); + if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { + ActivityState gwActivityState = sessionActivityStates.get(gwSessionId); + lastActivityTime = Math.max(gwActivityState.getLastActivityTime(), lastActivityTime); + } + } + + if (sessionMetaData != null && lastActivityTime < expirationTime) { + // log.info("Session has expired! Session id: [{}]", sessionId); + if (log.isDebugEnabled()) { + log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); + } + sessions.remove(sessionId); + activityStatesToRemove.add(sessionId); + process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } else if (activityState.getLastReportedTime() < lastActivityTime) { + long finalLastActivityTime = lastActivityTime; + reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + lock.readLock().lock(); + try { + updateLastReportedTime(sessionId, finalLastActivityTime); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public void onError(Throwable e) { + log.debug("[{}] Failed to report last activity time!", sessionId, e); + } + }); + } + entry.setValue(activityState.withReportedStatus(false)); + } + activityStatesToRemove.forEach(sessionActivityStates::remove); + } finally { + currentPeriodId.incrementAndGet(); + // log.info("Period change end! Current period id: [{}], activity states {}", currentPeriodId.get(), sessionActivityStates.keySet()); + // log.info("------------------------------------------------------------------------------------------------------------------------"); + lock.writeLock().unlock(); + } + } + + private void reportActivityStateToCore(TransportProtos.SessionInfoProto sessionInfo, long lastActivityTime, TransportServiceCallback msgAcknowledgedCallback) { + SessionMetaData sessionMetaData = sessions.get(toSessionId(sessionInfo)); + reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, msgAcknowledgedCallback); + } + + private void reportActivityStateToCore( + TransportProtos.SessionInfoProto sessionInfo, SessionMetaData sessionMetaData, long lastActivityTime, TransportServiceCallback msgAcknowledgedCallback + ) { + log.info("Reporting activity state to core! Session id: [{}], last activity time: [{}], current period id: [{}]", + toSessionId(sessionInfo), lastActivityTime, currentPeriodId.get()); + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) + .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) + .setLastActivityTime(lastActivityTime) + .build(); + process(sessionInfo, subscriptionInfo, msgAcknowledgedCallback); + } + + private void updateLastReportedTime(UUID sessionId, long lastActivityTime) { + sessionActivityStates.computeIfPresent(sessionId, (__, currentActivityState) -> { + long updatedLastReportedTime = Math.max(currentActivityState.getLastReportedTime(), lastActivityTime); + return currentActivityState.withLastReportedTime(updatedLastReportedTime); + }); + } + + } + @Override public void lifecycleEvent(TenantId tenantId, DeviceId deviceId, ComponentLifecycleEvent eventType, boolean success, Throwable error) { From e2023722ce23ee9860373454e98af37fbaa4350a Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Nov 2023 15:39:51 +0200 Subject: [PATCH 56/91] [WIP] Remove session activity data class --- .../service/SessionActivityData.java | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/SessionActivityData.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/SessionActivityData.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/SessionActivityData.java deleted file mode 100644 index 3e0be50ce6..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/SessionActivityData.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright © 2016-2024 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.common.transport.service; - -import lombok.Data; -import org.thingsboard.server.gen.transport.TransportProtos; - -/** - * Created by ashvayka on 15.10.18. - */ -@Data -public class SessionActivityData { - - private volatile TransportProtos.SessionInfoProto sessionInfo; - private volatile long lastActivityTime; - private volatile long lastReportedActivityTime; - - SessionActivityData(TransportProtos.SessionInfoProto sessionInfo) { - this.sessionInfo = sessionInfo; - } - - void updateLastActivityTime() { - this.lastActivityTime = System.currentTimeMillis(); - } - -} From 114d2c3c1cee3128329ca1616a76756fde056cba Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Wed, 6 Dec 2023 19:08:28 +0200 Subject: [PATCH 57/91] [WIP] Initial implementation --- .../transport/activity/ActivityState.java | 41 ++ .../activity/ActivityStateManager.java | 43 ++ .../activity/ActivityStateManagerImpl.java | 240 +++++++++++ .../activity/ActivityStateReportCallback.java | 41 ++ .../activity/AsyncActivityStateReporter.java | 41 ++ .../service/DefaultTransportService.java | 395 +++++------------- .../service/TransportActivityState.java | 44 ++ 7 files changed, 562 insertions(+), 283 deletions(-) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java new file mode 100644 index 0000000000..09285f9192 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java @@ -0,0 +1,41 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +import lombok.Data; + +@Data +public class ActivityState { + + private volatile long lastRecordedTime; + private volatile long lastReportedTime; + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java new file mode 100644 index 0000000000..db24c2388d --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java @@ -0,0 +1,43 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +import java.util.function.Supplier; + +public interface ActivityStateManager { + + void init(); + + void recordActivity(Key key, Supplier newActivityStateSupplier); + + void destroy(); + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java new file mode 100644 index 0000000000..7d87b02f19 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java @@ -0,0 +1,240 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.data.util.Pair; +import org.thingsboard.common.util.ThingsBoardThreadFactory; + +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +@Slf4j +public final class ActivityStateManagerImpl implements ActivityStateManager { + + private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + + @Data + private static class ActivityStateWrapper { + + volatile ActivityState activityState; + volatile boolean alreadyBeenReported; + + } + + private ScheduledExecutorService scheduler; + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final AtomicInteger currentPeriodId = new AtomicInteger(); + private final AsyncActivityStateReporter reporter; + private final long reportingPeriodDurationMillis; + private final String name; + private boolean initialized; + + public ActivityStateManagerImpl(AsyncActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { + this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided reporter is null."); + this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation + this.name = name == null ? "activity-state-manager" : name; + } + + @Override + public synchronized void init() { + if (!initialized) { + initialized = true; + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); + scheduler.scheduleAtFixedRate(this::reportLastEventAndStartNewPeriod, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); + } + } + + @Override + public void recordActivity(Key activityKey, Supplier newActivityStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + int capturedPeriodId = currentPeriodId.get(); + lock.readLock().lock(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + try { + activityStates.compute(activityKey, (key, activityStateWrapper) -> { + if (activityStateWrapper == null) { + State activityState = newActivityStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + activityStateWrapper = new ActivityStateWrapper(); + activityStateWrapper.setActivityState(activityState); + activityStateWrapper.setAlreadyBeenReported(false); + } else { + activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); + } + if (activityStateWrapper.isAlreadyBeenReported()) { + return activityStateWrapper; + } + var activityState = activityStateWrapper.getActivityState(); + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.reportAsync(key, (State) activityState, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(Key key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(Key key, Throwable t) { + reportCompletedFuture.setException(t); + } + + @Override + public void onRemove(Key key) { + lock.readLock().lock(); + try { + activityStates.remove(key); + } finally { + lock.readLock().unlock(); + } + } + }); + } + activityStateWrapper.setAlreadyBeenReported(true); + return activityStateWrapper; + }); + } finally { + lock.readLock().unlock(); + } + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + lock.readLock().lock(); + try { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public void onFailure(@NonNull Throwable t) { // TODO: add failure logging + lock.readLock().lock(); + try { + rollbackReportedStatus(activityKey, capturedPeriodId, newLastRecordedTime); + } finally { + lock.readLock().unlock(); + } + } + }, MoreExecutors.directExecutor()); + } + + private void rollbackReportedStatus(Key key, int capturedPeriodId, long newLastRecordedTime) { + activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { + if (capturedPeriodId == currentPeriodId.get() && activityStateWrapper.getActivityState().getLastReportedTime() < newLastRecordedTime) { + activityStateWrapper.setAlreadyBeenReported(false); + } + return activityStateWrapper; + }); + } + + private void reportLastEventAndStartNewPeriod() { + lock.writeLock().lock(); + try { + Map activityStateMap = activityStates.entrySet().stream() + .peek(entry -> entry.getValue().setAlreadyBeenReported(false)) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> (State) entry.getValue().getActivityState())); + reporter.reportAsync(activityStateMap, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(Key key, long reportedTime) { + lock.readLock().lock(); + try { + updateLastReportedTime(key, reportedTime); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public void onFailure(Key key, Throwable t) { + log.debug("Failed to report activity state for key [{}]!", key, t); + } + + @Override + public void onRemove(Key key) { + lock.readLock().lock(); + try { + activityStates.remove(key); + } finally { + lock.readLock().unlock(); + } + } + }); + } finally { + currentPeriodId.incrementAndGet(); + lock.writeLock().unlock(); + } + } + + private void updateLastReportedTime(Key key, long newLastReportedTime) { + activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getActivityState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java new file mode 100644 index 0000000000..d9d897d4a1 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java @@ -0,0 +1,41 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +public interface ActivityStateReportCallback { + + void onSuccess(Key key, long reportedTime); + + void onFailure(Key key, Throwable t); + + void onRemove(Key key); + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java new file mode 100644 index 0000000000..ab9094c252 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java @@ -0,0 +1,41 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +import java.util.Map; + +public interface AsyncActivityStateReporter { + + void reportAsync(Key key, State activityState, ActivityStateReportCallback reportCallback); + + void reportAsync(Map activityStates, ActivityStateReportCallback reportCallback); + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 0ece919d7b..7769762b84 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -72,6 +72,10 @@ import org.thingsboard.server.common.transport.TransportResourceCache; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportTenantProfileCache; +import org.thingsboard.server.common.transport.activity.ActivityStateManager; +import org.thingsboard.server.common.transport.activity.ActivityStateManagerImpl; +import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; +import org.thingsboard.server.common.transport.activity.AsyncActivityStateReporter; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; @@ -108,14 +112,11 @@ import org.thingsboard.server.queue.util.TbTransportComponent; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Random; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -125,8 +126,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; /** @@ -204,7 +203,7 @@ public class DefaultTransportService implements TransportService { private ExecutorService mainConsumerExecutor; public final ConcurrentMap sessions = new ConcurrentHashMap<>(); - private final ActivityStateManager activityStateManager; + private ActivityStateManager activityStateManager; private final Map toServerRpcPendingMap = new ConcurrentHashMap<>(); private volatile boolean stopped = false; @@ -236,7 +235,6 @@ public class DefaultTransportService implements TransportService { this.eventPublisher = eventPublisher; this.notificationRuleProcessor = notificationRuleProcessor; this.entityLimitsCache = entityLimitsCache; - activityStateManager = new ActivityStateManager(); } @PostConstruct @@ -245,7 +243,6 @@ public class DefaultTransportService implements TransportService { this.tbCoreProducerStats = statsFactory.createMessagesStats(StatsType.CORE.getName() + ".producer"); this.transportApiStats = statsFactory.createMessagesStats(StatsType.TRANSPORT.getName() + ".producer"); this.transportCallbackExecutor = ThingsBoardExecutors.newWorkStealingPool(20, getClass()); - activityStateManager.init(); this.scheduler.scheduleAtFixedRate(this::invalidateRateLimits, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS); transportApiRequestTemplate = queueProvider.createTransportApiRequestTemplate(); transportApiRequestTemplate.setMessagesStats(transportApiStats); @@ -256,8 +253,108 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); + activityStateManager = new ActivityStateManagerImpl<>(reporter, sessionReportTimeout, "transport-activity-state-manager"); + activityStateManager.init(); } + // TODO: why sessions and session activities are managed in a separate maps? maybe it is better to manage in a single map + // (eg. we can check if we had sent last activity event when deregistering session) + + // TODO: currently if activity event is received between precise session expiration time and reportLastEventAndStartNewPeriod() call + // we will "resurrect" this session meaning that it will be considered alive but in fact it did not perform any activity for more than timeout allows + + // TODO: I optimistically set alreadyBeenReported status to true to avoid reporting several activity events if they arrive in rapid succession + // this can cause lost activity updates if first event that got reported failed to enqueue in Kafka and next reporting period is already started + // (maybe having a queue of "first" events will help with this, queue will be cleared once event was successfully queued or later time was reported by event in next period) + // setting alreadyBeenReported status in callbacks ensures that events are reported but can cause several "first" events to be reported + private final AsyncActivityStateReporter reporter = new AsyncActivityStateReporter<>() { + @Override + public void reportAsync(UUID sessionId, TransportActivityState activityState, ActivityStateReportCallback reportCallback) { + SessionMetaData sessionMetaData = sessions.get(sessionId); + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) + .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) + .setLastActivityTime(activityState.getLastRecordedTime()) + .build(); + process(activityState.getSessionInfoProto(), subscriptionInfo, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + reportCallback.onSuccess(sessionId, activityState.getLastRecordedTime()); + } + + @Override + public void onError(Throwable e) { + reportCallback.onFailure(sessionId, e); + } + }); + } + + @Override + public void reportAsync(Map activityStates, ActivityStateReportCallback reportCallback) { + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + for (Map.Entry entry : activityStates.entrySet()) { + var sessionId = entry.getKey(); + var activityState = entry.getValue(); + + long lastActivityTime = activityState.getLastRecordedTime(); + + SessionMetaData sessionMetaData = sessions.get(sessionId); + if (sessionMetaData != null) { + activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); + } else { + reportCallback.onRemove(sessionId); + } + + TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); + + if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSessionMetaData = sessions.get(gwSessionId); + if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { + TransportActivityState gwActivityState = activityStates.get(gwSessionId); + if (gwActivityState != null) { + lastActivityTime = Math.max(gwActivityState.getLastRecordedTime(), lastActivityTime); + } + } + } + + if (sessionMetaData != null && lastActivityTime < expirationTime) { + if (log.isDebugEnabled()) { + log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); + } + sessions.remove(sessionId); + reportCallback.onRemove(sessionId); + process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } else if (activityState.getLastReportedTime() < lastActivityTime) { + long finalLastActivityTime = lastActivityTime; + reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + reportCallback.onSuccess(sessionId, finalLastActivityTime); + } + + @Override + public void onError(Throwable e) { + reportCallback.onFailure(sessionId, e); + } + }); + } + } + } + + private void reportActivityStateToCore( + TransportProtos.SessionInfoProto sessionInfo, SessionMetaData sessionMetaData, long lastActivityTime, TransportServiceCallback callback + ) { + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) + .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) + .setLastActivityTime(lastActivityTime) + .build(); + process(sessionInfo, subscriptionInfo, callback); + } + }; + @AfterStartUp(order = AfterStartUp.TRANSPORT_SERVICE) public void start() { mainConsumerExecutor.execute(() -> { @@ -309,6 +406,9 @@ public class DefaultTransportService implements TransportService { if (transportApiRequestTemplate != null) { transportApiRequestTemplate.stop(); } + if (activityStateManager != null) { + activityStateManager.destroy(); + } } @Override @@ -788,283 +888,12 @@ public class DefaultTransportService implements TransportService { } private void reportActivityInternal(TransportProtos.SessionInfoProto sessionInfo) { - activityStateManager.recordActivity(sessionInfo); - } - - /* - private void checkInactivityAndReportActivity() { - long expTime = System.currentTimeMillis() - sessionInactivityTimeout; - Set sessionsToRemove = new HashSet<>(); - sessionsActivity.forEach((uuid, sessionAD) -> { - long lastActivityTime = sessionAD.getLastActivityTime(); - SessionMetaData sessionMD = sessions.get(uuid); - if (sessionMD != null) { - sessionAD.setSessionInfo(sessionMD.getSessionInfo()); - } else { - sessionsToRemove.add(uuid); - } - TransportProtos.SessionInfoProto sessionInfo = sessionAD.getSessionInfo(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwMetaData = sessions.get(gwSessionId); - SessionActivityData gwActivityData = sessionsActivity.get(gwSessionId); - if (gwMetaData != null && gwMetaData.isOverwriteActivityTime()) { - lastActivityTime = Math.max(gwActivityData.getLastActivityTime(), lastActivityTime); - } - } - if (lastActivityTime < expTime) { - if (sessionMD != null) { - if (log.isDebugEnabled()) { - log.debug("[{}] Session has expired due to last activity time: {}", toSessionId(sessionInfo), lastActivityTime); - } - sessions.remove(uuid); - sessionsToRemove.add(uuid); - process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMD.getListener().onRemoteSessionCloseCommand(uuid, SESSION_EXPIRED_NOTIFICATION_PROTO); - } - } else { - if (lastActivityTime > sessionAD.getLastReportedActivityTime()) { - final long lastActivityTimeFinal = lastActivityTime; - process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(sessionMD != null && sessionMD.isSubscribedToAttributes()) - .setRpcSubscription(sessionMD != null && sessionMD.isSubscribedToRPC()) - .setLastActivityTime(lastActivityTime).build(), new TransportServiceCallback() { - @Override - public void onSuccess(Void msg) { - sessionAD.setLastReportedActivityTime(lastActivityTimeFinal); - } - - @Override - public void onError(Throwable e) { - log.warn("[{}] Failed to report last activity time", uuid, e); - } - }); - } - } + activityStateManager.recordActivity(toSessionId(sessionInfo), () -> { + var activityState = new TransportActivityState(); + activityState.setSessionInfoProto(sessionInfo); + return activityState; }); - // Removes all closed or short-lived sessions. - sessionsToRemove.forEach(sessionsActivity::remove); } - */ - - - // TODO: how can I get access to sessions if activity management logic is implemented as a separate service (class) - - // TODO: why sessions and session activities are managed in a separate maps? maybe it is better to manage in a single map - // (eg. we can check if we had sent last activity event when deregistering session) - - // TODO: currently if activity event is received between precise session expiration time and reportLastEventAndStartNewPeriod() call - // we will "resurrect" this session meaning that - - // TODO: I optimistically set alreadyBeenReported status to true to avoid reporting several activity events if they arrive in rapid succession - // this can cause lost activity updates if first event that got reported failed to enqueue in Kafka and next reporting period is already started - // (maybe having a queue of "first" events will help with this, queue will be cleared once event was successfully queued or later time was reported by event in next period) - // setting alreadyBeenReported status in callbacks ensures that events are reported but can cause several "first" events to be reported - - // TODO: currently activity states are reported on per session basis, but one physical device can have several sessions - // maybe it is a good idea to manage activity state on per device basis - - private final class ActivityStateManager { - - private final ConcurrentMap sessionActivityStates = new ConcurrentHashMap<>(); - - @lombok.Value - // TODO: I chose to have immutable objects for concurrency considerations, - // but it can possibly create a performance issue with creating large amounts of new objects - // maybe mutable objects with volatile fields is better - private class ActivityState { - - TransportProtos.SessionInfoProto sessionInfo; - long lastActivityTime; - boolean alreadyBeenReported; - long lastReportedTime; - - ActivityState withSessionInfo(TransportProtos.SessionInfoProto sessionInfo) { - return new ActivityState(sessionInfo, getLastActivityTime(), isAlreadyBeenReported(), getLastReportedTime()); - } - - ActivityState withLastActivityTime(long lastActivityTime) { - return new ActivityState(getSessionInfo(), lastActivityTime, isAlreadyBeenReported(), getLastReportedTime()); - } - - ActivityState withReportedStatus(boolean hasAlreadyBeenReported) { - return new ActivityState(getSessionInfo(), getLastActivityTime(), hasAlreadyBeenReported, getLastReportedTime()); - } - - ActivityState withLastReportedTime(long lastReportedTime) { - return new ActivityState(getSessionInfo(), getLastActivityTime(), isAlreadyBeenReported(), lastReportedTime); - } - - } - - // TODO: maybe CAS-based synchronization policy will perform better? - // locks can put threads to sleep which introduces scheduling overhead (it is up to JVM to device if a thread will go to sleep or will be spin-waiting) - // activity management tasks are short lived so scheduling overhead may be significant, so CAS can be better since it does not put threads to sleep (always spin-waiting) - // Compare ReadWriteLock to CAS - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private final AtomicInteger currentPeriodId = new AtomicInteger(); - - private void init() { - scheduler.scheduleAtFixedRate(this::reportLastEventAndStartNewPeriod, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS); - } - - private void recordActivity(TransportProtos.SessionInfoProto sessionInfo) { - long newLastActivityTime = System.currentTimeMillis(); - var sessionId = toSessionId(sessionInfo); - lock.readLock().lock(); - try { - sessionActivityStates.compute(sessionId, (id, currentActivityState) -> { - log.info("------------------------------------------------------------------------------------------------------------------------"); - log.info("Record activity: entered compute! Session id: [{}]", sessionId); - var activityState = Objects.requireNonNullElseGet(currentActivityState, () -> new ActivityState(sessionInfo, newLastActivityTime, false, 0L)); - if (activityState.isAlreadyBeenReported()) { // update the last activity time - log.info("------------------------------------------------------------------------------------------------------------------------"); - return activityState.withLastActivityTime(newLastActivityTime); - } - int capturedPeriodId = currentPeriodId.get(); - reportActivityStateToCore(activityState.getSessionInfo(), newLastActivityTime, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - // Success, the optimistic assumption was correct: update last reported time if it is newer - log.info("Record activity: successful callback received! Session id: [{}]", sessionId); - lock.readLock().lock(); - try { - updateLastReportedTime(sessionId, newLastActivityTime); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public void onError(Throwable e) { - // Error: revert alreadyBeenReported to false - log.info("Record activity: failed callback received! Session id: [{}]", sessionId); - log.debug("[{}] Failed to report last activity time!", sessionId, e); - lock.readLock().lock(); - try { - sessionActivityStates.computeIfPresent(sessionId, (__, activityState) -> { - boolean updatedReportedStatus = activityState.isAlreadyBeenReported(); - if (capturedPeriodId == currentPeriodId.get() && activityState.getLastReportedTime() < newLastActivityTime) { - updatedReportedStatus = false; - } - return activityState.withReportedStatus(updatedReportedStatus); - }); - } finally { - lock.readLock().unlock(); - } - } - }); - log.info("------------------------------------------------------------------------------------------------------------------------"); - // Optimistically set hasAlreadyBeenReported to true - return new ActivityState(sessionInfo, newLastActivityTime, true, activityState.getLastReportedTime()); - }); - } finally { - lock.readLock().unlock(); - } - } - - private void reportLastEventAndStartNewPeriod() { - lock.writeLock().lock(); - // log.info("------------------------------------------------------------------------------------------------------------------------"); - // log.info("Period change start! Current period id: [{}], activity states: {}", currentPeriodId.get(), sessionActivityStates.keySet()); - try { - Set activityStatesToRemove = new HashSet<>(); - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; - for (Map.Entry entry : sessionActivityStates.entrySet()) { - var sessionId = entry.getKey(); - var activityState = entry.getValue(); - - long lastActivityTime = activityState.getLastActivityTime(); - - // TODO: why this update is needed? if gateway session is present but this session is already gone we will not check if gateway's last activity time is greater than this one - SessionMetaData sessionMetaData = sessions.get(sessionId); - if (sessionMetaData != null) { - activityState = activityState.withSessionInfo(sessionMetaData.getSessionInfo()); - entry.setValue(activityState); - } else { - // log.info("Removing activity state! Session id: [{}]", sessionId); - activityStatesToRemove.add(sessionId); - } - // TODO: ask about this part end - - TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfo(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSessionMetaData = sessions.get(gwSessionId); - if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { - ActivityState gwActivityState = sessionActivityStates.get(gwSessionId); - lastActivityTime = Math.max(gwActivityState.getLastActivityTime(), lastActivityTime); - } - } - - if (sessionMetaData != null && lastActivityTime < expirationTime) { - // log.info("Session has expired! Session id: [{}]", sessionId); - if (log.isDebugEnabled()) { - log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); - } - sessions.remove(sessionId); - activityStatesToRemove.add(sessionId); - process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } else if (activityState.getLastReportedTime() < lastActivityTime) { - long finalLastActivityTime = lastActivityTime; - reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - lock.readLock().lock(); - try { - updateLastReportedTime(sessionId, finalLastActivityTime); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public void onError(Throwable e) { - log.debug("[{}] Failed to report last activity time!", sessionId, e); - } - }); - } - entry.setValue(activityState.withReportedStatus(false)); - } - activityStatesToRemove.forEach(sessionActivityStates::remove); - } finally { - currentPeriodId.incrementAndGet(); - // log.info("Period change end! Current period id: [{}], activity states {}", currentPeriodId.get(), sessionActivityStates.keySet()); - // log.info("------------------------------------------------------------------------------------------------------------------------"); - lock.writeLock().unlock(); - } - } - - private void reportActivityStateToCore(TransportProtos.SessionInfoProto sessionInfo, long lastActivityTime, TransportServiceCallback msgAcknowledgedCallback) { - SessionMetaData sessionMetaData = sessions.get(toSessionId(sessionInfo)); - reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, msgAcknowledgedCallback); - } - - private void reportActivityStateToCore( - TransportProtos.SessionInfoProto sessionInfo, SessionMetaData sessionMetaData, long lastActivityTime, TransportServiceCallback msgAcknowledgedCallback - ) { - log.info("Reporting activity state to core! Session id: [{}], last activity time: [{}], current period id: [{}]", - toSessionId(sessionInfo), lastActivityTime, currentPeriodId.get()); - TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) - .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) - .setLastActivityTime(lastActivityTime) - .build(); - process(sessionInfo, subscriptionInfo, msgAcknowledgedCallback); - } - - private void updateLastReportedTime(UUID sessionId, long lastActivityTime) { - sessionActivityStates.computeIfPresent(sessionId, (__, currentActivityState) -> { - long updatedLastReportedTime = Math.max(currentActivityState.getLastReportedTime(), lastActivityTime); - return currentActivityState.withLastReportedTime(updatedLastReportedTime); - }); - } - - } - @Override public void lifecycleEvent(TenantId tenantId, DeviceId deviceId, ComponentLifecycleEvent eventType, boolean success, Throwable error) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java new file mode 100644 index 0000000000..470699ec5d --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java @@ -0,0 +1,44 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.service; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.gen.transport.TransportProtos; + +@Data +@EqualsAndHashCode(callSuper = true) +public class TransportActivityState extends ActivityState { + + private volatile TransportProtos.SessionInfoProto sessionInfoProto; + +} From 3461f6ae618a17529a8f0da39df16fac722716a1 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 7 Dec 2023 11:25:42 +0200 Subject: [PATCH 58/91] [WIP] Implemented three activity strategies for integration service --- ...irstAndLastIntegrationActivityManager.java | 196 ++++++++++++++ .../FirstOnlyIntegrationActivityManager.java | 192 ++++++++++++++ .../LastOnlyIntegrationActivityManager.java | 145 +++++++++++ ...StateManager.java => ActivityManager.java} | 4 +- .../activity/ActivityStateManagerImpl.java | 240 ------------------ .../activity/ActivityStateReportCallback.java | 2 - ...porter.java => ActivityStateReporter.java} | 6 +- .../service/DefaultTransportService.java | 46 ++-- .../LastOnlyTransportActivityManager.java | 131 ++++++++++ 9 files changed, 692 insertions(+), 270 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java create mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java create mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/{ActivityStateManager.java => ActivityManager.java} (92%) delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/{AsyncActivityStateReporter.java => ActivityStateReporter.java} (85%) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java new file mode 100644 index 0000000000..12be2101c4 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java @@ -0,0 +1,196 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.integration.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.data.util.Pair; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityStateReporter; + +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +@Slf4j +public class FirstAndLastIntegrationActivityManager implements ActivityManager { + + private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + + @Data + private static class ActivityStateWrapper { + + volatile ActivityState activityState; + volatile boolean alreadyBeenReported; + + } + + private ScheduledExecutorService scheduler; + private final ActivityStateReporter reporter; + private final long reportingPeriodDurationMillis; + private final String name; + private boolean initialized; + + public FirstAndLastIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { + this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); + this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation + this.name = name == null ? "activity-state-manager" : name; + } + + @Override + public synchronized void init() { + if (!initialized) { + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); + initialized = true; + } + } + + @Override + public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + activityStates.compute(activityKey, (key, activityStateWrapper) -> { + if (activityStateWrapper == null) { + ActivityState activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + activityStateWrapper = new ActivityStateWrapper(); + activityStateWrapper.setActivityState(activityState); + activityStateWrapper.setAlreadyBeenReported(false); + } else { + activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); + } + if (activityStateWrapper.isAlreadyBeenReported()) { + return activityStateWrapper; + } + var activityState = activityStateWrapper.getActivityState(); + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(key, activityState, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + reportCompletedFuture.setException(t); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(true); + return activityStateWrapper; + }); + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } + + @Override + public void onFailure(@NonNull Throwable t) { + // TODO: log + } + }, MoreExecutors.directExecutor()); + } + + private void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - reportingPeriodDurationMillis; + Set statesToRemove = new HashSet<>(); + Set> entries = activityStates.entrySet(); + for (Map.Entry entry : entries) { + var activityKey = entry.getKey(); + var activityStateWrapper = entry.getValue(); + var activityState = activityStateWrapper.getActivityState(); + if (activityState.getLastRecordedTime() < expirationTime) { + statesToRemove.add(activityKey); + } + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(activityKey, activityState, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + // TODO: log + } + }); + } + activityStateWrapper.setAlreadyBeenReported(false); + } + statesToRemove.forEach(activityStates::remove); + } + + private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { + activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getActivityState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java new file mode 100644 index 0000000000..7a0bccd48c --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -0,0 +1,192 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.integration.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.data.util.Pair; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityStateReporter; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +@Slf4j +public class FirstOnlyIntegrationActivityManager implements ActivityManager { + + private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + + @Data + private static class ActivityStateWrapper { + + volatile ActivityState activityState; + volatile boolean alreadyBeenReported; + + } + + private ScheduledExecutorService scheduler; + private final ActivityStateReporter reporter; + private final long reportingPeriodDurationMillis; + private final String name; + private boolean initialized; + + public FirstOnlyIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { + this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); + this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation + this.name = name == null ? "activity-state-manager" : name; + } + + @Override + public synchronized void init() { + if (!initialized) { + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); + initialized = true; + } + } + + @Override + public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + activityStates.compute(activityKey, (key, activityStateWrapper) -> { + if (activityStateWrapper == null) { + ActivityState activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + activityStateWrapper = new ActivityStateWrapper(); + activityStateWrapper.setActivityState(activityState); + activityStateWrapper.setAlreadyBeenReported(false); + } else { + activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); + } + if (activityStateWrapper.isAlreadyBeenReported()) { + return activityStateWrapper; + } + var activityState = activityStateWrapper.getActivityState(); + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(key, activityState, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + reportCompletedFuture.setException(t); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(true); + return activityStateWrapper; + }); + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } + + @Override + public void onFailure(@NonNull Throwable t) { + // TODO: log + } + }, MoreExecutors.directExecutor()); + } + + private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { + activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getActivityState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + + private void onReportingPeriodEnd() { + Map statesToRemoveAndReport = new HashMap<>(); + Set> entries = activityStates.entrySet(); + for (Map.Entry entry : entries) { + var activityKey = entry.getKey(); + var activityStateWrapper = entry.getValue(); + var activityState = activityStateWrapper.getActivityState(); + if (!activityStateWrapper.isAlreadyBeenReported() && activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + statesToRemoveAndReport.put(activityKey, activityState); + } + activityStateWrapper.setAlreadyBeenReported(false); + } + statesToRemoveAndReport.forEach((key, state) -> reporter.report(key, state, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + activityStates.remove(key); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + // TODO: log + } + })); + } + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java new file mode 100644 index 0000000000..0dd7aa6fc1 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -0,0 +1,145 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.integration.activity; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityStateReporter; + +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +@Slf4j +public class LastOnlyIntegrationActivityManager implements ActivityManager { + + private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + + private ScheduledExecutorService scheduler; + private final ActivityStateReporter reporter; + private final long reportingPeriodDurationMillis; + private final String name; + private boolean initialized; + + public LastOnlyIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { + this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); + this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation + this.name = name == null ? "activity-state-manager" : name; + } + + @Override + public synchronized void init() { + if (!initialized) { + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); + initialized = true; + } + } + + @Override + public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + activityStates.compute(activityKey, (key, activityState) -> { + if (activityState == null) { + activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + } else { + activityState.setLastRecordedTime(newLastRecordedTime); + } + return activityState; + }); + } + + private void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - reportingPeriodDurationMillis; + Set statesToRemove = new HashSet<>(); + Set> entries = activityStates.entrySet(); + for (Map.Entry entry : entries) { + var activityKey = entry.getKey(); + var activityState = entry.getValue(); + if (activityState.getLastRecordedTime() < expirationTime) { + statesToRemove.add(activityKey); + } + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(activityKey, activityState, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + // TODO: log + } + }); + } + } + statesToRemove.forEach(activityStates::remove); + } + + private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { + activityStates.computeIfPresent(key, (__, activityState) -> { + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityState; + }); + } + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java similarity index 92% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index db24c2388d..d93756a922 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -32,11 +32,11 @@ package org.thingsboard.server.common.transport.activity; import java.util.function.Supplier; -public interface ActivityStateManager { +public interface ActivityManager { void init(); - void recordActivity(Key key, Supplier newActivityStateSupplier); + void onActivity(Key key, Supplier newStateSupplier); void destroy(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java deleted file mode 100644 index 7d87b02f19..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateManagerImpl.java +++ /dev/null @@ -1,240 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.common.transport.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.data.util.Pair; -import org.thingsboard.common.util.ThingsBoardThreadFactory; - -import java.util.Map; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -@Slf4j -public final class ActivityStateManagerImpl implements ActivityStateManager { - - private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); - - @Data - private static class ActivityStateWrapper { - - volatile ActivityState activityState; - volatile boolean alreadyBeenReported; - - } - - private ScheduledExecutorService scheduler; - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private final AtomicInteger currentPeriodId = new AtomicInteger(); - private final AsyncActivityStateReporter reporter; - private final long reportingPeriodDurationMillis; - private final String name; - private boolean initialized; - - public ActivityStateManagerImpl(AsyncActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { - this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided reporter is null."); - this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation - this.name = name == null ? "activity-state-manager" : name; - } - - @Override - public synchronized void init() { - if (!initialized) { - initialized = true; - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); - scheduler.scheduleAtFixedRate(this::reportLastEventAndStartNewPeriod, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); - } - } - - @Override - public void recordActivity(Key activityKey, Supplier newActivityStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - int capturedPeriodId = currentPeriodId.get(); - lock.readLock().lock(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - try { - activityStates.compute(activityKey, (key, activityStateWrapper) -> { - if (activityStateWrapper == null) { - State activityState = newActivityStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); - activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setActivityState(activityState); - activityStateWrapper.setAlreadyBeenReported(false); - } else { - activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); - } - if (activityStateWrapper.isAlreadyBeenReported()) { - return activityStateWrapper; - } - var activityState = activityStateWrapper.getActivityState(); - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.reportAsync(key, (State) activityState, new ActivityStateReportCallback<>() { - @Override - public void onSuccess(Key key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(Key key, Throwable t) { - reportCompletedFuture.setException(t); - } - - @Override - public void onRemove(Key key) { - lock.readLock().lock(); - try { - activityStates.remove(key); - } finally { - lock.readLock().unlock(); - } - } - }); - } - activityStateWrapper.setAlreadyBeenReported(true); - return activityStateWrapper; - }); - } finally { - lock.readLock().unlock(); - } - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - lock.readLock().lock(); - try { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public void onFailure(@NonNull Throwable t) { // TODO: add failure logging - lock.readLock().lock(); - try { - rollbackReportedStatus(activityKey, capturedPeriodId, newLastRecordedTime); - } finally { - lock.readLock().unlock(); - } - } - }, MoreExecutors.directExecutor()); - } - - private void rollbackReportedStatus(Key key, int capturedPeriodId, long newLastRecordedTime) { - activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { - if (capturedPeriodId == currentPeriodId.get() && activityStateWrapper.getActivityState().getLastReportedTime() < newLastRecordedTime) { - activityStateWrapper.setAlreadyBeenReported(false); - } - return activityStateWrapper; - }); - } - - private void reportLastEventAndStartNewPeriod() { - lock.writeLock().lock(); - try { - Map activityStateMap = activityStates.entrySet().stream() - .peek(entry -> entry.getValue().setAlreadyBeenReported(false)) - .collect(Collectors.toMap(Map.Entry::getKey, entry -> (State) entry.getValue().getActivityState())); - reporter.reportAsync(activityStateMap, new ActivityStateReportCallback<>() { - @Override - public void onSuccess(Key key, long reportedTime) { - lock.readLock().lock(); - try { - updateLastReportedTime(key, reportedTime); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public void onFailure(Key key, Throwable t) { - log.debug("Failed to report activity state for key [{}]!", key, t); - } - - @Override - public void onRemove(Key key) { - lock.readLock().lock(); - try { - activityStates.remove(key); - } finally { - lock.readLock().unlock(); - } - } - }); - } finally { - currentPeriodId.incrementAndGet(); - lock.writeLock().unlock(); - } - } - - private void updateLastReportedTime(Key key, long newLastReportedTime) { - activityStates.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getActivityState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java index d9d897d4a1..4ff752d61d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java @@ -36,6 +36,4 @@ public interface ActivityStateReportCallback { void onFailure(Key key, Throwable t); - void onRemove(Key key); - } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java similarity index 85% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java index ab9094c252..620646f894 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AsyncActivityStateReporter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java @@ -32,10 +32,10 @@ package org.thingsboard.server.common.transport.activity; import java.util.Map; -public interface AsyncActivityStateReporter { +public interface ActivityStateReporter { - void reportAsync(Key key, State activityState, ActivityStateReportCallback reportCallback); + void report(Key key, State activityState, ActivityStateReportCallback reportCallback); - void reportAsync(Map activityStates, ActivityStateReportCallback reportCallback); + void report(Map activityStates, ActivityStateReportCallback reportCallback); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 7769762b84..31ab2df09e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -72,16 +72,16 @@ import org.thingsboard.server.common.transport.TransportResourceCache; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportTenantProfileCache; -import org.thingsboard.server.common.transport.activity.ActivityStateManager; -import org.thingsboard.server.common.transport.activity.ActivityStateManagerImpl; +import org.thingsboard.server.common.transport.activity.ActivityManager; import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; -import org.thingsboard.server.common.transport.activity.AsyncActivityStateReporter; +import org.thingsboard.server.common.transport.activity.ActivityStateReporter; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.common.transport.limits.EntityLimitKey; import org.thingsboard.server.common.transport.limits.EntityLimitsCache; import org.thingsboard.server.common.transport.limits.TransportRateLimitService; +import org.thingsboard.server.common.transport.service.activity.LastOnlyTransportActivityManager; import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; @@ -203,7 +203,7 @@ public class DefaultTransportService implements TransportService { private ExecutorService mainConsumerExecutor; public final ConcurrentMap sessions = new ConcurrentHashMap<>(); - private ActivityStateManager activityStateManager; + private ActivityManager activityManager; private final Map toServerRpcPendingMap = new ConcurrentHashMap<>(); private volatile boolean stopped = false; @@ -253,8 +253,8 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); - activityStateManager = new ActivityStateManagerImpl<>(reporter, sessionReportTimeout, "transport-activity-state-manager"); - activityStateManager.init(); + activityManager = new LastOnlyTransportActivityManager(reporter, sessionReportTimeout, "transport-activity-state-manager"); + activityManager.init(); } // TODO: why sessions and session activities are managed in a separate maps? maybe it is better to manage in a single map @@ -267,44 +267,41 @@ public class DefaultTransportService implements TransportService { // this can cause lost activity updates if first event that got reported failed to enqueue in Kafka and next reporting period is already started // (maybe having a queue of "first" events will help with this, queue will be cleared once event was successfully queued or later time was reported by event in next period) // setting alreadyBeenReported status in callbacks ensures that events are reported but can cause several "first" events to be reported - private final AsyncActivityStateReporter reporter = new AsyncActivityStateReporter<>() { + private final ActivityStateReporter reporter = new ActivityStateReporter<>() { @Override - public void reportAsync(UUID sessionId, TransportActivityState activityState, ActivityStateReportCallback reportCallback) { + public void report(UUID sessionId, TransportActivityState activityState, ActivityStateReportCallback reportCallback) { SessionMetaData sessionMetaData = sessions.get(sessionId); - TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) - .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) - .setLastActivityTime(activityState.getLastRecordedTime()) - .build(); - process(activityState.getSessionInfoProto(), subscriptionInfo, new TransportServiceCallback<>() { + reportActivityStateToCore(activityState.getSessionInfoProto(), sessionMetaData, activityState.getLastRecordedTime(), new TransportServiceCallback<>() { @Override - public void onSuccess(Void msgAcknowledged) { + public void onSuccess(Void msg) { reportCallback.onSuccess(sessionId, activityState.getLastRecordedTime()); + } @Override public void onError(Throwable e) { reportCallback.onFailure(sessionId, e); + } }); } @Override - public void reportAsync(Map activityStates, ActivityStateReportCallback reportCallback) { + public void report(Map activityStates, ActivityStateReportCallback reportCallback) { long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; for (Map.Entry entry : activityStates.entrySet()) { var sessionId = entry.getKey(); var activityState = entry.getValue(); - long lastActivityTime = activityState.getLastRecordedTime(); - SessionMetaData sessionMetaData = sessions.get(sessionId); if (sessionMetaData != null) { activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); } else { - reportCallback.onRemove(sessionId); + log.info("Removing activity state due to session deregistration."); + activityStates.remove(sessionId); } + long lastActivityTime = activityState.getLastRecordedTime(); TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { @@ -323,7 +320,8 @@ public class DefaultTransportService implements TransportService { log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); } sessions.remove(sessionId); - reportCallback.onRemove(sessionId); + log.info("Removing activity state due to session expiration."); + activityStates.remove(sessionId); process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); } else if (activityState.getLastReportedTime() < lastActivityTime) { @@ -406,8 +404,8 @@ public class DefaultTransportService implements TransportService { if (transportApiRequestTemplate != null) { transportApiRequestTemplate.stop(); } - if (activityStateManager != null) { - activityStateManager.destroy(); + if (activityManager != null) { + activityManager.destroy(); } } @@ -660,6 +658,7 @@ public class DefaultTransportService implements TransportService { @Override public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.SessionEventMsg msg, TransportServiceCallback callback) { + log.info("Received session event: [{}]", msg.getEvent()); if (checkLimits(sessionInfo, msg, callback)) { reportActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) @@ -888,7 +887,7 @@ public class DefaultTransportService implements TransportService { } private void reportActivityInternal(TransportProtos.SessionInfoProto sessionInfo) { - activityStateManager.recordActivity(toSessionId(sessionInfo), () -> { + activityManager.onActivity(toSessionId(sessionInfo), () -> { var activityState = new TransportActivityState(); activityState.setSessionInfoProto(sessionInfo); return activityState; @@ -950,6 +949,7 @@ public class DefaultTransportService implements TransportService { log.debug("Stopping scheduler to avoid resending response if request has been ack."); currentSession.getScheduledFuture().cancel(false); } + log.info("Deregistering session."); sessions.remove(toSessionId(sessionInfo)); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java new file mode 100644 index 0000000000..41f0207f72 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java @@ -0,0 +1,131 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.service.activity; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityStateReporter; +import org.thingsboard.server.common.transport.service.TransportActivityState; + +import java.util.Objects; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +@Slf4j +public class LastOnlyTransportActivityManager implements ActivityManager { + + private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + + private ScheduledExecutorService scheduler; + private final ActivityStateReporter reporter; + private final long reportingPeriodDurationMillis; + private final String name; + private boolean initialized; + + public LastOnlyTransportActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { + this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); + this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation + this.name = name == null ? "activity-state-manager" : name; + } + + @Override + public synchronized void init() { + if (!initialized) { + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); + initialized = true; + } + } + + @Override + public void onActivity(UUID activityKey, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + activityStates.compute(activityKey, (key, activityState) -> { + if (activityState == null) { + log.info("Creating new activity state."); + activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + } else { + activityState.setLastRecordedTime(newLastRecordedTime); + } + return activityState; + }); + } + + private void onReportingPeriodEnd() { + reporter.report(activityStates, new ActivityStateReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(UUID uuid, Throwable t) { + // TODO: log + } + }); + } + + private void updateLastReportedTime(UUID key, long newLastReportedTime) { + activityStates.computeIfPresent(key, (__, activityState) -> { + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityState; + }); + } + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} From 2ca1f719981be755d01b1956bcfdefe8f3475e74 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 7 Dec 2023 17:09:51 +0200 Subject: [PATCH 59/91] [WIP] Migrate to using spring beans, add properties to yaml --- ...irstAndLastIntegrationActivityManager.java | 99 +++------ .../FirstOnlyIntegrationActivityManager.java | 110 +++------- .../LastOnlyIntegrationActivityManager.java | 82 ++----- .../src/main/resources/thingsboard.yml | 9 +- .../common/transport/TransportService.java | 3 + .../activity/AbstractActivityManager.java | 114 ++++++++++ .../transport/activity/ActivityManager.java | 6 + ...lback.java => ActivityReportCallback.java} | 2 +- .../activity/ActivityStateReporter.java | 7 +- .../service/DefaultTransportService.java | 129 +++-------- .../FirstAndLastTransportActivityManager.java | 203 +++++++++++++++++ .../FirstOnlyTransportActivityManager.java | 204 ++++++++++++++++++ .../LastOnlyTransportActivityManager.java | 143 ++++++------ 13 files changed, 731 insertions(+), 380 deletions(-) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/{ActivityStateReportCallback.java => ActivityReportCallback.java} (97%) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java index 12be2101c4..4a38af1a4d 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java @@ -37,80 +37,54 @@ import com.google.common.util.concurrent.SettableFuture; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.util.Pair; -import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityStateReporter; -import java.util.HashSet; import java.util.Map; -import java.util.Objects; -import java.util.Random; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @Slf4j -public class FirstAndLastIntegrationActivityManager implements ActivityManager { +@Component +@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first-and-last") +public class FirstAndLastIntegrationActivityManager extends AbstractActivityManager { - private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + private final ConcurrentMap states = new ConcurrentHashMap<>(); @Data private static class ActivityStateWrapper { - volatile ActivityState activityState; + volatile ActivityState state; volatile boolean alreadyBeenReported; } - private ScheduledExecutorService scheduler; - private final ActivityStateReporter reporter; - private final long reportingPeriodDurationMillis; - private final String name; - private boolean initialized; - - public FirstAndLastIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { - this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); - this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation - this.name = name == null ? "activity-state-manager" : name; - } - - @Override - public synchronized void init() { - if (!initialized) { - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); - scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); - initialized = true; - } - } - @Override - public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); SettableFuture> reportCompletedFuture = SettableFuture.create(); - activityStates.compute(activityKey, (key, activityStateWrapper) -> { + states.compute(activityKey, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { ActivityState activityState = newStateSupplier.get(); activityState.setLastRecordedTime(newLastRecordedTime); activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setActivityState(activityState); + activityStateWrapper.setState(activityState); activityStateWrapper.setAlreadyBeenReported(false); } else { - activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getActivityState(); + var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(key, activityState, new ActivityStateReportCallback<>() { + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { reportCompletedFuture.set(Pair.of(key, reportedTime)); @@ -133,24 +107,23 @@ public class FirstAndLastIntegrationActivityManager implements ActivityManager statesToRemove = new HashSet<>(); - Set> entries = activityStates.entrySet(); - for (Map.Entry entry : entries) { + @Override + protected void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; + for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); - var activityState = activityStateWrapper.getActivityState(); + var activityState = activityStateWrapper.getState(); if (activityState.getLastRecordedTime() < expirationTime) { - statesToRemove.add(activityKey); + states.remove(activityKey); } if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(activityKey, activityState, new ActivityStateReportCallback<>() { + reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -158,39 +131,21 @@ public class FirstAndLastIntegrationActivityManager implements ActivityManager { - var activityState = activityStateWrapper.getActivityState(); + states.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getState(); activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); return activityStateWrapper; }); } - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index 7a0bccd48c..b9965098df 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -37,80 +37,54 @@ import com.google.common.util.concurrent.SettableFuture; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.util.Pair; -import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityStateReporter; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; -import java.util.Random; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @Slf4j -public class FirstOnlyIntegrationActivityManager implements ActivityManager { +@Component +@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first") +public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager { - private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); + private final ConcurrentMap states = new ConcurrentHashMap<>(); @Data private static class ActivityStateWrapper { - volatile ActivityState activityState; + volatile ActivityState state; volatile boolean alreadyBeenReported; } - private ScheduledExecutorService scheduler; - private final ActivityStateReporter reporter; - private final long reportingPeriodDurationMillis; - private final String name; - private boolean initialized; - - public FirstOnlyIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { - this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); - this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation - this.name = name == null ? "activity-state-manager" : name; - } - - @Override - public synchronized void init() { - if (!initialized) { - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); - scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); - initialized = true; - } - } - @Override - public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); SettableFuture> reportCompletedFuture = SettableFuture.create(); - activityStates.compute(activityKey, (key, activityStateWrapper) -> { + states.compute(activityKey, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { ActivityState activityState = newStateSupplier.get(); activityState.setLastRecordedTime(newLastRecordedTime); activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setActivityState(activityState); + activityStateWrapper.setState(activityState); activityStateWrapper.setAlreadyBeenReported(false); } else { - activityStateWrapper.getActivityState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getActivityState(); + var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(key, activityState, new ActivityStateReportCallback<>() { + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { reportCompletedFuture.set(Pair.of(key, reportedTime)); @@ -133,59 +107,39 @@ public class FirstOnlyIntegrationActivityManager implements ActivityManager { - var activityState = activityStateWrapper.getActivityState(); + states.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getState(); activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); return activityStateWrapper; }); } - private void onReportingPeriodEnd() { - Map statesToRemoveAndReport = new HashMap<>(); - Set> entries = activityStates.entrySet(); - for (Map.Entry entry : entries) { + @Override + protected void onReportingPeriodEnd() { + for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); - var activityState = activityStateWrapper.getActivityState(); + var activityState = activityStateWrapper.getState(); if (!activityStateWrapper.isAlreadyBeenReported() && activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - statesToRemoveAndReport.put(activityKey, activityState); - } - activityStateWrapper.setAlreadyBeenReported(false); - } - statesToRemoveAndReport.forEach((key, state) -> reporter.report(key, state, new ActivityStateReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - activityStates.remove(key); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - // TODO: log - } - })); - } + reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + states.remove(key); + } - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } + }); } + activityStateWrapper.setAlreadyBeenReported(false); } } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java index 0dd7aa6fc1..bffdc49054 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -31,54 +31,28 @@ package org.thingsboard.server.service.integration.activity; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.transport.activity.ActivityManager; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityStateReporter; -import java.util.HashSet; import java.util.Map; -import java.util.Objects; -import java.util.Random; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @Slf4j -public class LastOnlyIntegrationActivityManager implements ActivityManager { +@Component +@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "last") +public class LastOnlyIntegrationActivityManager extends AbstractActivityManager { - private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); - - private ScheduledExecutorService scheduler; - private final ActivityStateReporter reporter; - private final long reportingPeriodDurationMillis; - private final String name; - private boolean initialized; - - public LastOnlyIntegrationActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { - this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); - this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation - this.name = name == null ? "activity-state-manager" : name; - } - - @Override - public synchronized void init() { - if (!initialized) { - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); - scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); - initialized = true; - } - } + private final ConcurrentMap states = new ConcurrentHashMap<>(); @Override - public void onActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); - activityStates.compute(activityKey, (key, activityState) -> { + states.compute(activityKey, (__, activityState) -> { if (activityState == null) { activityState = newStateSupplier.get(); activityState.setLastRecordedTime(newLastRecordedTime); @@ -90,18 +64,17 @@ public class LastOnlyIntegrationActivityManager implements ActivityManager statesToRemove = new HashSet<>(); - Set> entries = activityStates.entrySet(); - for (Map.Entry entry : entries) { + @Override + public void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; + for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityState = entry.getValue(); if (activityState.getLastRecordedTime() < expirationTime) { - statesToRemove.add(activityKey); + states.remove(activityKey); } if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(activityKey, activityState, new ActivityStateReportCallback<>() { + reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -109,37 +82,18 @@ public class LastOnlyIntegrationActivityManager implements ActivityManager { + states.computeIfPresent(key, (__, activityState) -> { activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); return activityState; }); } - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - } - } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index e746dc9dba..73f0622cd1 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -866,6 +866,13 @@ transport: inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" # Interval of periodic check for expired sessions and report of the changes to session last activity time report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:3000}" + activity: + # This property specifies the strategy for reporting activity events within each reporting period. + # The accepted values are 'first', 'last', and 'first and last'. + # - 'first': Only the first activity event in each reporting period is reported. + # - 'last': Only the last activity event in the reporting period is reported. + # - 'first-and-last': Both the first and last activity events in the reporting period are reported. + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:first-and-last}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" @@ -1695,4 +1702,4 @@ management: web: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). - include: '${METRICS_ENDPOINTS_EXPOSE:info}' \ No newline at end of file + include: '${METRICS_ENDPOINTS_EXPOSE:info}' diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index f51b399a5b..067527efec 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -63,6 +63,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509Ce import org.thingsboard.server.gen.transport.TransportProtos.ValidateOrCreateDeviceX509CertRequestMsg; import java.util.List; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; @@ -161,5 +162,7 @@ public interface TransportService { boolean hasSession(SessionInfoProto sessionInfo); + SessionMetaData getSession(UUID sessionId); + void createGaugeStats(String openConnections, AtomicInteger connectionsCounter); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java new file mode 100644 index 0000000000..0c7e00816a --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -0,0 +1,114 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity; + +import org.thingsboard.common.util.ThingsBoardThreadFactory; + +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +public abstract class AbstractActivityManager implements ActivityManager { + + private String name; + protected long reportingPeriodMillis; + protected ActivityStateReporter reporter; + private ScheduledExecutorService scheduler; + protected boolean initialized; + + @Override + public synchronized void init() { + Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); + if (reportingPeriodMillis < 1000) { + throw new IllegalArgumentException("Failed to initialize activity manager: provided reporting period duration is less that 1 second."); + } + if (!initialized) { + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name == null ? "activity-manager" : name)); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); + initialized = true; + } + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public void setReportingPeriod(long reportingPeriodMillis) { + this.reportingPeriodMillis = reportingPeriodMillis; + } + + @Override + public void setActivityReporter(ActivityStateReporter activityReporter) { + reporter = activityReporter; + } + + @Override + public void onActivity(Key key, Supplier newStateSupplier) { + if (!initialized) { + throw new IllegalStateException(name + " is not initialized."); + } + if (key == null) { + throw new IllegalArgumentException("Activity key can't be null."); + } + if (newStateSupplier == null) { + throw new IllegalArgumentException("New activity state supplier can't be null."); + } + doOnActivity(key, newStateSupplier); + } + + protected abstract void doOnActivity(Key key, Supplier newStateSupplier); + + protected abstract void onReportingPeriodEnd(); + + @Override + public synchronized void destroy() { + if (initialized) { + initialized = false; + if (scheduler != null) { + scheduler.shutdown(); + try { + if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index d93756a922..ba09ccf773 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -34,6 +34,12 @@ import java.util.function.Supplier; public interface ActivityManager { + void setName(String name); + + void setReportingPeriod(long reportingPeriodMillis); + + void setActivityReporter(ActivityStateReporter activityReporter); + void init(); void onActivity(Key key, Supplier newStateSupplier); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java similarity index 97% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java index 4ff752d61d..9d009d2707 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReportCallback.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java @@ -30,7 +30,7 @@ */ package org.thingsboard.server.common.transport.activity; -public interface ActivityStateReportCallback { +public interface ActivityReportCallback { void onSuccess(Key key, long reportedTime); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java index 620646f894..1092c569d2 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java @@ -30,12 +30,9 @@ */ package org.thingsboard.server.common.transport.activity; -import java.util.Map; - +@FunctionalInterface public interface ActivityStateReporter { - void report(Key key, State activityState, ActivityStateReportCallback reportCallback); - - void report(Map activityStates, ActivityStateReportCallback reportCallback); + void report(Key key, long timeToReport, State activityState, ActivityReportCallback callback); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 31ab2df09e..6453cbd24c 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -73,7 +73,6 @@ import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportTenantProfileCache; import org.thingsboard.server.common.transport.activity.ActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; import org.thingsboard.server.common.transport.activity.ActivityStateReporter; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; @@ -81,7 +80,6 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes import org.thingsboard.server.common.transport.limits.EntityLimitKey; import org.thingsboard.server.common.transport.limits.EntityLimitsCache; import org.thingsboard.server.common.transport.limits.TransportRateLimitService; -import org.thingsboard.server.common.transport.service.activity.LastOnlyTransportActivityManager; import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; @@ -187,8 +185,8 @@ public class DefaultTransportService implements TransportService { private final ApplicationEventPublisher eventPublisher; private final TransportResourceCache transportResourceCache; private final NotificationRuleProcessor notificationRuleProcessor; - private final EntityLimitsCache entityLimitsCache; + private ActivityManager activityManager; protected TbQueueRequestTemplate, TbProtoQueueMsg> transportApiRequestTemplate; protected TbQueueProducer> ruleEngineMsgProducer; @@ -203,7 +201,6 @@ public class DefaultTransportService implements TransportService { private ExecutorService mainConsumerExecutor; public final ConcurrentMap sessions = new ConcurrentHashMap<>(); - private ActivityManager activityManager; private final Map toServerRpcPendingMap = new ConcurrentHashMap<>(); private volatile boolean stopped = false; @@ -237,6 +234,11 @@ public class DefaultTransportService implements TransportService { this.entityLimitsCache = entityLimitsCache; } + @Autowired + public void setActivityManager(ActivityManager activityManager) { + this.activityManager = activityManager; + } + @PostConstruct public void init() { this.ruleEngineProducerStats = statsFactory.createMessagesStats(StatsType.RULE_ENGINE.getName() + ".producer"); @@ -253,104 +255,32 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); - activityManager = new LastOnlyTransportActivityManager(reporter, sessionReportTimeout, "transport-activity-state-manager"); + + activityManager.setName("transport-activity-manager"); + activityManager.setReportingPeriod(sessionReportTimeout); + activityManager.setActivityReporter(activityReporter); activityManager.init(); } - // TODO: why sessions and session activities are managed in a separate maps? maybe it is better to manage in a single map - // (eg. we can check if we had sent last activity event when deregistering session) - - // TODO: currently if activity event is received between precise session expiration time and reportLastEventAndStartNewPeriod() call - // we will "resurrect" this session meaning that it will be considered alive but in fact it did not perform any activity for more than timeout allows - - // TODO: I optimistically set alreadyBeenReported status to true to avoid reporting several activity events if they arrive in rapid succession - // this can cause lost activity updates if first event that got reported failed to enqueue in Kafka and next reporting period is already started - // (maybe having a queue of "first" events will help with this, queue will be cleared once event was successfully queued or later time was reported by event in next period) - // setting alreadyBeenReported status in callbacks ensures that events are reported but can cause several "first" events to be reported - private final ActivityStateReporter reporter = new ActivityStateReporter<>() { - @Override - public void report(UUID sessionId, TransportActivityState activityState, ActivityStateReportCallback reportCallback) { - SessionMetaData sessionMetaData = sessions.get(sessionId); - reportActivityStateToCore(activityState.getSessionInfoProto(), sessionMetaData, activityState.getLastRecordedTime(), new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msg) { - reportCallback.onSuccess(sessionId, activityState.getLastRecordedTime()); - - } - - @Override - public void onError(Throwable e) { - reportCallback.onFailure(sessionId, e); - - } - }); - } - - @Override - public void report(Map activityStates, ActivityStateReportCallback reportCallback) { - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; - for (Map.Entry entry : activityStates.entrySet()) { - var sessionId = entry.getKey(); - var activityState = entry.getValue(); - - SessionMetaData sessionMetaData = sessions.get(sessionId); - if (sessionMetaData != null) { - activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); - } else { - log.info("Removing activity state due to session deregistration."); - activityStates.remove(sessionId); - } - - long lastActivityTime = activityState.getLastRecordedTime(); - TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSessionMetaData = sessions.get(gwSessionId); - if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { - TransportActivityState gwActivityState = activityStates.get(gwSessionId); - if (gwActivityState != null) { - lastActivityTime = Math.max(gwActivityState.getLastRecordedTime(), lastActivityTime); - } - } - } - - if (sessionMetaData != null && lastActivityTime < expirationTime) { - if (log.isDebugEnabled()) { - log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); - } - sessions.remove(sessionId); - log.info("Removing activity state due to session expiration."); - activityStates.remove(sessionId); - process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } else if (activityState.getLastReportedTime() < lastActivityTime) { - long finalLastActivityTime = lastActivityTime; - reportActivityStateToCore(sessionInfo, sessionMetaData, lastActivityTime, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - reportCallback.onSuccess(sessionId, finalLastActivityTime); - } + private final ActivityStateReporter activityReporter = (sessionId, timeToReport, state, reportCallback) -> { + SessionMetaData sessionMetaData = sessions.get(sessionId); + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) + .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) + .setLastActivityTime(timeToReport) + .build(); + process(state.getSessionInfoProto(), subscriptionInfo, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + reportCallback.onSuccess(sessionId, timeToReport); - @Override - public void onError(Throwable e) { - reportCallback.onFailure(sessionId, e); - } - }); - } } - } - private void reportActivityStateToCore( - TransportProtos.SessionInfoProto sessionInfo, SessionMetaData sessionMetaData, long lastActivityTime, TransportServiceCallback callback - ) { - TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) - .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) - .setLastActivityTime(lastActivityTime) - .build(); - process(sessionInfo, subscriptionInfo, callback); - } + @Override + public void onError(Throwable e) { + reportCallback.onFailure(sessionId, e); + } + }); }; @AfterStartUp(order = AfterStartUp.TRANSPORT_SERVICE) @@ -658,7 +588,6 @@ public class DefaultTransportService implements TransportService { @Override public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.SessionEventMsg msg, TransportServiceCallback callback) { - log.info("Received session event: [{}]", msg.getEvent()); if (checkLimits(sessionInfo, msg, callback)) { reportActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) @@ -949,7 +878,6 @@ public class DefaultTransportService implements TransportService { log.debug("Stopping scheduler to avoid resending response if request has been ack."); currentSession.getScheduledFuture().cancel(false); } - log.info("Deregistering session."); sessions.remove(toSessionId(sessionInfo)); } @@ -1370,6 +1298,11 @@ public class DefaultTransportService implements TransportService { return sessions.containsKey(toSessionId(sessionInfo)); } + @Override + public SessionMetaData getSession(UUID sessionId) { + return sessions.get(sessionId); + } + @Override public void createGaugeStats(String statsName, AtomicInteger number) { statsFactory.createGauge(StatsType.TRANSPORT + "." + statsName, number); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java new file mode 100644 index 0000000000..e6bffa4dfd --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java @@ -0,0 +1,203 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.service.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.TransportService; +import org.thingsboard.server.common.transport.TransportServiceCallback; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.service.SessionMetaData; +import org.thingsboard.server.common.transport.service.TransportActivityState; +import org.thingsboard.server.gen.transport.TransportProtos; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; + +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; + +@Slf4j +@Component +@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first-and-last") +public class FirstAndLastTransportActivityManager extends AbstractActivityManager { + + private final ConcurrentMap states = new ConcurrentHashMap<>(); + + @Data + private static class ActivityStateWrapper { + + volatile TransportActivityState state; + volatile boolean alreadyBeenReported; + + } + + @Value("${transport.sessions.inactivity_timeout}") + private long sessionInactivityTimeout; + + @Autowired + private TransportService transportService; + + @Override + protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + states.compute(sessionId, (key, activityStateWrapper) -> { + if (activityStateWrapper == null) { + TransportActivityState activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + activityStateWrapper = new ActivityStateWrapper(); + activityStateWrapper.setState(activityState); + activityStateWrapper.setAlreadyBeenReported(false); + } else { + activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + } + if (activityStateWrapper.isAlreadyBeenReported()) { + return activityStateWrapper; + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(UUID key, Throwable t) { + reportCompletedFuture.setException(t); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(true); + return activityStateWrapper; + }); + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } + + @Override + public void onFailure(@NonNull Throwable t) { + log.debug("[{}] Failed to report first activity event in a period for session.", sessionId); + } + }, MoreExecutors.directExecutor()); + } + + @Override + protected void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + for (Map.Entry entry : states.entrySet()) { + var sessionId = entry.getKey(); + var activityStateWrapper = entry.getValue(); + var activityState = activityStateWrapper.getState(); + + SessionMetaData sessionMetaData = transportService.getSession(sessionId); + if (sessionMetaData != null) { + activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); + } else { + states.remove(sessionId); + } + + long lastActivityTime = activityState.getLastRecordedTime(); + TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); + + if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); + if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { + ActivityStateWrapper gwActivityStateWrapper = states.get(gwSessionId); + if (gwActivityStateWrapper != null) { + lastActivityTime = Math.max(gwActivityStateWrapper.getState().getLastRecordedTime(), lastActivityTime); + } + } + } + + boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; + if (hasExpired) { + if (log.isDebugEnabled()) { + log.debug("[{}] Session has expired due to last activity time: [{}]!", sessionId, lastActivityTime); + } + transportService.deregisterSession(sessionInfo); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + states.remove(sessionId); + } + + @Override + public void onError(Throwable e) { + states.remove(sessionId); + } + }); + sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } else if (activityState.getLastReportedTime() < lastActivityTime) { + reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(UUID key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for session.", sessionId); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(false); + } + } + + private void updateLastReportedTime(UUID key, long newLastReportedTime) { + states.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java new file mode 100644 index 0000000000..8cefbb0b46 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java @@ -0,0 +1,204 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.service.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.TransportService; +import org.thingsboard.server.common.transport.TransportServiceCallback; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.service.SessionMetaData; +import org.thingsboard.server.common.transport.service.TransportActivityState; +import org.thingsboard.server.gen.transport.TransportProtos; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; + +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; + +@Slf4j +@Component +@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first") +public class FirstOnlyTransportActivityManager extends AbstractActivityManager { + + private final ConcurrentMap states = new ConcurrentHashMap<>(); + + @Data + private static class ActivityStateWrapper { + + volatile TransportActivityState state; + volatile boolean alreadyBeenReported; + + } + + @Value("${transport.sessions.inactivity_timeout}") + private long sessionInactivityTimeout; + + @Autowired + private TransportService transportService; + + @Override + protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + states.compute(sessionId, (key, activityStateWrapper) -> { + if (activityStateWrapper == null) { + TransportActivityState activityState = newStateSupplier.get(); + activityState.setLastRecordedTime(newLastRecordedTime); + activityState.setLastReportedTime(0L); + activityStateWrapper = new ActivityStateWrapper(); + activityStateWrapper.setState(activityState); + activityStateWrapper.setAlreadyBeenReported(false); + } else { + activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + } + if (activityStateWrapper.isAlreadyBeenReported()) { + return activityStateWrapper; + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(UUID key, Throwable t) { + reportCompletedFuture.setException(t); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(true); + return activityStateWrapper; + }); + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } + + @Override + public void onFailure(@NonNull Throwable t) { + log.debug("[{}] Failed to report first activity event in a period for session.", sessionId); + } + }, MoreExecutors.directExecutor()); + } + + @Override + protected void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + for (Map.Entry entry : states.entrySet()) { + var sessionId = entry.getKey(); + var activityStateWrapper = entry.getValue(); + var activityState = activityStateWrapper.getState(); + + SessionMetaData sessionMetaData = transportService.getSession(sessionId); + if (sessionMetaData != null) { + activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); + } else { + states.remove(sessionId); + } + + long lastActivityTime = activityState.getLastRecordedTime(); + TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); + + if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); + if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { + ActivityStateWrapper gwActivityStateWrapper = states.get(gwSessionId); + if (gwActivityStateWrapper != null) { + lastActivityTime = Math.max(gwActivityStateWrapper.getState().getLastRecordedTime(), lastActivityTime); + } + } + } + + boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; + if (hasExpired) { + if (log.isDebugEnabled()) { + log.debug("[{}] Session has expired due to last activity time: {}!", sessionId, lastActivityTime); + } + transportService.deregisterSession(sessionInfo); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + states.remove(sessionId); + } + + @Override + public void onError(Throwable e) { + states.remove(sessionId); + } + }); + sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } + if ((sessionMetaData == null || hasExpired) && activityState.getLastReportedTime() < lastActivityTime) { + reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(UUID key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for session.", sessionId); + } + }); + } + activityStateWrapper.setAlreadyBeenReported(false); + } + } + + private void updateLastReportedTime(UUID key, long newLastReportedTime) { + states.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java index 41f0207f72..bc723e0e4a 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java @@ -31,54 +31,45 @@ package org.thingsboard.server.common.transport.service.activity; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.transport.activity.ActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityStateReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityStateReporter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.TransportService; +import org.thingsboard.server.common.transport.TransportServiceCallback; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; +import org.thingsboard.server.gen.transport.TransportProtos; -import java.util.Objects; -import java.util.Random; +import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; -@Slf4j -public class LastOnlyTransportActivityManager implements ActivityManager { +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; +import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; - private final ConcurrentMap activityStates = new ConcurrentHashMap<>(); +@Slf4j +@Component +@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "last") +public class LastOnlyTransportActivityManager extends AbstractActivityManager { - private ScheduledExecutorService scheduler; - private final ActivityStateReporter reporter; - private final long reportingPeriodDurationMillis; - private final String name; - private boolean initialized; + private final ConcurrentMap states = new ConcurrentHashMap<>(); - public LastOnlyTransportActivityManager(ActivityStateReporter reporter, long reportingPeriodDurationMillis, String name) { - this.reporter = Objects.requireNonNull(reporter, "Failed to create activity manager: provided reporter is null."); - this.reportingPeriodDurationMillis = reportingPeriodDurationMillis; // TODO: add min/max duration validation - this.name = name == null ? "activity-state-manager" : name; - } + @Value("${transport.sessions.inactivity_timeout}") + private long sessionInactivityTimeout; - @Override - public synchronized void init() { - if (!initialized) { - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name)); - scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodDurationMillis), reportingPeriodDurationMillis, TimeUnit.MILLISECONDS); - initialized = true; - } - } + @Autowired + private TransportService transportService; @Override - public void onActivity(UUID activityKey, Supplier newStateSupplier) { + protected void doOnActivity(UUID activityKey, Supplier newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); - activityStates.compute(activityKey, (key, activityState) -> { + states.compute(activityKey, (__, activityState) -> { if (activityState == null) { - log.info("Creating new activity state."); activityState = newStateSupplier.get(); activityState.setLastRecordedTime(newLastRecordedTime); activityState.setLastReportedTime(0L); @@ -89,43 +80,73 @@ public class LastOnlyTransportActivityManager implements ActivityManager() { - @Override - public void onSuccess(UUID key, long reportedTime) { - updateLastReportedTime(key, reportedTime); + @Override + protected void onReportingPeriodEnd() { + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + for (Map.Entry entry : states.entrySet()) { + var sessionId = entry.getKey(); + var activityState = entry.getValue(); + + SessionMetaData sessionMetaData = transportService.getSession(sessionId); + if (sessionMetaData != null) { + activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); + } else { + states.remove(sessionId); } - @Override - public void onFailure(UUID uuid, Throwable t) { - // TODO: log + long lastActivityTime = activityState.getLastRecordedTime(); + TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); + + if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); + if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { + TransportActivityState gwActivityState = states.get(gwSessionId); + if (gwActivityState != null) { + lastActivityTime = Math.max(gwActivityState.getLastRecordedTime(), lastActivityTime); + } + } } - }); + + boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; + if (hasExpired) { + if (log.isDebugEnabled()) { + log.debug("[{}] Session has expired due to last activity time: [{}]!", sessionId, lastActivityTime); + } + transportService.deregisterSession(sessionInfo); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + states.remove(sessionId); + } + + @Override + public void onError(Throwable e) { + states.remove(sessionId); + } + }); + sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } else if (activityState.getLastReportedTime() < lastActivityTime) { + reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(UUID key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(UUID key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for session.", sessionId); + } + }); + } + } } private void updateLastReportedTime(UUID key, long newLastReportedTime) { - activityStates.computeIfPresent(key, (__, activityState) -> { + states.computeIfPresent(key, (__, activityState) -> { activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); return activityState; }); } - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - } - } From c3556eba7d5c2560bde18944f57ab7b2bb14e8cf Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 8 Dec 2023 09:55:37 +0200 Subject: [PATCH 60/91] [WIP] Refactor abstract and integration activity managers --- ...irstAndLastIntegrationActivityManager.java | 31 +++++----- .../FirstOnlyIntegrationActivityManager.java | 59 ++++++++++--------- .../LastOnlyIntegrationActivityManager.java | 15 ++--- .../activity/AbstractActivityManager.java | 42 ++++++------- .../transport/activity/ActivityManager.java | 8 +-- 5 files changed, 72 insertions(+), 83 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java index 4a38af1a4d..e0dcc97ac0 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java @@ -70,19 +70,16 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana SettableFuture> reportCompletedFuture = SettableFuture.create(); states.compute(activityKey, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { - ActivityState activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(activityState); - activityStateWrapper.setAlreadyBeenReported(false); - } else { - activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.setState(newStateSupplier.get()); + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastRecordedTime() < newLastRecordedTime) { + activityState.setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override @@ -107,36 +104,36 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}] Failed to report first activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }, MoreExecutors.directExecutor()); } @Override protected void onReportingPeriodEnd() { - long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); var activityState = activityStateWrapper.getState(); - if (activityState.getLastRecordedTime() < expirationTime) { + long lastRecordedTime = activityState.getLastRecordedTime(); + // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks + if (!activityStateWrapper.isAlreadyBeenReported()) { states.remove(activityKey); } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + if (activityState.getLastReportedTime() < lastRecordedTime) { + reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - updateLastReportedTime(key, reportedTime); + public void onSuccess(IntegrationActivityKey key, long newLastReportedTime) { + updateLastReportedTime(key, newLastReportedTime); } @Override public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }); } activityStateWrapper.setAlreadyBeenReported(false); - activityState.getReportsCount().set(0); } } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index b9965098df..38f14f538a 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -70,19 +70,16 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager SettableFuture> reportCompletedFuture = SettableFuture.create(); states.compute(activityKey, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { - ActivityState activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(activityState); - activityStateWrapper.setAlreadyBeenReported(false); - } else { - activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.setState(newStateSupplier.get()); + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastRecordedTime() < newLastRecordedTime) { + activityState.setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override @@ -107,40 +104,46 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}] Failed to report first activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }, MoreExecutors.directExecutor()); } - private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - @Override protected void onReportingPeriodEnd() { for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); var activityState = activityStateWrapper.getState(); - if (!activityStateWrapper.isAlreadyBeenReported() && activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - states.remove(key); - } + long lastRecordedTime = activityState.getLastRecordedTime(); + // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks + if (!activityStateWrapper.isAlreadyBeenReported()) { + states.remove(activityKey); + // report leftover events + if (activityState.getLastReportedTime() < lastRecordedTime) { + reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + updateLastReportedTime(key, reportedTime); // just in case the same key was added again + } - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); - } - }); + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + } + }); + } } activityStateWrapper.setAlreadyBeenReported(false); } } + private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { + states.computeIfPresent(key, (__, activityStateWrapper) -> { + var activityState = activityStateWrapper.getState(); + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityStateWrapper; + }); + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java index bffdc49054..ef6fa4f8b6 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -55,9 +55,8 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< states.compute(activityKey, (__, activityState) -> { if (activityState == null) { activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); - } else { + } + if (activityState.getLastRecordedTime() < newLastRecordedTime) { activityState.setLastRecordedTime(newLastRecordedTime); } return activityState; @@ -70,11 +69,13 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityState = entry.getValue(); - if (activityState.getLastRecordedTime() < expirationTime) { + long lastRecordedTime = activityState.getLastRecordedTime(); + // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks + if (lastRecordedTime < expirationTime) { states.remove(activityKey); } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - reporter.report(activityKey, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + if (activityState.getLastReportedTime() < lastRecordedTime) { + reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -82,7 +83,7 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< @Override public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}]", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 0c7e00816a..4dc84037a8 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -30,7 +30,9 @@ */ package org.thingsboard.server.common.transport.activity; +import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.StringUtils; import java.util.Objects; import java.util.Random; @@ -39,52 +41,44 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +@Slf4j public abstract class AbstractActivityManager implements ActivityManager { private String name; protected long reportingPeriodMillis; protected ActivityStateReporter reporter; private ScheduledExecutorService scheduler; - protected boolean initialized; + private boolean initialized; @Override - public synchronized void init() { - Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); - if (reportingPeriodMillis < 1000) { - throw new IllegalArgumentException("Failed to initialize activity manager: provided reporting period duration is less that 1 second."); + public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter) { + this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); + this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); + if (reportingPeriodMillis <= 0) { + reportingPeriodMillis = 3000; + log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); } + this.reportingPeriodMillis = reportingPeriodMillis; if (!initialized) { - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(name == null ? "activity-manager" : name)); + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(this.name)); scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); initialized = true; } } - @Override - public void setName(String name) { - this.name = name; - } - - @Override - public void setReportingPeriod(long reportingPeriodMillis) { - this.reportingPeriodMillis = reportingPeriodMillis; - } - - @Override - public void setActivityReporter(ActivityStateReporter activityReporter) { - reporter = activityReporter; - } - @Override public void onActivity(Key key, Supplier newStateSupplier) { if (!initialized) { - throw new IllegalStateException(name + " is not initialized."); + log.error("[{}] Failed to process activity event: activity manager is not initialized.", name); + return; } if (key == null) { - throw new IllegalArgumentException("Activity key can't be null."); + log.error("[{}] Failed to process activity event: provided activity key is null.", name); + return; } if (newStateSupplier == null) { - throw new IllegalArgumentException("New activity state supplier can't be null."); + log.error("[{}] Failed to process activity event: provided new activity state supplier is null.", name); + return; } doOnActivity(key, newStateSupplier); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index ba09ccf773..8f006003ef 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -34,13 +34,7 @@ import java.util.function.Supplier; public interface ActivityManager { - void setName(String name); - - void setReportingPeriod(long reportingPeriodMillis); - - void setActivityReporter(ActivityStateReporter activityReporter); - - void init(); + void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter); void onActivity(Key key, Supplier newStateSupplier); From a941deaef9306e8a7c214a2fa3fd23545565be47 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 8 Dec 2023 11:12:24 +0200 Subject: [PATCH 61/91] [WIP] Refactor transport activity managers. Add telemetry TTL for device state. --- .../state/DefaultDeviceStateService.java | 8 +++- .../src/main/resources/thingsboard.yml | 2 + .../service/DefaultTransportService.java | 6 +-- .../FirstAndLastTransportActivityManager.java | 44 ++++++++----------- .../FirstOnlyTransportActivityManager.java | 44 ++++++++----------- .../LastOnlyTransportActivityManager.java | 34 ++++++-------- 6 files changed, 59 insertions(+), 79 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 37070718a3..e010cf3050 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -185,6 +185,10 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService deviceStates = new ConcurrentHashMap<>(); @@ -803,7 +807,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService(deviceId, key, value)); + telemetryTtl, new TelemetrySaveCallback<>(deviceId, key, value)); } else { tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); } @@ -814,7 +818,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService(deviceId, key, value)); + telemetryTtl, new TelemetrySaveCallback<>(deviceId, key, value)); } else { tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 73f0622cd1..16af7b1618 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -785,6 +785,8 @@ state: # If 'persistToTelemetry' is changed from 'false' to 'true': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_ts_view;' # If 'persistToTelemetry' is changed from 'true' to 'false': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view;' persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}" + # Time-to-live for device state telemetry data (e.g. 'active', 'lastActivityTime'). Used only when state.persistToTelemetry is set to 'true'. + telemetryTtl: "${STATE_TELEMETRY_TTL:0}" # Tbel parameters tbel: diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 6453cbd24c..692421b0ab 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -255,11 +255,7 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); - - activityManager.setName("transport-activity-manager"); - activityManager.setReportingPeriod(sessionReportTimeout); - activityManager.setActivityReporter(activityReporter); - activityManager.init(); + activityManager.init("transport-activity-manager", sessionReportTimeout, activityReporter); } private final ActivityStateReporter activityReporter = (sessionId, timeToReport, state, reportCallback) -> { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java index e6bffa4dfd..6370272813 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java @@ -43,14 +43,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.util.Pair; import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -86,19 +87,16 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage SettableFuture> reportCompletedFuture = SettableFuture.create(); states.compute(sessionId, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { - TransportActivityState activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(activityState); - activityStateWrapper.setAlreadyBeenReported(false); - } else { - activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.setState(newStateSupplier.get()); + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastRecordedTime() < newLastRecordedTime) { + activityState.setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override @@ -123,14 +121,14 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period for session.", sessionId); + log.debug("[{}] Failed to report first activity event in a period.", sessionId); } }, MoreExecutors.directExecutor()); } @Override protected void onReportingPeriodEnd() { - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; + Set statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -140,7 +138,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage if (sessionMetaData != null) { activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); } else { - states.remove(sessionId); + statesToRemove.add(sessionId); } long lastActivityTime = activityState.getLastRecordedTime(); @@ -157,25 +155,18 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage } } + long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; if (hasExpired) { if (log.isDebugEnabled()) { - log.debug("[{}] Session has expired due to last activity time: [{}]!", sessionId, lastActivityTime); + log.debug("[{}] Session has expired due to last activity time: [{}].", sessionId, lastActivityTime); } + statesToRemove.add(sessionId); transportService.deregisterSession(sessionInfo); - transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - states.remove(sessionId); - } - - @Override - public void onError(Throwable e) { - states.remove(sessionId); - } - }); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } else if (activityState.getLastReportedTime() < lastActivityTime) { + } + if (activityState.getLastReportedTime() < lastActivityTime) { reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -184,12 +175,13 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override public void onFailure(UUID key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for session.", sessionId); + log.debug("[{}] Failed to report last activity event in a period.", sessionId); } }); } activityStateWrapper.setAlreadyBeenReported(false); } + statesToRemove.forEach(states::remove); } private void updateLastReportedTime(UUID key, long newLastReportedTime) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java index 8cefbb0b46..768796b2be 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java @@ -43,14 +43,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.util.Pair; import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -86,19 +87,16 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager> reportCompletedFuture = SettableFuture.create(); states.compute(sessionId, (key, activityStateWrapper) -> { if (activityStateWrapper == null) { - TransportActivityState activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(activityState); - activityStateWrapper.setAlreadyBeenReported(false); - } else { - activityStateWrapper.getState().setLastRecordedTime(newLastRecordedTime); + activityStateWrapper.setState(newStateSupplier.get()); + } + var activityState = activityStateWrapper.getState(); + if (activityState.getLastRecordedTime() < newLastRecordedTime) { + activityState.setLastRecordedTime(newLastRecordedTime); } if (activityStateWrapper.isAlreadyBeenReported()) { return activityStateWrapper; } - var activityState = activityStateWrapper.getState(); if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override @@ -123,14 +121,14 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -140,7 +138,7 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager() { - @Override - public void onSuccess(Void msgAcknowledged) { - states.remove(sessionId); - } - - @Override - public void onError(Throwable e) { - states.remove(sessionId); - } - }); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); } - if ((sessionMetaData == null || hasExpired) && activityState.getLastReportedTime() < lastActivityTime) { + boolean shouldReportLeftoverEvents = sessionMetaData == null || hasExpired; + if (shouldReportLeftoverEvents && activityState.getLastReportedTime() < lastActivityTime) { reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -185,12 +176,13 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager { if (activityState == null) { activityState = newStateSupplier.get(); - activityState.setLastRecordedTime(newLastRecordedTime); - activityState.setLastReportedTime(0L); - } else { + } + if (activityState.getLastRecordedTime() < newLastRecordedTime) { activityState.setLastRecordedTime(newLastRecordedTime); } return activityState; @@ -82,7 +82,7 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityState = entry.getValue(); @@ -91,7 +91,7 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager() { - @Override - public void onSuccess(Void msgAcknowledged) { - states.remove(sessionId); - } - - @Override - public void onError(Throwable e) { - states.remove(sessionId); - } - }); + transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } else if (activityState.getLastReportedTime() < lastActivityTime) { + } + if (activityState.getLastReportedTime() < lastActivityTime) { reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -135,11 +128,12 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager Date: Fri, 8 Dec 2023 12:32:13 +0200 Subject: [PATCH 62/91] Add logging --- ...irstAndLastIntegrationActivityManager.java | 13 +++++++--- .../FirstOnlyIntegrationActivityManager.java | 13 +++++++--- .../LastOnlyIntegrationActivityManager.java | 7 +++-- .../activity/AbstractActivityManager.java | 26 ++++++++++++------- .../service/DefaultTransportService.java | 4 ++- .../FirstAndLastTransportActivityManager.java | 14 +++++----- .../FirstOnlyTransportActivityManager.java | 14 +++++----- .../LastOnlyTransportActivityManager.java | 11 ++++---- 8 files changed, 67 insertions(+), 35 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java index e0dcc97ac0..c9d05eaa26 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java @@ -81,6 +81,8 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana return activityStateWrapper; } if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + log.debug("[{}][{}] Going to report first activity event for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { @@ -104,13 +106,14 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}][{}] Failed to report first activity event for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); } }, MoreExecutors.directExecutor()); } @Override - protected void onReportingPeriodEnd() { + protected void doOnReportingPeriodEnd() { for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -118,9 +121,12 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana long lastRecordedTime = activityState.getLastRecordedTime(); // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks if (!activityStateWrapper.isAlreadyBeenReported()) { + log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); states.remove(activityKey); } if (activityState.getLastReportedTime() < lastRecordedTime) { + log.debug("[{}][{}] Going to report last activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long newLastReportedTime) { @@ -129,7 +135,8 @@ public class FirstAndLastIntegrationActivityManager extends AbstractActivityMana @Override public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); } }); } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index 38f14f538a..35567847a5 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -81,6 +81,8 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager return activityStateWrapper; } if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + log.debug("[{}][{}] Going to report first activity event for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { @@ -104,13 +106,14 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}][{}] Failed to report activity event for device with id: [{}].", + name, activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }, MoreExecutors.directExecutor()); } @Override - protected void onReportingPeriodEnd() { + protected void doOnReportingPeriodEnd() { for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -118,9 +121,12 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager long lastRecordedTime = activityState.getLastRecordedTime(); // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks if (!activityStateWrapper.isAlreadyBeenReported()) { + log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); states.remove(activityKey); // report leftover events if (activityState.getLastReportedTime() < lastRecordedTime) { + log.debug("[{}][{}] Going to report leftover activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(IntegrationActivityKey key, long reportedTime) { @@ -129,7 +135,8 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager @Override public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); } }); } diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java index ef6fa4f8b6..6517a1af2a 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -64,7 +64,7 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< } @Override - public void onReportingPeriodEnd() { + public void doOnReportingPeriodEnd() { long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); @@ -72,6 +72,8 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< long lastRecordedTime = activityState.getLastRecordedTime(); // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks if (lastRecordedTime < expirationTime) { + log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); states.remove(activityKey); } if (activityState.getLastReportedTime() < lastRecordedTime) { @@ -83,7 +85,8 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< @Override public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for device with id: [{}].", activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); } }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 4dc84037a8..9d7b5c4e19 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -44,7 +44,7 @@ import java.util.function.Supplier; @Slf4j public abstract class AbstractActivityManager implements ActivityManager { - private String name; + protected String name; protected long reportingPeriodMillis; protected ActivityStateReporter reporter; private ScheduledExecutorService scheduler; @@ -52,17 +52,19 @@ public abstract class AbstractActivityManager @Override public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter) { - this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); - this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); - if (reportingPeriodMillis <= 0) { - reportingPeriodMillis = 3000; - log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); - } - this.reportingPeriodMillis = reportingPeriodMillis; if (!initialized) { + log.info("[{}] initializing.", this.name); + this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); + this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); + if (reportingPeriodMillis <= 0) { + reportingPeriodMillis = 3000; + log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); + } + this.reportingPeriodMillis = reportingPeriodMillis; scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(this.name)); scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); initialized = true; + log.info("[{}] initialized.", this.name); } } @@ -80,12 +82,18 @@ public abstract class AbstractActivityManager log.error("[{}] Failed to process activity event: provided new activity state supplier is null.", name); return; } + log.debug("[{}] Received activity event for key: [{}]", name, key); doOnActivity(key, newStateSupplier); } protected abstract void doOnActivity(Key key, Supplier newStateSupplier); - protected abstract void onReportingPeriodEnd(); + private void onReportingPeriodEnd() { + log.debug("[{}] Going to end reporting period.", name); + doOnReportingPeriodEnd(); + } + + protected abstract void doOnReportingPeriodEnd(); @Override public synchronized void destroy() { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 692421b0ab..d2fa8ad8ca 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -187,6 +187,7 @@ public class DefaultTransportService implements TransportService { private final NotificationRuleProcessor notificationRuleProcessor; private final EntityLimitsCache entityLimitsCache; private ActivityManager activityManager; + private static final String ACTIVITY_MANAGER_NAME = "transport-activity-manager"; protected TbQueueRequestTemplate, TbProtoQueueMsg> transportApiRequestTemplate; protected TbQueueProducer> ruleEngineMsgProducer; @@ -255,10 +256,11 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); - activityManager.init("transport-activity-manager", sessionReportTimeout, activityReporter); + activityManager.init(ACTIVITY_MANAGER_NAME, sessionReportTimeout, activityReporter); } private final ActivityStateReporter activityReporter = (sessionId, timeToReport, state, reportCallback) -> { + log.debug("[{}] Reporting activity state for key: [{}]. Time to report: [{}].", ACTIVITY_MANAGER_NAME, sessionId, timeToReport); SessionMetaData sessionMetaData = sessions.get(sessionId); TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java index 6370272813..db0ebc7ddb 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java @@ -98,6 +98,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage return activityStateWrapper; } if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + log.debug("[{}] Going to report first activity event for session with id: [{}]", name, sessionId); reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -121,13 +122,13 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event in a period.", sessionId); + log.debug("[{}] Failed to report first activity event for session with id: [{}]", name, sessionId); } }, MoreExecutors.directExecutor()); } @Override - protected void onReportingPeriodEnd() { + protected void doOnReportingPeriodEnd() { Set statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); @@ -138,6 +139,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage if (sessionMetaData != null) { activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); } else { + log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); statesToRemove.add(sessionId); } @@ -150,6 +152,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { ActivityStateWrapper gwActivityStateWrapper = states.get(gwSessionId); if (gwActivityStateWrapper != null) { + log.debug("[{}] Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. Updating last activity time.", name, sessionId, gwSessionId); lastActivityTime = Math.max(gwActivityStateWrapper.getState().getLastRecordedTime(), lastActivityTime); } } @@ -158,15 +161,14 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; if (hasExpired) { - if (log.isDebugEnabled()) { - log.debug("[{}] Session has expired due to last activity time: [{}].", sessionId, lastActivityTime); - } + log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); statesToRemove.add(sessionId); transportService.deregisterSession(sessionInfo); transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); } if (activityState.getLastReportedTime() < lastActivityTime) { + log.debug("[{}] Going to report last activity event for session with id: [{}].", name, sessionId); reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -175,7 +177,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override public void onFailure(UUID key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period.", sessionId); + log.debug("[{}] Failed to report last activity event for session with id: [{}].", name, sessionId); } }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java index 768796b2be..b0762e0b5e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java @@ -98,6 +98,7 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -121,13 +122,13 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); @@ -138,6 +139,7 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -176,7 +178,7 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); @@ -91,6 +91,7 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager() { @Override public void onSuccess(UUID key, long reportedTime) { @@ -128,7 +129,7 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager Date: Fri, 8 Dec 2023 13:33:49 +0200 Subject: [PATCH 63/91] Change transport reporting strategy to be backward compatible --- application/src/main/resources/thingsboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 16af7b1618..e25d2ce3ba 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -874,7 +874,7 @@ transport: # - 'first': Only the first activity event in each reporting period is reported. # - 'last': Only the last activity event in the reporting period is reported. # - 'first-and-last': Both the first and last activity events in the reporting period are reported. - reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:first-and-last}" + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:last}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" From 84c22dc4a3050dd35662bb0146b39a18c8ac44de Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 8 Dec 2023 13:53:29 +0200 Subject: [PATCH 64/91] Add 'all' reporting strategy for integrations --- .../AllIntegrationActivityManager.java | 122 ++++++++++++++++++ .../FirstOnlyIntegrationActivityManager.java | 2 +- .../LastOnlyIntegrationActivityManager.java | 2 +- .../src/main/resources/thingsboard.yml | 3 +- 4 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java new file mode 100644 index 0000000000..de9b132896 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java @@ -0,0 +1,122 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.integration.activity; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityState; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; + +@Slf4j +@Component +@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "all") +public class AllIntegrationActivityManager extends AbstractActivityManager { + + private final ConcurrentMap states = new ConcurrentHashMap<>(); + + @Override + protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + SettableFuture> reportCompletedFuture = SettableFuture.create(); + states.compute(activityKey, (key, activityState) -> { + if (activityState == null) { + activityState = newStateSupplier.get(); + } + if (activityState.getLastRecordedTime() < newLastRecordedTime) { + activityState.setLastRecordedTime(newLastRecordedTime); + } + if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { + log.debug("[{}][{}] Going to report activity event for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + reportCompletedFuture.set(Pair.of(key, reportedTime)); + } + + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + reportCompletedFuture.setException(t); + } + }); + } + return activityState; + }); + Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { + @Override + public void onSuccess(Pair reportResult) { + updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); + } + + @Override + public void onFailure(@NonNull Throwable t) { + log.debug("[{}][{}] Failed to report activity event for device with id: [{}].", + name, activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); + } + }, MoreExecutors.directExecutor()); + } + + private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { + states.computeIfPresent(key, (__, activityState) -> { + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityState; + }); + } + + @Override + protected void doOnReportingPeriodEnd() { + for (Map.Entry entry : states.entrySet()) { + var activityKey = entry.getKey(); + var activityState = entry.getValue(); + // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks + long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; + if (activityState.getLastRecordedTime() < expirationTime) { + log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); + states.remove(activityKey); + } + } + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index 35567847a5..239fd5f19e 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -106,7 +106,7 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager @Override public void onFailure(@NonNull Throwable t) { - log.debug("[{}][{}] Failed to report activity event for device with id: [{}].", + log.debug("[{}][{}] Failed to report first activity event for device with id: [{}].", name, activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); } }, MoreExecutors.directExecutor()); diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java index 6517a1af2a..f29b81baf8 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -65,12 +65,12 @@ public class LastOnlyIntegrationActivityManager extends AbstractActivityManager< @Override public void doOnReportingPeriodEnd() { - long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; for (Map.Entry entry : states.entrySet()) { var activityKey = entry.getKey(); var activityState = entry.getValue(); long lastRecordedTime = activityState.getLastRecordedTime(); // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks + long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; if (lastRecordedTime < expirationTime) { log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index e25d2ce3ba..7baf6dbf9b 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -874,7 +874,8 @@ transport: # - 'first': Only the first activity event in each reporting period is reported. # - 'last': Only the last activity event in the reporting period is reported. # - 'first-and-last': Both the first and last activity events in the reporting period are reported. - reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:last}" + # - 'all': All activity events in the reporting period are reported. + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:all}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" From 64ccad0ed2b0f100a90618f7f145a506e3c428ca Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 8 Dec 2023 14:00:36 +0200 Subject: [PATCH 65/91] Fix typo --- application/src/main/resources/thingsboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 7baf6dbf9b..b47219c89a 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -875,7 +875,7 @@ transport: # - 'last': Only the last activity event in the reporting period is reported. # - 'first-and-last': Both the first and last activity events in the reporting period are reported. # - 'all': All activity events in the reporting period are reported. - reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:all}" + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:first-and-last}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" From 8b3ad49ed82bbb6a3726f98a9be7b08387981830 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 8 Dec 2023 14:01:40 +0200 Subject: [PATCH 66/91] Change default reporting strategy for transports to last to be backward compatible --- application/src/main/resources/thingsboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index b47219c89a..be52ee1f0d 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -875,7 +875,7 @@ transport: # - 'last': Only the last activity event in the reporting period is reported. # - 'first-and-last': Both the first and last activity events in the reporting period are reported. # - 'all': All activity events in the reporting period are reported. - reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:first-and-last}" + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:last}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" From 6d15bf82df25d1a12d3a120601eed60c6729098b Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Sat, 9 Dec 2023 10:05:06 +0200 Subject: [PATCH 67/91] Polishing after review --- .../FirstOnlyIntegrationActivityManager.java | 42 ++++++++++--------- .../src/main/resources/thingsboard.yml | 7 ++-- .../service/DefaultTransportService.java | 4 +- .../FirstAndLastTransportActivityManager.java | 12 ++---- .../FirstOnlyTransportActivityManager.java | 12 ++---- .../LastOnlyTransportActivityManager.java | 12 ++---- 6 files changed, 40 insertions(+), 49 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index 239fd5f19e..ae03c1fb94 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -115,31 +115,33 @@ public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager @Override protected void doOnReportingPeriodEnd() { for (Map.Entry entry : states.entrySet()) { - var activityKey = entry.getKey(); var activityStateWrapper = entry.getValue(); + if (activityStateWrapper.isAlreadyBeenReported()) { + activityStateWrapper.setAlreadyBeenReported(false); + continue; + } + var activityKey = entry.getKey(); var activityState = activityStateWrapper.getState(); long lastRecordedTime = activityState.getLastRecordedTime(); // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks - if (!activityStateWrapper.isAlreadyBeenReported()) { - log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - states.remove(activityKey); - // report leftover events - if (activityState.getLastReportedTime() < lastRecordedTime) { - log.debug("[{}][{}] Going to report leftover activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - updateLastReportedTime(key, reportedTime); // just in case the same key was added again - } + log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); + states.remove(activityKey); + // report leftover events + if (activityState.getLastReportedTime() < lastRecordedTime) { + log.debug("[{}][{}] Going to report leftover activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); + reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(IntegrationActivityKey key, long reportedTime) { + updateLastReportedTime(key, reportedTime); // just in case the same key was added again + } - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - } - }); - } + @Override + public void onFailure(IntegrationActivityKey key, Throwable t) { + log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", + activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); + } + }); } activityStateWrapper.setAlreadyBeenReported(false); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index be52ee1f0d..57e55f4eda 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -785,7 +785,9 @@ state: # If 'persistToTelemetry' is changed from 'false' to 'true': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_ts_view;' # If 'persistToTelemetry' is changed from 'true' to 'false': 'CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view;' persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}" - # Time-to-live for device state telemetry data (e.g. 'active', 'lastActivityTime'). Used only when state.persistToTelemetry is set to 'true'. + # Millisecond value defining time-to-live for device state telemetry data (e.g. 'active', 'lastActivityTime'). + # Used only when state.persistToTelemetry is set to 'true' and Cassandra is used for timeseries data. + # 0 means time-to-live mechanism is disabled. telemetryTtl: "${STATE_TELEMETRY_TTL:0}" # Tbel parameters @@ -870,11 +872,10 @@ transport: report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:3000}" activity: # This property specifies the strategy for reporting activity events within each reporting period. - # The accepted values are 'first', 'last', and 'first and last'. + # The accepted values are 'first', 'last', and 'first-and-last'. # - 'first': Only the first activity event in each reporting period is reported. # - 'last': Only the last activity event in the reporting period is reported. # - 'first-and-last': Both the first and last activity events in the reporting period are reported. - # - 'all': All activity events in the reporting period are reported. reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:last}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index d2fa8ad8ca..a86bdda312 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -136,6 +136,7 @@ public class DefaultTransportService implements TransportService { public static final String OVERWRITE_ACTIVITY_TIME = "overwriteActivityTime"; public static final String SESSION_EXPIRED_MESSAGE = "Session has expired due to last activity time!"; + private static final String ACTIVITY_MANAGER_NAME = "transport-activity-manager"; public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_OPEN = getSessionEventMsg(TransportProtos.SessionEvent.OPEN); public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_CLOSED = getSessionEventMsg(TransportProtos.SessionEvent.CLOSED); public static final TransportProtos.SessionCloseNotificationProto SESSION_EXPIRED_NOTIFICATION_PROTO = TransportProtos.SessionCloseNotificationProto.newBuilder() @@ -187,7 +188,6 @@ public class DefaultTransportService implements TransportService { private final NotificationRuleProcessor notificationRuleProcessor; private final EntityLimitsCache entityLimitsCache; private ActivityManager activityManager; - private static final String ACTIVITY_MANAGER_NAME = "transport-activity-manager"; protected TbQueueRequestTemplate, TbProtoQueueMsg> transportApiRequestTemplate; protected TbQueueProducer> ruleEngineMsgProducer; @@ -260,7 +260,7 @@ public class DefaultTransportService implements TransportService { } private final ActivityStateReporter activityReporter = (sessionId, timeToReport, state, reportCallback) -> { - log.debug("[{}] Reporting activity state for key: [{}]. Time to report: [{}].", ACTIVITY_MANAGER_NAME, sessionId, timeToReport); + log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", ACTIVITY_MANAGER_NAME, sessionId, timeToReport); SessionMetaData sessionMetaData = sessions.get(sessionId); TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java index db0ebc7ddb..f14d958307 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java @@ -49,9 +49,7 @@ import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -129,7 +127,6 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override protected void doOnReportingPeriodEnd() { - Set statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -139,8 +136,8 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage if (sessionMetaData != null) { activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); } else { - log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); - statesToRemove.add(sessionId); + log.debug("[{}] Session with id: [{}] is not present. Removing it's activity state.", name, sessionId); + states.remove(sessionId); } long lastActivityTime = activityState.getLastRecordedTime(); @@ -161,8 +158,8 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; if (hasExpired) { - log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); - statesToRemove.add(sessionId); + log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Removing it's activity state.", name, sessionId, lastActivityTime); + states.remove(sessionId); transportService.deregisterSession(sessionInfo); transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); @@ -183,7 +180,6 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage } activityStateWrapper.setAlreadyBeenReported(false); } - statesToRemove.forEach(states::remove); } private void updateLastReportedTime(UUID key, long newLastReportedTime) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java index b0762e0b5e..34378caeb6 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java @@ -49,9 +49,7 @@ import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -129,7 +127,6 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -139,8 +136,8 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityState = entry.getValue(); @@ -91,8 +88,8 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager Date: Sat, 9 Dec 2023 10:10:50 +0200 Subject: [PATCH 68/91] Add @TbCoreComponent and @TbTransportComponent --- .../integration/activity/AllIntegrationActivityManager.java | 2 ++ .../activity/FirstAndLastIntegrationActivityManager.java | 2 ++ .../activity/FirstOnlyIntegrationActivityManager.java | 2 ++ .../activity/LastOnlyIntegrationActivityManager.java | 2 ++ .../service/activity/FirstAndLastTransportActivityManager.java | 2 ++ .../service/activity/FirstOnlyTransportActivityManager.java | 2 ++ .../service/activity/LastOnlyTransportActivityManager.java | 2 ++ 7 files changed, 14 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java index de9b132896..5cb8d1ea38 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java @@ -42,6 +42,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -50,6 +51,7 @@ import java.util.function.Supplier; @Slf4j @Component +@TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "all") public class AllIntegrationActivityManager extends AbstractActivityManager { diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java index c9d05eaa26..785e6f4155 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java @@ -43,6 +43,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -51,6 +52,7 @@ import java.util.function.Supplier; @Slf4j @Component +@TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first-and-last") public class FirstAndLastIntegrationActivityManager extends AbstractActivityManager { diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java index ae03c1fb94..d99745af0a 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java @@ -43,6 +43,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -51,6 +52,7 @@ import java.util.function.Supplier; @Slf4j @Component +@TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first") public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager { diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java index f29b81baf8..c90b4f86e5 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java @@ -36,6 +36,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -44,6 +45,7 @@ import java.util.function.Supplier; @Slf4j @Component +@TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "last") public class LastOnlyIntegrationActivityManager extends AbstractActivityManager { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java index f14d958307..2cc17a532e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java @@ -48,6 +48,7 @@ import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.TbTransportComponent; import java.util.Map; import java.util.UUID; @@ -60,6 +61,7 @@ import static org.thingsboard.server.common.transport.service.DefaultTransportSe @Slf4j @Component +@TbTransportComponent @ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first-and-last") public class FirstAndLastTransportActivityManager extends AbstractActivityManager { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java index 34378caeb6..82d6fcccc8 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java @@ -48,6 +48,7 @@ import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.TbTransportComponent; import java.util.Map; import java.util.UUID; @@ -60,6 +61,7 @@ import static org.thingsboard.server.common.transport.service.DefaultTransportSe @Slf4j @Component +@TbTransportComponent @ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first") public class FirstOnlyTransportActivityManager extends AbstractActivityManager { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java index 056ace10b5..85db15b1ec 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/LastOnlyTransportActivityManager.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.TbTransportComponent; import java.util.Map; import java.util.UUID; @@ -53,6 +54,7 @@ import static org.thingsboard.server.common.transport.service.DefaultTransportSe @Slf4j @Component +@TbTransportComponent @ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "last") public class LastOnlyTransportActivityManager extends AbstractActivityManager { From cfdceb9ae005a0e191618e0245bdb32d8191f239 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Mon, 11 Dec 2023 13:15:47 +0200 Subject: [PATCH 69/91] Change activity manager names, remove activity after iteration on period end --- ...> AllEventsIntegrationActivityManager.java} | 2 +- ...dLastEventsIntegrationActivityManager.java} | 2 +- ...stEventOnlyIntegrationActivityManager.java} | 2 +- ...stEventOnlyIntegrationActivityManager.java} | 2 +- .../activity/AbstractActivityManager.java | 2 +- ...tAndLastEventTransportActivityManager.java} | 14 +++++++++----- ...nlyFirstEventTransportActivityManager.java} | 14 +++++++++----- ...OnlyLastEventTransportActivityManager.java} | 18 +++++++++++------- 8 files changed, 34 insertions(+), 22 deletions(-) rename application/src/main/java/org/thingsboard/server/service/integration/activity/{AllIntegrationActivityManager.java => AllEventsIntegrationActivityManager.java} (98%) rename application/src/main/java/org/thingsboard/server/service/integration/activity/{FirstAndLastIntegrationActivityManager.java => FirstAndLastEventsIntegrationActivityManager.java} (98%) rename application/src/main/java/org/thingsboard/server/service/integration/activity/{FirstOnlyIntegrationActivityManager.java => FirstEventOnlyIntegrationActivityManager.java} (98%) rename application/src/main/java/org/thingsboard/server/service/integration/activity/{LastOnlyIntegrationActivityManager.java => LastEventOnlyIntegrationActivityManager.java} (97%) rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/{FirstAndLastTransportActivityManager.java => FirstAndLastEventTransportActivityManager.java} (94%) rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/{FirstOnlyTransportActivityManager.java => OnlyFirstEventTransportActivityManager.java} (94%) rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/{LastOnlyTransportActivityManager.java => OnlyLastEventTransportActivityManager.java} (90%) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java rename to application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java index 5cb8d1ea38..f2edb20a7f 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java @@ -53,7 +53,7 @@ import java.util.function.Supplier; @Component @TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "all") -public class AllIntegrationActivityManager extends AbstractActivityManager { +public class AllEventsIntegrationActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java rename to application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java index 785e6f4155..1c2dba809e 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java @@ -54,7 +54,7 @@ import java.util.function.Supplier; @Component @TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first-and-last") -public class FirstAndLastIntegrationActivityManager extends AbstractActivityManager { +public class FirstAndLastEventsIntegrationActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java rename to application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java index d99745af0a..24f9a8f388 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java @@ -54,7 +54,7 @@ import java.util.function.Supplier; @Component @TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first") -public class FirstOnlyIntegrationActivityManager extends AbstractActivityManager { +public class FirstEventOnlyIntegrationActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java similarity index 97% rename from application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java rename to application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java index c90b4f86e5..16699b2e3c 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastOnlyIntegrationActivityManager.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java @@ -47,7 +47,7 @@ import java.util.function.Supplier; @Component @TbCoreComponent @ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "last") -public class LastOnlyIntegrationActivityManager extends AbstractActivityManager { +public class LastEventOnlyIntegrationActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 9d7b5c4e19..dd8682aaed 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -53,8 +53,8 @@ public abstract class AbstractActivityManager @Override public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter) { if (!initialized) { - log.info("[{}] initializing.", this.name); this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); + log.info("[{}] initializing.", this.name); this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); if (reportingPeriodMillis <= 0) { reportingPeriodMillis = 3000; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java similarity index 94% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java index 2cc17a532e..9c582b2587 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java @@ -50,7 +50,9 @@ import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbTransportComponent; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -63,7 +65,7 @@ import static org.thingsboard.server.common.transport.service.DefaultTransportSe @Component @TbTransportComponent @ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first-and-last") -public class FirstAndLastTransportActivityManager extends AbstractActivityManager { +public class FirstAndLastEventTransportActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); @@ -129,6 +131,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage @Override protected void doOnReportingPeriodEnd() { + Set statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -138,8 +141,8 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage if (sessionMetaData != null) { activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); } else { - log.debug("[{}] Session with id: [{}] is not present. Removing it's activity state.", name, sessionId); - states.remove(sessionId); + log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); + statesToRemove.add(sessionId); } long lastActivityTime = activityState.getLastRecordedTime(); @@ -160,9 +163,9 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; if (hasExpired) { - log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Removing it's activity state.", name, sessionId, lastActivityTime); - states.remove(sessionId); + log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); transportService.deregisterSession(sessionInfo); + statesToRemove.add(sessionId); transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); } @@ -182,6 +185,7 @@ public class FirstAndLastTransportActivityManager extends AbstractActivityManage } activityStateWrapper.setAlreadyBeenReported(false); } + statesToRemove.forEach(states::remove); } private void updateLastReportedTime(UUID key, long newLastReportedTime) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java similarity index 94% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java index 82d6fcccc8..19a6314450 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstOnlyTransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java @@ -50,7 +50,9 @@ import org.thingsboard.server.common.transport.service.TransportActivityState; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbTransportComponent; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -63,7 +65,7 @@ import static org.thingsboard.server.common.transport.service.DefaultTransportSe @Component @TbTransportComponent @ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first") -public class FirstOnlyTransportActivityManager extends AbstractActivityManager { +public class OnlyFirstEventTransportActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); @@ -129,6 +131,7 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityStateWrapper = entry.getValue(); @@ -138,8 +141,8 @@ public class FirstOnlyTransportActivityManager extends AbstractActivityManager { +public class OnlyLastEventTransportActivityManager extends AbstractActivityManager { private final ConcurrentMap states = new ConcurrentHashMap<>(); @@ -67,9 +69,9 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager newStateSupplier) { + protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); - states.compute(activityKey, (__, activityState) -> { + states.compute(sessionId, (__, activityState) -> { if (activityState == null) { activityState = newStateSupplier.get(); } @@ -82,6 +84,7 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager statesToRemove = new HashSet<>(); for (Map.Entry entry : states.entrySet()) { var sessionId = entry.getKey(); var activityState = entry.getValue(); @@ -90,8 +93,8 @@ public class LastOnlyTransportActivityManager extends AbstractActivityManager Date: Thu, 14 Dec 2023 23:14:44 +0200 Subject: [PATCH 70/91] [WIP] Refactoring after review --- .../AllEventsIntegrationActivityManager.java | 124 -------------- ...dLastEventsIntegrationActivityManager.java | 157 ----------------- ...stEventOnlyIntegrationActivityManager.java | 160 ------------------ ...stEventOnlyIntegrationActivityManager.java | 105 ------------ .../src/main/resources/thingsboard.yml | 13 +- .../activity/AbstractActivityManager.java | 103 +++++++++-- .../transport/activity/ActivityManager.java | 16 +- .../transport/activity/ActivityState.java | 5 +- .../activity/strategy/ActivityStrategy.java | 11 ++ .../strategy/ActivityStrategyType.java | 20 +++ .../strategy/AllEventsActivityStrategy.java | 17 ++ .../FirstAndLastEventActivityStrategy.java | 25 +++ .../strategy/FirstEventActivityStrategy.java | 25 +++ .../strategy/LastEventActivityStrategy.java | 17 ++ 14 files changed, 223 insertions(+), 575 deletions(-) delete mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java delete mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java delete mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java delete mode 100644 application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java deleted file mode 100644 index f2edb20a7f..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/AllEventsIntegrationActivityManager.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.queue.util.TbCoreComponent; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -@Slf4j -@Component -@TbCoreComponent -@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "all") -public class AllEventsIntegrationActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Override - protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - states.compute(activityKey, (key, activityState) -> { - if (activityState == null) { - activityState = newStateSupplier.get(); - } - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - log.debug("[{}][{}] Going to report activity event for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - reportCompletedFuture.setException(t); - } - }); - } - return activityState; - }); - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } - - @Override - public void onFailure(@NonNull Throwable t) { - log.debug("[{}][{}] Failed to report activity event for device with id: [{}].", - name, activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); - } - }, MoreExecutors.directExecutor()); - } - - private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityState) -> { - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityState; - }); - } - - @Override - protected void doOnReportingPeriodEnd() { - for (Map.Entry entry : states.entrySet()) { - var activityKey = entry.getKey(); - var activityState = entry.getValue(); - // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks - long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; - if (activityState.getLastRecordedTime() < expirationTime) { - log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - states.remove(activityKey); - } - } - } - -} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java deleted file mode 100644 index 1c2dba809e..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstAndLastEventsIntegrationActivityManager.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.queue.util.TbCoreComponent; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -@Slf4j -@Component -@TbCoreComponent -@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first-and-last") -public class FirstAndLastEventsIntegrationActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Data - private static class ActivityStateWrapper { - - volatile ActivityState state; - volatile boolean alreadyBeenReported; - - } - - @Override - protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - states.compute(activityKey, (key, activityStateWrapper) -> { - if (activityStateWrapper == null) { - activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(newStateSupplier.get()); - } - var activityState = activityStateWrapper.getState(); - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - if (activityStateWrapper.isAlreadyBeenReported()) { - return activityStateWrapper; - } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - log.debug("[{}][{}] Going to report first activity event for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - reportCompletedFuture.setException(t); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(true); - return activityStateWrapper; - }); - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } - - @Override - public void onFailure(@NonNull Throwable t) { - log.debug("[{}][{}] Failed to report first activity event for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - } - }, MoreExecutors.directExecutor()); - } - - @Override - protected void doOnReportingPeriodEnd() { - for (Map.Entry entry : states.entrySet()) { - var activityKey = entry.getKey(); - var activityStateWrapper = entry.getValue(); - var activityState = activityStateWrapper.getState(); - long lastRecordedTime = activityState.getLastRecordedTime(); - // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks - if (!activityStateWrapper.isAlreadyBeenReported()) { - log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - states.remove(activityKey); - } - if (activityState.getLastReportedTime() < lastRecordedTime) { - log.debug("[{}][{}] Going to report last activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long newLastReportedTime) { - updateLastReportedTime(key, newLastReportedTime); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(false); - } - } - - private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - -} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java deleted file mode 100644 index 24f9a8f388..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/FirstEventOnlyIntegrationActivityManager.java +++ /dev/null @@ -1,160 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.queue.util.TbCoreComponent; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -@Slf4j -@Component -@TbCoreComponent -@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "first") -public class FirstEventOnlyIntegrationActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Data - private static class ActivityStateWrapper { - - volatile ActivityState state; - volatile boolean alreadyBeenReported; - - } - - @Override - protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - states.compute(activityKey, (key, activityStateWrapper) -> { - if (activityStateWrapper == null) { - activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(newStateSupplier.get()); - } - var activityState = activityStateWrapper.getState(); - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - if (activityStateWrapper.isAlreadyBeenReported()) { - return activityStateWrapper; - } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - log.debug("[{}][{}] Going to report first activity event for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - reportCompletedFuture.setException(t); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(true); - return activityStateWrapper; - }); - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } - - @Override - public void onFailure(@NonNull Throwable t) { - log.debug("[{}][{}] Failed to report first activity event for device with id: [{}].", - name, activityKey.getTenantId().getId(), activityKey.getDeviceId().getId()); - } - }, MoreExecutors.directExecutor()); - } - - @Override - protected void doOnReportingPeriodEnd() { - for (Map.Entry entry : states.entrySet()) { - var activityStateWrapper = entry.getValue(); - if (activityStateWrapper.isAlreadyBeenReported()) { - activityStateWrapper.setAlreadyBeenReported(false); - continue; - } - var activityKey = entry.getKey(); - var activityState = activityStateWrapper.getState(); - long lastRecordedTime = activityState.getLastRecordedTime(); - // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks - log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - states.remove(activityKey); - // report leftover events - if (activityState.getLastReportedTime() < lastRecordedTime) { - log.debug("[{}][{}] Going to report leftover activity event for device with id: [{}].", activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - updateLastReportedTime(key, reportedTime); // just in case the same key was added again - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(false); - } - } - - private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - -} diff --git a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java b/application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java deleted file mode 100644 index 16699b2e3c..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/integration/activity/LastEventOnlyIntegrationActivityManager.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration.activity; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.queue.util.TbCoreComponent; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -@Slf4j -@Component -@TbCoreComponent -@ConditionalOnProperty(prefix = "integrations.activity", value = "reporting_strategy", havingValue = "last") -public class LastEventOnlyIntegrationActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Override - protected void doOnActivity(IntegrationActivityKey activityKey, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - states.compute(activityKey, (__, activityState) -> { - if (activityState == null) { - activityState = newStateSupplier.get(); - } - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - return activityState; - }); - } - - @Override - public void doOnReportingPeriodEnd() { - for (Map.Entry entry : states.entrySet()) { - var activityKey = entry.getKey(); - var activityState = entry.getValue(); - long lastRecordedTime = activityState.getLastRecordedTime(); - // if there were no activities during the reporting period, we should remove the entry to prevent memory leaks - long expirationTime = System.currentTimeMillis() - reportingPeriodMillis; - if (lastRecordedTime < expirationTime) { - log.debug("[{}][{}] No activity events were received during reporting period for device with id: [{}]. Going to remove activity state.", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - states.remove(activityKey); - } - if (activityState.getLastReportedTime() < lastRecordedTime) { - reporter.report(activityKey, lastRecordedTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(IntegrationActivityKey key, long reportedTime) { - updateLastReportedTime(key, reportedTime); - } - - @Override - public void onFailure(IntegrationActivityKey key, Throwable t) { - log.debug("[{}][{}] Failed to report last activity event in a period for device with id: [{}].", - activityKey.getTenantId().getId(), name, activityKey.getDeviceId().getId()); - } - }); - } - } - } - - private void updateLastReportedTime(IntegrationActivityKey key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityState) -> { - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityState; - }); - } - -} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 57e55f4eda..2f710f3e92 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -871,12 +871,13 @@ transport: # Interval of periodic check for expired sessions and report of the changes to session last activity time report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:3000}" activity: - # This property specifies the strategy for reporting activity events within each reporting period. - # The accepted values are 'first', 'last', and 'first-and-last'. - # - 'first': Only the first activity event in each reporting period is reported. - # - 'last': Only the last activity event in the reporting period is reported. - # - 'first-and-last': Both the first and last activity events in the reporting period are reported. - reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:last}" + # This property specifies the strategy for reporting activity events within each reporting period. + # The accepted values are 'FIRST', 'LAST', 'FIRST_AND_LAST' and 'ALL'. + # - 'FIRST': Only the first activity event in each reporting period is reported. + # - 'LAST': Only the last activity event in the reporting period is reported. + # - 'FIRST_AND_LAST': Both the first and last activity events in the reporting period are reported. + # - 'ALL': All activity events in the reporting period are reported. + reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:LAST}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index dd8682aaed..065a0106f3 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -1,22 +1,22 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * + *

* Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * + *

* NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to ThingsBoard, Inc. * and its suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. - * + *

* Dissemination of this information or reproduction of this material is strictly forbidden * unless prior written permission is obtained from COMPANY. - * + *

* Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, * managers or contractors who have executed Confidentiality and Non-disclosure agreements * explicitly covering such access. - * + *

* The copyright notice above does not evidence any actual or intended publication * or disclosure of this source code, which includes * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. @@ -33,25 +33,31 @@ package org.thingsboard.server.common.transport.activity; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import java.util.Map; import java.util.Objects; import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @Slf4j -public abstract class AbstractActivityManager implements ActivityManager { +public abstract class AbstractActivityManager implements ActivityManager> { - protected String name; - protected long reportingPeriodMillis; - protected ActivityStateReporter reporter; + private final ConcurrentMap> states = new ConcurrentHashMap<>(); + private String name; + private long reportingPeriodMillis; + private ActivityStateReporter> reporter; private ScheduledExecutorService scheduler; private boolean initialized; @Override - public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter) { + public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter> reporter) { if (!initialized) { this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); log.info("[{}] initializing.", this.name); @@ -69,7 +75,7 @@ public abstract class AbstractActivityManager } @Override - public void onActivity(Key key, Supplier newStateSupplier) { + public void onActivity(Key key, Supplier> newStateSupplier) { if (!initialized) { log.error("[{}] Failed to process activity event: activity manager is not initialized.", name); return; @@ -86,14 +92,83 @@ public abstract class AbstractActivityManager doOnActivity(key, newStateSupplier); } - protected abstract void doOnActivity(Key key, Supplier newStateSupplier); + private boolean validate(Key key, Supplier> newStateSupplier) { + + } + + protected abstract ActivityStrategy getStrategy(); + + private void doOnActivity(Key key, Supplier> newStateSupplier) { + long newLastRecordedTime = System.currentTimeMillis(); + + var shouldReport = new AtomicBoolean(false); + var activityState = states.compute(key, (__, state) -> { + if (state == null) { + state = newStateSupplier.get(); + state.setStrategy(getStrategy()); + } + if (state.getLastRecordedTime() < newLastRecordedTime) { + state.setLastRecordedTime(newLastRecordedTime); + } + shouldReport.set(state.getStrategy().onActivity(state)); + return state; + }); + + if (shouldReport.get()) { + log.debug("[{}] Going to report first activity event for key: [{}].", name, key); + reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + @Override + public void onSuccess(Key key, long reportedTime) { + updateLastReportedTime(key, reportedTime); + } + + @Override + public void onFailure(Key key, Throwable t) { + log.debug("[{}] Failed to report first activity event for key: [{}].", name, key, t); + } + }); + } + } private void onReportingPeriodEnd() { log.debug("[{}] Going to end reporting period.", name); - doOnReportingPeriodEnd(); + for (Map.Entry> entry : states.entrySet()) { + var key = entry.getKey(); + var state = entry.getValue(); + long lastRecordedTime = state.getLastRecordedTime(); + + boolean hasExpired = false; // TODO: implement state expiration + boolean shouldReport; + if (hasExpired) { + states.remove(key); + shouldReport = true; + } else { + shouldReport = state.getStrategy().onReportingPeriodEnd(state); + } + + if (shouldReport) { + log.debug("[{}] Going to report last activity event for key: [{}].", name, key); + reporter.report(key, lastRecordedTime, state, new ActivityReportCallback<>() { + @Override + public void onSuccess(Key key, long newLastReportedTime) { + updateLastReportedTime(key, newLastReportedTime); + } + + @Override + public void onFailure(Key key, Throwable t) { + log.debug("[{}] Failed to report last activity event in a period for key: [{}].", name, key, t); + } + }); + } + } } - protected abstract void doOnReportingPeriodEnd(); + private void updateLastReportedTime(Key key, long newLastReportedTime) { + states.computeIfPresent(key, (__, activityState) -> { + activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); + return activityState; + }); + } @Override public synchronized void destroy() { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index 8f006003ef..53228cb1a2 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -1,22 +1,22 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * + *

* Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * + *

* NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to ThingsBoard, Inc. * and its suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. - * + *

* Dissemination of this information or reproduction of this material is strictly forbidden * unless prior written permission is obtained from COMPANY. - * + *

* Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, * managers or contractors who have executed Confidentiality and Non-disclosure agreements * explicitly covering such access. - * + *

* The copyright notice above does not evidence any actual or intended publication * or disclosure of this source code, which includes * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. @@ -32,11 +32,11 @@ package org.thingsboard.server.common.transport.activity; import java.util.function.Supplier; -public interface ActivityManager { +public interface ActivityManager { - void init(String name, long reportingPeriodMillis, ActivityStateReporter reporter); + void init(String name, long reportingPeriodMillis, ActivityStateReporter> reporter); - void onActivity(Key key, Supplier newStateSupplier); + void onActivity(Key key, Supplier> newStateSupplier); void destroy(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java index 09285f9192..f0f607ddd3 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java @@ -31,11 +31,14 @@ package org.thingsboard.server.common.transport.activity; import lombok.Data; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; @Data -public class ActivityState { +public class ActivityState { private volatile long lastRecordedTime; private volatile long lastReportedTime; + private volatile ActivityStrategy strategy; + private volatile Metadata metadata; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java new file mode 100644 index 0000000000..58c8c6d165 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java @@ -0,0 +1,11 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.thingsboard.server.common.transport.activity.ActivityState; + +public interface ActivityStrategy { + + boolean onActivity(ActivityState state); + + boolean onReportingPeriodEnd(ActivityState state); + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java new file mode 100644 index 0000000000..b351d4a59a --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java @@ -0,0 +1,20 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +public enum ActivityStrategyType { + + FIRST(new FirstEventActivityStrategy()), + LAST(new LastEventActivityStrategy()), + FIRST_AND_LAST(new FirstAndLastEventActivityStrategy()), + ALL(new AllEventsActivityStrategy()); + + private final ActivityStrategy strategy; + + ActivityStrategyType(ActivityStrategy strategy) { + this.strategy = strategy; + } + + public ActivityStrategy getStrategy() { + return strategy; + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java new file mode 100644 index 0000000000..add491c3fa --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -0,0 +1,17 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.thingsboard.server.common.transport.activity.ActivityState; + +public class AllEventsActivityStrategy implements ActivityStrategy { + + @Override + public boolean onActivity(ActivityState state) { + return state.getLastReportedTime() < state.getLastReportedTime(); + } + + @Override + public boolean onReportingPeriodEnd(ActivityState state) { + return state.getLastReportedTime() < state.getLastReportedTime(); + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java new file mode 100644 index 0000000000..ecfbaff005 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -0,0 +1,25 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.thingsboard.server.common.transport.activity.ActivityState; + +public class FirstAndLastEventActivityStrategy implements ActivityStrategy { + + private volatile long firstEventTs; + + @Override + public boolean onActivity(ActivityState state) { + long lastRecordedTime = state.getLastRecordedTime(); + if (firstEventTs == 0L) { + firstEventTs = lastRecordedTime; + return state.getLastReportedTime() < firstEventTs; + } + return false; + } + + @Override + public boolean onReportingPeriodEnd(ActivityState state) { + firstEventTs = 0L; + return state.getLastReportedTime() < state.getLastRecordedTime(); + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java new file mode 100644 index 0000000000..2b787c3251 --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -0,0 +1,25 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.thingsboard.server.common.transport.activity.ActivityState; + +public class FirstEventActivityStrategy implements ActivityStrategy { + + private volatile long firstEventTs; + + @Override + public boolean onActivity(ActivityState state) { + long lastRecordedTime = state.getLastRecordedTime(); + if (firstEventTs == 0L) { + firstEventTs = lastRecordedTime; + return state.getLastReportedTime() < firstEventTs; + } + return false; + } + + @Override + public boolean onReportingPeriodEnd(ActivityState state) { + firstEventTs = 0L; + return false; + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java new file mode 100644 index 0000000000..57260ed5ca --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -0,0 +1,17 @@ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.thingsboard.server.common.transport.activity.ActivityState; + +public class LastEventActivityStrategy implements ActivityStrategy { + + @Override + public boolean onActivity(ActivityState state) { + return false; + } + + @Override + public boolean onReportingPeriodEnd(ActivityState state) { + return state.getLastReportedTime() < state.getLastRecordedTime(); + } + +} From 7431233f5d519b814e13c6282a8105d47dfddc3f Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 15 Dec 2023 09:02:06 +0200 Subject: [PATCH 71/91] [WIP] Reimplemented activity management --- .../integration/IntegrationActivityKey.java | 14 +- .../activity/AbstractActivityManager.java | 120 ++++++----- .../transport/activity/ActivityManager.java | 18 +- .../activity/strategy/ActivityStrategy.java | 36 +++- .../strategy/ActivityStrategyFactory.java | 58 +++++ .../strategy/ActivityStrategyType.java | 20 -- .../strategy/AllEventsActivityStrategy.java | 40 +++- .../FirstAndLastEventActivityStrategy.java | 49 ++++- .../strategy/FirstEventActivityStrategy.java | 50 ++++- .../strategy/LastEventActivityStrategy.java | 38 +++- .../service/DefaultTransportService.java | 135 ++++++++---- ...tAndLastEventTransportActivityManager.java | 199 ----------------- ...nlyFirstEventTransportActivityManager.java | 200 ------------------ ...OnlyLastEventTransportActivityManager.java | 149 ------------- 14 files changed, 420 insertions(+), 706 deletions(-) rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java => application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java (83%) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java delete mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyLastEventTransportActivityManager.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java b/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java similarity index 83% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java rename to application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java index 1092c569d2..d830d382cb 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityStateReporter.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java @@ -28,11 +28,17 @@ * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. */ -package org.thingsboard.server.common.transport.activity; +package org.thingsboard.server.service.integration; -@FunctionalInterface -public interface ActivityStateReporter { +import lombok.NonNull; +import lombok.Value; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.TenantId; - void report(Key key, long timeToReport, State activityState, ActivityReportCallback callback); +@Value +public class IntegrationActivityKey { + + @NonNull TenantId tenantId; + @NonNull DeviceId deviceId; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 065a0106f3..1c5da90bbd 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -1,22 +1,22 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - *

+ * * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - *

+ * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to ThingsBoard, Inc. * and its suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. - *

+ * * Dissemination of this information or reproduction of this material is strictly forbidden * unless prior written permission is obtained from COMPANY. - *

+ * * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, * managers or contractors who have executed Confidentiality and Non-disclosure agreements * explicitly covering such access. - *

+ * * The copyright notice above does not evidence any actual or intended publication * or disclosure of this source code, which includes * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. @@ -36,7 +36,6 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; import java.util.Map; -import java.util.Objects; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -44,38 +43,47 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; @Slf4j -public abstract class AbstractActivityManager implements ActivityManager> { +public abstract class AbstractActivityManager implements ActivityManager { private final ConcurrentMap> states = new ConcurrentHashMap<>(); - private String name; + protected String name; private long reportingPeriodMillis; - private ActivityStateReporter> reporter; private ScheduledExecutorService scheduler; private boolean initialized; @Override - public synchronized void init(String name, long reportingPeriodMillis, ActivityStateReporter> reporter) { + public synchronized void init(String name, long reportingPeriodMillis) { if (!initialized) { this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); - log.info("[{}] initializing.", this.name); - this.reporter = Objects.requireNonNull(reporter, "Failed to initialize activity manager: provided activity reporter is null."); + log.info("Activity manager with name [{}] is initializing.", this.name); if (reportingPeriodMillis <= 0) { reportingPeriodMillis = 3000; log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); } this.reportingPeriodMillis = reportingPeriodMillis; - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(this.name)); + scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(this.name)); // TODO: use scheduler component scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); initialized = true; - log.info("[{}] initialized.", this.name); + log.info("Activity manager with name [{}] is initialized.", this.name); } } + protected abstract ActivityState createNewState(Key key); + + protected abstract ActivityStrategy getStrategy(); + + protected abstract ActivityState updateState(Key key, ActivityState state); + + protected abstract boolean hasExpired(Key key, ActivityState state); + + protected abstract void onStateExpire(Key key, Metadata metadata); + + protected abstract void reportActivity(Key key, Metadata metadata, long timeToReport, ActivityReportCallback callback); + @Override - public void onActivity(Key key, Supplier> newStateSupplier) { + public void onActivity(Key key) { if (!initialized) { log.error("[{}] Failed to process activity event: activity manager is not initialized.", name); return; @@ -84,39 +92,35 @@ public abstract class AbstractActivityManager implements Activity log.error("[{}] Failed to process activity event: provided activity key is null.", name); return; } - if (newStateSupplier == null) { - log.error("[{}] Failed to process activity event: provided new activity state supplier is null.", name); - return; - } log.debug("[{}] Received activity event for key: [{}]", name, key); - doOnActivity(key, newStateSupplier); - } - - private boolean validate(Key key, Supplier> newStateSupplier) { - - } - - protected abstract ActivityStrategy getStrategy(); - private void doOnActivity(Key key, Supplier> newStateSupplier) { long newLastRecordedTime = System.currentTimeMillis(); - var shouldReport = new AtomicBoolean(false); var activityState = states.compute(key, (__, state) -> { if (state == null) { - state = newStateSupplier.get(); + var newState = createNewState(key); + if (newState == null) { + return null; + } + state = newState; state.setStrategy(getStrategy()); } if (state.getLastRecordedTime() < newLastRecordedTime) { state.setLastRecordedTime(newLastRecordedTime); } - shouldReport.set(state.getStrategy().onActivity(state)); + shouldReport.set(state.getStrategy().onActivity()); return state; }); - if (shouldReport.get()) { + if (activityState == null) { + return; + } + + long lastRecordedTime = activityState.getLastRecordedTime(); + long lastReportedTime = activityState.getLastReportedTime(); + if (shouldReport.get() && lastReportedTime < lastRecordedTime) { log.debug("[{}] Going to report first activity event for key: [{}].", name, key); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { + reportActivity(key, activityState.getMetadata(), lastRecordedTime, new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -130,33 +134,53 @@ public abstract class AbstractActivityManager implements Activity } } + protected long getLastRecordedTime(Key key) { + ActivityState state = states.get(key); + return state == null ? 0L : state.getLastRecordedTime(); + } + private void onReportingPeriodEnd() { log.debug("[{}] Going to end reporting period.", name); for (Map.Entry> entry : states.entrySet()) { var key = entry.getKey(); - var state = entry.getValue(); - long lastRecordedTime = state.getLastRecordedTime(); + var currentState = entry.getValue(); - boolean hasExpired = false; // TODO: implement state expiration + long lastRecordedTime = currentState.getLastRecordedTime(); + long lastReportedTime = currentState.getLastReportedTime(); + var metadata = currentState.getMetadata(); + + boolean hasExpired; boolean shouldReport; - if (hasExpired) { + + var updatedState = updateState(key, currentState); + if (updatedState != null) { + lastRecordedTime = updatedState.getLastRecordedTime(); + lastReportedTime = updatedState.getLastReportedTime(); + metadata = updatedState.getMetadata(); + hasExpired = hasExpired(key, updatedState); + shouldReport = updatedState.getStrategy().onReportingPeriodEnd(); + } else { states.remove(key); + hasExpired = false; shouldReport = true; - } else { - shouldReport = state.getStrategy().onReportingPeriodEnd(state); } - if (shouldReport) { + if (hasExpired) { + states.remove(key); + onStateExpire(key, metadata); + } + + if (shouldReport && lastReportedTime < lastRecordedTime) { log.debug("[{}] Going to report last activity event for key: [{}].", name, key); - reporter.report(key, lastRecordedTime, state, new ActivityReportCallback<>() { + reportActivity(key, metadata, currentState.getLastRecordedTime(), new ActivityReportCallback<>() { @Override - public void onSuccess(Key key, long newLastReportedTime) { - updateLastReportedTime(key, newLastReportedTime); + public void onSuccess(Key key, long reportedTime) { + updateLastReportedTime(key, reportedTime); } @Override public void onFailure(Key key, Throwable t) { - log.debug("[{}] Failed to report last activity event in a period for key: [{}].", name, key, t); + log.debug("[{}] Failed to report last activity event for key: [{}].", name, key, t); } }); } @@ -164,9 +188,9 @@ public abstract class AbstractActivityManager implements Activity } private void updateLastReportedTime(Key key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityState) -> { - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityState; + states.computeIfPresent(key, (__, state) -> { + state.setLastReportedTime(Math.max(state.getLastReportedTime(), newLastReportedTime)); + return state; }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index 53228cb1a2..5e659bef1e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -1,22 +1,22 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - *

+ * * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - *

+ * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to ThingsBoard, Inc. * and its suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. - *

+ * * Dissemination of this information or reproduction of this material is strictly forbidden * unless prior written permission is obtained from COMPANY. - *

+ * * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, * managers or contractors who have executed Confidentiality and Non-disclosure agreements * explicitly covering such access. - *

+ * * The copyright notice above does not evidence any actual or intended publication * or disclosure of this source code, which includes * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. @@ -30,13 +30,11 @@ */ package org.thingsboard.server.common.transport.activity; -import java.util.function.Supplier; +public interface ActivityManager { -public interface ActivityManager { + void init(String name, long reportingPeriodMillis); - void init(String name, long reportingPeriodMillis, ActivityStateReporter> reporter); - - void onActivity(Key key, Supplier> newStateSupplier); + void onActivity(Key key); void destroy(); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java index 58c8c6d165..1bb8dfdcaf 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java @@ -1,11 +1,39 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ package org.thingsboard.server.common.transport.activity.strategy; -import org.thingsboard.server.common.transport.activity.ActivityState; - public interface ActivityStrategy { - boolean onActivity(ActivityState state); + boolean onActivity(); - boolean onReportingPeriodEnd(ActivityState state); + boolean onReportingPeriodEnd(); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java new file mode 100644 index 0000000000..f4619e2afd --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java @@ -0,0 +1,58 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +public final class ActivityStrategyFactory { + + private static final String ALL_EVENTS_STRATEGY_NAME = "ALL"; + private static final String FIRST_EVENT_STRATEGY_NAME = "FIRST"; + private static final String LAST_EVENT_STRATEGY_NAME = "LAST"; + private static final String FIRST_AND_LAST_STRATEGY_NAME = "FIRST_AND_LAST"; + + private ActivityStrategyFactory() { + } + + public static ActivityStrategy createStrategy(String strategyName) { + switch (strategyName) { + case ALL_EVENTS_STRATEGY_NAME: + return new AllEventsActivityStrategy(); + case FIRST_EVENT_STRATEGY_NAME: + return new FirstEventActivityStrategy(); + case LAST_EVENT_STRATEGY_NAME: + return new LastEventActivityStrategy(); + case FIRST_AND_LAST_STRATEGY_NAME: + return new FirstAndLastEventActivityStrategy(); + default: + throw new IllegalArgumentException("Unknown activity strategy name: [" + strategyName + "."); + } + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java deleted file mode 100644 index b351d4a59a..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.thingsboard.server.common.transport.activity.strategy; - -public enum ActivityStrategyType { - - FIRST(new FirstEventActivityStrategy()), - LAST(new LastEventActivityStrategy()), - FIRST_AND_LAST(new FirstAndLastEventActivityStrategy()), - ALL(new AllEventsActivityStrategy()); - - private final ActivityStrategy strategy; - - ActivityStrategyType(ActivityStrategy strategy) { - this.strategy = strategy; - } - - public ActivityStrategy getStrategy() { - return strategy; - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java index add491c3fa..27797c5315 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -1,17 +1,45 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ package org.thingsboard.server.common.transport.activity.strategy; -import org.thingsboard.server.common.transport.activity.ActivityState; - public class AllEventsActivityStrategy implements ActivityStrategy { @Override - public boolean onActivity(ActivityState state) { - return state.getLastReportedTime() < state.getLastReportedTime(); + public boolean onActivity() { + return true; } @Override - public boolean onReportingPeriodEnd(ActivityState state) { - return state.getLastReportedTime() < state.getLastReportedTime(); + public boolean onReportingPeriodEnd() { + return true; } } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java index ecfbaff005..c2605cdeaf 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -1,25 +1,52 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ package org.thingsboard.server.common.transport.activity.strategy; -import org.thingsboard.server.common.transport.activity.ActivityState; - public class FirstAndLastEventActivityStrategy implements ActivityStrategy { - private volatile long firstEventTs; + private boolean firstEventReceived; @Override - public boolean onActivity(ActivityState state) { - long lastRecordedTime = state.getLastRecordedTime(); - if (firstEventTs == 0L) { - firstEventTs = lastRecordedTime; - return state.getLastReportedTime() < firstEventTs; + public synchronized boolean onActivity() { + if (!firstEventReceived) { + firstEventReceived = true; + return true; } return false; } @Override - public boolean onReportingPeriodEnd(ActivityState state) { - firstEventTs = 0L; - return state.getLastReportedTime() < state.getLastRecordedTime(); + public synchronized boolean onReportingPeriodEnd() { + firstEventReceived = false; + return true; } } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index 2b787c3251..d837591e04 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -1,24 +1,54 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ package org.thingsboard.server.common.transport.activity.strategy; -import org.thingsboard.server.common.transport.activity.ActivityState; - public class FirstEventActivityStrategy implements ActivityStrategy { - private volatile long firstEventTs; + private boolean firstEventReceived; @Override - public boolean onActivity(ActivityState state) { - long lastRecordedTime = state.getLastRecordedTime(); - if (firstEventTs == 0L) { - firstEventTs = lastRecordedTime; - return state.getLastReportedTime() < firstEventTs; + public synchronized boolean onActivity() { + if (!firstEventReceived) { + firstEventReceived = true; + return true; } return false; } @Override - public boolean onReportingPeriodEnd(ActivityState state) { - firstEventTs = 0L; + public synchronized boolean onReportingPeriodEnd() { + if (!firstEventReceived) { + return true; + } + firstEventReceived = false; return false; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java index 57260ed5ca..e22263096e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -1,17 +1,45 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ package org.thingsboard.server.common.transport.activity.strategy; -import org.thingsboard.server.common.transport.activity.ActivityState; - public class LastEventActivityStrategy implements ActivityStrategy { @Override - public boolean onActivity(ActivityState state) { + public boolean onActivity() { return false; } @Override - public boolean onReportingPeriodEnd(ActivityState state) { - return state.getLastReportedTime() < state.getLastRecordedTime(); + public boolean onReportingPeriodEnd() { + return true; } } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index a86bdda312..5646e35cec 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -23,7 +23,6 @@ import com.google.gson.JsonObject; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Lazy; @@ -72,8 +71,11 @@ import org.thingsboard.server.common.transport.TransportResourceCache; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportTenantProfileCache; -import org.thingsboard.server.common.transport.activity.ActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityStateReporter; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyFactory; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; @@ -132,7 +134,7 @@ import java.util.stream.Collectors; @Slf4j @Service @TbTransportComponent -public class DefaultTransportService implements TransportService { +public class DefaultTransportService extends AbstractActivityManager implements TransportService { public static final String OVERWRITE_ACTIVITY_TIME = "overwriteActivityTime"; public static final String SESSION_EXPIRED_MESSAGE = "Session has expired due to last activity time!"; @@ -156,6 +158,8 @@ public class DefaultTransportService implements TransportService { private long sessionInactivityTimeout; @Value("${transport.sessions.report_timeout}") private long sessionReportTimeout; + @Value("${transport.activity.reporting_strategy:LAST}") + private String reportingStrategyName; @Value("${transport.client_side_rpc.timeout:60000}") private long clientSideRpcTimeout; @Value("${queue.transport.poll_interval}") @@ -187,7 +191,6 @@ public class DefaultTransportService implements TransportService { private final TransportResourceCache transportResourceCache; private final NotificationRuleProcessor notificationRuleProcessor; private final EntityLimitsCache entityLimitsCache; - private ActivityManager activityManager; protected TbQueueRequestTemplate, TbProtoQueueMsg> transportApiRequestTemplate; protected TbQueueProducer> ruleEngineMsgProducer; @@ -235,13 +238,9 @@ public class DefaultTransportService implements TransportService { this.entityLimitsCache = entityLimitsCache; } - @Autowired - public void setActivityManager(ActivityManager activityManager) { - this.activityManager = activityManager; - } - @PostConstruct public void init() { + super.init(ACTIVITY_MANAGER_NAME, sessionReportTimeout); this.ruleEngineProducerStats = statsFactory.createMessagesStats(StatsType.RULE_ENGINE.getName() + ".producer"); this.tbCoreProducerStats = statsFactory.createMessagesStats(StatsType.CORE.getName() + ".producer"); this.transportApiStats = statsFactory.createMessagesStats(StatsType.TRANSPORT.getName() + ".producer"); @@ -256,31 +255,8 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); - activityManager.init(ACTIVITY_MANAGER_NAME, sessionReportTimeout, activityReporter); } - private final ActivityStateReporter activityReporter = (sessionId, timeToReport, state, reportCallback) -> { - log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", ACTIVITY_MANAGER_NAME, sessionId, timeToReport); - SessionMetaData sessionMetaData = sessions.get(sessionId); - TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToAttributes()) - .setRpcSubscription(sessionMetaData != null && sessionMetaData.isSubscribedToRPC()) - .setLastActivityTime(timeToReport) - .build(); - process(state.getSessionInfoProto(), subscriptionInfo, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - reportCallback.onSuccess(sessionId, timeToReport); - - } - - @Override - public void onError(Throwable e) { - reportCallback.onFailure(sessionId, e); - } - }); - }; - @AfterStartUp(order = AfterStartUp.TRANSPORT_SERVICE) public void start() { mainConsumerExecutor.execute(() -> { @@ -319,6 +295,7 @@ public class DefaultTransportService implements TransportService { @PreDestroy public void destroy() { stopped = true; + super.destroy(); if (transportNotificationsConsumer != null) { transportNotificationsConsumer.unsubscribe(); @@ -332,9 +309,6 @@ public class DefaultTransportService implements TransportService { if (transportApiRequestTemplate != null) { transportApiRequestTemplate.stop(); } - if (activityManager != null) { - activityManager.destroy(); - } } @Override @@ -814,10 +788,91 @@ public class DefaultTransportService implements TransportService { } private void reportActivityInternal(TransportProtos.SessionInfoProto sessionInfo) { - activityManager.onActivity(toSessionId(sessionInfo), () -> { - var activityState = new TransportActivityState(); - activityState.setSessionInfoProto(sessionInfo); - return activityState; + onActivity(toSessionId(sessionInfo)); + } + + @Override + protected ActivityState createNewState(UUID sessionId) { + SessionMetaData session = sessions.get(sessionId); + if (session == null) { + return null; + } + ActivityState state = new ActivityState<>(); + state.setMetadata(session.getSessionInfo()); + return state; + } + + @Override + protected ActivityStrategy getStrategy() { + return ActivityStrategyFactory.createStrategy(reportingStrategyName); + } + + @Override + protected ActivityState updateState(UUID sessionId, ActivityState state) { + SessionMetaData session = sessions.get(sessionId); + if (session == null) { + return null; + } + + state.setMetadata(session.getSessionInfo()); + var sessionInfo = state.getMetadata(); + + if (sessionInfo.getGwSessionIdMSB() == 0L || sessionInfo.getCustomerIdLSB() == 0L) { + return state; + } + + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSession = sessions.get(gwSessionId); + if (gwSession == null || !gwSession.isOverwriteActivityTime()) { + return state; + } + + long lastRecordedTime = state.getLastRecordedTime(); + long gwLastRecordedTime = getLastRecordedTime(gwSessionId); + log.debug("[{}] Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. " + + "Updating last activity time. Session last recorded time: [{}], gateway session last recorded time: [{}].", + name, sessionId, gwSessionId, lastRecordedTime, gwLastRecordedTime); + state.setLastRecordedTime(Math.max(lastRecordedTime, gwLastRecordedTime)); + return state; + } + + @Override + protected boolean hasExpired(UUID uuid, ActivityState state) { + return (System.currentTimeMillis() - sessionInactivityTimeout) < state.getLastReportedTime(); + } + + @Override + protected void onStateExpire(UUID sessionId, TransportProtos.SessionInfoProto sessionInfo) { + log.debug("[{}] Session with id: [{}] has expired due to last activity time.", name, sessionId); + SessionMetaData expiredSession = sessions.remove(sessionId); + if (expiredSession != null) { + deregisterSession(sessionInfo); + process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + expiredSession.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } + } + + @Override + protected void reportActivity(UUID sessionId, TransportProtos.SessionInfoProto currentSessionInfo, long timeToReport, ActivityReportCallback callback) { + log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", name, sessionId, timeToReport); + SessionMetaData session = sessions.get(sessionId); + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) + .setRpcSubscription(session != null && session.isSubscribedToRPC()) + .setLastActivityTime(timeToReport) + .build(); + TransportProtos.SessionInfoProto sessionInfo = session != null ? session.getSessionInfo() : currentSessionInfo; + process(sessionInfo, subscriptionInfo, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + callback.onSuccess(sessionId, timeToReport); + + } + + @Override + public void onError(Throwable e) { + callback.onFailure(sessionId, e); + } }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java deleted file mode 100644 index 9c582b2587..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/FirstAndLastEventTransportActivityManager.java +++ /dev/null @@ -1,199 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.common.transport.service.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.service.SessionMetaData; -import org.thingsboard.server.common.transport.service.TransportActivityState; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.util.TbTransportComponent; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; - -@Slf4j -@Component -@TbTransportComponent -@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first-and-last") -public class FirstAndLastEventTransportActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Data - private static class ActivityStateWrapper { - - volatile TransportActivityState state; - volatile boolean alreadyBeenReported; - - } - - @Value("${transport.sessions.inactivity_timeout}") - private long sessionInactivityTimeout; - - @Autowired - private TransportService transportService; - - @Override - protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - states.compute(sessionId, (key, activityStateWrapper) -> { - if (activityStateWrapper == null) { - activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(newStateSupplier.get()); - } - var activityState = activityStateWrapper.getState(); - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - if (activityStateWrapper.isAlreadyBeenReported()) { - return activityStateWrapper; - } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - log.debug("[{}] Going to report first activity event for session with id: [{}]", name, sessionId); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(UUID key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(UUID key, Throwable t) { - reportCompletedFuture.setException(t); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(true); - return activityStateWrapper; - }); - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } - - @Override - public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event for session with id: [{}]", name, sessionId); - } - }, MoreExecutors.directExecutor()); - } - - @Override - protected void doOnReportingPeriodEnd() { - Set statesToRemove = new HashSet<>(); - for (Map.Entry entry : states.entrySet()) { - var sessionId = entry.getKey(); - var activityStateWrapper = entry.getValue(); - var activityState = activityStateWrapper.getState(); - - SessionMetaData sessionMetaData = transportService.getSession(sessionId); - if (sessionMetaData != null) { - activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); - } else { - log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); - statesToRemove.add(sessionId); - } - - long lastActivityTime = activityState.getLastRecordedTime(); - TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); - if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { - ActivityStateWrapper gwActivityStateWrapper = states.get(gwSessionId); - if (gwActivityStateWrapper != null) { - log.debug("[{}] Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. Updating last activity time.", name, sessionId, gwSessionId); - lastActivityTime = Math.max(gwActivityStateWrapper.getState().getLastRecordedTime(), lastActivityTime); - } - } - } - - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; - boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; - if (hasExpired) { - log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); - transportService.deregisterSession(sessionInfo); - statesToRemove.add(sessionId); - transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } - if (activityState.getLastReportedTime() < lastActivityTime) { - log.debug("[{}] Going to report last activity event for session with id: [{}].", name, sessionId); - reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(UUID key, long reportedTime) { - updateLastReportedTime(key, reportedTime); - } - - @Override - public void onFailure(UUID key, Throwable t) { - log.debug("[{}] Failed to report last activity event for session with id: [{}].", name, sessionId); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(false); - } - statesToRemove.forEach(states::remove); - } - - private void updateLastReportedTime(UUID key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java deleted file mode 100644 index 19a6314450..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyFirstEventTransportActivityManager.java +++ /dev/null @@ -1,200 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.common.transport.service.activity; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.service.SessionMetaData; -import org.thingsboard.server.common.transport.service.TransportActivityState; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.util.TbTransportComponent; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; - -@Slf4j -@Component -@TbTransportComponent -@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "first") -public class OnlyFirstEventTransportActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Data - private static class ActivityStateWrapper { - - volatile TransportActivityState state; - volatile boolean alreadyBeenReported; - - } - - @Value("${transport.sessions.inactivity_timeout}") - private long sessionInactivityTimeout; - - @Autowired - private TransportService transportService; - - @Override - protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - SettableFuture> reportCompletedFuture = SettableFuture.create(); - states.compute(sessionId, (key, activityStateWrapper) -> { - if (activityStateWrapper == null) { - activityStateWrapper = new ActivityStateWrapper(); - activityStateWrapper.setState(newStateSupplier.get()); - } - var activityState = activityStateWrapper.getState(); - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - if (activityStateWrapper.isAlreadyBeenReported()) { - return activityStateWrapper; - } - if (activityState.getLastReportedTime() < activityState.getLastRecordedTime()) { - log.debug("[{}] Going to report first activity event for session with id: [{}]", name, sessionId); - reporter.report(key, activityState.getLastRecordedTime(), activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(UUID key, long reportedTime) { - reportCompletedFuture.set(Pair.of(key, reportedTime)); - } - - @Override - public void onFailure(UUID key, Throwable t) { - reportCompletedFuture.setException(t); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(true); - return activityStateWrapper; - }); - Futures.addCallback(reportCompletedFuture, new FutureCallback<>() { - @Override - public void onSuccess(Pair reportResult) { - updateLastReportedTime(reportResult.getFirst(), reportResult.getSecond()); - } - - @Override - public void onFailure(@NonNull Throwable t) { - log.debug("[{}] Failed to report first activity event for session with id: [{}]", name, sessionId); - } - }, MoreExecutors.directExecutor()); - } - - @Override - protected void doOnReportingPeriodEnd() { - Set statesToRemove = new HashSet<>(); - for (Map.Entry entry : states.entrySet()) { - var sessionId = entry.getKey(); - var activityStateWrapper = entry.getValue(); - var activityState = activityStateWrapper.getState(); - - SessionMetaData sessionMetaData = transportService.getSession(sessionId); - if (sessionMetaData != null) { - activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); - } else { - log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); - statesToRemove.add(sessionId); - } - - long lastActivityTime = activityState.getLastRecordedTime(); - TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); - if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { - ActivityStateWrapper gwActivityStateWrapper = states.get(gwSessionId); - if (gwActivityStateWrapper != null) { - log.debug("[{}] Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. Updating last activity time.", name, sessionId, gwSessionId); - lastActivityTime = Math.max(gwActivityStateWrapper.getState().getLastRecordedTime(), lastActivityTime); - } - } - } - - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; - boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; - if (hasExpired) { - log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); - transportService.deregisterSession(sessionInfo); - statesToRemove.add(sessionId); - transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } - boolean shouldReportLeftoverEvents = sessionMetaData == null || hasExpired; - if (shouldReportLeftoverEvents && activityState.getLastReportedTime() < lastActivityTime) { - log.debug("[{}] Going to report leftover activity event for session with id: [{}].", name, sessionId); - reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(UUID key, long reportedTime) { - updateLastReportedTime(key, reportedTime); - } - - @Override - public void onFailure(UUID key, Throwable t) { - log.debug("[{}] Failed to report leftover activity event for session with id: [{}].", name, sessionId); - } - }); - } - activityStateWrapper.setAlreadyBeenReported(false); - } - statesToRemove.forEach(states::remove); - } - - private void updateLastReportedTime(UUID key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityStateWrapper) -> { - var activityState = activityStateWrapper.getState(); - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityStateWrapper; - }); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyLastEventTransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyLastEventTransportActivityManager.java deleted file mode 100644 index 977930677f..0000000000 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/activity/OnlyLastEventTransportActivityManager.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.common.transport.service.activity; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.service.SessionMetaData; -import org.thingsboard.server.common.transport.service.TransportActivityState; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.util.TbTransportComponent; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; -import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; - -@Slf4j -@Component -@TbTransportComponent -@ConditionalOnProperty(prefix = "transport.activity", value = "reporting_strategy", havingValue = "last") -public class OnlyLastEventTransportActivityManager extends AbstractActivityManager { - - private final ConcurrentMap states = new ConcurrentHashMap<>(); - - @Value("${transport.sessions.inactivity_timeout}") - private long sessionInactivityTimeout; - - @Autowired - private TransportService transportService; - - @Override - protected void doOnActivity(UUID sessionId, Supplier newStateSupplier) { - long newLastRecordedTime = System.currentTimeMillis(); - states.compute(sessionId, (__, activityState) -> { - if (activityState == null) { - activityState = newStateSupplier.get(); - } - if (activityState.getLastRecordedTime() < newLastRecordedTime) { - activityState.setLastRecordedTime(newLastRecordedTime); - } - return activityState; - }); - } - - @Override - protected void doOnReportingPeriodEnd() { - Set statesToRemove = new HashSet<>(); - for (Map.Entry entry : states.entrySet()) { - var sessionId = entry.getKey(); - var activityState = entry.getValue(); - - SessionMetaData sessionMetaData = transportService.getSession(sessionId); - if (sessionMetaData != null) { - activityState.setSessionInfoProto(sessionMetaData.getSessionInfo()); - } else { - log.debug("[{}] Session with id: [{}] is not present. Marking it's activity state for removal.", name, sessionId); - statesToRemove.add(sessionId); - } - - long lastActivityTime = activityState.getLastRecordedTime(); - TransportProtos.SessionInfoProto sessionInfo = activityState.getSessionInfoProto(); - - if (sessionInfo.getGwSessionIdMSB() != 0 && sessionInfo.getGwSessionIdLSB() != 0) { - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSessionMetaData = transportService.getSession(gwSessionId); - if (gwSessionMetaData != null && gwSessionMetaData.isOverwriteActivityTime()) { - TransportActivityState gwActivityState = states.get(gwSessionId); - if (gwActivityState != null) { - log.debug("[{}] Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. Updating last activity time.", name, sessionId, gwSessionId); - lastActivityTime = Math.max(gwActivityState.getLastRecordedTime(), lastActivityTime); - } - } - } - - long expirationTime = System.currentTimeMillis() - sessionInactivityTimeout; - boolean hasExpired = sessionMetaData != null && lastActivityTime < expirationTime; - if (hasExpired) { - log.debug("[{}] Session with id: [{}] has expired due to last activity time: [{}]. Marking it's activity state for removal.", name, sessionId, lastActivityTime); - transportService.deregisterSession(sessionInfo); - statesToRemove.add(sessionId); - transportService.process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - sessionMetaData.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } - if (activityState.getLastReportedTime() < lastActivityTime) { - log.debug("[{}] Going to report last activity event for session with id: [{}].", name, sessionId); - reporter.report(sessionId, lastActivityTime, activityState, new ActivityReportCallback<>() { - @Override - public void onSuccess(UUID key, long reportedTime) { - updateLastReportedTime(key, reportedTime); - } - - @Override - public void onFailure(UUID key, Throwable t) { - log.debug("[{}] Failed to report last activity event for session with id: [{}].", name, sessionId); - } - }); - } - } - statesToRemove.forEach(states::remove); - } - - private void updateLastReportedTime(UUID key, long newLastReportedTime) { - states.computeIfPresent(key, (__, activityState) -> { - activityState.setLastReportedTime(Math.max(activityState.getLastReportedTime(), newLastReportedTime)); - return activityState; - }); - } - -} From 315202d9df444d797d73ff23e4c774f6945d5486 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 15 Dec 2023 09:43:49 +0200 Subject: [PATCH 72/91] Fixes after manual testing --- .../common/transport/TransportService.java | 3 -- .../activity/AbstractActivityManager.java | 33 ++++--------------- .../transport/activity/ActivityManager.java | 2 -- .../service/DefaultTransportService.java | 9 +---- 4 files changed, 8 insertions(+), 39 deletions(-) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index 067527efec..f51b399a5b 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -63,7 +63,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509Ce import org.thingsboard.server.gen.transport.TransportProtos.ValidateOrCreateDeviceX509CertRequestMsg; import java.util.List; -import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; @@ -162,7 +161,5 @@ public interface TransportService { boolean hasSession(SessionInfoProto sessionInfo); - SessionMetaData getSession(UUID sessionId); - void createGaugeStats(String openConnections, AtomicInteger connectionsCounter); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 1c5da90bbd..b7d5f5dac5 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -31,16 +31,15 @@ package org.thingsboard.server.common.transport.activity; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import org.thingsboard.server.queue.scheduler.SchedulerComponent; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -48,9 +47,11 @@ import java.util.concurrent.atomic.AtomicBoolean; public abstract class AbstractActivityManager implements ActivityManager { private final ConcurrentMap> states = new ConcurrentHashMap<>(); + + @Autowired + protected SchedulerComponent scheduler; + protected String name; - private long reportingPeriodMillis; - private ScheduledExecutorService scheduler; private boolean initialized; @Override @@ -62,8 +63,6 @@ public abstract class AbstractActivityManager implements Activity reportingPeriodMillis = 3000; log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); } - this.reportingPeriodMillis = reportingPeriodMillis; - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(this.name)); // TODO: use scheduler component scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); initialized = true; log.info("Activity manager with name [{}] is initialized.", this.name); @@ -172,7 +171,7 @@ public abstract class AbstractActivityManager implements Activity if (shouldReport && lastReportedTime < lastRecordedTime) { log.debug("[{}] Going to report last activity event for key: [{}].", name, key); - reportActivity(key, metadata, currentState.getLastRecordedTime(), new ActivityReportCallback<>() { + reportActivity(key, metadata, lastRecordedTime, new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -194,22 +193,4 @@ public abstract class AbstractActivityManager implements Activity }); } - @Override - public synchronized void destroy() { - if (initialized) { - initialized = false; - if (scheduler != null) { - scheduler.shutdown(); - try { - if (scheduler.awaitTermination(10L, TimeUnit.SECONDS)) { - scheduler.shutdownNow(); - } - } catch (InterruptedException e) { - scheduler.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - } - } - } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index 5e659bef1e..f19b9e30ca 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -36,6 +36,4 @@ public interface ActivityManager { void onActivity(Key key); - void destroy(); - } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 5646e35cec..4b70638e37 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -186,7 +186,6 @@ public class DefaultTransportService extends AbstractActivityManager state) { - return (System.currentTimeMillis() - sessionInactivityTimeout) < state.getLastReportedTime(); + return (System.currentTimeMillis() - sessionInactivityTimeout) > state.getLastRecordedTime(); } @Override @@ -1351,11 +1349,6 @@ public class DefaultTransportService extends AbstractActivityManager Date: Fri, 15 Dec 2023 10:38:15 +0200 Subject: [PATCH 73/91] Refactor first activity strategy and add tests for all strategies --- .../activity/AbstractActivityManager.java | 1 + .../strategy/FirstEventActivityStrategy.java | 3 - .../strategy/ActivityStrategyFactoryTest.java | 70 +++++++++++++++++++ .../AllEventsActivityStrategyTest.java | 57 +++++++++++++++ ...FirstAndLastEventActivityStrategyTest.java | 68 ++++++++++++++++++ .../FirstEventActivityStrategyTest.java | 67 ++++++++++++++++++ .../LastEventActivityStrategyTest.java | 58 +++++++++++++++ 7 files changed, 321 insertions(+), 3 deletions(-) create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index b7d5f5dac5..1090c7c341 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -167,6 +167,7 @@ public abstract class AbstractActivityManager implements Activity if (hasExpired) { states.remove(key); onStateExpire(key, metadata); + shouldReport = true; } if (shouldReport && lastReportedTime < lastRecordedTime) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index d837591e04..d61c7a68aa 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -45,9 +45,6 @@ public class FirstEventActivityStrategy implements ActivityStrategy { @Override public synchronized boolean onReportingPeriodEnd() { - if (!firstEventReceived) { - return true; - } firstEventReceived = false; return false; } diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java new file mode 100644 index 0000000000..c6eda7eb25 --- /dev/null +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java @@ -0,0 +1,70 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ActivityStrategyFactoryTest { + + @Test + public void testCreateAllEventsStrategy() { + ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("ALL"); + assertInstanceOf(AllEventsActivityStrategy.class, strategy, "Should return an instance of AllEventsActivityStrategy."); + } + + @Test + public void testCreateFirstEventStrategy() { + ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST"); + assertInstanceOf(FirstEventActivityStrategy.class, strategy, "Should return an instance of FirstEventActivityStrategy."); + } + + @Test + public void testCreateLastEventStrategy() { + ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("LAST"); + assertInstanceOf(LastEventActivityStrategy.class, strategy, "Should return an instance of LastEventActivityStrategy."); + } + + @Test + public void testCreateFirstAndLastEventStrategy() { + ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST_AND_LAST"); + assertInstanceOf(FirstAndLastEventActivityStrategy.class, strategy, "Should return an instance of FirstAndLastEventActivityStrategy."); + } + + @Test + public void testCreateUnknownStrategy() { + assertThrows(IllegalArgumentException.class, () -> ActivityStrategyFactory.createStrategy("UNKNOWN"), + "Should throw IllegalArgumentException for unknown strategy names."); + } + +} diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java new file mode 100644 index 0000000000..22cbc10ca2 --- /dev/null +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java @@ -0,0 +1,57 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AllEventsActivityStrategyTest { + + private AllEventsActivityStrategy strategy; + + @BeforeEach + public void setUp() { + strategy = new AllEventsActivityStrategy(); + } + + @Test + public void testOnActivity() { + assertTrue(strategy.onActivity(), "onActivity() should always return true."); + } + + @Test + public void testOnReportingPeriodEnd() { + assertTrue(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return true."); + } + +} diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java new file mode 100644 index 0000000000..597693f926 --- /dev/null +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java @@ -0,0 +1,68 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FirstAndLastEventActivityStrategyTest { + + private FirstAndLastEventActivityStrategy strategy; + + @BeforeEach + public void setUp() { + strategy = new FirstAndLastEventActivityStrategy(); + } + + @Test + public void testOnActivity_FirstCall() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + } + + @Test + public void testOnActivity_SubsequentCalls() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + assertFalse(strategy.onActivity(), "Subsequent calls of onActivity() should return false."); + } + + @Test + public void testOnReportingPeriodEnd() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + assertTrue(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return true."); + assertTrue(strategy.onActivity(), "onActivity() should return true after onReportingPeriodEnd() for the next reporting period"); + assertTrue(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return true."); + } + + +} diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java new file mode 100644 index 0000000000..5d4d270f0f --- /dev/null +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java @@ -0,0 +1,67 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FirstEventActivityStrategyTest { + + private FirstEventActivityStrategy strategy; + + @BeforeEach + public void setUp() { + strategy = new FirstEventActivityStrategy(); + } + + @Test + public void testOnActivity_FirstCall() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + } + + @Test + public void testOnActivity_SubsequentCalls() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + assertFalse(strategy.onActivity(), "Subsequent calls of onActivity() should return false."); + } + + @Test + public void testOnReportingPeriodEnd() { + assertTrue(strategy.onActivity(), "First call of onActivity() should return true."); + assertFalse(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return false."); + assertTrue(strategy.onActivity(), "onActivity() should return true after onReportingPeriodEnd()."); + assertFalse(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return false."); + } + +} diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java new file mode 100644 index 0000000000..51da85a9c3 --- /dev/null +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java @@ -0,0 +1,58 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.activity.strategy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class LastEventActivityStrategyTest { + + private LastEventActivityStrategy strategy; + + @BeforeEach + public void setUp() { + strategy = new LastEventActivityStrategy(); + } + + @Test + public void testOnActivity() { + assertFalse(strategy.onActivity(), "onActivity() should always return false."); + } + + @Test + public void testOnReportingPeriodEnd() { + assertTrue(strategy.onReportingPeriodEnd(), "onReportingPeriodEnd() should always return true."); + } + +} From 76fec4672006cb593581e64d84289c6ba818270a Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 15 Dec 2023 12:50:14 +0200 Subject: [PATCH 74/91] Minor refactoring and tests for integration activity manager --- .../IntegrationActivityManagerTest.java | 299 ++++++++++++++++++ .../activity/AbstractActivityManager.java | 12 +- .../service/DefaultTransportService.java | 13 +- 3 files changed, 307 insertions(+), 17 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java new file mode 100644 index 0000000000..6748bced4d --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -0,0 +1,299 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.integration; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; +import org.thingsboard.server.common.data.id.DeviceId; +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.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.AllEventsActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.FirstAndLastEventActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.FirstEventActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.LastEventActivityStrategy; +import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.TbQueueCallback; +import org.thingsboard.server.queue.TbQueueProducer; +import org.thingsboard.server.queue.common.TbProtoQueueMsg; +import org.thingsboard.server.queue.discovery.PartitionService; + +import java.util.UUID; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class IntegrationActivityManagerTest { + + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("1306648a-9b26-11ee-b9d1-0242ac120002")); + private final DeviceId DEVICE_ID = DeviceId.fromString("1d288a06-9b26-11ee-b9d1-0242ac120002"); + + @Mock + private DefaultPlatformIntegrationService integrationServiceMock; + + @Test + void testReportActivity() { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + + TbQueueProducer> tbCoreMsgProducerMock = mock(TbQueueProducer.class); + ReflectionTestUtils.setField(integrationServiceMock, "tbCoreMsgProducer", tbCoreMsgProducerMock); + + PartitionService partitionServiceMock = mock(PartitionService.class); + ReflectionTestUtils.setField(integrationServiceMock, "partitionService", partitionServiceMock); + TopicPartitionInfo tpi = TopicPartitionInfo.builder().build(); + when(partitionServiceMock.resolve(ServiceType.TB_CORE, TENANT_ID, DEVICE_ID)).thenReturn(tpi); + + ActivityReportCallback callbackMock = mock(ActivityReportCallback.class); + + long expectedTime = 123L; + + doCallRealMethod().when(integrationServiceMock).reportActivity(key, null, expectedTime, callbackMock); + + // WHEN + integrationServiceMock.reportActivity(key, null, expectedTime, callbackMock); + + // THEN + verify(partitionServiceMock).resolve(ServiceType.TB_CORE, TENANT_ID, DEVICE_ID); + + ArgumentCaptor> msgCaptor = ArgumentCaptor.forClass(TbProtoQueueMsg.class); + ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(TbQueueCallback.class); + verify(tbCoreMsgProducerMock).send(eq(tpi), msgCaptor.capture(), callbackCaptor.capture()); + + TbProtoQueueMsg queueMsg = msgCaptor.getValue(); + + TransportProtos.DeviceActivityProto expectedDeviceActivityMsg = TransportProtos.DeviceActivityProto.newBuilder() + .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) + .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) + .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) + .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) + .setLastActivityTime(expectedTime) + .build(); + + TransportProtos.ToCoreMsg expectedToCoreMsg = TransportProtos.ToCoreMsg.newBuilder() + .setDeviceActivityMsg(expectedDeviceActivityMsg) + .build(); + + assertThat(queueMsg.getKey()).isEqualTo(DEVICE_ID.getId()); + assertThat(queueMsg.getValue()).isEqualTo(expectedToCoreMsg); + + TbQueueCallback queueCallback = callbackCaptor.getValue(); + + queueCallback.onSuccess(null); + verify(callbackMock).onSuccess(key, expectedTime); + + var throwable = new Throwable(); + queueCallback.onFailure(throwable); + verify(callbackMock).onFailure(key, throwable); + } + + @Test + void givenPostTelemetryMsg_whenProcessingMsg_thenShouldCallOnActivity() { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) + .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) + .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) + .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) + .setDeviceName("Test Device") + .setDeviceType("default") + .build(); + TransportProtos.PostTelemetryMsg postTelemetryMsg = TransportProtos.PostTelemetryMsg.getDefaultInstance(); + doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postTelemetryMsg, null); + + // WHEN + integrationServiceMock.process(sessionInfo, postTelemetryMsg, null); + + // THEN + verify(integrationServiceMock).onActivity(key); + } + + @Test + void givenPostAttributesMsg_whenProcessingMsg_thenShouldCallOnActivity() { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) + .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) + .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) + .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) + .setDeviceName("Test Device") + .setDeviceType("default") + .build(); + TransportProtos.PostAttributeMsg postAttributeMsg = TransportProtos.PostAttributeMsg.getDefaultInstance(); + doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postAttributeMsg, null); + doNothing().when(integrationServiceMock).sendToRuleEngine(any(), any(), any(), any(), any(), any(), any()); + + // WHEN + integrationServiceMock.process(sessionInfo, postAttributeMsg, null); + + // THEN + verify(integrationServiceMock).onActivity(key); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForCreateNewState") + void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy( + String reportingStrategyName, Class reportingStrategyClass + ) { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenCallRealMethod(); + ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyName", reportingStrategyName); + + // WHEN + ActivityState newState = integrationServiceMock.createNewState(key); + + // THEN + assertThat(newState).isNotNull(); + assertThat(newState.getLastRecordedTime()).isEqualTo(0L); + assertThat(newState.getLastReportedTime()).isEqualTo(0L); + assertThat(newState.getStrategy()).isInstanceOf(reportingStrategyClass); + } + + private static Stream provideTestParamsForCreateNewState() { + return Stream.of( + Arguments.of("ALL", AllEventsActivityStrategy.class), + Arguments.of("FIRST", FirstEventActivityStrategy.class), + Arguments.of("LAST", LastEventActivityStrategy.class), + Arguments.of("FIRST_AND_LAST", FirstAndLastEventActivityStrategy.class) + ); + } + + @Test + void givenActivityState_whenUpdatingActivityState_thenShouldReturnSameInstanceWithNoChanges() { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + + long expectedLastRecordedTime = 123L; + long expectedLastReportedTime = 312L; + ActivityStrategy expectedStrategy = spy(new FirstEventActivityStrategy()); + + ActivityState expectedState = new ActivityState<>(); + expectedState.setLastRecordedTime(expectedLastRecordedTime); + expectedState.setLastReportedTime(expectedLastReportedTime); + expectedState.setStrategy(expectedStrategy); + + when(integrationServiceMock.updateState(key, expectedState)).thenCallRealMethod(); + + // WHEN + ActivityState actualNewState = integrationServiceMock.updateState(key, expectedState); + + // THEN + assertThat(actualNewState).isSameAs(expectedState); + assertThat(actualNewState.getLastRecordedTime()).isEqualTo(expectedLastRecordedTime); + assertThat(actualNewState.getLastReportedTime()).isEqualTo(expectedLastReportedTime); + assertThat(actualNewState.getStrategy()).isSameAs(expectedStrategy); + verifyNoInteractions(expectedStrategy); + assertThat(actualNewState.getMetadata()).isNull(); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForHasExpiredTrue") + public void givenExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnTrue(long currentTimeMillis, long lastRecordedTime, long reportingPeriodMillis) { + // GIVEN + ReflectionTestUtils.setField(integrationServiceMock, "reportingPeriodMillis", reportingPeriodMillis); + + when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); + when(integrationServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); + + // WHEN + boolean hasExpired = integrationServiceMock.hasExpired(lastRecordedTime); + + // THEN + assertThat(hasExpired).isTrue(); + } + + private static Stream provideTestParamsForHasExpiredTrue() { + return Stream.of( + Arguments.of(10L, 0L, 9L), + Arguments.of(10L, 7L, 2L), + Arguments.of(10L, 8L, 1L) + ); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForHasExpiredFalse") + public void givenNotExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnFalse(long currentTimeMillis, long lastRecordedTime, long reportingPeriodMillis) { + // GIVEN + ReflectionTestUtils.setField(integrationServiceMock, "reportingPeriodMillis", reportingPeriodMillis); + + when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); + when(integrationServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); + + // WHEN + boolean hasExpired = integrationServiceMock.hasExpired(lastRecordedTime); + + // THEN + assertThat(hasExpired).isFalse(); + } + + private static Stream provideTestParamsForHasExpiredFalse() { + return Stream.of( + Arguments.of(10L, 9L, 2L), + Arguments.of(10L, 0L, 11L), + Arguments.of(10L, 8L, 3L) + ); + } + + @Test + void givenKeyAndVoidMetadata_whenOnStateExpiryCalled_thenShouldDoNothing() { + // GIVEN + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + doCallRealMethod().when(integrationServiceMock).onStateExpiry(key, null); + + // WHEN-THEN + assertThatNoException().isThrownBy(() -> integrationServiceMock.onStateExpiry(key, null)); + } + +} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 1090c7c341..b5f4bf8f9e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -33,7 +33,6 @@ package org.thingsboard.server.common.transport.activity; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; import org.thingsboard.server.queue.scheduler.SchedulerComponent; import java.util.Map; @@ -71,13 +70,11 @@ public abstract class AbstractActivityManager implements Activity protected abstract ActivityState createNewState(Key key); - protected abstract ActivityStrategy getStrategy(); - protected abstract ActivityState updateState(Key key, ActivityState state); - protected abstract boolean hasExpired(Key key, ActivityState state); + protected abstract boolean hasExpired(long lastRecordedTime); - protected abstract void onStateExpire(Key key, Metadata metadata); + protected abstract void onStateExpiry(Key key, Metadata metadata); protected abstract void reportActivity(Key key, Metadata metadata, long timeToReport, ActivityReportCallback callback); @@ -102,7 +99,6 @@ public abstract class AbstractActivityManager implements Activity return null; } state = newState; - state.setStrategy(getStrategy()); } if (state.getLastRecordedTime() < newLastRecordedTime) { state.setLastRecordedTime(newLastRecordedTime); @@ -156,7 +152,7 @@ public abstract class AbstractActivityManager implements Activity lastRecordedTime = updatedState.getLastRecordedTime(); lastReportedTime = updatedState.getLastReportedTime(); metadata = updatedState.getMetadata(); - hasExpired = hasExpired(key, updatedState); + hasExpired = hasExpired(lastRecordedTime); shouldReport = updatedState.getStrategy().onReportingPeriodEnd(); } else { states.remove(key); @@ -166,7 +162,7 @@ public abstract class AbstractActivityManager implements Activity if (hasExpired) { states.remove(key); - onStateExpire(key, metadata); + onStateExpiry(key, metadata); shouldReport = true; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 4b70638e37..9cd41e7a62 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -74,7 +74,6 @@ import org.thingsboard.server.common.transport.TransportTenantProfileCache; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyFactory; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; @@ -797,14 +796,10 @@ public class DefaultTransportService extends AbstractActivityManager state = new ActivityState<>(); state.setMetadata(session.getSessionInfo()); + state.setStrategy(ActivityStrategyFactory.createStrategy(reportingStrategyName)); return state; } - @Override - protected ActivityStrategy getStrategy() { - return ActivityStrategyFactory.createStrategy(reportingStrategyName); - } - @Override protected ActivityState updateState(UUID sessionId, ActivityState state) { SessionMetaData session = sessions.get(sessionId); @@ -835,12 +830,12 @@ public class DefaultTransportService extends AbstractActivityManager state) { - return (System.currentTimeMillis() - sessionInactivityTimeout) > state.getLastRecordedTime(); + protected boolean hasExpired(long lastRecordedTime) { + return (System.currentTimeMillis() - sessionInactivityTimeout) > lastRecordedTime; } @Override - protected void onStateExpire(UUID sessionId, TransportProtos.SessionInfoProto sessionInfo) { + protected void onStateExpiry(UUID sessionId, TransportProtos.SessionInfoProto sessionInfo) { log.debug("[{}] Session with id: [{}] has expired due to last activity time.", name, sessionId); SessionMetaData expiredSession = sessions.remove(sessionId); if (expiredSession != null) { From f42ea7972617a9c13f3bf492156d3ead8000c3c1 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 15 Dec 2023 15:43:05 +0200 Subject: [PATCH 75/91] Additional improvements during testing and add tests for transport activity manager --- .../IntegrationActivityManagerTest.java | 58 +- .../coap/client/DefaultCoapClientContext.java | 2 +- .../transport/mqtt/MqttTransportHandler.java | 10 +- .../snmp/service/SnmpTransportService.java | 2 +- .../common/transport/TransportService.java | 2 +- .../activity/AbstractActivityManager.java | 3 +- .../transport/activity/ActivityManager.java | 2 + .../strategy/AllEventsActivityStrategy.java | 3 + .../FirstAndLastEventActivityStrategy.java | 3 + .../strategy/FirstEventActivityStrategy.java | 3 + .../strategy/LastEventActivityStrategy.java | 3 + .../service/DefaultTransportService.java | 40 +- .../service/TransportActivityManagerTest.java | 588 ++++++++++++++++++ 13 files changed, 662 insertions(+), 57 deletions(-) create mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java index 6748bced4d..fdb1710189 100644 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -81,7 +81,7 @@ public class IntegrationActivityManagerTest { private DefaultPlatformIntegrationService integrationServiceMock; @Test - void testReportActivity() { + void givenKeyAndTimeToReport_whenReportingActivity_thenShouldCorrectlyReportActivity() { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); @@ -184,58 +184,54 @@ public class IntegrationActivityManagerTest { @ParameterizedTest @MethodSource("provideTestParamsForCreateNewState") void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy( - String reportingStrategyName, Class reportingStrategyClass + String reportingStrategyName, ActivityStrategy reportingStrategy ) { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); when(integrationServiceMock.createNewState(key)).thenCallRealMethod(); ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyName", reportingStrategyName); + ActivityState expectedState = new ActivityState<>(); + expectedState.setStrategy(reportingStrategy); + // WHEN - ActivityState newState = integrationServiceMock.createNewState(key); + ActivityState actualState = integrationServiceMock.createNewState(key); // THEN - assertThat(newState).isNotNull(); - assertThat(newState.getLastRecordedTime()).isEqualTo(0L); - assertThat(newState.getLastReportedTime()).isEqualTo(0L); - assertThat(newState.getStrategy()).isInstanceOf(reportingStrategyClass); + assertThat(actualState).isEqualTo(expectedState); } private static Stream provideTestParamsForCreateNewState() { return Stream.of( - Arguments.of("ALL", AllEventsActivityStrategy.class), - Arguments.of("FIRST", FirstEventActivityStrategy.class), - Arguments.of("LAST", LastEventActivityStrategy.class), - Arguments.of("FIRST_AND_LAST", FirstAndLastEventActivityStrategy.class) + Arguments.of("ALL", new AllEventsActivityStrategy()), + Arguments.of("FIRST", new FirstEventActivityStrategy()), + Arguments.of("LAST", new LastEventActivityStrategy()), + Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy()) ); } @Test - void givenActivityState_whenUpdatingActivityState_thenShouldReturnSameInstanceWithNoChanges() { + void givenActivityState_whenUpdatingActivityState_thenShouldReturnSameInstanceWithNoInteractions() { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - long expectedLastRecordedTime = 123L; - long expectedLastReportedTime = 312L; - ActivityStrategy expectedStrategy = spy(new FirstEventActivityStrategy()); + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); - ActivityState expectedState = new ActivityState<>(); - expectedState.setLastRecordedTime(expectedLastRecordedTime); - expectedState.setLastReportedTime(expectedLastReportedTime); - expectedState.setStrategy(expectedStrategy); + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(123L); + state.setLastReportedTime(312L); + state.setStrategy(strategySpy); + ActivityState stateSpy = spy(state); - when(integrationServiceMock.updateState(key, expectedState)).thenCallRealMethod(); + when(integrationServiceMock.updateState(key, state)).thenCallRealMethod(); // WHEN - ActivityState actualNewState = integrationServiceMock.updateState(key, expectedState); + ActivityState updatedState = integrationServiceMock.updateState(key, state); // THEN - assertThat(actualNewState).isSameAs(expectedState); - assertThat(actualNewState.getLastRecordedTime()).isEqualTo(expectedLastRecordedTime); - assertThat(actualNewState.getLastReportedTime()).isEqualTo(expectedLastReportedTime); - assertThat(actualNewState.getStrategy()).isSameAs(expectedStrategy); - verifyNoInteractions(expectedStrategy); - assertThat(actualNewState.getMetadata()).isNull(); + assertThat(updatedState).isSameAs(state); + verifyNoInteractions(stateSpy); + verifyNoInteractions(strategySpy); } @ParameterizedTest @@ -258,7 +254,8 @@ public class IntegrationActivityManagerTest { return Stream.of( Arguments.of(10L, 0L, 9L), Arguments.of(10L, 7L, 2L), - Arguments.of(10L, 8L, 1L) + Arguments.of(10L, 8L, 1L), + Arguments.of(10000L, 5000L, 3000L) ); } @@ -282,12 +279,13 @@ public class IntegrationActivityManagerTest { return Stream.of( Arguments.of(10L, 9L, 2L), Arguments.of(10L, 0L, 11L), - Arguments.of(10L, 8L, 3L) + Arguments.of(10L, 8L, 3L), + Arguments.of(10000L, 8000L, 3000L) ); } @Test - void givenKeyAndVoidMetadata_whenOnStateExpiryCalled_thenShouldDoNothing() { + void givenKeyAndMetadata_whenOnStateExpiryCalled_thenShouldDoNothing() { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); doCallRealMethod().when(integrationServiceMock).onStateExpiry(key, null); diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java index 1e68779b70..735ec1d524 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java @@ -212,7 +212,7 @@ public class DefaultCoapClientContext implements CoapClientContext { public void reportActivity() { for (TbCoapClientState state : clients.values()) { if (state.getSession() != null) { - transportService.reportActivity(state.getSession()); + transportService.recordActivity(state.getSession()); } } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 90bddd2edc..8360111a54 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -322,7 +322,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement case PINGREQ: if (checkConnected(ctx, msg)) { ctx.writeAndFlush(new MqttMessage(new MqttFixedHeader(PINGRESP, false, AT_MOST_ONCE, false, 0))); - transportService.reportActivity(deviceSessionCtx.getSessionInfo()); + transportService.recordActivity(deviceSessionCtx.getSessionInfo()); } break; case DISCONNECT: @@ -350,7 +350,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement if (topicName.startsWith(MqttTopics.BASE_GATEWAY_API_TOPIC)) { if (gatewaySessionHandler != null) { handleGatewayPublishMsg(ctx, topicName, msgId, mqttMsg); - transportService.reportActivity(deviceSessionCtx.getSessionInfo()); + transportService.recordActivity(deviceSessionCtx.getSessionInfo()); } else { log.error("[gatewaySessionHandler] is null, [{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId); } @@ -526,7 +526,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement transportService.process(deviceSessionCtx.getSessionInfo(), getAttributeMsg, getPubAckCallback(ctx, msgId, getAttributeMsg)); attrReqTopicType = TopicType.V2; } else { - transportService.reportActivity(deviceSessionCtx.getSessionInfo()); + transportService.recordActivity(deviceSessionCtx.getSessionInfo()); ack(ctx, msgId, ReturnCode.TOPIC_NAME_INVALID); } } catch (AdaptorException e) { @@ -796,7 +796,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } if (!activityReported) { - transportService.reportActivity(deviceSessionCtx.getSessionInfo()); + transportService.recordActivity(deviceSessionCtx.getSessionInfo()); } ctx.writeAndFlush(createSubAckMessage(mqttMsg.variableHeader().messageId(), grantedQoSList)); } @@ -894,7 +894,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } if (!activityReported) { - transportService.reportActivity(deviceSessionCtx.getSessionInfo()); + transportService.recordActivity(deviceSessionCtx.getSessionInfo()); } ctx.writeAndFlush(createUnSubAckMessage(mqttMsg.variableHeader().messageId(), unSubResults)); } diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java index 5d41918cab..3a8811df97 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java @@ -416,7 +416,7 @@ public class SnmpTransportService implements TbTransportService, CommandResponde } private void reportActivity(TransportProtos.SessionInfoProto sessionInfo) { - transportService.reportActivity(sessionInfo); + transportService.recordActivity(sessionInfo); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index f51b399a5b..d394af3101 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -145,7 +145,7 @@ public interface TransportService { SessionMetaData registerSyncSession(SessionInfoProto sessionInfo, SessionMsgListener listener, long timeout); - void reportActivity(SessionInfoProto sessionInfo); + void recordActivity(SessionInfoProto sessionInfo); void lifecycleEvent(TenantId tenantId, DeviceId deviceId, ComponentLifecycleEvent eventType, boolean success, Throwable error); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index b5f4bf8f9e..07217e57e8 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -129,7 +129,8 @@ public abstract class AbstractActivityManager implements Activity } } - protected long getLastRecordedTime(Key key) { + @Override + public long getLastRecordedTime(Key key) { ActivityState state = states.get(key); return state == null ? 0L : state.getLastRecordedTime(); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index f19b9e30ca..847e8f4472 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -36,4 +36,6 @@ public interface ActivityManager { void onActivity(Key key); + long getLastRecordedTime(Key key); + } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java index 27797c5315..ba7ceab517 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -30,6 +30,9 @@ */ package org.thingsboard.server.common.transport.activity.strategy; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode public class AllEventsActivityStrategy implements ActivityStrategy { @Override diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java index c2605cdeaf..225d02ccb8 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -30,6 +30,9 @@ */ package org.thingsboard.server.common.transport.activity.strategy; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode public class FirstAndLastEventActivityStrategy implements ActivityStrategy { private boolean firstEventReceived; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index d61c7a68aa..f4f53de6c0 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -30,6 +30,9 @@ */ package org.thingsboard.server.common.transport.activity.strategy; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode public class FirstEventActivityStrategy implements ActivityStrategy { private boolean firstEventReceived; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java index e22263096e..f16fbed8d6 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -30,6 +30,9 @@ */ package org.thingsboard.server.common.transport.activity.strategy; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode public class LastEventActivityStrategy implements ActivityStrategy { @Override diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 9cd41e7a62..da0ef3ca99 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -558,7 +558,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) .setSessionEvent(msg).build(), callback); } @@ -578,7 +578,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback, msg.getKvCount())) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); TenantId tenantId = getTenantId(sessionInfo); DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB())); JsonObject json = JsonUtils.getJsonObject(msg.getKvList()); @@ -639,7 +639,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) .setGetAttributes(msg).build(), new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); } @@ -652,7 +652,7 @@ public class DefaultTransportService extends AbstractActivityManager(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); } @@ -665,7 +665,7 @@ public class DefaultTransportService extends AbstractActivityManager(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); } @@ -674,7 +674,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setToDeviceRPCCallResponse(msg).build(), new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); } @@ -683,7 +683,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setUplinkNotificationMsg(msg).build(), callback); } } @@ -704,7 +704,7 @@ public class DefaultTransportService extends AbstractActivityManager(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, TransportServiceCallback.EMPTY)); @@ -736,7 +736,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); UUID sessionId = toSessionId(sessionInfo); TenantId tenantId = getTenantId(sessionInfo); DeviceId deviceId = getDeviceId(sessionInfo); @@ -761,7 +761,7 @@ public class DefaultTransportService extends AbstractActivityManager callback) { if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); + recordActivityInternal(sessionInfo); sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo) .setClaimDevice(msg).build(), callback); } @@ -780,11 +780,11 @@ public class DefaultTransportService extends AbstractActivityManager lastRecordedTime; + return (getCurrentTimeMillis() - sessionInactivityTimeout) > lastRecordedTime; + } + + long getCurrentTimeMillis() { + return System.currentTimeMillis(); } @Override @@ -937,7 +941,7 @@ public class DefaultTransportService extends AbstractActivityManager sessions; + + @BeforeEach + public void setup() { + sessions = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(transportServiceMock, "sessions", sessions); + } + +// @Override +// protected void reportActivity(UUID sessionId, TransportProtos.SessionInfoProto currentSessionInfo, long timeToReport, ActivityReportCallback callback) { +// log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", name, sessionId, timeToReport); +// SessionMetaData session = sessions.get(sessionId); +// TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() +// .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) +// .setRpcSubscription(session != null && session.isSubscribedToRPC()) +// .setLastActivityTime(timeToReport) +// .build(); +// TransportProtos.SessionInfoProto sessionInfo = session != null ? session.getSessionInfo() : currentSessionInfo; +// process(sessionInfo, subscriptionInfo, new TransportServiceCallback<>() { +// @Override +// public void onSuccess(Void msgAcknowledged) { +// callback.onSuccess(sessionId, timeToReport); +// +// } +// +// @Override +// public void onError(Throwable e) { +// callback.onFailure(sessionId, e); +// } +// }); +// } + + @Test + void givenKeyAndTimeToReportAndSessionExists_whenReportingActivity_thenShouldReportActivityWithSubscriptionsAndSessionInfoFromSession() { + // GIVEN + long expectedTime = 123L; + boolean expectedAttributesSubscription = true; + boolean expectedRPCSubscription = true; + TransportProtos.SessionInfoProto expectedSessionInfo = TransportProtos.SessionInfoProto.getDefaultInstance(); + + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + SessionMetaData session = new SessionMetaData(expectedSessionInfo, TransportProtos.SessionType.ASYNC, listenerMock); + session.setSubscribedToAttributes(expectedAttributesSubscription); + session.setSubscribedToRPC(expectedRPCSubscription); + sessions.put(SESSION_ID, session); + + ActivityReportCallback callbackMock = mock(ActivityReportCallback.class); + + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + + doCallRealMethod().when(transportServiceMock).reportActivity(SESSION_ID, sessionInfo, expectedTime, callbackMock); + + // WHEN + transportServiceMock.reportActivity(SESSION_ID, sessionInfo, expectedTime, callbackMock); + + // THEN + ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); + ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + + verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); + + assertThat(sessionInfoCaptor.getValue()).isEqualTo(expectedSessionInfo); + + TransportProtos.SubscriptionInfoProto expectedSubscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(expectedAttributesSubscription) + .setRpcSubscription(expectedRPCSubscription) + .setLastActivityTime(expectedTime) + .build(); + assertThat(subscriptionInfoCaptor.getValue()).isEqualTo(expectedSubscriptionInfo); + + TransportServiceCallback queueCallback = callbackCaptor.getValue(); + + queueCallback.onSuccess(null); + verify(callbackMock).onSuccess(SESSION_ID, expectedTime); + + var throwable = new Throwable(); + queueCallback.onError(throwable); + verify(callbackMock).onFailure(SESSION_ID, throwable); + } + + @Test + void givenKeyAndTimeToReportAndSessionDoesNotExist_whenReportingActivity_thenShouldReportActivityWithNoSubscriptionsAndPreviousSessionInfo() { + // GIVEN + long expectedTime = 123L; + boolean expectedAttributesSubscription = false; + boolean expectedRPCSubscription = false; + TransportProtos.SessionInfoProto expectedSessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + + ActivityReportCallback callbackMock = mock(ActivityReportCallback.class); + + doCallRealMethod().when(transportServiceMock).reportActivity(SESSION_ID, expectedSessionInfo, expectedTime, callbackMock); + + // WHEN + transportServiceMock.reportActivity(SESSION_ID, expectedSessionInfo, expectedTime, callbackMock); + + // THEN + ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); + ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + + verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); + + assertThat(sessionInfoCaptor.getValue()).isEqualTo(expectedSessionInfo); + + TransportProtos.SubscriptionInfoProto expectedSubscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(expectedAttributesSubscription) + .setRpcSubscription(expectedRPCSubscription) + .setLastActivityTime(expectedTime) + .build(); + assertThat(subscriptionInfoCaptor.getValue()).isEqualTo(expectedSubscriptionInfo); + + TransportServiceCallback queueCallback = callbackCaptor.getValue(); + + queueCallback.onSuccess(null); + verify(callbackMock).onSuccess(SESSION_ID, expectedTime); + + var throwable = new Throwable(); + queueCallback.onError(throwable); + verify(callbackMock).onFailure(SESSION_ID, throwable); + } + + @Test + void givenActivityHappened_whenRecordActivity_thenShouldDelegateToOnActivity() { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + doCallRealMethod().when(transportServiceMock).recordActivity(sessionInfo); + when(transportServiceMock.toSessionId(sessionInfo)).thenReturn(SESSION_ID); + + // WHEN + transportServiceMock.recordActivity(sessionInfo); + + // THEN + verify(transportServiceMock).onActivity(SESSION_ID); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForCreateNewState") + void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy( + String reportingStrategyName, ActivityStrategy reportingStrategy + ) { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + ReflectionTestUtils.setField(transportServiceMock, "reportingStrategyName", reportingStrategyName); + + when(transportServiceMock.createNewState(SESSION_ID)).thenCallRealMethod(); + + ActivityState expectedState = new ActivityState<>(); + expectedState.setStrategy(reportingStrategy); + expectedState.setMetadata(sessionInfo); + + // WHEN + ActivityState actualState = transportServiceMock.createNewState(SESSION_ID); + + // THEN + assertThat(actualState).isEqualTo(expectedState); + } + + private static Stream provideTestParamsForCreateNewState() { + return Stream.of( + Arguments.of("ALL", new AllEventsActivityStrategy()), + Arguments.of("FIRST", new FirstEventActivityStrategy()), + Arguments.of("LAST", new LastEventActivityStrategy()), + Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy()) + ); + } + + @Test + void givenSessionDoesNotExist_whenUpdatingActivityState_thenShouldReturnNull() { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(123L); + state.setLastReportedTime(312L); + state.setMetadata(sessionInfo); + state.setStrategy(new FirstEventActivityStrategy()); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isNull(); + } + + @Test + void givenNoGwSessionId_whenUpdatingActivityState_thenShouldReturnSameInstanceWithUpdatedSessionInfo() { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + long lastRecordedTime = 123L; + long lastReportedTime = 312L; + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(lastRecordedTime); + state.setLastReportedTime(lastReportedTime); + state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); + state.setStrategy(strategySpy); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isSameAs(state); + assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); + assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); + assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); + assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); + verifyNoInteractions(strategySpy); + } + + @Test + void givenHasGwSessionIdButGwSessionIsNotNull_whenUpdatingActivityState_thenShouldReturnSameInstanceWithUpdatedSessionInfo() { + // GIVEN + var gwSessionId = UUID.fromString("19864038-9b48-11ee-b9d1-0242ac120002"); + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .setGwSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setGwSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + long lastRecordedTime = 123L; + long lastReportedTime = 312L; + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(lastRecordedTime); + state.setLastReportedTime(lastReportedTime); + state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); + state.setStrategy(strategySpy); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isSameAs(state); + assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); + assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); + assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); + assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); + verifyNoInteractions(strategySpy); + + verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId); + } + + @Test + void givenHasGwSessionWithoutOverwriteEnabled_whenUpdatingActivityState_thenShouldReturnSameInstanceWithUpdatedSessionInfo() { + // GIVEN + var gwSessionId = UUID.fromString("19864038-9b48-11ee-b9d1-0242ac120002"); + TransportProtos.SessionInfoProto gwSessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener gwListenerMock = mock(SessionMsgListener.class); + sessions.put(gwSessionId, new SessionMetaData(gwSessionInfo, TransportProtos.SessionType.ASYNC, gwListenerMock)); + + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .setGwSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setGwSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + long lastRecordedTime = 123L; + long lastReportedTime = 312L; + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(lastRecordedTime); + state.setLastReportedTime(lastReportedTime); + state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); + state.setStrategy(strategySpy); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isSameAs(state); + assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); + assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); + assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); + assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); + verifyNoInteractions(strategySpy); + + verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId); + } + + @Test + void givenHasGwSessionWithOverwriteEnabledAndGwLastRecordedTimeIsGreater_whenUpdatingActivityState_thenShouldReturnSameInstanceWithUpdatedSessionInfoAndLastRecordedTime() { + // GIVEN + var gwSessionId = UUID.fromString("19864038-9b48-11ee-b9d1-0242ac120002"); + TransportProtos.SessionInfoProto gwSessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener gwListenerMock = mock(SessionMsgListener.class); + SessionMetaData gwSession = new SessionMetaData(gwSessionInfo, TransportProtos.SessionType.ASYNC, gwListenerMock); + gwSession.setOverwriteActivityTime(true); + sessions.put(gwSessionId, gwSession); + + long gwLastRecordedTime = 500L; + when(transportServiceMock.getLastRecordedTime(gwSessionId)).thenReturn(gwLastRecordedTime); + + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .setGwSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setGwSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + long lastRecordedTime = 123L; + long lastReportedTime = 312L; + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(lastRecordedTime); + state.setLastReportedTime(lastReportedTime); + state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); + state.setStrategy(strategySpy); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isSameAs(state); + assertThat(updatedState.getLastRecordedTime()).isEqualTo(gwLastRecordedTime); + assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); + assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); + assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); + verifyNoInteractions(strategySpy); + } + + @Test + void givenHasGwSessionWithOverwriteEnabledAndGwLastRecordedTimeIsLess_whenUpdatingActivityState_thenShouldReturnSameInstanceWithUpdatedSessionInfoOnly() { + // GIVEN + var gwSessionId = UUID.fromString("19864038-9b48-11ee-b9d1-0242ac120002"); + TransportProtos.SessionInfoProto gwSessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener gwListenerMock = mock(SessionMsgListener.class); + SessionMetaData gwSession = new SessionMetaData(gwSessionInfo, TransportProtos.SessionType.ASYNC, gwListenerMock); + gwSession.setOverwriteActivityTime(true); + sessions.put(gwSessionId, gwSession); + + long gwLastRecordedTime = 100L; + when(transportServiceMock.getLastRecordedTime(gwSessionId)).thenReturn(gwLastRecordedTime); + + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .setGwSessionIdMSB(gwSessionId.getMostSignificantBits()) + .setGwSessionIdLSB(gwSessionId.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + + long lastRecordedTime = 123L; + long lastReportedTime = 312L; + ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); + + ActivityState state = new ActivityState<>(); + state.setLastRecordedTime(lastRecordedTime); + state.setLastReportedTime(lastReportedTime); + state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); + state.setStrategy(strategySpy); + + when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); + + // WHEN + ActivityState updatedState = transportServiceMock.updateState(SESSION_ID, state); + + // THEN + assertThat(updatedState).isSameAs(state); + assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); + assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); + assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); + assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); + verifyNoInteractions(strategySpy); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForHasExpiredTrue") + public void givenExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnTrue(long currentTimeMillis, long lastRecordedTime, long sessionInactivityTimeout) { + // GIVEN + ReflectionTestUtils.setField(transportServiceMock, "sessionInactivityTimeout", sessionInactivityTimeout); + + when(transportServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); + when(transportServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); + + // WHEN + boolean hasExpired = transportServiceMock.hasExpired(lastRecordedTime); + + // THEN + assertThat(hasExpired).isTrue(); + } + + private static Stream provideTestParamsForHasExpiredTrue() { + return Stream.of( + Arguments.of(10L, 0L, 9L), + Arguments.of(10L, 7L, 2L), + Arguments.of(10L, 8L, 1L), + Arguments.of(10000L, 5000L, 3000L) + ); + } + + @ParameterizedTest + @MethodSource("provideTestParamsForHasExpiredFalse") + public void givenNotExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnFalse(long currentTimeMillis, long lastRecordedTime, long sessionInactivityTimeout) { + // GIVEN + ReflectionTestUtils.setField(transportServiceMock, "sessionInactivityTimeout", sessionInactivityTimeout); + + when(transportServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); + when(transportServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); + + // WHEN + boolean hasExpired = transportServiceMock.hasExpired(lastRecordedTime); + + // THEN + assertThat(hasExpired).isFalse(); + } + + private static Stream provideTestParamsForHasExpiredFalse() { + return Stream.of( + Arguments.of(10L, 9L, 2L), + Arguments.of(10L, 0L, 11L), + Arguments.of(10L, 8L, 3L), + Arguments.of(10000L, 8000L, 3000L) + ); + } + + @Test + void givenSessionExists_whenOnStateExpiryCalled_thenShouldPerformExpirationActions() { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + SessionMsgListener listenerMock = mock(SessionMsgListener.class); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); + doCallRealMethod().when(transportServiceMock).onStateExpiry(SESSION_ID, sessionInfo); + + // WHEN + transportServiceMock.onStateExpiry(SESSION_ID, sessionInfo); + + // THEN + assertThat(sessions.containsKey(SESSION_ID)).isFalse(); + verify(transportServiceMock).deregisterSession(sessionInfo); + verify(transportServiceMock).process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + verify(listenerMock).onRemoteSessionCloseCommand(SESSION_ID, SESSION_EXPIRED_NOTIFICATION_PROTO); + } + + @Test + void givenSessionDoesNotExist_whenOnStateExpiryCalled_thenShouldNotPerformExpirationActions() { + // GIVEN + TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() + .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) + .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) + .build(); + doCallRealMethod().when(transportServiceMock).onStateExpiry(SESSION_ID, sessionInfo); + + // WHEN + transportServiceMock.onStateExpiry(SESSION_ID, sessionInfo); + + // THEN + assertThat(sessions.containsKey(SESSION_ID)).isFalse(); + verify(transportServiceMock, never()).deregisterSession(sessionInfo); + verify(transportServiceMock, never()).process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + } + +} From 07b8140b779bcc1b5edf1e67162e1625b588029d Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 15 Dec 2023 16:13:42 +0200 Subject: [PATCH 76/91] Remove missed comment --- .../service/TransportActivityManagerTest.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index a97a32a26e..6ad48043ce 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -82,30 +82,6 @@ public class TransportActivityManagerTest { ReflectionTestUtils.setField(transportServiceMock, "sessions", sessions); } -// @Override -// protected void reportActivity(UUID sessionId, TransportProtos.SessionInfoProto currentSessionInfo, long timeToReport, ActivityReportCallback callback) { -// log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", name, sessionId, timeToReport); -// SessionMetaData session = sessions.get(sessionId); -// TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() -// .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) -// .setRpcSubscription(session != null && session.isSubscribedToRPC()) -// .setLastActivityTime(timeToReport) -// .build(); -// TransportProtos.SessionInfoProto sessionInfo = session != null ? session.getSessionInfo() : currentSessionInfo; -// process(sessionInfo, subscriptionInfo, new TransportServiceCallback<>() { -// @Override -// public void onSuccess(Void msgAcknowledged) { -// callback.onSuccess(sessionId, timeToReport); -// -// } -// -// @Override -// public void onError(Throwable e) { -// callback.onFailure(sessionId, e); -// } -// }); -// } - @Test void givenKeyAndTimeToReportAndSessionExists_whenReportingActivity_thenShouldReportActivityWithSubscriptionsAndSessionInfoFromSession() { // GIVEN From a5c06ec70d6f721012470b1f1ce83c36a5b04c76 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Mon, 18 Dec 2023 09:41:45 +0200 Subject: [PATCH 77/91] Refactor: strategy creation, hide implementation details from clients --- .../IntegrationActivityManagerTest.java | 46 +++++------ .../activity/AbstractActivityManager.java | 53 ++++++++----- .../transport/activity/ActivityState.java | 3 - .../strategy/ActivityStrategyType.java} | 36 ++++++--- .../strategy/AllEventsActivityStrategy.java | 12 ++- .../FirstAndLastEventActivityStrategy.java | 2 +- .../strategy/FirstEventActivityStrategy.java | 2 +- .../strategy/LastEventActivityStrategy.java | 12 ++- .../service/DefaultTransportService.java | 11 ++- .../strategy/ActivityStrategyFactoryTest.java | 70 ----------------- .../strategy/ActivityStrategyTypeTest.java} | 39 +++++----- .../AllEventsActivityStrategyTest.java | 2 +- .../LastEventActivityStrategyTest.java | 2 +- .../service/TransportActivityManagerTest.java | 77 ++++--------------- 14 files changed, 148 insertions(+), 219 deletions(-) rename common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/{service/TransportActivityState.java => activity/strategy/ActivityStrategyType.java} (68%) delete mode 100644 common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java rename common/transport/transport-api/src/{main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java => test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java} (62%) diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java index fdb1710189..3b85261bac 100644 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -46,10 +47,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.AllEventsActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.FirstAndLastEventActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.FirstEventActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.LastEventActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueProducer; @@ -181,33 +179,32 @@ public class IntegrationActivityManagerTest { verify(integrationServiceMock).onActivity(key); } - @ParameterizedTest - @MethodSource("provideTestParamsForCreateNewState") - void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy( - String reportingStrategyName, ActivityStrategy reportingStrategy - ) { + @Test + void givenKey_whenCreatingNewState_thenShouldCorrectlyCreateNewEmptyState() { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); when(integrationServiceMock.createNewState(key)).thenCallRealMethod(); - ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyName", reportingStrategyName); - - ActivityState expectedState = new ActivityState<>(); - expectedState.setStrategy(reportingStrategy); // WHEN - ActivityState actualState = integrationServiceMock.createNewState(key); + ActivityState actualNewState = integrationServiceMock.createNewState(key); // THEN - assertThat(actualState).isEqualTo(expectedState); + ActivityState expectedNewState = new ActivityState<>(); + assertThat(actualNewState).isEqualTo(expectedNewState); } - private static Stream provideTestParamsForCreateNewState() { - return Stream.of( - Arguments.of("ALL", new AllEventsActivityStrategy()), - Arguments.of("FIRST", new FirstEventActivityStrategy()), - Arguments.of("LAST", new LastEventActivityStrategy()), - Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy()) - ); + @ParameterizedTest + @EnumSource(ActivityStrategyType.class) + void givenDifferentReportingStrategies_whenGettingStrategy_thenShouldReturnCorrectStrategy(ActivityStrategyType reportingStrategyType) { + // GIVEN + doCallRealMethod().when(integrationServiceMock).getStrategy(); + ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyType", reportingStrategyType); + + // WHEN + ActivityStrategy actualStrategy = integrationServiceMock.getStrategy(); + + // THEN + assertThat(actualStrategy).isEqualTo(reportingStrategyType.toStrategy()); } @Test @@ -215,12 +212,8 @@ public class IntegrationActivityManagerTest { // GIVEN var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); - ActivityState state = new ActivityState<>(); state.setLastRecordedTime(123L); - state.setLastReportedTime(312L); - state.setStrategy(strategySpy); ActivityState stateSpy = spy(state); when(integrationServiceMock.updateState(key, state)).thenCallRealMethod(); @@ -231,7 +224,6 @@ public class IntegrationActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); verifyNoInteractions(stateSpy); - verifyNoInteractions(strategySpy); } @ParameterizedTest diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 07217e57e8..2124eb13d2 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -30,9 +30,11 @@ */ package org.thingsboard.server.common.transport.activity; +import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; import org.thingsboard.server.queue.scheduler.SchedulerComponent; import java.util.Map; @@ -45,7 +47,7 @@ import java.util.concurrent.atomic.AtomicBoolean; @Slf4j public abstract class AbstractActivityManager implements ActivityManager { - private final ConcurrentMap> states = new ConcurrentHashMap<>(); + private final ConcurrentMap states = new ConcurrentHashMap<>(); @Autowired protected SchedulerComponent scheduler; @@ -53,6 +55,15 @@ public abstract class AbstractActivityManager implements Activity protected String name; private boolean initialized; + @Data + private class ActivityStateWrapper { + + private volatile ActivityState state; + private volatile long lastReportedTime; + private volatile ActivityStrategy strategy; + + } + @Override public synchronized void init(String name, long reportingPeriodMillis) { if (!initialized) { @@ -70,6 +81,8 @@ public abstract class AbstractActivityManager implements Activity protected abstract ActivityState createNewState(Key key); + protected abstract ActivityStrategy getStrategy(); + protected abstract ActivityState updateState(Key key, ActivityState state); protected abstract boolean hasExpired(long lastRecordedTime); @@ -92,27 +105,31 @@ public abstract class AbstractActivityManager implements Activity long newLastRecordedTime = System.currentTimeMillis(); var shouldReport = new AtomicBoolean(false); - var activityState = states.compute(key, (__, state) -> { - if (state == null) { + var activityStateWrapper = states.compute(key, (__, stateWrapper) -> { + if (stateWrapper == null) { var newState = createNewState(key); if (newState == null) { return null; } - state = newState; + stateWrapper = new ActivityStateWrapper(); + stateWrapper.setState(newState); + stateWrapper.setStrategy(getStrategy()); } + var state = stateWrapper.getState(); if (state.getLastRecordedTime() < newLastRecordedTime) { state.setLastRecordedTime(newLastRecordedTime); } - shouldReport.set(state.getStrategy().onActivity()); - return state; + shouldReport.set(stateWrapper.getStrategy().onActivity()); + return stateWrapper; }); - if (activityState == null) { + if (activityStateWrapper == null) { return; } + var activityState = activityStateWrapper.getState(); long lastRecordedTime = activityState.getLastRecordedTime(); - long lastReportedTime = activityState.getLastReportedTime(); + long lastReportedTime = activityStateWrapper.getLastReportedTime(); if (shouldReport.get() && lastReportedTime < lastRecordedTime) { log.debug("[{}] Going to report first activity event for key: [{}].", name, key); reportActivity(key, activityState.getMetadata(), lastRecordedTime, new ActivityReportCallback<>() { @@ -131,18 +148,19 @@ public abstract class AbstractActivityManager implements Activity @Override public long getLastRecordedTime(Key key) { - ActivityState state = states.get(key); - return state == null ? 0L : state.getLastRecordedTime(); + ActivityStateWrapper stateWrapper = states.get(key); + return stateWrapper == null ? 0L : stateWrapper.getState().getLastRecordedTime(); } private void onReportingPeriodEnd() { log.debug("[{}] Going to end reporting period.", name); - for (Map.Entry> entry : states.entrySet()) { + for (Map.Entry entry : states.entrySet()) { var key = entry.getKey(); - var currentState = entry.getValue(); + var stateWrapper = entry.getValue(); + var currentState = stateWrapper.getState(); long lastRecordedTime = currentState.getLastRecordedTime(); - long lastReportedTime = currentState.getLastReportedTime(); + long lastReportedTime = stateWrapper.getLastReportedTime(); var metadata = currentState.getMetadata(); boolean hasExpired; @@ -151,10 +169,9 @@ public abstract class AbstractActivityManager implements Activity var updatedState = updateState(key, currentState); if (updatedState != null) { lastRecordedTime = updatedState.getLastRecordedTime(); - lastReportedTime = updatedState.getLastReportedTime(); metadata = updatedState.getMetadata(); hasExpired = hasExpired(lastRecordedTime); - shouldReport = updatedState.getStrategy().onReportingPeriodEnd(); + shouldReport = stateWrapper.getStrategy().onReportingPeriodEnd(); } else { states.remove(key); hasExpired = false; @@ -185,9 +202,9 @@ public abstract class AbstractActivityManager implements Activity } private void updateLastReportedTime(Key key, long newLastReportedTime) { - states.computeIfPresent(key, (__, state) -> { - state.setLastReportedTime(Math.max(state.getLastReportedTime(), newLastReportedTime)); - return state; + states.computeIfPresent(key, (__, stateWrapper) -> { + stateWrapper.setLastReportedTime(Math.max(stateWrapper.getLastReportedTime(), newLastReportedTime)); + return stateWrapper; }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java index f0f607ddd3..b470a52d9d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java @@ -31,14 +31,11 @@ package org.thingsboard.server.common.transport.activity; import lombok.Data; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; @Data public class ActivityState { private volatile long lastRecordedTime; - private volatile long lastReportedTime; - private volatile ActivityStrategy strategy; private volatile Metadata metadata; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java similarity index 68% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java rename to common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java index 470699ec5d..bda213936e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityState.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java @@ -28,17 +28,35 @@ * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. */ -package org.thingsboard.server.common.transport.service; +package org.thingsboard.server.common.transport.activity.strategy; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.gen.transport.TransportProtos; +public enum ActivityStrategyType { -@Data -@EqualsAndHashCode(callSuper = true) -public class TransportActivityState extends ActivityState { + ALL { + @Override + public ActivityStrategy toStrategy() { + return AllEventsActivityStrategy.getInstance(); + } + }, + FIRST { + @Override + public ActivityStrategy toStrategy() { + return new FirstEventActivityStrategy(); + } + }, + LAST { + @Override + public ActivityStrategy toStrategy() { + return LastEventActivityStrategy.getInstance(); + } + }, + FIRST_AND_LAST { + @Override + public ActivityStrategy toStrategy() { + return new FirstAndLastEventActivityStrategy(); + } + }; - private volatile TransportProtos.SessionInfoProto sessionInfoProto; + public abstract ActivityStrategy toStrategy(); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java index ba7ceab517..6af3469fd5 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -30,10 +30,16 @@ */ package org.thingsboard.server.common.transport.activity.strategy; -import lombok.EqualsAndHashCode; +public final class AllEventsActivityStrategy implements ActivityStrategy { -@EqualsAndHashCode -public class AllEventsActivityStrategy implements ActivityStrategy { + private static final AllEventsActivityStrategy INSTANCE = new AllEventsActivityStrategy(); + + private AllEventsActivityStrategy() { + } + + public static AllEventsActivityStrategy getInstance() { + return INSTANCE; + } @Override public boolean onActivity() { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java index 225d02ccb8..71682da1ac 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -33,7 +33,7 @@ package org.thingsboard.server.common.transport.activity.strategy; import lombok.EqualsAndHashCode; @EqualsAndHashCode -public class FirstAndLastEventActivityStrategy implements ActivityStrategy { +public final class FirstAndLastEventActivityStrategy implements ActivityStrategy { private boolean firstEventReceived; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index f4f53de6c0..66c2b8a8e2 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -33,7 +33,7 @@ package org.thingsboard.server.common.transport.activity.strategy; import lombok.EqualsAndHashCode; @EqualsAndHashCode -public class FirstEventActivityStrategy implements ActivityStrategy { +public final class FirstEventActivityStrategy implements ActivityStrategy { private boolean firstEventReceived; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java index f16fbed8d6..fd9fe1f3eb 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -30,10 +30,16 @@ */ package org.thingsboard.server.common.transport.activity.strategy; -import lombok.EqualsAndHashCode; +public final class LastEventActivityStrategy implements ActivityStrategy { -@EqualsAndHashCode -public class LastEventActivityStrategy implements ActivityStrategy { + private static final LastEventActivityStrategy INSTANCE = new LastEventActivityStrategy(); + + private LastEventActivityStrategy() { + } + + public static LastEventActivityStrategy getInstance() { + return INSTANCE; + } @Override public boolean onActivity() { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index da0ef3ca99..fb14936ad5 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -74,7 +74,8 @@ import org.thingsboard.server.common.transport.TransportTenantProfileCache; import org.thingsboard.server.common.transport.activity.AbstractActivityManager; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyFactory; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; @@ -158,7 +159,7 @@ public class DefaultTransportService extends AbstractActivityManager state = new ActivityState<>(); state.setMetadata(session.getSessionInfo()); - state.setStrategy(ActivityStrategyFactory.createStrategy(reportingStrategyName)); return state; } + @Override + protected ActivityStrategy getStrategy() { + return reportingStrategyType.toStrategy(); + } + @Override protected ActivityState updateState(UUID sessionId, ActivityState state) { SessionMetaData session = sessions.get(sessionId); diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java deleted file mode 100644 index c6eda7eb25..0000000000 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactoryTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.common.transport.activity.strategy; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class ActivityStrategyFactoryTest { - - @Test - public void testCreateAllEventsStrategy() { - ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("ALL"); - assertInstanceOf(AllEventsActivityStrategy.class, strategy, "Should return an instance of AllEventsActivityStrategy."); - } - - @Test - public void testCreateFirstEventStrategy() { - ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST"); - assertInstanceOf(FirstEventActivityStrategy.class, strategy, "Should return an instance of FirstEventActivityStrategy."); - } - - @Test - public void testCreateLastEventStrategy() { - ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("LAST"); - assertInstanceOf(LastEventActivityStrategy.class, strategy, "Should return an instance of LastEventActivityStrategy."); - } - - @Test - public void testCreateFirstAndLastEventStrategy() { - ActivityStrategy strategy = ActivityStrategyFactory.createStrategy("FIRST_AND_LAST"); - assertInstanceOf(FirstAndLastEventActivityStrategy.class, strategy, "Should return an instance of FirstAndLastEventActivityStrategy."); - } - - @Test - public void testCreateUnknownStrategy() { - assertThrows(IllegalArgumentException.class, () -> ActivityStrategyFactory.createStrategy("UNKNOWN"), - "Should throw IllegalArgumentException for unknown strategy names."); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java similarity index 62% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java rename to common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java index f4619e2afd..854659c1bf 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyFactory.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java @@ -30,29 +30,30 @@ */ package org.thingsboard.server.common.transport.activity.strategy; -public final class ActivityStrategyFactory { +import org.junit.jupiter.api.Test; - private static final String ALL_EVENTS_STRATEGY_NAME = "ALL"; - private static final String FIRST_EVENT_STRATEGY_NAME = "FIRST"; - private static final String LAST_EVENT_STRATEGY_NAME = "LAST"; - private static final String FIRST_AND_LAST_STRATEGY_NAME = "FIRST_AND_LAST"; +import static org.assertj.core.api.Assertions.assertThat; - private ActivityStrategyFactory() { +public class ActivityStrategyTypeTest { + + @Test + public void testCreateAllEventsStrategy() { + assertThat(ActivityStrategyType.ALL.toStrategy()).isEqualTo(AllEventsActivityStrategy.getInstance()); + } + + @Test + public void testCreateFirstEventStrategy() { + assertThat(ActivityStrategyType.FIRST.toStrategy()).isEqualTo(new FirstEventActivityStrategy()); + } + + @Test + public void testCreateLastEventStrategy() { + assertThat(ActivityStrategyType.LAST.toStrategy()).isEqualTo(LastEventActivityStrategy.getInstance()); } - public static ActivityStrategy createStrategy(String strategyName) { - switch (strategyName) { - case ALL_EVENTS_STRATEGY_NAME: - return new AllEventsActivityStrategy(); - case FIRST_EVENT_STRATEGY_NAME: - return new FirstEventActivityStrategy(); - case LAST_EVENT_STRATEGY_NAME: - return new LastEventActivityStrategy(); - case FIRST_AND_LAST_STRATEGY_NAME: - return new FirstAndLastEventActivityStrategy(); - default: - throw new IllegalArgumentException("Unknown activity strategy name: [" + strategyName + "."); - } + @Test + public void testCreateFirstAndLastEventStrategy() { + assertThat(ActivityStrategyType.FIRST_AND_LAST.toStrategy()).isEqualTo(new FirstAndLastEventActivityStrategy()); } } diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java index 22cbc10ca2..01f4bbcef1 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java @@ -41,7 +41,7 @@ public class AllEventsActivityStrategyTest { @BeforeEach public void setUp() { - strategy = new AllEventsActivityStrategy(); + strategy = AllEventsActivityStrategy.getInstance(); } @Test diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java index 51da85a9c3..7b49c2215b 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java @@ -42,7 +42,7 @@ public class LastEventActivityStrategyTest { @BeforeEach public void setUp() { - strategy = new LastEventActivityStrategy(); + strategy = LastEventActivityStrategy.getInstance(); } @Test diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index 6ad48043ce..c966cc5535 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -45,10 +46,7 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.activity.ActivityReportCallback; import org.thingsboard.server.common.transport.activity.ActivityState; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.AllEventsActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.FirstAndLastEventActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.FirstEventActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.LastEventActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; import org.thingsboard.server.gen.transport.TransportProtos; import java.util.UUID; @@ -60,9 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EXPIRED_NOTIFICATION_PROTO; @@ -195,25 +191,18 @@ public class TransportActivityManagerTest { verify(transportServiceMock).onActivity(SESSION_ID); } - @ParameterizedTest - @MethodSource("provideTestParamsForCreateNewState") - void givenDifferentReportingStrategies_whenCreatingNewState_thenShouldCreateEmptyStateWithCorrectStrategy( - String reportingStrategyName, ActivityStrategy reportingStrategy - ) { + @Test + void givenKey_whenCreatingNewState_thenShouldCorrectlyCreateNewEmptyState() { // GIVEN TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() .setSessionIdMSB(SESSION_ID.getMostSignificantBits()) .setSessionIdLSB(SESSION_ID.getLeastSignificantBits()) .build(); - SessionMsgListener listenerMock = mock(SessionMsgListener.class); - sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); - - ReflectionTestUtils.setField(transportServiceMock, "reportingStrategyName", reportingStrategyName); + sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, null)); when(transportServiceMock.createNewState(SESSION_ID)).thenCallRealMethod(); ActivityState expectedState = new ActivityState<>(); - expectedState.setStrategy(reportingStrategy); expectedState.setMetadata(sessionInfo); // WHEN @@ -223,13 +212,18 @@ public class TransportActivityManagerTest { assertThat(actualState).isEqualTo(expectedState); } - private static Stream provideTestParamsForCreateNewState() { - return Stream.of( - Arguments.of("ALL", new AllEventsActivityStrategy()), - Arguments.of("FIRST", new FirstEventActivityStrategy()), - Arguments.of("LAST", new LastEventActivityStrategy()), - Arguments.of("FIRST_AND_LAST", new FirstAndLastEventActivityStrategy()) - ); + @ParameterizedTest + @EnumSource(ActivityStrategyType.class) + void givenDifferentReportingStrategies_whenGettingStrategy_thenShouldReturnCorrectStrategy(ActivityStrategyType reportingStrategyType) { + // GIVEN + doCallRealMethod().when(transportServiceMock).getStrategy(); + ReflectionTestUtils.setField(transportServiceMock, "reportingStrategyType", reportingStrategyType); + + // WHEN + ActivityStrategy actualStrategy = transportServiceMock.getStrategy(); + + // THEN + assertThat(actualStrategy).isEqualTo(reportingStrategyType.toStrategy()); } @Test @@ -242,9 +236,7 @@ public class TransportActivityManagerTest { ActivityState state = new ActivityState<>(); state.setLastRecordedTime(123L); - state.setLastReportedTime(312L); state.setMetadata(sessionInfo); - state.setStrategy(new FirstEventActivityStrategy()); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -266,14 +258,10 @@ public class TransportActivityManagerTest { sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); long lastRecordedTime = 123L; - long lastReportedTime = 312L; - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); ActivityState state = new ActivityState<>(); state.setLastRecordedTime(lastRecordedTime); - state.setLastReportedTime(lastReportedTime); state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); - state.setStrategy(strategySpy); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -283,10 +271,7 @@ public class TransportActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); - assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); - assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); - verifyNoInteractions(strategySpy); } @Test @@ -303,14 +288,10 @@ public class TransportActivityManagerTest { sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); long lastRecordedTime = 123L; - long lastReportedTime = 312L; - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); ActivityState state = new ActivityState<>(); state.setLastRecordedTime(lastRecordedTime); - state.setLastReportedTime(lastReportedTime); state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); - state.setStrategy(strategySpy); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -320,10 +301,7 @@ public class TransportActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); - assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); - assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); - verifyNoInteractions(strategySpy); verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId); } @@ -349,14 +327,10 @@ public class TransportActivityManagerTest { sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); long lastRecordedTime = 123L; - long lastReportedTime = 312L; - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); ActivityState state = new ActivityState<>(); state.setLastRecordedTime(lastRecordedTime); - state.setLastReportedTime(lastReportedTime); state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); - state.setStrategy(strategySpy); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -366,10 +340,7 @@ public class TransportActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); - assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); - assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); - verifyNoInteractions(strategySpy); verify(transportServiceMock, never()).getLastRecordedTime(gwSessionId); } @@ -400,14 +371,10 @@ public class TransportActivityManagerTest { sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); long lastRecordedTime = 123L; - long lastReportedTime = 312L; - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); ActivityState state = new ActivityState<>(); state.setLastRecordedTime(lastRecordedTime); - state.setLastReportedTime(lastReportedTime); state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); - state.setStrategy(strategySpy); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -417,10 +384,7 @@ public class TransportActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); assertThat(updatedState.getLastRecordedTime()).isEqualTo(gwLastRecordedTime); - assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); - assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); - verifyNoInteractions(strategySpy); } @Test @@ -449,14 +413,10 @@ public class TransportActivityManagerTest { sessions.put(SESSION_ID, new SessionMetaData(sessionInfo, TransportProtos.SessionType.ASYNC, listenerMock)); long lastRecordedTime = 123L; - long lastReportedTime = 312L; - ActivityStrategy strategySpy = spy(new FirstEventActivityStrategy()); ActivityState state = new ActivityState<>(); state.setLastRecordedTime(lastRecordedTime); - state.setLastReportedTime(lastReportedTime); state.setMetadata(TransportProtos.SessionInfoProto.getDefaultInstance()); - state.setStrategy(strategySpy); when(transportServiceMock.updateState(SESSION_ID, state)).thenCallRealMethod(); @@ -466,10 +426,7 @@ public class TransportActivityManagerTest { // THEN assertThat(updatedState).isSameAs(state); assertThat(updatedState.getLastRecordedTime()).isEqualTo(lastRecordedTime); - assertThat(updatedState.getLastReportedTime()).isEqualTo(lastReportedTime); assertThat(updatedState.getMetadata()).isEqualTo(sessionInfo); - assertThat(updatedState.getStrategy()).isEqualTo(strategySpy); - verifyNoInteractions(strategySpy); } @ParameterizedTest From 47c72fb4e52ff1ff166135d43cd728049963b5f6 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Mon, 18 Dec 2023 10:16:15 +0200 Subject: [PATCH 78/91] Refactor: remove explicit init method from activity manager interface --- .../activity/AbstractActivityManager.java | 40 ++++++------------- .../transport/activity/ActivityManager.java | 2 - .../service/DefaultTransportService.java | 16 +++++--- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 2124eb13d2..6c41ea70ea 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -33,7 +33,6 @@ package org.thingsboard.server.common.transport.activity; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; import org.thingsboard.server.queue.scheduler.SchedulerComponent; @@ -52,9 +51,6 @@ public abstract class AbstractActivityManager implements Activity @Autowired protected SchedulerComponent scheduler; - protected String name; - private boolean initialized; - @Data private class ActivityStateWrapper { @@ -64,21 +60,13 @@ public abstract class AbstractActivityManager implements Activity } - @Override - public synchronized void init(String name, long reportingPeriodMillis) { - if (!initialized) { - this.name = StringUtils.notBlankOrDefault(name, "activity-manager"); - log.info("Activity manager with name [{}] is initializing.", this.name); - if (reportingPeriodMillis <= 0) { - reportingPeriodMillis = 3000; - log.error("[{}] Negative or zero reporting period millisecond was provided. Going to use reporting period value of 3 seconds.", this.name); - } - scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); - initialized = true; - log.info("Activity manager with name [{}] is initialized.", this.name); - } + protected void init() { + var reportingPeriodMillis = getReportingPeriodMillis(); + scheduler.scheduleAtFixedRate(this::onReportingPeriodEnd, new Random().nextInt((int) reportingPeriodMillis), reportingPeriodMillis, TimeUnit.MILLISECONDS); } + protected abstract long getReportingPeriodMillis(); + protected abstract ActivityState createNewState(Key key); protected abstract ActivityStrategy getStrategy(); @@ -93,15 +81,11 @@ public abstract class AbstractActivityManager implements Activity @Override public void onActivity(Key key) { - if (!initialized) { - log.error("[{}] Failed to process activity event: activity manager is not initialized.", name); - return; - } if (key == null) { - log.error("[{}] Failed to process activity event: provided activity key is null.", name); + log.error("Failed to process activity event: provided activity key is null."); return; } - log.debug("[{}] Received activity event for key: [{}]", name, key); + log.debug("Received activity event for key: [{}]", key); long newLastRecordedTime = System.currentTimeMillis(); var shouldReport = new AtomicBoolean(false); @@ -131,7 +115,7 @@ public abstract class AbstractActivityManager implements Activity long lastRecordedTime = activityState.getLastRecordedTime(); long lastReportedTime = activityStateWrapper.getLastReportedTime(); if (shouldReport.get() && lastReportedTime < lastRecordedTime) { - log.debug("[{}] Going to report first activity event for key: [{}].", name, key); + log.debug("Going to report first activity event for key: [{}].", key); reportActivity(key, activityState.getMetadata(), lastRecordedTime, new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { @@ -140,7 +124,7 @@ public abstract class AbstractActivityManager implements Activity @Override public void onFailure(Key key, Throwable t) { - log.debug("[{}] Failed to report first activity event for key: [{}].", name, key, t); + log.debug("Failed to report first activity event for key: [{}].", key, t); } }); } @@ -153,7 +137,7 @@ public abstract class AbstractActivityManager implements Activity } private void onReportingPeriodEnd() { - log.debug("[{}] Going to end reporting period.", name); + log.debug("Going to end reporting period."); for (Map.Entry entry : states.entrySet()) { var key = entry.getKey(); var stateWrapper = entry.getValue(); @@ -185,7 +169,7 @@ public abstract class AbstractActivityManager implements Activity } if (shouldReport && lastReportedTime < lastRecordedTime) { - log.debug("[{}] Going to report last activity event for key: [{}].", name, key); + log.debug("Going to report last activity event for key: [{}].", key); reportActivity(key, metadata, lastRecordedTime, new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { @@ -194,7 +178,7 @@ public abstract class AbstractActivityManager implements Activity @Override public void onFailure(Key key, Throwable t) { - log.debug("[{}] Failed to report last activity event for key: [{}].", name, key, t); + log.debug("Failed to report last activity event for key: [{}].", key, t); } }); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index 847e8f4472..f8881d1b61 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -32,8 +32,6 @@ package org.thingsboard.server.common.transport.activity; public interface ActivityManager { - void init(String name, long reportingPeriodMillis); - void onActivity(Key key); long getLastRecordedTime(Key key); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index fb14936ad5..f733efef67 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -138,7 +138,6 @@ public class DefaultTransportService extends AbstractActivityManager createNewState(UUID sessionId) { SessionMetaData session = sessions.get(sessionId); @@ -827,9 +831,9 @@ public class DefaultTransportService extends AbstractActivityManager callback) { - log.debug("[{}] Reporting activity state for session with id: [{}]. Time to report: [{}].", name, sessionId, timeToReport); + log.debug("Reporting activity state for session with id: [{}]. Time to report: [{}].", sessionId, timeToReport); SessionMetaData session = sessions.get(sessionId); TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) From a31bd5e2c59dc8a37318f619c0d0848b5aafd9d4 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Mon, 18 Dec 2023 13:40:32 +0200 Subject: [PATCH 79/91] Add tests for onActivity() in integration activity manager, add concurrency fix in onActivity() --- .../IntegrationActivityManagerTest.java | 190 +++++++++++++++++- .../activity/AbstractActivityManager.java | 29 +-- .../transport/activity/ActivityManager.java | 4 +- .../service/DefaultTransportService.java | 2 +- .../service/TransportActivityManagerTest.java | 4 +- 5 files changed, 211 insertions(+), 18 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java index 3b85261bac..c63b267fbf 100644 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -55,15 +55,20 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.PartitionService; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; @@ -78,6 +83,182 @@ public class IntegrationActivityManagerTest { @Mock private DefaultPlatformIntegrationService integrationServiceMock; + @Test + void givenKeyIsNull_whenOnActivity_thenShouldNotRecordAndShouldNotReport() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + IntegrationActivityKey key = null; + + doCallRealMethod().when(integrationServiceMock).onActivity(eq(key), anyLong()); + + // WHEN + integrationServiceMock.onActivity(key, 123L); + + // THEN + assertThat(states.isEmpty()).isTrue(); + verify(integrationServiceMock, never()).createNewState(any()); + verify(integrationServiceMock, never()).getStrategy(); + verify(integrationServiceMock, never()).reportActivity(any(), any(), anyLong(), any()); + } + + @Test + void givenNewActivity_whenOnActivity_thenShouldCreateNewStateAndRecord() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + + long activityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + + // WHEN + integrationServiceMock.onActivity(key, activityTime); + + // THEN + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(activityTime); + verify(integrationServiceMock).createNewState(key); + verify(integrationServiceMock).getStrategy(); + } + + @Test + void givenSubsequentActivities_whenOnActivity_thenShouldRecordBoth() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + + // WHEN-THEN + long firstActivityTime = 100L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(firstActivityTime); + + long secondActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(secondActivityTime); + } + + @Test + void givenActivityAndStrategySaysThatShouldNotReport_whenOnActivity_thenShouldNotReport() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(strategyMock.onActivity()).thenReturn(false); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long activityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); + + // WHEN + integrationServiceMock.onActivity(key, activityTime); + + // THEN + verify(integrationServiceMock, never()).reportActivity(any(), any(), anyLong(), any()); + } + + @Test + void givenActivityAndStrategySaysThatShouldReport_whenOnActivity_thenShouldReport() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(strategyMock.onActivity()).thenReturn(true); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long activityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); + + // WHEN + integrationServiceMock.onActivity(key, activityTime); + + // THEN + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), any()); + } + + @Test + void givenActivityAndStrategySaysThatShouldReportButLastRecordedTimeIsEqualToLastReportedTime_whenOnActivity_thenShouldNotReport() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(strategyMock.onActivity()).thenReturn(true); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + // WHEN-THEN + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + long secondActivityTime = 100L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), any(), eq(secondActivityTime), any()); + } + + @Test + void givenActivityAndStrategySaysThatShouldReportAndLastRecordedTimeIsGreaterThanLastReportedTime_whenOnActivity_thenShouldReport() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + when(strategyMock.onActivity()).thenReturn(true); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + // WHEN-THEN + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + long secondActivityTime = 456L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + } + @Test void givenKeyAndTimeToReport_whenReportingActivity_thenShouldCorrectlyReportActivity() { // GIVEN @@ -148,12 +329,14 @@ public class IntegrationActivityManagerTest { .build(); TransportProtos.PostTelemetryMsg postTelemetryMsg = TransportProtos.PostTelemetryMsg.getDefaultInstance(); doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postTelemetryMsg, null); + long expectedTime = 123L; + when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(expectedTime); // WHEN integrationServiceMock.process(sessionInfo, postTelemetryMsg, null); // THEN - verify(integrationServiceMock).onActivity(key); + verify(integrationServiceMock).onActivity(key, expectedTime); } @Test @@ -172,11 +355,14 @@ public class IntegrationActivityManagerTest { doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postAttributeMsg, null); doNothing().when(integrationServiceMock).sendToRuleEngine(any(), any(), any(), any(), any(), any(), any()); + long activityTime = 123L; + when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(activityTime); + // WHEN integrationServiceMock.process(sessionInfo, postAttributeMsg, null); // THEN - verify(integrationServiceMock).onActivity(key); + verify(integrationServiceMock).onActivity(key, activityTime); } @Test diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 6c41ea70ea..80ab8d8665 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -42,6 +42,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; @Slf4j public abstract class AbstractActivityManager implements ActivityManager { @@ -80,15 +81,17 @@ public abstract class AbstractActivityManager implements Activity protected abstract void reportActivity(Key key, Metadata metadata, long timeToReport, ActivityReportCallback callback); @Override - public void onActivity(Key key) { + public void onActivity(Key key, long newLastRecordedTime) { if (key == null) { log.error("Failed to process activity event: provided activity key is null."); return; } log.debug("Received activity event for key: [{}]", key); - long newLastRecordedTime = System.currentTimeMillis(); var shouldReport = new AtomicBoolean(false); + var lastRecordedTime = new AtomicLong(); + var lastReportedTime = new AtomicLong(); + var activityStateWrapper = states.compute(key, (__, stateWrapper) -> { if (stateWrapper == null) { var newState = createNewState(key); @@ -104,6 +107,8 @@ public abstract class AbstractActivityManager implements Activity state.setLastRecordedTime(newLastRecordedTime); } shouldReport.set(stateWrapper.getStrategy().onActivity()); + lastRecordedTime.set(state.getLastRecordedTime()); + lastReportedTime.set(stateWrapper.getLastReportedTime()); return stateWrapper; }); @@ -111,12 +116,9 @@ public abstract class AbstractActivityManager implements Activity return; } - var activityState = activityStateWrapper.getState(); - long lastRecordedTime = activityState.getLastRecordedTime(); - long lastReportedTime = activityStateWrapper.getLastReportedTime(); - if (shouldReport.get() && lastReportedTime < lastRecordedTime) { + if (shouldReport.get() && lastReportedTime.get() < lastRecordedTime.get()) { log.debug("Going to report first activity event for key: [{}].", key); - reportActivity(key, activityState.getMetadata(), lastRecordedTime, new ActivityReportCallback<>() { + reportActivity(key, activityStateWrapper.getState().getMetadata(), lastRecordedTime.get(), new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -131,12 +133,7 @@ public abstract class AbstractActivityManager implements Activity } @Override - public long getLastRecordedTime(Key key) { - ActivityStateWrapper stateWrapper = states.get(key); - return stateWrapper == null ? 0L : stateWrapper.getState().getLastRecordedTime(); - } - - private void onReportingPeriodEnd() { + public void onReportingPeriodEnd() { log.debug("Going to end reporting period."); for (Map.Entry entry : states.entrySet()) { var key = entry.getKey(); @@ -185,6 +182,12 @@ public abstract class AbstractActivityManager implements Activity } } + @Override + public long getLastRecordedTime(Key key) { + ActivityStateWrapper stateWrapper = states.get(key); + return stateWrapper == null ? 0L : stateWrapper.getState().getLastRecordedTime(); + } + private void updateLastReportedTime(Key key, long newLastReportedTime) { states.computeIfPresent(key, (__, stateWrapper) -> { stateWrapper.setLastReportedTime(Math.max(stateWrapper.getLastReportedTime(), newLastReportedTime)); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index f8881d1b61..c55c94cc54 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -32,7 +32,9 @@ package org.thingsboard.server.common.transport.activity; public interface ActivityManager { - void onActivity(Key key); + void onActivity(Key key, long activityTimeMillis); + + void onReportingPeriodEnd(); long getLastRecordedTime(Key key); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index f733efef67..dc58c79250 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -785,7 +785,7 @@ public class DefaultTransportService extends AbstractActivityManager Date: Tue, 19 Dec 2023 12:18:21 +0200 Subject: [PATCH 80/91] Add tests for onReportingPeriodEnd() in integration activity manager --- .../IntegrationActivityManagerTest.java | 383 ++++++++++++++++++ .../activity/AbstractActivityManager.java | 6 +- 2 files changed, 388 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java index c63b267fbf..3cb40d3cb3 100644 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -70,8 +70,10 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -259,6 +261,387 @@ public class IntegrationActivityManagerTest { verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); } + @Test + void givenUpdatedStateIsNullAndHasUnreportedEvent_whenOnReportingPeriodEnd_thenShouldRemoveStateAndReportEvent() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + // second unreported event + long secondActivityTime = 456L; + when(strategyMock.onActivity()).thenReturn(false); + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + + verify(strategyMock, times(2)).onActivity(); + + long lastRecordedTime = secondActivityTime; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = null; + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).isEmpty(); + verify(integrationServiceMock, never()).hasExpired(anyLong()); + verifyNoMoreInteractions(strategyMock); + verify(integrationServiceMock, never()).onStateExpiry(any(), any()); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(lastRecordedTime), any()); + } + + @Test + void givenUpdatedStateIsNullAndDoesntHaveUnreportedEvent_whenOnReportingPeriodEnd_thenShouldRemoveStateAndShouldNotAnything() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long activityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); + integrationServiceMock.onActivity(key, activityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, activityTime); + + verify(strategyMock).onActivity(); + + long lastRecordedTime = activityTime; + // lastReportedTime = lastRecordedTime = 123L; + ActivityState updatedState = null; + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).isEmpty(); + verify(integrationServiceMock, never()).hasExpired(anyLong()); + verifyNoMoreInteractions(strategyMock); + verify(integrationServiceMock, never()).onStateExpiry(any(), any()); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(lastRecordedTime), any()); + } + + @Test + void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + // second unreported event + long secondActivityTime = 456L; + when(strategyMock.onActivity()).thenReturn(false); + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + + verify(strategyMock, times(2)).onActivity(); + + long updatedLastRecordedTime = 500L; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = new ActivityState<>(); + updatedState.setLastRecordedTime(updatedLastRecordedTime); + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); + when(strategyMock.onReportingPeriodEnd()).thenReturn(true); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).containsKey(key); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); + + verify(integrationServiceMock, never()).onStateExpiry(any(), any()); + + verify(strategyMock).onReportingPeriodEnd(); + verifyNoMoreInteractions(strategyMock); + + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); + } + + @Test + void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldReportAndDoesNotHaveUnreportedEvents_whenOnReportingPeriodEnd_thenShouldNotReportAnything() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long activityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); + integrationServiceMock.onActivity(key, activityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, activityTime); + + verify(strategyMock).onActivity(); + + long updatedLastRecordedTime = 123L; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = new ActivityState<>(); + updatedState.setLastRecordedTime(updatedLastRecordedTime); + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); + when(strategyMock.onReportingPeriodEnd()).thenReturn(true); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).containsKey(key); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); + + verify(integrationServiceMock, never()).onStateExpiry(any(), any()); + + verify(strategyMock).onReportingPeriodEnd(); + verifyNoMoreInteractions(strategyMock); + + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), any()); + } + + @Test + void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldNotReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldNotReportAnything() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + // second unreported event + long secondActivityTime = 456L; + when(strategyMock.onActivity()).thenReturn(false); + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + + verify(strategyMock, times(2)).onActivity(); + + long updatedLastRecordedTime = 500L; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = new ActivityState<>(); + updatedState.setLastRecordedTime(updatedLastRecordedTime); + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); + when(strategyMock.onReportingPeriodEnd()).thenReturn(false); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).containsKey(key); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); + + verify(integrationServiceMock, never()).onStateExpiry(any(), any()); + + verify(strategyMock).onReportingPeriodEnd(); + verifyNoMoreInteractions(strategyMock); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); + } + + @Test + void givenUpdatedStateIsNotNullAndHasExpiredAndStrategySaysThatShouldReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + // second unreported event + long secondActivityTime = 456L; + when(strategyMock.onActivity()).thenReturn(false); + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + + verify(strategyMock, times(2)).onActivity(); + + long updatedLastRecordedTime = 500L; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = new ActivityState<>(); + updatedState.setLastRecordedTime(updatedLastRecordedTime); + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(true); + when(strategyMock.onReportingPeriodEnd()).thenReturn(true); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).isEmpty(); + + verify(integrationServiceMock).onStateExpiry(key, null); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isZero(); + + verify(strategyMock).onReportingPeriodEnd(); + verifyNoMoreInteractions(strategyMock); + + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); + } + + @Test + void givenUpdatedStateIsNotNullAndHasExpiredAndStrategySaysThatShouldNotReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { + // GIVEN + ConcurrentMap states = new ConcurrentHashMap<>(); + ReflectionTestUtils.setField(integrationServiceMock, "states", states); + + var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); + ActivityStrategy strategyMock = mock(ActivityStrategy.class); + + // first reported event + when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); + when(strategyMock.onActivity()).thenReturn(true); + when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); + + long firstActivityTime = 123L; + doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); + integrationServiceMock.onActivity(key, firstActivityTime); + + ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); + firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); + + // second unreported event + long secondActivityTime = 456L; + when(strategyMock.onActivity()).thenReturn(false); + doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); + integrationServiceMock.onActivity(key, secondActivityTime); + + verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); + + verify(strategyMock, times(2)).onActivity(); + + long updatedLastRecordedTime = 500L; + // lastReportedTime = firstActivityTime = 123L; + ActivityState updatedState = new ActivityState<>(); + updatedState.setLastRecordedTime(updatedLastRecordedTime); + + when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); + when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(true); + when(strategyMock.onReportingPeriodEnd()).thenReturn(false); + + // WHEN + doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); + integrationServiceMock.onReportingPeriodEnd(); + + // THEN + assertThat(states).isEmpty(); + + verify(integrationServiceMock).onStateExpiry(key, null); + + when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); + assertThat(integrationServiceMock.getLastRecordedTime(key)).isZero(); + + verify(strategyMock).onReportingPeriodEnd(); + verifyNoMoreInteractions(strategyMock); + + verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); + } + + // TODO: onReportingPeriodEnd() test for updating reported time + @Test void givenKeyAndTimeToReport_whenReportingActivity_thenShouldCorrectlyReportActivity() { // GIVEN diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 80ab8d8665..e9ed4cdcea 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -43,6 +43,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; @Slf4j public abstract class AbstractActivityManager implements ActivityManager { @@ -91,6 +92,7 @@ public abstract class AbstractActivityManager implements Activity var shouldReport = new AtomicBoolean(false); var lastRecordedTime = new AtomicLong(); var lastReportedTime = new AtomicLong(); + var metadata = new AtomicReference(); var activityStateWrapper = states.compute(key, (__, stateWrapper) -> { if (stateWrapper == null) { @@ -109,6 +111,7 @@ public abstract class AbstractActivityManager implements Activity shouldReport.set(stateWrapper.getStrategy().onActivity()); lastRecordedTime.set(state.getLastRecordedTime()); lastReportedTime.set(stateWrapper.getLastReportedTime()); + metadata.set(state.getMetadata()); return stateWrapper; }); @@ -118,7 +121,7 @@ public abstract class AbstractActivityManager implements Activity if (shouldReport.get() && lastReportedTime.get() < lastRecordedTime.get()) { log.debug("Going to report first activity event for key: [{}].", key); - reportActivity(key, activityStateWrapper.getState().getMetadata(), lastRecordedTime.get(), new ActivityReportCallback<>() { + reportActivity(key, metadata.get(), lastRecordedTime.get(), new ActivityReportCallback<>() { @Override public void onSuccess(Key key, long reportedTime) { updateLastReportedTime(key, reportedTime); @@ -149,6 +152,7 @@ public abstract class AbstractActivityManager implements Activity var updatedState = updateState(key, currentState); if (updatedState != null) { + stateWrapper.setState(updatedState); lastRecordedTime = updatedState.getLastRecordedTime(); metadata = updatedState.getMetadata(); hasExpired = hasExpired(lastRecordedTime); From 563debe4212f1e8e83b0c46943bfa1e1e7b73db1 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 11 Jan 2024 13:56:45 +0200 Subject: [PATCH 81/91] Fix license --- .../server/service/integration/IntegrationActivityKey.java | 2 +- .../service/integration/IntegrationActivityManagerTest.java | 2 +- .../common/transport/activity/AbstractActivityManager.java | 2 +- .../server/common/transport/activity/ActivityManager.java | 2 +- .../common/transport/activity/ActivityReportCallback.java | 2 +- .../common/transport/activity/strategy/ActivityStrategy.java | 2 +- .../transport/activity/strategy/ActivityStrategyType.java | 2 +- .../transport/activity/strategy/AllEventsActivityStrategy.java | 2 +- .../activity/strategy/FirstAndLastEventActivityStrategy.java | 2 +- .../transport/activity/strategy/FirstEventActivityStrategy.java | 2 +- .../transport/activity/strategy/LastEventActivityStrategy.java | 2 +- .../transport/activity/strategy/ActivityStrategyTypeTest.java | 2 +- .../activity/strategy/AllEventsActivityStrategyTest.java | 2 +- .../strategy/FirstAndLastEventActivityStrategyTest.java | 2 +- .../activity/strategy/FirstEventActivityStrategyTest.java | 2 +- .../activity/strategy/LastEventActivityStrategyTest.java | 2 +- .../common/transport/service/TransportActivityManagerTest.java | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java b/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java index d830d382cb..683a2d26f8 100644 --- a/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java +++ b/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java index 3cb40d3cb3..f35fcc3bd0 100644 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index e9ed4cdcea..89efec8e1c 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index c55c94cc54..12eae33ee7 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java index 9d009d2707..2b00495ed2 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java index 1bb8dfdcaf..497ed31f9d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java index bda213936e..4db053f84a 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java index 6af3469fd5..6fdbca31ec 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java index 71682da1ac..4b8234ac9b 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index 66c2b8a8e2..3e75154c3e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java index fd9fe1f3eb..b731aa275e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java index 854659c1bf..89232623f6 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java index 01f4bbcef1..2d550991a3 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java index 597693f926..a1cb7ac302 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java index 5d4d270f0f..585c9caeb1 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java index 7b49c2215b..441a88c32f 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index e3e9ded47b..30395f28f4 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -1,7 +1,7 @@ /** * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of ThingsBoard, Inc. and its suppliers, From 4bbe23f9c3af5b3530f1ea4c204d1be3ef6c115b Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 11 Jan 2024 16:36:18 +0200 Subject: [PATCH 82/91] Fix license --- .../integration/IntegrationActivityKey.java | 44 - .../IntegrationActivityManagerTest.java | 858 ------------------ .../activity/AbstractActivityManager.java | 35 +- .../transport/activity/ActivityManager.java | 35 +- .../activity/ActivityReportCallback.java | 35 +- .../transport/activity/ActivityState.java | 35 +- .../activity/strategy/ActivityStrategy.java | 35 +- .../strategy/ActivityStrategyType.java | 35 +- .../strategy/AllEventsActivityStrategy.java | 35 +- .../FirstAndLastEventActivityStrategy.java | 35 +- .../strategy/FirstEventActivityStrategy.java | 35 +- .../strategy/LastEventActivityStrategy.java | 35 +- .../strategy/ActivityStrategyTypeTest.java | 35 +- .../AllEventsActivityStrategyTest.java | 35 +- ...FirstAndLastEventActivityStrategyTest.java | 35 +- .../FirstEventActivityStrategyTest.java | 35 +- .../LastEventActivityStrategyTest.java | 35 +- .../service/TransportActivityManagerTest.java | 35 +- 18 files changed, 160 insertions(+), 1302 deletions(-) delete mode 100644 application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java delete mode 100644 application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java diff --git a/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java b/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java deleted file mode 100644 index 683a2d26f8..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/integration/IntegrationActivityKey.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration; - -import lombok.NonNull; -import lombok.Value; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.TenantId; - -@Value -public class IntegrationActivityKey { - - @NonNull TenantId tenantId; - @NonNull DeviceId deviceId; - -} diff --git a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java b/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java deleted file mode 100644 index f35fcc3bd0..0000000000 --- a/application/src/test/java/org/thingsboard/server/service/integration/IntegrationActivityManagerTest.java +++ /dev/null @@ -1,858 +0,0 @@ -/** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL - * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. - */ -package org.thingsboard.server.service.integration; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; -import org.thingsboard.server.common.data.id.DeviceId; -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.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; -import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.TbQueueCallback; -import org.thingsboard.server.queue.TbQueueProducer; -import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import org.thingsboard.server.queue.discovery.PartitionService; - -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class IntegrationActivityManagerTest { - - private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("1306648a-9b26-11ee-b9d1-0242ac120002")); - private final DeviceId DEVICE_ID = DeviceId.fromString("1d288a06-9b26-11ee-b9d1-0242ac120002"); - - @Mock - private DefaultPlatformIntegrationService integrationServiceMock; - - @Test - void givenKeyIsNull_whenOnActivity_thenShouldNotRecordAndShouldNotReport() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - IntegrationActivityKey key = null; - - doCallRealMethod().when(integrationServiceMock).onActivity(eq(key), anyLong()); - - // WHEN - integrationServiceMock.onActivity(key, 123L); - - // THEN - assertThat(states.isEmpty()).isTrue(); - verify(integrationServiceMock, never()).createNewState(any()); - verify(integrationServiceMock, never()).getStrategy(); - verify(integrationServiceMock, never()).reportActivity(any(), any(), anyLong(), any()); - } - - @Test - void givenNewActivity_whenOnActivity_thenShouldCreateNewStateAndRecord() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - - long activityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - - // WHEN - integrationServiceMock.onActivity(key, activityTime); - - // THEN - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(activityTime); - verify(integrationServiceMock).createNewState(key); - verify(integrationServiceMock).getStrategy(); - } - - @Test - void givenSubsequentActivities_whenOnActivity_thenShouldRecordBoth() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - - // WHEN-THEN - long firstActivityTime = 100L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(firstActivityTime); - - long secondActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(secondActivityTime); - } - - @Test - void givenActivityAndStrategySaysThatShouldNotReport_whenOnActivity_thenShouldNotReport() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(strategyMock.onActivity()).thenReturn(false); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long activityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); - - // WHEN - integrationServiceMock.onActivity(key, activityTime); - - // THEN - verify(integrationServiceMock, never()).reportActivity(any(), any(), anyLong(), any()); - } - - @Test - void givenActivityAndStrategySaysThatShouldReport_whenOnActivity_thenShouldReport() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(strategyMock.onActivity()).thenReturn(true); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long activityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); - - // WHEN - integrationServiceMock.onActivity(key, activityTime); - - // THEN - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), any()); - } - - @Test - void givenActivityAndStrategySaysThatShouldReportButLastRecordedTimeIsEqualToLastReportedTime_whenOnActivity_thenShouldNotReport() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(strategyMock.onActivity()).thenReturn(true); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - // WHEN-THEN - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - long secondActivityTime = 100L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), any(), eq(secondActivityTime), any()); - } - - @Test - void givenActivityAndStrategySaysThatShouldReportAndLastRecordedTimeIsGreaterThanLastReportedTime_whenOnActivity_thenShouldReport() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - when(strategyMock.onActivity()).thenReturn(true); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - // WHEN-THEN - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - long secondActivityTime = 456L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - } - - @Test - void givenUpdatedStateIsNullAndHasUnreportedEvent_whenOnReportingPeriodEnd_thenShouldRemoveStateAndReportEvent() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - // second unreported event - long secondActivityTime = 456L; - when(strategyMock.onActivity()).thenReturn(false); - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - - verify(strategyMock, times(2)).onActivity(); - - long lastRecordedTime = secondActivityTime; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = null; - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).isEmpty(); - verify(integrationServiceMock, never()).hasExpired(anyLong()); - verifyNoMoreInteractions(strategyMock); - verify(integrationServiceMock, never()).onStateExpiry(any(), any()); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(lastRecordedTime), any()); - } - - @Test - void givenUpdatedStateIsNullAndDoesntHaveUnreportedEvent_whenOnReportingPeriodEnd_thenShouldRemoveStateAndShouldNotAnything() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long activityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); - integrationServiceMock.onActivity(key, activityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, activityTime); - - verify(strategyMock).onActivity(); - - long lastRecordedTime = activityTime; - // lastReportedTime = lastRecordedTime = 123L; - ActivityState updatedState = null; - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).isEmpty(); - verify(integrationServiceMock, never()).hasExpired(anyLong()); - verifyNoMoreInteractions(strategyMock); - verify(integrationServiceMock, never()).onStateExpiry(any(), any()); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(lastRecordedTime), any()); - } - - @Test - void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - // second unreported event - long secondActivityTime = 456L; - when(strategyMock.onActivity()).thenReturn(false); - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - - verify(strategyMock, times(2)).onActivity(); - - long updatedLastRecordedTime = 500L; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = new ActivityState<>(); - updatedState.setLastRecordedTime(updatedLastRecordedTime); - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); - when(strategyMock.onReportingPeriodEnd()).thenReturn(true); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).containsKey(key); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); - - verify(integrationServiceMock, never()).onStateExpiry(any(), any()); - - verify(strategyMock).onReportingPeriodEnd(); - verifyNoMoreInteractions(strategyMock); - - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); - } - - @Test - void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldReportAndDoesNotHaveUnreportedEvents_whenOnReportingPeriodEnd_thenShouldNotReportAnything() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long activityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, activityTime); - integrationServiceMock.onActivity(key, activityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, activityTime); - - verify(strategyMock).onActivity(); - - long updatedLastRecordedTime = 123L; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = new ActivityState<>(); - updatedState.setLastRecordedTime(updatedLastRecordedTime); - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); - when(strategyMock.onReportingPeriodEnd()).thenReturn(true); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).containsKey(key); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); - - verify(integrationServiceMock, never()).onStateExpiry(any(), any()); - - verify(strategyMock).onReportingPeriodEnd(); - verifyNoMoreInteractions(strategyMock); - - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(activityTime), any()); - } - - @Test - void givenUpdatedStateIsNotNullAndHasNotExpiredAndStrategySaysThatShouldNotReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldNotReportAnything() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - // second unreported event - long secondActivityTime = 456L; - when(strategyMock.onActivity()).thenReturn(false); - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - - verify(strategyMock, times(2)).onActivity(); - - long updatedLastRecordedTime = 500L; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = new ActivityState<>(); - updatedState.setLastRecordedTime(updatedLastRecordedTime); - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(false); - when(strategyMock.onReportingPeriodEnd()).thenReturn(false); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).containsKey(key); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isEqualTo(updatedLastRecordedTime); - - verify(integrationServiceMock, never()).onStateExpiry(any(), any()); - - verify(strategyMock).onReportingPeriodEnd(); - verifyNoMoreInteractions(strategyMock); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); - } - - @Test - void givenUpdatedStateIsNotNullAndHasExpiredAndStrategySaysThatShouldReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - // second unreported event - long secondActivityTime = 456L; - when(strategyMock.onActivity()).thenReturn(false); - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - - verify(strategyMock, times(2)).onActivity(); - - long updatedLastRecordedTime = 500L; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = new ActivityState<>(); - updatedState.setLastRecordedTime(updatedLastRecordedTime); - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(true); - when(strategyMock.onReportingPeriodEnd()).thenReturn(true); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).isEmpty(); - - verify(integrationServiceMock).onStateExpiry(key, null); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isZero(); - - verify(strategyMock).onReportingPeriodEnd(); - verifyNoMoreInteractions(strategyMock); - - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); - } - - @Test - void givenUpdatedStateIsNotNullAndHasExpiredAndStrategySaysThatShouldNotReportAndHasUnreportedEvents_whenOnReportingPeriodEnd_thenShouldReportEventUsingUpdatedState() { - // GIVEN - ConcurrentMap states = new ConcurrentHashMap<>(); - ReflectionTestUtils.setField(integrationServiceMock, "states", states); - - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - ActivityStrategy strategyMock = mock(ActivityStrategy.class); - - // first reported event - when(integrationServiceMock.createNewState(key)).thenReturn(new ActivityState<>()); - when(strategyMock.onActivity()).thenReturn(true); - when(integrationServiceMock.getStrategy()).thenReturn(strategyMock); - - long firstActivityTime = 123L; - doCallRealMethod().when(integrationServiceMock).onActivity(key, firstActivityTime); - integrationServiceMock.onActivity(key, firstActivityTime); - - ArgumentCaptor> firstCallbackCaptor = ArgumentCaptor.forClass(ActivityReportCallback.class); - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(firstActivityTime), firstCallbackCaptor.capture()); - firstCallbackCaptor.getValue().onSuccess(key, firstActivityTime); - - // second unreported event - long secondActivityTime = 456L; - when(strategyMock.onActivity()).thenReturn(false); - doCallRealMethod().when(integrationServiceMock).onActivity(key, secondActivityTime); - integrationServiceMock.onActivity(key, secondActivityTime); - - verify(integrationServiceMock, never()).reportActivity(eq(key), isNull(), eq(secondActivityTime), any()); - - verify(strategyMock, times(2)).onActivity(); - - long updatedLastRecordedTime = 500L; - // lastReportedTime = firstActivityTime = 123L; - ActivityState updatedState = new ActivityState<>(); - updatedState.setLastRecordedTime(updatedLastRecordedTime); - - when(integrationServiceMock.updateState(eq(key), any())).thenReturn(updatedState); - when(integrationServiceMock.hasExpired(updatedLastRecordedTime)).thenReturn(true); - when(strategyMock.onReportingPeriodEnd()).thenReturn(false); - - // WHEN - doCallRealMethod().when(integrationServiceMock).onReportingPeriodEnd(); - integrationServiceMock.onReportingPeriodEnd(); - - // THEN - assertThat(states).isEmpty(); - - verify(integrationServiceMock).onStateExpiry(key, null); - - when(integrationServiceMock.getLastRecordedTime(key)).thenCallRealMethod(); - assertThat(integrationServiceMock.getLastRecordedTime(key)).isZero(); - - verify(strategyMock).onReportingPeriodEnd(); - verifyNoMoreInteractions(strategyMock); - - verify(integrationServiceMock).reportActivity(eq(key), isNull(), eq(updatedLastRecordedTime), any()); - } - - // TODO: onReportingPeriodEnd() test for updating reported time - - @Test - void givenKeyAndTimeToReport_whenReportingActivity_thenShouldCorrectlyReportActivity() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - - TbQueueProducer> tbCoreMsgProducerMock = mock(TbQueueProducer.class); - ReflectionTestUtils.setField(integrationServiceMock, "tbCoreMsgProducer", tbCoreMsgProducerMock); - - PartitionService partitionServiceMock = mock(PartitionService.class); - ReflectionTestUtils.setField(integrationServiceMock, "partitionService", partitionServiceMock); - TopicPartitionInfo tpi = TopicPartitionInfo.builder().build(); - when(partitionServiceMock.resolve(ServiceType.TB_CORE, TENANT_ID, DEVICE_ID)).thenReturn(tpi); - - ActivityReportCallback callbackMock = mock(ActivityReportCallback.class); - - long expectedTime = 123L; - - doCallRealMethod().when(integrationServiceMock).reportActivity(key, null, expectedTime, callbackMock); - - // WHEN - integrationServiceMock.reportActivity(key, null, expectedTime, callbackMock); - - // THEN - verify(partitionServiceMock).resolve(ServiceType.TB_CORE, TENANT_ID, DEVICE_ID); - - ArgumentCaptor> msgCaptor = ArgumentCaptor.forClass(TbProtoQueueMsg.class); - ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(TbQueueCallback.class); - verify(tbCoreMsgProducerMock).send(eq(tpi), msgCaptor.capture(), callbackCaptor.capture()); - - TbProtoQueueMsg queueMsg = msgCaptor.getValue(); - - TransportProtos.DeviceActivityProto expectedDeviceActivityMsg = TransportProtos.DeviceActivityProto.newBuilder() - .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) - .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) - .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) - .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) - .setLastActivityTime(expectedTime) - .build(); - - TransportProtos.ToCoreMsg expectedToCoreMsg = TransportProtos.ToCoreMsg.newBuilder() - .setDeviceActivityMsg(expectedDeviceActivityMsg) - .build(); - - assertThat(queueMsg.getKey()).isEqualTo(DEVICE_ID.getId()); - assertThat(queueMsg.getValue()).isEqualTo(expectedToCoreMsg); - - TbQueueCallback queueCallback = callbackCaptor.getValue(); - - queueCallback.onSuccess(null); - verify(callbackMock).onSuccess(key, expectedTime); - - var throwable = new Throwable(); - queueCallback.onFailure(throwable); - verify(callbackMock).onFailure(key, throwable); - } - - @Test - void givenPostTelemetryMsg_whenProcessingMsg_thenShouldCallOnActivity() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() - .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) - .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) - .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) - .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) - .setDeviceName("Test Device") - .setDeviceType("default") - .build(); - TransportProtos.PostTelemetryMsg postTelemetryMsg = TransportProtos.PostTelemetryMsg.getDefaultInstance(); - doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postTelemetryMsg, null); - long expectedTime = 123L; - when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(expectedTime); - - // WHEN - integrationServiceMock.process(sessionInfo, postTelemetryMsg, null); - - // THEN - verify(integrationServiceMock).onActivity(key, expectedTime); - } - - @Test - void givenPostAttributesMsg_whenProcessingMsg_thenShouldCallOnActivity() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - TransportProtos.SessionInfoProto sessionInfo = TransportProtos.SessionInfoProto.newBuilder() - .setTenantIdMSB(TENANT_ID.getId().getMostSignificantBits()) - .setTenantIdLSB(TENANT_ID.getId().getLeastSignificantBits()) - .setDeviceIdMSB(DEVICE_ID.getId().getMostSignificantBits()) - .setDeviceIdLSB(DEVICE_ID.getId().getLeastSignificantBits()) - .setDeviceName("Test Device") - .setDeviceType("default") - .build(); - TransportProtos.PostAttributeMsg postAttributeMsg = TransportProtos.PostAttributeMsg.getDefaultInstance(); - doCallRealMethod().when(integrationServiceMock).process(sessionInfo, postAttributeMsg, null); - doNothing().when(integrationServiceMock).sendToRuleEngine(any(), any(), any(), any(), any(), any(), any()); - - long activityTime = 123L; - when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(activityTime); - - // WHEN - integrationServiceMock.process(sessionInfo, postAttributeMsg, null); - - // THEN - verify(integrationServiceMock).onActivity(key, activityTime); - } - - @Test - void givenKey_whenCreatingNewState_thenShouldCorrectlyCreateNewEmptyState() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - when(integrationServiceMock.createNewState(key)).thenCallRealMethod(); - - // WHEN - ActivityState actualNewState = integrationServiceMock.createNewState(key); - - // THEN - ActivityState expectedNewState = new ActivityState<>(); - assertThat(actualNewState).isEqualTo(expectedNewState); - } - - @ParameterizedTest - @EnumSource(ActivityStrategyType.class) - void givenDifferentReportingStrategies_whenGettingStrategy_thenShouldReturnCorrectStrategy(ActivityStrategyType reportingStrategyType) { - // GIVEN - doCallRealMethod().when(integrationServiceMock).getStrategy(); - ReflectionTestUtils.setField(integrationServiceMock, "reportingStrategyType", reportingStrategyType); - - // WHEN - ActivityStrategy actualStrategy = integrationServiceMock.getStrategy(); - - // THEN - assertThat(actualStrategy).isEqualTo(reportingStrategyType.toStrategy()); - } - - @Test - void givenActivityState_whenUpdatingActivityState_thenShouldReturnSameInstanceWithNoInteractions() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - - ActivityState state = new ActivityState<>(); - state.setLastRecordedTime(123L); - ActivityState stateSpy = spy(state); - - when(integrationServiceMock.updateState(key, state)).thenCallRealMethod(); - - // WHEN - ActivityState updatedState = integrationServiceMock.updateState(key, state); - - // THEN - assertThat(updatedState).isSameAs(state); - verifyNoInteractions(stateSpy); - } - - @ParameterizedTest - @MethodSource("provideTestParamsForHasExpiredTrue") - public void givenExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnTrue(long currentTimeMillis, long lastRecordedTime, long reportingPeriodMillis) { - // GIVEN - ReflectionTestUtils.setField(integrationServiceMock, "reportingPeriodMillis", reportingPeriodMillis); - - when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); - when(integrationServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); - - // WHEN - boolean hasExpired = integrationServiceMock.hasExpired(lastRecordedTime); - - // THEN - assertThat(hasExpired).isTrue(); - } - - private static Stream provideTestParamsForHasExpiredTrue() { - return Stream.of( - Arguments.of(10L, 0L, 9L), - Arguments.of(10L, 7L, 2L), - Arguments.of(10L, 8L, 1L), - Arguments.of(10000L, 5000L, 3000L) - ); - } - - @ParameterizedTest - @MethodSource("provideTestParamsForHasExpiredFalse") - public void givenNotExpiredLastRecordedTime_whenCheckingForExpiry_thenShouldReturnFalse(long currentTimeMillis, long lastRecordedTime, long reportingPeriodMillis) { - // GIVEN - ReflectionTestUtils.setField(integrationServiceMock, "reportingPeriodMillis", reportingPeriodMillis); - - when(integrationServiceMock.getCurrentTimeMillis()).thenReturn(currentTimeMillis); - when(integrationServiceMock.hasExpired(lastRecordedTime)).thenCallRealMethod(); - - // WHEN - boolean hasExpired = integrationServiceMock.hasExpired(lastRecordedTime); - - // THEN - assertThat(hasExpired).isFalse(); - } - - private static Stream provideTestParamsForHasExpiredFalse() { - return Stream.of( - Arguments.of(10L, 9L, 2L), - Arguments.of(10L, 0L, 11L), - Arguments.of(10L, 8L, 3L), - Arguments.of(10000L, 8000L, 3000L) - ); - } - - @Test - void givenKeyAndMetadata_whenOnStateExpiryCalled_thenShouldDoNothing() { - // GIVEN - var key = new IntegrationActivityKey(TENANT_ID, DEVICE_ID); - doCallRealMethod().when(integrationServiceMock).onStateExpiry(key, null); - - // WHEN-THEN - assertThatNoException().isThrownBy(() -> integrationServiceMock.onStateExpiry(key, null)); - } - -} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java index 89efec8e1c..84d6d37824 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/AbstractActivityManager.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java index 12eae33ee7..0f2145ab6f 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityManager.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java index 2b00495ed2..c58f2bfa34 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityReportCallback.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java index b470a52d9d..bde5e05645 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/ActivityState.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2023 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java index 497ed31f9d..b8fbb9ff12 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategy.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java index 4db053f84a..3f2ec74c3c 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyType.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java index 6fdbca31ec..f7d2679689 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategy.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java index 4b8234ac9b..a5a59046ae 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategy.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java index 3e75154c3e..5353635c45 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategy.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java index b731aa275e..bce35b0b34 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategy.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java index 89232623f6..7dcf0e8fd2 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/ActivityStrategyTypeTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java index 2d550991a3..ea89b28a02 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/AllEventsActivityStrategyTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java index a1cb7ac302..9ca6b58502 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstAndLastEventActivityStrategyTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java index 585c9caeb1..0df3517098 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/FirstEventActivityStrategyTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java index 441a88c32f..d747c13787 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/activity/strategy/LastEventActivityStrategyTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.activity.strategy; diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index 30395f28f4..e0f5ef128e 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.service; From 1a0ea09dea9757b8ace5254db876f9a1e3b916d6 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 11 Jan 2024 16:42:29 +0200 Subject: [PATCH 83/91] Add missed import during cherry picking --- .../common/transport/service/DefaultTransportService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index dc58c79250..83928759b0 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -23,6 +23,7 @@ import com.google.gson.JsonObject; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Lazy; @@ -49,6 +50,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.limit.LimitedApi; +import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.rpc.RpcStatus; From d23411f8d2766be115e6ac57909a8577982ddfca Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 11 Jan 2024 18:39:26 +0200 Subject: [PATCH 84/91] Refactor: move activity-related logic in transport to abstract TransportActivityManager. DefaultTransportService now extends TransportActivityManager. --- .../service/DefaultTransportService.java | 119 +------------ .../service/TransportActivityManager.java | 164 ++++++++++++++++++ 2 files changed, 168 insertions(+), 115 deletions(-) create mode 100644 common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 83928759b0..6b5780002d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -73,11 +73,6 @@ import org.thingsboard.server.common.transport.TransportResourceCache; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.TransportTenantProfileCache; -import org.thingsboard.server.common.transport.activity.AbstractActivityManager; -import org.thingsboard.server.common.transport.activity.ActivityReportCallback; -import org.thingsboard.server.common.transport.activity.ActivityState; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; -import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; @@ -121,7 +116,6 @@ import java.util.Optional; import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -136,14 +130,12 @@ import java.util.stream.Collectors; @Slf4j @Service @TbTransportComponent -public class DefaultTransportService extends AbstractActivityManager implements TransportService { +public class DefaultTransportService extends TransportActivityManager implements TransportService { public static final String OVERWRITE_ACTIVITY_TIME = "overwriteActivityTime"; - public static final String SESSION_EXPIRED_MESSAGE = "Session has expired due to last activity time!"; - public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_OPEN = getSessionEventMsg(TransportProtos.SessionEvent.OPEN); - public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_CLOSED = getSessionEventMsg(TransportProtos.SessionEvent.CLOSED); - public static final TransportProtos.SessionCloseNotificationProto SESSION_EXPIRED_NOTIFICATION_PROTO = TransportProtos.SessionCloseNotificationProto.newBuilder() - .setMessage(SESSION_EXPIRED_MESSAGE).build(); + public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_OPEN = TransportProtos.SessionEventMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC) + .setEvent(TransportProtos.SessionEvent.OPEN).build(); public static final TransportProtos.SubscribeToAttributeUpdatesMsg SUBSCRIBE_TO_ATTRIBUTE_UPDATES_ASYNC_MSG = TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder() .setSessionType(TransportProtos.SessionType.ASYNC).build(); public static final TransportProtos.SubscribeToRPCMsg SUBSCRIBE_TO_RPC_ASYNC_MSG = TransportProtos.SubscribeToRPCMsg.newBuilder() @@ -155,12 +147,6 @@ public class DefaultTransportService extends AbstractActivityManager sessions = new ConcurrentHashMap<>(); private final Map toServerRpcPendingMap = new ConcurrentHashMap<>(); private volatile boolean stopped = false; @@ -790,100 +775,10 @@ public class DefaultTransportService extends AbstractActivityManager createNewState(UUID sessionId) { - SessionMetaData session = sessions.get(sessionId); - if (session == null) { - return null; - } - ActivityState state = new ActivityState<>(); - state.setMetadata(session.getSessionInfo()); - return state; - } - - @Override - protected ActivityStrategy getStrategy() { - return reportingStrategyType.toStrategy(); - } - - @Override - protected ActivityState updateState(UUID sessionId, ActivityState state) { - SessionMetaData session = sessions.get(sessionId); - if (session == null) { - return null; - } - - state.setMetadata(session.getSessionInfo()); - var sessionInfo = state.getMetadata(); - - if (sessionInfo.getGwSessionIdMSB() == 0L || sessionInfo.getGwSessionIdLSB() == 0L) { - return state; - } - - var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); - SessionMetaData gwSession = sessions.get(gwSessionId); - if (gwSession == null || !gwSession.isOverwriteActivityTime()) { - return state; - } - - long lastRecordedTime = state.getLastRecordedTime(); - long gwLastRecordedTime = getLastRecordedTime(gwSessionId); - log.debug("Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. " + - "Updating last activity time. Session last recorded time: [{}], gateway session last recorded time: [{}].", - sessionId, gwSessionId, lastRecordedTime, gwLastRecordedTime); - state.setLastRecordedTime(Math.max(lastRecordedTime, gwLastRecordedTime)); - return state; - } - - @Override - protected boolean hasExpired(long lastRecordedTime) { - return (getCurrentTimeMillis() - sessionInactivityTimeout) > lastRecordedTime; - } - long getCurrentTimeMillis() { return System.currentTimeMillis(); } - @Override - protected void onStateExpiry(UUID sessionId, TransportProtos.SessionInfoProto sessionInfo) { - log.debug("Session with id: [{}] has expired due to last activity time.", sessionId); - SessionMetaData expiredSession = sessions.remove(sessionId); - if (expiredSession != null) { - deregisterSession(sessionInfo); - process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); - expiredSession.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); - } - } - - @Override - protected void reportActivity(UUID sessionId, TransportProtos.SessionInfoProto currentSessionInfo, long timeToReport, ActivityReportCallback callback) { - log.debug("Reporting activity state for session with id: [{}]. Time to report: [{}].", sessionId, timeToReport); - SessionMetaData session = sessions.get(sessionId); - TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() - .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) - .setRpcSubscription(session != null && session.isSubscribedToRPC()) - .setLastActivityTime(timeToReport) - .build(); - TransportProtos.SessionInfoProto sessionInfo = session != null ? session.getSessionInfo() : currentSessionInfo; - process(sessionInfo, subscriptionInfo, new TransportServiceCallback<>() { - @Override - public void onSuccess(Void msgAcknowledged) { - callback.onSuccess(sessionId, timeToReport); - - } - - @Override - public void onError(Throwable e) { - callback.onFailure(sessionId, e); - } - }); - } - @Override public void lifecycleEvent(TenantId tenantId, DeviceId deviceId, ComponentLifecycleEvent eventType, boolean success, Throwable error) { ToCoreMsg msg = ToCoreMsg.newBuilder() @@ -1199,12 +1094,6 @@ public class DefaultTransportService extends AbstractActivityManager callback) { ToCoreMsg toCoreMsg = ToCoreMsg.newBuilder().setToDeviceActorMsg(toDeviceActorMsg).build(); sendToCore(getTenantId(sessionInfo), getDeviceId(sessionInfo), toCoreMsg, getRoutingKey(sessionInfo), callback); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java new file mode 100644 index 0000000000..0c2a03e49f --- /dev/null +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java @@ -0,0 +1,164 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.common.transport.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.thingsboard.server.common.transport.TransportService; +import org.thingsboard.server.common.transport.TransportServiceCallback; +import org.thingsboard.server.common.transport.activity.AbstractActivityManager; +import org.thingsboard.server.common.transport.activity.ActivityReportCallback; +import org.thingsboard.server.common.transport.activity.ActivityState; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategy; +import org.thingsboard.server.common.transport.activity.strategy.ActivityStrategyType; +import org.thingsboard.server.gen.transport.TransportProtos; + +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +@Slf4j +public abstract class TransportActivityManager extends AbstractActivityManager implements TransportService { + + public static final String SESSION_EXPIRED_MESSAGE = "Session has expired due to last activity time!"; + + public static final TransportProtos.SessionEventMsg SESSION_EVENT_MSG_CLOSED = TransportProtos.SessionEventMsg.newBuilder() + .setSessionType(TransportProtos.SessionType.ASYNC) + .setEvent(TransportProtos.SessionEvent.CLOSED).build(); + public static final TransportProtos.SessionCloseNotificationProto SESSION_EXPIRED_NOTIFICATION_PROTO = TransportProtos.SessionCloseNotificationProto.newBuilder() + .setMessage(SESSION_EXPIRED_MESSAGE).build(); + + public final ConcurrentMap sessions = new ConcurrentHashMap<>(); + + @Value("${transport.sessions.report_timeout}") + protected long sessionReportTimeout; + + @Value("${transport.sessions.inactivity_timeout}") + protected long sessionInactivityTimeout; + + @Value("${transport.activity.reporting_strategy:LAST}") + private ActivityStrategyType reportingStrategyType; + + @Override + protected long getReportingPeriodMillis() { + return sessionReportTimeout; + } + + @Override + protected ActivityState createNewState(UUID sessionId) { + SessionMetaData session = sessions.get(sessionId); + if (session == null) { + return null; + } + ActivityState state = new ActivityState<>(); + state.setMetadata(session.getSessionInfo()); + return state; + } + + @Override + protected ActivityStrategy getStrategy() { + return reportingStrategyType.toStrategy(); + } + + @Override + protected ActivityState updateState(UUID sessionId, ActivityState state) { + SessionMetaData session = sessions.get(sessionId); + if (session == null) { + return null; + } + + state.setMetadata(session.getSessionInfo()); + var sessionInfo = state.getMetadata(); + + if (sessionInfo.getGwSessionIdMSB() == 0L || sessionInfo.getGwSessionIdLSB() == 0L) { + return state; + } + + var gwSessionId = new UUID(sessionInfo.getGwSessionIdMSB(), sessionInfo.getGwSessionIdLSB()); + SessionMetaData gwSession = sessions.get(gwSessionId); + if (gwSession == null || !gwSession.isOverwriteActivityTime()) { + return state; + } + + long lastRecordedTime = state.getLastRecordedTime(); + long gwLastRecordedTime = getLastRecordedTime(gwSessionId); + log.debug("Session with id: [{}] has gateway session with id: [{}] with overwrite activity time enabled. " + + "Updating last activity time. Session last recorded time: [{}], gateway session last recorded time: [{}].", + sessionId, gwSessionId, lastRecordedTime, gwLastRecordedTime); + state.setLastRecordedTime(Math.max(lastRecordedTime, gwLastRecordedTime)); + return state; + } + + @Override + protected boolean hasExpired(long lastRecordedTime) { + return (getCurrentTimeMillis() - sessionInactivityTimeout) > lastRecordedTime; + } + + @Override + protected void onStateExpiry(UUID sessionId, TransportProtos.SessionInfoProto sessionInfo) { + log.debug("Session with id: [{}] has expired due to last activity time.", sessionId); + SessionMetaData expiredSession = sessions.remove(sessionId); + if (expiredSession != null) { + deregisterSession(sessionInfo); + process(sessionInfo, SESSION_EVENT_MSG_CLOSED, null); + expiredSession.getListener().onRemoteSessionCloseCommand(sessionId, SESSION_EXPIRED_NOTIFICATION_PROTO); + } + } + + @Override + protected void reportActivity(UUID sessionId, TransportProtos.SessionInfoProto currentSessionInfo, long timeToReport, ActivityReportCallback callback) { + log.debug("Reporting activity state for session with id: [{}]. Time to report: [{}].", sessionId, timeToReport); + SessionMetaData session = sessions.get(sessionId); + TransportProtos.SubscriptionInfoProto subscriptionInfo = TransportProtos.SubscriptionInfoProto.newBuilder() + .setAttributeSubscription(session != null && session.isSubscribedToAttributes()) + .setRpcSubscription(session != null && session.isSubscribedToRPC()) + .setLastActivityTime(timeToReport) + .build(); + TransportProtos.SessionInfoProto sessionInfo = session != null ? session.getSessionInfo() : currentSessionInfo; + process(sessionInfo, subscriptionInfo, new TransportServiceCallback<>() { + @Override + public void onSuccess(Void msgAcknowledged) { + callback.onSuccess(sessionId, timeToReport); + + } + + @Override + public void onError(Throwable e) { + callback.onFailure(sessionId, e); + } + }); + } + + long getCurrentTimeMillis() { + return System.currentTimeMillis(); + } + +} From 8acbf85e9f6b03e4c549649fafb33cb963f900c0 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 11 Jan 2024 19:10:58 +0200 Subject: [PATCH 85/91] Fix license --- .../service/TransportActivityManager.java | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java index 0c2a03e49f..c9b1859de6 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2024 The Thingsboard Authors * - * Copyright © 2016-2024 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.common.transport.service; From 8690e922665c4ca74a85e6ed4c52490a73349457 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 12 Jan 2024 14:09:23 +0200 Subject: [PATCH 86/91] Move getCurrentTimeMillis() to abstract class and changed access modified to protected --- .../common/transport/service/DefaultTransportService.java | 4 ---- .../common/transport/service/TransportActivityManager.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 6b5780002d..a6a6f5d196 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -775,10 +775,6 @@ public class DefaultTransportService extends TransportActivityManager implements onActivity(toSessionId(sessionInfo), getCurrentTimeMillis()); } - long getCurrentTimeMillis() { - return System.currentTimeMillis(); - } - @Override public void lifecycleEvent(TenantId tenantId, DeviceId deviceId, ComponentLifecycleEvent eventType, boolean success, Throwable error) { ToCoreMsg msg = ToCoreMsg.newBuilder() diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java index c9b1859de6..1368785466 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TransportActivityManager.java @@ -142,7 +142,7 @@ public abstract class TransportActivityManager extends AbstractActivityManager Date: Fri, 12 Jan 2024 15:04:05 +0200 Subject: [PATCH 87/91] UI: Introduce new aggregation intervals. Improve data intervals processing and aggregation. --- .../widget_types/bar_chart_with_labels.json | 2 +- .../server/ThingsboardServerApplication.java | 6 +- ui-ngx/package.json | 1 + ui-ngx/src/app/core/api/data-aggregator.ts | 161 +++++++++------- .../app/core/api/entity-data-subscription.ts | 96 ++++++---- .../src/app/core/api/widget-subscription.ts | 9 +- ui-ngx/src/app/core/services/time.service.ts | 67 ++++--- .../lib/cards/aggregated-value-card.models.ts | 4 +- .../bar-chart-with-labels-widget.component.ts | 51 ++--- .../widget/lib/chart/echarts-widget.models.ts | 54 ++++-- .../lib/chart/range-chart-widget.component.ts | 3 + .../home/components/widget/lib/flot-widget.ts | 8 +- .../liquid-level-widget.component.ts | 5 +- .../time/timeinterval.component.html | 2 +- .../components/time/timeinterval.component.ts | 70 +++---- .../time/timewindow-panel.component.html | 2 + .../models/telemetry/telemetry.models.ts | 18 +- .../src/app/shared/models/time/time.models.ts | 178 +++++++++++++++--- .../shared/models/widget-settings.models.ts | 16 +- ui-ngx/src/app/shared/models/widget.models.ts | 8 +- .../assets/locale/locale.constant-en_US.json | 6 + ui-ngx/yarn.lock | 5 + 22 files changed, 522 insertions(+), 250 deletions(-) diff --git a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json index 06ee881c0a..75814a547a 100644 --- a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json +++ b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json @@ -20,7 +20,7 @@ "latestDataKeySettingsDirective": "", "hasBasicMode": true, "basicModeDirective": "tb-bar-chart-with-labels-basic-config", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2592000000,\"fixedTimewindow\":{\"startTimeMs\":1704293713163,\"endTimeMs\":1704380113163},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"showBarLabel\":true,\"barLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"12px\"},\"barLabelColor\":\"rgba(0, 0, 0, 0.54)\",\"showBarValue\":true,\"barValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"700\",\"lineHeight\":\"12px\"},\"barValueColor\":\"rgba(0, 0, 0, 0.76)\",\"showLegend\":true,\"legendPosition\":\"top\",\"legendLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"legendLabelColor\":\"rgba(0, 0, 0, 0.76)\",\"showTooltip\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipShowDate\":true,\"tooltipDateFormat\":{\"format\":\"MMMM y\",\"lastUpdateAgo\":false,\"custom\":true},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":11,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":4,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"public\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}" + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":\"MONTH\",\"fixedTimewindow\":{\"startTimeMs\":1704293713163,\"endTimeMs\":1704380113163},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"showBarLabel\":true,\"barLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"12px\"},\"barLabelColor\":\"rgba(0, 0, 0, 0.54)\",\"showBarValue\":true,\"barValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"700\",\"lineHeight\":\"12px\"},\"barValueColor\":\"rgba(0, 0, 0, 0.76)\",\"showLegend\":true,\"legendPosition\":\"top\",\"legendLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"legendLabelColor\":\"rgba(0, 0, 0, 0.76)\",\"showTooltip\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipShowDate\":true,\"tooltipDateFormat\":{\"format\":\"MMMM y\",\"lastUpdateAgo\":false,\"custom\":true},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":11,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":4,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"public\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}" }, "tags": [ "bar chart", diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java index 77442e53a8..60f69cd8a7 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java @@ -21,7 +21,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; -import java.time.ZoneId; import java.util.Arrays; @SpringBootConfiguration @@ -34,10 +33,7 @@ public class ThingsboardServerApplication { private static final String DEFAULT_SPRING_CONFIG_PARAM = SPRING_CONFIG_NAME_KEY + "=" + "thingsboard"; public static void main(String[] args) { - - ZoneId.getAvailableZoneIds().stream().sorted().forEach(System.out::println); - -// SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); + SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); } private static String[] updateArguments(String[] args) { diff --git a/ui-ngx/package.json b/ui-ngx/package.json index f32b68590a..4bbe817fcf 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -97,6 +97,7 @@ "rxjs": "~7.8.0", "schema-inspector": "^2.0.2", "screenfull": "^6.0.2", + "sorted-btree": "^1.8.1", "split.js": "^1.6.5", "systemjs": "6.14.1", "tinycolor2": "^1.6.0", diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index a09b1e984a..a16c4baa5b 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -19,36 +19,40 @@ import { IndexedSubscriptionData, } from '@app/shared/models/telemetry/telemetry.models'; import { - AggregationType, + AggregationType, calculateAggInterval, calculateIntervalComparisonEndTime, calculateIntervalEndTime, calculateIntervalStartEndTime, getCurrentTime, - getTime, + getTime, IntervalMath, SubscriptionTimewindow } from '@shared/models/time/time.models'; import { UtilsService } from '@core/services/utils.service'; import { deepClone, isDefinedAndNotNull, isNumber, isNumeric } from '@core/utils'; import Timeout = NodeJS.Timeout; +import { DataEntry, DataSet, IndexedData } from '@shared/models/widget.models'; +import BTree from 'sorted-btree'; -export declare type onAggregatedData = (data: IndexedSubscriptionData, detectChanges: boolean) => void; +export declare type onAggregatedData = (data: IndexedData, detectChanges: boolean) => void; interface AggData { count: number; sum: number; aggValue: any; + ts: number; + interval: [number, number]; } class AggDataMap { - rangeChanged = false; - private minTs = Number.MAX_SAFE_INTEGER; - private map = new Map(); + private map = new BTree(); + private reusePair: [number, AggData] = [undefined, undefined]; + + constructor( + private subsTw: SubscriptionTimewindow, + private endTs: number + ){}; set(ts: number, data: AggData) { - if (ts < this.minTs) { - this.rangeChanged = true; - this.minTs = ts; - } this.map.set(ts, data); } @@ -60,7 +64,38 @@ class AggDataMap { this.map.delete(ts); } - forEach(callback: (value: AggData, key: number, map: Map) => void, thisArg?: any) { + findDataForTs(ts: number): AggData | undefined { + if (ts >= this.endTs) { + this.updateLastInterval(ts + 1); + } + const pair = this.map.getPairOrNextLower(ts, this.reusePair); + if (pair) { + const data = pair[1]; + const interval = data.interval; + if (ts < interval[1]) { + return data; + } + } + } + + calculateAggInterval(timestamp: number): [number, number] { + return calculateAggInterval(this.subsTw, this.endTs, timestamp); + } + + updateLastInterval(endTs: number) { + if (endTs > this.endTs) { + this.endTs = endTs; + const lastTs = this.map.maxKey(); + if (lastTs) { + const data = this.map.get(lastTs); + const interval = calculateAggInterval(this.subsTw, endTs, data.ts); + data.interval = interval; + data.ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); + } + } + } + + forEach(callback: (value: AggData, key: number, map: BTree) => void, thisArg?: any) { this.map.forEach(callback, thisArg); } @@ -71,24 +106,6 @@ class AggDataMap { class AggregationMap { aggMap: {[id: number]: AggDataMap} = {}; - - detectRangeChanged(): boolean { - let changed = false; - for (const id of Object.keys(this.aggMap)) { - const aggDataMap = this.aggMap[id]; - if (aggDataMap.rangeChanged) { - changed = true; - aggDataMap.rangeChanged = false; - } - } - return changed; - } - - clearRangeChangedFlags() { - for (const id of Object.keys(this.aggMap)) { - this.aggMap[id].rangeChanged = false; - } - } } declare type AggFunction = (aggData: AggData, value?: any) => void; @@ -156,9 +173,9 @@ export class DataAggregator { } } - private dataBuffer: IndexedSubscriptionData = []; - private data: IndexedSubscriptionData; - private readonly lastPrevKvPairData: {[id: number]: [number, any]}; + private dataBuffer: IndexedData = []; + private data: IndexedData; + private readonly lastPrevKvPairData: {[id: number]: DataEntry}; private aggregationMap: AggregationMap; @@ -166,7 +183,7 @@ export class DataAggregator { private resetPending = false; private updatedData = false; - private aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(this.subsTw.aggregation.interval, 1000); + private aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(IntervalMath.numberValue(this.subsTw.aggregation.interval), 1000); private intervalTimeoutHandle: Timeout; private intervalScheduledTime: number; @@ -216,7 +233,7 @@ export class DataAggregator { this.intervalScheduledTime = this.utils.currentPerfTime(); this.calculateStartEndTs(); this.elapsed = 0; - this.aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(this.subsTw.aggregation.interval, 1000); + this.aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(IntervalMath.numberValue(this.subsTw.aggregation.interval), 1000); this.resetPending = true; this.updatedData = false; this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), Math.min(this.aggregationTimeout, MAX_INTERVAL_TIMEOUT)); @@ -252,7 +269,6 @@ export class DataAggregator { if (updateIntervalScheduledTime) { this.intervalScheduledTime = this.utils.currentPerfTime(); } - this.aggregationMap.clearRangeChangedFlags(); this.onInterval(history, detectChanges); } else { this.updateAggregatedData(data); @@ -260,9 +276,7 @@ export class DataAggregator { this.intervalScheduledTime = this.utils.currentPerfTime(); this.onInterval(history, detectChanges); } else { - if (this.aggregationMap.detectRangeChanged()) { - this.onInterval(false, detectChanges, true); - } + this.onInterval(false, detectChanges, true); } } } @@ -283,7 +297,7 @@ export class DataAggregator { } } - private onInterval(history?: boolean, detectChanges?: boolean, rangeChanged?: boolean) { + private onInterval(history?: boolean, detectChanges?: boolean, dataChanged?: boolean) { const now = this.utils.currentPerfTime(); this.elapsed += now - this.intervalScheduledTime; this.intervalScheduledTime = now; @@ -291,10 +305,10 @@ export class DataAggregator { clearTimeout(this.intervalTimeoutHandle); this.intervalTimeoutHandle = null; } - const intervalTimeout = rangeChanged ? this.aggregationTimeout - this.elapsed : this.aggregationTimeout; + const intervalTimeout = dataChanged ? this.aggregationTimeout - this.elapsed : this.aggregationTimeout; if (!history) { const delta = Math.floor(this.elapsed / this.aggregationTimeout); - if (delta || !this.data || rangeChanged) { + if (delta || !this.data || dataChanged) { const tickTs = delta * this.aggregationTimeout; if (this.subsTw.quickInterval) { const startEndTime = calculateIntervalStartEndTime(this.subsTw.quickInterval, this.subsTw.timezone); @@ -304,6 +318,7 @@ export class DataAggregator { this.startTs += tickTs; this.endTs += tickTs; } + this.updateLastInterval(); this.data = this.updateData(); this.elapsed = this.elapsed - delta * this.aggregationTimeout; } @@ -319,7 +334,7 @@ export class DataAggregator { } } - private updateData(): IndexedSubscriptionData { + private updateData(): IndexedData { this.dataBuffer = []; this.tsKeys.forEach((key) => { if (!this.dataBuffer[key.id]) { @@ -332,19 +347,21 @@ export class DataAggregator { const aggKey = this.aggKeyById(id); const noAggregation = aggKey.agg === AggregationType.NONE; let keyData = this.dataBuffer[id]; - aggKeyData.forEach((aggData, aggTimestamp) => { - if (aggTimestamp < this.startTs) { + const deletedKeys: number[] = []; + aggKeyData.forEach((aggData, aggStartTs) => { + if (aggStartTs < this.startTs) { if (this.subsTw.aggregation.stateData && - (!this.lastPrevKvPairData[id] || this.lastPrevKvPairData[id][0] < aggTimestamp)) { - this.lastPrevKvPairData[id] = [aggTimestamp, aggData.aggValue]; + (!this.lastPrevKvPairData[id] || this.lastPrevKvPairData[id][0] < aggData.ts)) { + this.lastPrevKvPairData[id] = [aggData.ts, aggData.aggValue, aggData.interval]; } - aggKeyData.delete(aggTimestamp); + deletedKeys.push(aggStartTs); this.updatedData = true; - } else if (aggTimestamp < this.endTs || noAggregation) { - const kvPair: [number, any] = [aggTimestamp, aggData.aggValue]; + } else if (aggData.ts < this.endTs || noAggregation) { + const kvPair: DataEntry = [aggData.ts, aggData.aggValue, aggData.interval]; keyData.push(kvPair); } }); + deletedKeys.forEach(ts => aggKeyData.delete(ts)); keyData.sort((set1, set2) => set1[0] - set2[0]); if (this.subsTw.aggregation.stateData) { this.updateStateBounds(keyData, deepClone(this.lastPrevKvPairData[id])); @@ -357,11 +374,11 @@ export class DataAggregator { return this.dataBuffer; } - private updateStateBounds(keyData: [number, any, number?][], lastPrevKvPair: [number, any]) { + private updateStateBounds(keyData: DataSet, lastPrevKvPair: DataEntry) { if (lastPrevKvPair) { lastPrevKvPair[0] = this.startTs; } - let firstKvPair; + let firstKvPair: DataEntry; if (!keyData.length) { if (lastPrevKvPair) { firstKvPair = lastPrevKvPair; @@ -395,20 +412,26 @@ export class DataAggregator { const noAggregation = aggType === AggregationType.NONE; let aggKeyData = aggregationMap.aggMap[id]; if (!aggKeyData) { - aggKeyData = new AggDataMap(); + aggKeyData = new AggDataMap(this.subsTw, this.endTs); aggregationMap.aggMap[id] = aggKeyData; } const keyData = data[id]; keyData.forEach((kvPair) => { const timestamp = kvPair[0]; const value = DataAggregator.convertValue(kvPair[1], noAggregation); - const tsKey = timestamp; - const aggData = { + let interval: [number, number] = [timestamp, timestamp]; + if (!noAggregation) { + interval = aggKeyData.calculateAggInterval(timestamp); + } + const ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); + const aggData: AggData = { count: isCount ? value : isDefinedAndNotNull(kvPair[2]) ? kvPair[2] : 1, sum: value, - aggValue: value + aggValue: value, + ts, + interval }; - aggKeyData.set(tsKey, aggData); + aggKeyData.set(interval[0], aggData); }); } return aggregationMap; @@ -423,24 +446,28 @@ export class DataAggregator { const noAggregation = aggType === AggregationType.NONE; let aggKeyData = this.aggregationMap.aggMap[id]; if (!aggKeyData) { - aggKeyData = new AggDataMap(); + aggKeyData = new AggDataMap(this.subsTw, this.endTs); this.aggregationMap.aggMap[id] = aggKeyData; } const keyData = data[id]; keyData.forEach((kvPair) => { const timestamp = kvPair[0]; const value = DataAggregator.convertValue(kvPair[1], noAggregation); - const aggTimestamp = noAggregation ? timestamp : (this.startTs + - Math.floor((timestamp - this.startTs) / this.subsTw.aggregation.interval) * - this.subsTw.aggregation.interval + this.subsTw.aggregation.interval / 2); - let aggData = aggKeyData.get(aggTimestamp); + let aggData = aggKeyData.findDataForTs(timestamp); if (!aggData) { + let interval: [number, number] = [timestamp, timestamp]; + if (!noAggregation) { + interval = aggKeyData.calculateAggInterval(timestamp); + } + const ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); aggData = { count: isDefinedAndNotNull(kvPair[2]) ? kvPair[2] : 1, sum: value, - aggValue: isCount ? 1 : value + aggValue: isCount ? 1 : value, + ts, + interval }; - aggKeyData.set(aggTimestamp, aggData); + aggKeyData.set(interval[0], aggData); } else { DataAggregator.getAggFunction(aggType)(aggData, value); } @@ -448,6 +475,14 @@ export class DataAggregator { } } + private updateLastInterval() { + for (const idStr of Object.keys(this.aggregationMap.aggMap)) { + const id = Number(idStr); + const aggKeyData = this.aggregationMap.aggMap[id]; + aggKeyData.updateLastInterval(this.endTs); + } + } + private aggKeyById(id: number): AggKey { return this.tsKeys.find(key => key.id === id); } diff --git a/ui-ngx/src/app/core/api/entity-data-subscription.ts b/ui-ngx/src/app/core/api/entity-data-subscription.ts index af3354c07b..a1c88b3330 100644 --- a/ui-ngx/src/app/core/api/entity-data-subscription.ts +++ b/ui-ngx/src/app/core/api/entity-data-subscription.ts @@ -14,12 +14,19 @@ /// limitations under the License. /// -import { ComparisonResultType, DataSet, DataSetHolder, DatasourceType, widgetType } from '@shared/models/widget.models'; +import { + ComparisonResultType, + DataEntry, + DataSet, + DataSetHolder, + DatasourceType, IndexedData, + widgetType +} from '@shared/models/widget.models'; import { AggregationType, ComparisonDuration, createTimewindowForComparison, - getCurrentTime, + getCurrentTime, IntervalMath, SubscriptionTimewindow } from '@shared/models/time/time.models'; import { @@ -42,15 +49,16 @@ import { EntityCountCmd, EntityDataCmd, IndexedSubscriptionData, + IntervalType, NOT_SUPPORTED, - SubscriptionData, + SubscriptionData, SubscriptionDataEntry, TelemetrySubscriber } from '@shared/models/telemetry/telemetry.models'; import { UtilsService } from '@core/services/utils.service'; import { EntityDataListener, EntityDataLoadResult } from '@core/api/entity-data.service'; import { deepClone, isDefined, isDefinedAndNotNull, isNumeric, isObject, objectHashCode } from '@core/utils'; import { PageData } from '@shared/models/page/page-data'; -import { DataAggregator } from '@core/api/data-aggregator'; +import { DataAggregator, onAggregatedData } from '@core/api/data-aggregator'; import { NULL_UUID } from '@shared/models/id/has-uuid'; import { EntityType } from '@shared/models/entity-type.models'; import { Observable, of, ReplaySubject, Subject } from 'rxjs'; @@ -154,7 +162,7 @@ export class EntityDataSubscription { return val; } - private static calculateComparisonValue(key: SubscriptionDataKey, comparisonTsValue: ComparisonTsValue): [number, any, number?][] { + private static calculateComparisonValue(key: SubscriptionDataKey, comparisonTsValue: ComparisonTsValue): DataSet { let timestamp: number; let value: any; switch (key.comparisonResultType) { @@ -385,7 +393,13 @@ export class EntityDataSubscription { if (this.entityDataSubscriptionOptions.type === widgetType.timeseries && this.tsFields.length) { targetCommand.tsCmd.startTs = this.subsTw.startTs; targetCommand.tsCmd.timeWindow = this.subsTw.aggregation.timeWindow; - targetCommand.tsCmd.interval = this.subsTw.aggregation.interval; + if (typeof this.subsTw.aggregation.interval === 'number') { + targetCommand.tsCmd.interval = this.subsTw.aggregation.interval; + targetCommand.tsCmd.intervalType = IntervalType.MILLISECONDS; + } else { + targetCommand.tsCmd.intervalType = this.subsTw.aggregation.interval; + } + targetCommand.tsCmd.timeZoneId = this.subsTw.timezone; targetCommand.tsCmd.limit = this.subsTw.aggregation.limit; targetCommand.tsCmd.agg = this.subsTw.aggregation.type; targetCommand.tsCmd.fetchLatestPreviousPoint = this.subsTw.aggregation.stateData; @@ -659,21 +673,35 @@ export class EntityDataSubscription { keys: this.tsFields.map(key => key.key), startTs: this.subsTw.fixedWindow.startTimeMs, endTs: this.subsTw.fixedWindow.endTimeMs, - interval: this.subsTw.aggregation.interval, + interval: 0, + intervalType: IntervalType.MILLISECONDS, limit: this.subsTw.aggregation.limit, + timeZoneId: this.subsTw.timezone, agg: this.subsTw.aggregation.type, fetchLatestPreviousPoint: this.subsTw.aggregation.stateData }; + if (typeof this.subsTw.aggregation.interval === 'number') { + cmd.historyCmd.interval = this.subsTw.aggregation.interval; + } else { + cmd.historyCmd.intervalType = this.subsTw.aggregation.interval; + } } else { cmd.tsCmd = { keys: this.tsFields.map(key => key.key), startTs: this.subsTw.startTs, timeWindow: this.subsTw.aggregation.timeWindow, - interval: this.subsTw.aggregation.interval, + interval: 0, + intervalType: IntervalType.MILLISECONDS, limit: this.subsTw.aggregation.limit, + timeZoneId: this.subsTw.timezone, agg: this.subsTw.aggregation.type, fetchLatestPreviousPoint: this.subsTw.aggregation.stateData }; + if (typeof this.subsTw.aggregation.interval === 'number') { + cmd.tsCmd.interval = this.subsTw.aggregation.interval; + } else { + cmd.tsCmd.intervalType = this.subsTw.aggregation.interval; + } } } latestValuesKeys = this.latestValues; @@ -717,7 +745,8 @@ export class EntityDataSubscription { this.frequency = 1000; this.latestFrequency = 1000; if (this.entityDataSubscriptionOptions.type === widgetType.timeseries) { - this.frequency = Math.min(this.entityDataSubscriptionOptions.subscriptionTimewindow.aggregation.interval, 5000); + this.frequency = + Math.min(IntervalMath.numberValue(this.entityDataSubscriptionOptions.subscriptionTimewindow.aggregation.interval), 5000); } this.tickScheduledTime = this.utils.currentPerfTime(); this.generateData(true); @@ -785,9 +814,9 @@ export class EntityDataSubscription { } private reportNotSupported(keys: AggKey[], isUpdate: boolean) { - const indexedData: IndexedSubscriptionData = []; + const indexedData: IndexedData = []; for (const key of keys) { - indexedData[key.id] = [[0, NOT_SUPPORTED]]; + indexedData[key.id] = [[0, NOT_SUPPORTED, [0,0]]]; } for (let dataIndex = 0; dataIndex < this.pageData.data.length; dataIndex++) { this.onIndexedData(indexedData, dataIndex, true, @@ -942,7 +971,7 @@ export class EntityDataSubscription { } if (Object.keys(aggData).length > 0 && this.tsLatestDataAggregators && this.tsLatestDataAggregators[dataIndex]) { const dataAggregator = this.tsLatestDataAggregators[dataIndex]; - let prevDataCb; + let prevDataCb: onAggregatedData; if (!isUpdate) { prevDataCb = dataAggregator.updateOnDataCb((data, detectChanges) => { this.onIndexedData(data, dataIndex, detectChanges, @@ -996,7 +1025,7 @@ export class EntityDataSubscription { for (const dataKey of dataKeys) { indexedData[dataKey.index] = subscriptionData[dataKey.name]; } - let prevDataCb; + let prevDataCb: onAggregatedData; if (!isUpdate) { prevDataCb = dataAggregator.updateOnDataCb((data, detectChanges) => { this.onIndexedData(data, dataIndex, detectChanges, false, dataUpdatedCb); @@ -1016,12 +1045,12 @@ export class EntityDataSubscription { isTsLatest: boolean, dataUpdatedCb: DataUpdatedCb) { for (const key of Object.keys(sourceData)) { const keyData = sourceData[key]; - this.onKeyData(keyData, key, 0, type, + this.onKeyData(keyData.map(entry => [entry[0], entry[1], [entry[0], entry[0]]]), key, 0, type, dataIndex, detectChanges, isTsLatest, false, dataUpdatedCb); } } - private onIndexedData(sourceData: IndexedSubscriptionData, dataIndex: number, detectChanges: boolean, + private onIndexedData(sourceData: IndexedData, dataIndex: number, detectChanges: boolean, isTsLatest: boolean, dataUpdatedCb: DataUpdatedCb) { for (const indexStr of Object.keys(sourceData)) { const id = Number(indexStr); @@ -1037,7 +1066,7 @@ export class EntityDataSubscription { } } - private onKeyData(keyData: [number, any, number?][], keyName: string, id: number, type: DataKeyType, + private onKeyData(keyData: DataSet, keyName: string, id: number, type: DataKeyType, dataIndex: number, detectChanges: boolean, isTsLatest: boolean, isAggLatest: boolean, dataUpdatedCb: DataUpdatedCb) { const keyIdSuffix = isAggLatest ? `_${id}` : ''; @@ -1048,8 +1077,8 @@ export class EntityDataSubscription { if (this.datasourceData[dataIndex][datasourceKey].data) { const dataKey = dataKeyList[keyIndex]; const data: DataSet = []; - let prevSeries: [number, any]; - let prevOrigSeries: [number, any]; + let prevSeries: DataEntry; + let prevOrigSeries: DataEntry; let datasourceKeyData: DataSet; let datasourceOrigKeyData: DataSet; let update = false; @@ -1064,36 +1093,36 @@ export class EntityDataSubscription { prevSeries = datasourceKeyData[datasourceKeyData.length - 1]; prevOrigSeries = datasourceOrigKeyData[datasourceOrigKeyData.length - 1]; } else { - prevSeries = [0, 0]; - prevOrigSeries = [0, 0]; + prevSeries = [0, 0, [0, 0]]; + prevOrigSeries = [0, 0, [0, 0]]; } this.datasourceOrigData[dataIndex][datasourceKey].data = []; if (this.entityDataSubscriptionOptions.type === widgetType.timeseries && !isTsLatest) { keyData.forEach((keySeries) => { let series = keySeries; const time = series[0]; - this.datasourceOrigData[dataIndex][datasourceKey].data.push([series[0], series[1]]); + this.datasourceOrigData[dataIndex][datasourceKey].data.push([series[0], series[1], series[2]]); let value = EntityDataSubscription.convertValue(series[1]); if (dataKey.postFunc) { value = dataKey.postFunc(time, value, prevSeries[1], prevOrigSeries[0], prevOrigSeries[1]); } - prevOrigSeries = [series[0], series[1]]; - series = [series[0], value]; - data.push([series[0], series[1]]); - prevSeries = [series[0], series[1]]; + prevOrigSeries = [series[0], series[1], series[2]]; + series = [series[0], value, series[2]]; + data.push([series[0], series[1], series[2]]); + prevSeries = [series[0], series[1], series[2]]; }); update = true; } else if (this.entityDataSubscriptionOptions.type === widgetType.latest || isTsLatest) { if (keyData.length > 0) { let series = keyData[0]; const time = series[0]; - this.datasourceOrigData[dataIndex][datasourceKey].data.push([series[0], series[1]]); + this.datasourceOrigData[dataIndex][datasourceKey].data.push([series[0], series[1], series[2]]); let value = EntityDataSubscription.convertValue(series[1]); if (dataKey.postFunc) { value = dataKey.postFunc(time, value, prevSeries[1], prevOrigSeries[0], prevOrigSeries[1]); } - series = [time, value]; - data.push([series[0], series[1]]); + series = [time, value, series[2]]; + data.push([series[0], series[1], series[2]]); } update = true; } @@ -1155,13 +1184,14 @@ export class EntityDataSubscription { return result; } - private generateSeries(dataKey: SubscriptionDataKey, startTime: number, endTime: number): [number, any][] { - const data: [number, any][] = []; - let prevSeries: [number, any]; + private generateSeries(dataKey: SubscriptionDataKey, startTime: number, endTime: number): SubscriptionDataEntry[] { + const data: SubscriptionDataEntry[] = []; + let prevSeries: SubscriptionDataEntry; const datasourceDataKey = `${dataKey.key}_${dataKey.listIndex}`; const datasourceKeyData = this.datasourceData[0][datasourceDataKey].data; if (datasourceKeyData.length > 0) { - prevSeries = datasourceKeyData[datasourceKeyData.length - 1]; + const prevDataEntry = datasourceKeyData[datasourceKeyData.length - 1]; + prevSeries = [prevDataEntry[0], prevDataEntry[1]]; } else { prevSeries = [0, 0]; } @@ -1178,7 +1208,7 @@ export class EntityDataSubscription { } private generateLatest(dataKey: SubscriptionDataKey, detectChanges: boolean) { - let prevSeries: [number, any]; + let prevSeries: DataEntry; const datasourceKey = dataKey.latest ? `${dataKey.key}_${dataKey.listIndex}` : dataKey.key; const datasourceKeyData = this.datasourceData[0][datasourceKey].data; if (datasourceKeyData.length > 0) { diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index b24e12b627..4f0f399bd0 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -1253,14 +1253,19 @@ export class WidgetSubscription implements IWidgetSubscription { private updateTimewindow() { this.timeWindow.interval = this.subscriptionTimewindow.aggregation.interval || 1000; this.timeWindow.timezone = this.subscriptionTimewindow.timezone; + this.timeWindow.tsOffset = this.subscriptionTimewindow.tsOffset; if (this.subscriptionTimewindow.realtimeWindowMs) { if (this.subscriptionTimewindow.quickInterval) { const startEndTime = calculateIntervalStartEndTime(this.subscriptionTimewindow.quickInterval, this.subscriptionTimewindow.timezone); this.timeWindow.maxTime = startEndTime[1] + this.subscriptionTimewindow.tsOffset; this.timeWindow.minTime = startEndTime[0] + this.subscriptionTimewindow.tsOffset; } else { - this.timeWindow.maxTime = moment().valueOf() + this.subscriptionTimewindow.tsOffset + this.timeWindow.stDiff; - this.timeWindow.minTime = this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs; + const now = moment().valueOf() + this.subscriptionTimewindow.tsOffset + this.timeWindow.stDiff; + if (!this.timeWindow.maxTime || Math.abs(now - this.timeWindow.maxTime) > 500) { + this.timeWindow.maxTime = now; + this.timeWindow.maxTime -= this.timeWindow.maxTime % 1000; + this.timeWindow.minTime = this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs; + } } } else if (this.subscriptionTimewindow.fixedWindow) { this.timeWindow.maxTime = this.subscriptionTimewindow.fixedWindow.endTimeMs + this.subscriptionTimewindow.tsOffset; diff --git a/ui-ngx/src/app/core/services/time.service.ts b/ui-ngx/src/app/core/services/time.service.ts index e9c7de1cd8..62d5a3507c 100644 --- a/ui-ngx/src/app/core/services/time.service.ts +++ b/ui-ngx/src/app/core/services/time.service.ts @@ -19,22 +19,14 @@ import { AggregationType, DAY, defaultTimeIntervals, - defaultTimewindow, + defaultTimewindow, Interval, IntervalMath, SECOND, + TimeInterval, Timewindow } from '@shared/models/time/time.models'; import { HttpClient } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { defaultHttpOptions } from '@core/http/http-utils'; -import { map } from 'rxjs/operators'; import { isDefined } from '@core/utils'; -export interface TimeInterval { - name: string; - translateParams: { [key: string]: any }; - value: number; -} - const MIN_INTERVAL = SECOND; const MAX_INTERVAL = 365 * 20 * DAY; @@ -60,15 +52,16 @@ export class TimeService { } } - public matchesExistingInterval(min: number, max: number, intervalMs: number): boolean { - const intervals = this.getIntervals(min, max); - return intervals.findIndex(interval => interval.value === intervalMs) > -1; + public matchesExistingInterval(min: number, max: number, interval: Interval, useCalendarIntervals = false): boolean { + const intervals = this.getIntervals(min, max, useCalendarIntervals); + return intervals.findIndex(timeInterval => timeInterval.value === interval) > -1; } - public getIntervals(min: number, max: number): Array { + public getIntervals(min: number, max: number, useCalendarIntervals = false): Array { min = this.boundMinInterval(min); max = this.boundMaxInterval(max); - return defaultTimeIntervals.filter((interval) => interval.value >= min && interval.value <= max); + return defaultTimeIntervals.filter((interval) => (useCalendarIntervals || typeof interval.value === 'number') && + IntervalMath.numberValue(interval.value) >= min && IntervalMath.numberValue(interval.value) <= max); } public boundMinInterval(min: number): number { @@ -85,32 +78,37 @@ export class TimeService { return this.toBound(max, MIN_INTERVAL, MAX_INTERVAL, MAX_INTERVAL); } - public boundToPredefinedInterval(min: number, max: number, intervalMs: number): number { - const intervals = this.getIntervals(min, max); + public boundToPredefinedInterval(min: number, max: number, interval: Interval, useCalendarIntervals = false): Interval { + const intervals = this.getIntervals(min, max, useCalendarIntervals); let minDelta = MAX_INTERVAL; - const boundedInterval = intervalMs || min; + const boundedInterval = interval || min; if (!intervals.length) { return boundedInterval; } - let matchedInterval: TimeInterval = intervals[0]; - intervals.forEach((interval) => { - const delta = Math.abs(interval.value - boundedInterval); - if (delta < minDelta) { - matchedInterval = interval; - minDelta = delta; - } - }); - return matchedInterval.value; + const found = intervals.find(timeInterval => timeInterval.value === boundedInterval); + if (found) { + return found.value; + } else { + let matchedInterval: TimeInterval = intervals[0]; + intervals.forEach((timeInterval) => { + const delta = Math.abs(IntervalMath.numberValue(timeInterval.value) - IntervalMath.numberValue(boundedInterval)); + if (delta <= minDelta) { + matchedInterval = timeInterval; + minDelta = delta; + } + }); + return matchedInterval.value; + } } - public boundIntervalToTimewindow(timewindow: number, intervalMs: number, aggType: AggregationType): number { + public boundIntervalToTimewindow(timewindow: number, interval: Interval, aggType: AggregationType): Interval { if (aggType === AggregationType.NONE) { return SECOND; } else { const min = this.minIntervalLimit(timewindow); const max = this.maxIntervalLimit(timewindow); - if (intervalMs) { - return this.toBound(intervalMs, min, max, intervalMs); + if (interval) { + return this.toIntervalBound(interval, min, max, interval); } else { return this.boundToPredefinedInterval(min, max, this.avgInterval(timewindow)); } @@ -154,4 +152,13 @@ export class TimeService { } } + private toIntervalBound(value: Interval, min: number, max: number, defValue: Interval): Interval { + if (isDefined(value)) { + value = IntervalMath.max(value, min); + value = IntervalMath.min(value, max); + return value; + } else { + return defValue; + } + } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/cards/aggregated-value-card.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/cards/aggregated-value-card.models.ts index 3b2618c680..34a3433ac5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/cards/aggregated-value-card.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/cards/aggregated-value-card.models.ts @@ -27,7 +27,7 @@ import { lastUpdateAgoDateFormat, textStyle } from '@shared/models/widget-settings.models'; -import { ComparisonResultType, DataKey, DatasourceData } from '@shared/models/widget.models'; +import { ComparisonResultType, DataEntry, DataKey, DatasourceData } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { AggregationType } from '@shared/models/time/time.models'; @@ -102,7 +102,7 @@ export const computeAggregatedCardValue = } }; -export const getTsValueByLatestDataKey = (latestData: Array, dataKey: DataKey): [number, any] => { +export const getTsValueByLatestDataKey = (latestData: Array, dataKey: DataKey): DataEntry => { if (latestData?.length) { const dsData = latestData.find(data => data.dataKey === dataKey); if (dsData?.data?.length) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts index 3398e289d7..ea8c46880e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -58,6 +58,7 @@ import { NamedDataSet, toNamedData } from '@home/components/widget/lib/chart/echarts-widget.models'; +import { IntervalMath } from '@shared/models/time/time.models'; interface BarChartDataItem { id: string; @@ -187,18 +188,23 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft this.barRenderItem = (params, api) => { - const interval = this.ctx.defaultSubscription.timeWindow.interval; + const time = api.value(0) as number; + let start = api.value(2) as number; + const end = api.value(3) as number; + let interval = end - start; + if (!start || !end || !interval) { + interval = IntervalMath.numberValue(this.ctx.timeWindow.interval); + start = time - interval / 2; + } const enabledDataItems = this.dataItems.filter(d => d.enabled); const barInterval = interval / (enabledDataItems.length + 1); const intervalGap = barInterval / 2; const index = enabledDataItems.findIndex(d => d.id === params.seriesId); - const time = api.value(0) as number; const value = api.value(1); - const start = time - interval / 2; const startTime = start + intervalGap + barInterval * index; const delta = barInterval; - const lowerLeft = api.coord([startTime, value]); + const lowerLeft = api.coord([startTime, value >= 0 ? value : 0]); const height = api.size([delta, value])[1]; const width = api.size([delta, 10])[0]; @@ -256,7 +262,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft this.barLabelLayoutCallback = (params) => { if (params.rect.width - params.labelRect.width < 2) { return { - y: '1000%', + y: '100000%', }; } else { return { @@ -293,28 +299,13 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft } public onDataUpdated() { - let minTime = this.ctx.defaultSubscription.timeWindow.minTime; - let maxTime = this.ctx.defaultSubscription.timeWindow.maxTime; - let dataMin = Number.MAX_VALUE; - let dataMax = Number.MIN_VALUE; for (const item of this.dataItems) { const datasourceData = this.ctx.data ? this.ctx.data.find(d => d.dataKey === item.dataKey) : null; item.data = datasourceData?.data ? toNamedData(datasourceData.data) : []; - if (datasourceData.data.length) { - dataMin = Math.min(datasourceData.data[0][0], dataMin); - dataMax = Math.max(datasourceData.data[datasourceData.data.length-1][0], dataMax); - } - } - if (dataMin !== Number.MAX_VALUE) { - minTime = dataMin - this.ctx.defaultSubscription.timeWindow.interval / 2; - } - if (dataMax !== Number.MIN_VALUE) { - dataMax = dataMax + this.ctx.defaultSubscription.timeWindow.interval / 2; - maxTime = Math.max(dataMax, maxTime); } if (this.barChart) { - (this.barChartOptions.xAxis as any).min = minTime; - (this.barChartOptions.xAxis as any).max = maxTime; + (this.barChartOptions.xAxis as any).min = this.ctx.defaultSubscription.timeWindow.minTime; + (this.barChartOptions.xAxis as any).max = this.ctx.defaultSubscription.timeWindow.maxTime; (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; this.barChartOptions.series = this.updateSeries(); this.barChart.setOption(this.barChartOptions); @@ -332,7 +323,15 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft color: item.dataKey.color, data: item.data, renderItem: this.barRenderItem, - labelLayout: this.barLabelLayoutCallback + labelLayout: this.barLabelLayoutCallback, + dimensions: [ + {name: 'intervalStart', type: 'number'}, + {name: 'intervalEnd', type: 'number'} + ], + encode: { + intervalStart: 2, + intervalEnd: 3 + } }; series.push(seriesOption); } @@ -407,8 +406,8 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft axisLine: { onZero: false }, - min: this.ctx.defaultSubscription.timeWindow.minTime - this.ctx.defaultSubscription.timeWindow.interval / 2, - max: this.ctx.defaultSubscription.timeWindow.maxTime + this.ctx.defaultSubscription.timeWindow.interval / 2 + min: this.ctx.defaultSubscription.timeWindow.minTime, + max: this.ctx.defaultSubscription.timeWindow.maxTime }, yAxis: { type: 'value', @@ -425,6 +424,8 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft if (this.settings.showTooltip) { this.barChartOptions.tooltip = { trigger: 'axis', + confine: true, + appendToBody: true, axisPointer: { type: 'shadow' }, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts index 23d7af8986..8bf2254a66 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts @@ -17,7 +17,7 @@ import * as echarts from 'echarts/core'; import { Axis } from 'echarts'; import AxisModel from 'echarts/types/src/coord/cartesian/AxisModel'; -import { formatValue, isNumber } from '@core/utils'; +import { formatValue, isDefinedAndNotNull, isNumber, isString } from '@core/utils'; import TimeScale from 'echarts/types/src/scale/Time'; import { DataZoomComponent, DataZoomComponentOption, @@ -36,7 +36,8 @@ import { } from 'echarts/charts'; import { LabelLayout } from 'echarts/features'; import { CanvasRenderer, SVGRenderer } from 'echarts/renderers'; -import { DataSet } from '@shared/models/widget.models'; +import { DataEntry, DataSet } from '@shared/models/widget.models'; +import { Interval, IntervalMath } from '@shared/models/time/time.models'; import { CallbackDataParams } from 'echarts/types/dist/shared'; import { Renderer2 } from '@angular/core'; import { DateFormatProcessor, DateFormatSettings, Font } from '@shared/models/widget-settings.models'; @@ -51,13 +52,13 @@ class EChartsModule { Axis.prototype.getBandWidth = function(){ const model: AxisModel = this.model; const axisOption = model.option; - const tbTimewindowInterval = (axisOption as any).tbTimewindowInterval; - if (this.scale.type === 'time' && isNumber(tbTimewindowInterval)) { + const tbTimewindowInterval: Interval = (axisOption as any).tbTimewindowInterval; + if (this.scale.type === 'time' && (isNumber(tbTimewindowInterval) || isString(tbTimewindowInterval))) { const timeScale: TimeScale = this.scale; const axisExtent: [number, number] = this._extent; const dataExtent = timeScale.getExtent(); const size = Math.abs(axisExtent[1] - axisExtent[0]); - return tbTimewindowInterval * (size / (dataExtent[1] - dataExtent[0])); + return IntervalMath.numberValue(tbTimewindowInterval) * (size / (dataExtent[1] - dataExtent[0])); } else { return axisGetBandWidth.call(this); } @@ -99,17 +100,31 @@ export type EChartsOption = echarts.ComposeOption< export type ECharts = echarts.ECharts; -export type NamedDataSet = {name: string; value: [number, any]}[]; +export type EChartsDataItem = [number, any, number, number]; + +export type NamedDataSet = {name: string; value: EChartsDataItem}[]; export const toNamedData = (data: DataSet): NamedDataSet => { if (!data?.length) { return []; } else { - return data.map(d => ({ - name: d[0] + '', - value: d - })); + return data.map(d => { + const ts = isDefinedAndNotNull(d[2]) ? d[2][0] : d[0]; + return { + name: ts + '', + value: toEChartsDataItem(d) + }; + }); + } +}; + +const toEChartsDataItem = (entry: DataEntry): EChartsDataItem => { + const item: EChartsDataItem = [entry[0], entry[1], entry[0], entry[0]]; + if (isDefinedAndNotNull(entry[2])) { + item[2] = entry[2][0]; + item[3] = entry[2][1]; } + return item; }; export interface EChartsTooltipWidgetSettings { @@ -141,9 +156,22 @@ export const echartsTooltipFormatter = (renderer: Renderer2, renderer.setStyle(tooltipElement, 'gap', '4px'); if (settings.tooltipShowDate) { const dateElement: HTMLElement = renderer.createElement('div'); - const ts = params[0].value[0]; - tooltipDateFormat.update(ts); - renderer.appendChild(dateElement, renderer.createText(tooltipDateFormat.formatted)); + let dateText: string; + const startTs = params[0].value[2]; + const endTs = params[0].value[3]; + if (startTs && endTs && (endTs - 1) > startTs) { + const startDateText = tooltipDateFormat.update(startTs); + const endDateText = tooltipDateFormat.update(endTs - 1); + if (startDateText === endDateText) { + dateText = startDateText; + } else { + dateText = startDateText + ' - ' + endDateText; + } + } else { + const ts = params[0].value[0]; + dateText = tooltipDateFormat.update(ts); + } + renderer.appendChild(dateElement, renderer.createText(dateText)); renderer.setStyle(dateElement, 'font-family', settings.tooltipDateFont.family); renderer.setStyle(dateElement, 'font-size', settings.tooltipDateFont.size + settings.tooltipDateFont.sizeUnit); renderer.setStyle(dateElement, 'font-style', settings.tooltipDateFont.style); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts index 84749b146c..b199b2c64f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts @@ -392,6 +392,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn show: false, type: 'piecewise', selected: this.selectedRanges, + dimension: 1, pieces: this.rangeItems.map(item => item.piece), outOfRange: { color: this.settings.outOfRangeColor @@ -405,6 +406,8 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn if (this.settings.showTooltip) { this.rangeChartOptions.tooltip = { trigger: 'axis', + confine: true, + appendToBody: true, formatter: (params: CallbackDataParams[]) => echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, this.settings, params, this.decimals, this.units, 0), padding: [8, 12], diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index b984ad4764..846c6b8331 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -56,7 +56,7 @@ import { } from './flot-widget.models'; import * as moment_ from 'moment'; import tinycolor from 'tinycolor2'; -import { AggregationType } from '@shared/models/time/time.models'; +import { AggregationType, IntervalMath } from '@shared/models/time/time.models'; import { CancelAnimationFrame } from '@core/services/raf.service'; import { UtilsService } from '@core/services/utils.service'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; @@ -558,7 +558,7 @@ export class TbFlot { this.subscription.timeWindowConfig.aggregation.type === AggregationType.NONE) { this.options.series.bars.barWidth = this.defaultBarWidth; } else { - this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; + this.options.series.bars.barWidth = IntervalMath.numberValue(this.subscription.timeWindow.interval) * 0.6; } } this.options.xaxes[0].min = this.subscription.timeWindow.minTime; @@ -663,7 +663,7 @@ export class TbFlot { this.subscription.timeWindowConfig.aggregation.type === AggregationType.NONE) { this.options.series.bars.barWidth = this.defaultBarWidth; } else { - this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; + this.options.series.bars.barWidth = IntervalMath.numberValue(this.subscription.timeWindow.interval) * 0.6; } } @@ -681,7 +681,7 @@ export class TbFlot { this.subscription.timeWindowConfig.aggregation.type === AggregationType.NONE) { this.plot.getOptions().series.bars.barWidth = this.defaultBarWidth; } else { - this.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; + this.plot.getOptions().series.bars.barWidth = IntervalMath.numberValue(this.subscription.timeWindow.interval) * 0.6; } } this.updateData(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.component.ts index 738b26563f..3c79883bf3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.component.ts @@ -60,6 +60,7 @@ import { TranslateService } from '@ngx-translate/core'; import ITooltipsterInstance = JQueryTooltipster.ITooltipsterInstance; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; +import { DataEntry } from '@shared/models/widget.models'; @Component({ selector: 'tb-liquid-level-widget', @@ -399,7 +400,7 @@ export class LiquidLevelWidgetComponent implements OnInit { return limits.min + (percentage / 100) * (limits.max - limits.min); } - private updateTooltip(value: [number, any]): void { + private updateTooltip(value: DataEntry): void { this.tooltipContent = this.getTooltipContent(value); if (this.tooltip) { @@ -494,7 +495,7 @@ export class LiquidLevelWidgetComponent implements OnInit { } } - private getTooltipContent(value?: [number, any]): string { + private getTooltipContent(value?: DataEntry): string { const contentValue = value || [0, '']; let tooltipValue: string | number = 'N/A'; diff --git a/ui-ngx/src/app/shared/components/time/timeinterval.component.html b/ui-ngx/src/app/shared/components/time/timeinterval.component.html index 704e7e9ec2..04292b4d93 100644 --- a/ui-ngx/src/app/shared/components/time/timeinterval.component.html +++ b/ui-ngx/src/app/shared/components/time/timeinterval.component.html @@ -43,7 +43,7 @@

{{ predefinedName }} - + {{ interval.name | translate:interval.translateParams }} diff --git a/ui-ngx/src/app/shared/components/time/timeinterval.component.ts b/ui-ngx/src/app/shared/components/time/timeinterval.component.ts index 2e092a3407..8775b0a6ed 100644 --- a/ui-ngx/src/app/shared/components/time/timeinterval.component.ts +++ b/ui-ngx/src/app/shared/components/time/timeinterval.component.ts @@ -16,10 +16,11 @@ import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { TimeInterval, TimeService } from '@core/services/time.service'; +import { TimeService } from '@core/services/time.service'; import { coerceNumberProperty } from '@angular/cdk/coercion'; import { SubscriptSizing } from '@angular/material/form-field'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { Interval, IntervalMath, TimeInterval } from '@shared/models/time/time.models'; @Component({ selector: 'tb-timeinterval', @@ -72,6 +73,10 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { @coerceBoolean() disabledAdvanced = false; + @Input() + @coerceBoolean() + useCalendarIntervals = false; + @Output() hideFlagChange = new EventEmitter(); @Input() disabled: boolean; @@ -84,8 +89,8 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { mins = 1; secs = 0; - intervalMs = 0; - modelValue: number; + interval: Interval = 0; + modelValue: Interval; advanced = false; rendered = false; @@ -112,26 +117,26 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { this.disabled = isDisabled; } - writeValue(intervalMs: number): void { - this.modelValue = intervalMs; + writeValue(interval: Interval): void { + this.modelValue = interval; this.rendered = true; if (typeof this.modelValue !== 'undefined') { const min = this.timeService.boundMinInterval(this.minValue); const max = this.timeService.boundMaxInterval(this.maxValue); - if (this.modelValue >= min && this.modelValue <= max) { - this.advanced = !this.timeService.matchesExistingInterval(this.minValue, this.maxValue, this.modelValue); - this.setIntervalMs(this.modelValue); + if (IntervalMath.numberValue(this.modelValue) >= min && IntervalMath.numberValue(this.modelValue) <= max) { + this.advanced = !this.timeService.matchesExistingInterval(this.minValue, this.maxValue, this.modelValue, this.useCalendarIntervals); + this.setInterval(this.modelValue); } else { this.boundInterval(); } } } - setIntervalMs(intervalMs: number) { + setInterval(interval: Interval) { if (!this.advanced) { - this.intervalMs = intervalMs; + this.interval = interval; } - const intervalSeconds = Math.floor(intervalMs / 1000); + const intervalSeconds = Math.floor(IntervalMath.numberValue(interval) / 1000); this.days = Math.floor(intervalSeconds / 86400); this.hours = Math.floor((intervalSeconds % 86400) / 3600); this.mins = Math.floor(((intervalSeconds % 86400) % 3600) / 60); @@ -141,19 +146,20 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { boundInterval(updateToPreferred = false) { const min = this.timeService.boundMinInterval(this.minValue); const max = this.timeService.boundMaxInterval(this.maxValue); - this.intervals = this.timeService.getIntervals(this.minValue, this.maxValue); + this.intervals = this.timeService.getIntervals(this.minValue, this.maxValue, this.useCalendarIntervals); if (this.rendered) { - let newIntervalMs = this.modelValue; + let newInterval = this.modelValue; + const newIntervalMs = IntervalMath.numberValue(newInterval); if (newIntervalMs < min) { - newIntervalMs = min; + newInterval = min; } else if (newIntervalMs >= max && updateToPreferred) { - newIntervalMs = this.timeService.boundMaxInterval(max / 7); + newInterval = this.timeService.boundMaxInterval(max / 7); } if (!this.advanced) { - newIntervalMs = this.timeService.boundToPredefinedInterval(min, max, newIntervalMs); + newInterval = this.timeService.boundToPredefinedInterval(min, max, newInterval, this.useCalendarIntervals); } - if (newIntervalMs !== this.modelValue) { - this.setIntervalMs(newIntervalMs); + if (newInterval !== this.modelValue) { + this.setInterval(newInterval); this.updateView(); } } @@ -163,18 +169,18 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { if (!this.rendered) { return; } - let value = null; - let intervalMs; + let value: Interval = null; + let interval: Interval; if (!this.advanced) { - intervalMs = this.intervalMs; - if (!intervalMs || isNaN(intervalMs)) { - intervalMs = this.calculateIntervalMs(); + interval = this.interval; + if (!interval || typeof interval === 'number' && isNaN(interval)) { + interval = this.calculateIntervalMs(); } } else { - intervalMs = this.calculateIntervalMs(); + interval = this.calculateIntervalMs(); } - if (!isNaN(intervalMs) && intervalMs > 0) { - value = intervalMs; + if (typeof interval === 'string' || !isNaN(interval) && interval > 0) { + value = interval; } this.modelValue = value; this.propagateChange(this.modelValue); @@ -188,19 +194,19 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { this.secs) * 1000; } - onIntervalMsChange() { + onIntervalChange() { this.updateView(); } onAdvancedChange() { if (!this.advanced) { - this.intervalMs = this.calculateIntervalMs(); + this.interval = this.calculateIntervalMs(); } else { - let intervalMs = this.intervalMs; - if (!intervalMs || isNaN(intervalMs)) { - intervalMs = this.calculateIntervalMs(); + let interval = this.interval; + if (!interval || typeof interval === 'number' && isNaN(interval)) { + interval = this.calculateIntervalMs(); } - this.setIntervalMs(intervalMs); + this.setInterval(interval); } this.updateView(); } diff --git a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html index f763cf8e85..1ad06bab3e 100644 --- a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html +++ b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html @@ -203,6 +203,7 @@ [(hideFlag)]="timewindow.hideAggInterval" (hideFlagChange)="onHideAggIntervalChanged()" [min]="minRealtimeAggInterval()" [max]="maxRealtimeAggInterval()" + useCalendarIntervals predefinedName="aggregation.group-interval">
@@ -215,6 +216,7 @@ [(hideFlag)]="timewindow.hideAggInterval" (hideFlagChange)="onHideAggIntervalChanged()" [min]="minHistoryAggInterval()" [max]="maxHistoryAggInterval()" + useCalendarIntervals predefinedName="aggregation.group-interval">
diff --git a/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts b/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts index 3531fd782a..95c8cd4925 100644 --- a/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts +++ b/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts @@ -171,6 +171,14 @@ export class AttributesSubscriptionCmd extends SubscriptionCmd { type = WsCmdType.ATTRIBUTES; } +export enum IntervalType { + MILLISECONDS = 'MILLISECONDS', + WEEK = 'WEEK', + WEEK_ISO = 'WEEK_ISO', + MONTH = 'MONTH', + QUARTER = 'QUARTER' +} + export class TimeseriesSubscriptionCmd extends SubscriptionCmd { startTs: number; timeWindow: number; @@ -197,7 +205,9 @@ export interface EntityHistoryCmd { keys: Array; startTs: number; endTs: number; + intervalType: IntervalType; interval: number; + timeZoneId: string; limit: number; agg: AggregationType; fetchLatestPreviousPoint?: boolean; @@ -211,7 +221,9 @@ export interface TimeSeriesCmd { keys: Array; startTs: number; timeWindow: number; + intervalType: IntervalType; interval: number; + timeZoneId: string; limit: number; agg: AggregationType; fetchLatestPreviousPoint?: boolean; @@ -382,12 +394,14 @@ export class TelemetryPluginCmdsWrapper implements CmdWrapper { } } +export type SubscriptionDataEntry = [number, any, number?]; + export interface SubscriptionData { - [key: string]: [number, any, number?][]; + [key: string]: SubscriptionDataEntry[]; } export interface IndexedSubscriptionData { - [id: number]: [number, any, number?][]; + [id: number]: SubscriptionDataEntry[]; } export interface SubscriptionDataHolder { diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index 4a063a26c3..f45fd54b5b 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -18,6 +18,7 @@ import { TimeService } from '@core/services/time.service'; import { deepClone, isDefined, isNumeric, isUndefined } from '@app/core/utils'; import * as moment_ from 'moment'; import * as momentTz from 'moment-timezone'; +import { IntervalType } from '@shared/models/telemetry/telemetry.models'; const moment = moment_; @@ -26,6 +27,11 @@ export const MINUTE = 60 * SECOND; export const HOUR = 60 * MINUTE; export const DAY = 24 * HOUR; export const WEEK = 7 * DAY; + +export const AVG_MONTH = Math.floor(30.44 * DAY); + +export const AVG_QUARTER = Math.floor(DAY * 365.2425 / 4); + export const YEAR = DAY * 365; export type ComparisonDuration = moment_.unitOfTime.DurationConstructor | 'previousInterval' | 'customInterval'; @@ -47,8 +53,28 @@ export enum HistoryWindowType { FOR_ALL_TIME } +export type Interval = number | IntervalType; + +export class IntervalMath { + public static max(...values: Interval[]): Interval { + const numberArr = values.map(v => IntervalMath.numberValue(v)); + const index = numberArr.indexOf(Math.max(...numberArr)); + return values[index]; + } + + public static min(...values: Interval[]): Interval { + const numberArr = values.map(v => IntervalMath.numberValue(v)); + const index = numberArr.indexOf(Math.min(...numberArr)); + return values[index]; + } + + public static numberValue(value: Interval): number { + return typeof value === 'number' ? value : IntervalTypeValuesMap.get(value); + } +} + export interface IntervalWindow { - interval?: number; + interval?: Interval; timewindowMs?: number; quickInterval?: QuickTimeInterval; } @@ -88,7 +114,7 @@ export const aggregationTranslations = new Map( ); export interface Aggregation { - interval?: number; + interval?: Interval; type: AggregationType; limit: number; } @@ -110,7 +136,7 @@ export interface Timewindow { } export interface SubscriptionAggregation extends Aggregation { - interval?: number; + interval?: Interval; timeWindow?: number; stateData?: boolean; } @@ -129,8 +155,9 @@ export interface SubscriptionTimewindow { export interface WidgetTimewindow { minTime?: number; maxTime?: number; - interval?: number; + interval?: Interval; timezone?: string; + tsOffset?: number; stDiff?: number; } @@ -188,6 +215,13 @@ export const QuickTimeIntervalTranslationMap = new Map([ + [IntervalType.WEEK, WEEK], + [IntervalType.WEEK_ISO, WEEK], + [IntervalType.MONTH, AVG_MONTH], + [IntervalType.QUARTER, AVG_QUARTER] +]); + export const forAllTimeInterval = (): Timewindow => ({ selectedTab: TimewindowType.HISTORY, history: { @@ -324,7 +358,7 @@ export const initModelFromDefaultTimewindow = (value: Timewindow, quickIntervalO }; export const toHistoryTimewindow = (timewindow: Timewindow, startTimeMs: number, endTimeMs: number, - interval: number, timeService: TimeService): Timewindow => { + interval: Interval, timeService: TimeService): Timewindow => { if (timewindow.history) { interval = isDefined(interval) ? interval : timewindow.history.interval; } else if (timewindow.realtime) { @@ -412,23 +446,23 @@ const getSubscriptionRealtimeWindowFromTimeInterval = (interval: QuickTimeInterv case QuickTimeInterval.CURRENT_MONTH: case QuickTimeInterval.CURRENT_MONTH_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('month').diff(currentDate.clone().startOf('month')); + return currentDate.endOf('month').add(1, 'milliseconds').diff(currentDate.clone().startOf('month')); case QuickTimeInterval.CURRENT_QUARTER: case QuickTimeInterval.CURRENT_QUARTER_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('quarter').diff(currentDate.clone().startOf('quarter')); + return currentDate.endOf('quarter').add(1, 'milliseconds').diff(currentDate.clone().startOf('quarter')); case QuickTimeInterval.CURRENT_HALF_YEAR: case QuickTimeInterval.CURRENT_HALF_YEAR_SO_FAR: currentDate = getCurrentTime(tz); if (currentDate.get('quarter') < 3) { - return currentDate.clone().set('quarter', 2).endOf('quarter').diff(currentDate.startOf('year')); + return currentDate.clone().set('quarter', 2).endOf('quarter').add(1, 'milliseconds').diff(currentDate.startOf('year')); } else { - return currentDate.endOf('year').diff(currentDate.clone().set('quarter', 3).startOf('quarter')); + return currentDate.endOf('year').add(1, 'milliseconds').diff(currentDate.clone().set('quarter', 3).startOf('quarter')); } case QuickTimeInterval.CURRENT_YEAR: case QuickTimeInterval.CURRENT_YEAR_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('year').diff(currentDate.clone().startOf('year')); + return currentDate.endOf('year').add(1, 'milliseconds').diff(currentDate.clone().startOf('year')); } }; @@ -551,10 +585,10 @@ export const createSubscriptionTimewindow = (timewindow: Timewindow, stDiff: num limit: timeService.getMaxDatapointsLimit(), type: AggregationType.AVG }, - timezone: timewindow.timezone, + timezone: timewindow.timezone || getDefaultTimezone(), tsOffset: calculateTsOffset(timewindow.timezone) }; - let aggTimewindow; + let aggTimewindow: number; if (stateData) { subscriptionTimewindow.aggregation.type = AggregationType.NONE; subscriptionTimewindow.aggregation.stateData = true; @@ -587,16 +621,13 @@ export const createSubscriptionTimewindow = (timewindow: Timewindow, stDiff: num subscriptionTimewindow.startTs = currentDate.valueOf() + stDiff - subscriptionTimewindow.realtimeWindowMs; } subscriptionTimewindow.aggregation.interval = - timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval, - subscriptionTimewindow.aggregation.type); + subscriptionTimewindow.aggregation.type === AggregationType.NONE + ? SECOND + : (!!timewindow.realtime.interval ? timewindow.realtime.interval : + timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval, + subscriptionTimewindow.aggregation.type)); + aggTimewindow = subscriptionTimewindow.realtimeWindowMs; - if (realtimeType !== RealtimeWindowType.INTERVAL) { - const startDiff = subscriptionTimewindow.startTs % subscriptionTimewindow.aggregation.interval; - if (startDiff) { - subscriptionTimewindow.startTs -= startDiff; - aggTimewindow += subscriptionTimewindow.aggregation.interval; - } - } } else { let historyType = timewindow.history.historyType; if (isUndefined(historyType)) { @@ -633,12 +664,17 @@ export const createSubscriptionTimewindow = (timewindow: Timewindow, stDiff: num } subscriptionTimewindow.startTs = subscriptionTimewindow.fixedWindow.startTimeMs; subscriptionTimewindow.aggregation.interval = - timeService.boundIntervalToTimewindow(aggTimewindow, timewindow.history.interval, subscriptionTimewindow.aggregation.type); + subscriptionTimewindow.aggregation.type === AggregationType.NONE + ? SECOND + : (!!timewindow.history.interval ? timewindow.history.interval : + timeService.boundIntervalToTimewindow(aggTimewindow, timewindow.history.interval, + subscriptionTimewindow.aggregation.type)); } const aggregation = subscriptionTimewindow.aggregation; aggregation.timeWindow = aggTimewindow; if (aggregation.type !== AggregationType.NONE) { - aggregation.limit = Math.ceil(aggTimewindow / subscriptionTimewindow.aggregation.interval); + aggregation.limit = calculateIntervalsCount(subscriptionTimewindow.startTs, aggTimewindow, + subscriptionTimewindow.aggregation.interval, timewindow.timezone); } return subscriptionTimewindow; }; @@ -759,12 +795,13 @@ export const createTimewindowForComparison = (subscriptionTimewindow: Subscripti fixedWindow: null, realtimeWindowMs: null, aggregation: subscriptionTimewindow.aggregation, - tsOffset: subscriptionTimewindow.tsOffset + tsOffset: subscriptionTimewindow.tsOffset, + timezone: subscriptionTimewindow.timezone }; if (subscriptionTimewindow.fixedWindow) { - let startTimeMs; - let endTimeMs; + let startTimeMs: number; + let endTimeMs: number; if (timeUnit === 'previousInterval') { if (subscriptionTimewindow.quickInterval) { const startDate = moment(subscriptionTimewindow.fixedWindow.startTimeMs); @@ -829,7 +866,7 @@ export const cloneSelectedTimewindow = (timewindow: Timewindow): Timewindow => { export interface TimeInterval { name: string; translateParams: {[key: string]: any}; - value: number; + value: Interval; } export const defaultTimeIntervals = new Array( @@ -923,10 +960,30 @@ export const defaultTimeIntervals = new Array( translateParams: {days: 7}, value: 7 * DAY }, + { + name: 'timeinterval.type.week', + translateParams: {}, + value: IntervalType.WEEK + }, + { + name: 'timeinterval.type.week-iso', + translateParams: {}, + value: IntervalType.WEEK_ISO + }, { name: 'timeinterval.days-interval', translateParams: {days: 30}, value: 30 * DAY + }, + { + name: 'timeinterval.type.month', + translateParams: {}, + value: IntervalType.MONTH + }, + { + name: 'timeinterval.type.quarter', + translateParams: {}, + value: IntervalType.QUARTER } ); @@ -1013,5 +1070,72 @@ export const getTime = (ts: number, tz?: string): moment_.Moment => { } }; +export const calculateIntervalsCount = (startTs: number, timewindow: number, interval: Interval, tz?: string): number => { + if (typeof interval === 'number') { + return Math.ceil(timewindow / interval); + } else { + const current = getTime(startTs, tz); + const endDate = getTime(startTs + timewindow, tz); + let startInterval = startIntervalDate(current, interval); + let endInterval = endIntervalDate(current, interval); + let count = 0; + while (startInterval.isBefore(endDate)) { + count++; + endInterval.add(1, 'milliseconds'); + startInterval = startIntervalDate(endInterval, interval); + endInterval = endIntervalDate(endInterval, interval); + } + return count; + } +}; + +export const startIntervalDate = (current: moment_.Moment, interval: IntervalType): moment_.Moment => { + switch (interval) { + case IntervalType.WEEK: + return current.clone().startOf('week'); + case IntervalType.WEEK_ISO: + return current.clone().startOf('isoWeek'); + case IntervalType.MONTH: + return current.clone().startOf('month'); + case IntervalType.QUARTER: + return current.clone().startOf('quarter'); + } +}; + +export const endIntervalDate = (current: moment_.Moment, interval: IntervalType): moment_.Moment => { + switch (interval) { + case IntervalType.WEEK: + return current.clone().endOf('week'); + case IntervalType.WEEK_ISO: + return current.clone().endOf('isoWeek'); + case IntervalType.MONTH: + return current.clone().endOf('month'); + case IntervalType.QUARTER: + return current.clone().endOf('quarter'); + } +}; + +export const calculateAggInterval = (subsTw: SubscriptionTimewindow, endTs: number, timestamp: number): [number, number] => { + let startIntervalTs: number; + let endIntervalTs: number; + if (typeof subsTw.aggregation.interval === 'number') { + const startTs = subsTw.startTs + subsTw.tsOffset; + startIntervalTs = startTs + Math.floor((timestamp - startTs) / subsTw.aggregation.interval) * subsTw.aggregation.interval; + endIntervalTs = startIntervalTs + subsTw.aggregation.interval; + } else { + const time = getTime(timestamp, subsTw.timezone); + let startInterval = startIntervalDate(time, subsTw.aggregation.interval); + const start = getTime(subsTw.startTs, subsTw.timezone); + if (start.isAfter(startInterval)) { + startInterval = start; + } + const endInterval = endIntervalDate(time, subsTw.aggregation.interval).add(1, 'milliseconds'); + startIntervalTs = startInterval.valueOf() + subsTw.tsOffset; + endIntervalTs = endInterval.valueOf() + subsTw.tsOffset; + } + endIntervalTs = Math.min(endIntervalTs, endTs); + return [startIntervalTs, endIntervalTs]; +}; + export const getCurrentTimeForComparison = (timeForComparison: moment_.unitOfTime.DurationConstructor, tz?: string): moment_.Moment => getCurrentTime(tz).subtract(1, timeForComparison); diff --git a/ui-ngx/src/app/shared/models/widget-settings.models.ts b/ui-ngx/src/app/shared/models/widget-settings.models.ts index 6a1cd755f6..a3d5b57954 100644 --- a/ui-ngx/src/app/shared/models/widget-settings.models.ts +++ b/ui-ngx/src/app/shared/models/widget-settings.models.ts @@ -15,7 +15,7 @@ /// import { isDefinedAndNotNull, isNumber, isNumeric, isUndefinedOrNull, parseFunction } from '@core/utils'; -import { DataKey, Datasource, DatasourceData } from '@shared/models/widget.models'; +import { DataEntry, DataKey, Datasource, DatasourceData } from '@shared/models/widget.models'; import { Injector } from '@angular/core'; import { DatePipe } from '@angular/common'; import { DateAgoPipe } from '@shared/pipe/date-ago.pipe'; @@ -366,7 +366,7 @@ export abstract class DateFormatProcessor { protected settings: DateFormatSettings) { } - abstract update(ts: string | number | Date): void; + abstract update(ts: string | number | Date): string; } @@ -380,12 +380,13 @@ export class SimpleDateFormatProcessor extends DateFormatProcessor { this.datePipe = $injector.get(DatePipe); } - update(ts: string| number | Date): void { + update(ts: string| number | Date): string { if (ts) { this.formatted = this.datePipe.transform(ts, this.settings.format); } else { this.formatted = ' '; } + return this.formatted; } } @@ -402,7 +403,7 @@ export class LastUpdateAgoDateFormatProcessor extends DateFormatProcessor { this.translate = $injector.get(TranslateService); } - update(ts: string| number | Date): void { + update(ts: string| number | Date): string { if (ts) { const agoText = this.dateAgoPipe.transform(ts, {applyAgo: true, short: true, textPart: true}); if (this.settings.hideLastUpdatePrefix) { @@ -414,6 +415,7 @@ export class LastUpdateAgoDateFormatProcessor extends DateFormatProcessor { } else { this.formatted = ' '; } + return this.formatted; } } @@ -629,7 +631,7 @@ export const setLabel = (label: string, datasources?: Datasource[]): void => { } }; -export const getSingleTsValue = (data: Array): [number, any] => { +export const getSingleTsValue = (data: Array): DataEntry => { if (data.length) { const dsData = data[0]; if (dsData.data.length) { @@ -639,7 +641,7 @@ export const getSingleTsValue = (data: Array): [number, any] => return null; }; -export const getSingleTsValueByDataKey = (data: Array, dataKey: DataKey): [number, any] => { +export const getSingleTsValueByDataKey = (data: Array, dataKey: DataKey): DataEntry => { if (data.length) { const dsData = data.find(d => d.dataKey === dataKey); if (dsData?.data?.length) { @@ -649,7 +651,7 @@ export const getSingleTsValueByDataKey = (data: Array, dataKey: return null; }; -export const getLatestSingleTsValue = (data: Array): [number, any] => { +export const getLatestSingleTsValue = (data: Array): DataEntry => { if (data.length) { const dsData = data[0]; if (dsData.data.length) { diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 2db85b853e..c8e5699d82 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -461,7 +461,13 @@ export interface ReplaceInfo { dataKeyName: string; } -export type DataSet = [number, any][]; +export type DataEntry = [number, any, [number, number]?]; + +export type DataSet = DataEntry[]; + +export interface IndexedData { + [id: number]: DataSet; +} export interface DataSetHolder { data: DataSet; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index de8d7706d5..e0e868cf96 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4220,6 +4220,12 @@ "current-half-year-so-far": "Current half year so far", "current-year": "Current year", "current-year-so-far": "Current year so far" + }, + "type": { + "week": "Week (Sun - Sat)", + "week-iso": "Week (Mon - Sun)", + "month": "Month", + "quarter": "Quarter" } }, "timeunit": { diff --git a/ui-ngx/yarn.lock b/ui-ngx/yarn.lock index 50815ce794..2c60a7f009 100644 --- a/ui-ngx/yarn.lock +++ b/ui-ngx/yarn.lock @@ -9840,6 +9840,11 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" +sorted-btree@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/sorted-btree/-/sorted-btree-1.8.1.tgz#6e6275f7955e5892bb8737149cbe495be10f426f" + integrity sha512-395+XIP+wqNn3USkFSrNz7G3Ss/MXlZEqesxvzCRFwL14h6e8LukDHdLBePn5pwbm5OQ9vGu8mDyz2lLDIqamQ== + "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" From d677f7c790b6ef4d77b614671a3f96057b9bcc8b Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Jan 2024 16:23:24 +0200 Subject: [PATCH 88/91] UI: Fix realtime timewindow calculation for quick interval. --- ui-ngx/src/app/shared/models/time/time.models.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index f45fd54b5b..c16b109984 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -446,23 +446,23 @@ const getSubscriptionRealtimeWindowFromTimeInterval = (interval: QuickTimeInterv case QuickTimeInterval.CURRENT_MONTH: case QuickTimeInterval.CURRENT_MONTH_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('month').add(1, 'milliseconds').diff(currentDate.clone().startOf('month')); + return currentDate.clone().endOf('month').add(1, 'milliseconds').diff(currentDate.clone().startOf('month')); case QuickTimeInterval.CURRENT_QUARTER: case QuickTimeInterval.CURRENT_QUARTER_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('quarter').add(1, 'milliseconds').diff(currentDate.clone().startOf('quarter')); + return currentDate.clone().endOf('quarter').add(1, 'milliseconds').diff(currentDate.clone().startOf('quarter')); case QuickTimeInterval.CURRENT_HALF_YEAR: case QuickTimeInterval.CURRENT_HALF_YEAR_SO_FAR: currentDate = getCurrentTime(tz); if (currentDate.get('quarter') < 3) { - return currentDate.clone().set('quarter', 2).endOf('quarter').add(1, 'milliseconds').diff(currentDate.startOf('year')); + return currentDate.clone().set('quarter', 2).endOf('quarter').add(1, 'milliseconds').diff(currentDate.clone().startOf('year')); } else { - return currentDate.endOf('year').add(1, 'milliseconds').diff(currentDate.clone().set('quarter', 3).startOf('quarter')); + return currentDate.clone().endOf('year').add(1, 'milliseconds').diff(currentDate.clone().set('quarter', 3).startOf('quarter')); } case QuickTimeInterval.CURRENT_YEAR: case QuickTimeInterval.CURRENT_YEAR_SO_FAR: currentDate = getCurrentTime(tz); - return currentDate.endOf('year').add(1, 'milliseconds').diff(currentDate.clone().startOf('year')); + return currentDate.clone().endOf('year').add(1, 'milliseconds').diff(currentDate.clone().startOf('year')); } }; From d2ba3d2d841d085371671b97d9c825f698152d69 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Jan 2024 18:03:40 +0200 Subject: [PATCH 89/91] UI: Calculate correct interval length for echarts axis pointer. --- ui-ngx/src/app/core/api/data-aggregator.ts | 6 +-- .../bar-chart-with-labels-widget.component.ts | 4 +- .../widget/lib/chart/echarts-widget.models.ts | 51 ++++++++++++++++--- .../src/app/shared/models/time/time.models.ts | 34 ++++++++----- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index a16c4baa5b..c11c08ad2b 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -19,7 +19,7 @@ import { IndexedSubscriptionData, } from '@app/shared/models/telemetry/telemetry.models'; import { - AggregationType, calculateAggInterval, + AggregationType, calculateAggIntervalWithSubscriptionTimeWindow, calculateIntervalComparisonEndTime, calculateIntervalEndTime, calculateIntervalStartEndTime, @@ -79,7 +79,7 @@ class AggDataMap { } calculateAggInterval(timestamp: number): [number, number] { - return calculateAggInterval(this.subsTw, this.endTs, timestamp); + return calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, this.endTs, timestamp); } updateLastInterval(endTs: number) { @@ -88,7 +88,7 @@ class AggDataMap { const lastTs = this.map.maxKey(); if (lastTs) { const data = this.map.get(lastTs); - const interval = calculateAggInterval(this.subsTw, endTs, data.ts); + const interval = calculateAggIntervalWithSubscriptionTimeWindow(this.subsTw, endTs, data.ts); data.interval = interval; data.ts = interval[0] + Math.floor((interval[1] - interval[0]) / 2); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts index ea8c46880e..57dbf908dd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -306,7 +306,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft if (this.barChart) { (this.barChartOptions.xAxis as any).min = this.ctx.defaultSubscription.timeWindow.minTime; (this.barChartOptions.xAxis as any).max = this.ctx.defaultSubscription.timeWindow.maxTime; - (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; + (this.barChartOptions.xAxis as any).tbTimeWindow = this.ctx.defaultSubscription.timeWindow; this.barChartOptions.series = this.updateSeries(); this.barChart.setOption(this.barChartOptions); } @@ -417,7 +417,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft } }; - (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; + (this.barChartOptions.xAxis as any).tbTimeWindow = this.ctx.defaultSubscription.timeWindow; this.barChartOptions.series = this.updateSeries(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts index 8bf2254a66..515e47559d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts @@ -37,7 +37,12 @@ import { import { LabelLayout } from 'echarts/features'; import { CanvasRenderer, SVGRenderer } from 'echarts/renderers'; import { DataEntry, DataSet } from '@shared/models/widget.models'; -import { Interval, IntervalMath } from '@shared/models/time/time.models'; +import { + calculateAggIntervalWithWidgetTimeWindow, + Interval, + IntervalMath, + WidgetTimewindow +} from '@shared/models/time/time.models'; import { CallbackDataParams } from 'echarts/types/dist/shared'; import { Renderer2 } from '@angular/core'; import { DateFormatProcessor, DateFormatSettings, Font } from '@shared/models/widget-settings.models'; @@ -52,13 +57,43 @@ class EChartsModule { Axis.prototype.getBandWidth = function(){ const model: AxisModel = this.model; const axisOption = model.option; - const tbTimewindowInterval: Interval = (axisOption as any).tbTimewindowInterval; - if (this.scale.type === 'time' && (isNumber(tbTimewindowInterval) || isString(tbTimewindowInterval))) { - const timeScale: TimeScale = this.scale; - const axisExtent: [number, number] = this._extent; - const dataExtent = timeScale.getExtent(); - const size = Math.abs(axisExtent[1] - axisExtent[0]); - return IntervalMath.numberValue(tbTimewindowInterval) * (size / (dataExtent[1] - dataExtent[0])); + if (this.scale.type === 'time') { + let interval: number; + const seriesDataIndices = axisOption.axisPointer?.seriesDataIndices; + if (seriesDataIndices?.length) { + const seriesDataIndex = seriesDataIndices[0]; + const series = model.ecModel.getSeriesByIndex(seriesDataIndex.seriesIndex); + if (series) { + const values = series.getData().getValues(seriesDataIndex.dataIndex); + const start = values[2]; + const end = values[3]; + if (typeof start === 'number' && typeof end === 'number') { + interval = Math.max(end - start, 1); + } + } + } + if (!interval) { + const tbTimeWindow: WidgetTimewindow = (axisOption as any).tbTimeWindow; + if (isDefinedAndNotNull(tbTimeWindow)) { + if (axisOption.axisPointer?.value && typeof axisOption.axisPointer?.value === 'number') { + const intervalArray = calculateAggIntervalWithWidgetTimeWindow(tbTimeWindow, axisOption.axisPointer.value); + const start = intervalArray[0]; + const end = intervalArray[1]; + interval = Math.max(end - start, 1); + } else { + interval = IntervalMath.numberValue(tbTimeWindow.interval); + } + } + } + if (interval) { + const timeScale: TimeScale = this.scale; + const axisExtent: [number, number] = this._extent; + const dataExtent = timeScale.getExtent(); + const size = Math.abs(axisExtent[1] - axisExtent[0]); + return interval * (size / (dataExtent[1] - dataExtent[0])); + } else { + return axisGetBandWidth.call(this); + } } else { return axisGetBandWidth.call(this); } diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index c16b109984..8d821b6689 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -1115,25 +1115,35 @@ export const endIntervalDate = (current: moment_.Moment, interval: IntervalType) } }; -export const calculateAggInterval = (subsTw: SubscriptionTimewindow, endTs: number, timestamp: number): [number, number] => { +export const calculateAggIntervalWithSubscriptionTimeWindow + = (subsTw: SubscriptionTimewindow, endTs: number, timestamp: number): [number, number] => + calculateInterval(subsTw.startTs, endTs, subsTw.aggregation.interval, subsTw.tsOffset, subsTw.timezone, timestamp); + +export const calculateAggIntervalWithWidgetTimeWindow + = (widgetTimeWindow: WidgetTimewindow, timestamp: number): [number, number] => + calculateInterval(widgetTimeWindow.minTime - widgetTimeWindow.tsOffset, + widgetTimeWindow.maxTime, widgetTimeWindow.interval, widgetTimeWindow.tsOffset, widgetTimeWindow.timezone, timestamp); + +export const calculateInterval = (startTime: number, endTime: number, + interval: Interval, tsOffset: number, timezone: string, timestamp: number): [number, number] => { let startIntervalTs: number; let endIntervalTs: number; - if (typeof subsTw.aggregation.interval === 'number') { - const startTs = subsTw.startTs + subsTw.tsOffset; - startIntervalTs = startTs + Math.floor((timestamp - startTs) / subsTw.aggregation.interval) * subsTw.aggregation.interval; - endIntervalTs = startIntervalTs + subsTw.aggregation.interval; + if (typeof interval === 'number') { + const startTs = startTime + tsOffset; + startIntervalTs = startTs + Math.floor((timestamp - startTs) / interval) * interval; + endIntervalTs = startIntervalTs + interval; } else { - const time = getTime(timestamp, subsTw.timezone); - let startInterval = startIntervalDate(time, subsTw.aggregation.interval); - const start = getTime(subsTw.startTs, subsTw.timezone); + const time = getTime(timestamp, timezone); + let startInterval = startIntervalDate(time, interval); + const start = getTime(startTime, timezone); if (start.isAfter(startInterval)) { startInterval = start; } - const endInterval = endIntervalDate(time, subsTw.aggregation.interval).add(1, 'milliseconds'); - startIntervalTs = startInterval.valueOf() + subsTw.tsOffset; - endIntervalTs = endInterval.valueOf() + subsTw.tsOffset; + const endInterval = endIntervalDate(time, interval).add(1, 'milliseconds'); + startIntervalTs = startInterval.valueOf() + tsOffset; + endIntervalTs = endInterval.valueOf() + tsOffset; } - endIntervalTs = Math.min(endIntervalTs, endTs); + endIntervalTs = Math.min(endIntervalTs, endTime); return [startIntervalTs, endIntervalTs]; }; From 0bf213be7d08d9da755622666caa78bef6d967d4 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Jan 2024 18:29:24 +0200 Subject: [PATCH 90/91] UI: Improve range chart and bar chart axis pointers. --- .../bar-chart-with-labels-widget.component.ts | 40 +++++++++---------- .../lib/chart/range-chart-widget.component.ts | 31 +++++++------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts index 57dbf908dd..2e2faf35e8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -384,7 +384,25 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft }); this.barChartOptions = { tooltip: { - trigger: 'none' + trigger: 'axis', + confine: true, + appendToBody: true, + axisPointer: { + type: 'shadow' + }, + formatter: (params: CallbackDataParams[]) => { + if (this.settings.showTooltip) { + const focusedSeriesIndex = this.focusedSeriesIndex(); + return echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, focusedSeriesIndex); + } else { + return undefined; + } + }, + padding: [8, 12], + backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, + extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }, grid: { containLabel: true, @@ -421,26 +439,6 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft this.barChartOptions.series = this.updateSeries(); - if (this.settings.showTooltip) { - this.barChartOptions.tooltip = { - trigger: 'axis', - confine: true, - appendToBody: true, - axisPointer: { - type: 'shadow' - }, - formatter: (params: CallbackDataParams[]) => { - const focusedSeriesIndex = this.focusedSeriesIndex(); - return echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, - this.settings, params, this.decimals, this.units, focusedSeriesIndex); - }, - padding: [8, 12], - backgroundColor: this.settings.tooltipBackgroundColor, - borderWidth: 0, - extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` - }; - } - this.barChart.setOption(this.barChartOptions); this.shapeResize$ = new ResizeObserver(() => { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts index b199b2c64f..0a8c15b247 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts @@ -286,7 +286,8 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn this.rangeChart.setOption({ xAxis: { min: this.ctx.defaultSubscription.timeWindow.minTime, - max: this.ctx.defaultSubscription.timeWindow.maxTime + max: this.ctx.defaultSubscription.timeWindow.maxTime, + tbTimeWindow: this.ctx.defaultSubscription.timeWindow }, series: [ {data: this.ctx.data?.length ? toNamedData(this.ctx.data[0].data) : []} @@ -315,7 +316,19 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn }); this.rangeChartOptions = { tooltip: { - trigger: 'none' + trigger: 'axis', + confine: true, + appendToBody: true, + axisPointer: { + type: 'shadow' + }, + formatter: (params: CallbackDataParams[]) => + this.settings.showTooltip ? echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, 0) : undefined, + padding: [8, 12], + backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, + extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }, grid: { containLabel: true, @@ -403,19 +416,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn } }; - if (this.settings.showTooltip) { - this.rangeChartOptions.tooltip = { - trigger: 'axis', - confine: true, - appendToBody: true, - formatter: (params: CallbackDataParams[]) => echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, - this.settings, params, this.decimals, this.units, 0), - padding: [8, 12], - backgroundColor: this.settings.tooltipBackgroundColor, - borderWidth: 0, - extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` - }; - } + (this.rangeChartOptions.xAxis as any).tbTimeWindow = this.ctx.defaultSubscription.timeWindow; this.rangeChart.setOption(this.rangeChartOptions); From e9d86fc91877f789796d9cdc412a2ca18acb52a3 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 15 Jan 2024 13:38:15 +0200 Subject: [PATCH 91/91] Test for the precise interval end --- .../server/controller/TelemetryControllerTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java index 98fbffaee5..0a110ef2d0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java @@ -75,8 +75,10 @@ public class TelemetryControllerTest extends AbstractControllerTest { tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899728000L, new LongDataEntry("t", 1L))); // Wednesday, January 10 15:15:28 GMT tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899729000L, new LongDataEntry("t", 3L))); // Wednesday, January 10 15:15:29 GMT - tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek1Ts + 1000, new LongDataEntry("t", 7L))); // Monday, January 15, 2024 0:00:01 GMT+02:00 - tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek2Ts + 1000, new LongDataEntry("t", 11L))); // Monday, January 22, 2024 0:00:01 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek1Ts, new LongDataEntry("t", 2L))); // Monday, January 15, 2024 0:00:00 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek1Ts + 1000, new LongDataEntry("t", 5L))); // Monday, January 15, 2024 0:00:01 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek2Ts, new LongDataEntry("t", 9L))); // Monday, January 22, 2024 0:00:00 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek2Ts + 1000, new LongDataEntry("t", 2L))); // Monday, January 22, 2024 0:00:01 GMT+02:00 ObjectNode result = doGetAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/values/timeseries?keys=t&startTs={startTs}&endTs={endTs}&agg={agg}&intervalType={intervalType}&timeZone={timeZone}",