ng-kinintel 0.0.397 → 20.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ng-kinintel.mjs +11874 -0
- package/fesm2022/ng-kinintel.mjs.map +1 -0
- package/index.d.ts +2818 -5
- package/package.json +6 -14
- package/esm2020/lib/components/alert-groups/alert-groups.component.mjs +0 -76
- package/esm2020/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.mjs +0 -83
- package/esm2020/lib/components/dashboard-editor/configure-item/configure-item.component.mjs +0 -853
- package/esm2020/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.mjs +0 -56
- package/esm2020/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.mjs +0 -114
- package/esm2020/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.mjs +0 -163
- package/esm2020/lib/components/dashboard-editor/configure-item/vis-network-options.json +0 -135
- package/esm2020/lib/components/dashboard-editor/dashboard-editor.component.mjs +0 -580
- package/esm2020/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.mjs +0 -15
- package/esm2020/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.mjs +0 -50
- package/esm2020/lib/components/dashboard-editor/item-component/item-component.component.mjs +0 -1226
- package/esm2020/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.mjs +0 -111
- package/esm2020/lib/components/dashboards/dashboards.component.mjs +0 -163
- package/esm2020/lib/components/dashboards/view-dashboard/view-dashboard.component.mjs +0 -429
- package/esm2020/lib/components/data-explorer/change-source-warning/change-source-warning.component.mjs +0 -20
- package/esm2020/lib/components/data-explorer/data-explorer.component.mjs +0 -243
- package/esm2020/lib/components/data-explorer/export-data/export-data.component.mjs +0 -62
- package/esm2020/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.mjs +0 -70
- package/esm2020/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.mjs +0 -190
- package/esm2020/lib/components/data-picker/data-picker.component.mjs +0 -79
- package/esm2020/lib/components/data-search/data-search.component.mjs +0 -11
- package/esm2020/lib/components/data-sharing-invite/data-sharing-invite.component.mjs +0 -52
- package/esm2020/lib/components/dataset/create-dataset/create-dataset.component.mjs +0 -47
- package/esm2020/lib/components/dataset/dataset-editor/available-columns/available-columns.component.mjs +0 -28
- package/esm2020/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.mjs +0 -344
- package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.mjs +0 -80
- package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.mjs +0 -54
- package/esm2020/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.mjs +0 -67
- package/esm2020/lib/components/dataset/dataset-editor/dataset-editor.component.mjs +0 -1134
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.mjs +0 -201
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.mjs +0 -25
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.mjs +0 -72
- package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.mjs +0 -62
- package/esm2020/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.mjs +0 -41
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.mjs +0 -78
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.mjs +0 -39
- package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.mjs +0 -75
- package/esm2020/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.mjs +0 -107
- package/esm2020/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.mjs +0 -58
- package/esm2020/lib/components/dataset/dataset-editor/share-query/share-query.component.mjs +0 -110
- package/esm2020/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.mjs +0 -20
- package/esm2020/lib/components/dataset/dataset.component.mjs +0 -294
- package/esm2020/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.mjs +0 -130
- package/esm2020/lib/components/datasource/create-datasource/api-access/api-access.component.mjs +0 -132
- package/esm2020/lib/components/datasource/create-datasource/create-datasource.component.mjs +0 -729
- package/esm2020/lib/components/datasource/create-datasource/import-data/import-data.component.mjs +0 -146
- package/esm2020/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.mjs +0 -165
- package/esm2020/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.mjs +0 -145
- package/esm2020/lib/components/datasource/datasource.component.mjs +0 -162
- package/esm2020/lib/components/datasource/document-datasource/document-datasource.component.mjs +0 -297
- package/esm2020/lib/components/export-project/export-project.component.mjs +0 -29
- package/esm2020/lib/components/feeds/feed/feed.component.mjs +0 -92
- package/esm2020/lib/components/feeds/feeds.component.mjs +0 -145
- package/esm2020/lib/components/job-tasks/job-tasks.component.mjs +0 -25
- package/esm2020/lib/components/marketplace/marketplace.component.mjs +0 -65
- package/esm2020/lib/components/metadata/metadata.component.mjs +0 -65
- package/esm2020/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.mjs +0 -113
- package/esm2020/lib/components/notification-groups/notification-groups.component.mjs +0 -86
- package/esm2020/lib/components/project-picker/project-picker.component.mjs +0 -118
- package/esm2020/lib/components/project-settings/project-link-selection/project-link-selection.component.mjs +0 -104
- package/esm2020/lib/components/project-settings/project-settings.component.mjs +0 -155
- package/esm2020/lib/components/query-caching/edit-query-cache/edit-query-cache.component.mjs +0 -51
- package/esm2020/lib/components/query-caching/query-cache-view/query-cache-view.component.mjs +0 -121
- package/esm2020/lib/components/query-caching/query-caching.component.mjs +0 -162
- package/esm2020/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.mjs +0 -45
- package/esm2020/lib/components/shared-with-me/shared-with-me.component.mjs +0 -174
- package/esm2020/lib/components/snapshots/snapshots.component.mjs +0 -244
- package/esm2020/lib/components/tag-picker/tag-picker.component.mjs +0 -74
- package/esm2020/lib/components/task-time-periods/task-time-periods.component.mjs +0 -55
- package/esm2020/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.mjs +0 -40
- package/esm2020/lib/guards/dashboard-changes.guard.mjs +0 -22
- package/esm2020/lib/kinintel-config.mjs +0 -3
- package/esm2020/lib/ng-kinintel.module.mjs +0 -437
- package/esm2020/lib/objects/action-event.mjs +0 -16
- package/esm2020/lib/services/alert.service.mjs +0 -52
- package/esm2020/lib/services/dashboard.service.mjs +0 -75
- package/esm2020/lib/services/data-processor.service.mjs +0 -56
- package/esm2020/lib/services/data-search.service.mjs +0 -36
- package/esm2020/lib/services/dataset.service.mjs +0 -187
- package/esm2020/lib/services/datasource.service.mjs +0 -93
- package/esm2020/lib/services/external.service.mjs +0 -33
- package/esm2020/lib/services/feed.service.mjs +0 -50
- package/esm2020/lib/services/notification.service.mjs +0 -41
- package/esm2020/lib/services/project.service.mjs +0 -130
- package/esm2020/lib/services/tag.service.mjs +0 -63
- package/esm2020/ng-kinintel.mjs +0 -5
- package/esm2020/public-api.mjs +0 -43
- package/fesm2015/ng-kinintel.mjs +0 -12182
- package/fesm2015/ng-kinintel.mjs.map +0 -1
- package/fesm2020/ng-kinintel.mjs +0 -11872
- package/fesm2020/ng-kinintel.mjs.map +0 -1
- package/lib/components/alert-groups/alert-groups.component.d.ts +0 -30
- package/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.d.ts +0 -28
- package/lib/components/dashboard-editor/configure-item/configure-item.component.d.ts +0 -256
- package/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.d.ts +0 -16
- package/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.d.ts +0 -59
- package/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.d.ts +0 -26
- package/lib/components/dashboard-editor/dashboard-editor.component.d.ts +0 -85
- package/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.d.ts +0 -8
- package/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.d.ts +0 -22
- package/lib/components/dashboard-editor/item-component/item-component.component.d.ts +0 -264
- package/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.d.ts +0 -30
- package/lib/components/dashboards/dashboards.component.d.ts +0 -56
- package/lib/components/dashboards/view-dashboard/view-dashboard.component.d.ts +0 -81
- package/lib/components/data-explorer/change-source-warning/change-source-warning.component.d.ts +0 -11
- package/lib/components/data-explorer/data-explorer.component.d.ts +0 -61
- package/lib/components/data-explorer/export-data/export-data.component.d.ts +0 -17
- package/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.d.ts +0 -25
- package/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.d.ts +0 -44
- package/lib/components/data-picker/data-picker.component.d.ts +0 -32
- package/lib/components/data-search/data-search.component.d.ts +0 -5
- package/lib/components/data-sharing-invite/data-sharing-invite.component.d.ts +0 -21
- package/lib/components/dataset/create-dataset/create-dataset.component.d.ts +0 -17
- package/lib/components/dataset/dataset-editor/available-columns/available-columns.component.d.ts +0 -12
- package/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.d.ts +0 -61
- package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.d.ts +0 -21
- package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.d.ts +0 -20
- package/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.d.ts +0 -19
- package/lib/components/dataset/dataset-editor/dataset-editor.component.d.ts +0 -131
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.d.ts +0 -63
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.d.ts +0 -20
- package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.d.ts +0 -16
- package/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.d.ts +0 -18
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.d.ts +0 -23
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.d.ts +0 -13
- package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.d.ts +0 -22
- package/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.d.ts +0 -27
- package/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.d.ts +0 -11
- package/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.d.ts +0 -25
- package/lib/components/dataset/dataset-editor/share-query/share-query.component.d.ts +0 -41
- package/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.d.ts +0 -11
- package/lib/components/dataset/dataset.component.d.ts +0 -74
- package/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.d.ts +0 -26
- package/lib/components/datasource/create-datasource/api-access/api-access.component.d.ts +0 -31
- package/lib/components/datasource/create-datasource/create-datasource.component.d.ts +0 -112
- package/lib/components/datasource/create-datasource/import-data/import-data.component.d.ts +0 -28
- package/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.d.ts +0 -40
- package/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.d.ts +0 -34
- package/lib/components/datasource/datasource.component.d.ts +0 -46
- package/lib/components/datasource/document-datasource/document-datasource.component.d.ts +0 -64
- package/lib/components/export-project/export-project.component.d.ts +0 -9
- package/lib/components/feeds/feed/feed.component.d.ts +0 -30
- package/lib/components/feeds/feeds.component.d.ts +0 -47
- package/lib/components/job-tasks/job-tasks.component.d.ts +0 -11
- package/lib/components/marketplace/marketplace.component.d.ts +0 -42
- package/lib/components/metadata/metadata.component.d.ts +0 -24
- package/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.d.ts +0 -37
- package/lib/components/notification-groups/notification-groups.component.d.ts +0 -28
- package/lib/components/project-picker/project-picker.component.d.ts +0 -37
- package/lib/components/project-settings/project-link-selection/project-link-selection.component.d.ts +0 -32
- package/lib/components/project-settings/project-settings.component.d.ts +0 -40
- package/lib/components/query-caching/edit-query-cache/edit-query-cache.component.d.ts +0 -17
- package/lib/components/query-caching/query-cache-view/query-cache-view.component.d.ts +0 -35
- package/lib/components/query-caching/query-caching.component.d.ts +0 -38
- package/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.d.ts +0 -21
- package/lib/components/shared-with-me/shared-with-me.component.d.ts +0 -43
- package/lib/components/snapshots/snapshots.component.d.ts +0 -52
- package/lib/components/tag-picker/tag-picker.component.d.ts +0 -27
- package/lib/components/task-time-periods/task-time-periods.component.d.ts +0 -20
- package/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.d.ts +0 -17
- package/lib/guards/dashboard-changes.guard.d.ts +0 -11
- package/lib/kinintel-config.d.ts +0 -10
- package/lib/ng-kinintel.module.d.ts +0 -116
- package/lib/objects/action-event.d.ts +0 -12
- package/lib/services/alert.service.d.ts +0 -17
- package/lib/services/dashboard.service.d.ts +0 -25
- package/lib/services/data-processor.service.d.ts +0 -18
- package/lib/services/data-search.service.d.ts +0 -14
- package/lib/services/dataset.service.d.ts +0 -56
- package/lib/services/datasource.service.d.ts +0 -34
- package/lib/services/external.service.d.ts +0 -12
- package/lib/services/feed.service.d.ts +0 -19
- package/lib/services/notification.service.d.ts +0 -16
- package/lib/services/project.service.d.ts +0 -27
- package/lib/services/tag.service.d.ts +0 -19
- package/public-api.d.ts +0 -38
|
@@ -1,853 +0,0 @@
|
|
|
1
|
-
import { Component, Inject, ViewChild } from '@angular/core';
|
|
2
|
-
import { MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA } from '@angular/material/legacy-dialog';
|
|
3
|
-
import { SourceSelectorDialogComponent } from '../../dashboard-editor/source-selector-dialog/source-selector-dialog.component';
|
|
4
|
-
import * as lodash from 'lodash';
|
|
5
|
-
import chroma from 'chroma-js';
|
|
6
|
-
import { EditDashboardAlertComponent } from '../configure-item/edit-dashboard-alert/edit-dashboard-alert.component';
|
|
7
|
-
import { DatasetFilterComponent } from '../../dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component';
|
|
8
|
-
import { BehaviorSubject, Subject } from 'rxjs';
|
|
9
|
-
import { BaseChartDirective } from 'ng2-charts';
|
|
10
|
-
import regression from 'regression';
|
|
11
|
-
import visNetworkOptions from './vis-network-options.json';
|
|
12
|
-
import { CreateDatasetComponent } from '../../dataset/create-dataset/create-dataset.component';
|
|
13
|
-
import { ChangeSourceWarningComponent } from '../../data-explorer/change-source-warning/change-source-warning.component';
|
|
14
|
-
import * as i0 from "@angular/core";
|
|
15
|
-
import * as i1 from "@angular/material/legacy-dialog";
|
|
16
|
-
import * as i2 from "../../../services/dashboard.service";
|
|
17
|
-
import * as i3 from "../../../services/dataset.service";
|
|
18
|
-
import * as i4 from "../../../services/datasource.service";
|
|
19
|
-
import * as i5 from "@angular/router";
|
|
20
|
-
import * as i6 from "../../../services/project.service";
|
|
21
|
-
import * as i7 from "@angular/common";
|
|
22
|
-
import * as i8 from "@angular/material/legacy-button";
|
|
23
|
-
import * as i9 from "@angular/material/icon";
|
|
24
|
-
import * as i10 from "ng2-charts";
|
|
25
|
-
import * as i11 from "@3dgenomes/ngx-resizable";
|
|
26
|
-
import * as i12 from "@angular/material/legacy-input";
|
|
27
|
-
import * as i13 from "@angular/forms";
|
|
28
|
-
import * as i14 from "@angular/material/legacy-select";
|
|
29
|
-
import * as i15 from "@angular/material/legacy-core";
|
|
30
|
-
import * as i16 from "@angular/material/legacy-slide-toggle";
|
|
31
|
-
import * as i17 from "@angular/material/legacy-checkbox";
|
|
32
|
-
import * as i18 from "@angular/material/legacy-tabs";
|
|
33
|
-
import * as i19 from "@angular/material/legacy-radio";
|
|
34
|
-
import * as i20 from "@ctrl/ngx-codemirror";
|
|
35
|
-
import * as i21 from "../../dataset/dataset-editor/dataset-editor.component";
|
|
36
|
-
import * as i22 from "../../dataset/dataset-editor/dataset-filters/dataset-filters.component";
|
|
37
|
-
import * as i23 from "./html-documentation/html-documentation.component";
|
|
38
|
-
import * as i24 from "./table-cell-formatter/table-cell-formatter.component";
|
|
39
|
-
const _ = lodash.default;
|
|
40
|
-
export class ConfigureItemComponent {
|
|
41
|
-
constructor(dialogRef, data, dialog, dashboardService, datasetService, datasourceService, router, projectService) {
|
|
42
|
-
this.dialogRef = dialogRef;
|
|
43
|
-
this.data = data;
|
|
44
|
-
this.dialog = dialog;
|
|
45
|
-
this.dashboardService = dashboardService;
|
|
46
|
-
this.datasetService = datasetService;
|
|
47
|
-
this.datasourceService = datasourceService;
|
|
48
|
-
this.router = router;
|
|
49
|
-
this.projectService = projectService;
|
|
50
|
-
this.metric = {};
|
|
51
|
-
this.textData = {};
|
|
52
|
-
this.networkData = {};
|
|
53
|
-
this.wordCloud = {};
|
|
54
|
-
this.imageData = {};
|
|
55
|
-
this.tabular = {};
|
|
56
|
-
this.tableCells = {};
|
|
57
|
-
this.general = {};
|
|
58
|
-
this.dependencies = {};
|
|
59
|
-
this.callToAction = {};
|
|
60
|
-
this.actionItem = {};
|
|
61
|
-
this.dashboards = [];
|
|
62
|
-
this.sharedDashboards = [];
|
|
63
|
-
this.privateDashboards = [];
|
|
64
|
-
this.dashboardParameters = [];
|
|
65
|
-
this.dashboardParamValues = [];
|
|
66
|
-
this.actionEvents = [];
|
|
67
|
-
this.filterFields = [];
|
|
68
|
-
this.chartTypes = ['line', 'bar', 'pie', 'doughnut', 'scatter'];
|
|
69
|
-
this.metricFormats = ['Currency', 'Number', 'Percentage'];
|
|
70
|
-
this.currencies = [
|
|
71
|
-
{
|
|
72
|
-
name: 'British Pound (£)',
|
|
73
|
-
value: 'GBP',
|
|
74
|
-
symbol: '£'
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: 'US Dollar ($)',
|
|
78
|
-
value: 'USD',
|
|
79
|
-
symbol: '$'
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'Euro (€)',
|
|
83
|
-
value: 'EUR',
|
|
84
|
-
symbol: '€'
|
|
85
|
-
}
|
|
86
|
-
];
|
|
87
|
-
this.filterJunction = {
|
|
88
|
-
logic: 'AND',
|
|
89
|
-
filters: [{
|
|
90
|
-
lhsExpression: '',
|
|
91
|
-
rhsExpression: '',
|
|
92
|
-
filterType: ''
|
|
93
|
-
}],
|
|
94
|
-
filterJunctions: []
|
|
95
|
-
};
|
|
96
|
-
this.columnFormats = [
|
|
97
|
-
{
|
|
98
|
-
title: 'Number',
|
|
99
|
-
type: 'number'
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
title: 'Currency',
|
|
103
|
-
type: 'currency'
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
title: 'Percentage',
|
|
107
|
-
type: 'percentage'
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
title: 'Date & Time',
|
|
111
|
-
type: 'datetime'
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
title: 'Comparison',
|
|
115
|
-
type: 'comparison'
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
title: 'Link',
|
|
119
|
-
type: 'link'
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
title: 'Custom',
|
|
123
|
-
type: 'custom'
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
title: 'Hide Column',
|
|
127
|
-
type: 'hide'
|
|
128
|
-
}
|
|
129
|
-
];
|
|
130
|
-
this.showAlertWarning = false;
|
|
131
|
-
this.dapFeeds = [];
|
|
132
|
-
this.sideOpen = false;
|
|
133
|
-
this.openSide = new BehaviorSubject(false);
|
|
134
|
-
this._ = _;
|
|
135
|
-
this.docColumns = new Subject();
|
|
136
|
-
this.canSetAlerts = false;
|
|
137
|
-
this.colourPalettes = [];
|
|
138
|
-
this.visNetworkOptions = visNetworkOptions;
|
|
139
|
-
this.availableNodeOptions = [];
|
|
140
|
-
this.availableEdgeOptions = [];
|
|
141
|
-
this.datasetNodes = [];
|
|
142
|
-
this.datasetEdges = [];
|
|
143
|
-
this.widgetParameters = {};
|
|
144
|
-
this.Array = Array;
|
|
145
|
-
this.Object = Object;
|
|
146
|
-
}
|
|
147
|
-
async ngOnInit() {
|
|
148
|
-
this.availableNodeOptions = Object.keys(this.visNetworkOptions.nodes);
|
|
149
|
-
this.availableEdgeOptions = Object.keys(this.visNetworkOptions.edges);
|
|
150
|
-
this.grid = this.data.grid;
|
|
151
|
-
this.dashboard = this.data.dashboard;
|
|
152
|
-
this.dashboardDatasetInstance = this.data.dashboardDatasetInstance;
|
|
153
|
-
this.dashboardItemType = this.data.dashboardItemType;
|
|
154
|
-
this.admin = !!this.data.admin;
|
|
155
|
-
this.actionEvents = this.data.actionEvents || [];
|
|
156
|
-
this.canSetAlerts = this.projectService.doesActiveProjectHavePrivilege('alertmanage');
|
|
157
|
-
if (this.actionEvents.length) {
|
|
158
|
-
this.columnFormats.push({
|
|
159
|
-
title: 'Action',
|
|
160
|
-
type: 'action'
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
if (!this.dashboardItemType.colourMode) {
|
|
164
|
-
this.dashboardItemType.colourMode = 'lrgb';
|
|
165
|
-
}
|
|
166
|
-
if (!this.dashboardItemType.borderColor || !Array.isArray(this.dashboardItemType.borderColor)) {
|
|
167
|
-
this.dashboardItemType.borderColor = [_.isString(this.dashboardItemType.borderColor) ? this.dashboardItemType.borderColor : ''];
|
|
168
|
-
}
|
|
169
|
-
if (!this.dashboardDatasetInstance) {
|
|
170
|
-
this.selectedDatasource();
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
this.loadDashboardItems();
|
|
174
|
-
}
|
|
175
|
-
this.dashboardService.getDashboards('', '100', '0').toPromise().then(dashboards => {
|
|
176
|
-
this.dashboards = dashboards;
|
|
177
|
-
});
|
|
178
|
-
this.dashboardService.getDashboards('', '100', '0', null).toPromise().then(dashboards => {
|
|
179
|
-
this.sharedDashboards = dashboards;
|
|
180
|
-
});
|
|
181
|
-
this.dashboardService.getDashboards('', '100', '0', 0).toPromise().then(dashboards => {
|
|
182
|
-
this.privateDashboards = dashboards;
|
|
183
|
-
});
|
|
184
|
-
this.dapFeeds = await this.datasetService.getDatasets('', '1000', '0', '', '').toPromise();
|
|
185
|
-
this.openSide.subscribe((open) => {
|
|
186
|
-
if (open) {
|
|
187
|
-
document.getElementById('sidebarWrapper2')?.classList.add('z-20');
|
|
188
|
-
document.getElementById('sidebarWrapper2')?.classList.remove('-z-10');
|
|
189
|
-
this.docColumns.next(this.filterFields);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
setTimeout(() => {
|
|
193
|
-
document.getElementById('sidebarWrapper2')?.classList.add('-z-10');
|
|
194
|
-
document.getElementById('sidebarWrapper2')?.classList.remove('z-20');
|
|
195
|
-
}, 700);
|
|
196
|
-
}
|
|
197
|
-
this.sideOpen = open;
|
|
198
|
-
});
|
|
199
|
-
const project = await this.projectService.getProject(this.projectService.activeProject.getValue().projectKey);
|
|
200
|
-
if (project.settings.palettes && project.settings.palettes.length) {
|
|
201
|
-
this.colourPalettes = project.settings.palettes;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
updateChart(newValue, index) {
|
|
205
|
-
this.dashboardItemType.backgroundColor[index] = newValue;
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
this.chart.chart.update();
|
|
208
|
-
}, 50);
|
|
209
|
-
}
|
|
210
|
-
changeSource() {
|
|
211
|
-
const dialogRef = this.dialog.open(CreateDatasetComponent, {
|
|
212
|
-
width: '1200px',
|
|
213
|
-
height: '800px',
|
|
214
|
-
data: {
|
|
215
|
-
admin: this.admin
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
219
|
-
if (res) {
|
|
220
|
-
const dialogRef2 = this.dialog.open(ChangeSourceWarningComponent, {
|
|
221
|
-
width: '700px',
|
|
222
|
-
height: '275px'
|
|
223
|
-
});
|
|
224
|
-
dialogRef2.afterClosed().subscribe(proceed => {
|
|
225
|
-
if (proceed) {
|
|
226
|
-
this.dashboardDatasetInstance.datasetInstanceId = res.datasetInstanceId;
|
|
227
|
-
this.dashboardDatasetInstance.datasourceInstanceKey = res.datasourceInstanceKey;
|
|
228
|
-
this.dashboardDatasetInstance.source = {
|
|
229
|
-
title: res.title,
|
|
230
|
-
datasetInstanceId: res.datasetInstanceId,
|
|
231
|
-
datasourceInstanceKey: res.datasourceInstanceKey,
|
|
232
|
-
type: null
|
|
233
|
-
};
|
|
234
|
-
const transformation = this.dashboardDatasetInstance.transformationInstances[0];
|
|
235
|
-
if (transformation) {
|
|
236
|
-
this.datasetEditorComponent.excludeUpstreamTransformations(transformation, true);
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
this.datasetEditorComponent.evaluateDataset(true);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
selectedDatasource() {
|
|
247
|
-
const dialogRef = this.dialog.open(SourceSelectorDialogComponent, {
|
|
248
|
-
width: '1200px',
|
|
249
|
-
height: '800px',
|
|
250
|
-
data: {
|
|
251
|
-
dashboard: this.dashboard,
|
|
252
|
-
dashboardItemInstanceKey: this.data.itemInstanceKey,
|
|
253
|
-
dashboardDatasetInstance: this.dashboardDatasetInstance || {
|
|
254
|
-
dashboardId: this.dashboard.id,
|
|
255
|
-
instanceKey: this.data.itemInstanceKey,
|
|
256
|
-
transformationInstances: [],
|
|
257
|
-
parameterValues: {},
|
|
258
|
-
parameters: []
|
|
259
|
-
},
|
|
260
|
-
admin: this.admin
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
dialogRef.afterClosed().subscribe(dashboardDatasetInstance => {
|
|
264
|
-
this.dashboardDatasetInstance = dashboardDatasetInstance;
|
|
265
|
-
this.loadDashboardItems();
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
pickNetworkEdgeDataset() {
|
|
269
|
-
const dialogRef = this.dialog.open(SourceSelectorDialogComponent, {
|
|
270
|
-
width: '1200px',
|
|
271
|
-
height: '800px',
|
|
272
|
-
data: {
|
|
273
|
-
dashboard: this.dashboard,
|
|
274
|
-
dashboardItemInstanceKey: this.data.itemInstanceKey,
|
|
275
|
-
dashboardDatasetInstance: this.dashboardDatasetInstance || {
|
|
276
|
-
dashboardId: this.dashboard.id,
|
|
277
|
-
instanceKey: this.data.itemInstanceKey,
|
|
278
|
-
transformationInstances: [],
|
|
279
|
-
parameterValues: {},
|
|
280
|
-
parameters: []
|
|
281
|
-
},
|
|
282
|
-
admin: this.admin
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
dialogRef.afterClosed().subscribe(async (dashboardDatasetInstance) => {
|
|
286
|
-
this.networkData.edgeDatasetId = dashboardDatasetInstance.datasetInstanceId;
|
|
287
|
-
this.networkData.edgeDatasourceKey = dashboardDatasetInstance.datasourceInstanceKey;
|
|
288
|
-
await this.loadEdgeDataset();
|
|
289
|
-
this.networkData.edgeDatasetTitle = dashboardDatasetInstance.title || this.edgeDataset.instanceTitle;
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
async loadEdgeDataset() {
|
|
293
|
-
const datasetInstanceSummary = {
|
|
294
|
-
datasetInstanceId: this.networkData.edgeDatasetId,
|
|
295
|
-
datasourceInstanceKey: this.networkData.edgeDatasourceKey,
|
|
296
|
-
transformationInstances: [],
|
|
297
|
-
parameterValues: {},
|
|
298
|
-
parameters: {}
|
|
299
|
-
};
|
|
300
|
-
this.edgeDataset = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '1');
|
|
301
|
-
}
|
|
302
|
-
clearEdgeDataset() {
|
|
303
|
-
delete this.networkData.edgeDatasetTitle;
|
|
304
|
-
delete this.networkData.edgeDatasetId;
|
|
305
|
-
delete this.networkData.edgeDatasourceKey;
|
|
306
|
-
this.edgeDataset = null;
|
|
307
|
-
}
|
|
308
|
-
addGroupOption(nodeGroup) {
|
|
309
|
-
if (!this.networkData.nodeGroupOptions) {
|
|
310
|
-
this.networkData.nodeGroupOptions = {};
|
|
311
|
-
}
|
|
312
|
-
if (!this.networkData.nodeGroupOptions[nodeGroup]) {
|
|
313
|
-
this.networkData.nodeGroupOptions[nodeGroup] = { options: [] };
|
|
314
|
-
}
|
|
315
|
-
this.networkData.nodeGroupOptions[nodeGroup].options.unshift({});
|
|
316
|
-
}
|
|
317
|
-
addOption(typeOptions) {
|
|
318
|
-
if (!this.networkData[typeOptions] || !Array.isArray(this.networkData[typeOptions])) {
|
|
319
|
-
this.networkData[typeOptions] = [];
|
|
320
|
-
}
|
|
321
|
-
this.networkData[typeOptions].unshift({});
|
|
322
|
-
}
|
|
323
|
-
updateOptions(nodeOption, datasetType) {
|
|
324
|
-
const option = nodeOption.key;
|
|
325
|
-
const column = nodeOption.column;
|
|
326
|
-
let value = nodeOption.value;
|
|
327
|
-
let allData = this.dataset.allData;
|
|
328
|
-
if (datasetType === 'datasetEdges') {
|
|
329
|
-
allData = this.fullEdgeDataset ? this.fullEdgeDataset.allData : this.dataset.allData;
|
|
330
|
-
}
|
|
331
|
-
this[datasetType].forEach(item => {
|
|
332
|
-
if (column) {
|
|
333
|
-
const dataset = _.find(allData, { id: item.id });
|
|
334
|
-
if (dataset) {
|
|
335
|
-
value = dataset[column];
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
const existing = _.find(item.options, { key: option });
|
|
339
|
-
if (existing) {
|
|
340
|
-
existing.value = value;
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
item.options.unshift({ key: option, value });
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
dataLoaded(dataset) {
|
|
348
|
-
this.dataset = dataset;
|
|
349
|
-
this.filterFields = _.map(dataset.columns, column => {
|
|
350
|
-
return {
|
|
351
|
-
title: column.title,
|
|
352
|
-
name: column.name
|
|
353
|
-
};
|
|
354
|
-
});
|
|
355
|
-
this.updateMetricDataValues();
|
|
356
|
-
this.setChartData();
|
|
357
|
-
this.setNetworkChartData();
|
|
358
|
-
}
|
|
359
|
-
async ctaUpdate(cta) {
|
|
360
|
-
this.dashboardParameters = [];
|
|
361
|
-
if (cta) {
|
|
362
|
-
if (cta.type && cta.type === 'dashboard') {
|
|
363
|
-
if (!cta.parameters) {
|
|
364
|
-
cta.parameters = {};
|
|
365
|
-
}
|
|
366
|
-
const dashboard = await this.dashboardService.getDashboard(cta.value);
|
|
367
|
-
if (dashboard.layoutSettings.parameters) {
|
|
368
|
-
this.dashboardParameters = _.values(dashboard.layoutSettings.parameters);
|
|
369
|
-
setTimeout(() => {
|
|
370
|
-
const el = document.getElementsByClassName('dashboard-param-pick').item(0);
|
|
371
|
-
if (el) {
|
|
372
|
-
el.scrollIntoView();
|
|
373
|
-
}
|
|
374
|
-
}, 0);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
cta.parameters = {};
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
setImageData(column) {
|
|
383
|
-
this.imageData.source = column ? this.dataset.allData[0][column] : null;
|
|
384
|
-
}
|
|
385
|
-
setColumn(column) {
|
|
386
|
-
if (!this.tableCells[column] || Array.isArray(this.tableCells[column])) {
|
|
387
|
-
this.tableCells[column] = {};
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
setColumnFormat(format) {
|
|
391
|
-
if (format === 'undefined') {
|
|
392
|
-
delete this.tableCells[this.tableCells.column].type;
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
if (!this.tableCells[this.tableCells.column].data || Array.isArray(this.tableCells[this.tableCells.column].data)) {
|
|
396
|
-
this.tableCells[this.tableCells.column].data = {};
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
editAlert(alert, index) {
|
|
401
|
-
const dialogRef = this.dialog.open(EditDashboardAlertComponent, {
|
|
402
|
-
width: '900px',
|
|
403
|
-
height: '750px',
|
|
404
|
-
data: {
|
|
405
|
-
alert,
|
|
406
|
-
filterFields: this.filterFields
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
dialogRef.afterClosed().subscribe(alertItem => {
|
|
410
|
-
if (alertItem) {
|
|
411
|
-
if (!this.dashboardDatasetInstance.alerts) {
|
|
412
|
-
this.dashboardDatasetInstance.alerts = [];
|
|
413
|
-
}
|
|
414
|
-
if (index >= 0) {
|
|
415
|
-
this.dashboardDatasetInstance.alerts[index] = alertItem;
|
|
416
|
-
}
|
|
417
|
-
else {
|
|
418
|
-
this.dashboardDatasetInstance.alerts.push(alertItem);
|
|
419
|
-
this.showAlertWarning = !this.dashboard.alertsEnabled;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
deleteAlert(index) {
|
|
425
|
-
const message = 'Are you sure you would like to delete this alert?';
|
|
426
|
-
if (window.confirm(message)) {
|
|
427
|
-
this.dashboardDatasetInstance.alerts.splice(index, 1);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
getAlertDetails(alert) {
|
|
431
|
-
let details = '';
|
|
432
|
-
const filter = alert.filterTransformation.filters[0];
|
|
433
|
-
if (filter) {
|
|
434
|
-
const filterType = DatasetFilterComponent.getFilterType(filter.filterType);
|
|
435
|
-
details += `<span class="font-medium">Where</span> ${filter.lhsExpression} `;
|
|
436
|
-
details += filterType ? filterType.label : '';
|
|
437
|
-
details += ` ${filter.rhsExpression}`;
|
|
438
|
-
}
|
|
439
|
-
const matchRule = alert.matchRuleConfiguration;
|
|
440
|
-
if (matchRule && alert.matchRuleType === 'rowcount') {
|
|
441
|
-
if (matchRule.matchType === 'equals') {
|
|
442
|
-
details += ` <span class="font-medium">And</span> exactly ${matchRule.value} row${matchRule.value > 1 ? 's' : ''} returned`;
|
|
443
|
-
}
|
|
444
|
-
else if (matchRule.matchType === 'greater') {
|
|
445
|
-
details += ` <span class="font-medium">And</span> more than ${matchRule.value} row${matchRule.value > 1 ? 's' : ''} returned`;
|
|
446
|
-
}
|
|
447
|
-
else if (matchRule.matchType === 'less') {
|
|
448
|
-
details += ` <span class="font-medium">And</span> less than ${matchRule.value} row${matchRule.value > 1 ? 's' : ''} returned`;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
return details;
|
|
452
|
-
}
|
|
453
|
-
setCallToActionItem(d1, d2) {
|
|
454
|
-
if (!d2) {
|
|
455
|
-
return true;
|
|
456
|
-
}
|
|
457
|
-
if (d2.type === 'custom') {
|
|
458
|
-
return d1.type === 'custom';
|
|
459
|
-
}
|
|
460
|
-
else if (d2.type === 'dashboard' || d2.type === 'feed') {
|
|
461
|
-
return d1.value === d2.value;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
ctaSelectOption(c1, c2) {
|
|
465
|
-
return c1 === c2;
|
|
466
|
-
}
|
|
467
|
-
paletteSelectOption(c1, c2) {
|
|
468
|
-
if (!c2) {
|
|
469
|
-
return true;
|
|
470
|
-
}
|
|
471
|
-
return c1.name === c2.name;
|
|
472
|
-
}
|
|
473
|
-
depSelection(c1, c2) {
|
|
474
|
-
if (!c2) {
|
|
475
|
-
return true;
|
|
476
|
-
}
|
|
477
|
-
return c1.type === c2.type;
|
|
478
|
-
}
|
|
479
|
-
backgroundColourUpdate() {
|
|
480
|
-
const colours = this.dashboardItemType.colourPalette ? this.dashboardItemType.colourPalette.colours : [
|
|
481
|
-
this.dashboardItemType.backgroundColorFrom || 'black',
|
|
482
|
-
this.dashboardItemType.backgroundColorTo || 'black'
|
|
483
|
-
];
|
|
484
|
-
if (this.dashboardItemType.colourMode !== 'repeat') {
|
|
485
|
-
const chromaScale = chroma.scale(colours);
|
|
486
|
-
chromaScale.mode(this.dashboardItemType.colourMode);
|
|
487
|
-
this.dashboardItemType.backgroundColor = chromaScale.colors(this.dashboardItemType.labels.length);
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
this.repeatColours(colours);
|
|
491
|
-
}
|
|
492
|
-
setTimeout(() => {
|
|
493
|
-
this.setChartData();
|
|
494
|
-
}, 50);
|
|
495
|
-
}
|
|
496
|
-
async updateInstanceFilterFields(change, instanceKey) {
|
|
497
|
-
if (change.type === 'MATCH') {
|
|
498
|
-
const selectedDatasetInstance = _.find(this.dashboard.datasetInstances, { instanceKey });
|
|
499
|
-
if (selectedDatasetInstance) {
|
|
500
|
-
const mappedParams = {};
|
|
501
|
-
_.forEach(selectedDatasetInstance.parameterValues, (value, key) => {
|
|
502
|
-
if (_.isString(value) && value.includes('{{')) {
|
|
503
|
-
const globalKey = value.replace('{{', '').replace('}}', '');
|
|
504
|
-
if (this.dashboard.layoutSettings.parameters && this.dashboard.layoutSettings.parameters[globalKey]) {
|
|
505
|
-
mappedParams[key] = this.dashboard.layoutSettings.parameters[globalKey].value;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
else {
|
|
509
|
-
mappedParams[key] = value;
|
|
510
|
-
}
|
|
511
|
-
});
|
|
512
|
-
const datasetInstanceSummary = {
|
|
513
|
-
datasetInstanceId: selectedDatasetInstance.datasetInstanceId,
|
|
514
|
-
datasourceInstanceKey: selectedDatasetInstance.datasourceInstanceKey,
|
|
515
|
-
transformationInstances: selectedDatasetInstance.transformationInstances,
|
|
516
|
-
parameterValues: mappedParams,
|
|
517
|
-
parameters: selectedDatasetInstance.parameters
|
|
518
|
-
};
|
|
519
|
-
this.dataset = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '10');
|
|
520
|
-
this.dependencies[instanceKey].filterFields = _.map(this.dataset.columns, column => {
|
|
521
|
-
return {
|
|
522
|
-
title: column.title,
|
|
523
|
-
name: column.name
|
|
524
|
-
};
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
async saveDashboard() {
|
|
530
|
-
const grid = this.grid.save(true);
|
|
531
|
-
if (!this.dashboard.layoutSettings) {
|
|
532
|
-
this.dashboard.layoutSettings = {};
|
|
533
|
-
}
|
|
534
|
-
this.dashboard.layoutSettings.grid = grid;
|
|
535
|
-
if (!this.dashboard.layoutSettings.charts) {
|
|
536
|
-
this.dashboard.layoutSettings.charts = {};
|
|
537
|
-
}
|
|
538
|
-
this.dashboard.layoutSettings.charts[this.dashboardDatasetInstance.instanceKey] = this.dashboardItemType;
|
|
539
|
-
this.mapComponentDataToDashboardInstance();
|
|
540
|
-
if (!this.networkData.nodeLevelOptions || Array.isArray(this.networkData.nodeLevelOptions)) {
|
|
541
|
-
this.networkData.nodeLevelOptions = {};
|
|
542
|
-
}
|
|
543
|
-
this.datasetNodes.forEach(node => {
|
|
544
|
-
if (node.options && node.options.length) {
|
|
545
|
-
this.networkData.nodeLevelOptions[node.id] = node.options;
|
|
546
|
-
}
|
|
547
|
-
});
|
|
548
|
-
if (!this.networkData.edgeLevelOptions || !Array.isArray(this.networkData.edgeLevelOptions)) {
|
|
549
|
-
this.networkData.edgeLevelOptions = [];
|
|
550
|
-
}
|
|
551
|
-
this.datasetEdges.forEach(edge => {
|
|
552
|
-
if (edge.options && edge.options.length) {
|
|
553
|
-
this.networkData.edgeLevelOptions.push(edge);
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
// If there is an old instance remove it, and then add the new/updated one.
|
|
557
|
-
_.remove(this.dashboard.datasetInstances, { instanceKey: this.dashboardDatasetInstance.instanceKey });
|
|
558
|
-
_.remove(this.dashboardDatasetInstance.transformationInstances, { type: 'paging' });
|
|
559
|
-
this.dashboard.datasetInstances.push(this.dashboardDatasetInstance);
|
|
560
|
-
this.dialogRef.close(this.dashboardDatasetInstance);
|
|
561
|
-
}
|
|
562
|
-
resetDefaultColours() {
|
|
563
|
-
this.dashboardItemType.backgroundColorFrom = null;
|
|
564
|
-
this.dashboardItemType.backgroundColorTo = null;
|
|
565
|
-
this.setChartData();
|
|
566
|
-
}
|
|
567
|
-
updateColourPalette() {
|
|
568
|
-
if (this.dashboardItemType.colourPalette) {
|
|
569
|
-
this.dashboardItemType.colourMode = 'repeat';
|
|
570
|
-
this.repeatColours(this.dashboardItemType.colourPalette.colours);
|
|
571
|
-
this.setChartData();
|
|
572
|
-
}
|
|
573
|
-
else {
|
|
574
|
-
this.backgroundColourUpdate();
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
async setChartData() {
|
|
578
|
-
if (this.dashboardItemType.xAxis && this.dashboardItemType.yAxis) {
|
|
579
|
-
let data;
|
|
580
|
-
if (!this.dashboardItemType.seriesColumn) {
|
|
581
|
-
if (this.dashboardItemType.type !== 'pie' && this.dashboardItemType.type !== 'doughnut') {
|
|
582
|
-
data = _.map(this.dataset.allData, item => {
|
|
583
|
-
return { x: item[this.dashboardItemType.xAxis], y: item[this.dashboardItemType.yAxis] };
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
else {
|
|
587
|
-
data = _.map(this.dataset.allData, item => {
|
|
588
|
-
return item[this.dashboardItemType.yAxis];
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
this.chartData = [
|
|
592
|
-
{
|
|
593
|
-
data,
|
|
594
|
-
label: _.find(this.filterFields, { name: this.dashboardItemType.xAxis }).title,
|
|
595
|
-
fill: !!this.dashboardItemType.fill,
|
|
596
|
-
borderColor: (this.dashboardItemType.type === 'pie' || this.dashboardItemType.type === 'doughnut') ? chroma('white').alpha(0.2).hex() : this.dashboardItemType.borderColor,
|
|
597
|
-
backgroundColor: (this.dashboardItemType.type === 'line' || this.dashboardItemType.type === 'scatter') ?
|
|
598
|
-
(Array.isArray(this.dashboardItemType.borderColor) ? _.map(this.dashboardItemType.borderColor, colour => {
|
|
599
|
-
return chroma(colour || 'black').alpha(0.5).hex();
|
|
600
|
-
}) : chroma(this.dashboardItemType.borderColor || 'black').alpha(0.5).hex()) : this.dashboardItemType.backgroundColor,
|
|
601
|
-
tension: 0.2,
|
|
602
|
-
pointBackgroundColor: this.dashboardItemType.borderColor ? this.dashboardItemType.borderColor[0] : null,
|
|
603
|
-
pointBorderColor: this.dashboardItemType.borderColor ? this.dashboardItemType.borderColor[0] : null
|
|
604
|
-
}
|
|
605
|
-
];
|
|
606
|
-
this.dashboardItemType.labels = _.map(this.dataset.allData, item => {
|
|
607
|
-
return item[this.dashboardItemType.xAxis];
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
const chartData = [];
|
|
612
|
-
const series = _.uniq(_.map(this.dataset.allData, this.dashboardItemType.seriesColumn));
|
|
613
|
-
series.forEach((value, index) => {
|
|
614
|
-
const seriesResults = _.filter(this.dataset.allData, allData => {
|
|
615
|
-
return allData[this.dashboardItemType.seriesColumn] === value;
|
|
616
|
-
});
|
|
617
|
-
chartData.push({
|
|
618
|
-
data: _.map(seriesResults, item => {
|
|
619
|
-
return { x: item[this.dashboardItemType.xAxis], y: item[this.dashboardItemType.yAxis] };
|
|
620
|
-
}),
|
|
621
|
-
label: value,
|
|
622
|
-
fill: !!this.dashboardItemType.fill,
|
|
623
|
-
borderColor: this.dashboardItemType.borderColor,
|
|
624
|
-
backgroundColor: (this.dashboardItemType.type === 'line' || this.dashboardItemType.type === 'scatter') ?
|
|
625
|
-
(Array.isArray(this.dashboardItemType.borderColor) ? _.map(this.dashboardItemType.borderColor, colour => {
|
|
626
|
-
return chroma(colour || 'black').alpha(0.5).hex();
|
|
627
|
-
}) : chroma(this.dashboardItemType.borderColor || 'black').alpha(0.5).hex()) : this.dashboardItemType.backgroundColor[index],
|
|
628
|
-
tension: 0.2,
|
|
629
|
-
pointBackgroundColor: this.dashboardItemType.borderColor[index],
|
|
630
|
-
pointBorderColor: this.dashboardItemType.borderColor[index]
|
|
631
|
-
});
|
|
632
|
-
});
|
|
633
|
-
this.chartData = chartData;
|
|
634
|
-
this.dashboardItemType.labels = _.uniq(_.map(this.dataset.allData, item => {
|
|
635
|
-
return item[this.dashboardItemType.xAxis];
|
|
636
|
-
}));
|
|
637
|
-
}
|
|
638
|
-
if (this.dashboardItemType.trendLine &&
|
|
639
|
-
this.dashboardItemType.type !== 'pie' &&
|
|
640
|
-
this.dashboardItemType.type !== 'doughnut') {
|
|
641
|
-
let trendLine = [];
|
|
642
|
-
let trendLabel = 'Trend';
|
|
643
|
-
if (this.dashboardItemType.trendLine === 'average') {
|
|
644
|
-
trendLabel = 'Average';
|
|
645
|
-
const trendData = [];
|
|
646
|
-
this.chartData.forEach(dataItem => {
|
|
647
|
-
trendData.push(_.map(dataItem.data, 'y'));
|
|
648
|
-
});
|
|
649
|
-
const average = _.flatMap(trendData).reduce((p, c) => p + c, 0) / _.flatMap(trendData).length;
|
|
650
|
-
trendLine = _.fill(_.range(0, _.flatMap(trendData).length), average, 0, _.flatMap(trendData).length);
|
|
651
|
-
}
|
|
652
|
-
else if (this.dashboardItemType.trendLine === 'logarithmic' ||
|
|
653
|
-
this.dashboardItemType.trendLine === 'linear' ||
|
|
654
|
-
this.dashboardItemType.trendLine === 'power' ||
|
|
655
|
-
this.dashboardItemType.trendLine === 'exponential') {
|
|
656
|
-
const trendLineData = _.map(this.dataset.allData, (item, index) => {
|
|
657
|
-
return { x: index + 1, y: item[this.dashboardItemType.yAxis] };
|
|
658
|
-
}).filter(({ x, y }) => {
|
|
659
|
-
return (typeof x === typeof y &&
|
|
660
|
-
!isNaN(x) &&
|
|
661
|
-
!isNaN(y) &&
|
|
662
|
-
Math.abs(x) !== Infinity &&
|
|
663
|
-
Math.abs(y) !== Infinity);
|
|
664
|
-
}).map(({ x, y }) => {
|
|
665
|
-
return [x, y];
|
|
666
|
-
});
|
|
667
|
-
const trendLineResults = regression[this.dashboardItemType.trendLine](trendLineData);
|
|
668
|
-
trendLine = trendLineResults.points.map(([x, y]) => {
|
|
669
|
-
return y;
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
trendLine = _.map(this.dataset.allData, item => {
|
|
674
|
-
return item[this.dashboardItemType.trendLine];
|
|
675
|
-
});
|
|
676
|
-
trendLabel = _.find(this.filterFields, { name: this.dashboardItemType.trendLine }).title;
|
|
677
|
-
}
|
|
678
|
-
this.chartData.push({
|
|
679
|
-
type: 'line',
|
|
680
|
-
data: trendLine,
|
|
681
|
-
label: trendLabel,
|
|
682
|
-
borderColor: this.dashboardItemType.trendLineColour,
|
|
683
|
-
fill: false,
|
|
684
|
-
order: -1,
|
|
685
|
-
tension: 0.15,
|
|
686
|
-
pointBackgroundColor: this.dashboardItemType.trendLineColour,
|
|
687
|
-
pointBorderColor: this.dashboardItemType.trendLineColour
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
updateMetricDataValues() {
|
|
693
|
-
if (this.metric.main) {
|
|
694
|
-
this.metric.mainValue = _.isNaN(Number(this.dataset.allData[0][this.metric.main])) ? this.dataset.allData[0][this.metric.main] : Number(this.dataset.allData[0][this.metric.main]);
|
|
695
|
-
this.metric.title = _.startCase(this.metric.main);
|
|
696
|
-
}
|
|
697
|
-
if (this.metric.subMetric) {
|
|
698
|
-
this.metric.subValue = Number(this.dataset.allData[0][this.metric.subMetric]);
|
|
699
|
-
this.metric.subTitle = _.startCase(this.metric.subMetric);
|
|
700
|
-
}
|
|
701
|
-
if (this.metric.showSubChange) {
|
|
702
|
-
this.metric.difference = Math.abs(this.metric.mainValue - this.metric.subValue);
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
mapLayoutSettingsToComponentData() {
|
|
706
|
-
_.forEach(this.dashboard.layoutSettings, (data, key) => {
|
|
707
|
-
if (key !== 'grid') {
|
|
708
|
-
const defaultValue = _.isPlainObject(this[key]) ? {} : [];
|
|
709
|
-
this[key] = Object.keys(data).length ?
|
|
710
|
-
(data[this.dashboardDatasetInstance.instanceKey] && Object.keys(data[this.dashboardDatasetInstance.instanceKey]).length ?
|
|
711
|
-
data[this.dashboardDatasetInstance.instanceKey] : defaultValue) : defaultValue;
|
|
712
|
-
}
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
mapComponentDataToDashboardInstance() {
|
|
716
|
-
const layoutSettings = ['metric', 'dependencies', 'tabular', 'tableCells', 'general', 'imageData', 'textData', 'callToAction', 'wordCloud', 'actionItem', 'networkData'];
|
|
717
|
-
layoutSettings.forEach(setting => {
|
|
718
|
-
if (!this.dashboard.layoutSettings[setting]) {
|
|
719
|
-
this.dashboard.layoutSettings[setting] = {};
|
|
720
|
-
}
|
|
721
|
-
const defaultData = _.isPlainObject(this[setting]) ? {} : [];
|
|
722
|
-
this.dashboard.layoutSettings[setting][this.dashboardDatasetInstance.instanceKey] = this[setting] || defaultData;
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
repeatColours(colours) {
|
|
726
|
-
this.dashboardItemType.backgroundColor = [];
|
|
727
|
-
this.dashboardItemType.borderColor = [];
|
|
728
|
-
while (this.dashboardItemType.backgroundColor.length < this.dataset.allData.length) {
|
|
729
|
-
for (const colour of colours) {
|
|
730
|
-
this.dashboardItemType.backgroundColor.push(colour);
|
|
731
|
-
if (this.dashboardItemType.backgroundColor.length === this.dataset.allData.length) {
|
|
732
|
-
break;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
const dataLength = (this.dashboardItemType.type === 'line' || this.dashboardItemType.type === 'scatter') ? this.chartData.length : this.dataset.allData;
|
|
737
|
-
while (this.dashboardItemType.borderColor.length < dataLength) {
|
|
738
|
-
for (const colour of colours) {
|
|
739
|
-
this.dashboardItemType.borderColor.push(colour);
|
|
740
|
-
if (this.dashboardItemType.borderColor.length === dataLength) {
|
|
741
|
-
break;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
loadDashboardItems() {
|
|
747
|
-
if (this.dashboard.layoutSettings) {
|
|
748
|
-
this.mapLayoutSettingsToComponentData();
|
|
749
|
-
if (!this.general.parameterBar) {
|
|
750
|
-
this.general.parameterBar = {};
|
|
751
|
-
}
|
|
752
|
-
if (this.dashboard.layoutSettings.parameters) {
|
|
753
|
-
this.dashboardParamValues = _(this.dashboard.layoutSettings.parameters)
|
|
754
|
-
.filter('value')
|
|
755
|
-
.map('value')
|
|
756
|
-
.valueOf();
|
|
757
|
-
}
|
|
758
|
-
this.widgetParameters = _.cloneDeep(this.dashboard.layoutSettings.parameters);
|
|
759
|
-
if (this.general.widgetParameters && Object.keys(this.general.widgetParameters).length) {
|
|
760
|
-
_.forEach(this.general.widgetParameters, widgetParam => {
|
|
761
|
-
if (widgetParam.value) {
|
|
762
|
-
this.widgetParameters[widgetParam.name].value = widgetParam.value;
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
const matchDependencies = _.filter(this.dependencies, (dep, key) => {
|
|
767
|
-
if (dep.type === 'MATCH') {
|
|
768
|
-
dep.key = key;
|
|
769
|
-
return true;
|
|
770
|
-
}
|
|
771
|
-
return false;
|
|
772
|
-
});
|
|
773
|
-
matchDependencies.forEach(dep => {
|
|
774
|
-
this.updateInstanceFilterFields(dep, dep.key);
|
|
775
|
-
});
|
|
776
|
-
if (this.tabular.cta) {
|
|
777
|
-
this.ctaUpdate(this.tabular.cta);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
async setNetworkChartData(reload = false) {
|
|
782
|
-
if (!reload && this.networkData.edgeDatasetTitle) {
|
|
783
|
-
await this.loadEdgeDataset();
|
|
784
|
-
}
|
|
785
|
-
const nodeData = this.dataset.allData;
|
|
786
|
-
this.datasetNodes = [];
|
|
787
|
-
this.datasetEdges = [];
|
|
788
|
-
nodeData.forEach(item => {
|
|
789
|
-
let nodeOptions = [];
|
|
790
|
-
if (this.networkData.nodeLevelOptions && Object.keys(this.networkData.nodeLevelOptions).length &&
|
|
791
|
-
this.networkData.nodeLevelOptions[item[this.networkData.nodeIds]]) {
|
|
792
|
-
nodeOptions = this.networkData.nodeLevelOptions[item[this.networkData.nodeIds]];
|
|
793
|
-
}
|
|
794
|
-
this.datasetNodes.push({
|
|
795
|
-
id: item[this.networkData.nodeIds],
|
|
796
|
-
label: item[this.networkData.nodeLabels],
|
|
797
|
-
group: item[this.networkData.nodeGroups],
|
|
798
|
-
options: nodeOptions
|
|
799
|
-
});
|
|
800
|
-
if (!this.networkData.edgeDatasetTitle) {
|
|
801
|
-
this.datasetEdges.push({
|
|
802
|
-
from: item[this.networkData.fromIds],
|
|
803
|
-
to: item[this.networkData.toIds],
|
|
804
|
-
options: []
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
});
|
|
808
|
-
if (this.networkData.edgeDatasetTitle) {
|
|
809
|
-
const datasetInstanceSummary = {
|
|
810
|
-
datasetInstanceId: this.networkData.edgeDatasetId,
|
|
811
|
-
datasourceInstanceKey: this.networkData.edgeDatasourceKey,
|
|
812
|
-
transformationInstances: [],
|
|
813
|
-
parameterValues: {},
|
|
814
|
-
parameters: {}
|
|
815
|
-
};
|
|
816
|
-
this.fullEdgeDataset = await this.datasetService.evaluateDataset(datasetInstanceSummary, '0', '10000000');
|
|
817
|
-
this.fullEdgeDataset.allData.forEach(item => {
|
|
818
|
-
this.datasetEdges.push({
|
|
819
|
-
from: item[this.networkData.fromIds],
|
|
820
|
-
to: item[this.networkData.toIds],
|
|
821
|
-
options: []
|
|
822
|
-
});
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
this.nodeGroups = _(this.datasetNodes)
|
|
826
|
-
.filter('group')
|
|
827
|
-
.map('group')
|
|
828
|
-
.uniq()
|
|
829
|
-
.valueOf();
|
|
830
|
-
this.datasetEdges.forEach(edge => {
|
|
831
|
-
const edgeOptions = _.find(this.networkData.edgeLevelOptions, { from: edge.from, to: edge.to });
|
|
832
|
-
if (edgeOptions) {
|
|
833
|
-
edge.options = edgeOptions.options;
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
ConfigureItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigureItemComponent, deps: [{ token: i1.MatLegacyDialogRef }, { token: MAT_DIALOG_DATA }, { token: i1.MatLegacyDialog }, { token: i2.DashboardService }, { token: i3.DatasetService }, { token: i4.DatasourceService }, { token: i5.Router }, { token: i6.ProjectService }], target: i0.ɵɵFactoryTarget.Component });
|
|
839
|
-
ConfigureItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ConfigureItemComponent, selector: "ki-configure-item", host: { classAttribute: "configure-dialog" }, viewQueries: [{ propertyName: "chart", first: true, predicate: BaseChartDirective, descendants: true }, { propertyName: "datasetEditorComponent", first: true, predicate: ["datasetEditorComponent"], descendants: true }], ngImport: i0, template: "<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper2\">\n <div [ngClass]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-html-documentation [columns]=\"docColumns\"></ki-html-documentation>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"configure-header\">\n Configure {{dashboardItemType.label}}\n <button mat-button (click)=\"saveDashboard()\">\n <div class=\"flex items-center\">\n <mat-icon class=\"mr-1\">chevron_left</mat-icon>\n Back to Dashboard\n </div>\n </button>\n</div>\n<nav class=\"h-10 flex border-b border-gray-200 bg-white\" aria-label=\"Breadcrumb\">\n <ol role=\"list\" class=\"flex w-full px-4\">\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <a mat-dialog-close [routerLink]=\"['/']\" class=\"text-gray-600 hover:text-gray-800 flex items-center\">\n <span class=\"material-symbols-outlined\">home</span>\n </a>\n </div>\n </li>\n\n <li class=\"flex truncate\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a mat-dialog-close [routerLink]=\"['/dashboards']\"\n class=\"capitalize ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n Dashboards</a>\n </div>\n </li>\n\n <li class=\"flex truncate\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a (click)=\"saveDashboard()\"\n class=\"capitalize ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n Dashboard Editor</a>\n </div>\n </li>\n\n <li class=\"flex\" *ngIf=\"dashboardDatasetInstance\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a class=\"ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\" aria-current=\"page\">\n {{dashboardItemType.label}} Editor\n </a>\n <ng-template [ngIf]=\"dashboardDatasetInstance && dashboardDatasetInstance.source\">\n <span\n class=\"flex items-center border border-gray-200 text-xs px-2 py-0 rounded-xl ml-2 font-thin bg-gray-100\">\n <span class=\"uppercase tracking-wider text-gray-700 font-medium\">Querying:</span>\n <ng-template [ngIf]=\"dashboardDatasetInstance.source.datasourceInstanceKey\">\n <img *ngIf=\"['custom', 'snapshot'].indexOf(dashboardDatasetInstance.source.type) === -1\"\n src=\"/assets/favicon-rev.png\" class=\"w-2.5 mx-1.5\">\n <span *ngIf=\"dashboardDatasetInstance.source.type === 'custom'\"\n class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">upload_file</span>\n <span *ngIf=\"dashboardDatasetInstance.source.type === 'snapshot'\"\n class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">history</span>\n </ng-template>\n <ng-template [ngIf]=\"!dashboardDatasetInstance.source.datasourceInstanceKey\">\n <span class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">query_stats</span>\n </ng-template>\n {{dashboardDatasetInstance.source.title}}\n <span class=\"material-symbols-outlined ml-2 cursor-pointer\" title=\"Change source query\"\n (click)=\"changeSource()\">change_circle</span>\n </span>\n </ng-template>\n </div>\n </li>\n </ol>\n</nav>\n<div class=\"configure-content\">\n\n <rsz-layout class=\"row top\" [directions]=\"['bottom']\" [rFlex]=\"true\">\n <div class=\"cell-contents p-0\">\n <div *ngIf=\"!dashboardDatasetInstance\" class=\"flex items-center justify-center h-full w-full\">\n <div class=\"flex items-center flex-col\">\n <button mat-stroked-button color=\"primary\" class=\"config-button\"\n (click)=\"selectedDatasource()\">\n Configure {{dashboardItemType.label}}\n </button>\n <p class=\"font-light w-3/4 text-center mt-4\">\n Please configure this {{dashboardItemType.label}} using a data feed or stored query.\n </p>\n </div>\n </div>\n\n <ki-dataset-editor #datasetEditorComponent *ngIf=\"dashboardDatasetInstance\" [(datasetInstanceSummary)]=\"dashboardDatasetInstance\"\n (dataLoaded)=\"dataLoaded($event)\" [admin]=\"admin\" [dashboardLayoutSettings]=\"general\"\n [dashboardParameters]=\"widgetParameters\"></ki-dataset-editor>\n </div>\n </rsz-layout>\n\n <rsz-layout class=\"row bottom\" [directions]=\"['none']\" [rFlex]=\"false\">\n <mat-tab-group class=\"gray-header h-full\">\n <mat-tab label=\"Header\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Header Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for the Title and Description fields\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"flex justify-between\">\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Title\n <input type=\"text\" [(ngModel)]=\"general.name\">\n <small class=\"font-normal\">Title of the item</small>\n </label>\n <label class=\"mb-2\">\n Description\n <textarea class=\"font-mono w-full\"\n cols=\"30\" rows=\"5\" [(ngModel)]=\"general.description\"></textarea>\n <small class=\"font-normal\">Description of the data item.</small>\n </label>\n\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.transparent\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Transparent background</p>\n </div>\n <small class=\"mb-4 block font-normal\">Make this dashboard items background transparent -\n requires page refresh to take affect</small>\n\n <ng-template [ngIf]=\"dashboard.layoutSettings && dashboard.layoutSettings.parameters && Object.keys(dashboard.layoutSettings.parameters).length\">\n <div class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.showParameterBar\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Show Parameter Bar</p>\n </div>\n <small class=\"mb-4 block font-normal\">\n Enable which parameters to show in this widget. Values entered here will only reload\n this widget.\n </small>\n\n <ng-template [ngIf]=\"general.showParameterBar\">\n <div class=\"border-l-2 pl-4\">\n <div *ngFor=\"let parameterKey of Object.keys(dashboard.layoutSettings.parameters)\"\n class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.parameterBar[parameterKey]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">{{dashboard.layoutSettings.parameters[parameterKey].title}}</p>\n </div>\n </div>\n\n </ng-template>\n\n </ng-template>\n </div>\n </div>\n </div>\n\n\n </mat-tab>\n <mat-tab label=\"Footer\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Footer Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for the footer field\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Footer\n <input type=\"text\" [(ngModel)]=\"general.footer\">\n <small class=\"font-normal\">Text to display at the bottom of the item</small>\n </label>\n\n <label class=\"mb-2\">\n Call to action\n <select matNativeControl [(ngModel)]=\"callToAction\" [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom'}\">Custom Link</option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup *ngIf=\"admin\" label=\"DAP Data Feeds\">\n <option *ngFor=\"let dapFeed of dapFeeds\"\n [ngValue]=\"{type: 'feed', value: dapFeed.id, label: dapFeed.title}\">{{dapFeed.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"callToAction.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"callToAction.link\">\n </label>\n\n </ng-template>\n\n <label class=\"mb-2\">\n Set action label\n <input type=\"text\" [(ngModel)]=\"callToAction.label\">\n </label>\n\n <ng-template [ngIf]=\"callToAction && callToAction.parameters && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!callToAction.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"callToAction.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option [value]=\"undefined\">-- Select Value --</option>\n <option *ngFor=\"let paramValue of dashboardParamValues\"\n [value]=\"paramValue\">\n {{paramValue}}\n </option>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-1\"\n [(ngModel)]=\"callToAction.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"callToAction.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"callToAction.parameters[param.name]\">\n </label>\n </ng-template>\n\n\n </ng-template>\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Dependencies\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Dependency Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n If the loading of this widget is dependant on the results of another,\n you can set the dependency here.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex justify-between\">\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the dashboard item(s) this depends on\n <mat-select [(ngModel)]=\"dependencies.instanceKeys\" multiple>\n <mat-option *ngFor=\"let instance of dashboard.datasetInstances\"\n [value]=\"instance.instanceKey\">\n {{dashboard.layoutSettings.general ? (dashboard.layoutSettings.general[instance.instanceKey] ? dashboard.layoutSettings.general[instance.instanceKey].name || instance.instanceKey : instance.instanceKey) : instance.instanceKey }}\n </mat-option>\n </mat-select>\n </label>\n\n <ng-template ngFor let-instanceKey [ngForOf]=\"dependencies.instanceKeys\">\n <label class=\"mb-2\">\n Dependency result type for\n {{dashboard.layoutSettings.general ? (dashboard.layoutSettings.general[instanceKey] ? dashboard.layoutSettings.general[instanceKey].name || instanceKey : instanceKey) : instanceKey }}\n <mat-select [(ngModel)]=\"dependencies[instanceKey]\" [compareWith]=\"depSelection\"\n (ngModelChange)=\"updateInstanceFilterFields($event, instanceKey)\">\n <mat-option [value]=\"{type: null}\">-- Select Type --</mat-option>\n <mat-option [value]=\"{type: 'LOADED'}\">Loaded</mat-option>\n <mat-option\n [value]=\"{type: 'MATCH', filterJunction: _.clone(filterJunction), key: instanceKey}\">\n Matches Criteria\n </mat-option>\n </mat-select>\n </label>\n\n <ng-template\n [ngIf]=\"dependencies[instanceKey] && dependencies[instanceKey].type === 'MATCH'\">\n <div class=\"w-full flex items-center\"\n *ngIf=\"!dependencies[instanceKey].filterFields\">\n Loading filter component...\n </div>\n <ki-dataset-filters *ngIf=\"dependencies[instanceKey].filterFields\" class=\"ml-0\"\n [filterJunction]=\"dependencies[instanceKey].filterJunction\"\n [filterFields]=\"dependencies[instanceKey].filterFields\"></ki-dataset-filters>\n </ng-template>\n\n </ng-template>\n\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n No data notice message\n <input type=\"text\" [(ngModel)]=\"dependencies.notice\">\n <small class=\"font-normal\">Enter the message to display when no data is returned from\n dependency.</small>\n </label>\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Action\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Action Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure available actions that can be performed on this item.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"font-medium mb-2\">\n Navigate to another dashboard or URL by clicking on this widget item.\n </div>\n\n <label class=\"mb-2\">\n Destination\n <select matNativeControl [(ngModel)]=\"actionItem\" [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom'}\">Custom Link</option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Shared Dashboards\">\n <option *ngFor=\"let dashboard of sharedDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Private Dashboards\" *ngIf=\"privateDashboards.length\">\n <option *ngFor=\"let dashboard of privateDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"actionItem.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"actionItem.link\">\n </label>\n\n </ng-template>\n\n <ng-template [ngIf]=\"actionItem && actionItem.parameters && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!actionItem.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"actionItem.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option [value]=\"undefined\">-- Select Value --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"'[['+column.name+']]'\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-1\"\n [(ngModel)]=\"actionItem.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"actionItem.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"actionItem.parameters[param.name]\">\n </label>\n </ng-template>\n\n\n </ng-template>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Text\" *ngIf=\"dashboardItemType.type === 'text'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Text Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for this item.\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <ngx-codemirror\n [(ngModel)]=\"textData.value\"\n [options]=\"{lineNumbers: true,theme: 'ttcn',mode: 'htmlmixed',autoRefresh: true,smartIndent: true,extraKeys: {'Ctrl-Space': 'autocomplete'}}\">\n\n </ngx-codemirror>\n </mat-tab>\n <mat-tab label=\"Image\" *ngIf=\"dashboardItemType.type === 'image'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Image Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Set the image to be displayed in this widget.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the column that corresponds to the desired image\n <select matNativeControl [(ngModel)]=\"imageData.column\"\n (ngModelChange)=\"setImageData($event)\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Table\" *ngIf=\"dashboardItemType.type === 'table'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Table Row Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings to be applied to each table row.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.expandRows\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Expand rows. By default rows are compressed and restrict wrapping.</p>\n </div>\n\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.hidePager\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Hide the pager at the bottom of the table.</p>\n </div>\n\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.actionRows\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Make table rows clickable</p>\n </div>\n\n <ng-template [ngIf]=\"tabular.actionRows\">\n <label class=\"mb-2\">\n Call to action\n <select matNativeControl [(ngModel)]=\"tabular.cta\"\n [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom', windowLocation: 'EXISTING'}\">Custom Link\n </option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title, windowLocation: 'EXISTING'}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Shared Dashboards\">\n <option *ngFor=\"let dashboard of sharedDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title, windowLocation: 'EXISTING'}\">{{dashboard.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"tabular.cta && tabular.cta.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"tabular.cta.link\">\n </label>\n\n </ng-template>\n\n <ng-template [ngIf]=\"tabular.cta && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!tabular.cta.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"tabular.cta.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option>-- Select Value --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"'[['+column.name+']]'\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-2\"\n [(ngModel)]=\"tabular.cta.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"tabular.cta.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"tabular.cta.parameters[param.name]\">\n </label>\n </ng-template>\n </ng-template>\n\n <mat-radio-group *ngIf=\"tabular.cta\" [(ngModel)]=\"tabular.cta.windowLocation\">\n <mat-radio-button class=\"mr-4\" value=\"EXISTING\">Existing Window</mat-radio-button>\n <mat-radio-button value=\"_blank\">New Window/Tab</mat-radio-button>\n </mat-radio-group>\n </ng-template>\n </div>\n\n </div>\n\n\n </mat-tab>\n <mat-tab label=\"Columns\" *ngIf=\"dashboardItemType.type === 'table'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Table Column Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Apply specific cell formatting to each table column.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the column to format\n <select matNativeControl [(ngModel)]=\"tableCells.column\"\n (ngModelChange)=\"setColumn($event)\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n\n <ng-template [ngIf]=\"tableCells[tableCells.column]\">\n <label class=\"mb-4\">\n Specify Max Column Width\n <div class=\"mt-1 relative rounded-md shadow-sm w-1/4\">\n <input type=\"number\" [(ngModel)]=\"tableCells[tableCells.column].maxWidth\"\n class=\"block w-full pl-7 pr-12 sm:text-sm border-gray-300 rounded-md\"\n placeholder=\"Enter width\">\n <div class=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <span class=\"text-gray-500 sm:text-sm\"> px </span>\n </div>\n </div>\n </label>\n\n <label class=\"mb-2\">\n Column Format\n <select matNativeControl [(ngModel)]=\"tableCells[tableCells.column].type\"\n (ngModelChange)=\"setColumnFormat($event)\">\n <option [value]=\"undefined\">Automatic</option>\n <option *ngFor=\"let format of columnFormats\"\n [value]=\"format.type\">\n {{format.title}}\n </option>\n </select>\n </label>\n\n <ki-table-cell-formatter *ngIf=\"tableCells[tableCells.column].type\"\n [type]=\"tableCells[tableCells.column].type\"\n [data]=\"tableCells[tableCells.column].data\"\n [openSide]=\"openSide\" [dataset]=\"dataset\"\n [currencies]=\"currencies\" [dashboards]=\"dashboards\"\n [sharedDashboards]=\"sharedDashboards\"\n [privateDashboards]=\"privateDashboards\"\n [actionEvents]=\"actionEvents\">\n </ki-table-cell-formatter>\n\n </ng-template>\n\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Metric\" *ngIf=\"dashboardItemType.type === 'metric'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Metric Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Select which pieces of information to display.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"p-4 flex justify-between\">\n <div class=\"flex-grow p-4\">\n <label class=\"mb-4\">\n Main Metric\n <select [(ngModel)]=\"metric.main\" (ngModelChange)=\"updateMetricDataValues()\">\n <option value=\"\">-- Select Main Metric --</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <hr>\n\n <label class=\"mb-4\">\n Sub Metric\n <select [(ngModel)]=\"metric.subMetric\" (ngModelChange)=\"updateMetricDataValues()\">\n <option value=\"\">-- Select Sub Metric --</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <mat-slide-toggle [(ngModel)]=\"metric.showSubChange\" class=\"mb-4\"\n (ngModelChange)=\"updateMetricDataValues()\">\n Show Metric Change\n </mat-slide-toggle>\n </div>\n\n <div class=\"w-6/12 p-4\">\n <p><b>Preview</b></p>\n\n <div class=\"shadow p-4 flex items-center metric-preview\">\n\n <div class=\"w-full\">\n <dt class=\"text-base font-normal text-gray-900\">{{metric.title}}</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-indigo-600\">\n {{metric.mainValue}}\n <span *ngIf=\"metric.subMetric\" class=\"ml-2 text-sm font-medium text-gray-500\">from {{metric.subValue}}\n <span class=\"text-xs\">({{metric.subTitle}})</span></span>\n </div>\n\n <div *ngIf=\"metric.showSubChange\"\n class=\"inline-flex items-baseline px-2.5 py-0.5 rounded-full text-sm font-medium md:mt-2 lg:mt-0\"\n [ngClass]=\"{'bg-green-100 text-green-800': metric.mainValue >= metric.subValue, 'bg-red-100 text-red-800': metric.mainValue < metric.subValue}\">\n <!-- Heroicon name: mini/arrow-up -->\n <svg *ngIf=\"metric.mainValue >= metric.subValue\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-green-500\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z\"\n clip-rule=\"evenodd\"/>\n </svg>\n <svg *ngIf=\"metric.mainValue < metric.subValue \"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-red-500\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n {{metric.difference}}\n </div>\n </dd>\n </div>\n\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Chart\" *ngIf=\"chartTypes.indexOf(dashboardItemType.type) > -1\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Chart Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure the chart data and display options.\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"p-4 flex justify-between\">\n <div class=\"flex-grow p-4\">\n <label class=\"mb-4\">\n Chart Type\n <select [(ngModel)]=\"dashboardItemType.type\">\n <option value=\"line\">Line</option>\n <option value=\"bar\">Bar</option>\n <option value=\"pie\">Pie</option>\n <option value=\"doughnut\">Doughnut</option>\n <option value=\"scatter\">Scatter</option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n X Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Labels Column\n </ng-template>\n <select [(ngModel)]=\"dashboardItemType.xAxis\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n X\n Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Labels Column\n </ng-template>\n --\n </option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n Y Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Values Column\n </ng-template>\n <select [(ngModel)]=\"dashboardItemType.yAxis\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n Y\n Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Values Column\n </ng-template>\n --\n </option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n <label class=\"mb-4\">\n Series Column\n <select [(ngModel)]=\"dashboardItemType.seriesColumn\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select Series Column--</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n Trend Line Options\n <select [(ngModel)]=\"dashboardItemType.trendLine\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select Trend Line Option--</option>\n <option value=\"average\">Average Line</option>\n <option value=\"linear\">Linear Line</option>\n <option value=\"exponential\">Exponential Line</option>\n <option value=\"logarithmic\">Logarithmic Line</option>\n <option value=\"power\">Power Line</option>\n <optgroup label=\"Use Column Data\">\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </optgroup>\n </select>\n <div class=\"mt-1 text-xs font-normal text-gray-400\">\n Select one of the options, or an existing column of data to plot an additional\n line on the graph.\n </div>\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.trendLine\">\n <label class=\"flex-1\">\n Trend Line Colour\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.trendLineColour\"\n (ngModelChange)=\"setChartData()\">\n </label>\n </ng-template>\n\n </ng-template>\n\n <div class=\"mt-4 mb-4 align-center justify-between\">\n <label class=\"flex-1\">\n Limit Results\n <input type=\"number\" [(ngModel)]=\"dashboardItemType.limit\">\n </label>\n <label class=\"ml-4 mt-4 flex-1\">\n <mat-checkbox [(ngModel)]=\"dashboardItemType.combineRemaining\">\n Combine remaining results\n </mat-checkbox>\n </label>\n </div>\n\n <label class=\"mb-4\" *ngIf=\"dashboardItemType.combineRemaining\">\n Remaining results label\n <input type=\"text\" [(ngModel)]=\"dashboardItemType.combineRemaingingLabel\">\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n <label class=\"mb-4\">\n Y Axes Max value\n <input class=\"w-1/2\" type=\"number\" [(ngModel)]=\"dashboardItemType.maxValue\">\n </label>\n\n <mat-slide-toggle [(ngModel)]=\"dashboardItemType.beginAtZero\" class=\"block mb-4\">\n Start Y Axes at Zero\n </mat-slide-toggle>\n </ng-template>\n\n <mat-slide-toggle [(ngModel)]=\"dashboardItemType.legend\" class=\"block mb-4\">Show Legend\n </mat-slide-toggle>\n <mat-slide-toggle *ngIf=\"dashboardItemType.type === 'line'\"\n [(ngModel)]=\"dashboardItemType.fill\"\n (ngModelChange)=\"setChartData()\" class=\"block mb-4\">Fill Background\n </mat-slide-toggle>\n\n <label class=\"mb-4\">\n Colour Palette\n <select matNativeControl [compareWith]=\"paletteSelectOption\"\n [(ngModel)]=\"dashboardItemType.colourPalette\" (ngModelChange)=\"updateColourPalette()\">\n <option value=\"\">-- Select Colour Palette--</option>\n <option [ngValue]=\"palette\" *ngFor=\"let palette of colourPalettes\">\n {{palette.name}}\n </option>\n </select>\n\n <div *ngIf=\"!colourPalettes.length\" class=\"border-l-4 border-yellow-400 bg-yellow-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-yellow-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <p class=\"text-sm text-yellow-700 mb-0 flex\">\n <span class=\"font-normal\">No colour palettes available.</span>\n <a [routerLink]=\"['/project-settings']\" target=\"_blank\" class=\"flex items-center ml-2 font-medium text-yellow-700 underline hover:text-yellow-600\">Manage palettes in project settings.<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"h-4 w-4\">\n <path d=\"M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z\" />\n <path d=\"M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z\" />\n </svg>\n </a>\n </p>\n </div>\n </div>\n </div>\n </label>\n\n<!-- <button mat-flat-button color=\"accent\" (click)=\"resetDefaultColours()\">-->\n<!-- <div class=\"flex items-center\">-->\n<!-- Reset to Default Colours-->\n<!-- </div>-->\n<!-- </button>-->\n\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'line' || dashboardItemType.type === 'scatter'\">\n <div *ngFor=\"let dataItem of chartData; let i = index\" class=\"mt-4 align-center justify-between\">\n <label class=\"flex-1\">\n {{_.startCase(dataItem.label)}} Colour\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.borderColor[i]\"\n (ngModelChange)=\"setChartData()\">\n </label>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'line'\">\n <div *ngIf=\"!dashboardItemType.colourPalette\" class=\"mt-4 mb-4 flex items-end justify-between\">\n <label class=\"flex-1\">\n Background Colour Range\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.backgroundColorFrom\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n </label>\n <label class=\"flex-1\">\n \n <input type=\"color\" [(ngModel)]=\"dashboardItemType.backgroundColorTo\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n </label>\n </div>\n\n <div class=\"mt-4 mb-4 align-center justify-between\">\n <label class=\"flex-1\">\n Colour Generator Mode\n <mat-radio-group [(ngModel)]=\"dashboardItemType.colourMode\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n <mat-radio-button class=\"mr-4\" value=\"repeat\">Repeat</mat-radio-button>\n <mat-radio-button class=\"mr-4\" value=\"lrgb\">Gradient</mat-radio-button>\n <mat-radio-button class=\"mr-4\" value=\"hsl\">HSL</mat-radio-button>\n <mat-radio-button value=\"lch\">LCH</mat-radio-button>\n </mat-radio-group>\n </label>\n </div>\n\n <ng-template [ngIf]=\"Array.isArray(dashboardItemType.backgroundColor)\">\n <label\n *ngIf=\"dashboardItemType.backgroundColor && dashboardItemType.backgroundColor.length\">\n Set Individual Colours\n </label>\n <div *ngFor=\"let backColour of dashboardItemType.backgroundColor; let i = index\">\n <ng-template [ngIf]=\"dataset && dataset.allData[i]\">\n <div class=\"tracking-wider uppercase text-gray-500 text-xs mt-2\"\n *ngIf=\"dataset && dataset.allData\">\n {{dataset.allData[i][dashboardItemType.xAxis]}}\n </div>\n <input type=\"color\" (change)=\"updateChart($event.target.value, i)\"\n [name]=\"'colour' + i\" [value]=\"dashboardItemType.backgroundColor[i]\">\n </ng-template>\n </div>\n </ng-template>\n </ng-template>\n\n\n\n </div>\n\n <div class=\"w-6/12 p-4\">\n <canvas #chart baseChart class=\"sticky top-10\" *ngIf=\"chartData\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{scales: {y: {beginAtZero: dashboardItemType.beginAtZero, max: dashboardItemType.maxValue || null}}, responsive: true}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Word Cloud\" *ngIf=\"dashboardItemType.type === 'words'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Word Cloud Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings for the Word Cloud generator.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Use an indexed document data source to populate word cloud, or provide a string from a\n single column.\n <mat-radio-group [(ngModel)]=\"wordCloud.populationMethod\">\n <mat-radio-button value=\"WHOLE\">Word Frequencies</mat-radio-button>\n <mat-radio-button class=\"ml-4\" value=\"SINGLE\">Single String</mat-radio-button>\n </mat-radio-group>\n </label>\n\n <ng-template [ngIf]=\"wordCloud.populationMethod === 'SINGLE'\">\n <label class=\"mb-2\">\n Select which row to use for the word cloud\n <select matNativeControl [(ngModel)]=\"wordCloud.row\">\n <option [value]=\"undefined\">-- Select Row --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let row of dataset.allData; let i = index\"\n [value]=\"i\">\n {{_.values(row)[0]}}\n </option>\n </ng-template>\n </select>\n </label>\n\n <label class=\"mb-2\">\n Select the column to use for the word cloud\n <select matNativeControl [(ngModel)]=\"wordCloud.column\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"wordCloud.populationMethod === 'WHOLE'\">\n <label class=\"mb-2\">\n Select the column to use for the words\n <select matNativeControl [(ngModel)]=\"wordCloud.column\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <label class=\"mb-2\">\n Select the column to use for the frequency\n <select matNativeControl [(ngModel)]=\"wordCloud.frequency\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </ng-template>\n\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Network Graph\" *ngIf=\"dashboardItemType.type === 'network'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Network Graph Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings for the Network Graph.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Node Data</div>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeIds\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\">IDs must be unique</div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Label Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeLabels\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Group Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeGroups\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\">Set which group nodes belong to.</div>\n </label>\n </div>\n\n <hr class=\"py-2\">\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Global Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Options defined here will apply to all nodes.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('nodeOptions')\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"networkData.nodeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeOptions[i].key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.nodeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"networkData.nodeOptions[i].key && visNetworkOptions.nodes[networkData.nodeOptions[i].key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[networkData.nodeOptions[i].key].type\" [(ngModel)]=\"nodeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"networkData.nodeOptions[i].key && visNetworkOptions.nodes[networkData.nodeOptions[i].key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.nodeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div class=\"font-medium mb-3 text-base\">Edge Data</div>\n <button mat-stroked-button color=\"primary\" (click)=\"pickNetworkEdgeDataset()\">\n <div class=\"flex items-center\">\n Select Edge Dataset\n </div>\n </button>\n </div>\n\n <ng-template [ngIf]=\"networkData.edgeDatasetTitle\">\n <div class=\"bg-blue-50 p-4 mb-2\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-blue-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3 flex-1 md:flex md:justify-between\">\n <p class=\"mb-0 text-sm text-blue-700\">\n You are currently using {{networkData.edgeDatasetTitle}} dataset\n </p>\n <p class=\"mb-0 mt-3 text-sm md:ml-6 md:mt-0\">\n <a (click)=\"clearEdgeDataset()\"\n class=\"whitespace-nowrap font-medium text-blue-700 hover:text-blue-600 hover:underline\">\n Clear Dataset\n </a>\n </p>\n </div>\n </div>\n </div>\n <div class=\"flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From Node ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.fromIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"edgeDataset\">\n <option *ngFor=\"let column of edgeDataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To Node ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.toIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"edgeDataset\">\n <option *ngFor=\"let column of edgeDataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n </div>\n </ng-template>\n\n <div *ngIf=\"!networkData.edgeDatasetTitle\" class=\"flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From ID\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.fromIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To ID\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.toIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n </div>\n\n <hr class=\"py-2\">\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Global Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Options defined here will apply to all edges.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('edgeOptions')\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"networkData.edgeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.edgeOptions[i].key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(networkData.edgeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"networkData.edgeOptions[i].key && visNetworkOptions.edges[networkData.edgeOptions[i].key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[networkData.edgeOptions[i].key].type\" [(ngModel)]=\"edgeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"networkData.edgeOptions[i].key && visNetworkOptions.edges[networkData.edgeOptions[i].key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/edges.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n edge options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.edgeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n\n </div>\n\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Groups\" *ngIf=\"dashboardItemType.type === 'network' && networkData.nodeGroups\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Group Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each group.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Group Data</div>\n <ng-template ngFor let-nodeGroup [ngForOf]=\"nodeGroups\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 ml-1\">\n Group Name\n <input type=\"text\" [value]=\"nodeGroup || ''\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Group Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this node.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addGroupOption(nodeGroup)\">\n <div class=\"flex items-center\">\n Add Group Option\n </div>\n </button>\n </div>\n\n <ng-template [ngIf]=\"networkData.nodeGroupOptions && networkData.nodeGroupOptions[nodeGroup]\">\n <ng-template ngFor let-groupOption [ngForOf]=\"networkData.nodeGroupOptions[nodeGroup]?.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"groupOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.nodeGroupOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"groupOption.key && visNetworkOptions.nodes[groupOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[groupOption.key].type\" [(ngModel)]=\"groupOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"groupOption.key && visNetworkOptions.nodes[groupOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"groupOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.nodeGroupOptions[nodeGroup]?.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Nodes\" *ngIf=\"dashboardItemType.type === 'network' && datasetNodes.length\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Node Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each node.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">These options will be applied to all nodes\n based on the column or custom value provided.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('globalNodeOptions')\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"networkData.globalNodeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.globalNodeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <div class=\"flex items-center\">\n <label class=\"flex-1 mb-2 ml-1\">\n Data Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.column\"\n (ngModelChange)=\"updateOptions(nodeOption, 'datasetNodes')\">\n <option value=\"\">-- Select Column --</option>\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Custom Value\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[nodeOption.key].type\" [(ngModel)]=\"nodeOption.value\" (change)=\"updateOptions(nodeOption, 'datasetNodes')\">\n </ng-template>\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\" (change)=\"updateOptions(nodeOption, 'datasetNodes')\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"networkData.globalNodeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Node Data</div>\n <ng-template ngFor let-node [ngForOf]=\"datasetNodes\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Node ID\n <input type=\"text\" [value]=\"node.id\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Node Label\n <input type=\"text\" [value]=\"node.label\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Node Group\n <input type=\"text\" [value]=\"node.group || ''\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this node.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"node.options.unshift({})\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"node.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.key\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(node.options, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[nodeOption.key].type\" [(ngModel)]=\"nodeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"node.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Edges\" *ngIf=\"dashboardItemType.type === 'network' && datasetEdges.length\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Edge Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each node.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">These options will be applied to all edges\n based on the column or custom value provided.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('globalEdgeOptions')\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"networkData.globalEdgeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.key\">\n <option [value]=\"undefined\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(networkData.globalEdgeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <div class=\"flex items-center\">\n <label class=\"flex-1 mb-2 ml-1\">\n Data Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.column\"\n (ngModelChange)=\"updateOptions(edgeOption, 'datasetEdges')\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let column of (edgeDataset && edgeDataset.columns) ? edgeDataset.columns : dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Custom Value\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[edgeOption.key].type\" [(ngModel)]=\"edgeOption.value\" (change)=\"updateOptions(edgeOption, 'datasetEdges')\">\n </ng-template>\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\" (change)=\"updateOptions(edgeOption, 'datasetEdges')\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"networkData.globalEdgeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Edge Data</div>\n <ng-template ngFor let-edge [ngForOf]=\"datasetEdges\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From Node\n <input type=\"text\" [value]=\"edge.from\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To Node\n <input type=\"text\" [value]=\"edge.to\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this edge.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"edge.options.unshift({})\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"edge.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(edge.options, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[edgeOption.key].type\" [(ngModel)]=\"edgeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/edges.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n edge options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"edge.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Alert\">\n <div class=\"relative\">\n <div *ngIf=\"!canSetAlerts\" class=\"px-4 sm:px-6 lg:px-8 mt-0\">\n <div class=\"flex flex-col\">\n <div class=\"mt-8 border-l-4 border-yellow-400 bg-yellow-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-yellow-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <p class=\"text-sm text-yellow-700 mb-0\">\n Dashboard Alerts are reserved for our Accredited users. Please <a class=\"font-medium text-yellow-700 underline hover:text-yellow-600\"\n href=\"https://dnsrf.org/joining-options/index.html\">review our Tiers</a> to find out more.\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n <ng-template [ngIf]=\"canSetAlerts\">\n <div *ngIf=\"showAlertWarning\"\n class=\"bg-white shadow sm:rounded-lg absolute top-4 left-0 right-0 w-96 mx-auto z-20\">\n <div class=\"px-4 py-5 sm:p-6 bg-gray-50\">\n <h3 class=\"text-lg leading-6 font-medium text-gray-900\" id=\"renew-subscription-label\">\n Turn on Dashboard Alerts\n </h3>\n <div class=\"mt-2 sm:flex sm:items-start sm:justify-between\">\n <div class=\"max-w-xl text-sm text-gray-500\">\n <p id=\"renew-subscription-description\">\n Alerts for this dashboard are currently <b>off</b>. Slide the toggle to turn\n them on and start receiving notifications.\n </p>\n </div>\n <div class=\"mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center\">\n <mat-slide-toggle [(ngModel)]=\"dashboard.alertsEnabled\"></mat-slide-toggle>\n </div>\n\n </div>\n <div class=\"flex items-center justify-between mt-2\">\n <button mat-stroked-button (click)=\"showAlertWarning = false\">Close</button>\n <div></div>\n </div>\n </div>\n </div>\n\n <div [ngClass]=\"{'filter blur-sm': showAlertWarning}\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Alert Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure alerts and notifications for this widget.\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <button mat-flat-button color=\"primary\" (click)=\"editAlert(null)\">\n <mat-icon>add</mat-icon>\n New Alert\n </button>\n </div>\n </div>\n </div>\n <table class=\"min-w-full border-separate\" style=\"border-spacing: 0\"\n *ngIf=\"dashboardDatasetInstance && dashboardDatasetInstance.alerts && dashboardDatasetInstance.alerts.length\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n Alert\n </th>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n Configuration\n </th>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 backdrop-blur backdrop-filter\">\n <span class=\"sr-only\">Edit</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let alert of dashboardDatasetInstance.alerts; let i = index\">\n <td class=\"whitespace-nowrap border-b border-gray-200 py-2 px-4 text-sm font-medium text-gray-900\">\n {{alert.title}}\n </td>\n <td class=\"whitespace-nowrap border-b border-gray-200 py-2 px-4 text-sm text-gray-500 capitalize\"\n [innerHTML]=\"getAlertDetails(alert)\"></td>\n <td class=\"relative whitespace-nowrap border-b border-gray-200 py-2 px-4 text-right text-sm\">\n <div class=\"align-center justify-end\">\n <button mat-button color=\"primary\" (click)=\"editAlert(alert, i)\"> Edit\n </button>\n <div class=\"divider\"></div>\n <button mat-button color=\"warn\" (click)=\"deleteAlert(i)\"> Delete</button>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n <div class=\"p-4\"\n *ngIf=\"dashboardDatasetInstance && (!dashboardDatasetInstance.alerts || !dashboardDatasetInstance.alerts.length)\">\n <button type=\"button\" (click)=\"editAlert(null)\"\n class=\"relative block w-full border-2 border-gray-300 border-dashed rounded-lg p-12 text-center hover:border-gray-400 focus:outline-none\">\n\n <div class=\"relative inline-block\">\n <mat-icon\n class=\"mx-auto text-6xl h-14 w-20 text-gray-300\">notifications_active\n </mat-icon>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n class=\"right-0 bottom-0 absolute h-8 w-8 text-gray-400\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"/>\n </svg>\n </div>\n\n <span class=\"mt-2 block text-sm font-medium text-gray-900\">Create New Alert</span>\n </button>\n </div>\n </div>\n </ng-template>\n\n </div>\n </mat-tab>\n </mat-tab-group>\n </rsz-layout>\n\n</div>\n\n<div class=\"configure-footer\">\n <div></div>\n <button mat-flat-button color=\"primary\" (click)=\"saveDashboard()\">\n <div class=\"flex items-center\">\n <mat-icon class=\"mr-1\">chevron_left</mat-icon>\n Back to Dashboard\n </div>\n </button>\n</div>\n", styles: [".configure-item-section{background-color:#f5f5f5}.metric-preview{width:100%;background-color:#fff;height:150px;max-width:350px;margin:0 auto;border-radius:6px}.configure-header{height:60px;width:100%;background-color:#f0f0f0;display:flex;align-items:center;justify-content:space-between;padding:0 1rem;box-sizing:border-box;font-size:1.2rem;font-weight:300}mat-tab-group{overflow-y:scroll}ki-dataset-filters{margin-left:-1rem;display:block}.configure-content{flex:1;background-color:#f5f5f5;overflow:hidden;display:flex;width:100%;height:100%;flex-direction:column}.configure-content .top{width:100%;display:flex;flex-basis:60%;position:relative;background-color:#fff}.configure-content .rg-bottom{background-color:#dadada}.configure-content .bottom{width:100%;flex-basis:40%;display:flex;flex-direction:column;position:relative;overflow:hidden}.cell-contents{position:absolute;inset:0;overflow-y:auto;padding:1rem}.cell-contents::-webkit-scrollbar{width:.75em;background:transparent}.cell-contents::-webkit-scrollbar-thumb{background:#d2d2d2}.cell-contents.pad{padding:2rem}.cell-contents.bar-space{margin-top:30px}.cell-contents .entity-header{padding:1rem}.cell-contents .cell-header{height:50px;width:100%;display:flex;align-items:center;justify-content:space-between}.configure-footer{height:60px;width:100%;background-color:#f0f0f0;display:flex;align-items:center;justify-content:space-between;padding:0 1rem;box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i10.BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }, { kind: "directive", type: i1.MatLegacyDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: i11.ResizableComponent, selector: "rsz-layout", inputs: ["rFlex", "directions"], outputs: ["resizeStart", "resizing", "resizeEnd"] }, { kind: "directive", type: i12.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i13.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i13.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i13.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: i13.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i13.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i13.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i13.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.MatLegacySelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i15.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i16.MatLegacySlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i17.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i18.MatLegacyTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { kind: "component", type: i18.MatLegacyTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "directive", type: i5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i19.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i19.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i20.CodemirrorComponent, selector: "ngx-codemirror", inputs: ["className", "name", "autoFocus", "options", "preserveScrollPosition"], outputs: ["cursorActivity", "focusChange", "scroll", "drop"] }, { kind: "component", type: i21.DatasetEditorComponent, selector: "ki-dataset-editor", inputs: ["datasetInstanceSummary", "environment", "admin", "dashboardParameters", "dashboardLayoutSettings", "accountId", "newTitle", "newDescription", "datasetEditorReadonly", "datasetEditorSimpleMode", "datasetEditorNoTools"], outputs: ["dataLoaded", "datasetInstanceSummaryChange"] }, { kind: "component", type: i22.DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }, { kind: "component", type: i23.HtmlDocumentationComponent, selector: "ki-html-documentation", inputs: ["columns"] }, { kind: "component", type: i24.TableCellFormatterComponent, selector: "ki-table-cell-formatter", inputs: ["type", "data", "currencies", "openSide", "dataset", "dashboards", "sharedDashboards", "privateDashboards", "dashboardParameters", "actionEvents"] }] });
|
|
840
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigureItemComponent, decorators: [{
|
|
841
|
-
type: Component,
|
|
842
|
-
args: [{ selector: 'ki-configure-item', host: { class: 'configure-dialog' }, template: "<div class=\"pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 -z-10\" id=\"sidebarWrapper2\">\n <div [ngClass]=\"{'translate-x-0': sideOpen, 'translate-x-full': !sideOpen}\"\n (click)=\"$event.stopPropagation()\"\n class=\"pointer-events-auto w-screen max-w-md transform transition ease-in-out duration-500 sm:duration-700\"\n id=\"docSidebar\">\n <div class=\"flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl\">\n <div class=\"px-4 sm:px-6\">\n <div class=\"flex items-start justify-between\">\n <div></div>\n <div class=\"ml-3 flex h-7 items-center\">\n <button type=\"button\" (click)=\"openSide.next(false)\"\n class=\"rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none\">\n <span class=\"sr-only\">Close panel</span>\n <!-- Heroicon name: outline/x -->\n <svg class=\"h-6 w-6\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n <div class=\"relative flex-1 px-4 sm:px-6\">\n <ki-html-documentation [columns]=\"docColumns\"></ki-html-documentation>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"configure-header\">\n Configure {{dashboardItemType.label}}\n <button mat-button (click)=\"saveDashboard()\">\n <div class=\"flex items-center\">\n <mat-icon class=\"mr-1\">chevron_left</mat-icon>\n Back to Dashboard\n </div>\n </button>\n</div>\n<nav class=\"h-10 flex border-b border-gray-200 bg-white\" aria-label=\"Breadcrumb\">\n <ol role=\"list\" class=\"flex w-full px-4\">\n <li class=\"flex\">\n <div class=\"flex items-center\">\n <a mat-dialog-close [routerLink]=\"['/']\" class=\"text-gray-600 hover:text-gray-800 flex items-center\">\n <span class=\"material-symbols-outlined\">home</span>\n </a>\n </div>\n </li>\n\n <li class=\"flex truncate\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a mat-dialog-close [routerLink]=\"['/dashboards']\"\n class=\"capitalize ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n Dashboards</a>\n </div>\n </li>\n\n <li class=\"flex truncate\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a (click)=\"saveDashboard()\"\n class=\"capitalize ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n Dashboard Editor</a>\n </div>\n </li>\n\n <li class=\"flex\" *ngIf=\"dashboardDatasetInstance\">\n <div class=\"flex items-center\">\n <svg class=\"h-full w-6 flex-shrink-0 text-gray-200\" viewBox=\"0 0 24 44\" preserveAspectRatio=\"none\"\n fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\"/>\n </svg>\n <a class=\"ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\" aria-current=\"page\">\n {{dashboardItemType.label}} Editor\n </a>\n <ng-template [ngIf]=\"dashboardDatasetInstance && dashboardDatasetInstance.source\">\n <span\n class=\"flex items-center border border-gray-200 text-xs px-2 py-0 rounded-xl ml-2 font-thin bg-gray-100\">\n <span class=\"uppercase tracking-wider text-gray-700 font-medium\">Querying:</span>\n <ng-template [ngIf]=\"dashboardDatasetInstance.source.datasourceInstanceKey\">\n <img *ngIf=\"['custom', 'snapshot'].indexOf(dashboardDatasetInstance.source.type) === -1\"\n src=\"/assets/favicon-rev.png\" class=\"w-2.5 mx-1.5\">\n <span *ngIf=\"dashboardDatasetInstance.source.type === 'custom'\"\n class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">upload_file</span>\n <span *ngIf=\"dashboardDatasetInstance.source.type === 'snapshot'\"\n class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">history</span>\n </ng-template>\n <ng-template [ngIf]=\"!dashboardDatasetInstance.source.datasourceInstanceKey\">\n <span class=\"material-symbols-outlined h-4 w-4 text-lg leading-4 mx-1.5\">query_stats</span>\n </ng-template>\n {{dashboardDatasetInstance.source.title}}\n <span class=\"material-symbols-outlined ml-2 cursor-pointer\" title=\"Change source query\"\n (click)=\"changeSource()\">change_circle</span>\n </span>\n </ng-template>\n </div>\n </li>\n </ol>\n</nav>\n<div class=\"configure-content\">\n\n <rsz-layout class=\"row top\" [directions]=\"['bottom']\" [rFlex]=\"true\">\n <div class=\"cell-contents p-0\">\n <div *ngIf=\"!dashboardDatasetInstance\" class=\"flex items-center justify-center h-full w-full\">\n <div class=\"flex items-center flex-col\">\n <button mat-stroked-button color=\"primary\" class=\"config-button\"\n (click)=\"selectedDatasource()\">\n Configure {{dashboardItemType.label}}\n </button>\n <p class=\"font-light w-3/4 text-center mt-4\">\n Please configure this {{dashboardItemType.label}} using a data feed or stored query.\n </p>\n </div>\n </div>\n\n <ki-dataset-editor #datasetEditorComponent *ngIf=\"dashboardDatasetInstance\" [(datasetInstanceSummary)]=\"dashboardDatasetInstance\"\n (dataLoaded)=\"dataLoaded($event)\" [admin]=\"admin\" [dashboardLayoutSettings]=\"general\"\n [dashboardParameters]=\"widgetParameters\"></ki-dataset-editor>\n </div>\n </rsz-layout>\n\n <rsz-layout class=\"row bottom\" [directions]=\"['none']\" [rFlex]=\"false\">\n <mat-tab-group class=\"gray-header h-full\">\n <mat-tab label=\"Header\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Header Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for the Title and Description fields\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"flex justify-between\">\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Title\n <input type=\"text\" [(ngModel)]=\"general.name\">\n <small class=\"font-normal\">Title of the item</small>\n </label>\n <label class=\"mb-2\">\n Description\n <textarea class=\"font-mono w-full\"\n cols=\"30\" rows=\"5\" [(ngModel)]=\"general.description\"></textarea>\n <small class=\"font-normal\">Description of the data item.</small>\n </label>\n\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.transparent\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Transparent background</p>\n </div>\n <small class=\"mb-4 block font-normal\">Make this dashboard items background transparent -\n requires page refresh to take affect</small>\n\n <ng-template [ngIf]=\"dashboard.layoutSettings && dashboard.layoutSettings.parameters && Object.keys(dashboard.layoutSettings.parameters).length\">\n <div class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.showParameterBar\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Show Parameter Bar</p>\n </div>\n <small class=\"mb-4 block font-normal\">\n Enable which parameters to show in this widget. Values entered here will only reload\n this widget.\n </small>\n\n <ng-template [ngIf]=\"general.showParameterBar\">\n <div class=\"border-l-2 pl-4\">\n <div *ngFor=\"let parameterKey of Object.keys(dashboard.layoutSettings.parameters)\"\n class=\"flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"general.parameterBar[parameterKey]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">{{dashboard.layoutSettings.parameters[parameterKey].title}}</p>\n </div>\n </div>\n\n </ng-template>\n\n </ng-template>\n </div>\n </div>\n </div>\n\n\n </mat-tab>\n <mat-tab label=\"Footer\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Footer Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for the footer field\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Footer\n <input type=\"text\" [(ngModel)]=\"general.footer\">\n <small class=\"font-normal\">Text to display at the bottom of the item</small>\n </label>\n\n <label class=\"mb-2\">\n Call to action\n <select matNativeControl [(ngModel)]=\"callToAction\" [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom'}\">Custom Link</option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup *ngIf=\"admin\" label=\"DAP Data Feeds\">\n <option *ngFor=\"let dapFeed of dapFeeds\"\n [ngValue]=\"{type: 'feed', value: dapFeed.id, label: dapFeed.title}\">{{dapFeed.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"callToAction.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"callToAction.link\">\n </label>\n\n </ng-template>\n\n <label class=\"mb-2\">\n Set action label\n <input type=\"text\" [(ngModel)]=\"callToAction.label\">\n </label>\n\n <ng-template [ngIf]=\"callToAction && callToAction.parameters && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!callToAction.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"callToAction.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option [value]=\"undefined\">-- Select Value --</option>\n <option *ngFor=\"let paramValue of dashboardParamValues\"\n [value]=\"paramValue\">\n {{paramValue}}\n </option>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-1\"\n [(ngModel)]=\"callToAction.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"callToAction.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"callToAction.parameters[param.name]\">\n </label>\n </ng-template>\n\n\n </ng-template>\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Dependencies\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Dependency Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n If the loading of this widget is dependant on the results of another,\n you can set the dependency here.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex justify-between\">\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the dashboard item(s) this depends on\n <mat-select [(ngModel)]=\"dependencies.instanceKeys\" multiple>\n <mat-option *ngFor=\"let instance of dashboard.datasetInstances\"\n [value]=\"instance.instanceKey\">\n {{dashboard.layoutSettings.general ? (dashboard.layoutSettings.general[instance.instanceKey] ? dashboard.layoutSettings.general[instance.instanceKey].name || instance.instanceKey : instance.instanceKey) : instance.instanceKey }}\n </mat-option>\n </mat-select>\n </label>\n\n <ng-template ngFor let-instanceKey [ngForOf]=\"dependencies.instanceKeys\">\n <label class=\"mb-2\">\n Dependency result type for\n {{dashboard.layoutSettings.general ? (dashboard.layoutSettings.general[instanceKey] ? dashboard.layoutSettings.general[instanceKey].name || instanceKey : instanceKey) : instanceKey }}\n <mat-select [(ngModel)]=\"dependencies[instanceKey]\" [compareWith]=\"depSelection\"\n (ngModelChange)=\"updateInstanceFilterFields($event, instanceKey)\">\n <mat-option [value]=\"{type: null}\">-- Select Type --</mat-option>\n <mat-option [value]=\"{type: 'LOADED'}\">Loaded</mat-option>\n <mat-option\n [value]=\"{type: 'MATCH', filterJunction: _.clone(filterJunction), key: instanceKey}\">\n Matches Criteria\n </mat-option>\n </mat-select>\n </label>\n\n <ng-template\n [ngIf]=\"dependencies[instanceKey] && dependencies[instanceKey].type === 'MATCH'\">\n <div class=\"w-full flex items-center\"\n *ngIf=\"!dependencies[instanceKey].filterFields\">\n Loading filter component...\n </div>\n <ki-dataset-filters *ngIf=\"dependencies[instanceKey].filterFields\" class=\"ml-0\"\n [filterJunction]=\"dependencies[instanceKey].filterJunction\"\n [filterFields]=\"dependencies[instanceKey].filterFields\"></ki-dataset-filters>\n </ng-template>\n\n </ng-template>\n\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n No data notice message\n <input type=\"text\" [(ngModel)]=\"dependencies.notice\">\n <small class=\"font-normal\">Enter the message to display when no data is returned from\n dependency.</small>\n </label>\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Action\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Action Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure available actions that can be performed on this item.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"font-medium mb-2\">\n Navigate to another dashboard or URL by clicking on this widget item.\n </div>\n\n <label class=\"mb-2\">\n Destination\n <select matNativeControl [(ngModel)]=\"actionItem\" [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom'}\">Custom Link</option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Shared Dashboards\">\n <option *ngFor=\"let dashboard of sharedDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Private Dashboards\" *ngIf=\"privateDashboards.length\">\n <option *ngFor=\"let dashboard of privateDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title}\">{{dashboard.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"actionItem.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"actionItem.link\">\n </label>\n\n </ng-template>\n\n <ng-template [ngIf]=\"actionItem && actionItem.parameters && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!actionItem.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"actionItem.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option [value]=\"undefined\">-- Select Value --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"'[['+column.name+']]'\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-1\"\n [(ngModel)]=\"actionItem.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"actionItem.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"actionItem.parameters[param.name]\">\n </label>\n </ng-template>\n\n\n </ng-template>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Text\" *ngIf=\"dashboardItemType.type === 'text'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Text Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Enter HTML/Text for this item.\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary text-cta\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <ngx-codemirror\n [(ngModel)]=\"textData.value\"\n [options]=\"{lineNumbers: true,theme: 'ttcn',mode: 'htmlmixed',autoRefresh: true,smartIndent: true,extraKeys: {'Ctrl-Space': 'autocomplete'}}\">\n\n </ngx-codemirror>\n </mat-tab>\n <mat-tab label=\"Image\" *ngIf=\"dashboardItemType.type === 'image'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Image Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Set the image to be displayed in this widget.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the column that corresponds to the desired image\n <select matNativeControl [(ngModel)]=\"imageData.column\"\n (ngModelChange)=\"setImageData($event)\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Table\" *ngIf=\"dashboardItemType.type === 'table'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Table Row Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings to be applied to each table row.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.expandRows\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Expand rows. By default rows are compressed and restrict wrapping.</p>\n </div>\n\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.hidePager\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Hide the pager at the bottom of the table.</p>\n </div>\n\n <div class=\"mb-4 flex items-center\">\n <mat-checkbox class=\"mr-2\" [(ngModel)]=\"tabular.actionRows\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Make table rows clickable</p>\n </div>\n\n <ng-template [ngIf]=\"tabular.actionRows\">\n <label class=\"mb-2\">\n Call to action\n <select matNativeControl [(ngModel)]=\"tabular.cta\"\n [compareWith]=\"setCallToActionItem\"\n (ngModelChange)=\"ctaUpdate($event)\">\n <option value=\"\">None</option>\n <option [ngValue]=\"{type: 'custom', windowLocation: 'EXISTING'}\">Custom Link\n </option>\n <optgroup label=\"Dashboards\">\n <option *ngFor=\"let dashboard of dashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title, windowLocation: 'EXISTING'}\">{{dashboard.title}}</option>\n </optgroup>\n <optgroup label=\"Shared Dashboards\">\n <option *ngFor=\"let dashboard of sharedDashboards\"\n [ngValue]=\"{type: 'dashboard', value: dashboard.id, label: dashboard.title, windowLocation: 'EXISTING'}\">{{dashboard.title}}</option>\n </optgroup>\n </select>\n <small class=\"font-normal\">Select the destination for the action link</small>\n </label>\n <ng-template [ngIf]=\"tabular.cta && tabular.cta.type === 'custom'\">\n <p>Please enter the link for this call to action.</p>\n\n <label class=\"mb-2\">\n Link\n <input type=\"text\" [(ngModel)]=\"tabular.cta.link\">\n </label>\n\n </ng-template>\n\n <ng-template [ngIf]=\"tabular.cta && dashboardParameters.length\">\n <p>Please enter the following parameters to use with this dashboard</p>\n\n <ng-template ngFor let-param [ngForOf]=\"dashboardParameters\">\n <label>{{param.title}}</label>\n <label *ngIf=\"!tabular.cta.parameters['custom-'+param.name]\"\n class=\"mb-2 dashboard-param-pick\">\n <select matNativeControl [(ngModel)]=\"tabular.cta.parameters[param.name]\"\n [compareWith]=\"ctaSelectOption\">\n <option>-- Select Value --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"'[['+column.name+']]'\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <div class=\"mb-2 flex items-center\">\n <mat-checkbox class=\"mr-2\"\n [(ngModel)]=\"tabular.cta.parameters['custom-'+param.name]\"></mat-checkbox>\n <p class=\"mb-0 mt-1\">Use custom value</p>\n </div>\n <label class=\"mb-2 dashboard-param-pick\">\n <input type=\"text\" *ngIf=\"tabular.cta.parameters['custom-'+param.name]\"\n placeholder=\"Enter custom parameter value\"\n [(ngModel)]=\"tabular.cta.parameters[param.name]\">\n </label>\n </ng-template>\n </ng-template>\n\n <mat-radio-group *ngIf=\"tabular.cta\" [(ngModel)]=\"tabular.cta.windowLocation\">\n <mat-radio-button class=\"mr-4\" value=\"EXISTING\">Existing Window</mat-radio-button>\n <mat-radio-button value=\"_blank\">New Window/Tab</mat-radio-button>\n </mat-radio-group>\n </ng-template>\n </div>\n\n </div>\n\n\n </mat-tab>\n <mat-tab label=\"Columns\" *ngIf=\"dashboardItemType.type === 'table'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Table Column Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Apply specific cell formatting to each table column.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Select the column to format\n <select matNativeControl [(ngModel)]=\"tableCells.column\"\n (ngModelChange)=\"setColumn($event)\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n\n <ng-template [ngIf]=\"tableCells[tableCells.column]\">\n <label class=\"mb-4\">\n Specify Max Column Width\n <div class=\"mt-1 relative rounded-md shadow-sm w-1/4\">\n <input type=\"number\" [(ngModel)]=\"tableCells[tableCells.column].maxWidth\"\n class=\"block w-full pl-7 pr-12 sm:text-sm border-gray-300 rounded-md\"\n placeholder=\"Enter width\">\n <div class=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <span class=\"text-gray-500 sm:text-sm\"> px </span>\n </div>\n </div>\n </label>\n\n <label class=\"mb-2\">\n Column Format\n <select matNativeControl [(ngModel)]=\"tableCells[tableCells.column].type\"\n (ngModelChange)=\"setColumnFormat($event)\">\n <option [value]=\"undefined\">Automatic</option>\n <option *ngFor=\"let format of columnFormats\"\n [value]=\"format.type\">\n {{format.title}}\n </option>\n </select>\n </label>\n\n <ki-table-cell-formatter *ngIf=\"tableCells[tableCells.column].type\"\n [type]=\"tableCells[tableCells.column].type\"\n [data]=\"tableCells[tableCells.column].data\"\n [openSide]=\"openSide\" [dataset]=\"dataset\"\n [currencies]=\"currencies\" [dashboards]=\"dashboards\"\n [sharedDashboards]=\"sharedDashboards\"\n [privateDashboards]=\"privateDashboards\"\n [actionEvents]=\"actionEvents\">\n </ki-table-cell-formatter>\n\n </ng-template>\n\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Metric\" *ngIf=\"dashboardItemType.type === 'metric'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Metric Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Select which pieces of information to display.\n </p>\n </div>\n </div>\n </div>\n </div>\n <div class=\"p-4 flex justify-between\">\n <div class=\"flex-grow p-4\">\n <label class=\"mb-4\">\n Main Metric\n <select [(ngModel)]=\"metric.main\" (ngModelChange)=\"updateMetricDataValues()\">\n <option value=\"\">-- Select Main Metric --</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <hr>\n\n <label class=\"mb-4\">\n Sub Metric\n <select [(ngModel)]=\"metric.subMetric\" (ngModelChange)=\"updateMetricDataValues()\">\n <option value=\"\">-- Select Sub Metric --</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <mat-slide-toggle [(ngModel)]=\"metric.showSubChange\" class=\"mb-4\"\n (ngModelChange)=\"updateMetricDataValues()\">\n Show Metric Change\n </mat-slide-toggle>\n </div>\n\n <div class=\"w-6/12 p-4\">\n <p><b>Preview</b></p>\n\n <div class=\"shadow p-4 flex items-center metric-preview\">\n\n <div class=\"w-full\">\n <dt class=\"text-base font-normal text-gray-900\">{{metric.title}}</dt>\n <dd class=\"mt-1 flex items-baseline justify-between md:block lg:flex\">\n <div class=\"flex items-baseline text-2xl font-semibold text-indigo-600\">\n {{metric.mainValue}}\n <span *ngIf=\"metric.subMetric\" class=\"ml-2 text-sm font-medium text-gray-500\">from {{metric.subValue}}\n <span class=\"text-xs\">({{metric.subTitle}})</span></span>\n </div>\n\n <div *ngIf=\"metric.showSubChange\"\n class=\"inline-flex items-baseline px-2.5 py-0.5 rounded-full text-sm font-medium md:mt-2 lg:mt-0\"\n [ngClass]=\"{'bg-green-100 text-green-800': metric.mainValue >= metric.subValue, 'bg-red-100 text-red-800': metric.mainValue < metric.subValue}\">\n <!-- Heroicon name: mini/arrow-up -->\n <svg *ngIf=\"metric.mainValue >= metric.subValue\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-green-500\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 17a.75.75 0 01-.75-.75V5.612L5.29 9.77a.75.75 0 01-1.08-1.04l5.25-5.5a.75.75 0 011.08 0l5.25 5.5a.75.75 0 11-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0110 17z\"\n clip-rule=\"evenodd\"/>\n </svg>\n <svg *ngIf=\"metric.mainValue < metric.subValue \"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center text-red-500\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n {{metric.difference}}\n </div>\n </dd>\n </div>\n\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Chart\" *ngIf=\"chartTypes.indexOf(dashboardItemType.type) > -1\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Chart Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure the chart data and display options.\n </p>\n </div>\n </div>\n <div class=\"mt-6 flex flex-col-reverse justify-stretch\">\n <a (click)=\"openSide.next(true)\"\n class=\"text-xs ml-2 hover:underline flex items-center primary\">\n view help docs \n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\"\n fill=\"currentColor\">\n <path\n d=\"M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z\"/>\n <path\n d=\"M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z\"/>\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div class=\"p-4 flex justify-between\">\n <div class=\"flex-grow p-4\">\n <label class=\"mb-4\">\n Chart Type\n <select [(ngModel)]=\"dashboardItemType.type\">\n <option value=\"line\">Line</option>\n <option value=\"bar\">Bar</option>\n <option value=\"pie\">Pie</option>\n <option value=\"doughnut\">Doughnut</option>\n <option value=\"scatter\">Scatter</option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n X Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Labels Column\n </ng-template>\n <select [(ngModel)]=\"dashboardItemType.xAxis\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n X\n Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Labels Column\n </ng-template>\n --\n </option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n Y Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Values Column\n </ng-template>\n <select [(ngModel)]=\"dashboardItemType.yAxis\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select\n <ng-template\n [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n Y\n Axis Column\n </ng-template>\n <ng-template\n [ngIf]=\"dashboardItemType.type === 'pie' || dashboardItemType.type === 'doughnut'\">\n Values Column\n </ng-template>\n --\n </option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n <label class=\"mb-4\">\n Series Column\n <select [(ngModel)]=\"dashboardItemType.seriesColumn\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select Series Column--</option>\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </select>\n </label>\n\n <label class=\"mb-4\">\n Trend Line Options\n <select [(ngModel)]=\"dashboardItemType.trendLine\" (ngModelChange)=\"setChartData()\">\n <option value=\"\">-- Select Trend Line Option--</option>\n <option value=\"average\">Average Line</option>\n <option value=\"linear\">Linear Line</option>\n <option value=\"exponential\">Exponential Line</option>\n <option value=\"logarithmic\">Logarithmic Line</option>\n <option value=\"power\">Power Line</option>\n <optgroup label=\"Use Column Data\">\n <option [value]=\"field.name\" *ngFor=\"let field of filterFields\">\n {{field.title}}\n </option>\n </optgroup>\n </select>\n <div class=\"mt-1 text-xs font-normal text-gray-400\">\n Select one of the options, or an existing column of data to plot an additional\n line on the graph.\n </div>\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.trendLine\">\n <label class=\"flex-1\">\n Trend Line Colour\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.trendLineColour\"\n (ngModelChange)=\"setChartData()\">\n </label>\n </ng-template>\n\n </ng-template>\n\n <div class=\"mt-4 mb-4 align-center justify-between\">\n <label class=\"flex-1\">\n Limit Results\n <input type=\"number\" [(ngModel)]=\"dashboardItemType.limit\">\n </label>\n <label class=\"ml-4 mt-4 flex-1\">\n <mat-checkbox [(ngModel)]=\"dashboardItemType.combineRemaining\">\n Combine remaining results\n </mat-checkbox>\n </label>\n </div>\n\n <label class=\"mb-4\" *ngIf=\"dashboardItemType.combineRemaining\">\n Remaining results label\n <input type=\"text\" [(ngModel)]=\"dashboardItemType.combineRemaingingLabel\">\n </label>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'pie' && dashboardItemType.type !== 'doughnut'\">\n <label class=\"mb-4\">\n Y Axes Max value\n <input class=\"w-1/2\" type=\"number\" [(ngModel)]=\"dashboardItemType.maxValue\">\n </label>\n\n <mat-slide-toggle [(ngModel)]=\"dashboardItemType.beginAtZero\" class=\"block mb-4\">\n Start Y Axes at Zero\n </mat-slide-toggle>\n </ng-template>\n\n <mat-slide-toggle [(ngModel)]=\"dashboardItemType.legend\" class=\"block mb-4\">Show Legend\n </mat-slide-toggle>\n <mat-slide-toggle *ngIf=\"dashboardItemType.type === 'line'\"\n [(ngModel)]=\"dashboardItemType.fill\"\n (ngModelChange)=\"setChartData()\" class=\"block mb-4\">Fill Background\n </mat-slide-toggle>\n\n <label class=\"mb-4\">\n Colour Palette\n <select matNativeControl [compareWith]=\"paletteSelectOption\"\n [(ngModel)]=\"dashboardItemType.colourPalette\" (ngModelChange)=\"updateColourPalette()\">\n <option value=\"\">-- Select Colour Palette--</option>\n <option [ngValue]=\"palette\" *ngFor=\"let palette of colourPalettes\">\n {{palette.name}}\n </option>\n </select>\n\n <div *ngIf=\"!colourPalettes.length\" class=\"border-l-4 border-yellow-400 bg-yellow-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-yellow-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <p class=\"text-sm text-yellow-700 mb-0 flex\">\n <span class=\"font-normal\">No colour palettes available.</span>\n <a [routerLink]=\"['/project-settings']\" target=\"_blank\" class=\"flex items-center ml-2 font-medium text-yellow-700 underline hover:text-yellow-600\">Manage palettes in project settings.<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"h-4 w-4\">\n <path d=\"M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z\" />\n <path d=\"M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z\" />\n </svg>\n </a>\n </p>\n </div>\n </div>\n </div>\n </label>\n\n<!-- <button mat-flat-button color=\"accent\" (click)=\"resetDefaultColours()\">-->\n<!-- <div class=\"flex items-center\">-->\n<!-- Reset to Default Colours-->\n<!-- </div>-->\n<!-- </button>-->\n\n\n <ng-template [ngIf]=\"dashboardItemType.type === 'line' || dashboardItemType.type === 'scatter'\">\n <div *ngFor=\"let dataItem of chartData; let i = index\" class=\"mt-4 align-center justify-between\">\n <label class=\"flex-1\">\n {{_.startCase(dataItem.label)}} Colour\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.borderColor[i]\"\n (ngModelChange)=\"setChartData()\">\n </label>\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"dashboardItemType.type !== 'line'\">\n <div *ngIf=\"!dashboardItemType.colourPalette\" class=\"mt-4 mb-4 flex items-end justify-between\">\n <label class=\"flex-1\">\n Background Colour Range\n <input type=\"color\" [(ngModel)]=\"dashboardItemType.backgroundColorFrom\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n </label>\n <label class=\"flex-1\">\n \n <input type=\"color\" [(ngModel)]=\"dashboardItemType.backgroundColorTo\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n </label>\n </div>\n\n <div class=\"mt-4 mb-4 align-center justify-between\">\n <label class=\"flex-1\">\n Colour Generator Mode\n <mat-radio-group [(ngModel)]=\"dashboardItemType.colourMode\"\n (ngModelChange)=\"backgroundColourUpdate()\">\n <mat-radio-button class=\"mr-4\" value=\"repeat\">Repeat</mat-radio-button>\n <mat-radio-button class=\"mr-4\" value=\"lrgb\">Gradient</mat-radio-button>\n <mat-radio-button class=\"mr-4\" value=\"hsl\">HSL</mat-radio-button>\n <mat-radio-button value=\"lch\">LCH</mat-radio-button>\n </mat-radio-group>\n </label>\n </div>\n\n <ng-template [ngIf]=\"Array.isArray(dashboardItemType.backgroundColor)\">\n <label\n *ngIf=\"dashboardItemType.backgroundColor && dashboardItemType.backgroundColor.length\">\n Set Individual Colours\n </label>\n <div *ngFor=\"let backColour of dashboardItemType.backgroundColor; let i = index\">\n <ng-template [ngIf]=\"dataset && dataset.allData[i]\">\n <div class=\"tracking-wider uppercase text-gray-500 text-xs mt-2\"\n *ngIf=\"dataset && dataset.allData\">\n {{dataset.allData[i][dashboardItemType.xAxis]}}\n </div>\n <input type=\"color\" (change)=\"updateChart($event.target.value, i)\"\n [name]=\"'colour' + i\" [value]=\"dashboardItemType.backgroundColor[i]\">\n </ng-template>\n </div>\n </ng-template>\n </ng-template>\n\n\n\n </div>\n\n <div class=\"w-6/12 p-4\">\n <canvas #chart baseChart class=\"sticky top-10\" *ngIf=\"chartData\"\n [datasets]=\"chartData\"\n [labels]=\"dashboardItemType.labels\"\n [options]=\"{scales: {y: {beginAtZero: dashboardItemType.beginAtZero, max: dashboardItemType.maxValue || null}}, responsive: true}\"\n [legend]=\"!!dashboardItemType.legend\"\n [type]=\"dashboardItemType.type\"\n [plugins]=\"[]\">\n </canvas>\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Word Cloud\" *ngIf=\"dashboardItemType.type === 'words'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Word Cloud Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings for the Word Cloud generator.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"w-1/2\">\n <div class=\"p-4\">\n <label class=\"mb-2\">\n Use an indexed document data source to populate word cloud, or provide a string from a\n single column.\n <mat-radio-group [(ngModel)]=\"wordCloud.populationMethod\">\n <mat-radio-button value=\"WHOLE\">Word Frequencies</mat-radio-button>\n <mat-radio-button class=\"ml-4\" value=\"SINGLE\">Single String</mat-radio-button>\n </mat-radio-group>\n </label>\n\n <ng-template [ngIf]=\"wordCloud.populationMethod === 'SINGLE'\">\n <label class=\"mb-2\">\n Select which row to use for the word cloud\n <select matNativeControl [(ngModel)]=\"wordCloud.row\">\n <option [value]=\"undefined\">-- Select Row --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let row of dataset.allData; let i = index\"\n [value]=\"i\">\n {{_.values(row)[0]}}\n </option>\n </ng-template>\n </select>\n </label>\n\n <label class=\"mb-2\">\n Select the column to use for the word cloud\n <select matNativeControl [(ngModel)]=\"wordCloud.column\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"wordCloud.populationMethod === 'WHOLE'\">\n <label class=\"mb-2\">\n Select the column to use for the words\n <select matNativeControl [(ngModel)]=\"wordCloud.column\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n <label class=\"mb-2\">\n Select the column to use for the frequency\n <select matNativeControl [(ngModel)]=\"wordCloud.frequency\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n </label>\n </ng-template>\n\n </div>\n\n </div>\n </mat-tab>\n <mat-tab label=\"Network Graph\" *ngIf=\"dashboardItemType.type === 'network'\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Network Graph Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Adjust the settings for the Network Graph.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Node Data</div>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeIds\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\">IDs must be unique</div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Label Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeLabels\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Group Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeGroups\"\n (ngModelChange)=\"setNetworkChartData(true)\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\">Set which group nodes belong to.</div>\n </label>\n </div>\n\n <hr class=\"py-2\">\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Global Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Options defined here will apply to all nodes.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('nodeOptions')\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"networkData.nodeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.nodeOptions[i].key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.nodeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"networkData.nodeOptions[i].key && visNetworkOptions.nodes[networkData.nodeOptions[i].key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[networkData.nodeOptions[i].key].type\" [(ngModel)]=\"nodeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"networkData.nodeOptions[i].key && visNetworkOptions.nodes[networkData.nodeOptions[i].key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.nodeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div class=\"font-medium mb-3 text-base\">Edge Data</div>\n <button mat-stroked-button color=\"primary\" (click)=\"pickNetworkEdgeDataset()\">\n <div class=\"flex items-center\">\n Select Edge Dataset\n </div>\n </button>\n </div>\n\n <ng-template [ngIf]=\"networkData.edgeDatasetTitle\">\n <div class=\"bg-blue-50 p-4 mb-2\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-blue-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3 flex-1 md:flex md:justify-between\">\n <p class=\"mb-0 text-sm text-blue-700\">\n You are currently using {{networkData.edgeDatasetTitle}} dataset\n </p>\n <p class=\"mb-0 mt-3 text-sm md:ml-6 md:mt-0\">\n <a (click)=\"clearEdgeDataset()\"\n class=\"whitespace-nowrap font-medium text-blue-700 hover:text-blue-600 hover:underline\">\n Clear Dataset\n </a>\n </p>\n </div>\n </div>\n </div>\n <div class=\"flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From Node ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.fromIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"edgeDataset\">\n <option *ngFor=\"let column of edgeDataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To Node ID Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.toIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"edgeDataset\">\n <option *ngFor=\"let column of edgeDataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n </div>\n </ng-template>\n\n <div *ngIf=\"!networkData.edgeDatasetTitle\" class=\"flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From ID\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.fromIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To ID\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.toIds\">\n <option value=\"\">-- Select Column --</option>\n <ng-template [ngIf]=\"dataset\">\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </ng-template>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n </div>\n\n <hr class=\"py-2\">\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Global Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Options defined here will apply to all edges.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('edgeOptions')\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"networkData.edgeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"networkData.edgeOptions[i].key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(networkData.edgeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"networkData.edgeOptions[i].key && visNetworkOptions.edges[networkData.edgeOptions[i].key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[networkData.edgeOptions[i].key].type\" [(ngModel)]=\"edgeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"networkData.edgeOptions[i].key && visNetworkOptions.edges[networkData.edgeOptions[i].key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/edges.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n edge options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.edgeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n\n </div>\n\n </div>\n </div>\n </div>\n\n </mat-tab>\n <mat-tab label=\"Groups\" *ngIf=\"dashboardItemType.type === 'network' && networkData.nodeGroups\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Group Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each group.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Group Data</div>\n <ng-template ngFor let-nodeGroup [ngForOf]=\"nodeGroups\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 ml-1\">\n Group Name\n <input type=\"text\" [value]=\"nodeGroup || ''\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Group Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this node.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addGroupOption(nodeGroup)\">\n <div class=\"flex items-center\">\n Add Group Option\n </div>\n </button>\n </div>\n\n <ng-template [ngIf]=\"networkData.nodeGroupOptions && networkData.nodeGroupOptions[nodeGroup]\">\n <ng-template ngFor let-groupOption [ngForOf]=\"networkData.nodeGroupOptions[nodeGroup]?.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"groupOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.nodeGroupOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"groupOption.key && visNetworkOptions.nodes[groupOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[groupOption.key].type\" [(ngModel)]=\"groupOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"groupOption.key && visNetworkOptions.nodes[groupOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"groupOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"networkData.nodeGroupOptions[nodeGroup]?.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Nodes\" *ngIf=\"dashboardItemType.type === 'network' && datasetNodes.length\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Node Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each node.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">These options will be applied to all nodes\n based on the column or custom value provided.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('globalNodeOptions')\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"networkData.globalNodeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(networkData.globalNodeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <div class=\"flex items-center\">\n <label class=\"flex-1 mb-2 ml-1\">\n Data Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.column\"\n (ngModelChange)=\"updateOptions(nodeOption, 'datasetNodes')\">\n <option value=\"\">-- Select Column --</option>\n <option *ngFor=\"let column of dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Custom Value\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[nodeOption.key].type\" [(ngModel)]=\"nodeOption.value\" (change)=\"updateOptions(nodeOption, 'datasetNodes')\">\n </ng-template>\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\" (change)=\"updateOptions(nodeOption, 'datasetNodes')\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"networkData.globalNodeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Node Data</div>\n <ng-template ngFor let-node [ngForOf]=\"datasetNodes\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Node ID\n <input type=\"text\" [value]=\"node.id\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Node Label\n <input type=\"text\" [value]=\"node.label\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Node Group\n <input type=\"text\" [value]=\"node.group || ''\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Node Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this node.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"node.options.unshift({})\">\n <div class=\"flex items-center\">\n Add Node Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-nodeOption [ngForOf]=\"node.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"nodeOption.key\">\n <option [value]=\"undefined\">-- Select Column --</option>\n <option *ngFor=\"let option of availableNodeOptions\"\n [disabled]=\"_.find(node.options, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.nodes[nodeOption.key].type\" [(ngModel)]=\"nodeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"nodeOption.key && visNetworkOptions.nodes[nodeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"nodeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"node.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Edges\" *ngIf=\"dashboardItemType.type === 'network' && datasetEdges.length\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Edge Options</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Define the options for each node.\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex\">\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">These options will be applied to all edges\n based on the column or custom value provided.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"addOption('globalEdgeOptions')\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"networkData.globalEdgeOptions\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.key\">\n <option [value]=\"undefined\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(networkData.globalEdgeOptions, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <div class=\"flex items-center\">\n <label class=\"flex-1 mb-2 ml-1\">\n Data Column\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.column\"\n (ngModelChange)=\"updateOptions(edgeOption, 'datasetEdges')\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let column of (edgeDataset && edgeDataset.columns) ? edgeDataset.columns : dataset.columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Custom Value\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[edgeOption.key].type\" [(ngModel)]=\"edgeOption.value\" (change)=\"updateOptions(edgeOption, 'datasetEdges')\">\n </ng-template>\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\" (change)=\"updateOptions(edgeOption, 'datasetEdges')\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/nodes.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n node options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n </div>\n\n <button mat-icon-button color=\"warn\" (click)=\"networkData.globalEdgeOptions.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\"flex-1 w-1/2\">\n <div class=\"p-4\">\n <div class=\"w-full bg-white p-4 border rounded\">\n <div class=\"font-medium mb-3 text-base\">Edge Data</div>\n <ng-template ngFor let-edge [ngForOf]=\"datasetEdges\">\n\n\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n From Node\n <input type=\"text\" [value]=\"edge.from\" disabled>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n To Node\n <input type=\"text\" [value]=\"edge.to\" disabled>\n </label>\n </div>\n\n\n <div class=\"flex items-start justify-between\">\n <div>\n <div class=\"font-medium text-base\">Edge Options</div>\n <div class=\"mb-3 text-xs text-gray-500\">Set the options for this edge.</div>\n </div>\n <button mat-stroked-button color=\"primary\" (click)=\"edge.options.unshift({})\">\n <div class=\"flex items-center\">\n Add Edge Option\n </div>\n </button>\n </div>\n\n <ng-template ngFor let-edgeOption [ngForOf]=\"edge.options\" let-i=index>\n <div class=\"mb-2 flex items-center justify-between\">\n <label class=\"flex-1 mb-2 mr-1\">\n Option\n <select class=\"w-full\" matNativeControl [(ngModel)]=\"edgeOption.key\">\n <option value=\"\">-- Select Option --</option>\n <option *ngFor=\"let option of availableEdgeOptions\"\n [disabled]=\"_.find(edge.options, {key: option})\"\n [value]=\"option\">\n {{option}}\n </option>\n </select>\n <div class=\"text-xs font-normal text-gray-500\"> </div>\n </label>\n <label class=\"flex-1 mb-2 ml-1\">\n Option Value\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type !== 'boolean'\">\n <input [type]=\"visNetworkOptions.edges[edgeOption.key].type\" [(ngModel)]=\"edgeOption.value\">\n </ng-template>\n <ng-template [ngIf]=\"edgeOption.key && visNetworkOptions.edges[edgeOption.key].type === 'boolean'\">\n <select [(ngModel)]=\"edgeOption.value\">\n <option [value]=\"true\">True</option>\n <option [value]=\"false\">False</option>\n </select>\n </ng-template>\n <div class=\"text-xs font-normal text-gray-500\">\n <a href=\"https://visjs.github.io/vis-network/docs/network/edges.html\"\n target=\"_blank\" class=\"text-secondary flex items-center hover:underline\">\n edge options documentation\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\" class=\"h-3 w-3 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </label>\n <button mat-icon-button color=\"warn\" (click)=\"edge.options.splice(i, 1)\">\n <mat-icon>clear</mat-icon>\n </button>\n </div>\n </ng-template>\n <hr class=\"py-2\">\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Alert\">\n <div class=\"relative\">\n <div *ngIf=\"!canSetAlerts\" class=\"px-4 sm:px-6 lg:px-8 mt-0\">\n <div class=\"flex flex-col\">\n <div class=\"mt-8 border-l-4 border-yellow-400 bg-yellow-50 p-4\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-yellow-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <div class=\"ml-3\">\n <p class=\"text-sm text-yellow-700 mb-0\">\n Dashboard Alerts are reserved for our Accredited users. Please <a class=\"font-medium text-yellow-700 underline hover:text-yellow-600\"\n href=\"https://dnsrf.org/joining-options/index.html\">review our Tiers</a> to find out more.\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n <ng-template [ngIf]=\"canSetAlerts\">\n <div *ngIf=\"showAlertWarning\"\n class=\"bg-white shadow sm:rounded-lg absolute top-4 left-0 right-0 w-96 mx-auto z-20\">\n <div class=\"px-4 py-5 sm:p-6 bg-gray-50\">\n <h3 class=\"text-lg leading-6 font-medium text-gray-900\" id=\"renew-subscription-label\">\n Turn on Dashboard Alerts\n </h3>\n <div class=\"mt-2 sm:flex sm:items-start sm:justify-between\">\n <div class=\"max-w-xl text-sm text-gray-500\">\n <p id=\"renew-subscription-description\">\n Alerts for this dashboard are currently <b>off</b>. Slide the toggle to turn\n them on and start receiving notifications.\n </p>\n </div>\n <div class=\"mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center\">\n <mat-slide-toggle [(ngModel)]=\"dashboard.alertsEnabled\"></mat-slide-toggle>\n </div>\n\n </div>\n <div class=\"flex items-center justify-between mt-2\">\n <button mat-stroked-button (click)=\"showAlertWarning = false\">Close</button>\n <div></div>\n </div>\n </div>\n </div>\n\n <div [ngClass]=\"{'filter blur-sm': showAlertWarning}\">\n <div class=\"px-6 py-3 bg-white border-b border-gray-200\">\n <div class=\"md:flex md:items-center md:justify-between md:space-x-5\">\n <div class=\"flex items-start flex-1\">\n <div class=\"pt-1.5\">\n <h1 class=\"text-xl font-bold text-gray-900 mb-0\">Alert Settings</h1>\n <p class=\"text-xs font-medium text-gray-500\">\n Configure alerts and notifications for this widget.\n </p>\n </div>\n </div>\n <div class=\"flex flex-col-reverse justify-stretch\">\n <button mat-flat-button color=\"primary\" (click)=\"editAlert(null)\">\n <mat-icon>add</mat-icon>\n New Alert\n </button>\n </div>\n </div>\n </div>\n <table class=\"min-w-full border-separate\" style=\"border-spacing: 0\"\n *ngIf=\"dashboardDatasetInstance && dashboardDatasetInstance.alerts && dashboardDatasetInstance.alerts.length\">\n <thead class=\"bg-gray-100\">\n <tr>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n Alert\n </th>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 text-left text-xs font-semibold text-gray-900 backdrop-blur backdrop-filter\">\n Configuration\n </th>\n <th scope=\"col\"\n class=\"sticky top-0 z-10 border-b border-gray-300 bg-gray-50 bg-opacity-75 py-3.5 px-4 backdrop-blur backdrop-filter\">\n <span class=\"sr-only\">Edit</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white\">\n <tr *ngFor=\"let alert of dashboardDatasetInstance.alerts; let i = index\">\n <td class=\"whitespace-nowrap border-b border-gray-200 py-2 px-4 text-sm font-medium text-gray-900\">\n {{alert.title}}\n </td>\n <td class=\"whitespace-nowrap border-b border-gray-200 py-2 px-4 text-sm text-gray-500 capitalize\"\n [innerHTML]=\"getAlertDetails(alert)\"></td>\n <td class=\"relative whitespace-nowrap border-b border-gray-200 py-2 px-4 text-right text-sm\">\n <div class=\"align-center justify-end\">\n <button mat-button color=\"primary\" (click)=\"editAlert(alert, i)\"> Edit\n </button>\n <div class=\"divider\"></div>\n <button mat-button color=\"warn\" (click)=\"deleteAlert(i)\"> Delete</button>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n <div class=\"p-4\"\n *ngIf=\"dashboardDatasetInstance && (!dashboardDatasetInstance.alerts || !dashboardDatasetInstance.alerts.length)\">\n <button type=\"button\" (click)=\"editAlert(null)\"\n class=\"relative block w-full border-2 border-gray-300 border-dashed rounded-lg p-12 text-center hover:border-gray-400 focus:outline-none\">\n\n <div class=\"relative inline-block\">\n <mat-icon\n class=\"mx-auto text-6xl h-14 w-20 text-gray-300\">notifications_active\n </mat-icon>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n class=\"right-0 bottom-0 absolute h-8 w-8 text-gray-400\" fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\" stroke-width=\"4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"/>\n </svg>\n </div>\n\n <span class=\"mt-2 block text-sm font-medium text-gray-900\">Create New Alert</span>\n </button>\n </div>\n </div>\n </ng-template>\n\n </div>\n </mat-tab>\n </mat-tab-group>\n </rsz-layout>\n\n</div>\n\n<div class=\"configure-footer\">\n <div></div>\n <button mat-flat-button color=\"primary\" (click)=\"saveDashboard()\">\n <div class=\"flex items-center\">\n <mat-icon class=\"mr-1\">chevron_left</mat-icon>\n Back to Dashboard\n </div>\n </button>\n</div>\n", styles: [".configure-item-section{background-color:#f5f5f5}.metric-preview{width:100%;background-color:#fff;height:150px;max-width:350px;margin:0 auto;border-radius:6px}.configure-header{height:60px;width:100%;background-color:#f0f0f0;display:flex;align-items:center;justify-content:space-between;padding:0 1rem;box-sizing:border-box;font-size:1.2rem;font-weight:300}mat-tab-group{overflow-y:scroll}ki-dataset-filters{margin-left:-1rem;display:block}.configure-content{flex:1;background-color:#f5f5f5;overflow:hidden;display:flex;width:100%;height:100%;flex-direction:column}.configure-content .top{width:100%;display:flex;flex-basis:60%;position:relative;background-color:#fff}.configure-content .rg-bottom{background-color:#dadada}.configure-content .bottom{width:100%;flex-basis:40%;display:flex;flex-direction:column;position:relative;overflow:hidden}.cell-contents{position:absolute;inset:0;overflow-y:auto;padding:1rem}.cell-contents::-webkit-scrollbar{width:.75em;background:transparent}.cell-contents::-webkit-scrollbar-thumb{background:#d2d2d2}.cell-contents.pad{padding:2rem}.cell-contents.bar-space{margin-top:30px}.cell-contents .entity-header{padding:1rem}.cell-contents .cell-header{height:50px;width:100%;display:flex;align-items:center;justify-content:space-between}.configure-footer{height:60px;width:100%;background-color:#f0f0f0;display:flex;align-items:center;justify-content:space-between;padding:0 1rem;box-sizing:border-box}\n"] }]
|
|
843
|
-
}], ctorParameters: function () { return [{ type: i1.MatLegacyDialogRef }, { type: undefined, decorators: [{
|
|
844
|
-
type: Inject,
|
|
845
|
-
args: [MAT_DIALOG_DATA]
|
|
846
|
-
}] }, { type: i1.MatLegacyDialog }, { type: i2.DashboardService }, { type: i3.DatasetService }, { type: i4.DatasourceService }, { type: i5.Router }, { type: i6.ProjectService }]; }, propDecorators: { chart: [{
|
|
847
|
-
type: ViewChild,
|
|
848
|
-
args: [BaseChartDirective]
|
|
849
|
-
}], datasetEditorComponent: [{
|
|
850
|
-
type: ViewChild,
|
|
851
|
-
args: ['datasetEditorComponent']
|
|
852
|
-
}] } });
|
|
853
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJlLWl0ZW0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2Rhc2hib2FyZC1lZGl0b3IvY29uZmlndXJlLWl0ZW0vY29uZmlndXJlLWl0ZW0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2Rhc2hib2FyZC1lZGl0b3IvY29uZmlndXJlLWl0ZW0vY29uZmlndXJlLWl0ZW0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQVUsU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFDSCxzQkFBc0IsSUFBSSxlQUFlLEVBRzVDLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUNILDZCQUE2QixFQUNoQyxNQUFNLGdGQUFnRixDQUFDO0FBRXhGLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBR2pDLE9BQU8sTUFBTSxNQUFNLFdBQVcsQ0FBQztBQUUvQixPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSx1RUFBdUUsQ0FBQztBQUNsSCxPQUFPLEVBQ0gsc0JBQXNCLEVBQ3pCLE1BQU0sc0ZBQXNGLENBQUM7QUFHOUYsT0FBTyxFQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFOUMsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQzlDLE9BQU8sVUFBVSxNQUFNLFlBQVksQ0FBQztBQUdwQyxPQUFPLGlCQUFpQixNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHVEQUF1RCxDQUFDO0FBQzdGLE9BQU8sRUFDSCw0QkFBNEIsRUFDL0IsTUFBTSwyRUFBMkUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFuQm5GLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUE0QnpCLE1BQU0sT0FBTyxzQkFBc0I7SUFpSC9CLFlBQW1CLFNBQStDLEVBQ3RCLElBQVMsRUFDakMsTUFBaUIsRUFDakIsZ0JBQWtDLEVBQ2xDLGNBQThCLEVBQzlCLGlCQUFvQyxFQUNwQyxNQUFjLEVBQ2QsY0FBOEI7UUFQL0IsY0FBUyxHQUFULFNBQVMsQ0FBc0M7UUFDdEIsU0FBSSxHQUFKLElBQUksQ0FBSztRQUNqQyxXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ2pCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQWpIM0MsV0FBTSxHQUFRLEVBQUUsQ0FBQztRQUNqQixhQUFRLEdBQVEsRUFBRSxDQUFDO1FBQ25CLGdCQUFXLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLGNBQVMsR0FBUSxFQUFFLENBQUM7UUFDcEIsY0FBUyxHQUFRLEVBQUUsQ0FBQztRQUNwQixZQUFPLEdBQVEsRUFBRSxDQUFDO1FBQ2xCLGVBQVUsR0FBUSxFQUFFLENBQUM7UUFDckIsWUFBTyxHQUFRLEVBQUUsQ0FBQztRQUNsQixpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUN2QixpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUN2QixlQUFVLEdBQVEsRUFBRSxDQUFDO1FBSXJCLGVBQVUsR0FBUSxFQUFFLENBQUM7UUFDckIscUJBQWdCLEdBQVEsRUFBRSxDQUFDO1FBQzNCLHNCQUFpQixHQUFRLEVBQUUsQ0FBQztRQUM1Qix3QkFBbUIsR0FBUSxFQUFFLENBQUM7UUFDOUIseUJBQW9CLEdBQVEsRUFBRSxDQUFDO1FBQy9CLGlCQUFZLEdBQWtCLEVBQUUsQ0FBQztRQUVqQyxpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUN2QixlQUFVLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDM0Qsa0JBQWEsR0FBRyxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDckQsZUFBVSxHQUFHO1lBQ2hCO2dCQUNJLElBQUksRUFBRSxtQkFBbUI7Z0JBQ3pCLEtBQUssRUFBRSxLQUFLO2dCQUNaLE1BQU0sRUFBRSxHQUFHO2FBQ2Q7WUFDRDtnQkFDSSxJQUFJLEVBQUUsZUFBZTtnQkFDckIsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osTUFBTSxFQUFFLEdBQUc7YUFDZDtZQUNEO2dCQUNJLElBQUksRUFBRSxVQUFVO2dCQUNoQixLQUFLLEVBQUUsS0FBSztnQkFDWixNQUFNLEVBQUUsR0FBRzthQUNkO1NBQ0osQ0FBQztRQUNLLG1CQUFjLEdBQUc7WUFDcEIsS0FBSyxFQUFFLEtBQUs7WUFDWixPQUFPLEVBQUUsQ0FBQztvQkFDTixhQUFhLEVBQUUsRUFBRTtvQkFDakIsYUFBYSxFQUFFLEVBQUU7b0JBQ2pCLFVBQVUsRUFBRSxFQUFFO2lCQUNqQixDQUFDO1lBQ0YsZUFBZSxFQUFFLEVBQUU7U0FDdEIsQ0FBQztRQUNLLGtCQUFhLEdBQVE7WUFDeEI7Z0JBQ0ksS0FBSyxFQUFFLFFBQVE7Z0JBQ2YsSUFBSSxFQUFFLFFBQVE7YUFDakI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsVUFBVTtnQkFDakIsSUFBSSxFQUFFLFVBQVU7YUFDbkI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsSUFBSSxFQUFFLFlBQVk7YUFDckI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsYUFBYTtnQkFDcEIsSUFBSSxFQUFFLFVBQVU7YUFDbkI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsSUFBSSxFQUFFLFlBQVk7YUFDckI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsTUFBTTtnQkFDYixJQUFJLEVBQUUsTUFBTTthQUNmO1lBQ0Q7Z0JBQ0ksS0FBSyxFQUFFLFFBQVE7Z0JBQ2YsSUFBSSxFQUFFLFFBQVE7YUFDakI7WUFDRDtnQkFDSSxLQUFLLEVBQUUsYUFBYTtnQkFDcEIsSUFBSSxFQUFFLE1BQU07YUFDZjtTQUNKLENBQUM7UUFDSyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDekIsYUFBUSxHQUFRLEVBQUUsQ0FBQztRQUNuQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUl0QyxNQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ04sZUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDM0IsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsbUJBQWMsR0FBUSxFQUFFLENBQUM7UUFDekIsc0JBQWlCLEdBQUcsaUJBQWlCLENBQUM7UUFDdEMseUJBQW9CLEdBQWEsRUFBRSxDQUFDO1FBQ3BDLHlCQUFvQixHQUFhLEVBQUUsQ0FBQztRQUNwQyxpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUN2QixpQkFBWSxHQUFRLEVBQUUsQ0FBQztRQUV2QixxQkFBZ0IsR0FBUSxFQUFFLENBQUM7UUFFZixVQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ2QsV0FBTSxHQUFHLE1BQU0sQ0FBQztJQVVuQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVE7UUFDVixJQUFJLENBQUMsb0JBQW9CLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNyQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQztRQUNuRSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUNyRCxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUMvQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsOEJBQThCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFdEYsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtZQUMxQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztnQkFDcEIsS0FBSyxFQUFFLFFBQVE7Z0JBQ2YsSUFBSSxFQUFFLFFBQVE7YUFDakIsQ0FBQyxDQUFDO1NBQ047UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsRUFBRTtZQUNwQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztTQUM5QztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDM0YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUNuSTtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDaEMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7U0FDN0I7YUFBTTtZQUNILElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzdCO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FDL0IsRUFBRSxFQUNGLEtBQUssRUFDTCxHQUFHLENBQ04sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUMvQixFQUFFLEVBQ0YsS0FBSyxFQUNMLEdBQUcsRUFDSCxJQUFJLENBQ1AsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDNUIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQy9CLEVBQUUsRUFDRixLQUFLLEVBQ0wsR0FBRyxFQUNILENBQUMsQ0FDSixDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUM1QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsVUFBVSxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUNqRCxFQUFFLEVBQ0YsTUFBTSxFQUNOLEdBQUcsRUFDSCxFQUFFLEVBQ0YsRUFBRSxDQUNMLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQWEsRUFBRSxFQUFFO1lBQ3RDLElBQUksSUFBSSxFQUFFO2dCQUNOLFFBQVEsQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsRUFBRSxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRSxRQUFRLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQzNDO2lCQUFNO2dCQUNILFVBQVUsQ0FBQyxHQUFHLEVBQUU7b0JBQ1osUUFBUSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ25FLFFBQVEsQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN6RSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7YUFDWDtZQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxPQUFPLEdBQVEsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNuSCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUMvRCxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1NBQ25EO0lBQ0wsQ0FBQztJQUVNLFdBQVcsQ0FBQyxRQUFRLEVBQUUsS0FBSztRQUM5QixJQUFJLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUN6RCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDOUIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVNLFlBQVk7UUFDZixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUN2RCxLQUFLLEVBQUUsUUFBUTtZQUNmLE1BQU0sRUFBRSxPQUFPO1lBQ2YsSUFBSSxFQUFFO2dCQUNGLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSzthQUNwQjtTQUNKLENBQUMsQ0FBQztRQUNILFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDcEMsSUFBSSxHQUFHLEVBQUU7Z0JBQ0wsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUU7b0JBQzlELEtBQUssRUFBRSxPQUFPO29CQUNkLE1BQU0sRUFBRSxPQUFPO2lCQUNsQixDQUFDLENBQUM7Z0JBQ0gsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRTtvQkFDekMsSUFBSSxPQUFPLEVBQUU7d0JBQ1QsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGlCQUFpQixHQUFHLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQzt3QkFDeEUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHFCQUFxQixHQUFHLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQzt3QkFDaEYsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sR0FBRzs0QkFDbkMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLOzRCQUNoQixpQkFBaUIsRUFBRSxHQUFHLENBQUMsaUJBQWlCOzRCQUN4QyxxQkFBcUIsRUFBRSxHQUFHLENBQUMscUJBQXFCOzRCQUNoRCxJQUFJLEVBQUUsSUFBSTt5QkFDYixDQUFDO3dCQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDaEYsSUFBSSxjQUFjLEVBQUU7NEJBQ2hCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyw4QkFBOEIsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7eUJBQ3BGOzZCQUFNOzRCQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7eUJBQ3JEO3FCQUNKO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2FBQ047UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTSxrQkFBa0I7UUFDckIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUU7WUFDOUQsS0FBSyxFQUFFLFFBQVE7WUFDZixNQUFNLEVBQUUsT0FBTztZQUNmLElBQUksRUFBRTtnQkFDRixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7Z0JBQ3pCLHdCQUF3QixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZTtnQkFDbkQsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixJQUFJO29CQUN2RCxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUM5QixXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlO29CQUN0Qyx1QkFBdUIsRUFBRSxFQUFFO29CQUMzQixlQUFlLEVBQUUsRUFBRTtvQkFDbkIsVUFBVSxFQUFFLEVBQUU7aUJBQ2pCO2dCQUNELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSzthQUNwQjtTQUNKLENBQUMsQ0FBQztRQUVILFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsRUFBRTtZQUN6RCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsd0JBQXdCLENBQUM7WUFDekQsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sc0JBQXNCO1FBQ3pCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFO1lBQzlELEtBQUssRUFBRSxRQUFRO1lBQ2YsTUFBTSxFQUFFLE9BQU87WUFDZixJQUFJLEVBQUU7Z0JBQ0YsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUN6Qix3QkFBd0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWU7Z0JBQ25ELHdCQUF3QixFQUFFLElBQUksQ0FBQyx3QkFBd0IsSUFBSTtvQkFDdkQsV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDOUIsV0FBVyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZTtvQkFDdEMsdUJBQXVCLEVBQUUsRUFBRTtvQkFDM0IsZUFBZSxFQUFFLEVBQUU7b0JBQ25CLFVBQVUsRUFBRSxFQUFFO2lCQUNqQjtnQkFDRCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7YUFDcEI7U0FDSixDQUFDLENBQUM7UUFFSCxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBQyx3QkFBd0IsRUFBQyxFQUFFO1lBQy9ELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxHQUFHLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDO1lBQzVFLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLEdBQUcsd0JBQXdCLENBQUMscUJBQXFCLENBQUM7WUFFcEYsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsR0FBRyx3QkFBd0IsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7UUFDekcsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sS0FBSyxDQUFDLGVBQWU7UUFDeEIsTUFBTSxzQkFBc0IsR0FBRztZQUMzQixpQkFBaUIsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWE7WUFDakQscUJBQXFCLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUI7WUFDekQsdUJBQXVCLEVBQUUsRUFBRTtZQUMzQixlQUFlLEVBQUUsRUFBRTtZQUNuQixVQUFVLEVBQUUsRUFBRTtTQUNqQixDQUFDO1FBRUYsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUN4RCxzQkFBc0IsRUFDdEIsR0FBRyxFQUNILEdBQUcsQ0FDTixDQUFDO0lBQ04sQ0FBQztJQUVNLGdCQUFnQjtRQUNuQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUM7UUFDekMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUM7UUFFMUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDNUIsQ0FBQztJQUVNLGNBQWMsQ0FBQyxTQUFpQjtRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRTtZQUNwQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztTQUMxQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQy9DLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBQyxPQUFPLEVBQUUsRUFBRSxFQUFDLENBQUM7U0FDaEU7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVNLFNBQVMsQ0FBQyxXQUFtQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFO1lBQ2pGLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ3RDO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVNLGFBQWEsQ0FBQyxVQUFlLEVBQUUsV0FBbUI7UUFDckQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUM5QixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQ2pDLElBQUksS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFDN0IsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFFbkMsSUFBSSxXQUFXLEtBQUssY0FBYyxFQUFFO1lBQ2hDLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7U0FDeEY7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzdCLElBQUksTUFBTSxFQUFFO2dCQUNSLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUMsQ0FBQyxDQUFDO2dCQUMvQyxJQUFJLE9BQU8sRUFBRTtvQkFDVCxLQUFLLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUMzQjthQUNKO1lBRUQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsR0FBRyxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUM7WUFDckQsSUFBSSxRQUFRLEVBQUU7Z0JBQ1YsUUFBUSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDMUI7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7YUFDOUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTSxVQUFVLENBQUMsT0FBTztRQUNyQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNoRCxPQUFPO2dCQUNILEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztnQkFDbkIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2FBQ3BCLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRU0sS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHO1FBQ3RCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxFQUFFLENBQUM7UUFDOUIsSUFBSSxHQUFHLEVBQUU7WUFDTCxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFO29CQUNqQixHQUFHLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztpQkFDdkI7Z0JBRUQsTUFBTSxTQUFTLEdBQVEsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDM0UsSUFBSSxTQUFTLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRTtvQkFDckMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFFekUsVUFBVSxDQUFDLEdBQUcsRUFBRTt3QkFDWixNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsc0JBQXNCLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQzNFLElBQUksRUFBRSxFQUFFOzRCQUNKLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQzt5QkFDdkI7b0JBQ0wsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNUO2FBQ0o7aUJBQU07Z0JBQ0gsR0FBRyxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7YUFDdkI7U0FDSjtJQUNMLENBQUM7SUFFTSxZQUFZLENBQUMsTUFBTTtRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDNUUsQ0FBQztJQUVNLFNBQVMsQ0FBQyxNQUFNO1FBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFO1lBQ3BFLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ2hDO0lBQ0wsQ0FBQztJQUVNLGVBQWUsQ0FBQyxNQUFNO1FBQ3pCLElBQUksTUFBTSxLQUFLLFdBQVcsRUFBRTtZQUN4QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDdkQ7YUFBTTtZQUNILElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUM5RyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQzthQUNyRDtTQUNKO0lBQ0wsQ0FBQztJQUVNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBTTtRQUMxQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRTtZQUM1RCxLQUFLLEVBQUUsT0FBTztZQUNkLE1BQU0sRUFBRSxPQUFPO1lBQ2YsSUFBSSxFQUFFO2dCQUNGLEtBQUs7Z0JBQ0wsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO2FBQ2xDO1NBQ0osQ0FBQyxDQUFDO1FBRUgsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUMxQyxJQUFJLFNBQVMsRUFBRTtnQkFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRTtvQkFDdkMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7aUJBQzdDO2dCQUNELElBQUksS0FBSyxJQUFJLENBQUMsRUFBRTtvQkFDWixJQUFJLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLFNBQVMsQ0FBQztpQkFDM0Q7cUJBQU07b0JBQ0gsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ3JELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDO2lCQUN6RDthQUNKO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sV0FBVyxDQUFDLEtBQUs7UUFDcEIsTUFBTSxPQUFPLEdBQUcsbURBQW1ELENBQUM7UUFDcEUsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3pCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN6RDtJQUNMLENBQUM7SUFFTSxlQUFlLENBQUMsS0FBSztRQUN4QixJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDakIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRCxJQUFJLE1BQU0sRUFBRTtZQUNSLE1BQU0sVUFBVSxHQUFHLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDM0UsT0FBTyxJQUFJLDBDQUEwQyxNQUFNLENBQUMsYUFBYSxHQUFHLENBQUM7WUFDN0UsT0FBTyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzlDLE9BQU8sSUFBSSxJQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUN6QztRQUVELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQztRQUMvQyxJQUFJLFNBQVMsSUFBSSxLQUFLLENBQUMsYUFBYSxLQUFLLFVBQVUsRUFBRTtZQUNqRCxJQUFJLFNBQVMsQ0FBQyxTQUFTLEtBQUssUUFBUSxFQUFFO2dCQUNsQyxPQUFPLElBQUksaURBQWlELFNBQVMsQ0FBQyxLQUFLLE9BQU8sU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUM7YUFDL0g7aUJBQU0sSUFBSSxTQUFTLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtnQkFDMUMsT0FBTyxJQUFJLG1EQUFtRCxTQUFTLENBQUMsS0FBSyxPQUFPLFNBQVMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDO2FBQ2pJO2lCQUFNLElBQUksU0FBUyxDQUFDLFNBQVMsS0FBSyxNQUFNLEVBQUU7Z0JBQ3ZDLE9BQU8sSUFBSSxtREFBbUQsU0FBUyxDQUFDLEtBQUssT0FBTyxTQUFTLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQzthQUNqSTtTQUNKO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQztJQUVNLG1CQUFtQixDQUFDLEVBQU8sRUFBRSxFQUFPO1FBQ3ZDLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDTCxPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUN0QixPQUFPLEVBQUUsQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDO1NBQy9CO2FBQU0sSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLFdBQVcsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRTtZQUN0RCxPQUFPLEVBQUUsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQztTQUNoQztJQUNMLENBQUM7SUFFTSxlQUFlLENBQUMsRUFBTyxFQUFFLEVBQU87UUFDbkMsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTSxtQkFBbUIsQ0FBQyxFQUFPLEVBQUUsRUFBTztRQUN2QyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ0wsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUNELE9BQU8sRUFBRSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFFTSxZQUFZLENBQUMsRUFBTyxFQUFFLEVBQU87UUFDaEMsSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNMLE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRU0sc0JBQXNCO1FBQ3pCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNsRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsbUJBQW1CLElBQUksT0FBTztZQUNyRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLElBQUksT0FBTztTQUN0RCxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRTtZQUNoRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3JHO2FBQU07WUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQy9CO1FBRUQsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNaLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRU0sS0FBSyxDQUFDLDBCQUEwQixDQUFDLE1BQU0sRUFBRSxXQUFXO1FBQ3ZELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDekIsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsRUFBQyxXQUFXLEVBQUMsQ0FBQyxDQUFDO1lBQ3ZGLElBQUksdUJBQXVCLEVBQUU7Z0JBQ3pCLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztnQkFDeEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7b0JBQzlELElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUMzQyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUM1RCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUU7NEJBQ2pHLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDO3lCQUNqRjtxQkFDSjt5QkFBTTt3QkFDSCxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO3FCQUM3QjtnQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFFSCxNQUFNLHNCQUFzQixHQUFHO29CQUMzQixpQkFBaUIsRUFBRSx1QkFBdUIsQ0FBQyxpQkFBaUI7b0JBQzVELHFCQUFxQixFQUFFLHVCQUF1QixDQUFDLHFCQUFxQjtvQkFDcEUsdUJBQXVCLEVBQUUsdUJBQXVCLENBQUMsdUJBQXVCO29CQUN4RSxlQUFlLEVBQUUsWUFBWTtvQkFDN0IsVUFBVSxFQUFFLHVCQUF1QixDQUFDLFVBQVU7aUJBQ2pELENBQUM7Z0JBRUYsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFNUYsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsRUFBRTtvQkFDL0UsT0FBTzt3QkFDSCxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7d0JBQ25CLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtxQkFDcEIsQ0FBQztnQkFDTixDQUFDLENBQUMsQ0FBQzthQUNOO1NBRUo7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLGFBQWE7UUFDdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztTQUN0QztRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFFMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRTtZQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1NBQzdDO1FBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFFekcsSUFBSSxDQUFDLG1DQUFtQyxFQUFFLENBQUM7UUFFM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDeEYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7U0FDMUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3QixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7YUFDN0Q7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDekYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7U0FDMUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3QixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2hEO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCwyRUFBMkU7UUFDM0UsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLEVBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUMsQ0FBQyxDQUFDO1FBQ3BHLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHVCQUF1QixFQUFFLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7UUFDbEYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVNLG1CQUFtQjtRQUN0QixJQUFJLENBQUMsaUJBQWlCLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2xELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDaEQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTSxtQkFBbUI7UUFDdEIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDO1lBQzdDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDdkI7YUFBTTtZQUNILElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1NBQ2pDO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZO1FBQ3JCLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFO1lBQzlELElBQUksSUFBUyxDQUFDO1lBRWQsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUU7Z0JBQ3RDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7b0JBQ3JGLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFO3dCQUN0QyxPQUFPLEVBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQztvQkFDMUYsQ0FBQyxDQUFDLENBQUM7aUJBQ047cUJBQU07b0JBQ0gsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUU7d0JBQ3RDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDOUMsQ0FBQyxDQUFDLENBQUM7aUJBQ047Z0JBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRztvQkFDYjt3QkFDSSxJQUFJO3dCQUNKLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBQyxDQUFDLENBQUMsS0FBSzt3QkFDNUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSTt3QkFDbkMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVc7d0JBQzFLLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQzs0QkFDcEcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUFFO2dDQUNwRyxPQUFPLE1BQU0sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDOzRCQUN0RCxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlO3dCQUN6SCxPQUFPLEVBQUUsR0FBRzt3QkFDWixvQkFBb0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO3dCQUN2RyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJO3FCQUN0RztpQkFDSixDQUFDO2dCQUNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRTtvQkFDL0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QyxDQUFDLENBQUMsQ0FBQzthQUNOO2lCQUFNO2dCQUNILE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQztnQkFDckIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO29CQUM1QixNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFO3dCQUMzRCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLEtBQUssS0FBSyxDQUFDO29CQUNsRSxDQUFDLENBQUMsQ0FBQztvQkFFSCxTQUFTLENBQUMsSUFBSSxDQUFDO3dCQUNYLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsRUFBRTs0QkFDOUIsT0FBTyxFQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUM7d0JBQzFGLENBQUMsQ0FBQzt3QkFDRixLQUFLLEVBQUUsS0FBSzt3QkFDWixJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJO3dCQUNuQyxXQUFXLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVc7d0JBQy9DLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQzs0QkFDcEcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUFFO2dDQUNwRyxPQUFPLE1BQU0sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDOzRCQUN0RCxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO3dCQUNoSSxPQUFPLEVBQUUsR0FBRzt3QkFDWixvQkFBb0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQzt3QkFDL0QsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7cUJBQzlELENBQUMsQ0FBQztnQkFDUCxDQUFDLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ3RFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNQO1lBRUQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUztnQkFDaEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxLQUFLO2dCQUNyQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRTtnQkFFNUMsSUFBSSxTQUFTLEdBQUcsRUFBRSxDQUFDO2dCQUNuQixJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUM7Z0JBQ3pCLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUU7b0JBQ2hELFVBQVUsR0FBRyxTQUFTLENBQUM7b0JBQ3ZCLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQztvQkFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7d0JBQzlCLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQzlDLENBQUMsQ0FBQyxDQUFDO29CQUNILE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztvQkFDOUYsU0FBUyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQ3hHO3FCQUFNLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsS0FBSyxhQUFhO29CQUN6RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxLQUFLLFFBQVE7b0JBQzdDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEtBQUssT0FBTztvQkFDNUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsS0FBSyxhQUFhLEVBQUU7b0JBRXBELE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7d0JBQzlELE9BQU8sRUFBQyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDO29CQUNqRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFFO3dCQUNqQixPQUFPLENBQ0gsT0FBTyxDQUFDLEtBQUssT0FBTyxDQUFDOzRCQUNyQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7NEJBQ1QsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDOzRCQUNULElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUTs0QkFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLENBQzNCLENBQUM7b0JBQ04sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBRTt3QkFDZCxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNsQixDQUFDLENBQUMsQ0FBQztvQkFFSCxNQUFNLGdCQUFnQixHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQ3JGLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTt3QkFDL0MsT0FBTyxDQUFDLENBQUM7b0JBQ2IsQ0FBQyxDQUFDLENBQUM7aUJBQ047cUJBQU07b0JBQ0gsU0FBUyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUU7d0JBQzNDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDbEQsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsVUFBVSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7aUJBQzFGO2dCQUVELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO29CQUNoQixJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsU0FBUztvQkFDZixLQUFLLEVBQUUsVUFBVTtvQkFDakIsV0FBVyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlO29CQUNuRCxJQUFJLEVBQUUsS0FBSztvQkFDWCxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUNULE9BQU8sRUFBRSxJQUFJO29CQUNiLG9CQUFvQixFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlO29CQUM1RCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZUFBZTtpQkFDM0QsQ0FBQyxDQUFDO2FBQ047U0FDSjtJQUNMLENBQUM7SUFFTSxzQkFBc0I7UUFDekIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtZQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuTCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDckQ7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDOUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQzdEO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRTtZQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDbkY7SUFDTCxDQUFDO0lBRU8sZ0NBQWdDO1FBQ3BDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDbkQsSUFBSSxHQUFHLEtBQUssTUFBTSxFQUFFO2dCQUNoQixNQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2xDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDckgsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQzthQUMxRjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLG1DQUFtQztRQUN2QyxNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztRQUN6SyxjQUFjLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDekMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQy9DO1lBQ0QsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFdBQVcsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxXQUFXLENBQUM7UUFDckgsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sYUFBYSxDQUFDLE9BQWlCO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQ2hGLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFO2dCQUMxQixJQUFJLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7b0JBQy9FLE1BQU07aUJBQ1Q7YUFDSjtTQUNKO1FBQ0QsTUFBTSxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDeEosT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxVQUFVLEVBQUU7WUFDM0QsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7Z0JBQzFCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsTUFBTSxLQUFLLFVBQVUsRUFBRTtvQkFDMUQsTUFBTTtpQkFDVDthQUNKO1NBQ0o7SUFDTCxDQUFDO0lBRU8sa0JBQWtCO1FBQ3RCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUU7WUFDL0IsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7WUFFeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFO2dCQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7YUFDbEM7WUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRTtnQkFDMUMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUM7cUJBQ2xFLE1BQU0sQ0FBQyxPQUFPLENBQUM7cUJBQ2YsR0FBRyxDQUFDLE9BQU8sQ0FBQztxQkFDWixPQUFPLEVBQUUsQ0FBQzthQUNsQjtZQUVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzlFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxNQUFNLEVBQUU7Z0JBQ3BGLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsRUFBRTtvQkFDbkQsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFO3dCQUNuQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDO3FCQUNyRTtnQkFDTCxDQUFDLENBQUMsQ0FBQzthQUNOO1lBRUQsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQy9ELElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7b0JBQ3RCLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO29CQUNkLE9BQU8sSUFBSSxDQUFDO2lCQUNmO2dCQUNELE9BQU8sS0FBSyxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUM1QixJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNsRCxDQUFDLENBQUMsQ0FBQztZQUVILElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNwQztTQUNKO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsS0FBSztRQUMzQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUU7WUFDOUMsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDaEM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUV0QyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUV2QixRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3BCLElBQUksV0FBVyxHQUFRLEVBQUUsQ0FBQztZQUMxQixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTTtnQkFDMUYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFO2dCQUNuRSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2FBQ25GO1lBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7Z0JBQ25CLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7Z0JBQ3hDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7Z0JBQ3hDLE9BQU8sRUFBRSxXQUFXO2FBQ3ZCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFO2dCQUNwQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztvQkFDbkIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztvQkFDcEMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztvQkFDaEMsT0FBTyxFQUFFLEVBQUU7aUJBQ2QsQ0FBQyxDQUFDO2FBQ047UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRTtZQUNuQyxNQUFNLHNCQUFzQixHQUFHO2dCQUMzQixpQkFBaUIsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWE7Z0JBQ2pELHFCQUFxQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCO2dCQUN6RCx1QkFBdUIsRUFBRSxFQUFFO2dCQUMzQixlQUFlLEVBQUUsRUFBRTtnQkFDbkIsVUFBVSxFQUFFLEVBQUU7YUFDakIsQ0FBQztZQUVGLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FDNUQsc0JBQXNCLEVBQ3RCLEdBQUcsRUFDSCxVQUFVLENBQ2IsQ0FBQztZQUVGLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7b0JBQ25CLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7b0JBQ3BDLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7b0JBQ2hDLE9BQU8sRUFBRSxFQUFFO2lCQUNkLENBQUMsQ0FBQztZQUNQLENBQUMsQ0FBQyxDQUFDO1NBQ047UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO2FBQ2pDLE1BQU0sQ0FBQyxPQUFPLENBQUM7YUFDZixHQUFHLENBQUMsT0FBTyxDQUFDO2FBQ1osSUFBSSxFQUFFO2FBQ04sT0FBTyxFQUFFLENBQUM7UUFFZixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3QixNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsRUFBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBQyxDQUFDLENBQUM7WUFDOUYsSUFBSSxXQUFXLEVBQUU7Z0JBQ2IsSUFBSSxDQUFDLE9BQU8sR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDO2FBQ3RDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztvSEE3NUJRLHNCQUFzQixvREFrSFgsZUFBZTt3R0FsSDFCLHNCQUFzQiw4SUFFcEIsa0JBQWtCLG1LQzFDakMsZ25ySUFzOURBOzRGRDk2RGEsc0JBQXNCO2tCQU5sQyxTQUFTOytCQUNJLG1CQUFtQixRQUd2QixFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQzs7MEJBb0hwQixNQUFNOzJCQUFDLGVBQWU7d05BaEhKLEtBQUs7c0JBQW5DLFNBQVM7dUJBQUMsa0JBQWtCO2dCQUNRLHNCQUFzQjtzQkFBMUQsU0FBUzt1QkFBQyx3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5qZWN0LCBPbkluaXQsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIE1BVF9MRUdBQ1lfRElBTE9HX0RBVEEgYXMgTUFUX0RJQUxPR19EQVRBLFxuICAgIE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2csXG4gICAgTWF0TGVnYWN5RGlhbG9nUmVmIGFzIE1hdERpYWxvZ1JlZlxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJztcbmltcG9ydCB7XG4gICAgU291cmNlU2VsZWN0b3JEaWFsb2dDb21wb25lbnRcbn0gZnJvbSAnLi4vLi4vZGFzaGJvYXJkLWVkaXRvci9zb3VyY2Utc2VsZWN0b3ItZGlhbG9nL3NvdXJjZS1zZWxlY3Rvci1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7RGFzaGJvYXJkU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGFzaGJvYXJkLnNlcnZpY2UnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcbmltcG9ydCBjaHJvbWEgZnJvbSAnY2hyb21hLWpzJztcbmltcG9ydCB7RGF0YXNldFNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2RhdGFzZXQuc2VydmljZSc7XG5pbXBvcnQge0VkaXREYXNoYm9hcmRBbGVydENvbXBvbmVudH0gZnJvbSAnLi4vY29uZmlndXJlLWl0ZW0vZWRpdC1kYXNoYm9hcmQtYWxlcnQvZWRpdC1kYXNoYm9hcmQtYWxlcnQuY29tcG9uZW50JztcbmltcG9ydCB7XG4gICAgRGF0YXNldEZpbHRlckNvbXBvbmVudFxufSBmcm9tICcuLi8uLi9kYXRhc2V0L2RhdGFzZXQtZWRpdG9yL2RhdGFzZXQtZmlsdGVycy9kYXRhc2V0LWZpbHRlci9kYXRhc2V0LWZpbHRlci5jb21wb25lbnQnO1xuaW1wb3J0IHtSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge0RhdGFzb3VyY2VTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9kYXRhc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBY3Rpb25FdmVudH0gZnJvbSAnLi4vLi4vLi4vb2JqZWN0cy9hY3Rpb24tZXZlbnQnO1xuaW1wb3J0IHtCYXNlQ2hhcnREaXJlY3RpdmV9IGZyb20gJ25nMi1jaGFydHMnO1xuaW1wb3J0IHJlZ3Jlc3Npb24gZnJvbSAncmVncmVzc2lvbic7XG5pbXBvcnQge1Byb2plY3RTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9wcm9qZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHtzY2FsZXN9IGZyb20gJ2NoYXJ0LmpzJztcbmltcG9ydCB2aXNOZXR3b3JrT3B0aW9ucyBmcm9tICcuL3Zpcy1uZXR3b3JrLW9wdGlvbnMuanNvbic7XG5pbXBvcnQge0NyZWF0ZURhdGFzZXRDb21wb25lbnR9IGZyb20gJy4uLy4uL2RhdGFzZXQvY3JlYXRlLWRhdGFzZXQvY3JlYXRlLWRhdGFzZXQuY29tcG9uZW50JztcbmltcG9ydCB7XG4gICAgQ2hhbmdlU291cmNlV2FybmluZ0NvbXBvbmVudFxufSBmcm9tICcuLi8uLi9kYXRhLWV4cGxvcmVyL2NoYW5nZS1zb3VyY2Utd2FybmluZy9jaGFuZ2Utc291cmNlLXdhcm5pbmcuY29tcG9uZW50JztcbmltcG9ydCB7RGF0YXNldEVkaXRvckNvbXBvbmVudH0gZnJvbSAnLi4vLi4vZGF0YXNldC9kYXRhc2V0LWVkaXRvci9kYXRhc2V0LWVkaXRvci5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2tpLWNvbmZpZ3VyZS1pdGVtJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY29uZmlndXJlLWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2NvbmZpZ3VyZS1pdGVtLmNvbXBvbmVudC5zYXNzJ10sXG4gICAgaG9zdDoge2NsYXNzOiAnY29uZmlndXJlLWRpYWxvZyd9XG59KVxuZXhwb3J0IGNsYXNzIENvbmZpZ3VyZUl0ZW1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgQFZpZXdDaGlsZChCYXNlQ2hhcnREaXJlY3RpdmUpIGNoYXJ0OiBCYXNlQ2hhcnREaXJlY3RpdmU7XG4gICAgQFZpZXdDaGlsZCgnZGF0YXNldEVkaXRvckNvbXBvbmVudCcpIGRhdGFzZXRFZGl0b3JDb21wb25lbnQ6IERhdGFzZXRFZGl0b3JDb21wb25lbnQ7XG5cbiAgICBwdWJsaWMgZ3JpZDtcbiAgICBwdWJsaWMgY2hhcnREYXRhOiBhbnk7XG4gICAgcHVibGljIG1ldHJpYzogYW55ID0ge307XG4gICAgcHVibGljIHRleHREYXRhOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgbmV0d29ya0RhdGE6IGFueSA9IHt9O1xuICAgIHB1YmxpYyB3b3JkQ2xvdWQ6IGFueSA9IHt9O1xuICAgIHB1YmxpYyBpbWFnZURhdGE6IGFueSA9IHt9O1xuICAgIHB1YmxpYyB0YWJ1bGFyOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgdGFibGVDZWxsczogYW55ID0ge307XG4gICAgcHVibGljIGdlbmVyYWw6IGFueSA9IHt9O1xuICAgIHB1YmxpYyBkZXBlbmRlbmNpZXM6IGFueSA9IHt9O1xuICAgIHB1YmxpYyBjYWxsVG9BY3Rpb246IGFueSA9IHt9O1xuICAgIHB1YmxpYyBhY3Rpb25JdGVtOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgZGFzaGJvYXJkO1xuICAgIHB1YmxpYyBkYXNoYm9hcmRJdGVtVHlwZTtcbiAgICBwdWJsaWMgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlOiBhbnk7XG4gICAgcHVibGljIGRhc2hib2FyZHM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBzaGFyZWREYXNoYm9hcmRzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgcHJpdmF0ZURhc2hib2FyZHM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBkYXNoYm9hcmRQYXJhbWV0ZXJzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgZGFzaGJvYXJkUGFyYW1WYWx1ZXM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBhY3Rpb25FdmVudHM6IEFjdGlvbkV2ZW50W10gPSBbXTtcbiAgICBwdWJsaWMgYWRtaW46IGJvb2xlYW47XG4gICAgcHVibGljIGZpbHRlckZpZWxkczogYW55ID0gW107XG4gICAgcHVibGljIGNoYXJ0VHlwZXMgPSBbJ2xpbmUnLCAnYmFyJywgJ3BpZScsICdkb3VnaG51dCcsICdzY2F0dGVyJ107XG4gICAgcHVibGljIG1ldHJpY0Zvcm1hdHMgPSBbJ0N1cnJlbmN5JywgJ051bWJlcicsICdQZXJjZW50YWdlJ107XG4gICAgcHVibGljIGN1cnJlbmNpZXMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdCcml0aXNoIFBvdW5kICjCoyknLFxuICAgICAgICAgICAgdmFsdWU6ICdHQlAnLFxuICAgICAgICAgICAgc3ltYm9sOiAnwqMnXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdVUyBEb2xsYXIgKCQpJyxcbiAgICAgICAgICAgIHZhbHVlOiAnVVNEJyxcbiAgICAgICAgICAgIHN5bWJvbDogJyQnXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdFdXJvICjigqwpJyxcbiAgICAgICAgICAgIHZhbHVlOiAnRVVSJyxcbiAgICAgICAgICAgIHN5bWJvbDogJ+KCrCdcbiAgICAgICAgfVxuICAgIF07XG4gICAgcHVibGljIGZpbHRlckp1bmN0aW9uID0ge1xuICAgICAgICBsb2dpYzogJ0FORCcsXG4gICAgICAgIGZpbHRlcnM6IFt7XG4gICAgICAgICAgICBsaHNFeHByZXNzaW9uOiAnJyxcbiAgICAgICAgICAgIHJoc0V4cHJlc3Npb246ICcnLFxuICAgICAgICAgICAgZmlsdGVyVHlwZTogJydcbiAgICAgICAgfV0sXG4gICAgICAgIGZpbHRlckp1bmN0aW9uczogW11cbiAgICB9O1xuICAgIHB1YmxpYyBjb2x1bW5Gb3JtYXRzOiBhbnkgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRpdGxlOiAnTnVtYmVyJyxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXInXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRpdGxlOiAnQ3VycmVuY3knLFxuICAgICAgICAgICAgdHlwZTogJ2N1cnJlbmN5J1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ1BlcmNlbnRhZ2UnLFxuICAgICAgICAgICAgdHlwZTogJ3BlcmNlbnRhZ2UnXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRpdGxlOiAnRGF0ZSAmIFRpbWUnLFxuICAgICAgICAgICAgdHlwZTogJ2RhdGV0aW1lJ1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ0NvbXBhcmlzb24nLFxuICAgICAgICAgICAgdHlwZTogJ2NvbXBhcmlzb24nXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHRpdGxlOiAnTGluaycsXG4gICAgICAgICAgICB0eXBlOiAnbGluaydcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdGl0bGU6ICdDdXN0b20nLFxuICAgICAgICAgICAgdHlwZTogJ2N1c3RvbSdcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgdGl0bGU6ICdIaWRlIENvbHVtbicsXG4gICAgICAgICAgICB0eXBlOiAnaGlkZSdcbiAgICAgICAgfVxuICAgIF07XG4gICAgcHVibGljIHNob3dBbGVydFdhcm5pbmcgPSBmYWxzZTtcbiAgICBwdWJsaWMgZGFwRmVlZHM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyBzaWRlT3BlbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBvcGVuU2lkZSA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuICAgIHB1YmxpYyBkYXRhc2V0OiBhbnk7XG4gICAgcHVibGljIGVkZ2VEYXRhc2V0OiBhbnk7XG4gICAgcHVibGljIGZ1bGxFZGdlRGF0YXNldDogYW55O1xuICAgIHB1YmxpYyBfID0gXztcbiAgICBwdWJsaWMgZG9jQ29sdW1ucyA9IG5ldyBTdWJqZWN0KCk7XG4gICAgcHVibGljIGNhblNldEFsZXJ0cyA9IGZhbHNlO1xuICAgIHB1YmxpYyBjb2xvdXJQYWxldHRlczogYW55ID0gW107XG4gICAgcHVibGljIHZpc05ldHdvcmtPcHRpb25zID0gdmlzTmV0d29ya09wdGlvbnM7XG4gICAgcHVibGljIGF2YWlsYWJsZU5vZGVPcHRpb25zOiBzdHJpbmdbXSA9IFtdO1xuICAgIHB1YmxpYyBhdmFpbGFibGVFZGdlT3B0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgICBwdWJsaWMgZGF0YXNldE5vZGVzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgZGF0YXNldEVkZ2VzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgbm9kZUdyb3VwczogYW55O1xuICAgIHB1YmxpYyB3aWRnZXRQYXJhbWV0ZXJzOiBhbnkgPSB7fTtcblxuICAgIHByb3RlY3RlZCByZWFkb25seSBBcnJheSA9IEFycmF5O1xuICAgIHByb3RlY3RlZCByZWFkb25seSBPYmplY3QgPSBPYmplY3Q7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Q29uZmlndXJlSXRlbUNvbXBvbmVudD4sXG4gICAgICAgICAgICAgICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHB1YmxpYyBkYXRhOiBhbnksXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhc2hib2FyZFNlcnZpY2U6IERhc2hib2FyZFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc2V0U2VydmljZTogRGF0YXNldFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc291cmNlU2VydmljZTogRGF0YXNvdXJjZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgICAgICAgICBwcml2YXRlIHByb2plY3RTZXJ2aWNlOiBQcm9qZWN0U2VydmljZSkge1xuICAgIH1cblxuICAgIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlTm9kZU9wdGlvbnMgPSBPYmplY3Qua2V5cyh0aGlzLnZpc05ldHdvcmtPcHRpb25zLm5vZGVzKTtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVFZGdlT3B0aW9ucyA9IE9iamVjdC5rZXlzKHRoaXMudmlzTmV0d29ya09wdGlvbnMuZWRnZXMpO1xuXG4gICAgICAgIHRoaXMuZ3JpZCA9IHRoaXMuZGF0YS5ncmlkO1xuICAgICAgICB0aGlzLmRhc2hib2FyZCA9IHRoaXMuZGF0YS5kYXNoYm9hcmQ7XG4gICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlID0gdGhpcy5kYXRhLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZTtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZSA9IHRoaXMuZGF0YS5kYXNoYm9hcmRJdGVtVHlwZTtcbiAgICAgICAgdGhpcy5hZG1pbiA9ICEhdGhpcy5kYXRhLmFkbWluO1xuICAgICAgICB0aGlzLmFjdGlvbkV2ZW50cyA9IHRoaXMuZGF0YS5hY3Rpb25FdmVudHMgfHwgW107XG4gICAgICAgIHRoaXMuY2FuU2V0QWxlcnRzID0gdGhpcy5wcm9qZWN0U2VydmljZS5kb2VzQWN0aXZlUHJvamVjdEhhdmVQcml2aWxlZ2UoJ2FsZXJ0bWFuYWdlJyk7XG5cbiAgICAgICAgaWYgKHRoaXMuYWN0aW9uRXZlbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5jb2x1bW5Gb3JtYXRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnQWN0aW9uJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnYWN0aW9uJ1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuY29sb3VyTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJNb2RlID0gJ2xyZ2InO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yKSkge1xuICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciA9IFtfLmlzU3RyaW5nKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IpID8gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvciA6ICcnXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWREYXRhc291cmNlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvYWREYXNoYm9hcmRJdGVtcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXNoYm9hcmRTZXJ2aWNlLmdldERhc2hib2FyZHMoXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICcxMDAnLFxuICAgICAgICAgICAgJzAnXG4gICAgICAgICkudG9Qcm9taXNlKCkudGhlbihkYXNoYm9hcmRzID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkcyA9IGRhc2hib2FyZHM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZGFzaGJvYXJkU2VydmljZS5nZXREYXNoYm9hcmRzKFxuICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAnMTAwJyxcbiAgICAgICAgICAgICcwJyxcbiAgICAgICAgICAgIG51bGxcbiAgICAgICAgKS50b1Byb21pc2UoKS50aGVuKGRhc2hib2FyZHMgPT4ge1xuICAgICAgICAgICAgdGhpcy5zaGFyZWREYXNoYm9hcmRzID0gZGFzaGJvYXJkcztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5kYXNoYm9hcmRTZXJ2aWNlLmdldERhc2hib2FyZHMoXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICcxMDAnLFxuICAgICAgICAgICAgJzAnLFxuICAgICAgICAgICAgMFxuICAgICAgICApLnRvUHJvbWlzZSgpLnRoZW4oZGFzaGJvYXJkcyA9PiB7XG4gICAgICAgICAgICB0aGlzLnByaXZhdGVEYXNoYm9hcmRzID0gZGFzaGJvYXJkcztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5kYXBGZWVkcyA9IGF3YWl0IHRoaXMuZGF0YXNldFNlcnZpY2UuZ2V0RGF0YXNldHMoXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICcxMDAwJyxcbiAgICAgICAgICAgICcwJyxcbiAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgJydcbiAgICAgICAgKS50b1Byb21pc2UoKTtcblxuICAgICAgICB0aGlzLm9wZW5TaWRlLnN1YnNjcmliZSgob3BlbjogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgaWYgKG9wZW4pIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhcldyYXBwZXIyJyk/LmNsYXNzTGlzdC5hZGQoJ3otMjAnKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhcldyYXBwZXIyJyk/LmNsYXNzTGlzdC5yZW1vdmUoJy16LTEwJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5kb2NDb2x1bW5zLm5leHQodGhpcy5maWx0ZXJGaWVsZHMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NpZGViYXJXcmFwcGVyMicpPy5jbGFzc0xpc3QuYWRkKCctei0xMCcpO1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhcldyYXBwZXIyJyk/LmNsYXNzTGlzdC5yZW1vdmUoJ3otMjAnKTtcbiAgICAgICAgICAgICAgICB9LCA3MDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zaWRlT3BlbiA9IG9wZW47XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHByb2plY3Q6IGFueSA9IGF3YWl0IHRoaXMucHJvamVjdFNlcnZpY2UuZ2V0UHJvamVjdCh0aGlzLnByb2plY3RTZXJ2aWNlLmFjdGl2ZVByb2plY3QuZ2V0VmFsdWUoKS5wcm9qZWN0S2V5KTtcbiAgICAgICAgaWYgKHByb2plY3Quc2V0dGluZ3MucGFsZXR0ZXMgJiYgcHJvamVjdC5zZXR0aW5ncy5wYWxldHRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuY29sb3VyUGFsZXR0ZXMgPSBwcm9qZWN0LnNldHRpbmdzLnBhbGV0dGVzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUNoYXJ0KG5ld1ZhbHVlLCBpbmRleCkge1xuICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvcltpbmRleF0gPSBuZXdWYWx1ZTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNoYXJ0LmNoYXJ0LnVwZGF0ZSgpO1xuICAgICAgICB9LCA1MCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNoYW5nZVNvdXJjZSgpIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihDcmVhdGVEYXRhc2V0Q29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzEyMDBweCcsXG4gICAgICAgICAgICBoZWlnaHQ6ICc4MDBweCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWRtaW46IHRoaXMuYWRtaW5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpYWxvZ1JlZjIgPSB0aGlzLmRpYWxvZy5vcGVuKENoYW5nZVNvdXJjZVdhcm5pbmdDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6ICc3MDBweCcsXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogJzI3NXB4J1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGRpYWxvZ1JlZjIuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUocHJvY2VlZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5kYXRhc2V0SW5zdGFuY2VJZCA9IHJlcy5kYXRhc2V0SW5zdGFuY2VJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmRhdGFzb3VyY2VJbnN0YW5jZUtleSA9IHJlcy5kYXRhc291cmNlSW5zdGFuY2VLZXk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5zb3VyY2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHJlcy50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogcmVzLmRhdGFzZXRJbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VJbnN0YW5jZUtleTogcmVzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtYXRpb24gPSB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS50cmFuc2Zvcm1hdGlvbkluc3RhbmNlc1swXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1hdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNldEVkaXRvckNvbXBvbmVudC5leGNsdWRlVXBzdHJlYW1UcmFuc2Zvcm1hdGlvbnModHJhbnNmb3JtYXRpb24sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFzZXRFZGl0b3JDb21wb25lbnQuZXZhbHVhdGVEYXRhc2V0KHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZWxlY3RlZERhdGFzb3VyY2UoKSB7XG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oU291cmNlU2VsZWN0b3JEaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTIwMHB4JyxcbiAgICAgICAgICAgIGhlaWdodDogJzgwMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkYXNoYm9hcmQ6IHRoaXMuZGFzaGJvYXJkLFxuICAgICAgICAgICAgICAgIGRhc2hib2FyZEl0ZW1JbnN0YW5jZUtleTogdGhpcy5kYXRhLml0ZW1JbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICBkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2U6IHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgZGFzaGJvYXJkSWQ6IHRoaXMuZGFzaGJvYXJkLmlkLFxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUtleTogdGhpcy5kYXRhLml0ZW1JbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IHt9LFxuICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiBbXVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYWRtaW46IHRoaXMuYWRtaW5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSA9IGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZTtcbiAgICAgICAgICAgIHRoaXMubG9hZERhc2hib2FyZEl0ZW1zKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBwaWNrTmV0d29ya0VkZ2VEYXRhc2V0KCkge1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKFNvdXJjZVNlbGVjdG9yRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzEyMDBweCcsXG4gICAgICAgICAgICBoZWlnaHQ6ICc4MDBweCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgZGFzaGJvYXJkOiB0aGlzLmRhc2hib2FyZCxcbiAgICAgICAgICAgICAgICBkYXNoYm9hcmRJdGVtSW5zdGFuY2VLZXk6IHRoaXMuZGF0YS5pdGVtSW5zdGFuY2VLZXksXG4gICAgICAgICAgICAgICAgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlOiB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZSB8fCB7XG4gICAgICAgICAgICAgICAgICAgIGRhc2hib2FyZElkOiB0aGlzLmRhc2hib2FyZC5pZCxcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VLZXk6IHRoaXMuZGF0YS5pdGVtSW5zdGFuY2VLZXksXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyVmFsdWVzOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyczogW11cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGFkbWluOiB0aGlzLmFkbWluXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShhc3luYyBkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UgPT4ge1xuICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldElkID0gZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmRhdGFzZXRJbnN0YW5jZUlkO1xuICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNvdXJjZUtleSA9IGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5kYXRhc291cmNlSW5zdGFuY2VLZXk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMubG9hZEVkZ2VEYXRhc2V0KCk7XG5cbiAgICAgICAgICAgIHRoaXMubmV0d29ya0RhdGEuZWRnZURhdGFzZXRUaXRsZSA9IGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS50aXRsZSB8fCB0aGlzLmVkZ2VEYXRhc2V0Lmluc3RhbmNlVGl0bGU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBsb2FkRWRnZURhdGFzZXQoKSB7XG4gICAgICAgIGNvbnN0IGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkgPSB7XG4gICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldElkLFxuICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiB0aGlzLm5ldHdvcmtEYXRhLmVkZ2VEYXRhc291cmNlS2V5LFxuICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXM6IFtdLFxuICAgICAgICAgICAgcGFyYW1ldGVyVmFsdWVzOiB7fSxcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHt9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5lZGdlRGF0YXNldCA9IGF3YWl0IHRoaXMuZGF0YXNldFNlcnZpY2UuZXZhbHVhdGVEYXRhc2V0KFxuICAgICAgICAgICAgZGF0YXNldEluc3RhbmNlU3VtbWFyeSxcbiAgICAgICAgICAgICcwJyxcbiAgICAgICAgICAgICcxJ1xuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBjbGVhckVkZ2VEYXRhc2V0KCkge1xuICAgICAgICBkZWxldGUgdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldFRpdGxlO1xuICAgICAgICBkZWxldGUgdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldElkO1xuICAgICAgICBkZWxldGUgdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNvdXJjZUtleTtcblxuICAgICAgICB0aGlzLmVkZ2VEYXRhc2V0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkR3JvdXBPcHRpb24obm9kZUdyb3VwOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLm5ldHdvcmtEYXRhLm5vZGVHcm91cE9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMubmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9ucyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLm5ldHdvcmtEYXRhLm5vZGVHcm91cE9wdGlvbnNbbm9kZUdyb3VwXSkge1xuICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlR3JvdXBPcHRpb25zW25vZGVHcm91cF0gPSB7b3B0aW9uczogW119O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlR3JvdXBPcHRpb25zW25vZGVHcm91cF0ub3B0aW9ucy51bnNoaWZ0KHt9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkT3B0aW9uKHR5cGVPcHRpb25zOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLm5ldHdvcmtEYXRhW3R5cGVPcHRpb25zXSB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLm5ldHdvcmtEYXRhW3R5cGVPcHRpb25zXSkpIHtcbiAgICAgICAgICAgIHRoaXMubmV0d29ya0RhdGFbdHlwZU9wdGlvbnNdID0gW107XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm5ldHdvcmtEYXRhW3R5cGVPcHRpb25zXS51bnNoaWZ0KHt9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlT3B0aW9ucyhub2RlT3B0aW9uOiBhbnksIGRhdGFzZXRUeXBlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gbm9kZU9wdGlvbi5rZXk7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IG5vZGVPcHRpb24uY29sdW1uO1xuICAgICAgICBsZXQgdmFsdWUgPSBub2RlT3B0aW9uLnZhbHVlO1xuICAgICAgICBsZXQgYWxsRGF0YSA9IHRoaXMuZGF0YXNldC5hbGxEYXRhO1xuXG4gICAgICAgIGlmIChkYXRhc2V0VHlwZSA9PT0gJ2RhdGFzZXRFZGdlcycpIHtcbiAgICAgICAgICAgIGFsbERhdGEgPSB0aGlzLmZ1bGxFZGdlRGF0YXNldCA/IHRoaXMuZnVsbEVkZ2VEYXRhc2V0LmFsbERhdGEgOiB0aGlzLmRhdGFzZXQuYWxsRGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXNbZGF0YXNldFR5cGVdLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBpZiAoY29sdW1uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YXNldCA9IF8uZmluZChhbGxEYXRhLCB7aWQ6IGl0ZW0uaWR9KTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YXNldCkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGRhdGFzZXRbY29sdW1uXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gXy5maW5kKGl0ZW0ub3B0aW9ucywge2tleTogb3B0aW9ufSk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAgICAgICBleGlzdGluZy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtLm9wdGlvbnMudW5zaGlmdCh7a2V5OiBvcHRpb24sIHZhbHVlfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkYXRhTG9hZGVkKGRhdGFzZXQpIHtcbiAgICAgICAgdGhpcy5kYXRhc2V0ID0gZGF0YXNldDtcbiAgICAgICAgdGhpcy5maWx0ZXJGaWVsZHMgPSBfLm1hcChkYXRhc2V0LmNvbHVtbnMsIGNvbHVtbiA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBjb2x1bW4udGl0bGUsXG4gICAgICAgICAgICAgICAgbmFtZTogY29sdW1uLm5hbWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZU1ldHJpY0RhdGFWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy5zZXRDaGFydERhdGEoKTtcbiAgICAgICAgdGhpcy5zZXROZXR3b3JrQ2hhcnREYXRhKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGN0YVVwZGF0ZShjdGEpIHtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRQYXJhbWV0ZXJzID0gW107XG4gICAgICAgIGlmIChjdGEpIHtcbiAgICAgICAgICAgIGlmIChjdGEudHlwZSAmJiBjdGEudHlwZSA9PT0gJ2Rhc2hib2FyZCcpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN0YS5wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0YS5wYXJhbWV0ZXJzID0ge307XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZGFzaGJvYXJkOiBhbnkgPSBhd2FpdCB0aGlzLmRhc2hib2FyZFNlcnZpY2UuZ2V0RGFzaGJvYXJkKGN0YS52YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKGRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkUGFyYW1ldGVycyA9IF8udmFsdWVzKGRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzKTtcblxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnZGFzaGJvYXJkLXBhcmFtLXBpY2snKS5pdGVtKDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjdGEucGFyYW1ldGVycyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNldEltYWdlRGF0YShjb2x1bW4pIHtcbiAgICAgICAgdGhpcy5pbWFnZURhdGEuc291cmNlID0gY29sdW1uID8gdGhpcy5kYXRhc2V0LmFsbERhdGFbMF1bY29sdW1uXSA6IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIHNldENvbHVtbihjb2x1bW4pIHtcbiAgICAgICAgaWYgKCF0aGlzLnRhYmxlQ2VsbHNbY29sdW1uXSB8fCBBcnJheS5pc0FycmF5KHRoaXMudGFibGVDZWxsc1tjb2x1bW5dKSkge1xuICAgICAgICAgICAgdGhpcy50YWJsZUNlbGxzW2NvbHVtbl0gPSB7fTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRDb2x1bW5Gb3JtYXQoZm9ybWF0KSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy50YWJsZUNlbGxzW3RoaXMudGFibGVDZWxscy5jb2x1bW5dLnR5cGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudGFibGVDZWxsc1t0aGlzLnRhYmxlQ2VsbHMuY29sdW1uXS5kYXRhIHx8IEFycmF5LmlzQXJyYXkodGhpcy50YWJsZUNlbGxzW3RoaXMudGFibGVDZWxscy5jb2x1bW5dLmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YWJsZUNlbGxzW3RoaXMudGFibGVDZWxscy5jb2x1bW5dLmRhdGEgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBlZGl0QWxlcnQoYWxlcnQsIGluZGV4Pykge1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEVkaXREYXNoYm9hcmRBbGVydENvbXBvbmVudCwge1xuICAgICAgICAgICAgd2lkdGg6ICc5MDBweCcsXG4gICAgICAgICAgICBoZWlnaHQ6ICc3NTBweCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWxlcnQsXG4gICAgICAgICAgICAgICAgZmlsdGVyRmllbGRzOiB0aGlzLmZpbHRlckZpZWxkc1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoYWxlcnRJdGVtID0+IHtcbiAgICAgICAgICAgIGlmIChhbGVydEl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHMgPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuYWxlcnRzW2luZGV4XSA9IGFsZXJ0SXRlbTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHMucHVzaChhbGVydEl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dBbGVydFdhcm5pbmcgPSAhdGhpcy5kYXNoYm9hcmQuYWxlcnRzRW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGVBbGVydChpbmRleCkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gJ0FyZSB5b3Ugc3VyZSB5b3Ugd291bGQgbGlrZSB0byBkZWxldGUgdGhpcyBhbGVydD8nO1xuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldEFsZXJ0RGV0YWlscyhhbGVydCkge1xuICAgICAgICBsZXQgZGV0YWlscyA9ICcnO1xuICAgICAgICBjb25zdCBmaWx0ZXIgPSBhbGVydC5maWx0ZXJUcmFuc2Zvcm1hdGlvbi5maWx0ZXJzWzBdO1xuXG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlclR5cGUgPSBEYXRhc2V0RmlsdGVyQ29tcG9uZW50LmdldEZpbHRlclR5cGUoZmlsdGVyLmZpbHRlclR5cGUpO1xuICAgICAgICAgICAgZGV0YWlscyArPSBgPHNwYW4gY2xhc3M9XCJmb250LW1lZGl1bVwiPldoZXJlPC9zcGFuPiAke2ZpbHRlci5saHNFeHByZXNzaW9ufSBgO1xuICAgICAgICAgICAgZGV0YWlscyArPSBmaWx0ZXJUeXBlID8gZmlsdGVyVHlwZS5sYWJlbCA6ICcnO1xuICAgICAgICAgICAgZGV0YWlscyArPSBgICR7ZmlsdGVyLnJoc0V4cHJlc3Npb259YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1hdGNoUnVsZSA9IGFsZXJ0Lm1hdGNoUnVsZUNvbmZpZ3VyYXRpb247XG4gICAgICAgIGlmIChtYXRjaFJ1bGUgJiYgYWxlcnQubWF0Y2hSdWxlVHlwZSA9PT0gJ3Jvd2NvdW50Jykge1xuICAgICAgICAgICAgaWYgKG1hdGNoUnVsZS5tYXRjaFR5cGUgPT09ICdlcXVhbHMnKSB7XG4gICAgICAgICAgICAgICAgZGV0YWlscyArPSBgIDxzcGFuIGNsYXNzPVwiZm9udC1tZWRpdW1cIj5BbmQ8L3NwYW4+IGV4YWN0bHkgJHttYXRjaFJ1bGUudmFsdWV9IHJvdyR7bWF0Y2hSdWxlLnZhbHVlID4gMSA/ICdzJyA6ICcnfSByZXR1cm5lZGA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hdGNoUnVsZS5tYXRjaFR5cGUgPT09ICdncmVhdGVyJykge1xuICAgICAgICAgICAgICAgIGRldGFpbHMgKz0gYCA8c3BhbiBjbGFzcz1cImZvbnQtbWVkaXVtXCI+QW5kPC9zcGFuPiBtb3JlIHRoYW4gJHttYXRjaFJ1bGUudmFsdWV9IHJvdyR7bWF0Y2hSdWxlLnZhbHVlID4gMSA/ICdzJyA6ICcnfSByZXR1cm5lZGA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1hdGNoUnVsZS5tYXRjaFR5cGUgPT09ICdsZXNzJykge1xuICAgICAgICAgICAgICAgIGRldGFpbHMgKz0gYCA8c3BhbiBjbGFzcz1cImZvbnQtbWVkaXVtXCI+QW5kPC9zcGFuPiBsZXNzIHRoYW4gJHttYXRjaFJ1bGUudmFsdWV9IHJvdyR7bWF0Y2hSdWxlLnZhbHVlID4gMSA/ICdzJyA6ICcnfSByZXR1cm5lZGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGV0YWlscztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Q2FsbFRvQWN0aW9uSXRlbShkMTogYW55LCBkMjogYW55KSB7XG4gICAgICAgIGlmICghZDIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkMi50eXBlID09PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgcmV0dXJuIGQxLnR5cGUgPT09ICdjdXN0b20nO1xuICAgICAgICB9IGVsc2UgaWYgKGQyLnR5cGUgPT09ICdkYXNoYm9hcmQnIHx8IGQyLnR5cGUgPT09ICdmZWVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGQxLnZhbHVlID09PSBkMi52YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjdGFTZWxlY3RPcHRpb24oYzE6IGFueSwgYzI6IGFueSkge1xuICAgICAgICByZXR1cm4gYzEgPT09IGMyO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYWxldHRlU2VsZWN0T3B0aW9uKGMxOiBhbnksIGMyOiBhbnkpIHtcbiAgICAgICAgaWYgKCFjMikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGMxLm5hbWUgPT09IGMyLm5hbWU7XG4gICAgfVxuXG4gICAgcHVibGljIGRlcFNlbGVjdGlvbihjMTogYW55LCBjMjogYW55KSB7XG4gICAgICAgIGlmICghYzIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjMS50eXBlID09PSBjMi50eXBlO1xuICAgIH1cblxuICAgIHB1YmxpYyBiYWNrZ3JvdW5kQ29sb3VyVXBkYXRlKCkge1xuICAgICAgICBjb25zdCBjb2xvdXJzID0gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJQYWxldHRlID8gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJQYWxldHRlLmNvbG91cnMgOiBbXG4gICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvckZyb20gfHwgJ2JsYWNrJyxcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yVG8gfHwgJ2JsYWNrJ1xuICAgICAgICBdO1xuXG4gICAgICAgIGlmICh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmNvbG91ck1vZGUgIT09ICdyZXBlYXQnKSB7XG4gICAgICAgICAgICBjb25zdCBjaHJvbWFTY2FsZSA9IGNocm9tYS5zY2FsZShjb2xvdXJzKTtcbiAgICAgICAgICAgIGNocm9tYVNjYWxlLm1vZGUodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJNb2RlKTtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yID0gY2hyb21hU2NhbGUuY29sb3JzKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUubGFiZWxzLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlcGVhdENvbG91cnMoY29sb3Vycyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0Q2hhcnREYXRhKCk7XG4gICAgICAgIH0sIDUwKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdXBkYXRlSW5zdGFuY2VGaWx0ZXJGaWVsZHMoY2hhbmdlLCBpbnN0YW5jZUtleSkge1xuICAgICAgICBpZiAoY2hhbmdlLnR5cGUgPT09ICdNQVRDSCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlID0gXy5maW5kKHRoaXMuZGFzaGJvYXJkLmRhdGFzZXRJbnN0YW5jZXMsIHtpbnN0YW5jZUtleX0pO1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkRGF0YXNldEluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWFwcGVkUGFyYW1zID0ge307XG4gICAgICAgICAgICAgICAgXy5mb3JFYWNoKHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLnBhcmFtZXRlclZhbHVlcywgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNTdHJpbmcodmFsdWUpICYmIHZhbHVlLmluY2x1ZGVzKCd7eycpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnbG9iYWxLZXkgPSB2YWx1ZS5yZXBsYWNlKCd7eycsICcnKS5yZXBsYWNlKCd9fScsICcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzICYmIHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnNbZ2xvYmFsS2V5XSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBlZFBhcmFtc1trZXldID0gdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVyc1tnbG9iYWxLZXldLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGVkUGFyYW1zW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YXNldEluc3RhbmNlU3VtbWFyeSA9IHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YXNldEluc3RhbmNlSWQ6IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLmRhdGFzZXRJbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXM6IHNlbGVjdGVkRGF0YXNldEluc3RhbmNlLnRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzLFxuICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IG1hcHBlZFBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyczogc2VsZWN0ZWREYXRhc2V0SW5zdGFuY2UucGFyYW1ldGVyc1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzZXQgPSBhd2FpdCB0aGlzLmRhdGFzZXRTZXJ2aWNlLmV2YWx1YXRlRGF0YXNldChkYXRhc2V0SW5zdGFuY2VTdW1tYXJ5LCAnMCcsICcxMCcpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXNbaW5zdGFuY2VLZXldLmZpbHRlckZpZWxkcyA9IF8ubWFwKHRoaXMuZGF0YXNldC5jb2x1bW5zLCBjb2x1bW4gPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGNvbHVtbi50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGNvbHVtbi5uYW1lXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzYXZlRGFzaGJvYXJkKCkge1xuICAgICAgICBjb25zdCBncmlkID0gdGhpcy5ncmlkLnNhdmUodHJ1ZSk7XG4gICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ3JpZCA9IGdyaWQ7XG5cbiAgICAgICAgaWYgKCF0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5jaGFydHMpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLmNoYXJ0cyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuY2hhcnRzW3RoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmluc3RhbmNlS2V5XSA9IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGU7XG5cbiAgICAgICAgdGhpcy5tYXBDb21wb25lbnREYXRhVG9EYXNoYm9hcmRJbnN0YW5jZSgpO1xuXG4gICAgICAgIGlmICghdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zIHx8IEFycmF5LmlzQXJyYXkodGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zKSkge1xuICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zID0ge307XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFzZXROb2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgaWYgKG5vZGUub3B0aW9ucyAmJiBub2RlLm9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zW25vZGUuaWRdID0gbm9kZS5vcHRpb25zO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXRoaXMubmV0d29ya0RhdGEuZWRnZUxldmVsT3B0aW9ucyB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLm5ldHdvcmtEYXRhLmVkZ2VMZXZlbE9wdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLm5ldHdvcmtEYXRhLmVkZ2VMZXZlbE9wdGlvbnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YXNldEVkZ2VzLmZvckVhY2goZWRnZSA9PiB7XG4gICAgICAgICAgICBpZiAoZWRnZS5vcHRpb25zICYmIGVkZ2Uub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5ldHdvcmtEYXRhLmVkZ2VMZXZlbE9wdGlvbnMucHVzaChlZGdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgYW4gb2xkIGluc3RhbmNlIHJlbW92ZSBpdCwgYW5kIHRoZW4gYWRkIHRoZSBuZXcvdXBkYXRlZCBvbmUuXG4gICAgICAgIF8ucmVtb3ZlKHRoaXMuZGFzaGJvYXJkLmRhdGFzZXRJbnN0YW5jZXMsIHtpbnN0YW5jZUtleTogdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuaW5zdGFuY2VLZXl9KTtcbiAgICAgICAgXy5yZW1vdmUodGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UudHJhbnNmb3JtYXRpb25JbnN0YW5jZXMsIHt0eXBlOiAncGFnaW5nJ30pO1xuICAgICAgICB0aGlzLmRhc2hib2FyZC5kYXRhc2V0SW5zdGFuY2VzLnB1c2godGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UpO1xuXG4gICAgICAgIHRoaXMuZGlhbG9nUmVmLmNsb3NlKHRoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVzZXREZWZhdWx0Q29sb3VycygpIHtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5iYWNrZ3JvdW5kQ29sb3JGcm9tID0gbnVsbDtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5iYWNrZ3JvdW5kQ29sb3JUbyA9IG51bGw7XG4gICAgICAgIHRoaXMuc2V0Q2hhcnREYXRhKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUNvbG91clBhbGV0dGUoKSB7XG4gICAgICAgIGlmICh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmNvbG91clBhbGV0dGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuY29sb3VyTW9kZSA9ICdyZXBlYXQnO1xuICAgICAgICAgICAgdGhpcy5yZXBlYXRDb2xvdXJzKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuY29sb3VyUGFsZXR0ZS5jb2xvdXJzKTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q2hhcnREYXRhKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJhY2tncm91bmRDb2xvdXJVcGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRDaGFydERhdGEoKSB7XG4gICAgICAgIGlmICh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzICYmIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUueUF4aXMpIHtcbiAgICAgICAgICAgIGxldCBkYXRhOiBhbnk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5zZXJpZXNDb2x1bW4pIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlICE9PSAncGllJyAmJiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdkb3VnaG51dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IF8ubWFwKHRoaXMuZGF0YXNldC5hbGxEYXRhLCBpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXSwgeTogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXX07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEgPSBfLm1hcCh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFydERhdGEgPSBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogXy5maW5kKHRoaXMuZmlsdGVyRmllbGRzLCB7bmFtZTogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS54QXhpc30pLnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogISF0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmZpbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBib3JkZXJDb2xvcjogKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3BpZScgfHwgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnZG91Z2hudXQnKSA/IGNocm9tYSgnd2hpdGUnKS5hbHBoYSgwLjIpLmhleCgpIDogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ2xpbmUnIHx8IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3NjYXR0ZXInKSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFycmF5LmlzQXJyYXkodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcikgPyBfLm1hcCh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yLCBjb2xvdXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hyb21hKGNvbG91ciB8fCAnYmxhY2snKS5hbHBoYSgwLjUpLmhleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pIDogY2hyb21hKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IgfHwgJ2JsYWNrJykuYWxwaGEoMC41KS5oZXgoKSkgOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbnNpb246IDAuMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50QmFja2dyb3VuZENvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yID8gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvclswXSA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludEJvcmRlckNvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yID8gdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvclswXSA6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5sYWJlbHMgPSBfLm1hcCh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueEF4aXNdO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFydERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBjb25zdCBzZXJpZXMgPSBfLnVuaXEoXy5tYXAodGhpcy5kYXRhc2V0LmFsbERhdGEsIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuc2VyaWVzQ29sdW1uKSk7XG4gICAgICAgICAgICAgICAgc2VyaWVzLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXJpZXNSZXN1bHRzID0gXy5maWx0ZXIodGhpcy5kYXRhc2V0LmFsbERhdGEsIGFsbERhdGEgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsbERhdGFbdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5zZXJpZXNDb2x1bW5dID09PSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY2hhcnREYXRhLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogXy5tYXAoc2VyaWVzUmVzdWx0cywgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt4OiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueEF4aXNdLCB5OiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueUF4aXNdfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogISF0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmZpbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBib3JkZXJDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ2xpbmUnIHx8IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3NjYXR0ZXInKSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFycmF5LmlzQXJyYXkodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcikgPyBfLm1hcCh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yLCBjb2xvdXIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hyb21hKGNvbG91ciB8fCAnYmxhY2snKS5hbHBoYSgwLjUpLmhleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pIDogY2hyb21hKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IgfHwgJ2JsYWNrJykuYWxwaGEoMC41KS5oZXgoKSkgOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvcltpbmRleF0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW5zaW9uOiAwLjIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludEJhY2tncm91bmRDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvcltpbmRleF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludEJvcmRlckNvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yW2luZGV4XVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYXJ0RGF0YSA9IGNoYXJ0RGF0YTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmxhYmVscyA9IF8udW5pcShfLm1hcCh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUueEF4aXNdO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lICYmXG4gICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50eXBlICE9PSAncGllJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2RvdWdobnV0Jykge1xuXG4gICAgICAgICAgICAgICAgbGV0IHRyZW5kTGluZSA9IFtdO1xuICAgICAgICAgICAgICAgIGxldCB0cmVuZExhYmVsID0gJ1RyZW5kJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmUgPT09ICdhdmVyYWdlJykge1xuICAgICAgICAgICAgICAgICAgICB0cmVuZExhYmVsID0gJ0F2ZXJhZ2UnO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmVuZERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFydERhdGEuZm9yRWFjaChkYXRhSXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmVuZERhdGEucHVzaChfLm1hcChkYXRhSXRlbS5kYXRhLCAneScpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF2ZXJhZ2UgPSBfLmZsYXRNYXAodHJlbmREYXRhKS5yZWR1Y2UoKHAsIGMpID0+IHAgKyBjLCAwKSAvIF8uZmxhdE1hcCh0cmVuZERhdGEpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgdHJlbmRMaW5lID0gXy5maWxsKF8ucmFuZ2UoMCwgXy5mbGF0TWFwKHRyZW5kRGF0YSkubGVuZ3RoKSwgYXZlcmFnZSwgMCwgXy5mbGF0TWFwKHRyZW5kRGF0YSkubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lID09PSAnbG9nYXJpdGhtaWMnIHx8XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lID09PSAnbGluZWFyJyB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZSA9PT0gJ3Bvd2VyJyB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZSA9PT0gJ2V4cG9uZW50aWFsJykge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyZW5kTGluZURhdGEgPSBfLm1hcCh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge3g6IGluZGV4ICsgMSwgeTogaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXX07XG4gICAgICAgICAgICAgICAgICAgIH0pLmZpbHRlcigoe3gsIHl9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB4ID09PSB0eXBlb2YgeSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpc05hTih4KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpc05hTih5KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguYWJzKHgpICE9PSBJbmZpbml0eSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguYWJzKHkpICE9PSBJbmZpbml0eVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSkubWFwKCh7eCwgeX0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbeCwgeV07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyZW5kTGluZVJlc3VsdHMgPSByZWdyZXNzaW9uW3RoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lXSh0cmVuZExpbmVEYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdHJlbmRMaW5lID0gdHJlbmRMaW5lUmVzdWx0cy5wb2ludHMubWFwKChbeCwgeV0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB5O1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0cmVuZExpbmUgPSBfLm1hcCh0aGlzLmRhdGFzZXQuYWxsRGF0YSwgaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbVt0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZV07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB0cmVuZExhYmVsID0gXy5maW5kKHRoaXMuZmlsdGVyRmllbGRzLCB7bmFtZTogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmV9KS50aXRsZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNoYXJ0RGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiB0cmVuZExpbmUsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiB0cmVuZExhYmVsLFxuICAgICAgICAgICAgICAgICAgICBib3JkZXJDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmVDb2xvdXIsXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvcmRlcjogLTEsXG4gICAgICAgICAgICAgICAgICAgIHRlbnNpb246IDAuMTUsXG4gICAgICAgICAgICAgICAgICAgIHBvaW50QmFja2dyb3VuZENvbG9yOiB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZUNvbG91cixcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRCb3JkZXJDb2xvcjogdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmVDb2xvdXJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVNZXRyaWNEYXRhVmFsdWVzKCkge1xuICAgICAgICBpZiAodGhpcy5tZXRyaWMubWFpbikge1xuICAgICAgICAgICAgdGhpcy5tZXRyaWMubWFpblZhbHVlID0gXy5pc05hTihOdW1iZXIodGhpcy5kYXRhc2V0LmFsbERhdGFbMF1bdGhpcy5tZXRyaWMubWFpbl0pKSA/IHRoaXMuZGF0YXNldC5hbGxEYXRhWzBdW3RoaXMubWV0cmljLm1haW5dIDogTnVtYmVyKHRoaXMuZGF0YXNldC5hbGxEYXRhWzBdW3RoaXMubWV0cmljLm1haW5dKTtcbiAgICAgICAgICAgIHRoaXMubWV0cmljLnRpdGxlID0gXy5zdGFydENhc2UodGhpcy5tZXRyaWMubWFpbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5tZXRyaWMuc3ViTWV0cmljKSB7XG4gICAgICAgICAgICB0aGlzLm1ldHJpYy5zdWJWYWx1ZSA9IE51bWJlcih0aGlzLmRhdGFzZXQuYWxsRGF0YVswXVt0aGlzLm1ldHJpYy5zdWJNZXRyaWNdKTtcbiAgICAgICAgICAgIHRoaXMubWV0cmljLnN1YlRpdGxlID0gXy5zdGFydENhc2UodGhpcy5tZXRyaWMuc3ViTWV0cmljKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm1ldHJpYy5zaG93U3ViQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLm1ldHJpYy5kaWZmZXJlbmNlID0gTWF0aC5hYnModGhpcy5tZXRyaWMubWFpblZhbHVlIC0gdGhpcy5tZXRyaWMuc3ViVmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtYXBMYXlvdXRTZXR0aW5nc1RvQ29tcG9uZW50RGF0YSgpIHtcbiAgICAgICAgXy5mb3JFYWNoKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLCAoZGF0YSwga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoa2V5ICE9PSAnZ3JpZCcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBfLmlzUGxhaW5PYmplY3QodGhpc1trZXldKSA/IHt9IDogW107XG4gICAgICAgICAgICAgICAgdGhpc1trZXldID0gT2JqZWN0LmtleXMoZGF0YSkubGVuZ3RoID9cbiAgICAgICAgICAgICAgICAgICAgKGRhdGFbdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuaW5zdGFuY2VLZXldICYmIE9iamVjdC5rZXlzKGRhdGFbdGhpcy5kYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuaW5zdGFuY2VLZXldKS5sZW5ndGggP1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVt0aGlzLmRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5pbnN0YW5jZUtleV0gOiBkZWZhdWx0VmFsdWUpIDogZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1hcENvbXBvbmVudERhdGFUb0Rhc2hib2FyZEluc3RhbmNlKCkge1xuICAgICAgICBjb25zdCBsYXlvdXRTZXR0aW5ncyA9IFsnbWV0cmljJywgJ2RlcGVuZGVuY2llcycsICd0YWJ1bGFyJywgJ3RhYmxlQ2VsbHMnLCAnZ2VuZXJhbCcsICdpbWFnZURhdGEnLCAndGV4dERhdGEnLCAnY2FsbFRvQWN0aW9uJywgJ3dvcmRDbG91ZCcsICdhY3Rpb25JdGVtJywgJ25ldHdvcmtEYXRhJ107XG4gICAgICAgIGxheW91dFNldHRpbmdzLmZvckVhY2goc2V0dGluZyA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzW3NldHRpbmddKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3Nbc2V0dGluZ10gPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHREYXRhID0gXy5pc1BsYWluT2JqZWN0KHRoaXNbc2V0dGluZ10pID8ge30gOiBbXTtcbiAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzW3NldHRpbmddW3RoaXMuZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmluc3RhbmNlS2V5XSA9IHRoaXNbc2V0dGluZ10gfHwgZGVmYXVsdERhdGE7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVwZWF0Q29sb3Vycyhjb2xvdXJzOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvciA9IFtdO1xuICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJvcmRlckNvbG9yID0gW107XG4gICAgICAgIHdoaWxlICh0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvci5sZW5ndGggPCB0aGlzLmRhdGFzZXQuYWxsRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY29sb3VyIG9mIGNvbG91cnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvci5wdXNoKGNvbG91cik7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yLmxlbmd0aCA9PT0gdGhpcy5kYXRhc2V0LmFsbERhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhTGVuZ3RoID0gKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ2xpbmUnIHx8IHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3NjYXR0ZXInKSA/IHRoaXMuY2hhcnREYXRhLmxlbmd0aCA6IHRoaXMuZGF0YXNldC5hbGxEYXRhO1xuICAgICAgICB3aGlsZSAodGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvci5sZW5ndGggPCBkYXRhTGVuZ3RoKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbG91ciBvZiBjb2xvdXJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXNoYm9hcmRJdGVtVHlwZS5ib3JkZXJDb2xvci5wdXNoKGNvbG91cik7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3IubGVuZ3RoID09PSBkYXRhTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZERhc2hib2FyZEl0ZW1zKCkge1xuICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MpIHtcbiAgICAgICAgICAgIHRoaXMubWFwTGF5b3V0U2V0dGluZ3NUb0NvbXBvbmVudERhdGEoKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmdlbmVyYWwucGFyYW1ldGVyQmFyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsLnBhcmFtZXRlckJhciA9IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgIHRoaXMuZGFzaGJvYXJkUGFyYW1WYWx1ZXMgPSBfKHRoaXMuZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMpXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoJ3ZhbHVlJylcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgndmFsdWUnKVxuICAgICAgICAgICAgICAgICAgICAudmFsdWVPZigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLndpZGdldFBhcmFtZXRlcnMgPSBfLmNsb25lRGVlcCh0aGlzLmRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmdlbmVyYWwud2lkZ2V0UGFyYW1ldGVycyAmJiBPYmplY3Qua2V5cyh0aGlzLmdlbmVyYWwud2lkZ2V0UGFyYW1ldGVycykubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMuZ2VuZXJhbC53aWRnZXRQYXJhbWV0ZXJzLCB3aWRnZXRQYXJhbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aWRnZXRQYXJhbS52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53aWRnZXRQYXJhbWV0ZXJzW3dpZGdldFBhcmFtLm5hbWVdLnZhbHVlID0gd2lkZ2V0UGFyYW0udmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWF0Y2hEZXBlbmRlbmNpZXMgPSBfLmZpbHRlcih0aGlzLmRlcGVuZGVuY2llcywgKGRlcCwga2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGRlcC50eXBlID09PSAnTUFUQ0gnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlcC5rZXkgPSBrZXk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1hdGNoRGVwZW5kZW5jaWVzLmZvckVhY2goZGVwID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUluc3RhbmNlRmlsdGVyRmllbGRzKGRlcCwgZGVwLmtleSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKHRoaXMudGFidWxhci5jdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN0YVVwZGF0ZSh0aGlzLnRhYnVsYXIuY3RhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXROZXR3b3JrQ2hhcnREYXRhKHJlbG9hZCA9IGZhbHNlKSB7XG4gICAgICAgIGlmICghcmVsb2FkICYmIHRoaXMubmV0d29ya0RhdGEuZWRnZURhdGFzZXRUaXRsZSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkRWRnZURhdGFzZXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vZGVEYXRhID0gdGhpcy5kYXRhc2V0LmFsbERhdGE7XG5cbiAgICAgICAgdGhpcy5kYXRhc2V0Tm9kZXMgPSBbXTtcbiAgICAgICAgdGhpcy5kYXRhc2V0RWRnZXMgPSBbXTtcblxuICAgICAgICBub2RlRGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgbGV0IG5vZGVPcHRpb25zOiBhbnkgPSBbXTtcbiAgICAgICAgICAgIGlmICh0aGlzLm5ldHdvcmtEYXRhLm5vZGVMZXZlbE9wdGlvbnMgJiYgT2JqZWN0LmtleXModGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zKS5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICB0aGlzLm5ldHdvcmtEYXRhLm5vZGVMZXZlbE9wdGlvbnNbaXRlbVt0aGlzLm5ldHdvcmtEYXRhLm5vZGVJZHNdXSkge1xuICAgICAgICAgICAgICAgIG5vZGVPcHRpb25zID0gdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGV2ZWxPcHRpb25zW2l0ZW1bdGhpcy5uZXR3b3JrRGF0YS5ub2RlSWRzXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZGF0YXNldE5vZGVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlkOiBpdGVtW3RoaXMubmV0d29ya0RhdGEubm9kZUlkc10sXG4gICAgICAgICAgICAgICAgbGFiZWw6IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS5ub2RlTGFiZWxzXSxcbiAgICAgICAgICAgICAgICBncm91cDogaXRlbVt0aGlzLm5ldHdvcmtEYXRhLm5vZGVHcm91cHNdLFxuICAgICAgICAgICAgICAgIG9wdGlvbnM6IG5vZGVPcHRpb25zXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghdGhpcy5uZXR3b3JrRGF0YS5lZGdlRGF0YXNldFRpdGxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc2V0RWRnZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGZyb206IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS5mcm9tSWRzXSxcbiAgICAgICAgICAgICAgICAgICAgdG86IGl0ZW1bdGhpcy5uZXR3b3JrRGF0YS50b0lkc10sXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IFtdXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLm5ldHdvcmtEYXRhLmVkZ2VEYXRhc2V0VGl0bGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFzZXRJbnN0YW5jZVN1bW1hcnkgPSB7XG4gICAgICAgICAgICAgICAgZGF0YXNldEluc3RhbmNlSWQ6IHRoaXMubmV0d29ya0RhdGEuZWRnZURhdGFzZXRJZCxcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMubmV0d29ya0RhdGEuZWRnZURhdGFzb3VyY2VLZXksXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXM6IFtdLFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlclZhbHVlczoge30sXG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyczoge31cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuZnVsbEVkZ2VEYXRhc2V0ID0gYXdhaXQgdGhpcy5kYXRhc2V0U2VydmljZS5ldmFsdWF0ZURhdGFzZXQoXG4gICAgICAgICAgICAgICAgZGF0YXNldEluc3RhbmNlU3VtbWFyeSxcbiAgICAgICAgICAgICAgICAnMCcsXG4gICAgICAgICAgICAgICAgJzEwMDAwMDAwJ1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgdGhpcy5mdWxsRWRnZURhdGFzZXQuYWxsRGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNldEVkZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiBpdGVtW3RoaXMubmV0d29ya0RhdGEuZnJvbUlkc10sXG4gICAgICAgICAgICAgICAgICAgIHRvOiBpdGVtW3RoaXMubmV0d29ya0RhdGEudG9JZHNdLFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBbXVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm5vZGVHcm91cHMgPSBfKHRoaXMuZGF0YXNldE5vZGVzKVxuICAgICAgICAgICAgLmZpbHRlcignZ3JvdXAnKVxuICAgICAgICAgICAgLm1hcCgnZ3JvdXAnKVxuICAgICAgICAgICAgLnVuaXEoKVxuICAgICAgICAgICAgLnZhbHVlT2YoKTtcblxuICAgICAgICB0aGlzLmRhdGFzZXRFZGdlcy5mb3JFYWNoKGVkZ2UgPT4ge1xuICAgICAgICAgICAgY29uc3QgZWRnZU9wdGlvbnMgPSBfLmZpbmQodGhpcy5uZXR3b3JrRGF0YS5lZGdlTGV2ZWxPcHRpb25zLCB7ZnJvbTogZWRnZS5mcm9tLCB0bzogZWRnZS50b30pO1xuICAgICAgICAgICAgaWYgKGVkZ2VPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgZWRnZS5vcHRpb25zID0gZWRnZU9wdGlvbnMub3B0aW9ucztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInBvaW50ZXItZXZlbnRzLW5vbmUgZml4ZWQgaW5zZXQteS0wIHJpZ2h0LTAgZmxleCBtYXgtdy1mdWxsIHBsLTEwIC16LTEwXCIgaWQ9XCJzaWRlYmFyV3JhcHBlcjJcIj5cbiAgICA8ZGl2IFtuZ0NsYXNzXT1cInsndHJhbnNsYXRlLXgtMCc6IHNpZGVPcGVuLCAndHJhbnNsYXRlLXgtZnVsbCc6ICFzaWRlT3Blbn1cIlxuICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICBjbGFzcz1cInBvaW50ZXItZXZlbnRzLWF1dG8gdy1zY3JlZW4gbWF4LXctbWQgdHJhbnNmb3JtIHRyYW5zaXRpb24gZWFzZS1pbi1vdXQgZHVyYXRpb24tNTAwIHNtOmR1cmF0aW9uLTcwMFwiXG4gICAgICAgICBpZD1cImRvY1NpZGViYXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaC1mdWxsIGZsZXgtY29sIG92ZXJmbG93LXktc2Nyb2xsIGJnLXdoaXRlIHB5LTYgc2hhZG93LXhsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNCBzbTpweC02XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zIGZsZXggaC03IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9wZW5TaWRlLm5leHQoZmFsc2UpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyb3VuZGVkLW1kIGJnLXdoaXRlIHRleHQtZ3JheS00MDAgaG92ZXI6dGV4dC1ncmF5LTUwMCBmb2N1czpvdXRsaW5lLW5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyLW9ubHlcIj5DbG9zZSBwYW5lbDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEhlcm9pY29uIG5hbWU6IG91dGxpbmUveCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiaC02IHctNlwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBmaWxsPVwibm9uZVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIHN0cm9rZS13aWR0aD1cIjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTYgMThMMTggNk02IDZsMTIgMTJcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBmbGV4LTEgcHgtNCBzbTpweC02XCI+XG4gICAgICAgICAgICAgICAgPGtpLWh0bWwtZG9jdW1lbnRhdGlvbiBbY29sdW1uc109XCJkb2NDb2x1bW5zXCI+PC9raS1odG1sLWRvY3VtZW50YXRpb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPGRpdiBjbGFzcz1cImNvbmZpZ3VyZS1oZWFkZXJcIj5cbiAgICBDb25maWd1cmUge3tkYXNoYm9hcmRJdGVtVHlwZS5sYWJlbH19XG4gICAgPGJ1dHRvbiBtYXQtYnV0dG9uIChjbGljayk9XCJzYXZlRGFzaGJvYXJkKClcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xXCI+Y2hldnJvbl9sZWZ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIEJhY2sgdG8gRGFzaGJvYXJkXG4gICAgICAgIDwvZGl2PlxuICAgIDwvYnV0dG9uPlxuPC9kaXY+XG48bmF2IGNsYXNzPVwiaC0xMCBmbGV4IGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMCBiZy13aGl0ZVwiIGFyaWEtbGFiZWw9XCJCcmVhZGNydW1iXCI+XG4gICAgPG9sIHJvbGU9XCJsaXN0XCIgY2xhc3M9XCJmbGV4IHctZnVsbCBweC00XCI+XG4gICAgICAgIDxsaSBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxhIG1hdC1kaWFsb2ctY2xvc2UgW3JvdXRlckxpbmtdPVwiWycvJ11cIiBjbGFzcz1cInRleHQtZ3JheS02MDAgaG92ZXI6dGV4dC1ncmF5LTgwMCBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj5ob21lPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2xpPlxuXG4gICAgICAgIDxsaSBjbGFzcz1cImZsZXggdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJoLWZ1bGwgdy02IGZsZXgtc2hyaW5rLTAgdGV4dC1ncmF5LTIwMFwiIHZpZXdCb3g9XCIwIDAgMjQgNDRcIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTS4yOTMgMGwyMiAyMi0yMiAyMmgxLjQxNGwyMi0yMi0yMi0yMkguMjkzelwiLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8YSBtYXQtZGlhbG9nLWNsb3NlIFtyb3V0ZXJMaW5rXT1cIlsnL2Rhc2hib2FyZHMnXVwiXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXBpdGFsaXplIG1sLTQgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwIGhvdmVyOnRleHQtZ3JheS03MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgRGFzaGJvYXJkczwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2xpPlxuXG4gICAgICAgIDxsaSBjbGFzcz1cImZsZXggdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJoLWZ1bGwgdy02IGZsZXgtc2hyaW5rLTAgdGV4dC1ncmF5LTIwMFwiIHZpZXdCb3g9XCIwIDAgMjQgNDRcIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTS4yOTMgMGwyMiAyMi0yMiAyMmgxLjQxNGwyMi0yMi0yMi0yMkguMjkzelwiLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwic2F2ZURhc2hib2FyZCgpXCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhcGl0YWxpemUgbWwtNCB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDAgaG92ZXI6dGV4dC1ncmF5LTcwMFwiPlxuICAgICAgICAgICAgICAgICAgICBEYXNoYm9hcmQgRWRpdG9yPC9hPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpIGNsYXNzPVwiZmxleFwiICpuZ0lmPVwiZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiaC1mdWxsIHctNiBmbGV4LXNocmluay0wIHRleHQtZ3JheS0yMDBcIiB2aWV3Qm94PVwiMCAwIDI0IDQ0XCIgcHJlc2VydmVBc3BlY3RSYXRpbz1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0uMjkzIDBsMjIgMjItMjIgMjJoMS40MTRsMjItMjItMjItMjJILjI5M3pcIi8+XG4gICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC00IHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMCBob3Zlcjp0ZXh0LWdyYXktNzAwXCIgYXJpYS1jdXJyZW50PVwicGFnZVwiPlxuICAgICAgICAgICAgICAgICAgICB7e2Rhc2hib2FyZEl0ZW1UeXBlLmxhYmVsfX0gRWRpdG9yXG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UgJiYgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnNvdXJjZVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHRleHQteHMgcHgtMiBweS0wIHJvdW5kZWQteGwgbWwtMiBmb250LXRoaW4gYmctZ3JheS0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ1cHBlcmNhc2UgdHJhY2tpbmctd2lkZXIgdGV4dC1ncmF5LTcwMCBmb250LW1lZGl1bVwiPlF1ZXJ5aW5nOjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5zb3VyY2UuZGF0YXNvdXJjZUluc3RhbmNlS2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwiWydjdXN0b20nLCAnc25hcHNob3QnXS5pbmRleE9mKGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5zb3VyY2UudHlwZSkgPT09IC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPVwiL2Fzc2V0cy9mYXZpY29uLXJldi5wbmdcIiBjbGFzcz1cInctMi41IG14LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2Uuc291cmNlLnR5cGUgPT09ICdjdXN0b20nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgaC00IHctNCB0ZXh0LWxnIGxlYWRpbmctNCBteC0xLjVcIj51cGxvYWRfZmlsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLnNvdXJjZS50eXBlID09PSAnc25hcHNob3QnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgaC00IHctNCB0ZXh0LWxnIGxlYWRpbmctNCBteC0xLjVcIj5oaXN0b3J5PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5zb3VyY2UuZGF0YXNvdXJjZUluc3RhbmNlS2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgaC00IHctNCB0ZXh0LWxnIGxlYWRpbmctNCBteC0xLjVcIj5xdWVyeV9zdGF0czwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgJm5ic3A7e3tkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2Uuc291cmNlLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkIG1sLTIgY3Vyc29yLXBvaW50ZXJcIiB0aXRsZT1cIkNoYW5nZSBzb3VyY2UgcXVlcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hhbmdlU291cmNlKClcIj5jaGFuZ2VfY2lyY2xlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2xpPlxuICAgIDwvb2w+XG48L25hdj5cbjxkaXYgY2xhc3M9XCJjb25maWd1cmUtY29udGVudFwiPlxuXG4gICAgPHJzei1sYXlvdXQgY2xhc3M9XCJyb3cgdG9wXCIgW2RpcmVjdGlvbnNdPVwiWydib3R0b20nXVwiIFtyRmxleF09XCJ0cnVlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjZWxsLWNvbnRlbnRzIHAtMFwiPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2VcIiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIGgtZnVsbCB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZmxleC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgY2xhc3M9XCJjb25maWctYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0ZWREYXRhc291cmNlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyZSB7e2Rhc2hib2FyZEl0ZW1UeXBlLmxhYmVsfX1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiZm9udC1saWdodCB3LTMvNCB0ZXh0LWNlbnRlciBtdC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBQbGVhc2UgY29uZmlndXJlIHRoaXMge3tkYXNoYm9hcmRJdGVtVHlwZS5sYWJlbH19IHVzaW5nIGEgZGF0YSBmZWVkIG9yIHN0b3JlZCBxdWVyeS5cbiAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxraS1kYXRhc2V0LWVkaXRvciAjZGF0YXNldEVkaXRvckNvbXBvbmVudCAqbmdJZj1cImRhc2hib2FyZERhdGFzZXRJbnN0YW5jZVwiIFsoZGF0YXNldEluc3RhbmNlU3VtbWFyeSldPVwiZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGF0YUxvYWRlZCk9XCJkYXRhTG9hZGVkKCRldmVudClcIiBbYWRtaW5dPVwiYWRtaW5cIiBbZGFzaGJvYXJkTGF5b3V0U2V0dGluZ3NdPVwiZ2VuZXJhbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rhc2hib2FyZFBhcmFtZXRlcnNdPVwid2lkZ2V0UGFyYW1ldGVyc1wiPjwva2ktZGF0YXNldC1lZGl0b3I+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvcnN6LWxheW91dD5cblxuICAgIDxyc3otbGF5b3V0IGNsYXNzPVwicm93IGJvdHRvbVwiIFtkaXJlY3Rpb25zXT1cIlsnbm9uZSddXCIgW3JGbGV4XT1cImZhbHNlXCI+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwIGNsYXNzPVwiZ3JheS1oZWFkZXIgaC1mdWxsXCI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkhlYWRlciBTZXR0aW5nczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRlciBIVE1ML1RleHQgZm9yIHRoZSBUaXRsZSBhbmQgRGVzY3JpcHRpb24gZmllbGRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wtcmV2ZXJzZSBqdXN0aWZ5LXN0cmV0Y2hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwib3BlblNpZGUubmV4dCh0cnVlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXhzIG1sLTIgaG92ZXI6dW5kZXJsaW5lIGZsZXggaXRlbXMtY2VudGVyIHByaW1hcnkgdGV4dC1jdGFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlldyBoZWxwIGRvY3MmbmJzcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgY2xhc3M9XCJoLTQgdy00XCIgdmlld0JveD1cIjAgMCAyMCAyMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTExIDNhMSAxIDAgMTAwIDJoMi41ODZsLTYuMjkzIDYuMjkzYTEgMSAwIDEwMS40MTQgMS40MTRMMTUgNi40MTRWOWExIDEgMCAxMDIgMFY0YTEgMSAwIDAwLTEtMWgtNXpcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNSA1YTIgMiAwIDAwLTIgMnY4YTIgMiAwIDAwMiAyaDhhMiAyIDAgMDAyLTJ2LTNhMSAxIDAgMTAtMiAwdjNINVY3aDNhMSAxIDAgMDAwLTJINXpcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaXRsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cImdlbmVyYWwubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPlRpdGxlIG9mIHRoZSBpdGVtPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9udC1tb25vIHctZnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzPVwiMzBcIiByb3dzPVwiNVwiIFsobmdNb2RlbCldPVwiZ2VuZXJhbC5kZXNjcmlwdGlvblwiPjwvdGV4dGFyZWE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cImZvbnQtbm9ybWFsXCI+RGVzY3JpcHRpb24gb2YgdGhlIGRhdGEgaXRlbS48L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtci0yXCIgWyhuZ01vZGVsKV09XCJnZW5lcmFsLnRyYW5zcGFyZW50XCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMCBtdC0xXCI+VHJhbnNwYXJlbnQgYmFja2dyb3VuZDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJtYi00IGJsb2NrIGZvbnQtbm9ybWFsXCI+TWFrZSB0aGlzIGRhc2hib2FyZCBpdGVtcyBiYWNrZ3JvdW5kIHRyYW5zcGFyZW50IC1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZXMgcGFnZSByZWZyZXNoIHRvIHRha2UgYWZmZWN0PC9zbWFsbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MgJiYgZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMgJiYgT2JqZWN0LmtleXMoZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLnBhcmFtZXRlcnMpLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtci0yXCIgWyhuZ01vZGVsKV09XCJnZW5lcmFsLnNob3dQYXJhbWV0ZXJCYXJcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMCBtdC0xXCI+U2hvdyBQYXJhbWV0ZXIgQmFyPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwibWItNCBibG9jayBmb250LW5vcm1hbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5hYmxlIHdoaWNoIHBhcmFtZXRlcnMgdG8gc2hvdyBpbiB0aGlzIHdpZGdldC4gVmFsdWVzIGVudGVyZWQgaGVyZSB3aWxsIG9ubHkgcmVsb2FkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHdpZGdldC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zbWFsbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZ2VuZXJhbC5zaG93UGFyYW1ldGVyQmFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWwtMiBwbC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcGFyYW1ldGVyS2V5IG9mIE9iamVjdC5rZXlzKGRhc2hib2FyZC5sYXlvdXRTZXR0aW5ncy5wYXJhbWV0ZXJzKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtci0yXCIgWyhuZ01vZGVsKV09XCJnZW5lcmFsLnBhcmFtZXRlckJhcltwYXJhbWV0ZXJLZXldXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMCBtdC0xXCI+e3tkYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MucGFyYW1ldGVyc1twYXJhbWV0ZXJLZXldLnRpdGxlfX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkZvb3RlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkZvb3RlciBTZXR0aW5nczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRlciBIVE1ML1RleHQgZm9yIHRoZSBmb290ZXIgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbC1yZXZlcnNlIGp1c3RpZnktc3RyZXRjaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJvcGVuU2lkZS5uZXh0KHRydWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQteHMgbWwtMiBob3Zlcjp1bmRlcmxpbmUgZmxleCBpdGVtcy1jZW50ZXIgcHJpbWFyeSB0ZXh0LWN0YVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3IGhlbHAgZG9jcyZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBjbGFzcz1cImgtNCB3LTRcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTEgM2ExIDEgMCAxMDAgMmgyLjU4NmwtNi4yOTMgNi4yOTNhMSAxIDAgMTAxLjQxNCAxLjQxNEwxNSA2LjQxNFY5YTEgMSAwIDEwMiAwVjRhMSAxIDAgMDAtMS0xaC01elwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk01IDVhMiAyIDAgMDAtMiAydjhhMiAyIDAgMDAyIDJoOGEyIDIgMCAwMDItMnYtM2ExIDEgMCAxMC0yIDB2M0g1VjdoM2ExIDEgMCAwMDAtMkg1elwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTEvMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9vdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJnZW5lcmFsLmZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cImZvbnQtbm9ybWFsXCI+VGV4dCB0byBkaXNwbGF5IGF0IHRoZSBib3R0b20gb2YgdGhlIGl0ZW08L3NtYWxsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbGwgdG8gYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwiY2FsbFRvQWN0aW9uXCIgW2NvbXBhcmVXaXRoXT1cInNldENhbGxUb0FjdGlvbkl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY3RhVXBkYXRlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPk5vbmU8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCJ7dHlwZTogJ2N1c3RvbSd9XCI+Q3VzdG9tIExpbms8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGdyb3VwIGxhYmVsPVwiRGFzaGJvYXJkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgZGFzaGJvYXJkIG9mIGRhc2hib2FyZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdWYWx1ZV09XCJ7dHlwZTogJ2Rhc2hib2FyZCcsIHZhbHVlOiBkYXNoYm9hcmQuaWQsIGxhYmVsOiBkYXNoYm9hcmQudGl0bGV9XCI+e3tkYXNoYm9hcmQudGl0bGV9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGdyb3VwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0Z3JvdXAgKm5nSWY9XCJhZG1pblwiIGxhYmVsPVwiREFQIERhdGEgRmVlZHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGRhcEZlZWQgb2YgZGFwRmVlZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdWYWx1ZV09XCJ7dHlwZTogJ2ZlZWQnLCB2YWx1ZTogZGFwRmVlZC5pZCwgbGFiZWw6IGRhcEZlZWQudGl0bGV9XCI+e3tkYXBGZWVkLnRpdGxlfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRncm91cD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPlNlbGVjdCB0aGUgZGVzdGluYXRpb24gZm9yIHRoZSBhY3Rpb24gbGluazwvc21hbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNhbGxUb0FjdGlvbi50eXBlID09PSAnY3VzdG9tJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBlbnRlciB0aGUgbGluayBmb3IgdGhpcyBjYWxsIHRvIGFjdGlvbi48L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpbmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJjYWxsVG9BY3Rpb24ubGlua1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQgYWN0aW9uIGxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJjYWxsVG9BY3Rpb24ubGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJjYWxsVG9BY3Rpb24gJiYgY2FsbFRvQWN0aW9uLnBhcmFtZXRlcnMgJiYgZGFzaGJvYXJkUGFyYW1ldGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD5QbGVhc2UgZW50ZXIgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIHRvIHVzZSB3aXRoIHRoaXMgZGFzaGJvYXJkPC9wPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1wYXJhbSBbbmdGb3JPZl09XCJkYXNoYm9hcmRQYXJhbWV0ZXJzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD57e3BhcmFtLnRpdGxlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgKm5nSWY9XCIhY2FsbFRvQWN0aW9uLnBhcmFtZXRlcnNbJ2N1c3RvbS0nK3BhcmFtLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWItMiBkYXNoYm9hcmQtcGFyYW0tcGlja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwiY2FsbFRvQWN0aW9uLnBhcmFtZXRlcnNbcGFyYW0ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29tcGFyZVdpdGhdPVwiY3RhU2VsZWN0T3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+LS0gU2VsZWN0IFZhbHVlIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgcGFyYW1WYWx1ZSBvZiBkYXNoYm9hcmRQYXJhbVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGFyYW1WYWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BhcmFtVmFsdWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0yIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwibXItMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY2FsbFRvQWN0aW9uLnBhcmFtZXRlcnNbJ2N1c3RvbS0nK3BhcmFtLm5hbWVdXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTAgbXQtMVwiPlVzZSBjdXN0b20gdmFsdWU8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yIGRhc2hib2FyZC1wYXJhbS1waWNrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAqbmdJZj1cImNhbGxUb0FjdGlvbi5wYXJhbWV0ZXJzWydjdXN0b20tJytwYXJhbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciBjdXN0b20gcGFyYW1ldGVyIHZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNhbGxUb0FjdGlvbi5wYXJhbWV0ZXJzW3BhcmFtLm5hbWVdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJEZXBlbmRlbmNpZXNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNiBweS0zIGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQ6ZmxleCBtZDppdGVtcy1jZW50ZXIgbWQ6anVzdGlmeS1iZXR3ZWVuIG1kOnNwYWNlLXgtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwIG1iLTBcIj5EZXBlbmRlbmN5IFNldHRpbmdzPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRoZSBsb2FkaW5nIG9mIHRoaXMgd2lkZ2V0IGlzIGRlcGVuZGFudCBvbiB0aGUgcmVzdWx0cyBvZiBhbm90aGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeW91IGNhbiBzZXQgdGhlIGRlcGVuZGVuY3kgaGVyZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xLzJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdCB0aGUgZGFzaGJvYXJkIGl0ZW0ocykgdGhpcyBkZXBlbmRzIG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwiZGVwZW5kZW5jaWVzLmluc3RhbmNlS2V5c1wiIG11bHRpcGxlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGluc3RhbmNlIG9mIGRhc2hib2FyZC5kYXRhc2V0SW5zdGFuY2VzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJpbnN0YW5jZS5pbnN0YW5jZUtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLmdlbmVyYWwgPyAoZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLmdlbmVyYWxbaW5zdGFuY2UuaW5zdGFuY2VLZXldID8gZGFzaGJvYXJkLmxheW91dFNldHRpbmdzLmdlbmVyYWxbaW5zdGFuY2UuaW5zdGFuY2VLZXldLm5hbWUgfHwgaW5zdGFuY2UuaW5zdGFuY2VLZXkgOiBpbnN0YW5jZS5pbnN0YW5jZUtleSkgOiBpbnN0YW5jZS5pbnN0YW5jZUtleSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtaW5zdGFuY2VLZXkgW25nRm9yT2ZdPVwiZGVwZW5kZW5jaWVzLmluc3RhbmNlS2V5c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXBlbmRlbmN5IHJlc3VsdCB0eXBlIGZvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tkYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ2VuZXJhbCA/IChkYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ2VuZXJhbFtpbnN0YW5jZUtleV0gPyBkYXNoYm9hcmQubGF5b3V0U2V0dGluZ3MuZ2VuZXJhbFtpbnN0YW5jZUtleV0ubmFtZSB8fCBpbnN0YW5jZUtleSA6IGluc3RhbmNlS2V5KSA6IGluc3RhbmNlS2V5IH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBbKG5nTW9kZWwpXT1cImRlcGVuZGVuY2llc1tpbnN0YW5jZUtleV1cIiBbY29tcGFyZVdpdGhdPVwiZGVwU2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInVwZGF0ZUluc3RhbmNlRmlsdGVyRmllbGRzKCRldmVudCwgaW5zdGFuY2VLZXkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cInt0eXBlOiBudWxsfVwiPi0tIFNlbGVjdCBUeXBlIC0tPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJ7dHlwZTogJ0xPQURFRCd9XCI+TG9hZGVkPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJ7dHlwZTogJ01BVENIJywgZmlsdGVySnVuY3Rpb246IF8uY2xvbmUoZmlsdGVySnVuY3Rpb24pLCBrZXk6IGluc3RhbmNlS2V5fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRjaGVzIENyaXRlcmlhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nSWZdPVwiZGVwZW5kZW5jaWVzW2luc3RhbmNlS2V5XSAmJiBkZXBlbmRlbmNpZXNbaW5zdGFuY2VLZXldLnR5cGUgPT09ICdNQVRDSCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFkZXBlbmRlbmNpZXNbaW5zdGFuY2VLZXldLmZpbHRlckZpZWxkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvYWRpbmcgZmlsdGVyIGNvbXBvbmVudC4uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8a2ktZGF0YXNldC1maWx0ZXJzICpuZ0lmPVwiZGVwZW5kZW5jaWVzW2luc3RhbmNlS2V5XS5maWx0ZXJGaWVsZHNcIiBjbGFzcz1cIm1sLTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVySnVuY3Rpb25dPVwiZGVwZW5kZW5jaWVzW2luc3RhbmNlS2V5XS5maWx0ZXJKdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWx0ZXJGaWVsZHNdPVwiZGVwZW5kZW5jaWVzW2luc3RhbmNlS2V5XS5maWx0ZXJGaWVsZHNcIj48L2tpLWRhdGFzZXQtZmlsdGVycz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBObyBkYXRhIG5vdGljZSBtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwiZGVwZW5kZW5jaWVzLm5vdGljZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPkVudGVyIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiBubyBkYXRhIGlzIHJldHVybmVkIGZyb21cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3kuPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkFjdGlvblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkFjdGlvbiBTZXR0aW5nczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWd1cmUgYXZhaWxhYmxlIGFjdGlvbnMgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoaXMgaXRlbS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTEvMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hdmlnYXRlIHRvIGFub3RoZXIgZGFzaGJvYXJkIG9yIFVSTCBieSBjbGlja2luZyBvbiB0aGlzIHdpZGdldCBpdGVtLlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0aW5hdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cImFjdGlvbkl0ZW1cIiBbY29tcGFyZVdpdGhdPVwic2V0Q2FsbFRvQWN0aW9uSXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjdGFVcGRhdGUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+Tm9uZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cInt0eXBlOiAnY3VzdG9tJ31cIj5DdXN0b20gTGluazwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0Z3JvdXAgbGFiZWw9XCJEYXNoYm9hcmRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBkYXNoYm9hcmQgb2YgZGFzaGJvYXJkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1ZhbHVlXT1cInt0eXBlOiAnZGFzaGJvYXJkJywgdmFsdWU6IGRhc2hib2FyZC5pZCwgbGFiZWw6IGRhc2hib2FyZC50aXRsZX1cIj57e2Rhc2hib2FyZC50aXRsZX19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0Z3JvdXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRncm91cCBsYWJlbD1cIlNoYXJlZCBEYXNoYm9hcmRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBkYXNoYm9hcmQgb2Ygc2hhcmVkRGFzaGJvYXJkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1ZhbHVlXT1cInt0eXBlOiAnZGFzaGJvYXJkJywgdmFsdWU6IGRhc2hib2FyZC5pZCwgbGFiZWw6IGRhc2hib2FyZC50aXRsZX1cIj57e2Rhc2hib2FyZC50aXRsZX19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0Z3JvdXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRncm91cCBsYWJlbD1cIlByaXZhdGUgRGFzaGJvYXJkc1wiICpuZ0lmPVwicHJpdmF0ZURhc2hib2FyZHMubGVuZ3RoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBkYXNoYm9hcmQgb2YgcHJpdmF0ZURhc2hib2FyZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdWYWx1ZV09XCJ7dHlwZTogJ2Rhc2hib2FyZCcsIHZhbHVlOiBkYXNoYm9hcmQuaWQsIGxhYmVsOiBkYXNoYm9hcmQudGl0bGV9XCI+e3tkYXNoYm9hcmQudGl0bGV9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGdyb3VwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cImZvbnQtbm9ybWFsXCI+U2VsZWN0IHRoZSBkZXN0aW5hdGlvbiBmb3IgdGhlIGFjdGlvbiBsaW5rPC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiYWN0aW9uSXRlbS50eXBlID09PSAnY3VzdG9tJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBlbnRlciB0aGUgbGluayBmb3IgdGhpcyBjYWxsIHRvIGFjdGlvbi48L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpbmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJhY3Rpb25JdGVtLmxpbmtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiYWN0aW9uSXRlbSAmJiBhY3Rpb25JdGVtLnBhcmFtZXRlcnMgJiYgZGFzaGJvYXJkUGFyYW1ldGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD5QbGVhc2UgZW50ZXIgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIHRvIHVzZSB3aXRoIHRoaXMgZGFzaGJvYXJkPC9wPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1wYXJhbSBbbmdGb3JPZl09XCJkYXNoYm9hcmRQYXJhbWV0ZXJzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD57e3BhcmFtLnRpdGxlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgKm5nSWY9XCIhYWN0aW9uSXRlbS5wYXJhbWV0ZXJzWydjdXN0b20tJytwYXJhbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1iLTIgZGFzaGJvYXJkLXBhcmFtLXBpY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cImFjdGlvbkl0ZW0ucGFyYW1ldGVyc1twYXJhbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYXJlV2l0aF09XCJjdGFTZWxlY3RPcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ1bmRlZmluZWRcIj4tLSBTZWxlY3QgVmFsdWUgLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiJ1tbJytjb2x1bW4ubmFtZSsnXV0nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtci0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhY3Rpb25JdGVtLnBhcmFtZXRlcnNbJ2N1c3RvbS0nK3BhcmFtLm5hbWVdXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTAgbXQtMVwiPlVzZSBjdXN0b20gdmFsdWU8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yIGRhc2hib2FyZC1wYXJhbS1waWNrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAqbmdJZj1cImFjdGlvbkl0ZW0ucGFyYW1ldGVyc1snY3VzdG9tLScrcGFyYW0ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRW50ZXIgY3VzdG9tIHBhcmFtZXRlciB2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhY3Rpb25JdGVtLnBhcmFtZXRlcnNbcGFyYW0ubmFtZV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJUZXh0XCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAndGV4dCdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNiBweS0zIGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQ6ZmxleCBtZDppdGVtcy1jZW50ZXIgbWQ6anVzdGlmeS1iZXR3ZWVuIG1kOnNwYWNlLXgtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwIG1iLTBcIj5UZXh0IFNldHRpbmdzPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudGVyIEhUTUwvVGV4dCBmb3IgdGhpcyBpdGVtLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sLXJldmVyc2UganVzdGlmeS1zdHJldGNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgKGNsaWNrKT1cIm9wZW5TaWRlLm5leHQodHJ1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC14cyBtbC0yIGhvdmVyOnVuZGVybGluZSBmbGV4IGl0ZW1zLWNlbnRlciBwcmltYXJ5IHRleHQtY3RhXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgaGVscCBkb2NzJm5ic3A7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGNsYXNzPVwiaC00IHctNFwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMSAzYTEgMSAwIDEwMCAyaDIuNTg2bC02LjI5MyA2LjI5M2ExIDEgMCAxMDEuNDE0IDEuNDE0TDE1IDYuNDE0VjlhMSAxIDAgMTAyIDBWNGExIDEgMCAwMC0xLTFoLTV6XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTUgNWEyIDIgMCAwMC0yIDJ2OGEyIDIgMCAwMDIgMmg4YTIgMiAwIDAwMi0ydi0zYTEgMSAwIDEwLTIgMHYzSDVWN2gzYTEgMSAwIDAwMC0ySDV6XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPG5neC1jb2RlbWlycm9yXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidGV4dERhdGEudmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJ7bGluZU51bWJlcnM6IHRydWUsdGhlbWU6ICd0dGNuJyxtb2RlOiAnaHRtbG1peGVkJyxhdXRvUmVmcmVzaDogdHJ1ZSxzbWFydEluZGVudDogdHJ1ZSxleHRyYUtleXM6IHsnQ3RybC1TcGFjZSc6ICdhdXRvY29tcGxldGUnfX1cIj5cblxuICAgICAgICAgICAgICAgIDwvbmd4LWNvZGVtaXJyb3I+XG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkltYWdlXCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnaW1hZ2UnXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTYgcHktMyBiZy13aGl0ZSBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1kOmZsZXggbWQ6aXRlbXMtY2VudGVyIG1kOmp1c3RpZnktYmV0d2VlbiBtZDpzcGFjZS14LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwdC0xLjVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgxIGNsYXNzPVwidGV4dC14bCBmb250LWJvbGQgdGV4dC1ncmF5LTkwMCBtYi0wXCI+SW1hZ2UgU2V0dGluZ3M8L2gxPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0IHRoZSBpbWFnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhpcyB3aWRnZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xLzJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdCB0aGUgY29sdW1uIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGRlc2lyZWQgaW1hZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJpbWFnZURhdGEuY29sdW1uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldEltYWdlRGF0YSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInVuZGVmaW5lZFwiPi0tIFNlbGVjdCBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY29sdW1uLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJUYWJsZVwiICpuZ0lmPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3RhYmxlJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPlRhYmxlIFJvdyBTZXR0aW5nczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBZGp1c3QgdGhlIHNldHRpbmdzIHRvIGJlIGFwcGxpZWQgdG8gZWFjaCB0YWJsZSByb3cuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xLzJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTQgZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwibXItMlwiIFsobmdNb2RlbCldPVwidGFidWxhci5leHBhbmRSb3dzXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wIG10LTFcIj5FeHBhbmQgcm93cy4gQnkgZGVmYXVsdCByb3dzIGFyZSBjb21wcmVzc2VkIGFuZCByZXN0cmljdCB3cmFwcGluZy48L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTQgZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwibXItMlwiIFsobmdNb2RlbCldPVwidGFidWxhci5oaWRlUGFnZXJcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTAgbXQtMVwiPkhpZGUgdGhlIHBhZ2VyIGF0IHRoZSBib3R0b20gb2YgdGhlIHRhYmxlLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItNCBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtci0yXCIgWyhuZ01vZGVsKV09XCJ0YWJ1bGFyLmFjdGlvblJvd3NcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTAgbXQtMVwiPk1ha2UgdGFibGUgcm93cyBjbGlja2FibGU8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInRhYnVsYXIuYWN0aW9uUm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsbCB0byBhY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwidGFidWxhci5jdGFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYXJlV2l0aF09XCJzZXRDYWxsVG9BY3Rpb25JdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjdGFVcGRhdGUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPk5vbmU8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwie3R5cGU6ICdjdXN0b20nLCB3aW5kb3dMb2NhdGlvbjogJ0VYSVNUSU5HJ31cIj5DdXN0b20gTGlua1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0Z3JvdXAgbGFiZWw9XCJEYXNoYm9hcmRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgZGFzaGJvYXJkIG9mIGRhc2hib2FyZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVmFsdWVdPVwie3R5cGU6ICdkYXNoYm9hcmQnLCB2YWx1ZTogZGFzaGJvYXJkLmlkLCBsYWJlbDogZGFzaGJvYXJkLnRpdGxlLCB3aW5kb3dMb2NhdGlvbjogJ0VYSVNUSU5HJ31cIj57e2Rhc2hib2FyZC50aXRsZX19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGdyb3VwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGdyb3VwIGxhYmVsPVwiU2hhcmVkIERhc2hib2FyZHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBkYXNoYm9hcmQgb2Ygc2hhcmVkRGFzaGJvYXJkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdWYWx1ZV09XCJ7dHlwZTogJ2Rhc2hib2FyZCcsIHZhbHVlOiBkYXNoYm9hcmQuaWQsIGxhYmVsOiBkYXNoYm9hcmQudGl0bGUsIHdpbmRvd0xvY2F0aW9uOiAnRVhJU1RJTkcnfVwiPnt7ZGFzaGJvYXJkLnRpdGxlfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0Z3JvdXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJmb250LW5vcm1hbFwiPlNlbGVjdCB0aGUgZGVzdGluYXRpb24gZm9yIHRoZSBhY3Rpb24gbGluazwvc21hbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwidGFidWxhci5jdGEgJiYgdGFidWxhci5jdGEudHlwZSA9PT0gJ2N1c3RvbSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+UGxlYXNlIGVudGVyIHRoZSBsaW5rIGZvciB0aGlzIGNhbGwgdG8gYWN0aW9uLjwvcD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaW5rXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInRhYnVsYXIuY3RhLmxpbmtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwidGFidWxhci5jdGEgJiYgZGFzaGJvYXJkUGFyYW1ldGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+UGxlYXNlIGVudGVyIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB0byB1c2Ugd2l0aCB0aGlzIGRhc2hib2FyZDwvcD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LXBhcmFtIFtuZ0Zvck9mXT1cImRhc2hib2FyZFBhcmFtZXRlcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD57e3BhcmFtLnRpdGxlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsICpuZ0lmPVwiIXRhYnVsYXIuY3RhLnBhcmFtZXRlcnNbJ2N1c3RvbS0nK3BhcmFtLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1iLTIgZGFzaGJvYXJkLXBhcmFtLXBpY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJ0YWJ1bGFyLmN0YS5wYXJhbWV0ZXJzW3BhcmFtLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYXJlV2l0aF09XCJjdGFTZWxlY3RPcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbj4tLSBTZWxlY3QgVmFsdWUgLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiJ1tbJytjb2x1bW4ubmFtZSsnXV0nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwibXItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRhYnVsYXIuY3RhLnBhcmFtZXRlcnNbJ2N1c3RvbS0nK3BhcmFtLm5hbWVdXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wIG10LTFcIj5Vc2UgY3VzdG9tIHZhbHVlPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yIGRhc2hib2FyZC1wYXJhbS1waWNrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgKm5nSWY9XCJ0YWJ1bGFyLmN0YS5wYXJhbWV0ZXJzWydjdXN0b20tJytwYXJhbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRW50ZXIgY3VzdG9tIHBhcmFtZXRlciB2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidGFidWxhci5jdGEucGFyYW1ldGVyc1twYXJhbS5uYW1lXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1yYWRpby1ncm91cCAqbmdJZj1cInRhYnVsYXIuY3RhXCIgWyhuZ01vZGVsKV09XCJ0YWJ1bGFyLmN0YS53aW5kb3dMb2NhdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvbiBjbGFzcz1cIm1yLTRcIiB2YWx1ZT1cIkVYSVNUSU5HXCI+RXhpc3RpbmcgV2luZG93PC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvbiB2YWx1ZT1cIl9ibGFua1wiPk5ldyBXaW5kb3cvVGFiPC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXJhZGlvLWdyb3VwPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkNvbHVtbnNcIiAqbmdJZj1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICd0YWJsZSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNiBweS0zIGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQ6ZmxleCBtZDppdGVtcy1jZW50ZXIgbWQ6anVzdGlmeS1iZXR3ZWVuIG1kOnNwYWNlLXgtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwIG1iLTBcIj5UYWJsZSBDb2x1bW4gU2V0dGluZ3M8L2gxPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbHkgc3BlY2lmaWMgY2VsbCBmb3JtYXR0aW5nIHRvIGVhY2ggdGFibGUgY29sdW1uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgdGhlIGNvbHVtbiB0byBmb3JtYXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJ0YWJsZUNlbGxzLmNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRDb2x1bW4oJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ1bmRlZmluZWRcIj4tLSBTZWxlY3QgQ29sdW1uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwidGFibGVDZWxsc1t0YWJsZUNlbGxzLmNvbHVtbl1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNwZWNpZnkgTWF4IENvbHVtbiBXaWR0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSByZWxhdGl2ZSByb3VuZGVkLW1kIHNoYWRvdy1zbSB3LTEvNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBbKG5nTW9kZWwpXT1cInRhYmxlQ2VsbHNbdGFibGVDZWxscy5jb2x1bW5dLm1heFdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJsb2NrIHctZnVsbCBwbC03IHByLTEyIHNtOnRleHQtc20gYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRW50ZXIgd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhYnNvbHV0ZSBpbnNldC15LTAgcmlnaHQtMCBwci0zIGZsZXggaXRlbXMtY2VudGVyIHBvaW50ZXItZXZlbnRzLW5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtZ3JheS01MDAgc206dGV4dC1zbVwiPiBweCA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uIEZvcm1hdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJ0YWJsZUNlbGxzW3RhYmxlQ2VsbHMuY29sdW1uXS50eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRDb2x1bW5Gb3JtYXQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+QXV0b21hdGljPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBmb3JtYXQgb2YgY29sdW1uRm9ybWF0c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJmb3JtYXQudHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Zm9ybWF0LnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGtpLXRhYmxlLWNlbGwtZm9ybWF0dGVyICpuZ0lmPVwidGFibGVDZWxsc1t0YWJsZUNlbGxzLmNvbHVtbl0udHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cInRhYmxlQ2VsbHNbdGFibGVDZWxscy5jb2x1bW5dLnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJ0YWJsZUNlbGxzW3RhYmxlQ2VsbHMuY29sdW1uXS5kYXRhXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wZW5TaWRlXT1cIm9wZW5TaWRlXCIgW2RhdGFzZXRdPVwiZGF0YXNldFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjdXJyZW5jaWVzXT1cImN1cnJlbmNpZXNcIiBbZGFzaGJvYXJkc109XCJkYXNoYm9hcmRzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NoYXJlZERhc2hib2FyZHNdPVwic2hhcmVkRGFzaGJvYXJkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcml2YXRlRGFzaGJvYXJkc109XCJwcml2YXRlRGFzaGJvYXJkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthY3Rpb25FdmVudHNdPVwiYWN0aW9uRXZlbnRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9raS10YWJsZS1jZWxsLWZvcm1hdHRlcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiTWV0cmljXCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbWV0cmljJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPk1ldHJpYyBTZXR0aW5nczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Qgd2hpY2ggcGllY2VzIG9mIGluZm9ybWF0aW9uIHRvIGRpc3BsYXkuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00IGZsZXgganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3cgcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFpbiBNZXRyaWNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwibWV0cmljLm1haW5cIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVNZXRyaWNEYXRhVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBNYWluIE1ldHJpYyAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJmaWVsZC5uYW1lXCIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZpbHRlckZpZWxkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tmaWVsZC50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGhyPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ViIE1ldHJpY1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJtZXRyaWMuc3ViTWV0cmljXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlTWV0cmljRGF0YVZhbHVlcygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgU3ViIE1ldHJpYyAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJmaWVsZC5uYW1lXCIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZpbHRlckZpZWxkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tmaWVsZC50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGUgWyhuZ01vZGVsKV09XCJtZXRyaWMuc2hvd1N1YkNoYW5nZVwiIGNsYXNzPVwibWItNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVNZXRyaWNEYXRhVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaG93IE1ldHJpYyBDaGFuZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNi8xMiBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPjxiPlByZXZpZXc8L2I+PC9wPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hhZG93IHAtNCBmbGV4IGl0ZW1zLWNlbnRlciBtZXRyaWMtcHJldmlld1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHQgY2xhc3M9XCJ0ZXh0LWJhc2UgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTkwMFwiPnt7bWV0cmljLnRpdGxlfX08L2R0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGQgY2xhc3M9XCJtdC0xIGZsZXggaXRlbXMtYmFzZWxpbmUganVzdGlmeS1iZXR3ZWVuIG1kOmJsb2NrIGxnOmZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWJhc2VsaW5lIHRleHQtMnhsIGZvbnQtc2VtaWJvbGQgdGV4dC1pbmRpZ28tNjAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRyaWMubWFpblZhbHVlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1ldHJpYy5zdWJNZXRyaWNcIiBjbGFzcz1cIm1sLTIgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+ZnJvbSB7e21ldHJpYy5zdWJWYWx1ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC14c1wiPih7e21ldHJpYy5zdWJUaXRsZX19KTwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIm1ldHJpYy5zaG93U3ViQ2hhbmdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBpdGVtcy1iYXNlbGluZSBweC0yLjUgcHktMC41IHJvdW5kZWQtZnVsbCB0ZXh0LXNtIGZvbnQtbWVkaXVtIG1kOm10LTIgbGc6bXQtMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYmctZ3JlZW4tMTAwIHRleHQtZ3JlZW4tODAwJzogbWV0cmljLm1haW5WYWx1ZSA+PSBtZXRyaWMuc3ViVmFsdWUsICdiZy1yZWQtMTAwIHRleHQtcmVkLTgwMCc6IG1ldHJpYy5tYWluVmFsdWUgPCBtZXRyaWMuc3ViVmFsdWV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBIZXJvaWNvbiBuYW1lOiBtaW5pL2Fycm93LXVwIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJtZXRyaWMubWFpblZhbHVlID49IG1ldHJpYy5zdWJWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIi1tbC0xIG1yLTAuNSBoLTUgdy01IGZsZXgtc2hyaW5rLTAgc2VsZi1jZW50ZXIgdGV4dC1ncmVlbi01MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMCAxN2EuNzUuNzUgMCAwMS0uNzUtLjc1VjUuNjEyTDUuMjkgOS43N2EuNzUuNzUgMCAwMS0xLjA4LTEuMDRsNS4yNS01LjVhLjc1Ljc1IDAgMDExLjA4IDBsNS4yNSA1LjVhLjc1Ljc1IDAgMTEtMS4wOCAxLjA0bC0zLjk2LTQuMTU4VjE2LjI1QS43NS43NSAwIDAxMTAgMTd6XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwibWV0cmljLm1haW5WYWx1ZSA8IG1ldHJpYy5zdWJWYWx1ZSBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiLW1sLTEgbXItMC41IGgtNSB3LTUgZmxleC1zaHJpbmstMCBzZWxmLWNlbnRlciB0ZXh0LXJlZC01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTAgM2EuNzUuNzUgMCAwMS43NS43NXYxMC42MzhsMy45Ni00LjE1OGEuNzUuNzUgMCAxMTEuMDggMS4wNGwtNS4yNSA1LjVhLjc1Ljc1IDAgMDEtMS4wOCAwbC01LjI1LTUuNWEuNzUuNzUgMCAxMTEuMDgtMS4wNGwzLjk2IDQuMTU4VjMuNzVBLjc1Ljc1IDAgMDExMCAzelwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXAtcnVsZT1cImV2ZW5vZGRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttZXRyaWMuZGlmZmVyZW5jZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkNoYXJ0XCIgKm5nSWY9XCJjaGFydFR5cGVzLmluZGV4T2YoZGFzaGJvYXJkSXRlbVR5cGUudHlwZSkgPiAtMVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkNoYXJ0IFNldHRpbmdzPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyZSB0aGUgY2hhcnQgZGF0YSBhbmQgZGlzcGxheSBvcHRpb25zLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC02IGZsZXggZmxleC1jb2wtcmV2ZXJzZSBqdXN0aWZ5LXN0cmV0Y2hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSAoY2xpY2spPVwib3BlblNpZGUubmV4dCh0cnVlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXhzIG1sLTIgaG92ZXI6dW5kZXJsaW5lIGZsZXggaXRlbXMtY2VudGVyIHByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlldyBoZWxwIGRvY3MmbmJzcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgY2xhc3M9XCJoLTQgdy00XCIgdmlld0JveD1cIjAgMCAyMCAyMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTExIDNhMSAxIDAgMTAwIDJoMi41ODZsLTYuMjkzIDYuMjkzYTEgMSAwIDEwMS40MTQgMS40MTRMMTUgNi40MTRWOWExIDEgMCAxMDIgMFY0YTEgMSAwIDAwLTEtMWgtNXpcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNSA1YTIgMiAwIDAwLTIgMnY4YTIgMiAwIDAwMiAyaDhhMiAyIDAgMDAyLTJ2LTNhMSAxIDAgMTAtMiAwdjNINVY3aDNhMSAxIDAgMDAwLTJINXpcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00IGZsZXgganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3cgcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhcnQgVHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJsaW5lXCI+TGluZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiYmFyXCI+QmFyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJwaWVcIj5QaWU8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImRvdWdobnV0XCI+RG91Z2hudXQ8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInNjYXR0ZXJcIj5TY2F0dGVyPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdwaWUnICYmIGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWCBBeGlzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdwaWUnIHx8IGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFiZWxzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q2hhcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ3BpZScgJiYgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2RvdWdobnV0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBeGlzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdwaWUnIHx8IGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYWJlbHMgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZpZWxkLm5hbWVcIiAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZmlsdGVyRmllbGRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdwaWUnICYmIGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgIT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWSBBeGlzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdwaWUnIHx8IGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWVzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLnlBeGlzXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q2hhcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ3BpZScgJiYgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2RvdWdobnV0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBeGlzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdwaWUnIHx8IGRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdkb3VnaG51dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZXMgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZpZWxkLm5hbWVcIiAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZmlsdGVyRmllbGRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ3BpZScgJiYgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2RvdWdobnV0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VyaWVzIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUuc2VyaWVzQ29sdW1uXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q2hhcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgU2VyaWVzIENvbHVtbi0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJmaWVsZC5uYW1lXCIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZpbHRlckZpZWxkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmllbGQudGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZW5kIExpbmUgT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUudHJlbmRMaW5lXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q2hhcnREYXRhKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgVHJlbmQgTGluZSBPcHRpb24tLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImF2ZXJhZ2VcIj5BdmVyYWdlIExpbmU8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJsaW5lYXJcIj5MaW5lYXIgTGluZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImV4cG9uZW50aWFsXCI+RXhwb25lbnRpYWwgTGluZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImxvZ2FyaXRobWljXCI+TG9nYXJpdGhtaWMgTGluZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInBvd2VyXCI+UG93ZXIgTGluZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGdyb3VwIGxhYmVsPVwiVXNlIENvbHVtbiBEYXRhXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiZmllbGQubmFtZVwiICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWx0ZXJGaWVsZHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tmaWVsZC50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGdyb3VwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTEgdGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNDAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Qgb25lIG9mIHRoZSBvcHRpb25zLCBvciBhbiBleGlzdGluZyBjb2x1bW4gb2YgZGF0YSB0byBwbG90IGFuIGFkZGl0aW9uYWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgb24gdGhlIGdyYXBoLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhc2hib2FyZEl0ZW1UeXBlLnRyZW5kTGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZW5kIExpbmUgQ29sb3VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS50cmVuZExpbmVDb2xvdXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldENoYXJ0RGF0YSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTQgbWItNCBhbGlnbi1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpbWl0IFJlc3VsdHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLmxpbWl0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtbC00IG10LTQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS5jb21iaW5lUmVtYWluaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21iaW5lIHJlbWFpbmluZyByZXN1bHRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiICpuZ0lmPVwiZGFzaGJvYXJkSXRlbVR5cGUuY29tYmluZVJlbWFpbmluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbWFpbmluZyByZXN1bHRzIGxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS5jb21iaW5lUmVtYWluZ2luZ0xhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ3BpZScgJiYgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2RvdWdobnV0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWSBBeGVzIE1heCB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJ3LTEvMlwiIHR5cGU9XCJudW1iZXJcIiBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLm1heFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlIFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUuYmVnaW5BdFplcm9cIiBjbGFzcz1cImJsb2NrIG1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhcnQgWSBBeGVzIGF0IFplcm9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZSBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLmxlZ2VuZFwiIGNsYXNzPVwiYmxvY2sgbWItNFwiPlNob3cgTGVnZW5kXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZSAqbmdJZj1cImRhc2hib2FyZEl0ZW1UeXBlLnR5cGUgPT09ICdsaW5lJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLmZpbGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q2hhcnREYXRhKClcIiBjbGFzcz1cImJsb2NrIG1iLTRcIj5GaWxsIEJhY2tncm91bmRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbG91ciBQYWxldHRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFtjb21wYXJlV2l0aF09XCJwYWxldHRlU2VsZWN0T3B0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJkYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJQYWxldHRlXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQ29sb3VyUGFsZXR0ZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgQ29sb3VyIFBhbGV0dGUtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cInBhbGV0dGVcIiAqbmdGb3I9XCJsZXQgcGFsZXR0ZSBvZiBjb2xvdXJQYWxldHRlc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3twYWxldHRlLm5hbWV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhY29sb3VyUGFsZXR0ZXMubGVuZ3RoXCIgY2xhc3M9XCJib3JkZXItbC00IGJvcmRlci15ZWxsb3ctNDAwIGJnLXllbGxvdy01MCBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC15ZWxsb3ctNDAwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNOC40ODUgMi40OTVjLjY3My0xLjE2NyAyLjM1Ny0xLjE2NyAzLjAzIDBsNi4yOCAxMC44NzVjLjY3MyAxLjE2Ny0uMTcgMi42MjUtMS41MTYgMi42MjVIMy43MmMtMS4zNDcgMC0yLjE4OS0xLjQ1OC0xLjUxNS0yLjYyNUw4LjQ4NSAyLjQ5NXpNMTAgNWEuNzUuNzUgMCAwMS43NS43NXYzLjVhLjc1Ljc1IDAgMDEtMS41IDB2LTMuNUEuNzUuNzUgMCAwMTEwIDV6bTAgOWExIDEgMCAxMDAtMiAxIDEgMCAwMDAgMnpcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1sLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQtc20gdGV4dC15ZWxsb3ctNzAwIG1iLTAgZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtbm9ybWFsXCI+Tm8gY29sb3VyIHBhbGV0dGVzIGF2YWlsYWJsZS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIFtyb3V0ZXJMaW5rXT1cIlsnL3Byb2plY3Qtc2V0dGluZ3MnXVwiIHRhcmdldD1cIl9ibGFua1wiIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgbWwtMiBmb250LW1lZGl1bSB0ZXh0LXllbGxvdy03MDAgdW5kZXJsaW5lIGhvdmVyOnRleHQteWVsbG93LTYwMFwiPk1hbmFnZSBwYWxldHRlcyBpbiBwcm9qZWN0IHNldHRpbmdzLjxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgY2xhc3M9XCJoLTQgdy00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYuMjIgOC43MmEuNzUuNzUgMCAwIDAgMS4wNiAxLjA2bDUuMjItNS4yMnYxLjY5YS43NS43NSAwIDAgMCAxLjUgMHYtMy41YS43NS43NSAwIDAgMC0uNzUtLjc1aC0zLjVhLjc1Ljc1IDAgMCAwIDAgMS41aDEuNjlMNi4yMiA4LjcyWlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTMuNSA2Ljc1YzAtLjY5LjU2LTEuMjUgMS4yNS0xLjI1SDdBLjc1Ljc1IDAgMCAwIDcgNEg0Ljc1QTIuNzUgMi43NSAwIDAgMCAyIDYuNzV2NC41QTIuNzUgMi43NSAwIDAgMCA0Ljc1IDE0aDQuNUEyLjc1IDIuNzUgMCAwIDAgMTIgMTEuMjVWOWEuNzUuNzUgMCAwIDAtMS41IDB2Mi4yNWMwIC42OS0uNTYgMS4yNS0xLjI1IDEuMjVoLTQuNWMtLjY5IDAtMS4yNS0uNTYtMS4yNS0xLjI1di00LjVaXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG48IS0tICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gY29sb3I9XCJhY2NlbnRcIiAoY2xpY2spPVwicmVzZXREZWZhdWx0Q29sb3VycygpXCI+LS0+XG48IS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPi0tPlxuPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzZXQgdG8gRGVmYXVsdCBDb2xvdXJzLS0+XG48IS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pi0tPlxuPCEtLSAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPi0tPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbGluZScgfHwgZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3NjYXR0ZXInXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZGF0YUl0ZW0gb2YgY2hhcnREYXRhOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJtdC00IGFsaWduLWNlbnRlciBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e18uc3RhcnRDYXNlKGRhdGFJdGVtLmxhYmVsKX19IENvbG91clxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUuYm9yZGVyQ29sb3JbaV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldENoYXJ0RGF0YSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSAhPT0gJ2xpbmUnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFkYXNoYm9hcmRJdGVtVHlwZS5jb2xvdXJQYWxldHRlXCIgY2xhc3M9XCJtdC00IG1iLTQgZmxleCBpdGVtcy1lbmQganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmFja2dyb3VuZCBDb2xvdXIgUmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBbKG5nTW9kZWwpXT1cImRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvckZyb21cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImJhY2tncm91bmRDb2xvdXJVcGRhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yVG9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImJhY2tncm91bmRDb2xvdXJVcGRhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTQgbWItNCBhbGlnbi1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sb3VyIEdlbmVyYXRvciBNb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXJhZGlvLWdyb3VwIFsobmdNb2RlbCldPVwiZGFzaGJvYXJkSXRlbVR5cGUuY29sb3VyTW9kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImJhY2tncm91bmRDb2xvdXJVcGRhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIGNsYXNzPVwibXItNFwiIHZhbHVlPVwicmVwZWF0XCI+UmVwZWF0PC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIGNsYXNzPVwibXItNFwiIHZhbHVlPVwibHJnYlwiPkdyYWRpZW50PC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIGNsYXNzPVwibXItNFwiIHZhbHVlPVwiaHNsXCI+SFNMPC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIHZhbHVlPVwibGNoXCI+TENIPC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtcmFkaW8tZ3JvdXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiQXJyYXkuaXNBcnJheShkYXNoYm9hcmRJdGVtVHlwZS5iYWNrZ3JvdW5kQ29sb3IpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS5iYWNrZ3JvdW5kQ29sb3IgJiYgZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0IEluZGl2aWR1YWwgQ29sb3Vyc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBiYWNrQ29sb3VyIG9mIGRhc2hib2FyZEl0ZW1UeXBlLmJhY2tncm91bmRDb2xvcjsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXQgJiYgZGF0YXNldC5hbGxEYXRhW2ldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRyYWNraW5nLXdpZGVyIHVwcGVyY2FzZSB0ZXh0LWdyYXktNTAwIHRleHQteHMgbXQtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRhdGFzZXQgJiYgZGF0YXNldC5hbGxEYXRhXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZGF0YXNldC5hbGxEYXRhW2ldW2Rhc2hib2FyZEl0ZW1UeXBlLnhBeGlzXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIChjaGFuZ2UpPVwidXBkYXRlQ2hhcnQoJGV2ZW50LnRhcmdldC52YWx1ZSwgaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCInY29sb3VyJyArIGlcIiBbdmFsdWVdPVwiZGFzaGJvYXJkSXRlbVR5cGUuYmFja2dyb3VuZENvbG9yW2ldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuXG5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNi8xMiBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxjYW52YXMgI2NoYXJ0IGJhc2VDaGFydCBjbGFzcz1cInN0aWNreSB0b3AtMTBcIiAqbmdJZj1cImNoYXJ0RGF0YVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhc2V0c109XCJjaGFydERhdGFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxzXT1cImRhc2hib2FyZEl0ZW1UeXBlLmxhYmVsc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cIntzY2FsZXM6IHt5OiB7YmVnaW5BdFplcm86IGRhc2hib2FyZEl0ZW1UeXBlLmJlZ2luQXRaZXJvLCBtYXg6IGRhc2hib2FyZEl0ZW1UeXBlLm1heFZhbHVlIHx8IG51bGx9fSwgcmVzcG9uc2l2ZTogdHJ1ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGVnZW5kXT1cIiEhZGFzaGJvYXJkSXRlbVR5cGUubGVnZW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbHVnaW5zXT1cIltdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2NhbnZhcz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiV29yZCBDbG91ZFwiICpuZ0lmPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ3dvcmRzJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPldvcmQgQ2xvdWQgU2V0dGluZ3M8L2gxPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRqdXN0IHRoZSBzZXR0aW5ncyBmb3IgdGhlIFdvcmQgQ2xvdWQgZ2VuZXJhdG9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xLzJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZSBhbiBpbmRleGVkIGRvY3VtZW50IGRhdGEgc291cmNlIHRvIHBvcHVsYXRlIHdvcmQgY2xvdWQsIG9yIHByb3ZpZGUgYSBzdHJpbmcgZnJvbSBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlIGNvbHVtbi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXJhZGlvLWdyb3VwIFsobmdNb2RlbCldPVwid29yZENsb3VkLnBvcHVsYXRpb25NZXRob2RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1yYWRpby1idXR0b24gdmFsdWU9XCJXSE9MRVwiPldvcmQgRnJlcXVlbmNpZXM8L21hdC1yYWRpby1idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIGNsYXNzPVwibWwtNFwiIHZhbHVlPVwiU0lOR0xFXCI+U2luZ2xlIFN0cmluZzwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1yYWRpby1ncm91cD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ3b3JkQ2xvdWQucG9wdWxhdGlvbk1ldGhvZCA9PT0gJ1NJTkdMRSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdCB3aGljaCByb3cgdG8gdXNlIGZvciB0aGUgd29yZCBjbG91ZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJ3b3JkQ2xvdWQucm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ1bmRlZmluZWRcIj4tLSBTZWxlY3QgUm93IC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHJvdyBvZiBkYXRhc2V0LmFsbERhdGE7IGxldCBpID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tfLnZhbHVlcyhyb3cpWzBdfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdCB0aGUgY29sdW1uIHRvIHVzZSBmb3IgdGhlIHdvcmQgY2xvdWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwid29yZENsb3VkLmNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIndvcmRDbG91ZC5wb3B1bGF0aW9uTWV0aG9kID09PSAnV0hPTEUnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgdGhlIGNvbHVtbiB0byB1c2UgZm9yIHRoZSB3b3Jkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJ3b3JkQ2xvdWQuY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ1bmRlZmluZWRcIj4tLSBTZWxlY3QgQ29sdW1uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgdGhlIGNvbHVtbiB0byB1c2UgZm9yIHRoZSBmcmVxdWVuY3lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwid29yZENsb3VkLmZyZXF1ZW5jeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJOZXR3b3JrIEdyYXBoXCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbmV0d29yaydcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNiBweS0zIGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQ6ZmxleCBtZDppdGVtcy1jZW50ZXIgbWQ6anVzdGlmeS1iZXR3ZWVuIG1kOnNwYWNlLXgtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwIG1iLTBcIj5OZXR3b3JrIEdyYXBoIFNldHRpbmdzPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkanVzdCB0aGUgc2V0dGluZ3MgZm9yIHRoZSBOZXR3b3JrIEdyYXBoLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC0xIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGJnLXdoaXRlIHAtNCBib3JkZXIgcm91bmRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gbWItMyB0ZXh0LWJhc2VcIj5Ob2RlIERhdGE8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtci0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUQgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJuZXR3b3JrRGF0YS5ub2RlSWRzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0TmV0d29ya0NoYXJ0RGF0YSh0cnVlKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGRhdGFzZXQuY29sdW1uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5JRHMgbXVzdCBiZSB1bmlxdWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFiZWwgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJuZXR3b3JrRGF0YS5ub2RlTGFiZWxzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldE5ldHdvcmtDaGFydERhdGEodHJ1ZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImRhdGFzZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY29sdW1uLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+Jm5ic3A7PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdyb3VwIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ3LWZ1bGxcIiBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwibmV0d29ya0RhdGEubm9kZUdyb3Vwc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXROZXR3b3JrQ2hhcnREYXRhKHRydWUpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgQ29sdW1uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlNldCB3aGljaCBncm91cCBub2RlcyBiZWxvbmcgdG8uPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJweS0yXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb250LW1lZGl1bSB0ZXh0LWJhc2VcIj5HbG9iYWwgTm9kZSBPcHRpb25zPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+T3B0aW9ucyBkZWZpbmVkIGhlcmUgd2lsbCBhcHBseSB0byBhbGwgbm9kZXMuPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJhZGRPcHRpb24oJ25vZGVPcHRpb25zJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkIE5vZGUgT3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1ub2RlT3B0aW9uIFtuZ0Zvck9mXT1cIm5ldHdvcmtEYXRhLm5vZGVPcHRpb25zXCIgbGV0LWk9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtci0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwidy1mdWxsXCIgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cIm5ldHdvcmtEYXRhLm5vZGVPcHRpb25zW2ldLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBPcHRpb24gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBhdmFpbGFibGVOb2RlT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJfLmZpbmQobmV0d29ya0RhdGEubm9kZU9wdGlvbnMsIHtrZXk6IG9wdGlvbn0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cIm9wdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ufX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb24gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5ldHdvcmtEYXRhLm5vZGVPcHRpb25zW2ldLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5ub2Rlc1tuZXR3b3JrRGF0YS5ub2RlT3B0aW9uc1tpXS5rZXldLnR5cGUgIT09ICdib29sZWFuJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cInZpc05ldHdvcmtPcHRpb25zLm5vZGVzW25ldHdvcmtEYXRhLm5vZGVPcHRpb25zW2ldLmtleV0udHlwZVwiIFsobmdNb2RlbCldPVwibm9kZU9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwibmV0d29ya0RhdGEubm9kZU9wdGlvbnNbaV0ua2V5ICYmIHZpc05ldHdvcmtPcHRpb25zLm5vZGVzW25ldHdvcmtEYXRhLm5vZGVPcHRpb25zW2ldLmtleV0udHlwZSA9PT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwibm9kZU9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInRydWVcIj5UcnVlPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiZmFsc2VcIj5GYWxzZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9XCJodHRwczovL3Zpc2pzLmdpdGh1Yi5pby92aXMtbmV0d29yay9kb2NzL25ldHdvcmsvbm9kZXMuaHRtbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIiBjbGFzcz1cInRleHQtc2Vjb25kYXJ5IGZsZXggaXRlbXMtY2VudGVyIGhvdmVyOnVuZGVybGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgb3B0aW9ucyBkb2N1bWVudGF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIGNsYXNzPVwiaC0zIHctMyBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGQ9XCJNMTMuNSA2SDUuMjVBMi4yNSAyLjI1IDAgMCAwIDMgOC4yNXYxMC41QTIuMjUgMi4yNSAwIDAgMCA1LjI1IDIxaDEwLjVBMi4yNSAyLjI1IDAgMCAwIDE4IDE4Ljc1VjEwLjVtLTEwLjUgNkwyMSAzbTAgMGgtNS4yNU0yMSAzdjUuMjVcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwid2FyblwiIChjbGljayk9XCJuZXR3b3JrRGF0YS5ub2RlT3B0aW9ucy5zcGxpY2UoaSwgMSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsZWFyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC0xIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGJnLXdoaXRlIHAtNCBib3JkZXIgcm91bmRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb250LW1lZGl1bSBtYi0zIHRleHQtYmFzZVwiPkVkZ2UgRGF0YTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInBpY2tOZXR3b3JrRWRnZURhdGFzZXQoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgRWRnZSBEYXRhc2V0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5ldHdvcmtEYXRhLmVkZ2VEYXRhc2V0VGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiZy1ibHVlLTUwIHAtNCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJoLTUgdy01IHRleHQtYmx1ZS00MDBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBkPVwiTTE4IDEwYTggOCAwIDExLTE2IDAgOCA4IDAgMDExNiAwem0tNy00YTEgMSAwIDExLTIgMCAxIDEgMCAwMTIgMHpNOSA5YS43NS43NSAwIDAwMCAxLjVoLjI1M2EuMjUuMjUgMCAwMS4yNDQuMzA0bC0uNDU5IDIuMDY2QTEuNzUgMS43NSAwIDAwMTAuNzQ3IDE1SDExYS43NS43NSAwIDAwMC0xLjVoLS4yNTNhLjI1LjI1IDAgMDEtLjI0NC0uMzA0bC40NTktMi4wNjZBMS43NSAxLjc1IDAgMDA5LjI1MyA5SDl6XCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbC0zIGZsZXgtMSBtZDpmbGV4IG1kOmp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wIHRleHQtc20gdGV4dC1ibHVlLTcwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdSBhcmUgY3VycmVudGx5IHVzaW5nIHt7bmV0d29ya0RhdGEuZWRnZURhdGFzZXRUaXRsZX19IGRhdGFzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMCBtdC0zIHRleHQtc20gbWQ6bWwtNiBtZDptdC0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgKGNsaWNrKT1cImNsZWFyRWRnZURhdGFzZXQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3aGl0ZXNwYWNlLW5vd3JhcCBmb250LW1lZGl1bSB0ZXh0LWJsdWUtNzAwIGhvdmVyOnRleHQtYmx1ZS02MDAgaG92ZXI6dW5kZXJsaW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsZWFyIERhdGFzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGcm9tIE5vZGUgSUQgQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ3LWZ1bGxcIiBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwibmV0d29ya0RhdGEuZnJvbUlkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJlZGdlRGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBlZGdlRGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbyBOb2RlIElEIENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwidy1mdWxsXCIgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cIm5ldHdvcmtEYXRhLnRvSWRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImVkZ2VEYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGVkZ2VEYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+Jm5ic3A7PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhbmV0d29ya0RhdGEuZWRnZURhdGFzZXRUaXRsZVwiIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtci0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnJvbSBJRFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ3LWZ1bGxcIiBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwibmV0d29ya0RhdGEuZnJvbUlkc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGRhdGFzZXQuY29sdW1uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj4mbmJzcDs8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG8gSURcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwidy1mdWxsXCIgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cIm5ldHdvcmtEYXRhLnRvSWRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgQ29sdW1uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJkYXRhc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZGF0YXNldC5jb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwicHktMlwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gdGV4dC1iYXNlXCI+R2xvYmFsIEVkZ2UgT3B0aW9uczwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHRleHQteHMgdGV4dC1ncmF5LTUwMFwiPk9wdGlvbnMgZGVmaW5lZCBoZXJlIHdpbGwgYXBwbHkgdG8gYWxsIGVkZ2VzLjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkT3B0aW9uKCdlZGdlT3B0aW9ucycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBFZGdlIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtZWRnZU9wdGlvbiBbbmdGb3JPZl09XCJuZXR3b3JrRGF0YS5lZGdlT3B0aW9uc1wiIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJuZXR3b3JrRGF0YS5lZGdlT3B0aW9uc1tpXS5rZXlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgT3B0aW9uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgYXZhaWxhYmxlRWRnZU9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiXy5maW5kKG5ldHdvcmtEYXRhLmVkZ2VPcHRpb25zLCB7a2V5OiBvcHRpb259KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e29wdGlvbn19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj4mbmJzcDs8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uIFZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJuZXR3b3JrRGF0YS5lZGdlT3B0aW9uc1tpXS5rZXkgJiYgdmlzTmV0d29ya09wdGlvbnMuZWRnZXNbbmV0d29ya0RhdGEuZWRnZU9wdGlvbnNbaV0ua2V5XS50eXBlICE9PSAnYm9vbGVhbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbdHlwZV09XCJ2aXNOZXR3b3JrT3B0aW9ucy5lZGdlc1tuZXR3b3JrRGF0YS5lZGdlT3B0aW9uc1tpXS5rZXldLnR5cGVcIiBbKG5nTW9kZWwpXT1cImVkZ2VPcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5ldHdvcmtEYXRhLmVkZ2VPcHRpb25zW2ldLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5lZGdlc1tuZXR3b3JrRGF0YS5lZGdlT3B0aW9uc1tpXS5rZXldLnR5cGUgPT09ICdib29sZWFuJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImVkZ2VPcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ0cnVlXCI+VHJ1ZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZhbHNlXCI+RmFsc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly92aXNqcy5naXRodWIuaW8vdmlzLW5ldHdvcmsvZG9jcy9uZXR3b3JrL2VkZ2VzLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBmbGV4IGl0ZW1zLWNlbnRlciBob3Zlcjp1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlIG9wdGlvbnMgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cImgtMyB3LTMgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEzLjUgNkg1LjI1QTIuMjUgMi4yNSAwIDAgMCAzIDguMjV2MTAuNUEyLjI1IDIuMjUgMCAwIDAgNS4yNSAyMWgxMC41QTIuMjUgMi4yNSAwIDAgMCAxOCAxOC43NVYxMC41bS0xMC41IDZMMjEgM20wIDBoLTUuMjVNMjEgM3Y1LjI1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwibmV0d29ya0RhdGEuZWRnZU9wdGlvbnMuc3BsaWNlKGksIDEpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIDxtYXQtdGFiIGxhYmVsPVwiR3JvdXBzXCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbmV0d29yaycgJiYgbmV0d29ya0RhdGEubm9kZUdyb3Vwc1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkdyb3VwIE9wdGlvbnM8L2gxPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmaW5lIHRoZSBvcHRpb25zIGZvciBlYWNoIGdyb3VwLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC0xIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgYmctd2hpdGUgcC00IGJvcmRlciByb3VuZGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvbnQtbWVkaXVtIG1iLTMgdGV4dC1iYXNlXCI+R3JvdXAgRGF0YTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtbm9kZUdyb3VwIFtuZ0Zvck9mXT1cIm5vZGVHcm91cHNcIj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0yIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdyb3VwIE5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibm9kZUdyb3VwIHx8ICcnXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gdGV4dC1iYXNlXCI+R3JvdXAgT3B0aW9uczwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHRleHQteHMgdGV4dC1ncmF5LTUwMFwiPlNldCB0aGUgb3B0aW9ucyBmb3IgdGhpcyBub2RlLjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkR3JvdXBPcHRpb24obm9kZUdyb3VwKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBZGQgR3JvdXAgT3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5ldHdvcmtEYXRhLm5vZGVHcm91cE9wdGlvbnMgJiYgbmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9uc1tub2RlR3JvdXBdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtZ3JvdXBPcHRpb24gW25nRm9yT2ZdPVwibmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9uc1tub2RlR3JvdXBdPy5vcHRpb25zXCIgbGV0LWk9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtci0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwidy1mdWxsXCIgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cImdyb3VwT3B0aW9uLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBPcHRpb24gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBhdmFpbGFibGVOb2RlT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJfLmZpbmQobmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9ucywge2tleTogb3B0aW9ufSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwib3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb259fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+Jm5ic3A7PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbiBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZ3JvdXBPcHRpb24ua2V5ICYmIHZpc05ldHdvcmtPcHRpb25zLm5vZGVzW2dyb3VwT3B0aW9uLmtleV0udHlwZSAhPT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3R5cGVdPVwidmlzTmV0d29ya09wdGlvbnMubm9kZXNbZ3JvdXBPcHRpb24ua2V5XS50eXBlXCIgWyhuZ01vZGVsKV09XCJncm91cE9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZ3JvdXBPcHRpb24ua2V5ICYmIHZpc05ldHdvcmtPcHRpb25zLm5vZGVzW2dyb3VwT3B0aW9uLmtleV0udHlwZSA9PT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwiZ3JvdXBPcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ0cnVlXCI+VHJ1ZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZhbHNlXCI+RmFsc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly92aXNqcy5naXRodWIuaW8vdmlzLW5ldHdvcmsvZG9jcy9uZXR3b3JrL25vZGVzLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBmbGV4IGl0ZW1zLWNlbnRlciBob3Zlcjp1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIG9wdGlvbnMgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cImgtMyB3LTMgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEzLjUgNkg1LjI1QTIuMjUgMi4yNSAwIDAgMCAzIDguMjV2MTAuNUEyLjI1IDIuMjUgMCAwIDAgNS4yNSAyMWgxMC41QTIuMjUgMi4yNSAwIDAgMCAxOCAxOC43NVYxMC41bS0xMC41IDZMMjEgM20wIDBoLTUuMjVNMjEgM3Y1LjI1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwibmV0d29ya0RhdGEubm9kZUdyb3VwT3B0aW9uc1tub2RlR3JvdXBdPy5vcHRpb25zLnNwbGljZShpLCAxKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xlYXI8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxociBjbGFzcz1cInB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJOb2Rlc1wiICpuZ0lmPVwiZGFzaGJvYXJkSXRlbVR5cGUudHlwZSA9PT0gJ25ldHdvcmsnICYmIGRhdGFzZXROb2Rlcy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNiBweS0zIGJnLXdoaXRlIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQ6ZmxleCBtZDppdGVtcy1jZW50ZXIgbWQ6anVzdGlmeS1iZXR3ZWVuIG1kOnNwYWNlLXgtNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnQgZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB0LTEuNVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktOTAwIG1iLTBcIj5Ob2RlIE9wdGlvbnM8L2gxPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmaW5lIHRoZSBvcHRpb25zIGZvciBlYWNoIG5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LTEgdy0xLzJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy1mdWxsIGJnLXdoaXRlIHAtNCBib3JkZXIgcm91bmRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvbnQtbWVkaXVtIHRleHQtYmFzZVwiPk5vZGUgT3B0aW9uczwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+VGhlc2Ugb3B0aW9ucyB3aWxsIGJlIGFwcGxpZWQgdG8gYWxsIG5vZGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWQgb24gdGhlIGNvbHVtbiBvciBjdXN0b20gdmFsdWUgcHJvdmlkZWQuPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkT3B0aW9uKCdnbG9iYWxOb2RlT3B0aW9ucycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBZGQgTm9kZSBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtbm9kZU9wdGlvbiBbbmdGb3JPZl09XCJuZXR3b3JrRGF0YS5nbG9iYWxOb2RlT3B0aW9uc1wiIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1yLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwidy1mdWxsXCIgbWF0TmF0aXZlQ29udHJvbCBbKG5nTW9kZWwpXT1cIm5vZGVPcHRpb24ua2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgT3B0aW9uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBhdmFpbGFibGVOb2RlT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIl8uZmluZChuZXR3b3JrRGF0YS5nbG9iYWxOb2RlT3B0aW9ucywge2tleTogb3B0aW9ufSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ufX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSBDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJub2RlT3B0aW9uLmNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVPcHRpb25zKG5vZGVPcHRpb24sICdkYXRhc2V0Tm9kZXMnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIFNlbGVjdCBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY29sdW1uLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbm9ybWFsIHRleHQtZ3JheS01MDBcIj4mbmJzcDs8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tIFZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJub2RlT3B0aW9uLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5ub2Rlc1tub2RlT3B0aW9uLmtleV0udHlwZSAhPT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgW3R5cGVdPVwidmlzTmV0d29ya09wdGlvbnMubm9kZXNbbm9kZU9wdGlvbi5rZXldLnR5cGVcIiBbKG5nTW9kZWwpXT1cIm5vZGVPcHRpb24udmFsdWVcIiAoY2hhbmdlKT1cInVwZGF0ZU9wdGlvbnMobm9kZU9wdGlvbiwgJ2RhdGFzZXROb2RlcycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJub2RlT3B0aW9uLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5ub2Rlc1tub2RlT3B0aW9uLmtleV0udHlwZSA9PT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwibm9kZU9wdGlvbi52YWx1ZVwiIChjaGFuZ2UpPVwidXBkYXRlT3B0aW9ucyhub2RlT3B0aW9uLCAnZGF0YXNldE5vZGVzJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ0cnVlXCI+VHJ1ZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZhbHNlXCI+RmFsc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly92aXNqcy5naXRodWIuaW8vdmlzLW5ldHdvcmsvZG9jcy9uZXR3b3JrL25vZGVzLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBmbGV4IGl0ZW1zLWNlbnRlciBob3Zlcjp1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIG9wdGlvbnMgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cImgtMyB3LTMgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEzLjUgNkg1LjI1QTIuMjUgMi4yNSAwIDAgMCAzIDguMjV2MTAuNUEyLjI1IDIuMjUgMCAwIDAgNS4yNSAyMWgxMC41QTIuMjUgMi4yNSAwIDAgMCAxOCAxOC43NVYxMC41bS0xMC41IDZMMjEgM20wIDBoLTUuMjVNMjEgM3Y1LjI1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwibmV0d29ya0RhdGEuZ2xvYmFsTm9kZU9wdGlvbnMuc3BsaWNlKGksIDEpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsZWFyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC0xIHctMS8yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBiZy13aGl0ZSBwLTQgYm9yZGVyIHJvdW5kZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvbnQtbWVkaXVtIG1iLTMgdGV4dC1iYXNlXCI+Tm9kZSBEYXRhPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtbm9kZSBbbmdGb3JPZl09XCJkYXRhc2V0Tm9kZXNcIj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0yIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgSURcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibm9kZS5pZFwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1sLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlIExhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW3ZhbHVlXT1cIm5vZGUubGFiZWxcIiBkaXNhYmxlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBHcm91cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFt2YWx1ZV09XCJub2RlLmdyb3VwIHx8ICcnXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gdGV4dC1iYXNlXCI+Tm9kZSBPcHRpb25zPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+U2V0IHRoZSBvcHRpb25zIGZvciB0aGlzIG5vZGUuPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJub2RlLm9wdGlvbnMudW5zaGlmdCh7fSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkIE5vZGUgT3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1ub2RlT3B0aW9uIFtuZ0Zvck9mXT1cIm5vZGUub3B0aW9uc1wiIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJub2RlT3B0aW9uLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+LS0gU2VsZWN0IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF2YWlsYWJsZU5vZGVPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIl8uZmluZChub2RlLm9wdGlvbnMsIHtrZXk6IG9wdGlvbn0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cIm9wdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ufX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb24gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5vZGVPcHRpb24ua2V5ICYmIHZpc05ldHdvcmtPcHRpb25zLm5vZGVzW25vZGVPcHRpb24ua2V5XS50eXBlICE9PSAnYm9vbGVhbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbdHlwZV09XCJ2aXNOZXR3b3JrT3B0aW9ucy5ub2Rlc1tub2RlT3B0aW9uLmtleV0udHlwZVwiIFsobmdNb2RlbCldPVwibm9kZU9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwibm9kZU9wdGlvbi5rZXkgJiYgdmlzTmV0d29ya09wdGlvbnMubm9kZXNbbm9kZU9wdGlvbi5rZXldLnR5cGUgPT09ICdib29sZWFuJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cIm5vZGVPcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ0cnVlXCI+VHJ1ZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZhbHNlXCI+RmFsc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly92aXNqcy5naXRodWIuaW8vdmlzLW5ldHdvcmsvZG9jcy9uZXR3b3JrL25vZGVzLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBmbGV4IGl0ZW1zLWNlbnRlciBob3Zlcjp1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIG9wdGlvbnMgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cImgtMyB3LTMgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEzLjUgNkg1LjI1QTIuMjUgMi4yNSAwIDAgMCAzIDguMjV2MTAuNUEyLjI1IDIuMjUgMCAwIDAgNS4yNSAyMWgxMC41QTIuMjUgMi4yNSAwIDAgMCAxOCAxOC43NVYxMC41bS0xMC41IDZMMjEgM20wIDBoLTUuMjVNMjEgM3Y1LjI1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwibm9kZS5vcHRpb25zLnNwbGljZShpLCAxKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xlYXI8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkVkZ2VzXCIgKm5nSWY9XCJkYXNoYm9hcmRJdGVtVHlwZS50eXBlID09PSAnbmV0d29yaycgJiYgZGF0YXNldEVkZ2VzLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkVkZ2UgT3B0aW9uczwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyBmb250LW1lZGl1bSB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZpbmUgdGhlIG9wdGlvbnMgZm9yIGVhY2ggbm9kZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtMSB3LTEvMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgYmctd2hpdGUgcC00IGJvcmRlciByb3VuZGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9udC1tZWRpdW0gdGV4dC1iYXNlXCI+RWRnZSBPcHRpb25zPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+VGhlc2Ugb3B0aW9ucyB3aWxsIGJlIGFwcGxpZWQgdG8gYWxsIGVkZ2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VkIG9uIHRoZSBjb2x1bW4gb3IgY3VzdG9tIHZhbHVlIHByb3ZpZGVkLjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkT3B0aW9uKCdnbG9iYWxFZGdlT3B0aW9ucycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBFZGdlIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtZWRnZU9wdGlvbiBbbmdGb3JPZl09XCJuZXR3b3JrRGF0YS5nbG9iYWxFZGdlT3B0aW9uc1wiIGxldC1pPWluZGV4PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJlZGdlT3B0aW9uLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidW5kZWZpbmVkXCI+LS0gU2VsZWN0IE9wdGlvbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF2YWlsYWJsZUVkZ2VPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIl8uZmluZChuZXR3b3JrRGF0YS5nbG9iYWxFZGdlT3B0aW9ucywge2tleTogb3B0aW9ufSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwib3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb259fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+Jm5ic3A7PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSBDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJ3LWZ1bGxcIiBtYXROYXRpdmVDb250cm9sIFsobmdNb2RlbCldPVwiZWRnZU9wdGlvbi5jb2x1bW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVPcHRpb25zKGVkZ2VPcHRpb24sICdkYXRhc2V0RWRnZXMnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgT3B0aW9uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIChlZGdlRGF0YXNldCAmJiBlZGdlRGF0YXNldC5jb2x1bW5zKSA/IGVkZ2VEYXRhc2V0LmNvbHVtbnMgOiBkYXRhc2V0LmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXN0b20gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJlZGdlT3B0aW9uLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5lZGdlc1tlZGdlT3B0aW9uLmtleV0udHlwZSAhPT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cInZpc05ldHdvcmtPcHRpb25zLmVkZ2VzW2VkZ2VPcHRpb24ua2V5XS50eXBlXCIgWyhuZ01vZGVsKV09XCJlZGdlT3B0aW9uLnZhbHVlXCIgKGNoYW5nZSk9XCJ1cGRhdGVPcHRpb25zKGVkZ2VPcHRpb24sICdkYXRhc2V0RWRnZXMnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJlZGdlT3B0aW9uLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5lZGdlc1tlZGdlT3B0aW9uLmtleV0udHlwZSA9PT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImVkZ2VPcHRpb24udmFsdWVcIiAoY2hhbmdlKT1cInVwZGF0ZU9wdGlvbnMoZWRnZU9wdGlvbiwgJ2RhdGFzZXRFZGdlcycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInRydWVcIj5UcnVlPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cImZhbHNlXCI+RmFsc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBmb250LW5vcm1hbCB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImh0dHBzOi8vdmlzanMuZ2l0aHViLmlvL3Zpcy1uZXR3b3JrL2RvY3MvbmV0d29yay9ub2Rlcy5odG1sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIiBjbGFzcz1cInRleHQtc2Vjb25kYXJ5IGZsZXggaXRlbXMtY2VudGVyIGhvdmVyOnVuZGVybGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIG9wdGlvbnMgZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBmaWxsPVwibm9uZVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIGNsYXNzPVwiaC0zIHctMyBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBkPVwiTTEzLjUgNkg1LjI1QTIuMjUgMi4yNSAwIDAgMCAzIDguMjV2MTAuNUEyLjI1IDIuMjUgMCAwIDAgNS4yNSAyMWgxMC41QTIuMjUgMi4yNSAwIDAgMCAxOCAxOC43NVYxMC41bS0xMC41IDZMMjEgM20wIDBoLTUuMjVNMjEgM3Y1LjI1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwibmV0d29ya0RhdGEuZ2xvYmFsRWRnZU9wdGlvbnMuc3BsaWNlKGksIDEpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtMSB3LTEvMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgYmctd2hpdGUgcC00IGJvcmRlciByb3VuZGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb250LW1lZGl1bSBtYi0zIHRleHQtYmFzZVwiPkVkZ2UgRGF0YTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LWVkZ2UgW25nRm9yT2ZdPVwiZGF0YXNldEVkZ2VzXCI+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbXItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGcm9tIE5vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW3ZhbHVlXT1cImVkZ2UuZnJvbVwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleC0xIG1iLTIgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbyBOb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFt2YWx1ZV09XCJlZGdlLnRvXCIgZGlzYWJsZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0IGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb250LW1lZGl1bSB0ZXh0LWJhc2VcIj5FZGdlIE9wdGlvbnM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC14cyB0ZXh0LWdyYXktNTAwXCI+U2V0IHRoZSBvcHRpb25zIGZvciB0aGlzIGVkZ2UuPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cImVkZ2Uub3B0aW9ucy51bnNoaWZ0KHt9KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBFZGdlIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LWVkZ2VPcHRpb24gW25nRm9yT2ZdPVwiZWRnZS5vcHRpb25zXCIgbGV0LWk9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXgtMSBtYi0yIG1yLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInctZnVsbFwiIG1hdE5hdGl2ZUNvbnRyb2wgWyhuZ01vZGVsKV09XCJlZGdlT3B0aW9uLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgT3B0aW9uIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGF2YWlsYWJsZUVkZ2VPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJfLmZpbmQoZWRnZS5vcHRpb25zLCB7a2V5OiBvcHRpb259KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwib3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ufX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPiZuYnNwOzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4LTEgbWItMiBtbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb24gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJlZGdlT3B0aW9uLmtleSAmJiB2aXNOZXR3b3JrT3B0aW9ucy5lZGdlc1tlZGdlT3B0aW9uLmtleV0udHlwZSAhPT0gJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFt0eXBlXT1cInZpc05ldHdvcmtPcHRpb25zLmVkZ2VzW2VkZ2VPcHRpb24ua2V5XS50eXBlXCIgWyhuZ01vZGVsKV09XCJlZGdlT3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImVkZ2VPcHRpb24ua2V5ICYmIHZpc05ldHdvcmtPcHRpb25zLmVkZ2VzW2VkZ2VPcHRpb24ua2V5XS50eXBlID09PSAnYm9vbGVhbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwiZWRnZU9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJ0cnVlXCI+VHJ1ZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJmYWxzZVwiPkZhbHNlPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgZm9udC1ub3JtYWwgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9XCJodHRwczovL3Zpc2pzLmdpdGh1Yi5pby92aXMtbmV0d29yay9kb2NzL25ldHdvcmsvZWRnZXMuaHRtbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBmbGV4IGl0ZW1zLWNlbnRlciBob3Zlcjp1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRnZSBvcHRpb25zIGRvY3VtZW50YXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBjbGFzcz1cImgtMyB3LTMgbWwtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgZD1cIk0xMy41IDZINS4yNUEyLjI1IDIuMjUgMCAwIDAgMyA4LjI1djEwLjVBMi4yNSAyLjI1IDAgMCAwIDUuMjUgMjFoMTAuNUEyLjI1IDIuMjUgMCAwIDAgMTggMTguNzVWMTAuNW0tMTAuNSA2TDIxIDNtMCAwaC01LjI1TTIxIDN2NS4yNVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cIndhcm5cIiAoY2xpY2spPVwiZWRnZS5vcHRpb25zLnNwbGljZShpLCAxKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNsZWFyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJBbGVydFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNhblNldEFsZXJ0c1wiIGNsYXNzPVwicHgtNCBzbTpweC02IGxnOnB4LTggbXQtMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtOCBib3JkZXItbC00IGJvcmRlci15ZWxsb3ctNDAwIGJnLXllbGxvdy01MCBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LXNocmluay0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImgtNSB3LTUgdGV4dC15ZWxsb3ctNDAwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTguNDg1IDIuNDk1Yy42NzMtMS4xNjcgMi4zNTctMS4xNjcgMy4wMyAwbDYuMjggMTAuODc1Yy42NzMgMS4xNjctLjE3IDIuNjI1LTEuNTE2IDIuNjI1SDMuNzJjLTEuMzQ3IDAtMi4xODktMS40NTgtMS41MTUtMi42MjVMOC40ODUgMi40OTV6TTEwIDVhLjc1Ljc1IDAgMDEuNzUuNzV2My41YS43NS43NSAwIDAxLTEuNSAwdi0zLjVBLjc1Ljc1IDAgMDExMCA1em0wIDlhMSAxIDAgMTAwLTIgMSAxIDAgMDAwIDJ6XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1sLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQtc20gdGV4dC15ZWxsb3ctNzAwIG1iLTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGFzaGJvYXJkIEFsZXJ0cyBhcmUgcmVzZXJ2ZWQgZm9yIG91ciBBY2NyZWRpdGVkIHVzZXJzLiBQbGVhc2UgPGEgY2xhc3M9XCJmb250LW1lZGl1bSB0ZXh0LXllbGxvdy03MDAgdW5kZXJsaW5lIGhvdmVyOnRleHQteWVsbG93LTYwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHJlZj1cImh0dHBzOi8vZG5zcmYub3JnL2pvaW5pbmctb3B0aW9ucy9pbmRleC5odG1sXCI+cmV2aWV3IG91ciBUaWVyczwvYT4gdG8gZmluZCBvdXQgbW9yZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJjYW5TZXRBbGVydHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzaG93QWxlcnRXYXJuaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJiZy13aGl0ZSBzaGFkb3cgc206cm91bmRlZC1sZyBhYnNvbHV0ZSB0b3AtNCBsZWZ0LTAgcmlnaHQtMCB3LTk2IG14LWF1dG8gei0yMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC00IHB5LTUgc206cC02IGJnLWdyYXktNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwidGV4dC1sZyBsZWFkaW5nLTYgZm9udC1tZWRpdW0gdGV4dC1ncmF5LTkwMFwiIGlkPVwicmVuZXctc3Vic2NyaXB0aW9uLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUdXJuIG9uIERhc2hib2FyZCBBbGVydHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgc206ZmxleCBzbTppdGVtcy1zdGFydCBzbTpqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYXgtdy14bCB0ZXh0LXNtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD1cInJlbmV3LXN1YnNjcmlwdGlvbi1kZXNjcmlwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGVydHMgZm9yIHRoaXMgZGFzaGJvYXJkIGFyZSBjdXJyZW50bHkgPGI+b2ZmPC9iPi4gU2xpZGUgdGhlIHRvZ2dsZSB0byB0dXJuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW0gb24gYW5kIHN0YXJ0IHJlY2VpdmluZyBub3RpZmljYXRpb25zLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTUgc206bXQtMCBzbTptbC02IHNtOmZsZXgtc2hyaW5rLTAgc206ZmxleCBzbTppdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZSBbKG5nTW9kZWwpXT1cImRhc2hib2FyZC5hbGVydHNFbmFibGVkXCI+PC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gKGNsaWNrKT1cInNob3dBbGVydFdhcm5pbmcgPSBmYWxzZVwiPkNsb3NlPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsnZmlsdGVyIGJsdXItc20nOiBzaG93QWxlcnRXYXJuaW5nfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC02IHB5LTMgYmctd2hpdGUgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZDpmbGV4IG1kOml0ZW1zLWNlbnRlciBtZDpqdXN0aWZ5LWJldHdlZW4gbWQ6c3BhY2UteC01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMS41XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMSBjbGFzcz1cInRleHQteGwgZm9udC1ib2xkIHRleHQtZ3JheS05MDAgbWItMFwiPkFsZXJ0IFNldHRpbmdzPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIGZvbnQtbWVkaXVtIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyZSBhbGVydHMgYW5kIG5vdGlmaWNhdGlvbnMgZm9yIHRoaXMgd2lkZ2V0LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sLXJldmVyc2UganVzdGlmeS1zdHJldGNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cImVkaXRBbGVydChudWxsKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV3IEFsZXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwibWluLXctZnVsbCBib3JkZXItc2VwYXJhdGVcIiBzdHlsZT1cImJvcmRlci1zcGFjaW5nOiAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UgJiYgZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cyAmJiBkYXNoYm9hcmREYXRhc2V0SW5zdGFuY2UuYWxlcnRzLmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQgY2xhc3M9XCJiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3RpY2t5IHRvcC0wIHotMTAgYm9yZGVyLWIgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktNTAgYmctb3BhY2l0eS03NSBweS0zLjUgcHgtNCB0ZXh0LWxlZnQgdGV4dC14cyBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgYmFja2Ryb3AtYmx1ciBiYWNrZHJvcC1maWx0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGVydFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0xMCBib3JkZXItYiBib3JkZXItZ3JheS0zMDAgYmctZ3JheS01MCBiZy1vcGFjaXR5LTc1IHB5LTMuNSBweC00IHRleHQtbGVmdCB0ZXh0LXhzIGZvbnQtc2VtaWJvbGQgdGV4dC1ncmF5LTkwMCBiYWNrZHJvcC1ibHVyIGJhY2tkcm9wLWZpbHRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3RpY2t5IHRvcC0wIHotMTAgYm9yZGVyLWIgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktNTAgYmctb3BhY2l0eS03NSBweS0zLjUgcHgtNCBiYWNrZHJvcC1ibHVyIGJhY2tkcm9wLWZpbHRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3Itb25seVwiPkVkaXQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJiZy13aGl0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IGFsZXJ0IG9mIGRhc2hib2FyZERhdGFzZXRJbnN0YW5jZS5hbGVydHM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndoaXRlc3BhY2Utbm93cmFwIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMCBweS0yIHB4LTQgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktOTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3thbGVydC50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwid2hpdGVzcGFjZS1ub3dyYXAgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwIHB5LTIgcHgtNCB0ZXh0LXNtIHRleHQtZ3JheS01MDAgY2FwaXRhbGl6ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJnZXRBbGVydERldGFpbHMoYWxlcnQpXCI+PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInJlbGF0aXZlIHdoaXRlc3BhY2Utbm93cmFwIGJvcmRlci1iIGJvcmRlci1ncmF5LTIwMCBweS0yIHB4LTQgdGV4dC1yaWdodCB0ZXh0LXNtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsaWduLWNlbnRlciBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cImVkaXRBbGVydChhbGVydCwgaSlcIj4gRWRpdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwid2FyblwiIChjbGljayk9XCJkZWxldGVBbGVydChpKVwiPiBEZWxldGU8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC00XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlICYmICghZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cyB8fCAhZGFzaGJvYXJkRGF0YXNldEluc3RhbmNlLmFsZXJ0cy5sZW5ndGgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJlZGl0QWxlcnQobnVsbClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVsYXRpdmUgYmxvY2sgdy1mdWxsIGJvcmRlci0yIGJvcmRlci1ncmF5LTMwMCBib3JkZXItZGFzaGVkIHJvdW5kZWQtbGcgcC0xMiB0ZXh0LWNlbnRlciBob3Zlcjpib3JkZXItZ3JheS00MDAgZm9jdXM6b3V0bGluZS1ub25lXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBpbmxpbmUtYmxvY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJteC1hdXRvIHRleHQtNnhsIGgtMTQgdy0yMCB0ZXh0LWdyYXktMzAwXCI+bm90aWZpY2F0aW9uc19hY3RpdmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJpZ2h0LTAgYm90dG9tLTAgYWJzb2x1dGUgaC04IHctOCB0ZXh0LWdyYXktNDAwXCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCI0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGQ9XCJNMTIgNHYxNm04LThINFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm10LTIgYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktOTAwXCI+Q3JlYXRlIE5ldyBBbGVydDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgPC9yc3otbGF5b3V0PlxuXG48L2Rpdj5cblxuPGRpdiBjbGFzcz1cImNvbmZpZ3VyZS1mb290ZXJcIj5cbiAgICA8ZGl2PjwvZGl2PlxuICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJzYXZlRGFzaGJvYXJkKClcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xXCI+Y2hldnJvbl9sZWZ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIEJhY2sgdG8gRGFzaGJvYXJkXG4gICAgICAgIDwvZGl2PlxuICAgIDwvYnV0dG9uPlxuPC9kaXY+XG4iXX0=
|