@c8y/ngx-components 1021.67.0 → 1021.70.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/common/bytes.pipe.d.ts +26 -10
- package/core/common/bytes.pipe.d.ts.map +1 -1
- package/echart/charts.component.d.ts +14 -3
- package/echart/charts.component.d.ts.map +1 -1
- package/esm2022/core/common/bytes.pipe.mjs +47 -18
- package/esm2022/core/data-grid/data-grid.component.mjs +3 -3
- package/esm2022/echart/charts.component.mjs +50 -3
- package/esm2022/messaging-management/api/model/backlogQuota.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespace.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespaceDetails.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespaceList.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespacePolicies.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespacePublishers.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespaceSubscribers.mjs +2 -0
- package/esm2022/messaging-management/api/model/namespaceTopics.mjs +2 -0
- package/esm2022/messaging-management/api/model/pageStatistics.mjs +2 -0
- package/esm2022/messaging-management/api/model/pageable.mjs +2 -0
- package/esm2022/messaging-management/api/model/sortable.mjs +2 -0
- package/esm2022/messaging-management/api/model/subscriber.mjs +2 -0
- package/esm2022/messaging-management/api/model/subscriberFilters.mjs +2 -0
- package/esm2022/messaging-management/api/model/subscriberList.mjs +2 -0
- package/esm2022/messaging-management/api/model/subscriberToDelete.mjs +2 -0
- package/esm2022/messaging-management/api/model/topic.mjs +2 -0
- package/esm2022/messaging-management/api/model/topicDetailFilters.mjs +2 -0
- package/esm2022/messaging-management/api/model/topicList.mjs +2 -0
- package/esm2022/messaging-management/api/model/topicListFilters.mjs +2 -0
- package/esm2022/messaging-management/api/model/topicType.mjs +9 -0
- package/esm2022/messaging-management/api/services/messaging-namespaces.service.mjs +83 -0
- package/esm2022/messaging-management/api/services/messaging-subscribers.service.mjs +55 -0
- package/esm2022/messaging-management/api/services/messaging-topics.service.mjs +48 -0
- package/esm2022/messaging-management/c8y-ngx-components-messaging-management.mjs +5 -0
- package/esm2022/messaging-management/constants.mjs +4 -0
- package/esm2022/messaging-management/index.mjs +2 -0
- package/esm2022/messaging-management/messaging/namespace-list/namespace-item/namespace-item-card/namespace-item-card.component.mjs +43 -0
- package/esm2022/messaging-management/messaging/namespace-list/namespace-item/namespace-item.component.mjs +36 -0
- package/esm2022/messaging-management/messaging/namespace-list/namespace-list.component.mjs +51 -0
- package/esm2022/messaging-management/messaging/shared/usage/usage.component.mjs +68 -0
- package/esm2022/messaging-management/messaging/topic/topic-list-view.component.mjs +81 -0
- package/esm2022/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-data-grid.service.mjs +220 -0
- package/esm2022/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-view.component.mjs +137 -0
- package/esm2022/messaging-management/messaging/topic/topics-data-grid.service.mjs +113 -0
- package/esm2022/messaging-management/messaging-management.guard.mjs +40 -0
- package/esm2022/messaging-management/messaging-management.module.mjs +72 -0
- package/esm2022/messaging-management/navigator/messaging-navigator-factory.mjs +55 -0
- package/esm2022/messaging-management/navigator/topic-details-tab.factory.mjs +33 -0
- package/esm2022/messaging-management/utils/backlog-quota-limit.pipe.mjs +32 -0
- package/esm2022/messaging-management/utils/namespace-props.mjs +23 -0
- package/esm2022/messaging-management/utils/time-to-live.pipe.mjs +122 -0
- package/esm2022/operations/device-selector/device-selector.component.mjs +5 -1
- package/esm2022/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.mjs +18 -3
- package/fesm2022/c8y-ngx-components-echart.mjs +49 -2
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-messaging-management.mjs +1225 -0
- package/fesm2022/c8y-ngx-components-messaging-management.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-operations-device-selector.mjs +4 -0
- package/fesm2022/c8y-ngx-components-operations-device-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +17 -2
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +49 -22
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +272 -5
- package/locales/es.po +271 -4
- package/locales/fr.po +272 -5
- package/locales/ja_JP.po +272 -5
- package/locales/ko.po +271 -4
- package/locales/locales.pot +240 -0
- package/locales/nl.po +271 -4
- package/locales/pl.po +271 -4
- package/locales/pt_BR.po +272 -5
- package/locales/zh_CN.po +271 -4
- package/locales/zh_TW.po +272 -5
- package/messaging-management/api/model/backlogQuota.d.ts +14 -0
- package/messaging-management/api/model/backlogQuota.d.ts.map +1 -0
- package/messaging-management/api/model/namespace.d.ts +13 -0
- package/messaging-management/api/model/namespace.d.ts.map +1 -0
- package/messaging-management/api/model/namespaceDetails.d.ts +8 -0
- package/messaging-management/api/model/namespaceDetails.d.ts.map +1 -0
- package/messaging-management/api/model/namespaceList.d.ts +5 -0
- package/messaging-management/api/model/namespaceList.d.ts.map +1 -0
- package/messaging-management/api/model/namespacePolicies.d.ts +10 -0
- package/messaging-management/api/model/namespacePolicies.d.ts.map +1 -0
- package/messaging-management/api/model/namespacePublishers.d.ts +4 -0
- package/messaging-management/api/model/namespacePublishers.d.ts.map +1 -0
- package/messaging-management/api/model/namespaceSubscribers.d.ts +4 -0
- package/messaging-management/api/model/namespaceSubscribers.d.ts.map +1 -0
- package/messaging-management/api/model/namespaceTopics.d.ts +5 -0
- package/messaging-management/api/model/namespaceTopics.d.ts.map +1 -0
- package/messaging-management/api/model/pageStatistics.d.ts +12 -0
- package/messaging-management/api/model/pageStatistics.d.ts.map +1 -0
- package/messaging-management/api/model/pageable.d.ts +8 -0
- package/messaging-management/api/model/pageable.d.ts.map +1 -0
- package/messaging-management/api/model/sortable.d.ts +6 -0
- package/messaging-management/api/model/sortable.d.ts.map +1 -0
- package/messaging-management/api/model/subscriber.d.ts +28 -0
- package/messaging-management/api/model/subscriber.d.ts.map +1 -0
- package/messaging-management/api/model/subscriberFilters.d.ts +13 -0
- package/messaging-management/api/model/subscriberFilters.d.ts.map +1 -0
- package/messaging-management/api/model/subscriberList.d.ts +7 -0
- package/messaging-management/api/model/subscriberList.d.ts.map +1 -0
- package/messaging-management/api/model/subscriberToDelete.d.ts +12 -0
- package/messaging-management/api/model/subscriberToDelete.d.ts.map +1 -0
- package/messaging-management/api/model/topic.d.ts +52 -0
- package/messaging-management/api/model/topic.d.ts.map +1 -0
- package/messaging-management/api/model/topicDetailFilters.d.ts +9 -0
- package/messaging-management/api/model/topicDetailFilters.d.ts.map +1 -0
- package/messaging-management/api/model/topicList.d.ts +7 -0
- package/messaging-management/api/model/topicList.d.ts.map +1 -0
- package/messaging-management/api/model/topicListFilters.d.ts +12 -0
- package/messaging-management/api/model/topicListFilters.d.ts.map +1 -0
- package/messaging-management/api/model/topicType.d.ts +8 -0
- package/messaging-management/api/model/topicType.d.ts.map +1 -0
- package/messaging-management/api/services/messaging-namespaces.service.d.ts +52 -0
- package/messaging-management/api/services/messaging-namespaces.service.d.ts.map +1 -0
- package/messaging-management/api/services/messaging-subscribers.service.d.ts +30 -0
- package/messaging-management/api/services/messaging-subscribers.service.d.ts.map +1 -0
- package/messaging-management/api/services/messaging-topics.service.d.ts +21 -0
- package/messaging-management/api/services/messaging-topics.service.d.ts.map +1 -0
- package/messaging-management/c8y-ngx-components-messaging-management.d.ts.map +1 -0
- package/messaging-management/constants.d.ts +4 -0
- package/messaging-management/constants.d.ts.map +1 -0
- package/messaging-management/index.d.ts +2 -0
- package/messaging-management/index.d.ts.map +1 -0
- package/messaging-management/messaging/namespace-list/namespace-item/namespace-item-card/namespace-item-card.component.d.ts +29 -0
- package/messaging-management/messaging/namespace-list/namespace-item/namespace-item-card/namespace-item-card.component.d.ts.map +1 -0
- package/messaging-management/messaging/namespace-list/namespace-item/namespace-item.component.d.ts +15 -0
- package/messaging-management/messaging/namespace-list/namespace-item/namespace-item.component.d.ts.map +1 -0
- package/messaging-management/messaging/namespace-list/namespace-list.component.d.ts +17 -0
- package/messaging-management/messaging/namespace-list/namespace-list.component.d.ts.map +1 -0
- package/messaging-management/messaging/shared/usage/usage.component.d.ts +40 -0
- package/messaging-management/messaging/shared/usage/usage.component.d.ts.map +1 -0
- package/messaging-management/messaging/topic/topic-list-view.component.d.ts +38 -0
- package/messaging-management/messaging/topic/topic-list-view.component.d.ts.map +1 -0
- package/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-data-grid.service.d.ts +21 -0
- package/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-data-grid.service.d.ts.map +1 -0
- package/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-view.component.d.ts +52 -0
- package/messaging-management/messaging/topic/topic-subscribers-view/topic-subscribers-view.component.d.ts.map +1 -0
- package/messaging-management/messaging/topic/topics-data-grid.service.d.ts +13 -0
- package/messaging-management/messaging/topic/topics-data-grid.service.d.ts.map +1 -0
- package/messaging-management/messaging-management.guard.d.ts +12 -0
- package/messaging-management/messaging-management.guard.d.ts.map +1 -0
- package/messaging-management/messaging-management.module.d.ts +7 -0
- package/messaging-management/messaging-management.module.d.ts.map +1 -0
- package/messaging-management/navigator/messaging-navigator-factory.d.ts +18 -0
- package/messaging-management/navigator/messaging-navigator-factory.d.ts.map +1 -0
- package/messaging-management/navigator/topic-details-tab.factory.d.ts +15 -0
- package/messaging-management/navigator/topic-details-tab.factory.d.ts.map +1 -0
- package/messaging-management/utils/backlog-quota-limit.pipe.d.ts +13 -0
- package/messaging-management/utils/backlog-quota-limit.pipe.d.ts.map +1 -0
- package/messaging-management/utils/namespace-props.d.ts +10 -0
- package/messaging-management/utils/namespace-props.d.ts.map +1 -0
- package/messaging-management/utils/time-to-live.pipe.d.ts +16 -0
- package/messaging-management/utils/time-to-live.pipe.d.ts.map +1 -0
- package/operations/device-selector/device-selector.component.d.ts.map +1 -1
- package/package.json +1 -1
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts +2 -0
- package/widgets/implementations/datapoints-graph/datapoints-graph-view/datapoints-graph-widget-view.component.d.ts.map +1 -1
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { inject, Injectable } from '@angular/core';
|
|
2
|
+
import { AlertService, BaseColumn, gettext, ModalService, Status } from '@c8y/ngx-components';
|
|
3
|
+
import { MessagingSubscribersService } from '../../../api/services/messaging-subscribers.service';
|
|
4
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class TopicSubscribersDataGridService {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.subscribersService = inject(MessagingSubscribersService);
|
|
9
|
+
this.alertService = inject(AlertService);
|
|
10
|
+
this.modalService = inject(ModalService);
|
|
11
|
+
this.translateService = inject(TranslateService);
|
|
12
|
+
}
|
|
13
|
+
getColumns() {
|
|
14
|
+
return [
|
|
15
|
+
this.createColumn({
|
|
16
|
+
name: 'name',
|
|
17
|
+
header: gettext('Name'),
|
|
18
|
+
path: 'name',
|
|
19
|
+
filterable: true,
|
|
20
|
+
filteringConfig: {
|
|
21
|
+
fields: [
|
|
22
|
+
{
|
|
23
|
+
key: 'name',
|
|
24
|
+
type: 'input',
|
|
25
|
+
props: {
|
|
26
|
+
label: gettext('Filter subscribers by partial name'),
|
|
27
|
+
placeholder: 'mySubscriber',
|
|
28
|
+
required: true
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
getFilter(model) {
|
|
33
|
+
return model.name;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
this.createColumn({
|
|
38
|
+
name: 'activeClients',
|
|
39
|
+
header: gettext('Connected clients'),
|
|
40
|
+
path: 'activeClients'
|
|
41
|
+
}),
|
|
42
|
+
this.createColumn({
|
|
43
|
+
name: 'messageAckRate',
|
|
44
|
+
header: gettext('Acknowledgment rate (msg/s)'),
|
|
45
|
+
path: 'messageAckRate'
|
|
46
|
+
}),
|
|
47
|
+
this.createColumn({
|
|
48
|
+
name: 'lastAcknowledgeDate',
|
|
49
|
+
header: gettext('Last acknowledged'),
|
|
50
|
+
path: 'lastAcknowledgeDate',
|
|
51
|
+
sortingConfig: {
|
|
52
|
+
pathSortingConfigs: [
|
|
53
|
+
{
|
|
54
|
+
path: 'lastAcknowledgeTimestamp'
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}),
|
|
59
|
+
this.createColumn({
|
|
60
|
+
name: 'unackMsgBacklog',
|
|
61
|
+
header: gettext('Unacknowledged messages'),
|
|
62
|
+
path: 'unackMsgBacklog'
|
|
63
|
+
}),
|
|
64
|
+
this.createColumn({
|
|
65
|
+
name: 'backlogUsagePercentage',
|
|
66
|
+
header: gettext('Used backlog'),
|
|
67
|
+
path: 'backlogUsagePercentage',
|
|
68
|
+
sortOrder: 'desc'
|
|
69
|
+
})
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
async getServerSideData(tenantId, namespaceId, topicId, topicType, dataSourceModifier) {
|
|
73
|
+
const subscriberFilters = this.getSubscriberFilters(tenantId, namespaceId, topicId, topicType, dataSourceModifier);
|
|
74
|
+
const { res, data, paging } = await this.subscribersService.list(subscriberFilters);
|
|
75
|
+
const filteredSize = paging.totalElements;
|
|
76
|
+
const size = (await this.subscribersService.list({
|
|
77
|
+
...subscriberFilters,
|
|
78
|
+
currentPage: 1,
|
|
79
|
+
pageSize: 1
|
|
80
|
+
})).paging.totalPages;
|
|
81
|
+
return {
|
|
82
|
+
res,
|
|
83
|
+
data: data.map(subscriber => ({
|
|
84
|
+
...subscriber,
|
|
85
|
+
lastAcknowledgeDate: this.getLastAcknowledgeDate(subscriber),
|
|
86
|
+
id: subscriber.name
|
|
87
|
+
})),
|
|
88
|
+
paging,
|
|
89
|
+
size,
|
|
90
|
+
filteredSize
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async unsubscribeSubscriber(subscriber, refreshCallback) {
|
|
94
|
+
const confirmationTitle = gettext('Unsubscribe "{{ subscriberName }}"?');
|
|
95
|
+
const confirmationMessage = subscriber.activeClients > 0
|
|
96
|
+
? gettext('You are about to unsubscribe "{{ subscriberName }}" which has active clients. Do you want to proceed?')
|
|
97
|
+
: gettext('You are about to unsubscribe "{{ subscriberName }}". Do you want to proceed?');
|
|
98
|
+
try {
|
|
99
|
+
const subscriberName = subscriber.name;
|
|
100
|
+
await this.modalService.confirm(this.translateService.instant(confirmationTitle, {
|
|
101
|
+
subscriberName
|
|
102
|
+
}), this.translateService.instant(confirmationMessage, {
|
|
103
|
+
subscriberName
|
|
104
|
+
}), Status.DANGER, {
|
|
105
|
+
ok: gettext('Unsubscribe')
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
// cancel
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
await this.subscribersService.delete(subscriber);
|
|
114
|
+
this.alertService.success(this.translateService.instant(gettext('Subscriber "{{ subscriberName }}" unsubscribed.'), {
|
|
115
|
+
subscriberName: subscriber.name
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.alertService.addServerFailure(error);
|
|
120
|
+
}
|
|
121
|
+
refreshCallback();
|
|
122
|
+
}
|
|
123
|
+
async bulkUnsubscribeSubscribers(subscribers, refreshCallback) {
|
|
124
|
+
const anySubscriberHasActiveClients = subscribers.some(subscriber => subscriber.activeClients > 0);
|
|
125
|
+
const confirmationTitle = gettext('Unsubscribe {{ numberOfSubscribers }} subscribers?');
|
|
126
|
+
const confirmationMessage = anySubscriberHasActiveClients
|
|
127
|
+
? gettext('You are about to unsubscribe {{ numberOfSubscribers }} subscribers. Some of them have active clients. Do you want to proceed?')
|
|
128
|
+
: gettext('You are about to unsubscribe {{ numberOfSubscribers }} subscribers. Do you want to proceed?');
|
|
129
|
+
try {
|
|
130
|
+
const numberOfSubscribers = subscribers.length;
|
|
131
|
+
await this.modalService.confirm(this.translateService.instant(confirmationTitle, {
|
|
132
|
+
numberOfSubscribers
|
|
133
|
+
}), this.translateService.instant(confirmationMessage, {
|
|
134
|
+
numberOfSubscribers
|
|
135
|
+
}), Status.DANGER, {
|
|
136
|
+
ok: gettext('Unsubscribe')
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
// cancel
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const results = await Promise.allSettled(subscribers.map(sub => this.subscribersService
|
|
144
|
+
.delete(sub)
|
|
145
|
+
.then(() => ({
|
|
146
|
+
success: true,
|
|
147
|
+
name: sub.name
|
|
148
|
+
}))
|
|
149
|
+
.catch(error => ({
|
|
150
|
+
success: false,
|
|
151
|
+
name: sub.name,
|
|
152
|
+
error
|
|
153
|
+
}))));
|
|
154
|
+
const failed = results
|
|
155
|
+
.filter(result => result.status === 'fulfilled' && result.value.success === false)
|
|
156
|
+
.map(result => result.value);
|
|
157
|
+
const succeeded = results
|
|
158
|
+
.filter(result => result.status === 'fulfilled' && result.value.success === true)
|
|
159
|
+
.map(result => result.value);
|
|
160
|
+
if (failed.length === 0) {
|
|
161
|
+
this.alertService.success(this.translateService.instant(gettext('{{ numberOfSubscribers }} subscribers unsubscribed.'), { numberOfSubscribers: succeeded.length }));
|
|
162
|
+
}
|
|
163
|
+
else if (succeeded.length === 0) {
|
|
164
|
+
const errorMessage = this.translateService.instant(gettext('Failed to unsubscribe {{ numberOfSubscribers }} subscribers.'), {
|
|
165
|
+
numberOfSubscribers: failed.length
|
|
166
|
+
});
|
|
167
|
+
const details = `${failed.map(f => `'${f.name}': ${f.error.data.message}`).join('\n')}`;
|
|
168
|
+
this.alertService.danger(errorMessage, details);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Some succeeded, some failed
|
|
172
|
+
const nonUnsubscribedSubscribers = failed.map(s => s.name).join(', ');
|
|
173
|
+
const message = this.translateService.instant(gettext(`Successfully unsubscribed {{ count }} subscribers.<br/>Failed to unsubscribe: {{ nonUnsubscribedSubscribers }}.`), { count: succeeded.length, nonUnsubscribedSubscribers });
|
|
174
|
+
const details = `${failed.map(f => `'${f.name}': ${f.error.data.message}`).join('\n')}`;
|
|
175
|
+
this.alertService.warning(message, details);
|
|
176
|
+
}
|
|
177
|
+
refreshCallback();
|
|
178
|
+
}
|
|
179
|
+
createColumn(columnProps) {
|
|
180
|
+
const column = new BaseColumn();
|
|
181
|
+
Object.assign(column, columnProps);
|
|
182
|
+
return column;
|
|
183
|
+
}
|
|
184
|
+
getSubscriberFilters(tenantId, namespaceId, topicId, topicType, dataSourceModifier) {
|
|
185
|
+
const subscriberFilters = {
|
|
186
|
+
tenant: tenantId,
|
|
187
|
+
namespace: namespaceId,
|
|
188
|
+
topic: topicId,
|
|
189
|
+
type: topicType,
|
|
190
|
+
currentPage: dataSourceModifier.pagination.currentPage,
|
|
191
|
+
pageSize: dataSourceModifier.pagination.pageSize
|
|
192
|
+
};
|
|
193
|
+
return dataSourceModifier.columns.reduce((subscriberFilters, column) => {
|
|
194
|
+
if (column.filterable) {
|
|
195
|
+
if (column.filterPredicate) {
|
|
196
|
+
subscriberFilters[column.path] = column.filterPredicate;
|
|
197
|
+
}
|
|
198
|
+
if (column.externalFilterQuery) {
|
|
199
|
+
subscriberFilters[column.path] = column.filteringConfig.getFilter(column.externalFilterQuery);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (column.sortable && column.sortOrder) {
|
|
203
|
+
const sortPath = column.sortingConfig?.pathSortingConfigs?.[0]?.path || column.path;
|
|
204
|
+
subscriberFilters.sort = `${sortPath},${column.sortOrder}`;
|
|
205
|
+
}
|
|
206
|
+
return subscriberFilters;
|
|
207
|
+
}, subscriberFilters);
|
|
208
|
+
}
|
|
209
|
+
getLastAcknowledgeDate(subscriber) {
|
|
210
|
+
const lastAcknowledgeDate = new Date(subscriber.lastAcknowledgeTimestamp);
|
|
211
|
+
return lastAcknowledgeDate.getTime() > 0 ? lastAcknowledgeDate : null;
|
|
212
|
+
}
|
|
213
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TopicSubscribersDataGridService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
214
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TopicSubscribersDataGridService, providedIn: 'root' }); }
|
|
215
|
+
}
|
|
216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TopicSubscribersDataGridService, decorators: [{
|
|
217
|
+
type: Injectable,
|
|
218
|
+
args: [{ providedIn: 'root' }]
|
|
219
|
+
}] });
|
|
220
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9waWMtc3Vic2NyaWJlcnMtZGF0YS1ncmlkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9tZXNzYWdpbmctbWFuYWdlbWVudC9tZXNzYWdpbmcvdG9waWMvdG9waWMtc3Vic2NyaWJlcnMtdmlldy90b3BpYy1zdWJzY3JpYmVycy1kYXRhLWdyaWQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsWUFBWSxFQUNaLFVBQVUsRUFHVixPQUFPLEVBQ1AsWUFBWSxFQUVaLE1BQU0sRUFDUCxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBSWxHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQUl2RCxNQUFNLE9BQU8sK0JBQStCO0lBRDVDO1FBRVksdUJBQWtCLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDM0QsaUJBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEMsaUJBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEMscUJBQWdCLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7S0EwUnJEO0lBeFJDLFVBQVU7UUFDUixPQUFPO1lBQ0wsSUFBSSxDQUFDLFlBQVksQ0FBQztnQkFDaEIsSUFBSSxFQUFFLE1BQU07Z0JBQ1osTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUM7Z0JBQ3ZCLElBQUksRUFBRSxNQUFNO2dCQUNaLFVBQVUsRUFBRSxJQUFJO2dCQUNoQixlQUFlLEVBQUU7b0JBQ2YsTUFBTSxFQUFFO3dCQUNOOzRCQUNFLEdBQUcsRUFBRSxNQUFNOzRCQUNYLElBQUksRUFBRSxPQUFPOzRCQUNiLEtB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QyxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVPLHNCQUFzQixDQUFDLFVBQStCO1FBQzVELE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDMUUsT0FBTyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDeEUsQ0FBQzsrR0E3UlUsK0JBQStCO21IQUEvQiwrQkFBK0IsY0FEbEIsTUFBTTs7NEZBQ25CLCtCQUErQjtrQkFEM0MsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFsZXJ0U2VydmljZSxcbiAgQmFzZUNvbHVtbixcbiAgQ29sdW1uLFxuICBEYXRhU291cmNlTW9kaWZpZXIsXG4gIGdldHRleHQsXG4gIE1vZGFsU2VydmljZSxcbiAgU2VydmVyU2lkZURhdGFSZXN1bHQsXG4gIFN0YXR1c1xufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IE1lc3NhZ2luZ1N1YnNjcmliZXJzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2FwaS9zZXJ2aWNlcy9tZXNzYWdpbmctc3Vic2NyaWJlcnMuc2VydmljZSc7XG5pbXBvcnQgeyBNZXNzYWdpbmdUb3BpY1R5cGUgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvdG9waWNUeXBlJztcbmltcG9ydCB7IE1lc3NhZ2luZ1N1YnNjcmliZXJGaWx0ZXJzIH0gZnJvbSAnLi4vLi4vLi4vYXBpL21vZGVsL3N1YnNjcmliZXJGaWx0ZXJzJztcbmltcG9ydCB7IE1lc3NhZ2luZ1N1YnNjcmliZXIgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvc3Vic2NyaWJlcic7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBNZXNzYWdpbmdTdWJzY3JpYmVyVG9EZWxldGUgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvc3Vic2NyaWJlclRvRGVsZXRlJztcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBUb3BpY1N1YnNjcmliZXJzRGF0YUdyaWRTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIHN1YnNjcmliZXJzU2VydmljZSA9IGluamVjdChNZXNzYWdpbmdTdWJzY3JpYmVyc1NlcnZpY2UpO1xuICBwcml2YXRlIGFsZXJ0U2VydmljZSA9IGluamVjdChBbGVydFNlcnZpY2UpO1xuICBwcml2YXRlIG1vZGFsU2VydmljZSA9IGluamVjdChNb2RhbFNlcnZpY2UpO1xuICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2UgPSBpbmplY3QoVHJhbnNsYXRlU2VydmljZSk7XG5cbiAgZ2V0Q29sdW1ucygpOiBDb2x1bW5bXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlQ29sdW1uKHtcbiAgICAgICAgbmFtZTogJ25hbWUnLFxuICAgICAgICBoZWFkZXI6IGdldHRleHQoJ05hbWUnKSxcbiAgICAgICAgcGF0aDogJ25hbWUnLFxuICAgICAgICBmaWx0ZXJhYmxlOiB0cnVlLFxuICAgICAgICBmaWx0ZXJpbmdDb25maWc6IHtcbiAgICAgICAgICBmaWVsZHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAga2V5OiAnbmFtZScsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbnB1dCcsXG4gICAgICAgICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IGdldHRleHQoJ0ZpbHRlciBzdWJzY3JpYmVycyBieSBwYXJ0aWFsIG5hbWUnKSxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogJ215U3Vic2NyaWJlcicsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIF0sXG4gICAgICAgICAgZ2V0RmlsdGVyKG1vZGVsOiB7IG5hbWU6IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgICAgICAgICAgIHJldHVybiBtb2RlbC5uYW1lO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICB0aGlzLmNyZWF0ZUNvbHVtbih7XG4gICAgICAgIG5hbWU6ICdhY3RpdmVDbGllbnRzJyxcbiAgICAgICAgaGVhZGVyOiBnZXR0ZXh0KCdDb25uZWN0ZWQgY2xpZW50cycpLFxuICAgICAgICBwYXRoOiAnYWN0aXZlQ2xpZW50cydcbiAgICAgIH0pLFxuICAgICAgdGhpcy5jcmVhdGVDb2x1bW4oe1xuICAgICAgICBuYW1lOiAnbWVzc2FnZUFja1JhdGUnLFxuICAgICAgICBoZWFkZXI6IGdldHRleHQoJ0Fja25vd2xlZGdtZW50IHJhdGUgKG1zZy9zKScpLFxuICAgICAgICBwYXRoOiAnbWVzc2FnZUFja1JhdGUnXG4gICAgICB9KSxcbiAgICAgIHRoaXMuY3JlYXRlQ29sdW1uKHtcbiAgICAgICAgbmFtZTogJ2xhc3RBY2tub3dsZWRnZURhdGUnLFxuICAgICAgICBoZWFkZXI6IGdldHRleHQoJ0xhc3QgYWNrbm93bGVkZ2VkJyksXG4gICAgICAgIHBhdGg6ICdsYXN0QWNrbm93bGVkZ2VEYXRlJyxcbiAgICAgICAgc29ydGluZ0NvbmZpZzoge1xuICAgICAgICAgIHBhdGhTb3J0aW5nQ29uZmlnczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBwYXRoOiAnbGFzdEFja25vd2xlZGdlVGltZXN0YW1wJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICB0aGlzLmNyZWF0ZUNvbHVtbih7XG4gICAgICAgIG5hbWU6ICd1bmFja01zZ0JhY2tsb2cnLFxuICAgICAgICBoZWFkZXI6IGdldHRleHQoJ1VuYWNrbm93bGVkZ2VkIG1lc3NhZ2VzJyksXG4gICAgICAgIHBhdGg6ICd1bmFja01zZ0JhY2tsb2cnXG4gICAgICB9KSxcbiAgICAgIHRoaXMuY3JlYXRlQ29sdW1uKHtcbiAgICAgICAgbmFtZTogJ2JhY2tsb2dVc2FnZVBlcmNlbnRhZ2UnLFxuICAgICAgICBoZWFkZXI6IGdldHRleHQoJ1VzZWQgYmFja2xvZycpLFxuICAgICAgICBwYXRoOiAnYmFja2xvZ1VzYWdlUGVyY2VudGFnZScsXG4gICAgICAgIHNvcnRPcmRlcjogJ2Rlc2MnXG4gICAgICB9KVxuICAgIF07XG4gIH1cblxuICBhc3luYyBnZXRTZXJ2ZXJTaWRlRGF0YShcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG5hbWVzcGFjZUlkOiBzdHJpbmcsXG4gICAgdG9waWNJZDogc3RyaW5nLFxuICAgIHRvcGljVHlwZTogTWVzc2FnaW5nVG9waWNUeXBlLFxuICAgIGRhdGFTb3VyY2VNb2RpZmllcjogRGF0YVNvdXJjZU1vZGlmaWVyXG4gICk6IFByb21pc2U8U2VydmVyU2lkZURhdGFSZXN1bHQ+IHtcbiAgICBjb25zdCBzdWJzY3JpYmVyRmlsdGVycyA9IHRoaXMuZ2V0U3Vic2NyaWJlckZpbHRlcnMoXG4gICAgICB0ZW5hbnRJZCxcbiAgICAgIG5hbWVzcGFjZUlkLFxuICAgICAgdG9waWNJZCxcbiAgICAgIHRvcGljVHlwZSxcbiAgICAgIGRhdGFTb3VyY2VNb2RpZmllclxuICAgICk7XG4gICAgY29uc3QgeyByZXMsIGRhdGEsIHBhZ2luZyB9ID0gYXdhaXQgdGhpcy5zdWJzY3JpYmVyc1NlcnZpY2UubGlzdChzdWJzY3JpYmVyRmlsdGVycyk7XG4gICAgY29uc3QgZmlsdGVyZWRTaXplID0gcGFnaW5nLnRvdGFsRWxlbWVudHM7XG4gICAgY29uc3Qgc2l6ZSA9IChcbiAgICAgIGF3YWl0IHRoaXMuc3Vic2NyaWJlcnNTZXJ2aWNlLmxpc3Qoe1xuICAgICAgICAuLi5zdWJzY3JpYmVyRmlsdGVycyxcbiAgICAgICAgY3VycmVudFBhZ2U6IDEsXG4gICAgICAgIHBhZ2VTaXplOiAxXG4gICAgICB9KVxuICAgICkucGFnaW5nLnRvdGFsUGFnZXM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVzLFxuICAgICAgZGF0YTogZGF0YS5tYXAoc3Vic2NyaWJlciA9PiAoe1xuICAgICAgICAuLi5zdWJzY3JpYmVyLFxuICAgICAgICBsYXN0QWNrbm93bGVkZ2VEYXRlOiB0aGlzLmdldExhc3RBY2tub3dsZWRnZURhdGUoc3Vic2NyaWJlciksXG4gICAgICAgIGlkOiBzdWJzY3JpYmVyLm5hbWVcbiAgICAgIH0pKSxcbiAgICAgIHBhZ2luZyxcbiAgICAgIHNpemUsXG4gICAgICBmaWx0ZXJlZFNpemVcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgdW5zdWJzY3JpYmVTdWJzY3JpYmVyKFxuICAgIHN1YnNjcmliZXI6IE1lc3NhZ2luZ1N1YnNjcmliZXJUb0RlbGV0ZSxcbiAgICByZWZyZXNoQ2FsbGJhY2s6ICgpID0+IHZvaWRcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29uZmlybWF0aW9uVGl0bGUgPSBnZXR0ZXh0KCdVbnN1YnNjcmliZSBcInt7IHN1YnNjcmliZXJOYW1lIH19XCI/Jyk7XG4gICAgY29uc3QgY29uZmlybWF0aW9uTWVzc2FnZSA9XG4gICAgICBzdWJzY3JpYmVyLmFjdGl2ZUNsaWVudHMgPiAwXG4gICAgICAgID8gZ2V0dGV4dChcbiAgICAgICAgICAgICdZb3UgYXJlIGFib3V0IHRvIHVuc3Vic2NyaWJlIFwie3sgc3Vic2NyaWJlck5hbWUgfX1cIiB3aGljaCBoYXMgYWN0aXZlIGNsaWVudHMuIERvIHlvdSB3YW50IHRvIHByb2NlZWQ/J1xuICAgICAgICAgIClcbiAgICAgICAgOiBnZXR0ZXh0KCdZb3UgYXJlIGFib3V0IHRvIHVuc3Vic2NyaWJlIFwie3sgc3Vic2NyaWJlck5hbWUgfX1cIi4gRG8geW91IHdhbnQgdG8gcHJvY2VlZD8nKTtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Vic2NyaWJlck5hbWUgPSBzdWJzY3JpYmVyLm5hbWU7XG4gICAgICBhd2FpdCB0aGlzLm1vZGFsU2VydmljZS5jb25maXJtKFxuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChjb25maXJtYXRpb25UaXRsZSwge1xuICAgICAgICAgIHN1YnNjcmliZXJOYW1lXG4gICAgICAgIH0pLFxuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChjb25maXJtYXRpb25NZXNzYWdlLCB7XG4gICAgICAgICAgc3Vic2NyaWJlck5hbWVcbiAgICAgICAgfSksXG4gICAgICAgIFN0YXR1cy5EQU5HRVIsXG4gICAgICAgIHtcbiAgICAgICAgICBvazogZ2V0dGV4dCgnVW5zdWJzY3JpYmUnKVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGNhbmNlbFxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnN1YnNjcmliZXJzU2VydmljZS5kZWxldGUoc3Vic2NyaWJlcik7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5zdWNjZXNzKFxuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChnZXR0ZXh0KCdTdWJzY3JpYmVyIFwie3sgc3Vic2NyaWJlck5hbWUgfX1cIiB1bnN1YnNjcmliZWQuJyksIHtcbiAgICAgICAgICBzdWJzY3JpYmVyTmFtZTogc3Vic2NyaWJlci5uYW1lXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG4gICAgcmVmcmVzaENhbGxiYWNrKCk7XG4gIH1cblxuICBhc3luYyBidWxrVW5zdWJzY3JpYmVTdWJzY3JpYmVycyhcbiAgICBzdWJzY3JpYmVyczogTWVzc2FnaW5nU3Vic2NyaWJlclRvRGVsZXRlW10sXG4gICAgcmVmcmVzaENhbGxiYWNrOiAoKSA9PiB2b2lkXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFueVN1YnNjcmliZXJIYXNBY3RpdmVDbGllbnRzID0gc3Vic2NyaWJlcnMuc29tZShcbiAgICAgIHN1YnNjcmliZXIgPT4gc3Vic2NyaWJlci5hY3RpdmVDbGllbnRzID4gMFxuICAgICk7XG5cbiAgICBjb25zdCBjb25maXJtYXRpb25UaXRsZSA9IGdldHRleHQoJ1Vuc3Vic2NyaWJlIHt7IG51bWJlck9mU3Vic2NyaWJlcnMgfX0gc3Vic2NyaWJlcnM/Jyk7XG4gICAgY29uc3QgY29uZmlybWF0aW9uTWVzc2FnZSA9IGFueVN1YnNjcmliZXJIYXNBY3RpdmVDbGllbnRzXG4gICAgICA/IGdldHRleHQoXG4gICAgICAgICAgJ1lvdSBhcmUgYWJvdXQgdG8gdW5zdWJzY3JpYmUge3sgbnVtYmVyT2ZTdWJzY3JpYmVycyB9fSBzdWJzY3JpYmVycy4gU29tZSBvZiB0aGVtIGhhdmUgYWN0aXZlIGNsaWVudHMuIERvIHlvdSB3YW50IHRvIHByb2NlZWQ/J1xuICAgICAgICApXG4gICAgICA6IGdldHRleHQoXG4gICAgICAgICAgJ1lvdSBhcmUgYWJvdXQgdG8gdW5zdWJzY3JpYmUge3sgbnVtYmVyT2ZTdWJzY3JpYmVycyB9fSBzdWJzY3JpYmVycy4gRG8geW91IHdhbnQgdG8gcHJvY2VlZD8nXG4gICAgICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbnVtYmVyT2ZTdWJzY3JpYmVycyA9IHN1YnNjcmliZXJzLmxlbmd0aDtcbiAgICAgIGF3YWl0IHRoaXMubW9kYWxTZXJ2aWNlLmNvbmZpcm0oXG4gICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGNvbmZpcm1hdGlvblRpdGxlLCB7XG4gICAgICAgICAgbnVtYmVyT2ZTdWJzY3JpYmVyc1xuICAgICAgICB9KSxcbiAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoY29uZmlybWF0aW9uTWVzc2FnZSwge1xuICAgICAgICAgIG51bWJlck9mU3Vic2NyaWJlcnNcbiAgICAgICAgfSksXG4gICAgICAgIFN0YXR1cy5EQU5HRVIsXG4gICAgICAgIHtcbiAgICAgICAgICBvazogZ2V0dGV4dCgnVW5zdWJzY3JpYmUnKVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGNhbmNlbFxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICBzdWJzY3JpYmVycy5tYXAoc3ViID0+XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnNTZXJ2aWNlXG4gICAgICAgICAgLmRlbGV0ZShzdWIpXG4gICAgICAgICAgLnRoZW4oKCkgPT4gKHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBuYW1lOiBzdWIubmFtZVxuICAgICAgICAgIH0pKVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiAoe1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBuYW1lOiBzdWIubmFtZSxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgfSkpXG4gICAgICApXG4gICAgKTtcblxuICAgIGNvbnN0IGZhaWxlZCA9IHJlc3VsdHNcbiAgICAgIC5maWx0ZXIocmVzdWx0ID0+IHJlc3VsdC5zdGF0dXMgPT09ICdmdWxmaWxsZWQnICYmIHJlc3VsdC52YWx1ZS5zdWNjZXNzID09PSBmYWxzZSlcbiAgICAgIC5tYXAocmVzdWx0ID0+IChyZXN1bHQgYXMgUHJvbWlzZUZ1bGZpbGxlZFJlc3VsdDxhbnk+KS52YWx1ZSk7XG5cbiAgICBjb25zdCBzdWNjZWVkZWQgPSByZXN1bHRzXG4gICAgICAuZmlsdGVyKHJlc3VsdCA9PiByZXN1bHQuc3RhdHVzID09PSAnZnVsZmlsbGVkJyAmJiByZXN1bHQudmFsdWUuc3VjY2VzcyA9PT0gdHJ1ZSlcbiAgICAgIC5tYXAocmVzdWx0ID0+IChyZXN1bHQgYXMgUHJvbWlzZUZ1bGZpbGxlZFJlc3VsdDxhbnk+KS52YWx1ZSk7XG5cbiAgICBpZiAoZmFpbGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2Uuc3VjY2VzcyhcbiAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICAgICAgZ2V0dGV4dCgne3sgbnVtYmVyT2ZTdWJzY3JpYmVycyB9fSBzdWJzY3JpYmVycyB1bnN1YnNjcmliZWQuJyksXG4gICAgICAgICAgeyBudW1iZXJPZlN1YnNjcmliZXJzOiBzdWNjZWVkZWQubGVuZ3RoIH1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHN1Y2NlZWRlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICBnZXR0ZXh0KCdGYWlsZWQgdG8gdW5zdWJzY3JpYmUge3sgbnVtYmVyT2ZTdWJzY3JpYmVycyB9fSBzdWJzY3JpYmVycy4nKSxcbiAgICAgICAge1xuICAgICAgICAgIG51bWJlck9mU3Vic2NyaWJlcnM6IGZhaWxlZC5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSBgJHtmYWlsZWQubWFwKGYgPT4gYCcke2YubmFtZX0nOiAke2YuZXJyb3IuZGF0YS5tZXNzYWdlfWApLmpvaW4oJ1xcbicpfWA7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5kYW5nZXIoZXJyb3JNZXNzYWdlLCBkZXRhaWxzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU29tZSBzdWNjZWVkZWQsIHNvbWUgZmFpbGVkXG4gICAgICBjb25zdCBub25VbnN1YnNjcmliZWRTdWJzY3JpYmVycyA9IGZhaWxlZC5tYXAocyA9PiBzLm5hbWUpLmpvaW4oJywgJyk7XG4gICAgICBjb25zdCBtZXNzYWdlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICAgIGdldHRleHQoXG4gICAgICAgICAgYFN1Y2Nlc3NmdWxseSB1bnN1YnNjcmliZWQge3sgY291bnQgfX0gc3Vic2NyaWJlcnMuPGJyLz5GYWlsZWQgdG8gdW5zdWJzY3JpYmU6IHt7IG5vblVuc3Vic2NyaWJlZFN1YnNjcmliZXJzIH19LmBcbiAgICAgICAgKSxcbiAgICAgICAgeyBjb3VudDogc3VjY2VlZGVkLmxlbmd0aCwgbm9uVW5zdWJzY3JpYmVkU3Vic2NyaWJlcnMgfVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSBgJHtmYWlsZWQubWFwKGYgPT4gYCcke2YubmFtZX0nOiAke2YuZXJyb3IuZGF0YS5tZXNzYWdlfWApLmpvaW4oJ1xcbicpfWA7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS53YXJuaW5nKG1lc3NhZ2UsIGRldGFpbHMpO1xuICAgIH1cblxuICAgIHJlZnJlc2hDYWxsYmFjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDb2x1bW4oY29sdW1uUHJvcHM6IFBhcnRpYWw8QmFzZUNvbHVtbj4pOiBCYXNlQ29sdW1uIHtcbiAgICBjb25zdCBjb2x1bW4gPSBuZXcgQmFzZUNvbHVtbigpO1xuICAgIE9iamVjdC5hc3NpZ24oY29sdW1uLCBjb2x1bW5Qcm9wcyk7XG4gICAgcmV0dXJuIGNvbHVtbjtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3Vic2NyaWJlckZpbHRlcnMoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBuYW1lc3BhY2VJZDogc3RyaW5nLFxuICAgIHRvcGljSWQ6IHN0cmluZyxcbiAgICB0b3BpY1R5cGU6IE1lc3NhZ2luZ1RvcGljVHlwZSxcbiAgICBkYXRhU291cmNlTW9kaWZpZXI6IERhdGFTb3VyY2VNb2RpZmllclxuICApOiBNZXNzYWdpbmdTdWJzY3JpYmVyRmlsdGVycyB7XG4gICAgY29uc3Qgc3Vic2NyaWJlckZpbHRlcnM6IE1lc3NhZ2luZ1N1YnNjcmliZXJGaWx0ZXJzID0ge1xuICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgIG5hbWVzcGFjZTogbmFtZXNwYWNlSWQsXG4gICAgICB0b3BpYzogdG9waWNJZCxcbiAgICAgIHR5cGU6IHRvcGljVHlwZSxcbiAgICAgIGN1cnJlbnRQYWdlOiBkYXRhU291cmNlTW9kaWZpZXIucGFnaW5hdGlvbi5jdXJyZW50UGFnZSxcbiAgICAgIHBhZ2VTaXplOiBkYXRhU291cmNlTW9kaWZpZXIucGFnaW5hdGlvbi5wYWdlU2l6ZVxuICAgIH07XG5cbiAgICByZXR1cm4gZGF0YVNvdXJjZU1vZGlmaWVyLmNvbHVtbnMucmVkdWNlKChzdWJzY3JpYmVyRmlsdGVycywgY29sdW1uKSA9PiB7XG4gICAgICBpZiAoY29sdW1uLmZpbHRlcmFibGUpIHtcbiAgICAgICAgaWYgKGNvbHVtbi5maWx0ZXJQcmVkaWNhdGUpIHtcbiAgICAgICAgICBzdWJzY3JpYmVyRmlsdGVyc1tjb2x1bW4ucGF0aF0gPSBjb2x1bW4uZmlsdGVyUHJlZGljYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbHVtbi5leHRlcm5hbEZpbHRlclF1ZXJ5KSB7XG4gICAgICAgICAgc3Vic2NyaWJlckZpbHRlcnNbY29sdW1uLnBhdGhdID0gY29sdW1uLmZpbHRlcmluZ0NvbmZpZy5nZXRGaWx0ZXIoXG4gICAgICAgICAgICBjb2x1bW4uZXh0ZXJuYWxGaWx0ZXJRdWVyeVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbHVtbi5zb3J0YWJsZSAmJiBjb2x1bW4uc29ydE9yZGVyKSB7XG4gICAgICAgIGNvbnN0IHNvcnRQYXRoID0gY29sdW1uLnNvcnRpbmdDb25maWc/LnBhdGhTb3J0aW5nQ29uZmlncz8uWzBdPy5wYXRoIHx8IGNvbHVtbi5wYXRoO1xuICAgICAgICBzdWJzY3JpYmVyRmlsdGVycy5zb3J0ID0gYCR7c29ydFBhdGh9LCR7Y29sdW1uLnNvcnRPcmRlcn1gO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3Vic2NyaWJlckZpbHRlcnM7XG4gICAgfSwgc3Vic2NyaWJlckZpbHRlcnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMYXN0QWNrbm93bGVkZ2VEYXRlKHN1YnNjcmliZXI6IE1lc3NhZ2luZ1N1YnNjcmliZXIpOiBEYXRlIHtcbiAgICBjb25zdCBsYXN0QWNrbm93bGVkZ2VEYXRlID0gbmV3IERhdGUoc3Vic2NyaWJlci5sYXN0QWNrbm93bGVkZ2VUaW1lc3RhbXApO1xuICAgIHJldHVybiBsYXN0QWNrbm93bGVkZ2VEYXRlLmdldFRpbWUoKSA+IDAgPyBsYXN0QWNrbm93bGVkZ2VEYXRlIDogbnVsbDtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Component, DestroyRef, EventEmitter, inject, ViewChild } from '@angular/core';
|
|
2
|
+
import { ActionBarItemComponent, AppStateService, BreadcrumbModule, BytesPipe, C8yTranslateDirective, C8yTranslatePipe, DataGridComponent, DataGridModule, EmptyStateComponent, EmptyStateContextDirective, gettext, HeaderModule, IconDirective, LoadingComponent, Permissions, RelativeTimePipe } from '@c8y/ngx-components';
|
|
3
|
+
import { ActivatedRoute } from '@angular/router';
|
|
4
|
+
import { CommonModule, DecimalPipe } from '@angular/common';
|
|
5
|
+
import { MessagingTopicType } from '../../../api/model/topicType';
|
|
6
|
+
import { MessagingTopicsService } from '../../../api/services/messaging-topics.service';
|
|
7
|
+
import { MessagingNamespacesService } from '../../../api/services/messaging-namespaces.service';
|
|
8
|
+
import { NAMESPACE_PROPS } from '../../../utils/namespace-props';
|
|
9
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
10
|
+
import { TopicSubscribersDataGridService } from './topic-subscribers-data-grid.service';
|
|
11
|
+
import { BehaviorSubject, combineLatest, firstValueFrom } from 'rxjs';
|
|
12
|
+
import { map, shareReplay, switchMap, tap } from 'rxjs/operators';
|
|
13
|
+
import { UsageComponent } from '../../shared/usage/usage.component';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "@c8y/ngx-components";
|
|
16
|
+
import * as i2 from "@angular/common";
|
|
17
|
+
export class TopicSubscribersViewComponent {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.route = inject(ActivatedRoute);
|
|
20
|
+
this.appState = inject(AppStateService);
|
|
21
|
+
this.namespacesService = inject(MessagingNamespacesService);
|
|
22
|
+
this.topicsService = inject(MessagingTopicsService);
|
|
23
|
+
this.topicSubscribersDataGridService = inject(TopicSubscribersDataGridService);
|
|
24
|
+
this.translateService = inject(TranslateService);
|
|
25
|
+
this.permissions = inject(Permissions);
|
|
26
|
+
this.destroyRef = inject(DestroyRef);
|
|
27
|
+
this.loading$ = new BehaviorSubject(false);
|
|
28
|
+
this.refresh = new EventEmitter();
|
|
29
|
+
this.tenantId$ = this.appState.currentTenant.pipe(map(tenant => tenant.name));
|
|
30
|
+
this.namespaceId$ = this.route.params.pipe(map(params => params['namespace']));
|
|
31
|
+
this.namespaceLabel$ = this.namespaceId$.pipe(map(namespaceId => this.translateService.instant(NAMESPACE_PROPS[namespaceId].label)));
|
|
32
|
+
this.topicId$ = this.route.params.pipe(map(params => params['topic']));
|
|
33
|
+
this.overview$ = combineLatest([this.tenantId$, this.namespaceId$, this.topicId$, this.refresh]).pipe(tap(() => this.loading$.next(true)), switchMap(async ([tenantId, namespaceId, topicId]) => ({
|
|
34
|
+
topic: (await this.topicsService.detail({
|
|
35
|
+
tenant: tenantId,
|
|
36
|
+
namespace: namespaceId,
|
|
37
|
+
topic: topicId,
|
|
38
|
+
type: MessagingTopicType.Persistent
|
|
39
|
+
})).data,
|
|
40
|
+
policies: await this.namespacesService.getNamespacePolicies(tenantId, namespaceId)
|
|
41
|
+
})), tap(() => this.loading$.next(false)), shareReplay(1));
|
|
42
|
+
this.topicName$ = this.overview$.pipe(map(overview => overview.topic.name));
|
|
43
|
+
this.tableTitle = gettext('Subscribers');
|
|
44
|
+
this.loadingItemsLabel = gettext('Loading subscribers...');
|
|
45
|
+
this.loadMoreItemsLabel = gettext('Load more subscribers');
|
|
46
|
+
this.noResultsMessage = gettext('No matching subscribers found.');
|
|
47
|
+
this.noResultsSubtitle = gettext('Refine your search terms or check your spelling.');
|
|
48
|
+
this.noDataMessage = gettext('No subscribers to display.');
|
|
49
|
+
this.noDataSubtitle = gettext('Create new subscribers to monitor them here.');
|
|
50
|
+
this.columns = this.topicSubscribersDataGridService.getColumns();
|
|
51
|
+
this.pagination = {
|
|
52
|
+
pageSize: 20,
|
|
53
|
+
currentPage: 1
|
|
54
|
+
};
|
|
55
|
+
this.selectable = true;
|
|
56
|
+
this.actionControls = [
|
|
57
|
+
{
|
|
58
|
+
type: 'unsubscribeSubscriber',
|
|
59
|
+
icon: 'unsubscribe',
|
|
60
|
+
text: gettext('Unsubscribe'),
|
|
61
|
+
callback: (subscriber) => this.unsubscribeSubscriber(subscriber),
|
|
62
|
+
showIf: () => this.permissions.hasRole(Permissions.ROLE_TENANT_MANAGEMENT_ADMIN)
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
this.bulkActionControls = [
|
|
66
|
+
{
|
|
67
|
+
type: 'unsubscribeSubscriber',
|
|
68
|
+
icon: 'unsubscribe',
|
|
69
|
+
text: gettext('Unsubscribe'),
|
|
70
|
+
callback: (subscribersNames) => this.bulkUnsubscribeSubscribers(subscribersNames),
|
|
71
|
+
showIf: () => this.permissions.hasRole(Permissions.ROLE_TENANT_MANAGEMENT_ADMIN)
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
this.serverSideDataCallback = this.onDataSourceModifier.bind(this);
|
|
75
|
+
}
|
|
76
|
+
async onDataSourceModifier(dataSourceModifier) {
|
|
77
|
+
return firstValueFrom(combineLatest([this.tenantId$, this.namespaceId$, this.topicId$]).pipe(switchMap(([tenantId, namespaceId, topicId]) => this.topicSubscribersDataGridService.getServerSideData(tenantId, namespaceId, topicId, MessagingTopicType.Persistent, dataSourceModifier))));
|
|
78
|
+
}
|
|
79
|
+
ngAfterViewInit() {
|
|
80
|
+
this.refresh.emit();
|
|
81
|
+
}
|
|
82
|
+
async unsubscribeSubscriber(subscriber) {
|
|
83
|
+
const tenant = await firstValueFrom(this.tenantId$);
|
|
84
|
+
const namespace = await firstValueFrom(this.namespaceId$);
|
|
85
|
+
const topic = await firstValueFrom(this.topicId$);
|
|
86
|
+
this.topicSubscribersDataGridService.unsubscribeSubscriber({
|
|
87
|
+
...subscriber,
|
|
88
|
+
tenant,
|
|
89
|
+
namespace,
|
|
90
|
+
topic,
|
|
91
|
+
type: MessagingTopicType.Persistent
|
|
92
|
+
}, () => this.refresh.emit());
|
|
93
|
+
}
|
|
94
|
+
async bulkUnsubscribeSubscribers(subscribersNames) {
|
|
95
|
+
const tenant = await firstValueFrom(this.tenantId$);
|
|
96
|
+
const namespace = await firstValueFrom(this.namespaceId$);
|
|
97
|
+
const topic = await firstValueFrom(this.topicId$);
|
|
98
|
+
const allSubscribers = await firstValueFrom(this.dataGrid.dataSource.data$);
|
|
99
|
+
const subscribers = subscribersNames.map(subscriberName => {
|
|
100
|
+
const subscriber = allSubscribers.find(subscriber => subscriber.name === subscriberName);
|
|
101
|
+
return {
|
|
102
|
+
...subscriber,
|
|
103
|
+
tenant,
|
|
104
|
+
namespace,
|
|
105
|
+
topic,
|
|
106
|
+
type: MessagingTopicType.Persistent
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
this.topicSubscribersDataGridService.bulkUnsubscribeSubscribers(subscribers, () => this.refresh.emit());
|
|
110
|
+
}
|
|
111
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TopicSubscribersViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
112
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TopicSubscribersViewComponent, isStandalone: true, selector: "app-topic-subscribers-view", viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true, static: true }], ngImport: i0, template: "<c8y-title>{{ topicName$ | async }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'monitoring'\"\n [label]=\"'Monitoring' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [label]=\"'Messaging service' | translate\"\n [path]=\"'/monitoring/messaging-service'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [label]=\"namespaceLabel$ | async\"\n [path]=\"'/monitoring/messaging-service/namespace/' + (namespaceId$ | async)\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"topicName$ | async\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <a\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"refresh.emit()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': loading$ | async }\"\n ></i>\n {{ 'Reload' | translate }}\n </a>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage d-flex d-col\">\n <div class=\"bg-level-1 separator-bottom flex-no-shrink\">\n <div class=\"card-block\">\n <div\n class=\"col-md-4 m-b-24 col-xs-12 d-flex p-t-24 gap-16 text-default a-i-center a-s-stretch\"\n >\n <div class=\"text-center d-col\">\n <i\n class=\"m-b-8 icon-40 c8y-icon-duocolor\"\n [c8yIcon]=\"'day-view'\"\n ></i>\n <span class=\"tag tag--default\">{{ 'Topic' | translate }}</span>\n </div>\n <span class=\"h4\">{{ topicName$ | async }}</span>\n </div>\n <div class=\"col-md-4\">\n <fieldset class=\"c8y-fieldset c8y-fieldset--lg\">\n <legend translate>Topic usage</legend>\n\n <ng-container *ngIf=\"loading$ | async; else topicSummary\">\n <c8y-loading></c8y-loading>\n </ng-container>\n\n <ng-template #topicSummary>\n <ng-container *ngIf=\"overview$ | async as overview\">\n <ul class=\"list-unstyled small animated fadeIn\">\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">{{ 'Active subscribers' | translate }}</label>\n <span class=\"m-l-16\">{{ overview.topic.activeSubscribers | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">{{ 'Total subscribers' | translate }}</label>\n <span class=\"m-l-16\">{{ overview.topic.subscribers | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Total unacknowledged messages' | translate }}\n </label>\n <span class=\"m-l-16\">{{ overview.topic.unackMsgBacklog | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Message rate in' | translate }}\n </label>\n <span\n class=\"m-l-16\"\n ngNonBindable\n translate\n [translateParams]=\"{\n messagesPerSecond: overview.topic.msgRateIn | number\n }\"\n >\n {{ messagesPerSecond }} msg/s\n </span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Message rate out' | translate }}\n </label>\n <span\n class=\"m-l-16\"\n ngNonBindable\n translate\n [translateParams]=\"{\n messagesPerSecond: overview.topic.msgRateOut | number\n }\"\n >\n {{ messagesPerSecond }} msg/s\n </span>\n </li>\n </ul>\n </ng-container>\n </ng-template>\n </fieldset>\n </div>\n\n <div class=\"col-md-4\">\n <fieldset class=\"c8y-fieldset c8y-fieldset--lg\">\n <legend translate>Topic message backlog</legend>\n\n <ng-container *ngIf=\"loading$ | async; else topicBacklog\">\n <c8y-loading></c8y-loading>\n </ng-container>\n\n <ng-template #topicBacklog>\n <ng-container *ngIf=\"overview$ | async as overview\">\n <ul class=\"list-unstyled small animated fadeIn\">\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label\n class=\"small m-b-0 m-r-auto\"\n translate\n >\n Backlog usage\n </label>\n <app-usage [percentage]=\"overview.topic.backlogUsagePercentage\"></app-usage>\n <span class=\"m-l-16\">{{ overview.topic.backlogSize | bytes }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex text-nowrap\">\n <label\n class=\"small m-b-0 m-r-auto\"\n translate\n >\n Backlog quota\n </label>\n <span class=\"m-l-16\">\n {{\n overview.policies.backlogQuota?.limit > 0\n ? (overview.policies.backlogQuota?.limit | bytes)\n : '-'\n }}\n </span>\n </li>\n </ul>\n </ng-container>\n </ng-template>\n </fieldset>\n </div>\n </div>\n </div>\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col border-top border-bottom\"\n [title]=\"tableTitle | translate\"\n [loadingItemsLabel]=\"loadingItemsLabel | translate\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel | translate\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [refresh]=\"refresh\"\n [hideReload]=\"true\"\n [selectable]=\"selectable\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n >\n <c8y-ui-empty-state\n [icon]=\"stats?.size > 0 ? 'search' : 'input'\"\n [title]=\"stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)\"\n [subtitle]=\"stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)\"\n *emptyStateContext=\"let stats\"\n [horizontal]=\"stats?.size > 0\"\n ></c8y-ui-empty-state>\n\n <c8y-column name=\"name\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value }}\">\n {{ context.value }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"activeClients\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"messageAckRate\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"lastAcknowledgeDate\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n title=\"{{ context.value }}\"\n *ngIf=\"context.value; else noLastAcknwoldegeDate\"\n >\n {{ context.value | relativeTime }}\n </span>\n <ng-template #noLastAcknwoldegeDate>–</ng-template>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"unackMsgBacklog\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"backlogUsagePercentage\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value / 100 | percent: '1.0-2' }}\">\n {{ context.value / 100 | percent: '1.0-2' }}\n </span>\n </ng-container>\n </c8y-column>\n </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "ngmodule", type: DataGridModule }, { kind: "directive", type: i1.CellRendererDefDirective, selector: "[c8yCellRendererDef]" }, { kind: "directive", type: i1.ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: i1.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "hideReload"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "ngmodule", type: HeaderModule }, { kind: "component", type: i1.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: RelativeTimePipe, name: "relativeTime" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.PercentPipe, name: "percent" }, { kind: "pipe", type: BytesPipe, name: "bytes" }, { kind: "ngmodule", type: BreadcrumbModule }, { kind: "component", type: i1.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i1.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: UsageComponent, selector: "app-usage", inputs: ["count", "limit", "percentage"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: EmptyStateContextDirective, selector: "[emptyStateContext]" }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }] }); }
|
|
113
|
+
}
|
|
114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TopicSubscribersViewComponent, decorators: [{
|
|
115
|
+
type: Component,
|
|
116
|
+
args: [{ selector: 'app-topic-subscribers-view', standalone: true, imports: [
|
|
117
|
+
DataGridModule,
|
|
118
|
+
DecimalPipe,
|
|
119
|
+
HeaderModule,
|
|
120
|
+
C8yTranslateDirective,
|
|
121
|
+
RelativeTimePipe,
|
|
122
|
+
C8yTranslatePipe,
|
|
123
|
+
CommonModule,
|
|
124
|
+
BytesPipe,
|
|
125
|
+
BreadcrumbModule,
|
|
126
|
+
UsageComponent,
|
|
127
|
+
ActionBarItemComponent,
|
|
128
|
+
IconDirective,
|
|
129
|
+
EmptyStateComponent,
|
|
130
|
+
EmptyStateContextDirective,
|
|
131
|
+
LoadingComponent
|
|
132
|
+
], template: "<c8y-title>{{ topicName$ | async }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'monitoring'\"\n [label]=\"'Monitoring' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [label]=\"'Messaging service' | translate\"\n [path]=\"'/monitoring/messaging-service'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [label]=\"namespaceLabel$ | async\"\n [path]=\"'/monitoring/messaging-service/namespace/' + (namespaceId$ | async)\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"topicName$ | async\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <a\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"refresh.emit()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': loading$ | async }\"\n ></i>\n {{ 'Reload' | translate }}\n </a>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage d-flex d-col\">\n <div class=\"bg-level-1 separator-bottom flex-no-shrink\">\n <div class=\"card-block\">\n <div\n class=\"col-md-4 m-b-24 col-xs-12 d-flex p-t-24 gap-16 text-default a-i-center a-s-stretch\"\n >\n <div class=\"text-center d-col\">\n <i\n class=\"m-b-8 icon-40 c8y-icon-duocolor\"\n [c8yIcon]=\"'day-view'\"\n ></i>\n <span class=\"tag tag--default\">{{ 'Topic' | translate }}</span>\n </div>\n <span class=\"h4\">{{ topicName$ | async }}</span>\n </div>\n <div class=\"col-md-4\">\n <fieldset class=\"c8y-fieldset c8y-fieldset--lg\">\n <legend translate>Topic usage</legend>\n\n <ng-container *ngIf=\"loading$ | async; else topicSummary\">\n <c8y-loading></c8y-loading>\n </ng-container>\n\n <ng-template #topicSummary>\n <ng-container *ngIf=\"overview$ | async as overview\">\n <ul class=\"list-unstyled small animated fadeIn\">\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">{{ 'Active subscribers' | translate }}</label>\n <span class=\"m-l-16\">{{ overview.topic.activeSubscribers | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">{{ 'Total subscribers' | translate }}</label>\n <span class=\"m-l-16\">{{ overview.topic.subscribers | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Total unacknowledged messages' | translate }}\n </label>\n <span class=\"m-l-16\">{{ overview.topic.unackMsgBacklog | number }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Message rate in' | translate }}\n </label>\n <span\n class=\"m-l-16\"\n ngNonBindable\n translate\n [translateParams]=\"{\n messagesPerSecond: overview.topic.msgRateIn | number\n }\"\n >\n {{ messagesPerSecond }} msg/s\n </span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex text-nowrap\">\n <label class=\"small m-b-0 m-r-auto\">\n {{ 'Message rate out' | translate }}\n </label>\n <span\n class=\"m-l-16\"\n ngNonBindable\n translate\n [translateParams]=\"{\n messagesPerSecond: overview.topic.msgRateOut | number\n }\"\n >\n {{ messagesPerSecond }} msg/s\n </span>\n </li>\n </ul>\n </ng-container>\n </ng-template>\n </fieldset>\n </div>\n\n <div class=\"col-md-4\">\n <fieldset class=\"c8y-fieldset c8y-fieldset--lg\">\n <legend translate>Topic message backlog</legend>\n\n <ng-container *ngIf=\"loading$ | async; else topicBacklog\">\n <c8y-loading></c8y-loading>\n </ng-container>\n\n <ng-template #topicBacklog>\n <ng-container *ngIf=\"overview$ | async as overview\">\n <ul class=\"list-unstyled small animated fadeIn\">\n <li class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\">\n <label\n class=\"small m-b-0 m-r-auto\"\n translate\n >\n Backlog usage\n </label>\n <app-usage [percentage]=\"overview.topic.backlogUsagePercentage\"></app-usage>\n <span class=\"m-l-16\">{{ overview.topic.backlogSize | bytes }}</span>\n </li>\n\n <li class=\"p-t-4 p-b-4 d-flex text-nowrap\">\n <label\n class=\"small m-b-0 m-r-auto\"\n translate\n >\n Backlog quota\n </label>\n <span class=\"m-l-16\">\n {{\n overview.policies.backlogQuota?.limit > 0\n ? (overview.policies.backlogQuota?.limit | bytes)\n : '-'\n }}\n </span>\n </li>\n </ul>\n </ng-container>\n </ng-template>\n </fieldset>\n </div>\n </div>\n </div>\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col border-top border-bottom\"\n [title]=\"tableTitle | translate\"\n [loadingItemsLabel]=\"loadingItemsLabel | translate\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel | translate\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [refresh]=\"refresh\"\n [hideReload]=\"true\"\n [selectable]=\"selectable\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n >\n <c8y-ui-empty-state\n [icon]=\"stats?.size > 0 ? 'search' : 'input'\"\n [title]=\"stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)\"\n [subtitle]=\"stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)\"\n *emptyStateContext=\"let stats\"\n [horizontal]=\"stats?.size > 0\"\n ></c8y-ui-empty-state>\n\n <c8y-column name=\"name\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value }}\">\n {{ context.value }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"activeClients\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"messageAckRate\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"lastAcknowledgeDate\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n title=\"{{ context.value }}\"\n *ngIf=\"context.value; else noLastAcknwoldegeDate\"\n >\n {{ context.value | relativeTime }}\n </span>\n <ng-template #noLastAcknwoldegeDate>–</ng-template>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"unackMsgBacklog\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value | number }}\">\n {{ context.value | number }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"backlogUsagePercentage\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span title=\"{{ context.value / 100 | percent: '1.0-2' }}\">\n {{ context.value / 100 | percent: '1.0-2' }}\n </span>\n </ng-container>\n </c8y-column>\n </c8y-data-grid>\n</div>\n" }]
|
|
133
|
+
}], propDecorators: { dataGrid: [{
|
|
134
|
+
type: ViewChild,
|
|
135
|
+
args: [DataGridComponent, { static: true }]
|
|
136
|
+
}] } });
|
|
137
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9waWMtc3Vic2NyaWJlcnMtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9tZXNzYWdpbmctbWFuYWdlbWVudC9tZXNzYWdpbmcvdG9waWMvdG9waWMtc3Vic2NyaWJlcnMtdmlldy90b3BpYy1zdWJzY3JpYmVycy12aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL21lc3NhZ2luZy1tYW5hZ2VtZW50L21lc3NhZ2luZy90b3BpYy90b3BpYy1zdWJzY3JpYmVycy12aWV3L3RvcGljLXN1YnNjcmliZXJzLXZpZXcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixlQUFlLEVBQ2YsZ0JBQWdCLEVBRWhCLFNBQVMsRUFDVCxxQkFBcUIsRUFDckIsZ0JBQWdCLEVBRWhCLGlCQUFpQixFQUNqQixjQUFjLEVBRWQsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQixPQUFPLEVBQ1AsWUFBWSxFQUNaLGFBQWEsRUFDYixnQkFBZ0IsRUFFaEIsV0FBVyxFQUNYLGdCQUFnQixFQUdqQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQ3hGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG9EQUFvRCxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxlQUFlLEVBQUUs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VUFBVTthQUNwQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsK0JBQStCLENBQUMsMEJBQTBCLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUNoRixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUNwQixDQUFDO0lBQ0osQ0FBQzsrR0FySVUsNkJBQTZCO21HQUE3Qiw2QkFBNkIsZ0lBc0U3QixpQkFBaUIsOERDM0k5QixnN1FBdU9BLDJDRHBMSSxjQUFjLHUrQkFDZCxXQUFXLDhDQUNYLFlBQVksbUlBQ1oscUJBQXFCLG1FQUNyQixnQkFBZ0IsZ0RBQ2hCLGdCQUFnQixpREFDaEIsWUFBWSwwVUFDWixTQUFTLDZDQUNULGdCQUFnQixzUUFDaEIsY0FBYyxnR0FDZCxzQkFBc0IsMEpBQ3RCLGFBQWEsMkVBQ2IsbUJBQW1CLG9IQUNuQiwwQkFBMEIsZ0VBQzFCLGdCQUFnQjs7NEZBSVAsNkJBQTZCO2tCQXRCekMsU0FBUzsrQkFDRSw0QkFBNEIsY0FDMUIsSUFBSSxXQUNQO3dCQUNQLGNBQWM7d0JBQ2QsV0FBVzt3QkFDWCxZQUFZO3dCQUNaLHFCQUFxQjt3QkFDckIsZ0JBQWdCO3dCQUNoQixnQkFBZ0I7d0JBQ2hCLFlBQVk7d0JBQ1osU0FBUzt3QkFDVCxnQkFBZ0I7d0JBQ2hCLGNBQWM7d0JBQ2Qsc0JBQXNCO3dCQUN0QixhQUFhO3dCQUNiLG1CQUFtQjt3QkFDbkIsMEJBQTBCO3dCQUMxQixnQkFBZ0I7cUJBQ2pCOzhCQXlFK0MsUUFBUTtzQkFBdkQsU0FBUzt1QkFBQyxpQkFBaUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgaW5qZWN0LFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBY3Rpb25CYXJJdGVtQ29tcG9uZW50LFxuICBBY3Rpb25Db250cm9sLFxuICBBcHBTdGF0ZVNlcnZpY2UsXG4gIEJyZWFkY3J1bWJNb2R1bGUsXG4gIEJ1bGtBY3Rpb25Db250cm9sLFxuICBCeXRlc1BpcGUsXG4gIEM4eVRyYW5zbGF0ZURpcmVjdGl2ZSxcbiAgQzh5VHJhbnNsYXRlUGlwZSxcbiAgQ29sdW1uLFxuICBEYXRhR3JpZENvbXBvbmVudCxcbiAgRGF0YUdyaWRNb2R1bGUsXG4gIERhdGFTb3VyY2VNb2RpZmllcixcbiAgRW1wdHlTdGF0ZUNvbXBvbmVudCxcbiAgRW1wdHlTdGF0ZUNvbnRleHREaXJlY3RpdmUsXG4gIGdldHRleHQsXG4gIEhlYWRlck1vZHVsZSxcbiAgSWNvbkRpcmVjdGl2ZSxcbiAgTG9hZGluZ0NvbXBvbmVudCxcbiAgUGFnaW5hdGlvbixcbiAgUGVybWlzc2lvbnMsXG4gIFJlbGF0aXZlVGltZVBpcGUsXG4gIFNlcnZlclNpZGVEYXRhQ2FsbGJhY2ssXG4gIFNlcnZlclNpZGVEYXRhUmVzdWx0XG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlLCBEZWNpbWFsUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNZXNzYWdpbmdUb3BpY1R5cGUgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvdG9waWNUeXBlJztcbmltcG9ydCB7IE1lc3NhZ2luZ1RvcGljc1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hcGkvc2VydmljZXMvbWVzc2FnaW5nLXRvcGljcy5zZXJ2aWNlJztcbmltcG9ydCB7IE1lc3NhZ2luZ05hbWVzcGFjZXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXBpL3NlcnZpY2VzL21lc3NhZ2luZy1uYW1lc3BhY2VzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTkFNRVNQQUNFX1BST1BTIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvbmFtZXNwYWNlLXByb3BzJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IFRvcGljU3Vic2NyaWJlcnNEYXRhR3JpZFNlcnZpY2UgfSBmcm9tICcuL3RvcGljLXN1YnNjcmliZXJzLWRhdGEtZ3JpZC5zZXJ2aWNlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc2hhcmVSZXBsYXksIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVXNhZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXNhZ2UvdXNhZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IE1lc3NhZ2luZ1N1YnNjcmliZXIgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvc3Vic2NyaWJlcic7XG5pbXBvcnQgeyBNZXNzYWdpbmdTdWJzY3JpYmVyVG9EZWxldGUgfSBmcm9tICcuLi8uLi8uLi9hcGkvbW9kZWwvc3Vic2NyaWJlclRvRGVsZXRlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXRvcGljLXN1YnNjcmliZXJzLXZpZXcnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRGF0YUdyaWRNb2R1bGUsXG4gICAgRGVjaW1hbFBpcGUsXG4gICAgSGVhZGVyTW9kdWxlLFxuICAgIEM4eVRyYW5zbGF0ZURpcmVjdGl2ZSxcbiAgICBSZWxhdGl2ZVRpbWVQaXBlLFxuICAgIEM4eVRyYW5zbGF0ZVBpcGUsXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEJ5dGVzUGlwZSxcbiAgICBCcmVhZGNydW1iTW9kdWxlLFxuICAgIFVzYWdlQ29tcG9uZW50LFxuICAgIEFjdGlvbkJhckl0ZW1Db21wb25lbnQsXG4gICAgSWNvbkRpcmVjdGl2ZSxcbiAgICBFbXB0eVN0YXRlQ29tcG9uZW50LFxuICAgIEVtcHR5U3RhdGVDb250ZXh0RGlyZWN0aXZlLFxuICAgIExvYWRpbmdDb21wb25lbnRcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3RvcGljLXN1YnNjcmliZXJzLXZpZXcuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFRvcGljU3Vic2NyaWJlcnNWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG4gIHJvdXRlID0gaW5qZWN0KEFjdGl2YXRlZFJvdXRlKTtcbiAgYXBwU3RhdGUgPSBpbmplY3QoQXBwU3RhdGVTZXJ2aWNlKTtcbiAgbmFtZXNwYWNlc1NlcnZpY2UgPSBpbmplY3QoTWVzc2FnaW5nTmFtZXNwYWNlc1NlcnZpY2UpO1xuICB0b3BpY3NTZXJ2aWNlID0gaW5qZWN0KE1lc3NhZ2luZ1RvcGljc1NlcnZpY2UpO1xuICB0b3BpY1N1YnNjcmliZXJzRGF0YUdyaWRTZXJ2aWNlID0gaW5qZWN0KFRvcGljU3Vic2NyaWJlcnNEYXRhR3JpZFNlcnZpY2UpO1xuICB0cmFuc2xhdGVTZXJ2aWNlID0gaW5qZWN0KFRyYW5zbGF0ZVNlcnZpY2UpO1xuICBwZXJtaXNzaW9ucyA9IGluamVjdChQZXJtaXNzaW9ucyk7XG4gIGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgbG9hZGluZyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVmcmVzaCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICB0ZW5hbnRJZCQgPSB0aGlzLmFwcFN0YXRlLmN1cnJlbnRUZW5hbnQucGlwZShtYXAodGVuYW50ID0+IHRlbmFudC5uYW1lKSk7XG4gIG5hbWVzcGFjZUlkJCA9IHRoaXMucm91dGUucGFyYW1zLnBpcGUobWFwKHBhcmFtcyA9PiBwYXJhbXNbJ25hbWVzcGFjZSddIGFzIHN0cmluZykpO1xuICBuYW1lc3BhY2VMYWJlbCQgPSB0aGlzLm5hbWVzcGFjZUlkJC5waXBlKFxuICAgIG1hcChuYW1lc3BhY2VJZCA9PiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChOQU1FU1BBQ0VfUFJPUFNbbmFtZXNwYWNlSWRdLmxhYmVsKSlcbiAgKTtcbiAgdG9waWNJZCQgPSB0aGlzLnJvdXRlLnBhcmFtcy5waXBlKG1hcChwYXJhbXMgPT4gcGFyYW1zWyd0b3BpYyddIGFzIHN0cmluZykpO1xuICBvdmVydmlldyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLnRlbmFudElkJCwgdGhpcy5uYW1lc3BhY2VJZCQsIHRoaXMudG9waWNJZCQsIHRoaXMucmVmcmVzaF0pLnBpcGUoXG4gICAgdGFwKCgpID0+IHRoaXMubG9hZGluZyQubmV4dCh0cnVlKSksXG4gICAgc3dpdGNoTWFwKGFzeW5jIChbdGVuYW50SWQsIG5hbWVzcGFjZUlkLCB0b3BpY0lkXSkgPT4gKHtcbiAgICAgIHRvcGljOiAoXG4gICAgICAgIGF3YWl0IHRoaXMudG9waWNzU2VydmljZS5kZXRhaWwoe1xuICAgICAgICAgIHRlbmFudDogdGVuYW50SWQsXG4gICAgICAgICAgbmFtZXNwYWNlOiBuYW1lc3BhY2VJZCxcbiAgICAgICAgICB0b3BpYzogdG9waWNJZCxcbiAgICAgICAgICB0eXBlOiBNZXNzYWdpbmdUb3BpY1R5cGUuUGVyc2lzdGVudFxuICAgICAgICB9KVxuICAgICAgKS5kYXRhLFxuICAgICAgcG9saWNpZXM6IGF3YWl0IHRoaXMubmFtZXNwYWNlc1NlcnZpY2UuZ2V0TmFtZXNwYWNlUG9saWNpZXModGVuYW50SWQsIG5hbWVzcGFjZUlkKVxuICAgIH0pKSxcbiAgICB0YXAoKCkgPT4gdGhpcy5sb2FkaW5nJC5uZXh0KGZhbHNlKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcbiAgdG9waWNOYW1lJCA9IHRoaXMub3ZlcnZpZXckLnBpcGUobWFwKG92ZXJ2aWV3ID0+IG92ZXJ2aWV3LnRvcGljLm5hbWUpKTtcblxuICB0YWJsZVRpdGxlID0gZ2V0dGV4dCgnU3Vic2NyaWJlcnMnKTtcbiAgbG9hZGluZ0l0ZW1zTGFiZWwgPSBnZXR0ZXh0KCdMb2FkaW5nIHN1YnNjcmliZXJzLi4uJyk7XG4gIGxvYWRNb3JlSXRlbXNMYWJlbCA9IGdldHRleHQoJ0xvYWQgbW9yZSBzdWJzY3JpYmVycycpO1xuICBub1Jlc3VsdHNNZXNzYWdlID0gZ2V0dGV4dCgnTm8gbWF0Y2hpbmcgc3Vic2NyaWJlcnMgZm91bmQuJyk7XG4gIG5vUmVzdWx0c1N1YnRpdGxlID0gZ2V0dGV4dCgnUmVmaW5lIHlvdXIgc2VhcmNoIHRlcm1zIG9yIGNoZWNrIHlvdXIgc3BlbGxpbmcuJyk7XG4gIG5vRGF0YU1lc3NhZ2UgPSBnZXR0ZXh0KCdObyBzdWJzY3JpYmVycyB0byBkaXNwbGF5LicpO1xuICBub0RhdGFTdWJ0aXRsZSA9IGdldHRleHQoJ0NyZWF0ZSBuZXcgc3Vic2NyaWJlcnMgdG8gbW9uaXRvciB0aGVtIGhlcmUuJyk7XG5cbiAgY29sdW1uczogQ29sdW1uW10gPSB0aGlzLnRvcGljU3Vic2NyaWJlcnNEYXRhR3JpZFNlcnZpY2UuZ2V0Q29sdW1ucygpO1xuICBwYWdpbmF0aW9uOiBQYWdpbmF0aW9uID0ge1xuICAgIHBhZ2VTaXplOiAyMCxcbiAgICBjdXJyZW50UGFnZTogMVxuICB9O1xuXG4gIHNlbGVjdGFibGUgPSB0cnVlO1xuICBhY3Rpb25Db250cm9sczogQWN0aW9uQ29udHJvbFtdID0gW1xuICAgIHtcbiAgICAgIHR5cGU6ICd1bnN1YnNjcmliZVN1YnNjcmliZXInLFxuICAgICAgaWNvbjogJ3Vuc3Vic2NyaWJlJyxcbiAgICAgIHRleHQ6IGdldHRleHQoJ1Vuc3Vic2NyaWJlJyksXG4gICAgICBjYWxsYmFjazogKHN1YnNjcmliZXI6IE1lc3NhZ2luZ1N1YnNjcmliZXIpID0+IHRoaXMudW5zdWJzY3JpYmVTdWJzY3JpYmVyKHN1YnNjcmliZXIpLFxuICAgICAgc2hvd0lmOiAoKSA9PiB0aGlzLnBlcm1pc3Npb25zLmhhc1JvbGUoUGVybWlzc2lvbnMuUk9MRV9URU5BTlRfTUFOQUdFTUVOVF9BRE1JTilcbiAgICB9XG4gIF07XG4gIGJ1bGtBY3Rpb25Db250cm9sczogQnVsa0FjdGlvbkNvbnRyb2xbXSA9IFtcbiAgICB7XG4gICAgICB0eXBlOiAndW5zdWJzY3JpYmVTdWJzY3JpYmVyJyxcbiAgICAgIGljb246ICd1bnN1YnNjcmliZScsXG4gICAgICB0ZXh0OiBnZXR0ZXh0KCdVbnN1YnNjcmliZScpLFxuICAgICAgY2FsbGJhY2s6IChzdWJzY3JpYmVyc05hbWVzOiBzdHJpbmdbXSkgPT4gdGhpcy5idWxrVW5zdWJzY3JpYmVTdWJzY3JpYmVycyhzdWJzY3JpYmVyc05hbWVzKSxcbiAgICAgIHNob3dJZjogKCkgPT4gdGhpcy5wZXJtaXNzaW9ucy5oYXNSb2xlKFBlcm1pc3Npb25zLlJPTEVfVEVOQU5UX01BTkFHRU1FTlRfQURNSU4pXG4gICAgfVxuICBdO1xuICBAVmlld0NoaWxkKERhdGFHcmlkQ29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KSBkYXRhR3JpZDogRGF0YUdyaWRDb21wb25lbnQ7XG5cbiAgc2VydmVyU2lkZURhdGFDYWxsYmFjazogU2VydmVyU2lkZURhdGFDYWxsYmFjayA9IHRoaXMub25EYXRhU291cmNlTW9kaWZpZXIuYmluZCh0aGlzKTtcbiAgYXN5bmMgb25EYXRhU291cmNlTW9kaWZpZXIoXG4gICAgZGF0YVNvdXJjZU1vZGlmaWVyOiBEYXRhU291cmNlTW9kaWZpZXJcbiAgKTogUHJvbWlzZTxTZXJ2ZXJTaWRlRGF0YVJlc3VsdD4ge1xuICAgIHJldHVybiBmaXJzdFZhbHVlRnJvbShcbiAgICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMudGVuYW50SWQkLCB0aGlzLm5hbWVzcGFjZUlkJCwgdGhpcy50b3BpY0lkJF0pLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoW3RlbmFudElkLCBuYW1lc3BhY2VJZCwgdG9waWNJZF0pID0+XG4gICAgICAgICAgdGhpcy50b3BpY1N1YnNjcmliZXJzRGF0YUdyaWRTZXJ2aWNlLmdldFNlcnZlclNpZGVEYXRhKFxuICAgICAgICAgICAgdGVuYW50SWQsXG4gICAgICAgICAgICBuYW1lc3BhY2VJZCxcbiAgICAgICAgICAgIHRvcGljSWQsXG4gICAgICAgICAgICBNZXNzYWdpbmdUb3BpY1R5cGUuUGVyc2lzdGVudCxcbiAgICAgICAgICAgIGRhdGFTb3VyY2VNb2RpZmllclxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5yZWZyZXNoLmVtaXQoKTtcbiAgfVxuXG4gIGFzeW5jIHVuc3Vic2NyaWJlU3Vic2NyaWJlcihzdWJzY3JpYmVyOiBNZXNzYWdpbmdTdWJzY3JpYmVyKSB7XG4gICAgY29uc3QgdGVuYW50ID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy50ZW5hbnRJZCQpO1xuICAgIGNvbnN0IG5hbWVzcGFjZSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMubmFtZXNwYWNlSWQkKTtcbiAgICBjb25zdCB0b3BpYyA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMudG9waWNJZCQpO1xuICAgIHRoaXMudG9waWNTdWJzY3JpYmVyc0RhdGFHcmlkU2VydmljZS51bnN1YnNjcmliZVN1YnNjcmliZXIoXG4gICAgICB7XG4gICAgICAgIC4uLnN1YnNjcmliZXIsXG4gICAgICAgIHRlbmFudCxcbiAgICAgICAgbmFtZXNwYWNlLFxuICAgICAgICB0b3BpYyxcbiAgICAgICAgdHlwZTogTWVzc2FnaW5nVG9waWNUeXBlLlBlcnNpc3RlbnRcbiAgICAgIH0sXG4gICAgICAoKSA9PiB0aGlzLnJlZnJlc2guZW1pdCgpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGJ1bGtVbnN1YnNjcmliZVN1YnNjcmliZXJzKHN1YnNjcmliZXJzTmFtZXM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGVuYW50ID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy50ZW5hbnRJZCQpO1xuICAgIGNvbnN0IG5hbWVzcGFjZSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMubmFtZXNwYWNlSWQkKTtcbiAgICBjb25zdCB0b3BpYyA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMudG9waWNJZCQpO1xuICAgIGNvbnN0IGFsbFN1YnNjcmliZXJzOiBNZXNzYWdpbmdTdWJzY3JpYmVyW10gPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgIHRoaXMuZGF0YUdyaWQuZGF0YVNvdXJjZS5kYXRhJFxuICAgICk7XG5cbiAgICBjb25zdCBzdWJzY3JpYmVyczogTWVzc2FnaW5nU3Vic2NyaWJlclRvRGVsZXRlW10gPSBzdWJzY3JpYmVyc05hbWVzLm1hcChzdWJzY3JpYmVyTmFtZSA9PiB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gYWxsU3Vic2NyaWJlcnMuZmluZChzdWJzY3JpYmVyID0+IHN1YnNjcmliZXIubmFtZSA9PT0gc3Vic2NyaWJlck5hbWUpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc3Vic2NyaWJlcixcbiAgICAgICAgdGVuYW50LFxuICAgICAgICBuYW1lc3BhY2UsXG4gICAgICAgIHRvcGljLFxuICAgICAgICB0eXBlOiBNZXNzYWdpbmdUb3BpY1R5cGUuUGVyc2lzdGVudFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHRoaXMudG9waWNTdWJzY3JpYmVyc0RhdGFHcmlkU2VydmljZS5idWxrVW5zdWJzY3JpYmVTdWJzY3JpYmVycyhzdWJzY3JpYmVycywgKCkgPT5cbiAgICAgIHRoaXMucmVmcmVzaC5lbWl0KClcbiAgICApO1xuICB9XG59XG4iLCI8Yzh5LXRpdGxlPnt7IHRvcGljTmFtZSQgfCBhc3luYyB9fTwvYzh5LXRpdGxlPlxuXG48Yzh5LWJyZWFkY3J1bWI+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtXG4gICAgW2ljb25dPVwiJ21vbml0b3JpbmcnXCJcbiAgICBbbGFiZWxdPVwiJ01vbml0b3JpbmcnIHwgdHJhbnNsYXRlXCJcbiAgPjwvYzh5LWJyZWFkY3J1bWItaXRlbT5cbiAgPGM4eS1icmVhZGNydW1iLWl0ZW1cbiAgICBbbGFiZWxdPVwiJ01lc3NhZ2luZyBzZXJ2aWNlJyB8IHRyYW5zbGF0ZVwiXG4gICAgW3BhdGhdPVwiJy9tb25pdG9yaW5nL21lc3NhZ2luZy1zZXJ2aWNlJ1wiXG4gID48L2M4eS1icmVhZGNydW1iLWl0ZW0+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtXG4gICAgW2xhYmVsXT1cIm5hbWVzcGFjZUxhYmVsJCB8IGFzeW5jXCJcbiAgICBbcGF0aF09XCInL21vbml0b3JpbmcvbWVzc2FnaW5nLXNlcnZpY2UvbmFtZXNwYWNlLycgKyAobmFtZXNwYWNlSWQkIHwgYXN5bmMpXCJcbiAgPjwvYzh5LWJyZWFkY3J1bWItaXRlbT5cbiAgPGM4eS1icmVhZGNydW1iLWl0ZW0gW2xhYmVsXT1cInRvcGljTmFtZSQgfCBhc3luY1wiPjwvYzh5LWJyZWFkY3J1bWItaXRlbT5cbjwvYzh5LWJyZWFkY3J1bWI+XG5cbjxjOHktYWN0aW9uLWJhci1pdGVtIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiPlxuICA8YVxuICAgIGNsYXNzPVwiYnRuIGJ0bi1saW5rXCJcbiAgICB0aXRsZT1cInt7ICdSZWxvYWQnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAoY2xpY2spPVwicmVmcmVzaC5lbWl0KClcIlxuICA+XG4gICAgPGlcbiAgICAgIGM4eUljb249XCJyZWZyZXNoXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ2ljb24tc3Bpbic6IGxvYWRpbmckIHwgYXN5bmMgfVwiXG4gICAgPjwvaT5cbiAgICB7eyAnUmVsb2FkJyB8IHRyYW5zbGF0ZSB9fVxuICA8L2E+XG48L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbjxkaXYgY2xhc3M9XCJjYXJkIGNvbnRlbnQtZnVsbHBhZ2UgZC1mbGV4IGQtY29sXCI+XG4gIDxkaXYgY2xhc3M9XCJiZy1sZXZlbC0xIHNlcGFyYXRvci1ib3R0b20gZmxleC1uby1zaHJpbmtcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ibG9ja1wiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImNvbC1tZC00IG0tYi0yNCBjb2wteHMtMTIgZC1mbGV4IHAtdC0yNCBnYXAtMTYgdGV4dC1kZWZhdWx0IGEtaS1jZW50ZXIgYS1zLXN0cmV0Y2hcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgZC1jb2xcIj5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJtLWItOCBpY29uLTQwIGM4eS1pY29uLWR1b2NvbG9yXCJcbiAgICAgICAgICAgIFtjOHlJY29uXT1cIidkYXktdmlldydcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0YWcgdGFnLS1kZWZhdWx0XCI+e3sgJ1RvcGljJyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaDRcIj57eyB0b3BpY05hbWUkIHwgYXN5bmMgfX08L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNFwiPlxuICAgICAgICA8ZmllbGRzZXQgY2xhc3M9XCJjOHktZmllbGRzZXQgYzh5LWZpZWxkc2V0LS1sZ1wiPlxuICAgICAgICAgIDxsZWdlbmQgdHJhbnNsYXRlPlRvcGljIHVzYWdlPC9sZWdlbmQ+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZyQgfCBhc3luYzsgZWxzZSB0b3BpY1N1bW1hcnlcIj5cbiAgICAgICAgICAgIDxjOHktbG9hZGluZz48L2M4eS1sb2FkaW5nPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICN0b3BpY1N1bW1hcnk+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwib3ZlcnZpZXckIHwgYXN5bmMgYXMgb3ZlcnZpZXdcIj5cbiAgICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZCBzbWFsbCBhbmltYXRlZCBmYWRlSW5cIj5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggc2VwYXJhdG9yLWJvdHRvbSB0ZXh0LW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwic21hbGwgbS1iLTAgbS1yLWF1dG9cIj57eyAnQWN0aXZlIHN1YnNjcmliZXJzJyB8IHRyYW5zbGF0ZSB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm0tbC0xNlwiPnt7IG92ZXJ2aWV3LnRvcGljLmFjdGl2ZVN1YnNjcmliZXJzIHwgbnVtYmVyIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbGk+XG5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggc2VwYXJhdG9yLWJvdHRvbSB0ZXh0LW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwic21hbGwgbS1iLTAgbS1yLWF1dG9cIj57eyAnVG90YWwgc3Vic2NyaWJlcnMnIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibS1sLTE2XCI+e3sgb3ZlcnZpZXcudG9waWMuc3Vic2NyaWJlcnMgfCBudW1iZXIgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9saT5cblxuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm93cmFwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJzbWFsbCBtLWItMCBtLXItYXV0b1wiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnVG90YWwgdW5hY2tub3dsZWRnZWQgbWVzc2FnZXMnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtLWwtMTZcIj57eyBvdmVydmlldy50b3BpYy51bmFja01zZ0JhY2tsb2cgfCBudW1iZXIgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9saT5cblxuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tIHRleHQtbm93cmFwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJzbWFsbCBtLWItMCBtLXItYXV0b1wiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnTWVzc2FnZSByYXRlIGluJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibS1sLTE2XCJcbiAgICAgICAgICAgICAgICAgICAgbmdOb25CaW5kYWJsZVxuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICAgICAgICAgICAgW3RyYW5zbGF0ZVBhcmFtc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXNQZXJTZWNvbmQ6IG92ZXJ2aWV3LnRvcGljLm1zZ1JhdGVJbiB8IG51bWJlclxuICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgbWVzc2FnZXNQZXJTZWNvbmQgfX0gbXNnL3NcbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuXG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHRleHQtbm93cmFwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJzbWFsbCBtLWItMCBtLXItYXV0b1wiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnTWVzc2FnZSByYXRlIG91dCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm0tbC0xNlwiXG4gICAgICAgICAgICAgICAgICAgIG5nTm9uQmluZGFibGVcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgICAgIFt0cmFuc2xhdGVQYXJhbXNdPVwie1xuICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzUGVyU2Vjb25kOiBvdmVydmlldy50b3BpYy5tc2dSYXRlT3V0IHwgbnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7eyBtZXNzYWdlc1BlclNlY29uZCB9fSBtc2cvc1xuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2ZpZWxkc2V0PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNFwiPlxuICAgICAgICA8ZmllbGRzZXQgY2xhc3M9XCJjOHktZmllbGRzZXQgYzh5LWZpZWxkc2V0LS1sZ1wiPlxuICAgICAgICAgIDxsZWdlbmQgdHJhbnNsYXRlPlRvcGljIG1lc3NhZ2UgYmFja2xvZzwvbGVnZW5kPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmckIHwgYXN5bmM7IGVsc2UgdG9waWNCYWNrbG9nXCI+XG4gICAgICAgICAgICA8Yzh5LWxvYWRpbmc+PC9jOHktbG9hZGluZz5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjdG9waWNCYWNrbG9nPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm92ZXJ2aWV3JCB8IGFzeW5jIGFzIG92ZXJ2aWV3XCI+XG4gICAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtdW5zdHlsZWQgc21hbGwgYW5pbWF0ZWQgZmFkZUluXCI+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHNlcGFyYXRvci1ib3R0b20gdGV4dC1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNtYWxsIG0tYi0wIG0tci1hdXRvXCJcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIEJhY2tsb2cgdXNhZ2VcbiAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8YXBwLXVzYWdlIFtwZXJjZW50YWdlXT1cIm92ZXJ2aWV3LnRvcGljLmJhY2tsb2dVc2FnZVBlcmNlbnRhZ2VcIj48L2FwcC11c2FnZT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibS1sLTE2XCI+e3sgb3ZlcnZpZXcudG9waWMuYmFja2xvZ1NpemUgfCBieXRlcyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuXG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicC10LTQgcC1iLTQgZC1mbGV4IHRleHQtbm93cmFwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzbWFsbCBtLWItMCBtLXItYXV0b1wiXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICBCYWNrbG9nIHF1b3RhXG4gICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtLWwtMTZcIj5cbiAgICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgICBvdmVydmlldy5wb2xpY2llcy5iYWNrbG9nUXVvdGE/LmxpbWl0ID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyAob3ZlcnZpZXcucG9saWNpZXMuYmFja2xvZ1F1b3RhPy5saW1pdCB8IGJ5dGVzKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiAnLSdcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9maWVsZHNldD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGM4eS1kYXRhLWdyaWRcbiAgICBjbGFzcz1cImNvbnRlbnQtZnVsbHBhZ2UgZC1mbGV4IGQtY29sIGJvcmRlci10b3AgYm9yZGVyLWJvdHRvbVwiXG4gICAgW3RpdGxlXT1cInRhYmxlVGl0bGUgfCB0cmFuc2xhdGVcIlxuICAgIFtsb2FkaW5nSXRlbXNMYWJlbF09XCJsb2FkaW5nSXRlbXNMYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgW2xvYWRNb3JlSXRlbXNMYWJlbF09XCJsb2FkTW9yZUl0ZW1zTGFiZWwgfCB0cmFuc2xhdGVcIlxuICAgIFtjb2x1bW5zXT1cImNvbHVtbnNcIlxuICAgIFtwYWdpbmF0aW9uXT1cInBhZ2luYXRpb25cIlxuICAgIFtzZXJ2ZXJTaWRlRGF0YUNhbGxiYWNrXT1cInNlcnZlclNpZGVEYXRhQ2FsbGJhY2tcIlxuICAgIFtyZWZyZXNoXT1cInJlZnJlc2hcIlxuICAgIFtoaWRlUmVsb2FkXT1cInRydWVcIlxuICAgIFtzZWxlY3RhYmxlXT1cInNlbGVjdGFibGVcIlxuICAgIFthY3Rpb25Db250cm9sc109XCJhY3Rpb25Db250cm9sc1wiXG4gICAgW2J1bGtBY3Rpb25Db250cm9sc109XCJidWxrQWN0aW9uQ29udHJvbHNcIlxuICA+XG4gICAgPGM4eS11aS1lbXB0eS1zdGF0ZVxuICAgICAgW2ljb25dPVwic3RhdHM/LnNpemUgPiAwID8gJ3NlYXJjaCcgOiAnaW5wdXQnXCJcbiAgICAgIFt0aXRsZV09XCJzdGF0cz8uc2l6ZSA+IDAgPyAobm9SZXN1bHRzTWVzc2FnZSB8IHRyYW5zbGF0ZSkgOiAobm9EYXRhTWVzc2FnZSB8IHRyYW5zbGF0ZSlcIlxuICAgICAgW3N1YnRpdGxlXT1cInN0YXRzPy5zaXplID4gMCA/IChub1Jlc3VsdHNTdWJ0aXRsZSB8IHRyYW5zbGF0ZSkgOiAobm9EYXRhU3VidGl0bGUgfCB0cmFuc2xhdGUpXCJcbiAgICAgICplbXB0eVN0YXRlQ29udGV4dD1cImxldCBzdGF0c1wiXG4gICAgICBbaG9yaXpvbnRhbF09XCJzdGF0cz8uc2l6ZSA+IDBcIlxuICAgID48L2M4eS11aS1lbXB0eS1zdGF0ZT5cblxuICAgIDxjOHktY29sdW1uIG5hbWU9XCJuYW1lXCI+XG4gICAgICA8bmctY29udGFpbmVyICpjOHlDZWxsUmVuZGVyZXJEZWY9XCJsZXQgY29udGV4dFwiPlxuICAgICAgICA8c3BhbiB0aXRsZT1cInt7IGNvbnRleHQudmFsdWUgfX1cIj5cbiAgICAgICAgICB7eyBjb250ZXh0LnZhbHVlIH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvYzh5LWNvbHVtbj5cblxuICAgIDxjOHktY29sdW1uIG5hbWU9XCJhY3RpdmVDbGllbnRzXCI+XG4gICAgICA8bmctY29udGFpbmVyICpjOHlDZWxsUmVuZGVyZXJEZWY9XCJsZXQgY29udGV4dFwiPlxuICAgICAgICA8c3BhbiB0aXRsZT1cInt7IGNvbnRleHQudmFsdWUgfCBudW1iZXIgfX1cIj5cbiAgICAgICAgICB7eyBjb250ZXh0LnZhbHVlIHwgbnVtYmVyIH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvYzh5LWNvbHVtbj5cblxuICAgIDxjOHktY29sdW1uIG5hbWU9XCJtZXNzYWdlQWNrUmF0ZVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqYzh5Q2VsbFJlbmRlcmVyRGVmPVwibGV0IGNvbnRleHRcIj5cbiAgICAgICAgPHNwYW4gdGl0bGU9XCJ7eyBjb250ZXh0LnZhbHVlIHwgbnVtYmVyIH19XCI+XG4gICAgICAgICAge3sgY29udGV4dC52YWx1ZSB8IG51bWJlciB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2M4eS1jb2x1bW4+XG5cbiAgICA8Yzh5LWNvbHVtbiBuYW1lPVwibGFzdEFja25vd2xlZGdlRGF0ZVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqYzh5Q2VsbFJlbmRlcmVyRGVmPVwibGV0IGNvbnRleHRcIj5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICB0aXRsZT1cInt7IGNvbnRleHQudmFsdWUgfX1cIlxuICAgICAgICAgICpuZ0lmPVwiY29udGV4dC52YWx1ZTsgZWxzZSBub0xhc3RBY2tud29sZGVnZURhdGVcIlxuICAgICAgICA+XG4gICAgICAgICAge3sgY29udGV4dC52YWx1ZSB8IHJlbGF0aXZlVGltZSB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9MYXN0QWNrbndvbGRlZ2VEYXRlPiZuZGFzaDs8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9jOHktY29sdW1uPlxuXG4gICAgPGM4eS1jb2x1bW4gbmFtZT1cInVuYWNrTXNnQmFja2xvZ1wiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqYzh5Q2VsbFJlbmRlcmVyRGVmPVwibGV0IGNvbnRleHRcIj5cbiAgICAgICAgPHNwYW4gdGl0bGU9XCJ7eyBjb250ZXh0LnZhbHVlIHwgbnVtYmVyIH19XCI+XG4gICAgICAgICAge3sgY29udGV4dC52YWx1ZSB8IG51bWJlciB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2M4eS1jb2x1bW4+XG5cbiAgICA8Yzh5LWNvbHVtbiBuYW1lPVwiYmFja2xvZ1VzYWdlUGVyY2VudGFnZVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqYzh5Q2VsbFJlbmRlcmVyRGVmPVwibGV0IGNvbnRleHRcIj5cbiAgICAgICAgPHNwYW4gdGl0bGU9XCJ7eyBjb250ZXh0LnZhbHVlIC8gMTAwIHwgcGVyY2VudDogJzEuMC0yJyB9fVwiPlxuICAgICAgICAgIHt7IGNvbnRleHQudmFsdWUgLyAxMDAgfCBwZXJjZW50OiAnMS4wLTInIH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvYzh5LWNvbHVtbj5cbiAgPC9jOHktZGF0YS1ncmlkPlxuPC9kaXY+XG4iXX0=
|