@posiwise/smart-crm 0.0.53 → 0.0.55

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.
Files changed (69) hide show
  1. package/fesm2022/posiwise-smart-crm.mjs +244 -246
  2. package/fesm2022/posiwise-smart-crm.mjs.map +1 -1
  3. package/lib/private/components/smart-crm-accounts/smart-crm-accounts.component.d.ts +1 -0
  4. package/lib/private/components/smart-crm-insight/smart-crm-account-insight/smart-crm-account-insight.component.d.ts +1 -1
  5. package/lib/private/components/smart-crm-opportunities/smart-crm-opportunities-list/smart-crm-opportunities-list.component.d.ts +1 -0
  6. package/package.json +3 -5
  7. package/esm2022/index.mjs +0 -52
  8. package/esm2022/lib/private/components/smart-crm-accounts/smart-crm-account-details/smart-crm-account-details.component.mjs +0 -210
  9. package/esm2022/lib/private/components/smart-crm-accounts/smart-crm-account-files/smart-crm-account-files.component.mjs +0 -191
  10. package/esm2022/lib/private/components/smart-crm-accounts/smart-crm-account-info/smart-crm-account-info.component.mjs +0 -612
  11. package/esm2022/lib/private/components/smart-crm-accounts/smart-crm-account-invoices/smart-crm-account-invoices.component.mjs +0 -71
  12. package/esm2022/lib/private/components/smart-crm-accounts/smart-crm-accounts.component.mjs +0 -361
  13. package/esm2022/lib/private/components/smart-crm-actions/smart-crm-actions.component.mjs +0 -267
  14. package/esm2022/lib/private/components/smart-crm-competition/smart-crm-competition/smart-crm-competition.component.mjs +0 -12
  15. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-actions/smart-crm-actions-details/smart-crm-actions-details.component.mjs +0 -103
  16. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-actions/smart-crm-actions.component.mjs +0 -126
  17. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-configuration.component.mjs +0 -35
  18. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-opportunity-categories/smart-crm-opportunity-categories-details/smart-crm-opportunity-categories-details.component.mjs +0 -88
  19. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-opportunity-categories/smart-crm-opportunity-categories.component.mjs +0 -120
  20. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-source/smart-crm-source-details/smart-crm-source-details.component.mjs +0 -79
  21. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-source/smart-crm-source.component.mjs +0 -107
  22. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-stages/smart-crm-stage-details/smart-crm-stage-details.component.mjs +0 -97
  23. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-stages/smart-crm-stages.component.mjs +0 -156
  24. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-widgets/smart-crm-widgets-details/smart-crm-widgets-details.component.mjs +0 -99
  25. package/esm2022/lib/private/components/smart-crm-configuration/smart-crm-widgets/smart-crm-widgets.component.mjs +0 -125
  26. package/esm2022/lib/private/components/smart-crm-contacts/smart-crm-contact-details/smart-crm-contact-details.component.mjs +0 -197
  27. package/esm2022/lib/private/components/smart-crm-contacts/smart-crm-contact-info/smart-crm-contact-info.component.mjs +0 -481
  28. package/esm2022/lib/private/components/smart-crm-contacts/smart-crm-contacts.component.mjs +0 -301
  29. package/esm2022/lib/private/components/smart-crm-customer/smart-crm-customer-success/smart-crm-customer-success.component.mjs +0 -12
  30. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-account-insight/smart-crm-account-insight.component.mjs +0 -314
  31. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-analysis-insight/smart-crm-analysis.component.mjs +0 -104
  32. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-contact-insight/smart-crm-contact-insight.component.mjs +0 -105
  33. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-insight.component.mjs +0 -27
  34. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-marketing-insight/smart-crm-marketing-insight.component.mjs +0 -80
  35. package/esm2022/lib/private/components/smart-crm-insight/smart-crm-opportunities-insight/smart-crm-opportunities-insight.component.mjs +0 -160
  36. package/esm2022/lib/private/components/smart-crm-leads/smart-crm-leads-details/smart-crm-leads-details.component.mjs +0 -227
  37. package/esm2022/lib/private/components/smart-crm-leads/smart-crm-leads.component.mjs +0 -146
  38. package/esm2022/lib/private/components/smart-crm-marketing/smart-crm-marketing-list/smart-crm-marketing-contacts/smart-crm-marketing-contacts.component.mjs +0 -79
  39. package/esm2022/lib/private/components/smart-crm-marketing/smart-crm-marketing-list/smart-crm-marketing-details/smart-crm-marketing-details.component.mjs +0 -269
  40. package/esm2022/lib/private/components/smart-crm-marketing/smart-crm-marketing-list/smart-crm-marketing-list.component.mjs +0 -157
  41. package/esm2022/lib/private/components/smart-crm-marketing/smart-crm-marketing-list/smart-crm-marketing-view-details/smart-crm-marketing-view-details.component.mjs +0 -60
  42. package/esm2022/lib/private/components/smart-crm-marketing/smart-crm-marketing.component.mjs +0 -18
  43. package/esm2022/lib/private/components/smart-crm-media/smart-crm-social-media/smart-crm-social-media.component.mjs +0 -12
  44. package/esm2022/lib/private/components/smart-crm-opportunities/smart-crm-board/smart-crm-board.component.mjs +0 -236
  45. package/esm2022/lib/private/components/smart-crm-opportunities/smart-crm-opportunities-list/smart-crm-opportunities-details/smart-crm-opportunities-details.component.mjs +0 -376
  46. package/esm2022/lib/private/components/smart-crm-opportunities/smart-crm-opportunities-list/smart-crm-opportunities-info/smart-crm-opportunities-info.component.mjs +0 -483
  47. package/esm2022/lib/private/components/smart-crm-opportunities/smart-crm-opportunities-list/smart-crm-opportunities-list.component.mjs +0 -256
  48. package/esm2022/lib/private/components/smart-crm-opportunities/smart-crm-opportunities.component.mjs +0 -14
  49. package/esm2022/lib/private/components/smart-crm-tabs/smart-crm-tabs.component.mjs +0 -99
  50. package/esm2022/lib/private/smart-crm-private.module.mjs +0 -356
  51. package/esm2022/lib/private/smart-crm-private.routing.module.mjs +0 -318
  52. package/esm2022/lib/public/components/smart-crm-newsletter-confirmation/smart-crm-newsletter-confirmation.component.mjs +0 -56
  53. package/esm2022/lib/public/components/smart-crm-newsletter-unsubscribe/smart-crm-newsletter-unsubscribe.component.mjs +0 -57
  54. package/esm2022/lib/public/components/smart-crm-signup/smart-crm-signup.component.mjs +0 -38
  55. package/esm2022/lib/public/smart-crm-public.module.mjs +0 -46
  56. package/esm2022/lib/public/smart-crm-public.routing.module.mjs +0 -44
  57. package/esm2022/lib/shared/interface/crm-account.interface.mjs +0 -2
  58. package/esm2022/lib/shared/interface/crm-action.interface.mjs +0 -2
  59. package/esm2022/lib/shared/interface/crm-contact.interface.mjs +0 -2
  60. package/esm2022/lib/shared/interface/crm-lead.interface.mjs +0 -2
  61. package/esm2022/lib/shared/interface/crm-newsletter.interface.mjs +0 -2
  62. package/esm2022/lib/shared/interface/crm-opportunity.interface.mjs +0 -2
  63. package/esm2022/lib/shared/interface/crm-source.interface.mjs +0 -2
  64. package/esm2022/lib/shared/interface/crm-stages.interface.mjs +0 -2
  65. package/esm2022/lib/shared/interface/crm-widget.interface.mjs +0 -2
  66. package/esm2022/lib/shared/interface/smart-crm-module.interface.mjs +0 -2
  67. package/esm2022/lib/shared/models/smart-crm.model.mjs +0 -191
  68. package/esm2022/lib/shared/routers/routers.mjs +0 -24
  69. package/esm2022/posiwise-smart-crm.mjs +0 -5
@@ -1,361 +0,0 @@
1
- import { ChangeDetectorRef, Component, Injector } from '@angular/core';
2
- import { AppBaseComponent } from '@posiwise/app-base-component';
3
- import { CommonService, LogoCacheService } from '@posiwise/common-services';
4
- import { PAGE_SIZE } from '@posiwise/common-utilities';
5
- import { HelperService } from '@posiwise/helper-service';
6
- import { CrmService } from '@posiwise/smart-crm-shared';
7
- import { ROUTERS } from '../../../shared/routers/routers';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "@posiwise/smart-crm-shared";
10
- import * as i2 from "@posiwise/common-services";
11
- import * as i3 from "@angular/common";
12
- import * as i4 from "@angular/forms";
13
- import * as i5 from "primeng/inputtext";
14
- import * as i6 from "@ng-bootstrap/ng-bootstrap";
15
- import * as i7 from "@posiwise/directives";
16
- import * as i8 from "angular-plotly.js";
17
- import * as i9 from "@angular-magic/ngx-gp-autocomplete";
18
- import * as i10 from "@angular/router";
19
- import * as i11 from "primeng/table";
20
- import * as i12 from "primeng/api";
21
- import * as i13 from "primeng/tooltip";
22
- import * as i14 from "primeng/multiselect";
23
- import * as i15 from "primeng/progressspinner";
24
- import * as i16 from "@posiwise/shared-components";
25
- import * as i17 from "@posiwise/pipes";
26
- import * as i18 from "@jsverse/transloco";
27
- export class SmartCrmCompaniesComponent extends AppBaseComponent {
28
- constructor(crmService, commonService, logoCacheService, injector, cdr) {
29
- super(injector);
30
- this.crmService = crmService;
31
- this.commonService = commonService;
32
- this.logoCacheService = logoCacheService;
33
- this.cdr = cdr;
34
- this.page = 1;
35
- this.data = {
36
- accounts: [],
37
- object_count: 0,
38
- unfiltered_count: 0
39
- };
40
- this.totals = {
41
- total_mrr: 0,
42
- sessions_last_month: 0,
43
- sessions_last_quarter: 0
44
- };
45
- this.organizationSizes = [];
46
- this.searchOptions = [];
47
- this.filterByIndustries = [];
48
- this.status = [];
49
- this.priority = [];
50
- this.source = [];
51
- this.filterBySource = [];
52
- this.filterByStatus = [];
53
- this.filterByPriority = [];
54
- this.filterBySizeId = [];
55
- this.searchText = '';
56
- this.accountActivities = [];
57
- this.loading = true;
58
- this.hasAccess = false;
59
- this.isLoaded = false;
60
- this.routers = ROUTERS;
61
- this.actionNames = [];
62
- }
63
- ngOnInit() {
64
- this.getUserSubscription().subscribe(response => {
65
- this.subscription = response;
66
- if (this.subscription?.id) {
67
- this.accountDefaultValues(this.subscription.id);
68
- this.hasAccess = this.hasAdminAccess(this.subscription.id);
69
- this.getUserInfo();
70
- }
71
- });
72
- this.getIndustries();
73
- this.getAllOrganizationSize();
74
- }
75
- ngAfterViewChecked() {
76
- this.cdr.detectChanges();
77
- }
78
- onLazyLoad(event) {
79
- const pageDetails = HelperService.onTableLazyLoad(event);
80
- this.page = pageDetails.page;
81
- this.getAllAccounts({
82
- page: this.page,
83
- page_size: PAGE_SIZE,
84
- order_by: pageDetails.sortField,
85
- order_direction: pageDetails.sortOrder,
86
- search: this.searchText
87
- });
88
- }
89
- /** Function to get user details */
90
- getUserInfo() {
91
- this.userStore().subscribe(user => {
92
- if (user) {
93
- this.userId = user?.id;
94
- if (this.permissionService.isGranted('Pages.Beta')) {
95
- this.getAccountGeography();
96
- this.getAccountActivities();
97
- }
98
- }
99
- });
100
- }
101
- handleImageError(event, fallbackPath) {
102
- HelperService.handleImageFallbackPath(event, fallbackPath);
103
- }
104
- /** Function to call account default values */
105
- accountDefaultValues(id) {
106
- this.crmService.getCrmAccountDefaultValues(id).subscribe(response => {
107
- const { status } = response;
108
- status.forEach(val => {
109
- const data = {
110
- label: val,
111
- value: val
112
- };
113
- this.status.push(data);
114
- });
115
- const { priority } = response;
116
- priority.forEach(val => {
117
- const data = {
118
- label: val,
119
- value: val
120
- };
121
- this.priority.push(data);
122
- });
123
- const { source } = response;
124
- source.forEach(val => {
125
- const data = {
126
- label: val.name,
127
- value: val.id
128
- };
129
- this.source.push(data);
130
- });
131
- });
132
- }
133
- /** Function to get the accounts list */
134
- getAllAccounts(paging) {
135
- this.data.accounts = [];
136
- this.getUserSubscriptionId().subscribe(response => {
137
- this.subscriptionId = response;
138
- if (this.subscriptionId) {
139
- this.crmService
140
- .getAllAccounts({
141
- subscription_id: this.subscriptionId,
142
- paging: paging,
143
- industry: this.filterByIndustries.join() || '',
144
- size: this.filterBySizeId.join() || '',
145
- status: this.filterByStatus.join() || '',
146
- priority: this.filterByPriority.join() || '',
147
- source: this.filterBySource.join() || '',
148
- location: this.filterByLocation || ''
149
- })
150
- .subscribe(res => {
151
- this.data = res;
152
- // Map totals from API response only - don't calculate
153
- if (this.data.totals) {
154
- this.totals = {
155
- total_mrr: this.data.totals.expected_mrr_usd || 0,
156
- sessions_last_month: this.data.totals.sessions_last_month || 0,
157
- sessions_last_quarter: this.data.totals.sessions_last_quarter || 0
158
- };
159
- }
160
- else {
161
- // If no totals from API, set to 0 (don't calculate)
162
- this.totals = {
163
- total_mrr: 0,
164
- sessions_last_month: 0,
165
- sessions_last_quarter: 0
166
- };
167
- }
168
- })
169
- .add(() => {
170
- this.isLoaded = true;
171
- this.loading = false;
172
- });
173
- }
174
- });
175
- }
176
- /** Function to call accounts size */
177
- getAllOrganizationSize() {
178
- this.commonService.getOrganizationSizes().subscribe(response => {
179
- const organizationSizes = response.organization_sizes;
180
- organizationSizes.forEach(val => {
181
- const data = {
182
- label: val.name,
183
- value: val.id
184
- };
185
- this.organizationSizes.push(data);
186
- });
187
- });
188
- }
189
- /** Function to get organization industries */
190
- getIndustries() {
191
- this.commonService.getOrganizationIndustries().subscribe(response => {
192
- this.allIndustries = response.organization_industries;
193
- this.allIndustries.forEach(val => {
194
- const industries = {
195
- label: val.name,
196
- value: val.id
197
- };
198
- this.searchOptions.push(industries);
199
- });
200
- });
201
- }
202
- /** Function to execute on delete button click */
203
- onDelete(id, subscription_id) {
204
- HelperService.raiseDeletePopup().then(res => {
205
- if (res.value) {
206
- this.crmService.deleteAccount(id, subscription_id).subscribe(() => {
207
- this.getAllAccounts({
208
- page: this.page,
209
- page_size: PAGE_SIZE,
210
- search: this.searchText
211
- });
212
- this.toast.success(this.translation.translate('Crm.AccountMessage.DeletedMessage'));
213
- });
214
- }
215
- });
216
- }
217
- /** filtering accounts */
218
- onSearchOptionChange(event, filterBy) {
219
- if (filterBy === 'industry') {
220
- this.filterByIndustries = event.value;
221
- this.getAllAccounts({
222
- page: this.page,
223
- page_size: PAGE_SIZE
224
- });
225
- }
226
- if (filterBy === 'size') {
227
- this.filterBySizeId = event.value;
228
- this.getAllAccounts({
229
- page: this.page,
230
- page_size: PAGE_SIZE
231
- });
232
- }
233
- if (filterBy === 'status') {
234
- this.filterByStatus = event.value;
235
- this.getAllAccounts({
236
- page: this.page,
237
- page_size: PAGE_SIZE
238
- });
239
- }
240
- if (filterBy === 'priority') {
241
- this.filterByPriority = event.value;
242
- this.getAllAccounts({
243
- page: this.page,
244
- page_size: PAGE_SIZE
245
- });
246
- }
247
- if (filterBy === 'source') {
248
- this.filterBySource = event.value;
249
- this.getAllAccounts({
250
- page: this.page,
251
- page_size: PAGE_SIZE
252
- });
253
- }
254
- }
255
- /** Function to execute on location select */
256
- handleAddressChange(event) {
257
- this.filterByLocation = event.formatted_address;
258
- this.getAllAccounts({
259
- page: this.page,
260
- page_size: PAGE_SIZE
261
- });
262
- }
263
- /** Location filter while keyup */
264
- locationSearch(event) {
265
- if (event.target.value.length === 0) {
266
- this.filterByLocation = '';
267
- this.getAllAccounts({
268
- page: this.page,
269
- page_size: PAGE_SIZE
270
- });
271
- }
272
- }
273
- /** Function to clear all filters */
274
- clearFilters() {
275
- this.filterBySizeId = [];
276
- this.filterByIndustries = [];
277
- this.filterByPriority = [];
278
- this.filterBySource = [];
279
- this.filterByStatus = [];
280
- this.searchText = '';
281
- this.filterByLocation = '';
282
- this.searchLocationText = '';
283
- this.getAllAccounts({
284
- page: this.page,
285
- page_size: PAGE_SIZE
286
- });
287
- }
288
- /** Function to call account geography */
289
- getAccountGeography() {
290
- this.crmService
291
- .getCrmAnalytics(this.subscription?.id, 'accounts_geography')
292
- .subscribe(response => {
293
- // API now returns { items: [], totals: {} } instead of array/object
294
- this.accountGeography = response?.items || response;
295
- });
296
- }
297
- getUserAccountInfo(account) {
298
- if (account.signed_up_at !== null) {
299
- if (account.unsubscribed_at === null) {
300
- return { message: 'Paying Customer', iconClass: 'fas fa-dollar-sign money-icon' };
301
- }
302
- else {
303
- return {
304
- message: 'Old Customer',
305
- iconClass: 'fas fa-exclamation-triangle text-danger'
306
- };
307
- }
308
- }
309
- else if (account.child_subscription_id !== null) {
310
- return {
311
- message: 'Account with existing subscription',
312
- iconClass: 'fas fa-link account-link-icon'
313
- };
314
- }
315
- return { message: null, iconClass: null };
316
- }
317
- /** Function to call account activities */
318
- getAccountActivities() {
319
- this.crmService
320
- .getCrmAnalytics(this.subscription?.id, 'accounts_last_activities')
321
- .subscribe(response => {
322
- // API now returns { items: [], totals: {} } instead of array
323
- const items = response?.items || response;
324
- if (typeof items === 'object' && Object.keys(items).length === 0) {
325
- this.accountActivities = [];
326
- }
327
- else {
328
- this.accountActivities = Array.isArray(items) ? items : [];
329
- this.actionNames = this.accountActivities?.map(action => {
330
- return action?.crm_action?.name;
331
- });
332
- }
333
- });
334
- }
335
- getCountryFromLocation(location) {
336
- const parts = location?.split(',') || [];
337
- return parts[parts.length - 1]?.trim() || '';
338
- }
339
- getAccountLogo(url) {
340
- if (url) {
341
- return this.logoCacheService.getLogo(HelperService.getLogoByUrl(url));
342
- }
343
- return '';
344
- }
345
- getMainCurrency() {
346
- if (this.data?.accounts?.length > 0) {
347
- return this.data.accounts[0]?.main_currency || 'USD';
348
- }
349
- return 'USD';
350
- }
351
- ngOnDestroy() {
352
- super.ngOnDestroy();
353
- }
354
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SmartCrmCompaniesComponent, deps: [{ token: i1.CrmService }, { token: i2.CommonService }, { token: i2.LogoCacheService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
355
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: SmartCrmCompaniesComponent, selector: "pw-smart-crm-companies", usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Accounts</h2>\n <a class=\"btn btn-sm btn-outline-primary float-end\" data-cy=\"add-contact\"\n [routerLink]=\"['/' + subscription?.slug + routers.addAccount]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Crm.AccountMessage.AddAccount' | transloco }} </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n</div>\n<div class=\"primeng-datatable-container table-responsive\" [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #dt [value]=\"data.accounts\" [paginator]=\"data.object_count !== 0\" [lazy]=\"true\" [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\" [loading]=\"loading\" [filterDelay]=\"1000\" (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template pTemplate=\"caption\">\n <div class=\"row m-0\">\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Industry\" [options]=\"searchOptions\" [(ngModel)]=\"filterByIndustries\"\n (onChange)=\"onSearchOptionChange($event, 'industry')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Size\" [options]=\"organizationSizes\" [(ngModel)]=\"filterBySizeId\"\n (onChange)=\"onSearchOptionChange($event, 'size')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Status\" [options]=\"status\" [(ngModel)]=\"filterByStatus\"\n (onChange)=\"onSearchOptionChange($event, 'status')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Priority\" [options]=\"priority\" [(ngModel)]=\"filterByPriority\"\n (onChange)=\"onSearchOptionChange($event, 'priority')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Source\" [options]=\"source\" [(ngModel)]=\"filterBySource\"\n (onChange)=\"onSearchOptionChange($event, 'source')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4 mb-2\">\n <input ngx-gp-autocomplete class=\"form-control location\" #places=\"ngx-places\" [(ngModel)]=\"searchLocationText\"\n placeholder=\"Search location...\" (keyup)=\"locationSearch($event)\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </div>\n </div>\n <div class=\"search-filter\">\n <a class=\"mt-3 ms-3 text-start btn-filter-primary\" (click)=\"clearFilters()\">Clear all filters</a>\n <div class=\"text-end mt-0 mt-sm-3\">\n <i class=\"fa fa-search mt-2 me-2\" aria-hidden=\"true\"></i>\n <input type=\"text\" [(ngModel)]=\"searchText\" pInputText size=\"50\" placeholder=\"Search accounts...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\" class=\"mw-90\" />\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\" pSortableColumn=\"name\"> {{ 'Crm.AccountMessage.Name' | transloco }} <p-sortIcon field=\"name\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"location\"> {{ 'Crm.AccountMessage.Location' | transloco }} <p-sortIcon\n field=\"location\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"owner_id\"> {{ 'Crm.AccountMessage.Owner' | transloco }} <p-sortIcon\n field=\"owner_id\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"organization_size_id\"> {{ 'Crm.AccountMessage.Size' | transloco }} <p-sortIcon\n field=\"organization_size_id\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"expected_mrr\" class=\"mrr-header\"> {{ 'Crm.AccountMessage.MRR' | transloco }} <p-sortIcon field=\"expected_mrr\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"signed_up_at\"> {{ 'Crm.AccountMessage.SignUpAt' | transloco }} <p-sortIcon field=\"signed_up_at\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"sessions_last_quarter\"> {{ 'Crm.AccountMessage.Quarter' | transloco }} <p-sortIcon field=\"sessions_last_quarter\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"sessions_last_month\"> {{ 'Crm.AccountMessage.Month' | transloco }} <p-sortIcon field=\"sessions_last_month\">\n </p-sortIcon>\n <th scope=\"true\" pSortableColumn=\"status\"> {{ 'Crm.AccountMessage.Status' | transloco }} <p-sortIcon field=\"status\">\n </p-sortIcon>\n <th scope=\"true\" pSortableColumn=\"priority\"> {{ 'Crm.AccountMessage.Priority' | transloco }} <p-sortIcon field=\"priority\">\n </p-sortIcon>\n </th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-account let-i=\"rowIndex\">\n <!-- Totals row at the top (first row) - show before first data row -->\n <ng-container *ngIf=\"i === 0 && data?.accounts?.length\">\n <tr class=\"totals-row \">\n <td></td>\n <td></td>\n <td></td>\n <td></td>\n <td class=\"fw-bold expected-mrr\">\n <strong>{{ totals?.total_mrr / 100 | currency: 'USD' }}</strong>\n </td>\n <td></td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_quarter }}</strong>\n </td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_month }}</strong>\n </td>\n <td></td>\n <td></td>\n <td></td>\n </tr>\n </ng-container>\n <!-- Regular data row -->\n <tr>\n <td data-head=\"Name\" class=\"name-column\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.accountInfo, account.id]\" class=\"name-link\">\n <img alt=\"Company Logo\" [src]=\"getAccountLogo(account.company_url)\" class=\"img-fluid company-logo me-2\"\n (error)=\"handleImageError($event, 'assets/img/icons/company.png')\" />\n <span [ngbTooltip]=\"account.name\" class=\"account-name\" [title]=\"account.name\">{{ account.name | textTruncate:30 }}</span>\n <i [ngClass]=\"getUserAccountInfo(account).iconClass\" [ngbTooltip]=\"getUserAccountInfo(account).message\"\n class=\"info-icon\"></i>\n <i class=\"fas fa-exclamation-circle text-danger info-icon\"\n *ngIf=\"account?.reason_to_cancel\"\n [pTooltip]=\"account.reason_to_cancel\"\n tooltipPosition=\"top\"></i>\n </a>\n </td>\n <td data-head=\"Location\" class=\"no-wrap\"><span [ngbTooltip]=\"account.location\">{{ getCountryFromLocation(account.location) }}</span></td>\n <td data-head=\"Owner\">\n <a [routerLink]=\"['/members', account?.owner?.slug]\"> {{ account.owner.first_name.charAt(0) }}. {{account.owner.last_name}}</a>\n </td>\n <td data-head=\"Size\" class=\"no-wrap\">{{ account?.organisation_size?.name !== 'Not available' ? account?.organisation_size?.name : '' }}\n</td>\n<td data-head=\"MRR\" class=\"no-wrap fw-bold expected-mrr\" >\n <span *ngIf=\"account.expected_mrr && (hasAccess || account.owner_id === userId)\">\n {{ account.expected_mrr / 100 | currency: account.main_currency }}\n </span>\n</td>\n <td data-head=\"Signed Up\">{{ account.signed_up_at | date: 'dd-MMM-YYYY' }}</td>\n <td data-head=\"Quarter\" [ngClass]=\"{'month-quarter-text fw-bold': account.sessions_last_quarter > 15}\">{{ account.sessions_last_quarter }}</td>\n <td data-head=\"Month\" [ngClass]=\"{'month-quarter-text fw-bold': account.sessions_last_quarter > 5}\">{{ account.sessions_last_month }}</td>\n <td data-head=\"Status\">\n <span *ngIf=\"account.status === 'Prospect'\" class=\"badge bg-primary\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Trial - Active'\" class=\"badge bg-success\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Trial - Inactive'\" class=\"badge bg-secondary\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - New'\" class=\"badge bg-info\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Active'\" class=\"badge bg-success\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Inactive'\" class=\"badge bg-warning\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Old'\" class=\"badge bg-dark\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Dead'\" class=\"badge bg-danger\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Competitor'\" class=\"badge bg-danger\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Vendor'\" class=\"badge bg-blue-grey\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Supplier'\" class=\"badge bg-blue-grey\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Other'\" class=\"badge bg-teal\">{{account.status}}</span>\n </td>\n\n <td data-head=\"Priority\">\n <span *ngIf=\"account.priority === 'A - Ideal Fit'\" class=\"badge bg-success\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'B - High Potential'\" class=\"badge bg-primary\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'C - Low Potential'\" class=\"badge bg-warning\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'D - Out of market'\" class=\"badge bg-secondary\">{{account.priority}}</span>\n </td>\n\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li ngbTooltip=\"See contacts\" class=\"me-2 me-sm-3 see-icon\"\n [routerLink]=\"['/' + subscription?.slug + routers.accountContacts, account.id]\">\n <i class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n </li>\n <ng-container *ngIf=\"hasAccess || account.owner_id === userId\">\n <li ngbTooltip=\"Edit\" class=\"me-2 me-sm-3\" [routerLink]=\"[\n '/' + subscription?.slug + routers.accounts,\n account.id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li ngbTooltip=\"Delete\" class=\"me-2 me-sm-3\">\n <i class=\"fa fa-trash delete-icon\" (keydown.enter)=\"onDelete(account.id, subscription.id)\"\n (keydown.space)=\"onDelete(account.id, subscription.id)\"\n (click)=\"onDelete(account.id, subscription.id)\"\n aria-hidden=\"true\"></i>\n </li>\n </ng-container>\n </ul>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"footer\">\n <tr *ngIf=\"data?.accounts?.length\">\n <td></td>\n <td></td>\n <td></td>\n <td></td>\n <td class=\"expected-mrr\">\n <strong>{{ totals?.total_mrr / 100 | currency: 'USD' }}</strong>\n </td>\n <td></td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_quarter }}</strong>\n </td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_month }}</strong>\n </td>\n <td></td>\n <td></td>\n <td></td>\n </tr>\n </ng-template>\n </p-table>\n<div *ngIf=\"data.object_count === 0 && data.unfiltered_count !== 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n</div>\n <span class=\"total-records-count\" *ngIf=\"data.object_count !== 0\">{{ 'Label.Total' | transloco }}: {{ data.object_count }}</span>\n</div>\n<div *ngIf=\"data.unfiltered_count === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoAccountMessage' | transloco\"> </pw-no-data>\n</div>\n<ng-container>\n <div class=\"row mt-5\" *ngIf=\"data.unfiltered_count !== 0 && isLoaded\">\n <!-- Last Activities -->\n <div class=\"col-12 col-md-6 mb-3 analytics\">\n <h5 class=\"accordion-heading\">Latest Activities</h5>\n <div class=\"primeng-datatable-container table-responsive\" *ngIf=\"accountActivities?.length\">\n <p-table class=\"table\" #dt [value]=\"accountActivities\" [paginator]=\"accountInsight?.length !== 0\" [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"accountActivities.length\" [lazy]=\"true\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Owner' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Account' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Contact' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Action' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.When' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-activities>\n <tr>\n <td data-head=\"Owner\"> {{ activities.owner?.first_name.charAt(0) }}. {{ activities.owner?.last_name }} </td>\n <td data-head=\"Account\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.accountInfo, activities.crm_account_id]\" class=\"name-link\">\n <span [ngbTooltip]=\"activities.crm_account?.name\">{{ activities.crm_account?.name }}</span>\n </a>\n </td>\n <td data-head=\"Contact\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.contactInfo, activities.crm_contact_id]\" class=\"name-link\">\n <span [ngbTooltip]=\"activities.crm_contact ? activities.crm_contact.first_name + ' ' + activities.crm_contact.last_name : ''\">{{ (activities.crm_contact?.first_name + ' ' + activities.crm_contact?.last_name) | textTruncate:20 }}</span>\n </a>\n </td>\n <td data-head=\"Action\">\n <span [ngbTooltip]=\"activities.comment\" [appDynamicBadge]=\"{\n itemsArray: actionNames,\n item: activities.crm_action?.name\n }\"\n color=\"blue-grey\"\n class=\"badge\">{{ activities.crm_action?.name }}</span>\n </td>\n <td data-head=\"When\">{{ activities.when | date:'dd-MMM-YYYY' }}</td>\n </tr>\n </ng-template>\n </p-table>\n <span class=\"total-records-count\" *ngIf=\"accountInsight?.length !== 0\">{{ 'Label.Total' | transloco }}: {{ accountActivities.length }}</span>\n </div>\n <div *ngIf=\"accountActivities?.length === 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoInsightMessage' | transloco\">\n </pw-no-data>\n </div>\n </div>\n <!-- Geography -->\n <div class=\"col-12 col-md-6 mb-3 analytics\">\n <h5 class=\"accordion-heading\">Accounts Location</h5>\n <div>\n <ng-template [ngIf]=\"accountGeography\">\n <plotly-plot [data]=\"accountGeography?.data\" [layout]=\"accountGeography?.layout\" [config]=\"accountGeography?.config\" [useResizeHandler]=\"accountGeography ? true : false\">\n </plotly-plot>\n </ng-template>\n </div>\n <div *ngIf=\"!accountGeography\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoInsightMessage' | transloco\">\n </pw-no-data>\n </div>\n </div>\n </div>\n</ng-container>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.location{background-color:#fff}.company-logo{height:20px;width:20px}::ng-deep .ui-multiselect{display:inline-block}::ng-deep body .ui-multiselect .ui-multiselect-label{font-weight:700}.name-column{text-align:left}.account-name{margin-right:5px}.info-icon{vertical-align:middle;margin-left:5px}.account-link-icon{color:gray}.money-icon{color:green;font-size:.85em;background-color:#90ee90;border-radius:50%;padding:5px;width:18.5px;box-shadow:0 0 10px #00800080}.icon-ul{width:111px}.no-wrap{word-break:keep-all;white-space:pre-line}.totals-row{background-color:#f8f9fa;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i6.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i7.DynamicBadgeDirective, selector: "[appDynamicBadge]", inputs: ["appDynamicBadge", "color", "colorByName", "dataName"] }, { kind: "directive", type: i7.LazyImgDirective, selector: "img" }, { kind: "component", type: i8.PlotlyComponent, selector: "plotly-plot", inputs: ["data", "layout", "config", "frames", "style", "theme", "divId", "revision", "className", "debug", "useResizeHandler", "updateOnLayoutChange", "updateOnDataChange", "updateOnlyWithRevision"], outputs: ["initialized", "update", "purge", "error", "afterExport", "afterPlot", "animated", "animatingFrame", "animationInterrupted", "autoSize", "beforeExport", "beforeHover", "buttonClicked", "click", "plotlyClick", "clickAnnotation", "deselect", "doubleClick", "framework", "hover", "legendClick", "legendDoubleClick", "react", "relayout", "relayouting", "restyle", "redraw", "selected", "selecting", "sliderChange", "sliderEnd", "sliderStart", "sunburstclick", "transitioning", "transitionInterrupted", "unhover", "treemapclick", "webglcontextlost"] }, { kind: "directive", type: i9.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "directive", type: i10.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i11.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i12.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i11.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i11.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i13.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i14.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i15.ProgressSpinner, selector: "p-progressSpinner", inputs: ["styleClass", "style", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i16.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i3.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: i17.TextTruncatePipe, name: "textTruncate" }, { kind: "pipe", type: i18.TranslocoPipe, name: "transloco" }] }); }
356
- }
357
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SmartCrmCompaniesComponent, decorators: [{
358
- type: Component,
359
- args: [{ selector: 'pw-smart-crm-companies', template: "<div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Accounts</h2>\n <a class=\"btn btn-sm btn-outline-primary float-end\" data-cy=\"add-contact\"\n [routerLink]=\"['/' + subscription?.slug + routers.addAccount]\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Crm.AccountMessage.AddAccount' | transloco }} </a>\n </div>\n</div>\n<div class=\"w-100 text-center mt-3\" *ngIf=\"!isLoaded\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n</div>\n<div class=\"primeng-datatable-container table-responsive\" [class.hideTable]=\"data.unfiltered_count === 0\">\n <p-table #dt [value]=\"data.accounts\" [paginator]=\"data.object_count !== 0\" [lazy]=\"true\" [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"data.object_count\" [loading]=\"loading\" [filterDelay]=\"1000\" (onLazyLoad)=\"onLazyLoad($event)\"\n [customSort]=\"true\">\n <ng-template pTemplate=\"caption\">\n <div class=\"row m-0\">\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Industry\" [options]=\"searchOptions\" [(ngModel)]=\"filterByIndustries\"\n (onChange)=\"onSearchOptionChange($event, 'industry')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Size\" [options]=\"organizationSizes\" [(ngModel)]=\"filterBySizeId\"\n (onChange)=\"onSearchOptionChange($event, 'size')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Status\" [options]=\"status\" [(ngModel)]=\"filterByStatus\"\n (onChange)=\"onSearchOptionChange($event, 'status')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Priority\" [options]=\"priority\" [(ngModel)]=\"filterByPriority\"\n (onChange)=\"onSearchOptionChange($event, 'priority')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4\">\n <p-multiSelect placeholder=\"Select Source\" [options]=\"source\" [(ngModel)]=\"filterBySource\"\n (onChange)=\"onSearchOptionChange($event, 'source')\" [filter]=\"true\" [showHeader]=\"true\"\n [showToggleAll]=\"true\" appendTo=\"body\">\n </p-multiSelect>\n </div>\n <div class=\"col-sm-4 mb-2\">\n <input ngx-gp-autocomplete class=\"form-control location\" #places=\"ngx-places\" [(ngModel)]=\"searchLocationText\"\n placeholder=\"Search location...\" (keyup)=\"locationSearch($event)\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </div>\n </div>\n <div class=\"search-filter\">\n <a class=\"mt-3 ms-3 text-start btn-filter-primary\" (click)=\"clearFilters()\">Clear all filters</a>\n <div class=\"text-end mt-0 mt-sm-3\">\n <i class=\"fa fa-search mt-2 me-2\" aria-hidden=\"true\"></i>\n <input type=\"text\" [(ngModel)]=\"searchText\" pInputText size=\"50\" placeholder=\"Search accounts...\"\n (input)=\"dt.filterGlobal($event.target.value, 'contains')\" class=\"mw-90\" />\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\" pSortableColumn=\"name\"> {{ 'Crm.AccountMessage.Name' | transloco }} <p-sortIcon field=\"name\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"location\"> {{ 'Crm.AccountMessage.Location' | transloco }} <p-sortIcon\n field=\"location\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"owner_id\"> {{ 'Crm.AccountMessage.Owner' | transloco }} <p-sortIcon\n field=\"owner_id\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"organization_size_id\"> {{ 'Crm.AccountMessage.Size' | transloco }} <p-sortIcon\n field=\"organization_size_id\"></p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"expected_mrr\" class=\"mrr-header\"> {{ 'Crm.AccountMessage.MRR' | transloco }} <p-sortIcon field=\"expected_mrr\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"signed_up_at\"> {{ 'Crm.AccountMessage.SignUpAt' | transloco }} <p-sortIcon field=\"signed_up_at\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"sessions_last_quarter\"> {{ 'Crm.AccountMessage.Quarter' | transloco }} <p-sortIcon field=\"sessions_last_quarter\">\n </p-sortIcon>\n </th>\n <th scope=\"true\" pSortableColumn=\"sessions_last_month\"> {{ 'Crm.AccountMessage.Month' | transloco }} <p-sortIcon field=\"sessions_last_month\">\n </p-sortIcon>\n <th scope=\"true\" pSortableColumn=\"status\"> {{ 'Crm.AccountMessage.Status' | transloco }} <p-sortIcon field=\"status\">\n </p-sortIcon>\n <th scope=\"true\" pSortableColumn=\"priority\"> {{ 'Crm.AccountMessage.Priority' | transloco }} <p-sortIcon field=\"priority\">\n </p-sortIcon>\n </th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-account let-i=\"rowIndex\">\n <!-- Totals row at the top (first row) - show before first data row -->\n <ng-container *ngIf=\"i === 0 && data?.accounts?.length\">\n <tr class=\"totals-row \">\n <td></td>\n <td></td>\n <td></td>\n <td></td>\n <td class=\"fw-bold expected-mrr\">\n <strong>{{ totals?.total_mrr / 100 | currency: 'USD' }}</strong>\n </td>\n <td></td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_quarter }}</strong>\n </td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_month }}</strong>\n </td>\n <td></td>\n <td></td>\n <td></td>\n </tr>\n </ng-container>\n <!-- Regular data row -->\n <tr>\n <td data-head=\"Name\" class=\"name-column\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.accountInfo, account.id]\" class=\"name-link\">\n <img alt=\"Company Logo\" [src]=\"getAccountLogo(account.company_url)\" class=\"img-fluid company-logo me-2\"\n (error)=\"handleImageError($event, 'assets/img/icons/company.png')\" />\n <span [ngbTooltip]=\"account.name\" class=\"account-name\" [title]=\"account.name\">{{ account.name | textTruncate:30 }}</span>\n <i [ngClass]=\"getUserAccountInfo(account).iconClass\" [ngbTooltip]=\"getUserAccountInfo(account).message\"\n class=\"info-icon\"></i>\n <i class=\"fas fa-exclamation-circle text-danger info-icon\"\n *ngIf=\"account?.reason_to_cancel\"\n [pTooltip]=\"account.reason_to_cancel\"\n tooltipPosition=\"top\"></i>\n </a>\n </td>\n <td data-head=\"Location\" class=\"no-wrap\"><span [ngbTooltip]=\"account.location\">{{ getCountryFromLocation(account.location) }}</span></td>\n <td data-head=\"Owner\">\n <a [routerLink]=\"['/members', account?.owner?.slug]\"> {{ account.owner.first_name.charAt(0) }}. {{account.owner.last_name}}</a>\n </td>\n <td data-head=\"Size\" class=\"no-wrap\">{{ account?.organisation_size?.name !== 'Not available' ? account?.organisation_size?.name : '' }}\n</td>\n<td data-head=\"MRR\" class=\"no-wrap fw-bold expected-mrr\" >\n <span *ngIf=\"account.expected_mrr && (hasAccess || account.owner_id === userId)\">\n {{ account.expected_mrr / 100 | currency: account.main_currency }}\n </span>\n</td>\n <td data-head=\"Signed Up\">{{ account.signed_up_at | date: 'dd-MMM-YYYY' }}</td>\n <td data-head=\"Quarter\" [ngClass]=\"{'month-quarter-text fw-bold': account.sessions_last_quarter > 15}\">{{ account.sessions_last_quarter }}</td>\n <td data-head=\"Month\" [ngClass]=\"{'month-quarter-text fw-bold': account.sessions_last_quarter > 5}\">{{ account.sessions_last_month }}</td>\n <td data-head=\"Status\">\n <span *ngIf=\"account.status === 'Prospect'\" class=\"badge bg-primary\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Trial - Active'\" class=\"badge bg-success\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Trial - Inactive'\" class=\"badge bg-secondary\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - New'\" class=\"badge bg-info\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Active'\" class=\"badge bg-success\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Inactive'\" class=\"badge bg-warning\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Customer - Old'\" class=\"badge bg-dark\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Dead'\" class=\"badge bg-danger\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Competitor'\" class=\"badge bg-danger\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Vendor'\" class=\"badge bg-blue-grey\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Supplier'\" class=\"badge bg-blue-grey\">{{account.status}}</span>\n <span *ngIf=\"account.status === 'Other'\" class=\"badge bg-teal\">{{account.status}}</span>\n </td>\n\n <td data-head=\"Priority\">\n <span *ngIf=\"account.priority === 'A - Ideal Fit'\" class=\"badge bg-success\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'B - High Potential'\" class=\"badge bg-primary\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'C - Low Potential'\" class=\"badge bg-warning\">{{account.priority}}</span>\n <span *ngIf=\"account.priority === 'D - Out of market'\" class=\"badge bg-secondary\">{{account.priority}}</span>\n </td>\n\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n <li ngbTooltip=\"See contacts\" class=\"me-2 me-sm-3 see-icon\"\n [routerLink]=\"['/' + subscription?.slug + routers.accountContacts, account.id]\">\n <i class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n </li>\n <ng-container *ngIf=\"hasAccess || account.owner_id === userId\">\n <li ngbTooltip=\"Edit\" class=\"me-2 me-sm-3\" [routerLink]=\"[\n '/' + subscription?.slug + routers.accounts,\n account.id\n ]\">\n <i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i>\n </li>\n <li ngbTooltip=\"Delete\" class=\"me-2 me-sm-3\">\n <i class=\"fa fa-trash delete-icon\" (keydown.enter)=\"onDelete(account.id, subscription.id)\"\n (keydown.space)=\"onDelete(account.id, subscription.id)\"\n (click)=\"onDelete(account.id, subscription.id)\"\n aria-hidden=\"true\"></i>\n </li>\n </ng-container>\n </ul>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"footer\">\n <tr *ngIf=\"data?.accounts?.length\">\n <td></td>\n <td></td>\n <td></td>\n <td></td>\n <td class=\"expected-mrr\">\n <strong>{{ totals?.total_mrr / 100 | currency: 'USD' }}</strong>\n </td>\n <td></td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_quarter }}</strong>\n </td>\n <td class=\"fw-bold\">\n <strong>{{ totals?.sessions_last_month }}</strong>\n </td>\n <td></td>\n <td></td>\n <td></td>\n </tr>\n </ng-template>\n </p-table>\n<div *ngIf=\"data.object_count === 0 && data.unfiltered_count !== 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n</div>\n <span class=\"total-records-count\" *ngIf=\"data.object_count !== 0\">{{ 'Label.Total' | transloco }}: {{ data.object_count }}</span>\n</div>\n<div *ngIf=\"data.unfiltered_count === 0 && isLoaded\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoAccountMessage' | transloco\"> </pw-no-data>\n</div>\n<ng-container>\n <div class=\"row mt-5\" *ngIf=\"data.unfiltered_count !== 0 && isLoaded\">\n <!-- Last Activities -->\n <div class=\"col-12 col-md-6 mb-3 analytics\">\n <h5 class=\"accordion-heading\">Latest Activities</h5>\n <div class=\"primeng-datatable-container table-responsive\" *ngIf=\"accountActivities?.length\">\n <p-table class=\"table\" #dt [value]=\"accountActivities\" [paginator]=\"accountInsight?.length !== 0\" [rows]=\"PAGE_SIZE\"\n [totalRecords]=\"accountActivities.length\" [lazy]=\"true\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Owner' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Account' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Contact' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.Action' | transloco }}</th>\n <th scope=\"true\">{{ 'Crm.AccountMessage.When' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-activities>\n <tr>\n <td data-head=\"Owner\"> {{ activities.owner?.first_name.charAt(0) }}. {{ activities.owner?.last_name }} </td>\n <td data-head=\"Account\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.accountInfo, activities.crm_account_id]\" class=\"name-link\">\n <span [ngbTooltip]=\"activities.crm_account?.name\">{{ activities.crm_account?.name }}</span>\n </a>\n </td>\n <td data-head=\"Contact\">\n <a [routerLink]=\"['/' + subscription?.slug + routers.contactInfo, activities.crm_contact_id]\" class=\"name-link\">\n <span [ngbTooltip]=\"activities.crm_contact ? activities.crm_contact.first_name + ' ' + activities.crm_contact.last_name : ''\">{{ (activities.crm_contact?.first_name + ' ' + activities.crm_contact?.last_name) | textTruncate:20 }}</span>\n </a>\n </td>\n <td data-head=\"Action\">\n <span [ngbTooltip]=\"activities.comment\" [appDynamicBadge]=\"{\n itemsArray: actionNames,\n item: activities.crm_action?.name\n }\"\n color=\"blue-grey\"\n class=\"badge\">{{ activities.crm_action?.name }}</span>\n </td>\n <td data-head=\"When\">{{ activities.when | date:'dd-MMM-YYYY' }}</td>\n </tr>\n </ng-template>\n </p-table>\n <span class=\"total-records-count\" *ngIf=\"accountInsight?.length !== 0\">{{ 'Label.Total' | transloco }}: {{ accountActivities.length }}</span>\n </div>\n <div *ngIf=\"accountActivities?.length === 0\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoInsightMessage' | transloco\">\n </pw-no-data>\n </div>\n </div>\n <!-- Geography -->\n <div class=\"col-12 col-md-6 mb-3 analytics\">\n <h5 class=\"accordion-heading\">Accounts Location</h5>\n <div>\n <ng-template [ngIf]=\"accountGeography\">\n <plotly-plot [data]=\"accountGeography?.data\" [layout]=\"accountGeography?.layout\" [config]=\"accountGeography?.config\" [useResizeHandler]=\"accountGeography ? true : false\">\n </plotly-plot>\n </ng-template>\n </div>\n <div *ngIf=\"!accountGeography\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Crm.AccountMessage.NoInsightMessage' | transloco\">\n </pw-no-data>\n </div>\n </div>\n </div>\n</ng-container>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.location{background-color:#fff}.company-logo{height:20px;width:20px}::ng-deep .ui-multiselect{display:inline-block}::ng-deep body .ui-multiselect .ui-multiselect-label{font-weight:700}.name-column{text-align:left}.account-name{margin-right:5px}.info-icon{vertical-align:middle;margin-left:5px}.account-link-icon{color:gray}.money-icon{color:green;font-size:.85em;background-color:#90ee90;border-radius:50%;padding:5px;width:18.5px;box-shadow:0 0 10px #00800080}.icon-ul{width:111px}.no-wrap{word-break:keep-all;white-space:pre-line}.totals-row{background-color:#f8f9fa;font-weight:700}\n"] }]
360
- }], ctorParameters: () => [{ type: i1.CrmService }, { type: i2.CommonService }, { type: i2.LogoCacheService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
361
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnQtY3JtLWFjY291bnRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc21hcnQtY3JtL3NyYy9saWIvcHJpdmF0ZS9jb21wb25lbnRzL3NtYXJ0LWNybS1hY2NvdW50cy9zbWFydC1jcm0tYWNjb3VudHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9zbWFydC1jcm0vc3JjL2xpYi9wcml2YXRlL2NvbXBvbmVudHMvc21hcnQtY3JtLWFjY291bnRzL3NtYXJ0LWNybS1hY2NvdW50cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUgsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxRQUFRLEVBR1gsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxTQUFTLEVBQWdDLE1BQU0sNEJBQTRCLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQVV4RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTzFELE1BQU0sT0FBTywwQkFDVCxTQUFRLGdCQUFnQjtJQStDeEIsWUFDcUIsVUFBc0IsRUFDdEIsYUFBNEIsRUFDNUIsZ0JBQWtDLEVBQ25ELFFBQWtCLEVBQ0QsR0FBc0I7UUFFdkMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBTkMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixxQkFBZ0IsR0FB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QyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsSUFBSSxLQUFLLENBQUM7UUFDekQsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFUSxXQUFXO1FBQ2hCLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN4QixDQUFDOytHQWpYUSwwQkFBMEI7bUdBQTFCLDBCQUEwQixxRkM5QnZDLDQzZ0JBaVNBOzs0RkRuUWEsMEJBQTBCO2tCQUx0QyxTQUFTOytCQUNJLHdCQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQWZ0ZXJWaWV3Q2hlY2tlZCxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgSW5qZWN0b3IsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQXBwQmFzZUNvbXBvbmVudCB9IGZyb20gJ0Bwb3Npd2lzZS9hcHAtYmFzZS1jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tbW9uU2VydmljZSwgTG9nb0NhY2hlU2VydmljZSB9IGZyb20gJ0Bwb3Npd2lzZS9jb21tb24tc2VydmljZXMnO1xuaW1wb3J0IHsgUEFHRV9TSVpFLCBQYWdpbmcsIFBsb3RseSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAnQHBvc2l3aXNlL2NvbW1vbi11dGlsaXRpZXMnO1xuaW1wb3J0IHsgSGVscGVyU2VydmljZSB9IGZyb20gJ0Bwb3Npd2lzZS9oZWxwZXItc2VydmljZSc7XG5pbXBvcnQgeyBDcm1TZXJ2aWNlIH0gZnJvbSAnQHBvc2l3aXNlL3NtYXJ0LWNybS1zaGFyZWQnO1xuXG5pbXBvcnQgeyBMYXp5TG9hZEV2ZW50IH0gZnJvbSAncHJpbWVuZy9hcGknO1xuXG5pbXBvcnQgeyBDcm1BY2NvdW50UmVzcG9uc2UgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvaW50ZXJmYWNlL2NybS1hY2NvdW50LmludGVyZmFjZSc7XG5pbXBvcnQge1xuICAgIE9wcG9ydHVuaXR5Q2F0ZWdvcnksXG4gICAgT3JnYW5pemF0aW9uVHlwZSxcbiAgICBVc2VyQWNjb3VudFxufSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvaW50ZXJmYWNlL3NtYXJ0LWNybS1tb2R1bGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJPVVRFUlMgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvcm91dGVycy9yb3V0ZXJzJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwdy1zbWFydC1jcm0tY29tcGFuaWVzJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc21hcnQtY3JtLWFjY291bnRzLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zbWFydC1jcm0tYWNjb3VudHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBTbWFydENybUNvbXBhbmllc0NvbXBvbmVudFxuICAgIGV4dGVuZHMgQXBwQmFzZUNvbXBvbmVudFxuICAgIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0NoZWNrZWRcbntcbiAgICBwcml2YXRlIHBhZ2UgPSAxO1xuICAgIHByaXZhdGUgYWxsSW5kdXN0cmllczogT3JnYW5pemF0aW9uVHlwZVtdO1xuICAgIHByaXZhdGUgZmlsdGVyQnlMb2NhdGlvbjogc3RyaW5nO1xuXG4gICAgZGF0YTogQ3JtQWNjb3VudFJlc3BvbnNlID0ge1xuICAgICAgICBhY2NvdW50czogW10sXG4gICAgICAgIG9iamVjdF9jb3VudDogMCxcbiAgICAgICAgdW5maWx0ZXJlZF9jb3VudDogMFxuICAgIH07XG5cbiAgICB0b3RhbHMgPSB7XG4gICAgICAgIHRvdGFsX21ycjogMCxcbiAgICAgICAgc2Vzc2lvbnNfbGFzdF9tb250aDogMCxcbiAgICAgICAgc2Vzc2lvbnNfbGFzdF9xdWFydGVyOiAwXG4gICAgfTtcblxuICAgIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIHN1YnNjcmlwdGlvbklkOiBudW1iZXI7XG4gICAgdXNlcklkOiBudW1iZXI7XG5cbiAgICBvcmdhbml6YXRpb25TaXplcyA9IFtdO1xuICAgIHNlYXJjaE9wdGlvbnM6IE9wcG9ydHVuaXR5Q2F0ZWdvcnlbXSA9IFtdO1xuICAgIGZpbHRlckJ5SW5kdXN0cmllcyA9IFtdO1xuICAgIHN0YXR1cyA9IFtdO1xuICAgIHByaW9yaXR5ID0gW107XG4gICAgc291cmNlID0gW107XG4gICAgZmlsdGVyQnlTb3VyY2UgPSBbXTtcbiAgICBmaWx0ZXJCeVN0YXR1cyA9IFtdO1xuICAgIGZpbHRlckJ5UHJpb3JpdHkgPSBbXTtcbiAgICBmaWx0ZXJCeVNpemVJZCA9IFtdO1xuXG4gICAgc2VhcmNoVGV4dCA9ICcnO1xuICAgIHNlYXJjaExvY2F0aW9uVGV4dDogc3RyaW5nO1xuXG4gICAgYWNjb3VudEdlb2dyYXBoeTogUGxvdGx5LkZpZ3VyZTtcbiAgICBhY2NvdW50QWN0aXZpdGllcyA9IFtdO1xuXG4gICAgbG9hZGluZyA9IHRydWU7XG4gICAgaGFzQWNjZXNzID0gZmFsc2U7XG4gICAgaXNMb2FkZWQgPSBmYWxzZTtcblxuICAgIHJvdXRlcnMgPSBST1VURVJTO1xuICAgIGFjdGlvbk5hbWVzID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBjcm1TZXJ2aWNlOiBDcm1TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGNvbW1vblNlcnZpY2U6IENvbW1vblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nb0NhY2hlU2VydmljZTogTG9nb0NhY2hlU2VydmljZSxcbiAgICAgICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgICApIHtcbiAgICAgICAgc3VwZXIoaW5qZWN0b3IpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmdldFVzZXJTdWJzY3JpcHRpb24oKS5zdWJzY3JpYmUocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSByZXNwb25zZTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbj8uaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY291bnREZWZhdWx0VmFsdWVzKHRoaXMuc3Vic2NyaXB0aW9uLmlkKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhc0FjY2VzcyA9IHRoaXMuaGFzQWRtaW5BY2Nlc3ModGhpcy5zdWJzY3JpcHRpb24uaWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2V0VXNlckluZm8oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2V0SW5kdXN0cmllcygpO1xuICAgICAgICB0aGlzLmdldEFsbE9yZ2FuaXphdGlvblNpemUoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0NoZWNrZWQoKSB7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBvbkxhenlMb2FkKGV2ZW50OiBMYXp5TG9hZEV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHBhZ2VEZXRhaWxzID0gSGVscGVyU2VydmljZS5vblRhYmxlTGF6eUxvYWQoZXZlbnQpO1xuICAgICAgICB0aGlzLnBhZ2UgPSBwYWdlRGV0YWlscy5wYWdlO1xuICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZSxcbiAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFLFxuICAgICAgICAgICAgb3JkZXJfYnk6IHBhZ2VEZXRhaWxzLnNvcnRGaWVsZCxcbiAgICAgICAgICAgIG9yZGVyX2RpcmVjdGlvbjogcGFnZURldGFpbHMuc29ydE9yZGVyLFxuICAgICAgICAgICAgc2VhcmNoOiB0aGlzLnNlYXJjaFRleHRcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqIEZ1bmN0aW9uIHRvIGdldCB1c2VyIGRldGFpbHMgKi9cbiAgICBwcml2YXRlIGdldFVzZXJJbmZvKCkge1xuICAgICAgICB0aGlzLnVzZXJTdG9yZSgpLnN1YnNjcmliZSh1c2VyID0+IHtcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51c2VySWQgPSB1c2VyPy5pZDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wZXJtaXNzaW9uU2VydmljZS5pc0dyYW50ZWQoJ1BhZ2VzLkJldGEnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldEFjY291bnRHZW9ncmFwaHkoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRBY2NvdW50QWN0aXZpdGllcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaGFuZGxlSW1hZ2VFcnJvcihldmVudDogRXZlbnQsIGZhbGxiYWNrUGF0aCk6IHZvaWQge1xuICAgICAgICBIZWxwZXJTZXJ2aWNlLmhhbmRsZUltYWdlRmFsbGJhY2tQYXRoKGV2ZW50LCBmYWxsYmFja1BhdGgpO1xuICAgIH1cblxuICAgIC8qKiBGdW5jdGlvbiB0byBjYWxsIGFjY291bnQgZGVmYXVsdCB2YWx1ZXMgKi9cbiAgICBwcml2YXRlIGFjY291bnREZWZhdWx0VmFsdWVzKGlkOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5jcm1TZXJ2aWNlLmdldENybUFjY291bnREZWZhdWx0VmFsdWVzKGlkKS5zdWJzY3JpYmUocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBzdGF0dXMgfSA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgc3RhdHVzLmZvckVhY2godmFsID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogdmFsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXR1cy5wdXNoKGRhdGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB7IHByaW9yaXR5IH0gPSByZXNwb25zZTtcbiAgICAgICAgICAgIHByaW9yaXR5LmZvckVhY2godmFsID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogdmFsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnByaW9yaXR5LnB1c2goZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHsgc291cmNlIH0gPSByZXNwb25zZTtcbiAgICAgICAgICAgIHNvdXJjZS5mb3JFYWNoKHZhbCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHZhbC5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsLmlkXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZS5wdXNoKGRhdGEpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiBGdW5jdGlvbiB0byBnZXQgdGhlIGFjY291bnRzIGxpc3QgKi9cbiAgICBwcml2YXRlIGdldEFsbEFjY291bnRzKHBhZ2luZzogUGFnaW5nKSB7XG4gICAgICAgIHRoaXMuZGF0YS5hY2NvdW50cyA9IFtdO1xuXG4gICAgICAgIHRoaXMuZ2V0VXNlclN1YnNjcmlwdGlvbklkKCkuc3Vic2NyaWJlKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uSWQgPSByZXNwb25zZTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcm1TZXJ2aWNlXG4gICAgICAgICAgICAgICAgICAgIC5nZXRBbGxBY2NvdW50cyh7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25faWQ6IHRoaXMuc3Vic2NyaXB0aW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWdpbmc6IHBhZ2luZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZHVzdHJ5OiB0aGlzLmZpbHRlckJ5SW5kdXN0cmllcy5qb2luKCkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiB0aGlzLmZpbHRlckJ5U2l6ZUlkLmpvaW4oKSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogdGhpcy5maWx0ZXJCeVN0YXR1cy5qb2luKCkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmlvcml0eTogdGhpcy5maWx0ZXJCeVByaW9yaXR5LmpvaW4oKSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZTogdGhpcy5maWx0ZXJCeVNvdXJjZS5qb2luKCkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbjogdGhpcy5maWx0ZXJCeUxvY2F0aW9uIHx8ICcnXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IHJlcztcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFwIHRvdGFscyBmcm9tIEFQSSByZXNwb25zZSBvbmx5IC0gZG9uJ3QgY2FsY3VsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXRhLnRvdGFscykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG90YWxzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9tcnI6IHRoaXMuZGF0YS50b3RhbHMuZXhwZWN0ZWRfbXJyX3VzZCB8fCAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uc19sYXN0X21vbnRoOiB0aGlzLmRhdGEudG90YWxzLnNlc3Npb25zX2xhc3RfbW9udGggfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbnNfbGFzdF9xdWFydGVyOiB0aGlzLmRhdGEudG90YWxzLnNlc3Npb25zX2xhc3RfcXVhcnRlciB8fCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgbm8gdG90YWxzIGZyb20gQVBJLCBzZXQgdG8gMCAoZG9uJ3QgY2FsY3VsYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG90YWxzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9tcnI6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25zX2xhc3RfbW9udGg6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25zX2xhc3RfcXVhcnRlcjogMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5hZGQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiBGdW5jdGlvbiB0byBjYWxsIGFjY291bnRzIHNpemUgKi9cbiAgICBwcml2YXRlIGdldEFsbE9yZ2FuaXphdGlvblNpemUoKSB7XG4gICAgICAgIHRoaXMuY29tbW9uU2VydmljZS5nZXRPcmdhbml6YXRpb25TaXplcygpLnN1YnNjcmliZShyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvcmdhbml6YXRpb25TaXplcyA9IHJlc3BvbnNlLm9yZ2FuaXphdGlvbl9zaXplcztcbiAgICAgICAgICAgIG9yZ2FuaXphdGlvblNpemVzLmZvckVhY2godmFsID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogdmFsLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWwuaWRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMub3JnYW5pemF0aW9uU2l6ZXMucHVzaChkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiogRnVuY3Rpb24gdG8gZ2V0IG9yZ2FuaXphdGlvbiBpbmR1c3RyaWVzICovXG4gICAgcHJpdmF0ZSBnZXRJbmR1c3RyaWVzKCkge1xuICAgICAgICB0aGlzLmNvbW1vblNlcnZpY2UuZ2V0T3JnYW5pemF0aW9uSW5kdXN0cmllcygpLnN1YnNjcmliZShyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFsbEluZHVzdHJpZXMgPSByZXNwb25zZS5vcmdhbml6YXRpb25faW5kdXN0cmllcztcbiAgICAgICAgICAgIHRoaXMuYWxsSW5kdXN0cmllcy5mb3JFYWNoKHZhbCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5kdXN0cmllcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHZhbC5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsLmlkXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaE9wdGlvbnMucHVzaChpbmR1c3RyaWVzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiogRnVuY3Rpb24gdG8gZXhlY3V0ZSBvbiBkZWxldGUgYnV0dG9uIGNsaWNrICAqL1xuICAgIG9uRGVsZXRlKGlkOiBudW1iZXIsIHN1YnNjcmlwdGlvbl9pZDogbnVtYmVyKSB7XG4gICAgICAgIEhlbHBlclNlcnZpY2UucmFpc2VEZWxldGVQb3B1cCgpLnRoZW4ocmVzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXMudmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNybVNlcnZpY2UuZGVsZXRlQWNjb3VudChpZCwgc3Vic2NyaXB0aW9uX2lkKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VhcmNoOiB0aGlzLnNlYXJjaFRleHRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9hc3Quc3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRpb24udHJhbnNsYXRlKCdDcm0uQWNjb3VudE1lc3NhZ2UuRGVsZXRlZE1lc3NhZ2UnKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiogZmlsdGVyaW5nIGFjY291bnRzICovXG4gICAgb25TZWFyY2hPcHRpb25DaGFuZ2UoZXZlbnQsIGZpbHRlckJ5OiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKGZpbHRlckJ5ID09PSAnaW5kdXN0cnknKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlckJ5SW5kdXN0cmllcyA9IGV2ZW50LnZhbHVlO1xuICAgICAgICAgICAgdGhpcy5nZXRBbGxBY2NvdW50cyh7XG4gICAgICAgICAgICAgICAgcGFnZTogdGhpcy5wYWdlLFxuICAgICAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyQnkgPT09ICdzaXplJykge1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJCeVNpemVJZCA9IGV2ZW50LnZhbHVlO1xuICAgICAgICAgICAgdGhpcy5nZXRBbGxBY2NvdW50cyh7XG4gICAgICAgICAgICAgICAgcGFnZTogdGhpcy5wYWdlLFxuICAgICAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyQnkgPT09ICdzdGF0dXMnKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlckJ5U3RhdHVzID0gZXZlbnQudmFsdWU7XG4gICAgICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgICAgICBwYWdlOiB0aGlzLnBhZ2UsXG4gICAgICAgICAgICAgICAgcGFnZV9zaXplOiBQQUdFX1NJWkVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXJCeSA9PT0gJ3ByaW9yaXR5Jykge1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJCeVByaW9yaXR5ID0gZXZlbnQudmFsdWU7XG4gICAgICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgICAgICBwYWdlOiB0aGlzLnBhZ2UsXG4gICAgICAgICAgICAgICAgcGFnZV9zaXplOiBQQUdFX1NJWkVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXJCeSA9PT0gJ3NvdXJjZScpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyQnlTb3VyY2UgPSBldmVudC52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZ2V0QWxsQWNjb3VudHMoe1xuICAgICAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZSxcbiAgICAgICAgICAgICAgICBwYWdlX3NpemU6IFBBR0VfU0laRVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogRnVuY3Rpb24gdG8gZXhlY3V0ZSBvbiBsb2NhdGlvbiBzZWxlY3QgKi9cbiAgICBoYW5kbGVBZGRyZXNzQ2hhbmdlKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuZmlsdGVyQnlMb2NhdGlvbiA9IGV2ZW50LmZvcm1hdHRlZF9hZGRyZXNzO1xuICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZSxcbiAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiBMb2NhdGlvbiBmaWx0ZXIgd2hpbGUga2V5dXAgKi9cbiAgICBsb2NhdGlvblNlYXJjaChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQudGFyZ2V0LnZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJCeUxvY2F0aW9uID0gJyc7XG4gICAgICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgICAgICBwYWdlOiB0aGlzLnBhZ2UsXG4gICAgICAgICAgICAgICAgcGFnZV9zaXplOiBQQUdFX1NJWkVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEZ1bmN0aW9uIHRvIGNsZWFyIGFsbCBmaWx0ZXJzICovXG4gICAgY2xlYXJGaWx0ZXJzKCkge1xuICAgICAgICB0aGlzLmZpbHRlckJ5U2l6ZUlkID0gW107XG4gICAgICAgIHRoaXMuZmlsdGVyQnlJbmR1c3RyaWVzID0gW107XG4gICAgICAgIHRoaXMuZmlsdGVyQnlQcmlvcml0eSA9IFtdO1xuICAgICAgICB0aGlzLmZpbHRlckJ5U291cmNlID0gW107XG4gICAgICAgIHRoaXMuZmlsdGVyQnlTdGF0dXMgPSBbXTtcbiAgICAgICAgdGhpcy5zZWFyY2hUZXh0ID0gJyc7XG4gICAgICAgIHRoaXMuZmlsdGVyQnlMb2NhdGlvbiA9ICcnO1xuICAgICAgICB0aGlzLnNlYXJjaExvY2F0aW9uVGV4dCA9ICcnO1xuICAgICAgICB0aGlzLmdldEFsbEFjY291bnRzKHtcbiAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZSxcbiAgICAgICAgICAgIHBhZ2Vfc2l6ZTogUEFHRV9TSVpFXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiBGdW5jdGlvbiB0byBjYWxsIGFjY291bnQgZ2VvZ3JhcGh5ICovXG4gICAgcHJpdmF0ZSBnZXRBY2NvdW50R2VvZ3JhcGh5KCkge1xuICAgICAgICB0aGlzLmNybVNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRDcm1BbmFseXRpY3ModGhpcy5zdWJzY3JpcHRpb24/LmlkLCAnYWNjb3VudHNfZ2VvZ3JhcGh5JylcbiAgICAgICAgICAgIC5zdWJzY3JpYmUocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEFQSSBub3cgcmV0dXJucyB7IGl0ZW1zOiBbXSwgdG90YWxzOiB7fSB9IGluc3RlYWQgb2YgYXJyYXkvb2JqZWN0XG4gICAgICAgICAgICAgICAgdGhpcy5hY2NvdW50R2VvZ3JhcGh5ID0gcmVzcG9uc2U/Lml0ZW1zIHx8IHJlc3BvbnNlO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0VXNlckFjY291bnRJbmZvKGFjY291bnQ6IFVzZXJBY2NvdW50KTogeyBtZXNzYWdlOiBzdHJpbmc7IGljb25DbGFzczogc3RyaW5nIH0ge1xuICAgICAgICBpZiAoYWNjb3VudC5zaWduZWRfdXBfYXQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChhY2NvdW50LnVuc3Vic2NyaWJlZF9hdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IG1lc3NhZ2U6ICdQYXlpbmcgQ3VzdG9tZXInLCBpY29uQ2xhc3M6ICdmYXMgZmEtZG9sbGFyLXNpZ24gbW9uZXktaWNvbicgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ09sZCBDdXN0b21lcicsXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzczogJ2ZhcyBmYS1leGNsYW1hdGlvbi10cmlhbmdsZSB0ZXh0LWRhbmdlcidcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGFjY291bnQuY2hpbGRfc3Vic2NyaXB0aW9uX2lkICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdBY2NvdW50IHdpdGggZXhpc3Rpbmcgc3Vic2NyaXB0aW9uJyxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3M6ICdmYXMgZmEtbGluayBhY2NvdW50LWxpbmstaWNvbidcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZTogbnVsbCwgaWNvbkNsYXNzOiBudWxsIH07XG4gICAgfVxuXG4gICAgLyoqIEZ1bmN0aW9uIHRvIGNhbGwgYWNjb3VudCBhY3Rpdml0aWVzICovXG4gICAgcHJpdmF0ZSBnZXRBY2NvdW50QWN0aXZpdGllcygpIHtcbiAgICAgICAgdGhpcy5jcm1TZXJ2aWNlXG4gICAgICAgICAgICAuZ2V0Q3JtQW5hbHl0aWNzKHRoaXMuc3Vic2NyaXB0aW9uPy5pZCwgJ2FjY291bnRzX2xhc3RfYWN0aXZpdGllcycpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAvLyBBUEkgbm93IHJldHVybnMgeyBpdGVtczogW10sIHRvdGFsczoge30gfSBpbnN0ZWFkIG9mIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbXMgPSByZXNwb25zZT8uaXRlbXMgfHwgcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtcyA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoaXRlbXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjY291bnRBY3Rpdml0aWVzID0gW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY2NvdW50QWN0aXZpdGllcyA9IEFycmF5LmlzQXJyYXkoaXRlbXMpID8gaXRlbXMgOiBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3Rpb25OYW1lcyA9IHRoaXMuYWNjb3VudEFjdGl2aXRpZXM/Lm1hcChhY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjdGlvbj8uY3JtX2FjdGlvbj8ubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0Q291bnRyeUZyb21Mb2NhdGlvbihsb2NhdGlvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcGFydHMgPSBsb2NhdGlvbj8uc3BsaXQoJywnKSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdPy50cmltKCkgfHwgJyc7XG4gICAgfVxuXG4gICAgZ2V0QWNjb3VudExvZ28odXJsOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHVybCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9nb0NhY2hlU2VydmljZS5nZXRMb2dvKEhlbHBlclNlcnZpY2UuZ2V0TG9nb0J5VXJsKHVybCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGdldE1haW5DdXJyZW5jeSgpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5kYXRhPy5hY2NvdW50cz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5hY2NvdW50c1swXT8ubWFpbl9jdXJyZW5jeSB8fCAnVVNEJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ1VTRCc7XG4gICAgfVxuXG4gICAgb3ZlcnJpZGUgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInJvd1wiPlxuICA8ZGl2IGNsYXNzPVwiY29sLTEyIG1iLTNcIj5cbiAgICA8aDI+QWNjb3VudHM8L2gyPlxuICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1wcmltYXJ5IGZsb2F0LWVuZFwiIGRhdGEtY3k9XCJhZGQtY29udGFjdFwiXG4gICAgICBbcm91dGVyTGlua109XCJbJy8nICsgc3Vic2NyaXB0aW9uPy5zbHVnICsgcm91dGVycy5hZGRBY2NvdW50XVwiPlxuICAgICAgPGkgY2xhc3M9XCJmYSBmYS1wbHVzLWNpcmNsZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT4ge3sgJ0NybS5BY2NvdW50TWVzc2FnZS5BZGRBY2NvdW50JyB8IHRyYW5zbG9jbyB9fSA8L2E+XG4gIDwvZGl2PlxuPC9kaXY+XG48ZGl2IGNsYXNzPVwidy0xMDAgdGV4dC1jZW50ZXIgbXQtM1wiICpuZ0lmPVwiIWlzTG9hZGVkXCI+XG4gIDxwLXByb2dyZXNzU3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIj4gPC9wLXByb2dyZXNzU3Bpbm5lcj5cbjwvZGl2PlxuPGRpdiBjbGFzcz1cInByaW1lbmctZGF0YXRhYmxlLWNvbnRhaW5lciB0YWJsZS1yZXNwb25zaXZlXCIgW2NsYXNzLmhpZGVUYWJsZV09XCJkYXRhLnVuZmlsdGVyZWRfY291bnQgPT09IDBcIj5cbiAgPHAtdGFibGUgI2R0IFt2YWx1ZV09XCJkYXRhLmFjY291bnRzXCIgW3BhZ2luYXRvcl09XCJkYXRhLm9iamVjdF9jb3VudCAhPT0gMFwiIFtsYXp5XT1cInRydWVcIiBbcm93c109XCJQQUdFX1NJWkVcIlxuICAgIFt0b3RhbFJlY29yZHNdPVwiZGF0YS5vYmplY3RfY291bnRcIiBbbG9hZGluZ109XCJsb2FkaW5nXCIgW2ZpbHRlckRlbGF5XT1cIjEwMDBcIiAob25MYXp5TG9hZCk9XCJvbkxhenlMb2FkKCRldmVudClcIlxuICAgIFtjdXN0b21Tb3J0XT1cInRydWVcIj5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiY2FwdGlvblwiPlxuICAgICAgPGRpdiBjbGFzcz1cInJvdyBtLTBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS00XCI+XG4gICAgICAgICAgPHAtbXVsdGlTZWxlY3QgcGxhY2Vob2xkZXI9XCJTZWxlY3QgSW5kdXN0cnlcIiBbb3B0aW9uc109XCJzZWFyY2hPcHRpb25zXCIgWyhuZ01vZGVsKV09XCJmaWx0ZXJCeUluZHVzdHJpZXNcIlxuICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2VhcmNoT3B0aW9uQ2hhbmdlKCRldmVudCwgJ2luZHVzdHJ5JylcIiBbZmlsdGVyXT1cInRydWVcIiBbc2hvd0hlYWRlcl09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtzaG93VG9nZ2xlQWxsXT1cInRydWVcIiBhcHBlbmRUbz1cImJvZHlcIj5cbiAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTRcIj5cbiAgICAgICAgICA8cC1tdWx0aVNlbGVjdCBwbGFjZWhvbGRlcj1cIlNlbGVjdCBTaXplXCIgW29wdGlvbnNdPVwib3JnYW5pemF0aW9uU2l6ZXNcIiBbKG5nTW9kZWwpXT1cImZpbHRlckJ5U2l6ZUlkXCJcbiAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNlYXJjaE9wdGlvbkNoYW5nZSgkZXZlbnQsICdzaXplJylcIiBbZmlsdGVyXT1cInRydWVcIiBbc2hvd0hlYWRlcl09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtzaG93VG9nZ2xlQWxsXT1cInRydWVcIiBhcHBlbmRUbz1cImJvZHlcIj5cbiAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTRcIj5cbiAgICAgICAgICA8cC1tdWx0aVNlbGVjdCBwbGFjZWhvbGRlcj1cIlNlbGVjdCBTdGF0dXNcIiBbb3B0aW9uc109XCJzdGF0dXNcIiBbKG5nTW9kZWwpXT1cImZpbHRlckJ5U3RhdHVzXCJcbiAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNlYXJjaE9wdGlvbkNoYW5nZSgkZXZlbnQsICdzdGF0dXMnKVwiIFtmaWx0ZXJdPVwidHJ1ZVwiIFtzaG93SGVhZGVyXT1cInRydWVcIlxuICAgICAgICAgICAgW3Nob3dUb2dnbGVBbGxdPVwidHJ1ZVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tNFwiPlxuICAgICAgICAgIDxwLW11bHRpU2VsZWN0IHBsYWNlaG9sZGVyPVwiU2VsZWN0IFByaW9yaXR5XCIgW29wdGlvbnNdPVwicHJpb3JpdHlcIiBbKG5nTW9kZWwpXT1cImZpbHRlckJ5UHJpb3JpdHlcIlxuICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2VhcmNoT3B0aW9uQ2hhbmdlKCRldmVudCwgJ3ByaW9yaXR5JylcIiBbZmlsdGVyXT1cInRydWVcIiBbc2hvd0hlYWRlcl09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtzaG93VG9nZ2xlQWxsXT1cInRydWVcIiBhcHBlbmRUbz1cImJvZHlcIj5cbiAgICAgICAgICA8L3AtbXVsdGlTZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTRcIj5cbiAgICAgICAgICA8cC1tdWx0aVNlbGVjdCBwbGFjZWhvbGRlcj1cIlNlbGVjdCBTb3VyY2VcIiBbb3B0aW9uc109XCJzb3VyY2VcIiBbKG5nTW9kZWwpXT1cImZpbHRlckJ5U291cmNlXCJcbiAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNlYXJjaE9wdGlvbkNoYW5nZSgkZXZlbnQsICdzb3VyY2UnKVwiIFtmaWx0ZXJdPVwidHJ1ZVwiIFtzaG93SGVhZGVyXT1cInRydWVcIlxuICAgICAgICAgICAgW3Nob3dUb2dnbGVBbGxdPVwidHJ1ZVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tNCBtYi0yXCI+XG4gICAgICAgICAgPGlucHV0IG5neC1ncC1hdXRvY29tcGxldGUgY2xhc3M9XCJmb3JtLWNvbnRyb2wgbG9jYXRpb25cIiAjcGxhY2VzPVwibmd4LXBsYWNlc1wiIFsobmdNb2RlbCldPVwic2VhcmNoTG9jYXRpb25UZXh0XCJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGxvY2F0aW9uLi4uXCIgKGtleXVwKT1cImxvY2F0aW9uU2VhcmNoKCRldmVudClcIlxuICAgICAgICAgICAgKG9uQWRkcmVzc0NoYW5nZSk9XCJoYW5kbGVBZGRyZXNzQ2hhbmdlKCRldmVudClcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1maWx0ZXJcIj5cbiAgICAgICAgPGEgY2xhc3M9XCJtdC0zIG1zLTMgdGV4dC1zdGFydCBidG4tZmlsdGVyLXByaW1hcnlcIiAoY2xpY2spPVwiY2xlYXJGaWx0ZXJzKClcIj5DbGVhciBhbGwgZmlsdGVyczwvYT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtZW5kIG10LTAgbXQtc20tM1wiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtc2VhcmNoIG10LTIgbWUtMlwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInNlYXJjaFRleHRcIiBwSW5wdXRUZXh0IHNpemU9XCI1MFwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGFjY291bnRzLi4uXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJkdC5maWx0ZXJHbG9iYWwoJGV2ZW50LnRhcmdldC52YWx1ZSwgJ2NvbnRhaW5zJylcIiBjbGFzcz1cIm13LTkwXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgIDx0cj5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cIm5hbWVcIj4ge3sgJ0NybS5BY2NvdW50TWVzc2FnZS5OYW1lJyB8IHRyYW5zbG9jbyB9fSA8cC1zb3J0SWNvbiBmaWVsZD1cIm5hbWVcIj5cbiAgICAgICAgICA8L3Atc29ydEljb24+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0aCBzY29wZT1cInRydWVcIiBwU29ydGFibGVDb2x1bW49XCJsb2NhdGlvblwiPiB7eyAnQ3JtLkFjY291bnRNZXNzYWdlLkxvY2F0aW9uJyB8IHRyYW5zbG9jbyB9fSA8cC1zb3J0SWNvblxuICAgICAgICAgICAgZmllbGQ9XCJsb2NhdGlvblwiPjwvcC1zb3J0SWNvbj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cIm93bmVyX2lkXCI+IHt7ICdDcm0uQWNjb3VudE1lc3NhZ2UuT3duZXInIHwgdHJhbnNsb2NvIH19IDxwLXNvcnRJY29uXG4gICAgICAgICAgICBmaWVsZD1cIm93bmVyX2lkXCI+PC9wLXNvcnRJY29uPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGggc2NvcGU9XCJ0cnVlXCIgcFNvcnRhYmxlQ29sdW1uPVwib3JnYW5pemF0aW9uX3NpemVfaWRcIj4ge3sgJ0NybS5BY2NvdW50TWVzc2FnZS5TaXplJyB8IHRyYW5zbG9jbyB9fSA8cC1zb3J0SWNvblxuICAgICAgICAgICAgZmllbGQ9XCJvcmdhbml6YXRpb25fc2l6ZV9pZFwiPjwvcC1zb3J0SWNvbj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cImV4cGVjdGVkX21yclwiIGNsYXNzPVwibXJyLWhlYWRlclwiPiB7eyAnQ3JtLkFjY291bnRNZXNzYWdlLk1SUicgfCB0cmFuc2xvY28gfX0gPHAtc29ydEljb24gZmllbGQ9XCJleHBlY3RlZF9tcnJcIj5cbiAgICAgICAgPC9wLXNvcnRJY29uPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGggc2NvcGU9XCJ0cnVlXCIgcFNvcnRhYmxlQ29sdW1uPVwic2lnbmVkX3VwX2F0XCI+IHt7ICdDcm0uQWNjb3VudE1lc3NhZ2UuU2lnblVwQXQnIHwgdHJhbnNsb2NvIH19IDxwLXNvcnRJY29uIGZpZWxkPVwic2lnbmVkX3VwX2F0XCI+XG4gICAgICAgIDwvcC1zb3J0SWNvbj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cInNlc3Npb25zX2xhc3RfcXVhcnRlclwiPiB7eyAnQ3JtLkFjY291bnRNZXNzYWdlLlF1YXJ0ZXInIHwgdHJhbnNsb2NvIH19IDxwLXNvcnRJY29uIGZpZWxkPVwic2Vzc2lvbnNfbGFzdF9xdWFydGVyXCI+XG4gICAgICAgIDwvcC1zb3J0SWNvbj5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cInNlc3Npb25zX2xhc3RfbW9udGhcIj4ge3sgJ0NybS5BY2NvdW50TWVzc2FnZS5Nb250aCcgfCB0cmFuc2xvY28gfX0gPHAtc29ydEljb24gZmllbGQ9XCJzZXNzaW9uc19sYXN0X21vbnRoXCI+XG4gICAgICAgIDwvcC1zb3J0SWNvbj5cbiAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiIHBTb3J0YWJsZUNvbHVtbj1cInN0YXR1c1wiPiB7eyAnQ3JtLkFjY291bnRNZXNzYWdlLlN0YXR1cycgfCB0cmFuc2xvY28gfX0gPHAtc29ydEljb24gZmllbGQ9XCJzdGF0dXNcIj5cbiAgICAgICAgPC9wLXNvcnRJY29uPlxuICAgICAgICA8dGggc2NvcGU9XCJ0cnVlXCIgcFNvcnRhYmxlQ29sdW1uPVwicHJpb3JpdHlcIj4ge3sgJ0NybS5BY2NvdW50TWVzc2FnZS5Qcmlvcml0eScgfCB0cmFuc2xvY28gfX0gPHAtc29ydEljb24gZmllbGQ9XCJwcmlvcml0eVwiPlxuICAgICAgICA8L3Atc29ydEljb24+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0aCBzY29wZT1cInRydWVcIj57eyAnTGFiZWwuQWN0aW9ucycgfCB0cmFuc2xvY28gfX08L3RoPlxuICAgICAgPC90cj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJib2R5XCIgbGV0LWFjY291bnQgbGV0LWk9XCJyb3dJbmRleFwiPlxuICAgICAgPCEtLSBUb3RhbHMgcm93IGF0IHRoZSB0b3AgKGZpcnN0IHJvdykgLSBzaG93IGJlZm9yZSBmaXJzdCBkYXRhIHJvdyAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpID09PSAwICYmIGRhdGE/LmFjY291bnRzPy5sZW5ndGhcIj5cbiAgICAgICAgPHRyIGNsYXNzPVwidG90YWxzLXJvdyBcIj5cbiAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJmdy1ib2xkIGV4cGVjdGVkLW1yclwiPlxuICAgICAgICAgICAgPHN0cm9uZz57eyB0b3RhbHM/LnRvdGFsX21yciAvIDEwMCB8IGN1cnJlbmN5OiAnVVNEJyB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkPjwvdGQ+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiZnctYm9sZFwiPlxuICAgICAgICAgICAgPHN0cm9uZz57eyB0b3RhbHM/LnNlc3Npb25zX2xhc3RfcXVhcnRlciB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiZnctYm9sZFwiPlxuICAgICAgICAgICAgPHN0cm9uZz57eyB0b3RhbHM/LnNlc3Npb25zX2xhc3RfbW9udGggfX08L3N0cm9uZz5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD48L3RkPlxuICAgICAgICAgIDx0ZD48L3RkPlxuICAgICAgICAgIDx0ZD48L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8IS0tIFJlZ3VsYXIgZGF0YSByb3cgLS0+XG4gICAgICA8dHI+XG4gICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJOYW1lXCIgY2xhc3M9XCJuYW1lLWNvbHVtblwiPlxuICAgICAgICAgIDxhIFtyb3V0ZXJMaW5rXT1cIlsnLycgKyBzdWJzY3JpcHRpb24/LnNsdWcgKyByb3V0ZXJzLmFjY291bnRJbmZvLCBhY2NvdW50LmlkXVwiIGNsYXNzPVwibmFtZS1saW5rXCI+XG4gICAgICAgICAgICA8aW1nIGFsdD1cIkNvbXBhbnkgTG9nb1wiIFtzcmNdPVwiZ2V0QWNjb3VudExvZ28oYWNjb3VudC5jb21wYW55X3VybClcIiBjbGFzcz1cImltZy1mbHVpZCBjb21wYW55LWxvZ28gbWUtMlwiXG4gICAgICAgICAgICAgICAgICAoZXJyb3IpPVwiaGFuZGxlSW1hZ2VFcnJvcigkZXZlbnQsICdhc3NldHMvaW1nL2ljb25zL2NvbXBhbnkucG5nJylcIiAvPlxuICAgICAgICAgICAgPHNwYW4gW25nYlRvb2x0aXBdPVwiYWNjb3VudC5uYW1lXCIgY2xhc3M9XCJhY2NvdW50LW5hbWVcIiBbdGl0bGVdPVwiYWNjb3VudC5uYW1lXCI+e3sgYWNjb3VudC5uYW1lIHwgdGV4dFRydW5jYXRlOjMwIH19PC9zcGFuPlxuICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwiZ2V0VXNlckFjY291bnRJbmZvKGFjY291bnQpLmljb25DbGFzc1wiIFtuZ2JUb29sdGlwXT1cImdldFVzZXJBY2NvdW50SW5mbyhhY2NvdW50KS5tZXNzYWdlXCJcbiAgICAgICAgICAgICAgIGNsYXNzPVwiaW5mby1pY29uXCI+PC9pPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZXhjbGFtYXRpb24tY2lyY2xlIHRleHQtZGFuZ2VyIGluZm8taWNvblwiXG4gICAgICAgICAgICAgICAqbmdJZj1cImFjY291bnQ/LnJlYXNvbl90b19jYW5jZWxcIlxuICAgICAgICAgICAgICAgW3BUb29sdGlwXT1cImFjY291bnQucmVhc29uX3RvX2NhbmNlbFwiXG4gICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIj48L2k+XG4gICAgICAgICAgPC9hPlxuICAgICAgICA8L3RkPlxuICAgICAgICA8dGQgZGF0YS1oZWFkPVwiTG9jYXRpb25cIiBjbGFzcz1cIm5vLXdyYXBcIj48c3BhbiBbbmdiVG9vbHRpcF09XCJhY2NvdW50LmxvY2F0aW9uXCI+e3sgZ2V0Q291bnRyeUZyb21Mb2NhdGlvbihhY2NvdW50LmxvY2F0aW9uKSB9fTwvc3Bhbj48L3RkPlxuICAgICAgICA8dGQgZGF0YS1oZWFkPVwiT3duZXJcIj5cbiAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJbJy9tZW1iZXJzJywgYWNjb3VudD8ub3duZXI/LnNsdWddXCI+IHt7IGFjY291bnQub3duZXIuZmlyc3RfbmFtZS5jaGFyQXQoMCkgfX0uIHt7YWNjb3VudC5vd25lci5sYXN0X25hbWV9fTwvYT5cbiAgICAgICAgPC90ZD5cbiAgICAgICAgPHRkIGRhdGEtaGVhZD1cIlNpemVcIiBjbGFzcz1cIm5vLXdyYXBcIj57eyBhY2NvdW50Py5vcmdhbmlzYXRpb25fc2l6ZT8ubmFtZSAhPT0gJ05vdCBhdmFpbGFibGUnID8gYWNjb3VudD8ub3JnYW5pc2F0aW9uX3NpemU/Lm5hbWUgOiAnJyB9fVxuPC90ZD5cbjx0ZCBkYXRhLWhlYWQ9XCJNUlJcIiBjbGFzcz1cIm5vLXdyYXAgZnctYm9sZCBleHBlY3RlZC1tcnJcIiA+XG4gIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5leHBlY3RlZF9tcnIgJiYgKGhhc0FjY2VzcyB8fCBhY2NvdW50Lm93bmVyX2lkID09PSB1c2VySWQpXCI+XG4gICAge3sgYWNjb3VudC5leHBlY3RlZF9tcnIgLyAxMDAgfCBjdXJyZW5jeTogYWNjb3VudC5tYWluX2N1cnJlbmN5IH19XG4gIDwvc3Bhbj5cbjwvdGQ+XG4gICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJTaWduZWQgVXBcIj57eyBhY2NvdW50LnNpZ25lZF91cF9hdCB8IGRhdGU6ICdkZC1NTU0tWVlZWScgfX08L3RkPlxuICAgICAgICA8dGQgZGF0YS1oZWFkPVwiUXVhcnRlclwiIFtuZ0NsYXNzXT1cInsnbW9udGgtcXVhcnRlci10ZXh0IGZ3LWJvbGQnOiBhY2NvdW50LnNlc3Npb25zX2xhc3RfcXVhcnRlciA+IDE1fVwiPnt7IGFjY291bnQuc2Vzc2lvbnNfbGFzdF9xdWFydGVyIH19PC90ZD5cbiAgICAgICAgPHRkIGRhdGEtaGVhZD1cIk1vbnRoXCIgW25nQ2xhc3NdPVwieydtb250aC1xdWFydGVyLXRleHQgZnctYm9sZCc6IGFjY291bnQuc2Vzc2lvbnNfbGFzdF9xdWFydGVyID4gNX1cIj57eyBhY2NvdW50LnNlc3Npb25zX2xhc3RfbW9udGggfX08L3RkPlxuICAgICAgICA8dGQgZGF0YS1oZWFkPVwiU3RhdHVzXCI+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJhY2NvdW50LnN0YXR1cyA9PT0gJ1Byb3NwZWN0J1wiIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnVHJpYWwgLSBBY3RpdmUnXCIgY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+e3thY2NvdW50LnN0YXR1c319PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5zdGF0dXMgPT09ICdUcmlhbCAtIEluYWN0aXZlJ1wiIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+e3thY2NvdW50LnN0YXR1c319PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5zdGF0dXMgPT09ICdDdXN0b21lciAtIE5ldydcIiBjbGFzcz1cImJhZGdlIGJnLWluZm9cIj57e2FjY291bnQuc3RhdHVzfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJhY2NvdW50LnN0YXR1cyA9PT0gJ0N1c3RvbWVyIC0gQWN0aXZlJ1wiIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnQ3VzdG9tZXIgLSBJbmFjdGl2ZSdcIiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj57e2FjY291bnQuc3RhdHVzfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJhY2NvdW50LnN0YXR1cyA9PT0gJ0N1c3RvbWVyIC0gT2xkJ1wiIGNsYXNzPVwiYmFkZ2UgYmctZGFya1wiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnRGVhZCdcIiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnQ29tcGV0aXRvcidcIiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnVmVuZG9yJ1wiIGNsYXNzPVwiYmFkZ2UgYmctYmx1ZS1ncmV5XCI+e3thY2NvdW50LnN0YXR1c319PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5zdGF0dXMgPT09ICdTdXBwbGllcidcIiBjbGFzcz1cImJhZGdlIGJnLWJsdWUtZ3JleVwiPnt7YWNjb3VudC5zdGF0dXN9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjY291bnQuc3RhdHVzID09PSAnT3RoZXInXCIgY2xhc3M9XCJiYWRnZSBiZy10ZWFsXCI+e3thY2NvdW50LnN0YXR1c319PC9zcGFuPlxuICAgICAgICA8L3RkPlxuXG4gICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJQcmlvcml0eVwiPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5wcmlvcml0eSA9PT0gJ0EgLSBJZGVhbCBGaXQnXCIgY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+e3thY2NvdW50LnByaW9yaXR5fX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJhY2NvdW50LnByaW9yaXR5ID09PSAnQiAtIEhpZ2ggUG90ZW50aWFsJ1wiIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPnt7YWNjb3VudC5wcmlvcml0eX19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5wcmlvcml0eSA9PT0gJ0MgLSBMb3cgUG90ZW50aWFsJ1wiIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPnt7YWNjb3VudC5wcmlvcml0eX19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWNjb3VudC5wcmlvcml0eSA9PT0gJ0QgLSBPdXQgb2YgbWFya2V0J1wiIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+e3thY2NvdW50LnByaW9yaXR5fX08L3NwYW4+XG4gICAgICAgIDwvdGQ+XG5cbiAgICAgICAgPHRkIGRhdGEtaGVhZD1cIkFjdGlvblwiPlxuICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtdW5zdHlsZWQgbGlzdC1pbmxpbmUgbGlzdC1hY3Rpb25cIj5cbiAgICAgICAgICAgIDxsaSBuZ2JUb29sdGlwPVwiU2VlIGNvbnRhY3RzXCIgY2xhc3M9XCJtZS0yIG1lLXNtLTMgc2VlLWljb25cIlxuICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJbJy8nICsgc3Vic2NyaXB0aW9uPy5zbHVnICsgcm91dGVycy5hY2NvdW50Q29udGFjdHMsIGFjY291bnQuaWRdXCI+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtZXllXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNBY2Nlc3MgfHwgYWNjb3VudC5vd25lcl9pZCA9PT0gdXNlcklkXCI+XG4gICAgICAgICAgICAgIDxsaSBuZ2JUb29sdGlwPVwiRWRpdFwiIGNsYXNzPVwibWUtMiBtZS1zbS0zXCIgW3JvdXRlckxpbmtdPVwiW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy8nICsgc3Vic2NyaXB0aW9uPy5zbHVnICsgcm91dGVycy5hY2NvdW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnQuaWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtZWRpdCBlZGl0LWljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgIDxsaSBuZ2JUb29sdGlwPVwiRGVsZXRlXCIgY2xhc3M9XCJtZS0yIG1lLXNtLTNcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXRyYXNoIGRlbGV0ZS1pY29uXCIgKGtleWRvd24uZW50ZXIpPVwib25EZWxldGUoYWNjb3VudC5pZCwgc3Vic2NyaXB0aW9uLmlkKVwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwib25EZWxldGUoYWNjb3VudC5pZCwgc3Vic2NyaXB0aW9uLmlkKVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlKGFjY291bnQuaWQsIHN1YnNjcmlwdGlvbi5pZClcIlxuICAgICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC91bD5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgICA8dHIgKm5nSWY9XCJkYXRhPy5hY2NvdW50cz8ubGVuZ3RoXCI+XG4gICAgICAgIDx0ZD48L3RkPlxuICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgPHRkPjwvdGQ+XG4gICAgICAgIDx0ZD48L3RkPlxuICAgICAgICA8dGQgY2xhc3M9XCJleHBlY3RlZC1tcnJcIj5cbiAgICAgICAgICA8c3Ryb25nPnt7IHRvdGFscz8udG90YWxfbXJyIC8gMTAwIHwgY3VycmVuY3k6ICdVU0QnIH19PC9zdHJvbmc+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIDx0ZD48L3RkPlxuICAgICAgICA8dGQgY2xhc3M9XCJmdy1ib2xkXCI+XG4gICAgICAgICAgPHN0cm9uZz57eyB0b3RhbHM/LnNlc3Npb25zX2xhc3RfcXVhcnRlciB9fTwvc3Ryb25nPlxuICAgICAgICA8L3RkPlxuICAgICAgICA8dGQgY2xhc3M9XCJmdy1ib2xkXCI+XG4gICAgICAgICAgPHN0cm9uZz57eyB0b3RhbHM/LnNlc3Npb25zX2xhc3RfbW9udGggfX08L3N0cm9uZz5cbiAgICAgICAgPC90ZD5cbiAgICAgICAgPHRkPjwvdGQ+XG4gICAgICAgIDx0ZD48L3RkPlxuICAgICAgICA8dGQ+PC90ZD5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9wLXRhYmxlPlxuPGRpdiAqbmdJZj1cImRhdGEub2JqZWN0X2NvdW50ID09PSAwICYmIGRhdGEudW5maWx0ZXJlZF9jb3VudCAhPT0gMFwiPlxuICAgIDxwdy1uby1kYXRhIFt3aXRoSW1hZ2VdPVwidHJ1ZVwiIFttZXNzYWdlXT1cIidTZWFyY2guTm9EYXRhTWVzc2FnZScgfCB0cmFuc2xvY29cIiBbZGVzY3JpcHRpb25dPVwiJ1NlYXJjaC5Ob0RhdGFEZXNjcmlwdGlvbicgfCB0cmFuc2xvY29cIiA+XG4gICAgPC9wdy1uby1kYXRhPlxuPC9kaXY+XG4gIDxzcGFuIGNsYXNzPVwidG90YWwtcmVjb3Jkcy1jb3VudFwiICpuZ0lmPVwiZGF0YS5vYmplY3RfY291bnQgIT09IDBcIj57eyAnTGFiZWwuVG90YWwnIHwgdHJhbnNsb2NvIH19OiB7eyBkYXRhLm9iamVjdF9jb3VudCB9fTwvc3Bhbj5cbjwvZGl2PlxuPGRpdiAqbmdJZj1cImRhdGEudW5maWx0ZXJlZF9jb3VudCA9PT0gMCAmJiBpc0xvYWRlZFwiPlxuICA8cHctbm8tZGF0YSBbd2l0aEltYWdlXT1cInRydWVcIiBbbWVzc2FnZV09XCInQ3JtLkFjY291bnRNZXNzYWdlLk5vQWNjb3VudE1lc3NhZ2UnIHwgdHJhbnNsb2NvXCI+IDwvcHctbm8tZGF0YT5cbjwvZGl2PlxuPG5nLWNvbnRhaW5lcj5cbiAgPGRpdiBjbGFzcz1cInJvdyBtdC01XCIgKm5nSWY9XCJkYXRhLnVuZmlsdGVyZWRfY291bnQgIT09IDAgJiYgaXNMb2FkZWRcIj5cbiAgICAgIDwhLS0gTGFzdCBBY3Rpdml0aWVzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC0xMiBjb2wtbWQtNiBtYi0zIGFuYWx5dGljc1wiPlxuICAgICAgICA8aDUgY2xhc3M9XCJhY2NvcmRpb24taGVhZGluZ1wiPkxhdGVzdCBBY3Rpdml0aWVzPC9oNT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInByaW1lbmctZGF0YXRhYmxlLWNvbnRhaW5lciB0YWJsZS1yZXNwb25zaXZlXCIgKm5nSWY9XCJhY2NvdW50QWN0aXZpdGllcz8ubGVuZ3RoXCI+XG4gICAgICAgICAgPHAtdGFibGUgY2xhc3M9XCJ0YWJsZVwiICNkdCBbdmFsdWVdPVwiYWNjb3VudEFjdGl2aXRpZXNcIiBbcGFnaW5hdG9yXT1cImFjY291bnRJbnNpZ2h0Py5sZW5ndGggIT09IDBcIiBbcm93c109XCJQQUdFX1NJWkVcIlxuICAgICAgICAgICAgW3RvdGFsUmVjb3Jkc109XCJhY2NvdW50QWN0aXZpdGllcy5sZW5ndGhcIiBbbGF6eV09XCJ0cnVlXCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJ0cnVlXCI+e3sgJ0NybS5BY2NvdW50TWVzc2FnZS5Pd25lcicgfCB0cmFuc2xvY28gfX08L3RoPlxuICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cInRydWVcIj57eyAnQ3JtLkFjY291bnRNZXNzYWdlLkFjY291bnQnIHwgdHJhbnNsb2NvIH19PC90aD5cbiAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJ0cnVlXCI+e3sgJ0NybS5BY2NvdW50TWVzc2FnZS5Db250YWN0JyB8IHRyYW5zbG9jbyB9fTwvdGg+XG4gICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiPnt7ICdDcm0uQWNjb3VudE1lc3NhZ2UuQWN0aW9uJyB8IHRyYW5zbG9jbyB9fTwvdGg+XG4gICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwidHJ1ZVwiPnt7ICdDcm0uQWNjb3VudE1lc3NhZ2UuV2hlbicgfCB0cmFuc2xvY28gfX08L3RoPlxuICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJib2R5XCIgbGV0LWFjdGl2aXRpZXM+XG4gICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICA8dGQgZGF0YS1oZWFkPVwiT3duZXJcIj4ge3sgYWN0aXZpdGllcy5vd25lcj8uZmlyc3RfbmFtZS5jaGFyQXQoMCkgfX0uIHt7IGFjdGl2aXRpZXMub3duZXI/Lmxhc3RfbmFtZSB9fSA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJBY2NvdW50XCI+XG4gICAgICAgICAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJbJy8nICsgc3Vic2NyaXB0aW9uPy5zbHVnICsgcm91dGVycy5hY2NvdW50SW5mbywgYWN0aXZpdGllcy5jcm1fYWNjb3VudF9pZF1cIiBjbGFzcz1cIm5hbWUtbGlua1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdiVG9vbHRpcF09XCJhY3Rpdml0aWVzLmNybV9hY2NvdW50Py5uYW1lXCI+e3sgYWN0aXZpdGllcy5jcm1fYWNjb3VudD8ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJDb250YWN0XCI+XG4gICAgICAgICAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJbJy8nICsgc3Vic2NyaXB0aW9uPy5zbHVnICsgcm91dGVycy5jb250YWN0SW5mbywgYWN0aXZpdGllcy5jcm1fY29udGFjdF9pZF1cIiBjbGFzcz1cIm5hbWUtbGlua1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdiVG9vbHRpcF09XCJhY3Rpdml0aWVzLmNybV9jb250YWN0ID8gYWN0aXZpdGllcy5jcm1fY29udGFjdC5maXJzdF9uYW1lICsgJyAnICsgYWN0aXZpdGllcy5jcm1fY29udGFjdC5sYXN0X25hbWUgOiAnJ1wiPnt7IChhY3Rpdml0aWVzLmNybV9jb250YWN0Py5maXJzdF9uYW1lICsgJyAnICsgYWN0aXZpdGllcy5jcm1fY29udGFjdD8ubGFzdF9uYW1lKSB8IHRleHRUcnVuY2F0ZToyMCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJBY3Rpb25cIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIFtuZ2JUb29sdGlwXT1cImFjdGl2aXRpZXMuY29tbWVudFwiIFthcHBEeW5hbWljQmFkZ2VdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXNBcnJheTogYWN0aW9uTmFtZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtOiBhY3Rpdml0aWVzLmNybV9hY3Rpb24/Lm5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwiYmx1ZS1ncmV5XCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJiYWRnZVwiPnt7IGFjdGl2aXRpZXMuY3JtX2FjdGlvbj8ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBkYXRhLWhlYWQ9XCJXaGVuXCI+e3sgYWN0aXZpdGllcy53aGVuIHwgZGF0ZTonZGQtTU1NLVlZWVknIH19PC90ZD5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9wLXRhYmxlPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRvdGFsLXJlY29yZHMtY291bnRcIiAqbmdJZj1cImFjY291bnRJbnNpZ2h0Py5sZW5ndGggIT09IDBcIj57eyAnTGFiZWwuVG90YWwnIHwgdHJhbnNsb2NvIH19OiB7eyBhY2NvdW50QWN0aXZpdGllcy5sZW5ndGggfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiYWNjb3VudEFjdGl2aXRpZXM/Lmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgIDxwdy1uby1kYXRhIFt3aXRoSW1hZ2VdPVwidHJ1ZVwiIFttZXNzYWdlXT1cIidDcm0uQWNjb3VudE1lc3NhZ2UuTm9JbnNpZ2h0TWVzc2FnZScgfCB0cmFuc2xvY29cIj5cbiAgICAgICAgICA8L3B3LW5vLWRhdGE+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPCEtLSBHZW9ncmFwaHkgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNvbC0xMiBjb2wtbWQtNiBtYi0zIGFuYWx5dGljc1wiPlxuICAgICAgPGg1IGNsYXNzPVwiYWNjb3JkaW9uLWhlYWRpbmdcIj5BY2NvdW50cyBMb2NhdGlvbjwvaDU+XG4gICAgICA8ZGl2PlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiYWNjb3VudEdlb2dyYXBoeVwiPlxuICAgICAgICAgIDxwbG90bHktcGxvdCBbZGF0YV09XCJhY2NvdW50R2VvZ3JhcGh5Py5kYXRhXCIgW2xheW91dF09XCJhY2NvdW50R2VvZ3JhcGh5Py5sYXlvdXRcIiBbY29uZmlnXT1cImFjY291bnRHZW9ncmFwaHk/LmNvbmZpZ1wiIFt1c2VSZXNpemVIYW5kbGVyXT1cImFjY291bnRHZW9ncmFwaHkgPyB0cnVlIDogZmFsc2VcIj5cbiAgICAgICAgICA8L3Bsb3RseS1wbG90PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWFjY291bnRHZW9ncmFwaHlcIj5cbiAgICAgICAgPHB3LW5vLWRhdGEgW3dpdGhJbWFnZV09XCJ0cnVlXCIgW21lc3NhZ2VdPVwiJ0NybS5BY2NvdW50TWVzc2FnZS5Ob0luc2lnaHRNZXNzYWdlJyB8IHRyYW5zbG9jb1wiPlxuICAgICAgICA8L3B3LW5vLWRhdGE+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==