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.
Files changed (184) hide show
  1. package/fesm2022/ng-kinintel.mjs +11874 -0
  2. package/fesm2022/ng-kinintel.mjs.map +1 -0
  3. package/index.d.ts +2818 -5
  4. package/package.json +6 -14
  5. package/esm2020/lib/components/alert-groups/alert-groups.component.mjs +0 -76
  6. package/esm2020/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.mjs +0 -83
  7. package/esm2020/lib/components/dashboard-editor/configure-item/configure-item.component.mjs +0 -853
  8. package/esm2020/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.mjs +0 -56
  9. package/esm2020/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.mjs +0 -114
  10. package/esm2020/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.mjs +0 -163
  11. package/esm2020/lib/components/dashboard-editor/configure-item/vis-network-options.json +0 -135
  12. package/esm2020/lib/components/dashboard-editor/dashboard-editor.component.mjs +0 -580
  13. package/esm2020/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.mjs +0 -15
  14. package/esm2020/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.mjs +0 -50
  15. package/esm2020/lib/components/dashboard-editor/item-component/item-component.component.mjs +0 -1226
  16. package/esm2020/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.mjs +0 -111
  17. package/esm2020/lib/components/dashboards/dashboards.component.mjs +0 -163
  18. package/esm2020/lib/components/dashboards/view-dashboard/view-dashboard.component.mjs +0 -429
  19. package/esm2020/lib/components/data-explorer/change-source-warning/change-source-warning.component.mjs +0 -20
  20. package/esm2020/lib/components/data-explorer/data-explorer.component.mjs +0 -243
  21. package/esm2020/lib/components/data-explorer/export-data/export-data.component.mjs +0 -62
  22. package/esm2020/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.mjs +0 -70
  23. package/esm2020/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.mjs +0 -190
  24. package/esm2020/lib/components/data-picker/data-picker.component.mjs +0 -79
  25. package/esm2020/lib/components/data-search/data-search.component.mjs +0 -11
  26. package/esm2020/lib/components/data-sharing-invite/data-sharing-invite.component.mjs +0 -52
  27. package/esm2020/lib/components/dataset/create-dataset/create-dataset.component.mjs +0 -47
  28. package/esm2020/lib/components/dataset/dataset-editor/available-columns/available-columns.component.mjs +0 -28
  29. package/esm2020/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.mjs +0 -344
  30. package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.mjs +0 -80
  31. package/esm2020/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.mjs +0 -54
  32. package/esm2020/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.mjs +0 -67
  33. package/esm2020/lib/components/dataset/dataset-editor/dataset-editor.component.mjs +0 -1134
  34. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.mjs +0 -201
  35. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.mjs +0 -25
  36. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.mjs +0 -72
  37. package/esm2020/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.mjs +0 -62
  38. package/esm2020/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.mjs +0 -41
  39. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.mjs +0 -78
  40. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.mjs +0 -39
  41. package/esm2020/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.mjs +0 -75
  42. package/esm2020/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.mjs +0 -107
  43. package/esm2020/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.mjs +0 -20
  44. package/esm2020/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.mjs +0 -20
  45. package/esm2020/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.mjs +0 -58
  46. package/esm2020/lib/components/dataset/dataset-editor/share-query/share-query.component.mjs +0 -110
  47. package/esm2020/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.mjs +0 -20
  48. package/esm2020/lib/components/dataset/dataset.component.mjs +0 -294
  49. package/esm2020/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.mjs +0 -130
  50. package/esm2020/lib/components/datasource/create-datasource/api-access/api-access.component.mjs +0 -132
  51. package/esm2020/lib/components/datasource/create-datasource/create-datasource.component.mjs +0 -729
  52. package/esm2020/lib/components/datasource/create-datasource/import-data/import-data.component.mjs +0 -146
  53. package/esm2020/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.mjs +0 -165
  54. package/esm2020/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.mjs +0 -145
  55. package/esm2020/lib/components/datasource/datasource.component.mjs +0 -162
  56. package/esm2020/lib/components/datasource/document-datasource/document-datasource.component.mjs +0 -297
  57. package/esm2020/lib/components/export-project/export-project.component.mjs +0 -29
  58. package/esm2020/lib/components/feeds/feed/feed.component.mjs +0 -92
  59. package/esm2020/lib/components/feeds/feeds.component.mjs +0 -145
  60. package/esm2020/lib/components/job-tasks/job-tasks.component.mjs +0 -25
  61. package/esm2020/lib/components/marketplace/marketplace.component.mjs +0 -65
  62. package/esm2020/lib/components/metadata/metadata.component.mjs +0 -65
  63. package/esm2020/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.mjs +0 -113
  64. package/esm2020/lib/components/notification-groups/notification-groups.component.mjs +0 -86
  65. package/esm2020/lib/components/project-picker/project-picker.component.mjs +0 -118
  66. package/esm2020/lib/components/project-settings/project-link-selection/project-link-selection.component.mjs +0 -104
  67. package/esm2020/lib/components/project-settings/project-settings.component.mjs +0 -155
  68. package/esm2020/lib/components/query-caching/edit-query-cache/edit-query-cache.component.mjs +0 -51
  69. package/esm2020/lib/components/query-caching/query-cache-view/query-cache-view.component.mjs +0 -121
  70. package/esm2020/lib/components/query-caching/query-caching.component.mjs +0 -162
  71. package/esm2020/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.mjs +0 -45
  72. package/esm2020/lib/components/shared-with-me/shared-with-me.component.mjs +0 -174
  73. package/esm2020/lib/components/snapshots/snapshots.component.mjs +0 -244
  74. package/esm2020/lib/components/tag-picker/tag-picker.component.mjs +0 -74
  75. package/esm2020/lib/components/task-time-periods/task-time-periods.component.mjs +0 -55
  76. package/esm2020/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.mjs +0 -40
  77. package/esm2020/lib/guards/dashboard-changes.guard.mjs +0 -22
  78. package/esm2020/lib/kinintel-config.mjs +0 -3
  79. package/esm2020/lib/ng-kinintel.module.mjs +0 -437
  80. package/esm2020/lib/objects/action-event.mjs +0 -16
  81. package/esm2020/lib/services/alert.service.mjs +0 -52
  82. package/esm2020/lib/services/dashboard.service.mjs +0 -75
  83. package/esm2020/lib/services/data-processor.service.mjs +0 -56
  84. package/esm2020/lib/services/data-search.service.mjs +0 -36
  85. package/esm2020/lib/services/dataset.service.mjs +0 -187
  86. package/esm2020/lib/services/datasource.service.mjs +0 -93
  87. package/esm2020/lib/services/external.service.mjs +0 -33
  88. package/esm2020/lib/services/feed.service.mjs +0 -50
  89. package/esm2020/lib/services/notification.service.mjs +0 -41
  90. package/esm2020/lib/services/project.service.mjs +0 -130
  91. package/esm2020/lib/services/tag.service.mjs +0 -63
  92. package/esm2020/ng-kinintel.mjs +0 -5
  93. package/esm2020/public-api.mjs +0 -43
  94. package/fesm2015/ng-kinintel.mjs +0 -12182
  95. package/fesm2015/ng-kinintel.mjs.map +0 -1
  96. package/fesm2020/ng-kinintel.mjs +0 -11872
  97. package/fesm2020/ng-kinintel.mjs.map +0 -1
  98. package/lib/components/alert-groups/alert-groups.component.d.ts +0 -30
  99. package/lib/components/alert-groups/edit-alert-group/edit-alert-group.component.d.ts +0 -28
  100. package/lib/components/dashboard-editor/configure-item/configure-item.component.d.ts +0 -256
  101. package/lib/components/dashboard-editor/configure-item/edit-dashboard-alert/edit-dashboard-alert.component.d.ts +0 -16
  102. package/lib/components/dashboard-editor/configure-item/html-documentation/html-documentation.component.d.ts +0 -59
  103. package/lib/components/dashboard-editor/configure-item/table-cell-formatter/table-cell-formatter.component.d.ts +0 -26
  104. package/lib/components/dashboard-editor/dashboard-editor.component.d.ts +0 -85
  105. package/lib/components/dashboard-editor/dashboard-parameter/dashboard-parameter.component.d.ts +0 -8
  106. package/lib/components/dashboard-editor/dashboard-settings/dashboard-settings.component.d.ts +0 -22
  107. package/lib/components/dashboard-editor/item-component/item-component.component.d.ts +0 -264
  108. package/lib/components/dashboard-editor/source-selector-dialog/source-selector-dialog.component.d.ts +0 -30
  109. package/lib/components/dashboards/dashboards.component.d.ts +0 -56
  110. package/lib/components/dashboards/view-dashboard/view-dashboard.component.d.ts +0 -81
  111. package/lib/components/data-explorer/change-source-warning/change-source-warning.component.d.ts +0 -11
  112. package/lib/components/data-explorer/data-explorer.component.d.ts +0 -61
  113. package/lib/components/data-explorer/export-data/export-data.component.d.ts +0 -17
  114. package/lib/components/data-explorer/snapshot-api-access/snapshot-api-access.component.d.ts +0 -25
  115. package/lib/components/data-explorer/snapshot-profile-dialog/snapshot-profile-dialog.component.d.ts +0 -44
  116. package/lib/components/data-picker/data-picker.component.d.ts +0 -32
  117. package/lib/components/data-search/data-search.component.d.ts +0 -5
  118. package/lib/components/data-sharing-invite/data-sharing-invite.component.d.ts +0 -21
  119. package/lib/components/dataset/create-dataset/create-dataset.component.d.ts +0 -17
  120. package/lib/components/dataset/dataset-editor/available-columns/available-columns.component.d.ts +0 -12
  121. package/lib/components/dataset/dataset-editor/dataset-add-join/dataset-add-join.component.d.ts +0 -61
  122. package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-editor/dataset-column-editor.component.d.ts +0 -21
  123. package/lib/components/dataset/dataset-editor/dataset-column-settings/dataset-column-settings.component.d.ts +0 -20
  124. package/lib/components/dataset/dataset-editor/dataset-create-formula/dataset-create-formula.component.d.ts +0 -19
  125. package/lib/components/dataset/dataset-editor/dataset-editor.component.d.ts +0 -131
  126. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter/dataset-filter.component.d.ts +0 -63
  127. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-inclusion/dataset-filter-inclusion.component.d.ts +0 -11
  128. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filter-junction/dataset-filter-junction.component.d.ts +0 -20
  129. package/lib/components/dataset/dataset-editor/dataset-filters/dataset-filters.component.d.ts +0 -16
  130. package/lib/components/dataset/dataset-editor/dataset-name-dialog/dataset-name-dialog.component.d.ts +0 -18
  131. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-add-parameter/dataset-add-parameter.component.d.ts +0 -23
  132. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-type/dataset-parameter-type.component.d.ts +0 -13
  133. package/lib/components/dataset/dataset-editor/dataset-parameter-values/dataset-parameter-values.component.d.ts +0 -22
  134. package/lib/components/dataset/dataset-editor/dataset-summarise/dataset-summarise.component.d.ts +0 -27
  135. package/lib/components/dataset/dataset-editor/move-transformation-confirmation/move-transformation-confirmation.component.d.ts +0 -11
  136. package/lib/components/dataset/dataset-editor/remove-transformation-warning/remove-transformation-warning.component.d.ts +0 -11
  137. package/lib/components/dataset/dataset-editor/save-as-query/save-as-query.component.d.ts +0 -25
  138. package/lib/components/dataset/dataset-editor/share-query/share-query.component.d.ts +0 -41
  139. package/lib/components/dataset/dataset-editor/upstream-changes-confirmation/upstream-changes-confirmation.component.d.ts +0 -11
  140. package/lib/components/dataset/dataset.component.d.ts +0 -74
  141. package/lib/components/datasource/create-datasource/advanced-settings/advanced-settings.component.d.ts +0 -26
  142. package/lib/components/datasource/create-datasource/api-access/api-access.component.d.ts +0 -31
  143. package/lib/components/datasource/create-datasource/create-datasource.component.d.ts +0 -112
  144. package/lib/components/datasource/create-datasource/import-data/import-data.component.d.ts +0 -28
  145. package/lib/components/datasource/create-datasource/import-data/import-wizard/import-wizard.component.d.ts +0 -40
  146. package/lib/components/datasource/create-datasource/tabular-datasource/tabular-datasource.component.d.ts +0 -34
  147. package/lib/components/datasource/datasource.component.d.ts +0 -46
  148. package/lib/components/datasource/document-datasource/document-datasource.component.d.ts +0 -64
  149. package/lib/components/export-project/export-project.component.d.ts +0 -9
  150. package/lib/components/feeds/feed/feed.component.d.ts +0 -30
  151. package/lib/components/feeds/feeds.component.d.ts +0 -47
  152. package/lib/components/job-tasks/job-tasks.component.d.ts +0 -11
  153. package/lib/components/marketplace/marketplace.component.d.ts +0 -42
  154. package/lib/components/metadata/metadata.component.d.ts +0 -24
  155. package/lib/components/notification-groups/edit-notification-group/edit-notification-group.component.d.ts +0 -37
  156. package/lib/components/notification-groups/notification-groups.component.d.ts +0 -28
  157. package/lib/components/project-picker/project-picker.component.d.ts +0 -37
  158. package/lib/components/project-settings/project-link-selection/project-link-selection.component.d.ts +0 -32
  159. package/lib/components/project-settings/project-settings.component.d.ts +0 -40
  160. package/lib/components/query-caching/edit-query-cache/edit-query-cache.component.d.ts +0 -17
  161. package/lib/components/query-caching/query-cache-view/query-cache-view.component.d.ts +0 -35
  162. package/lib/components/query-caching/query-caching.component.d.ts +0 -38
  163. package/lib/components/shared-with-me/feed-api-modal/feed-api-modal.component.d.ts +0 -21
  164. package/lib/components/shared-with-me/shared-with-me.component.d.ts +0 -43
  165. package/lib/components/snapshots/snapshots.component.d.ts +0 -52
  166. package/lib/components/tag-picker/tag-picker.component.d.ts +0 -27
  167. package/lib/components/task-time-periods/task-time-periods.component.d.ts +0 -20
  168. package/lib/components/whitelisted-sql-functions/whitelisted-sql-functions.component.d.ts +0 -17
  169. package/lib/guards/dashboard-changes.guard.d.ts +0 -11
  170. package/lib/kinintel-config.d.ts +0 -10
  171. package/lib/ng-kinintel.module.d.ts +0 -116
  172. package/lib/objects/action-event.d.ts +0 -12
  173. package/lib/services/alert.service.d.ts +0 -17
  174. package/lib/services/dashboard.service.d.ts +0 -25
  175. package/lib/services/data-processor.service.d.ts +0 -18
  176. package/lib/services/data-search.service.d.ts +0 -14
  177. package/lib/services/dataset.service.d.ts +0 -56
  178. package/lib/services/datasource.service.d.ts +0 -34
  179. package/lib/services/external.service.d.ts +0 -12
  180. package/lib/services/feed.service.d.ts +0 -19
  181. package/lib/services/notification.service.d.ts +0 -16
  182. package/lib/services/project.service.d.ts +0 -27
  183. package/lib/services/tag.service.d.ts +0 -19
  184. package/public-api.d.ts +0 -38
@@ -1,729 +0,0 @@
1
- import { Component, Input } from '@angular/core';
2
- import * as lodash from 'lodash';
3
- import { ImportDataComponent } from '../create-datasource/import-data/import-data.component';
4
- import { ApiAccessComponent } from '../create-datasource/api-access/api-access.component';
5
- import { AdvancedSettingsComponent } from '../create-datasource/advanced-settings/advanced-settings.component';
6
- import { ImportWizardComponent } from '../create-datasource/import-data/import-wizard/import-wizard.component';
7
- import { BehaviorSubject } from 'rxjs';
8
- import { CreateDatasetComponent } from '../../dataset/create-dataset/create-dataset.component';
9
- import shortHash from 'short-hash';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/material/legacy-dialog";
12
- import * as i2 from "@angular/router";
13
- import * as i3 from "../../../services/datasource.service";
14
- import * as i4 from "../../../services/dataset.service";
15
- import * as i5 from "@angular/material/legacy-snack-bar";
16
- import * as i6 from "@angular/common";
17
- import * as i7 from "@angular/material/legacy-button";
18
- import * as i8 from "@angular/material/icon";
19
- import * as i9 from "@angular/material/legacy-menu";
20
- import * as i10 from "@angular/forms";
21
- import * as i11 from "@angular/material/legacy-checkbox";
22
- import * as i12 from "@angular/material/legacy-tooltip";
23
- import * as i13 from "../../dataset/dataset-editor/dataset-filters/dataset-filters.component";
24
- const _ = lodash.default;
25
- export class CreateDatasourceComponent {
26
- constructor(dialog, route, datasourceService, datasetService, snackbar, location, router) {
27
- this.dialog = dialog;
28
- this.route = route;
29
- this.datasourceService = datasourceService;
30
- this.datasetService = datasetService;
31
- this.snackbar = snackbar;
32
- this.location = location;
33
- this.router = router;
34
- this.backURL = '/imported-data';
35
- this.reloadURL = 'import-data';
36
- this.namePrefix = '';
37
- this.readonly = false;
38
- this.automaticImportKey = false;
39
- this.hideAPIAccess = false;
40
- this.editColumns = true;
41
- this.filterJunction = {
42
- logic: 'AND',
43
- filters: [{
44
- lhsExpression: '',
45
- rhsExpression: [],
46
- filterType: ''
47
- }],
48
- filterJunctions: []
49
- };
50
- this.datasourceTypes = {
51
- string: 'Text (up to 255 chars)',
52
- mediumstring: 'Medium Text (up to 32767 chars)',
53
- longstring: 'Long Text (more than 32767 chars)',
54
- integer: 'Number (whole number)',
55
- biginteger: 'Number (large number)',
56
- boolean: 'Tick (Yes / No)',
57
- float: 'Decimal number',
58
- date: 'Date',
59
- datetime: 'Date and Time',
60
- pickfromsource: 'Pick From List (using another source)',
61
- json: 'Nested JSON Object'
62
- };
63
- this.rows = [];
64
- this.columns = [
65
- {
66
- title: 'Column 1',
67
- name: 'column_1',
68
- type: 'string'
69
- },
70
- {
71
- title: 'Column 2',
72
- name: 'column_2',
73
- type: 'string'
74
- }
75
- ];
76
- this.selectedItem = {};
77
- this._ = _;
78
- this.showUpload = false;
79
- this.headerRow = false;
80
- this.adds = [];
81
- this.updates = [];
82
- this.deletes = [];
83
- this.invalidItems = [];
84
- this.editMode = false;
85
- this.autoIncrementColumn = false;
86
- this.datasourceUpdate = {
87
- title: '',
88
- instanceImportKey: '',
89
- fields: [],
90
- adds: [],
91
- updates: [],
92
- deletes: []
93
- };
94
- this.offset = 0;
95
- this.limit = 25;
96
- this.page = 1;
97
- this.endOfResults = false;
98
- this.showAutoIncrement = false;
99
- this.selectAll = false;
100
- this.showFilters = false;
101
- this.filterFields = [];
102
- this.sortConfig = null;
103
- this.openSide = new BehaviorSubject(false);
104
- this.Object = Object;
105
- this.isMouseDown = false;
106
- this.startRowIndex = null;
107
- this.startCellIndex = null;
108
- this.endRowIndex = null;
109
- this.endCellIndex = null;
110
- this.selectedCell = null;
111
- // Associative list of pick from datasets used for list selection
112
- this.columnPickFromDatasets = {};
113
- }
114
- ngOnInit() {
115
- this.datasourceInstanceKey = this.route.snapshot.params.key;
116
- if (this.datasourceInstanceKey) {
117
- this.showAutoIncrement = localStorage.getItem(this.datasourceInstanceKey + '_show_id') === 'true';
118
- this.loadDatasource();
119
- }
120
- else {
121
- const dialogRef = this.dialog.open(ImportWizardComponent, {
122
- width: '800px',
123
- height: '900px',
124
- disableClose: true,
125
- data: {
126
- columns: this.columns,
127
- datasourceUpdate: this.datasourceUpdate,
128
- rows: this.rows,
129
- datasourceInstanceKey: this.datasourceInstanceKey,
130
- reloadURL: this.reloadURL,
131
- namePrefix: this.namePrefix,
132
- automaticImportKey: this.automaticImportKey
133
- }
134
- });
135
- dialogRef.afterClosed().subscribe(res => {
136
- if (res === 'closed') {
137
- this.location.back();
138
- }
139
- });
140
- }
141
- }
142
- ngAfterViewInit() {
143
- if (this.sidenavService) {
144
- setTimeout(() => {
145
- this.sidenavService.close();
146
- }, 100);
147
- }
148
- document.addEventListener('mouseup', () => {
149
- this.isMouseDown = false;
150
- });
151
- }
152
- ngOnDestroy() {
153
- if (this.sidenavService) {
154
- this.sidenavService.open();
155
- }
156
- }
157
- clearFilter() {
158
- this.filterJunction = {
159
- logic: 'AND',
160
- filters: [{
161
- lhsExpression: '',
162
- rhsExpression: [],
163
- filterType: ''
164
- }],
165
- filterJunctions: []
166
- };
167
- this.loadDatasource();
168
- }
169
- applyFilter() {
170
- this.loadDatasource();
171
- }
172
- sortColumn(column, direction) {
173
- this.sortConfig = { fieldName: column.name, direction };
174
- this.loadDatasource();
175
- }
176
- updateSelectAll() {
177
- this.rows.map(row => {
178
- row._selected = this.selectAll;
179
- });
180
- }
181
- updateSelected() {
182
- this.selectAll = _.every(this.rows, '_selected');
183
- }
184
- updateAutoIncrementColumn(value) {
185
- if (value) {
186
- this.columns.map(column => {
187
- column.keyField = false;
188
- return column;
189
- });
190
- this.columns.unshift({
191
- title: 'ID',
192
- name: 'id',
193
- type: 'id'
194
- });
195
- }
196
- else {
197
- _.remove(this.columns, { type: 'id' });
198
- }
199
- }
200
- addColumn(index) {
201
- this.selectedItem = {
202
- _tableType: 'column',
203
- type: 'string'
204
- };
205
- if (index > -1) {
206
- this.columns.splice(index, 0, this.selectedItem);
207
- this.selectedItem._index = index;
208
- }
209
- else {
210
- this.columns.push(this.selectedItem);
211
- this.selectedItem._index = this.columns.length - 1;
212
- }
213
- setTimeout(() => {
214
- document.getElementById(this.selectedItem.type + this.selectedItem._index).scrollIntoView();
215
- });
216
- }
217
- import() {
218
- const dialogRef = this.dialog.open(ImportDataComponent, {
219
- width: '800px',
220
- height: '900px',
221
- data: {
222
- columns: this.columns,
223
- datasourceUpdate: this.datasourceUpdate,
224
- rows: this.rows,
225
- datasourceInstanceKey: this.datasourceInstanceKey,
226
- reloadURL: this.reloadURL
227
- }
228
- });
229
- dialogRef.afterClosed().subscribe(res => {
230
- if (res) {
231
- if (!this.selectedCell) {
232
- const rowColIndex = 0;
233
- this.selectedCell = { rowIndex: 0, rowColIndex };
234
- }
235
- if (res.headerRow) {
236
- const columns = [];
237
- res.data[0].forEach(header => {
238
- columns.push({
239
- title: header,
240
- name: _.snakeCase(header),
241
- type: 'string'
242
- });
243
- });
244
- this.columns = columns;
245
- res.data.shift();
246
- this.insertCellData(res.data);
247
- }
248
- else {
249
- this.insertCellData(res.data);
250
- }
251
- }
252
- });
253
- }
254
- async deleteSelectedEntries() {
255
- const message = 'Are you sure you would like to remove all of the selected entries? This action cannot be reversed.';
256
- if (window.confirm(message)) {
257
- const selected = _.filter(this.rows, '_selected');
258
- await this.datasourceService.updateCustomDatasource(this.datasourceInstanceKey, {
259
- title: this.datasourceUpdate.title,
260
- importKey: this.datasourceUpdate.instanceImportKey || '',
261
- fields: this.datasourceUpdate.fields,
262
- adds: [],
263
- updates: [],
264
- deletes: selected
265
- });
266
- window.location.href = this.reloadURL + '/' + this.datasourceInstanceKey;
267
- }
268
- }
269
- addFilter() {
270
- }
271
- advancedSettings() {
272
- const dialogRef = this.dialog.open(AdvancedSettingsComponent, {
273
- width: '800px',
274
- height: '900px',
275
- data: {
276
- datasourceUpdate: this.datasourceUpdate,
277
- datasourceInstanceKey: this.datasourceInstanceKey,
278
- backendURL: this.backendURL,
279
- columns: this.columns,
280
- showAutoIncrement: this.showAutoIncrement
281
- }
282
- });
283
- dialogRef.afterClosed().subscribe(advancedSettings => {
284
- if (advancedSettings) {
285
- this.columns = advancedSettings.columns;
286
- this.datasourceUpdate.indexes = advancedSettings.datasourceUpdate.indexes;
287
- this.showAutoIncrement = advancedSettings.showAutoIncrement;
288
- localStorage.setItem(this.datasourceInstanceKey + '_show_id', String(this.showAutoIncrement));
289
- }
290
- });
291
- }
292
- apiAccess() {
293
- const dialogRef = this.dialog.open(ApiAccessComponent, {
294
- width: '800px',
295
- height: '900px',
296
- data: {
297
- datasourceUpdate: this.datasourceUpdate,
298
- datasourceInstanceKey: this.datasourceInstanceKey,
299
- backendURL: this.backendURL,
300
- columns: this.columns
301
- }
302
- });
303
- dialogRef.afterClosed().subscribe(res => {
304
- });
305
- }
306
- selectColumn(column, index) {
307
- if (this.editColumns && !column.autoIncrement) {
308
- this.selectedCell = null;
309
- document.querySelectorAll('.datasource-table .bg-indigo-50').forEach(element => {
310
- element.classList.remove('bg-indigo-50');
311
- });
312
- if (index === this.selectedItem._index) {
313
- this.selectedItem = {};
314
- }
315
- else {
316
- column._tableType = 'column';
317
- column._index = index;
318
- if (!column.previousName) {
319
- column.previousName = column.name;
320
- }
321
- this.selectedItem = column;
322
- this.removeCellFocusBorder();
323
- }
324
- }
325
- }
326
- deleteColumn(index) {
327
- this.columns.splice(index, 1);
328
- }
329
- addRow(index) {
330
- const row = {};
331
- this.columns.forEach(column => {
332
- row[column.name] = null;
333
- });
334
- if (index > -1) {
335
- this.rows.splice(index, 0, row);
336
- this.adds.push(index);
337
- }
338
- else {
339
- this.rows.push(row);
340
- this.adds.push(this.rows.length - 1);
341
- }
342
- setTimeout(() => {
343
- const tableWrapper = document.getElementById('tableWrapper');
344
- tableWrapper.scrollTop = tableWrapper.scrollHeight;
345
- }, 0);
346
- }
347
- deleteRow(rowIndex) {
348
- const inAdds = this.adds.indexOf(rowIndex);
349
- if (inAdds > -1) {
350
- this.rows.splice(rowIndex, 1);
351
- this.adds.pop();
352
- }
353
- else {
354
- this.deletes.push(rowIndex);
355
- }
356
- const inUpdates = this.updates.indexOf(rowIndex);
357
- if (inUpdates > -1) {
358
- this.updates.splice(inUpdates, 1);
359
- }
360
- }
361
- focusCell(event, rowIndex, rowColIndex) {
362
- this.selectedCell = { rowIndex, rowColIndex };
363
- this.removeCellFocusBorder();
364
- event.target.parentElement.classList.add('border', 'border-blue-500');
365
- }
366
- blurCell() {
367
- this.selectedCell = null;
368
- this.removeCellFocusBorder();
369
- }
370
- clearCell(rowIndex, rowColIndex) {
371
- const columnName = this.columns[rowColIndex].name;
372
- this.rows[rowIndex][columnName] = '';
373
- if (this.adds.indexOf(rowIndex) === -1) {
374
- this.updates.push(rowIndex);
375
- }
376
- }
377
- updateField(field, rowIndex, event) {
378
- if (this.adds.indexOf(rowIndex) === -1) {
379
- if (this.updates.indexOf(rowIndex) === -1) {
380
- this.updates.push(rowIndex);
381
- }
382
- }
383
- // Handle implicit false values for booleans and implicit nulls for other fields
384
- if (field.type == 'boolean') {
385
- this.rows[rowIndex][field.name] = event.target.checked;
386
- }
387
- else {
388
- if (this.rows[rowIndex][field.name] === '')
389
- this.rows[rowIndex][field.name] = null;
390
- }
391
- this.editMode = true;
392
- }
393
- updateColumnName() {
394
- this.selectedItem.name = _.snakeCase(this.selectedItem.title);
395
- this.rows.map(row => {
396
- row[this.selectedItem.name] = row[this.selectedItem.previousName] || '';
397
- if (row[this.selectedItem.previousName]) {
398
- delete row[this.selectedItem.previousName];
399
- }
400
- return row;
401
- });
402
- }
403
- enterCell(rowIndex, rowColIndex, event) {
404
- const row = {};
405
- let rowElement = null;
406
- let rowElementIndex;
407
- this.columns.forEach(column => {
408
- row[column.name] = '';
409
- });
410
- if (rowIndex === this.rows.length - 1) {
411
- this.rows.push(row);
412
- rowElementIndex = this.rows.length - 1;
413
- this.adds.push(this.rows.length - 1);
414
- }
415
- else {
416
- rowElementIndex = rowIndex + 1;
417
- }
418
- setTimeout(() => {
419
- rowElement = document.querySelectorAll('.table-rows').item(rowElementIndex);
420
- const rowCell = rowElement.querySelectorAll('.row-cell').item(this.showAutoIncrement ? rowColIndex + 1 : rowColIndex);
421
- rowCell.querySelectorAll('.cell-input').item(0).focus();
422
- }, 0);
423
- }
424
- async save(exit = false) {
425
- if (!this.datasourceUpdate.title) {
426
- window.alert('Please enter a title for this Datasource.');
427
- return;
428
- }
429
- if (!_.find(this.columns, { keyField: true }) &&
430
- !_.find(this.columns, { type: 'id' })) {
431
- window.alert('Please select one of your fields as the "Unique Key"');
432
- return;
433
- }
434
- this.datasourceUpdate.fields = this.columns.map(column => {
435
- if (column.name === column.previousName) {
436
- delete column.previousName;
437
- }
438
- return column;
439
- });
440
- const changes = ['adds', 'updates', 'deletes'];
441
- changes.forEach(change => {
442
- this.datasourceUpdate[change] = _.map(_.uniq(this[change]), rowIndex => {
443
- return this.rows[rowIndex];
444
- });
445
- });
446
- if (this.namePrefix && !this.datasourceUpdate.title.includes(this.namePrefix)) {
447
- this.datasourceUpdate.title = this.namePrefix + this.datasourceUpdate.title;
448
- }
449
- // Reset invalid items
450
- this.invalidItems = [];
451
- if (!this.datasourceInstanceKey) {
452
- if (this.automaticImportKey) {
453
- this.datasourceUpdate.importKey = shortHash(Date.now().toString());
454
- }
455
- await this.datasourceService.createCustomDatasource(this.datasourceUpdate).then(key => {
456
- if (!exit) {
457
- window.location.href = this.reloadURL + '/' + key;
458
- }
459
- return true;
460
- }).catch(err => {
461
- const errorCode = (err.error && err.error.sqlStateCode) ? err.error.sqlStateCode : 0;
462
- this.displayError(errorCode);
463
- });
464
- }
465
- else {
466
- this.datasourceUpdate.importKey = this.datasourceUpdate.instanceImportKey;
467
- await this.datasourceService.updateCustomDatasource(this.datasourceInstanceKey, this.datasourceUpdate)
468
- .then(async (result) => {
469
- if (result && result.rejected && result.rejected > 0) {
470
- this.snackbar.open('There were validation problems with one or more of your rows - see highlighted cells below', null, {
471
- duration: 5000,
472
- verticalPosition: 'top'
473
- });
474
- const invalidAddRows = _.map(result.validationErrors.add || [], 'itemNumber');
475
- for (let i = this.adds.length - 1; i >= 0; i--) {
476
- if (invalidAddRows.includes(i)) {
477
- this.invalidItems[this.adds[i]] = _.find(result.validationErrors.add, { itemNumber: i }).validationErrors;
478
- }
479
- }
480
- const invalidUpdateRows = _.map(result.validationErrors.update || [], 'itemNumber');
481
- for (let i = this.updates.length - 1; i >= 0; i--) {
482
- if (invalidUpdateRows.includes(i)) {
483
- this.invalidItems[this.updates[i]] = _.find(result.validationErrors.update, { itemNumber: i }).validationErrors;
484
- }
485
- }
486
- }
487
- else {
488
- this.adds = [];
489
- this.updates = [];
490
- this.deletes = [];
491
- await this.loadDatasource();
492
- }
493
- return true;
494
- })
495
- .catch(err => {
496
- console.log('ERROR', err);
497
- const errorCode = (err.error && err.error.sqlStateCode) ? err.error.sqlStateCode : 0;
498
- this.displayError(errorCode);
499
- });
500
- }
501
- if (exit) {
502
- return this.router.navigate([this.backURL]);
503
- }
504
- }
505
- cancelChanges() {
506
- this.adds = [];
507
- this.updates = [];
508
- this.deletes = [];
509
- this.loadDatasource();
510
- }
511
- setTypeConfig() {
512
- if (!this.selectedItem.typeConfig || Array.isArray(this.selectedItem.typeConfig)) {
513
- this.selectedItem.typeConfig = {};
514
- }
515
- }
516
- deleteSelectedColumn() {
517
- this.columns.splice(this.selectedItem._index, 1);
518
- }
519
- pageSizeChange(value) {
520
- this.limit = value;
521
- this.loadDatasource();
522
- }
523
- increaseOffset() {
524
- this.page = this.page + 1;
525
- this.offset = (this.limit * this.page) - this.limit;
526
- this.loadDatasource();
527
- }
528
- decreaseOffset() {
529
- this.page = this.page <= 1 ? 1 : this.page - 1;
530
- this.offset = (this.limit * this.page) - this.limit;
531
- this.loadDatasource();
532
- }
533
- // Get input type for field
534
- inputTypeForField(field) {
535
- switch (field.type) {
536
- case 'integer':
537
- case 'float':
538
- return 'number';
539
- case 'boolean':
540
- return 'checkbox';
541
- case 'date':
542
- return 'date';
543
- case 'datetime':
544
- return 'datetime-local';
545
- default:
546
- return 'text';
547
- }
548
- }
549
- loadDatasource() {
550
- if (this.datasourceInstanceKey) {
551
- // If we have a filter in use, apply it to the next load...
552
- const transformationInstances = [];
553
- if (this.filterJunction.filterJunctions.length || this.filterJunction.filters[0].filterType) {
554
- transformationInstances.push({ type: 'filter', config: this.filterJunction });
555
- }
556
- if (this.sortConfig) {
557
- transformationInstances.push({ type: 'multisort', config: { sorts: [this.sortConfig] } });
558
- }
559
- const evaluatedDatasource = {
560
- key: this.datasourceInstanceKey,
561
- transformationInstances,
562
- parameterValues: {},
563
- offset: this.offset,
564
- limit: this.limit
565
- };
566
- this.datasourceService.evaluateDatasource(evaluatedDatasource).then((res) => {
567
- let jsonColumns = [];
568
- this.columns = res.columns.map(column => {
569
- column.previousName = column.name;
570
- if (column.type === 'pickfromsource') {
571
- if (!this.columnPickFromDatasets[column.name]) {
572
- this.populateColumnPickFrom(column);
573
- }
574
- }
575
- else if (column.type === 'json') {
576
- jsonColumns.push(column.name);
577
- }
578
- return column;
579
- });
580
- this.filterFields = _.map(this.columns, column => {
581
- return {
582
- title: column.title,
583
- name: column.name
584
- };
585
- });
586
- this.rows = res.allData;
587
- // If JSON Columns, ensure we deserialise JSON values
588
- if (jsonColumns.length) {
589
- this.rows.forEach(row => {
590
- jsonColumns.forEach(jsonColumn => {
591
- if (row[jsonColumn] || null)
592
- row[jsonColumn] = JSON.stringify(row[jsonColumn]);
593
- });
594
- });
595
- }
596
- this.endOfResults = this.rows.length < this.limit;
597
- this.datasourceUpdate.title = res.instanceTitle;
598
- this.datasourceUpdate.instanceImportKey = res.instanceImportKey;
599
- this.datasourceUpdate.indexes = res.indexes;
600
- this.datasourceUpdate.adds = [];
601
- this.datasourceUpdate.updates = [];
602
- this.datasourceUpdate.deletes = [];
603
- this.autoIncrementColumn = _.some(this.columns, { type: 'id' });
604
- this.selectAll = false;
605
- });
606
- }
607
- this.editMode = false;
608
- }
609
- selectCell(rowIndex, cellIndex) {
610
- let rowStart, rowEnd, cellStart, cellEnd;
611
- if (rowIndex < this.startRowIndex) {
612
- rowStart = rowIndex;
613
- rowEnd = this.startRowIndex;
614
- }
615
- else {
616
- rowStart = this.startRowIndex;
617
- rowEnd = rowIndex;
618
- }
619
- if (cellIndex < this.startCellIndex) {
620
- cellStart = cellIndex;
621
- cellEnd = this.startCellIndex;
622
- }
623
- else {
624
- cellStart = this.startCellIndex;
625
- cellEnd = cellIndex;
626
- }
627
- for (let i = rowStart; i <= rowEnd; i++) {
628
- const rowElement = document.querySelectorAll('.table-rows').item(i);
629
- const rowCells = rowElement.querySelectorAll('td');
630
- for (let j = cellStart; j <= cellEnd; j++) {
631
- rowCells.item(j).classList.add('bg-indigo-50');
632
- }
633
- }
634
- }
635
- removeCellFocusBorder() {
636
- document.querySelectorAll('.input-wrapper.border-blue-500').forEach(element => {
637
- element.classList.remove('border-blue-500');
638
- });
639
- }
640
- insertCellData(data) {
641
- const row = {};
642
- this.columns.forEach(column => {
643
- row[column.name] = '';
644
- });
645
- let startIndex = this.selectedCell.rowIndex;
646
- while (this.rows.length < (data.length + this.selectedCell.rowIndex)) {
647
- this.rows.push(_.clone(row));
648
- this.deletes.splice(startIndex, 1);
649
- this.updates.splice(startIndex, 1);
650
- this.adds.splice(startIndex, 1);
651
- this.adds.push(startIndex);
652
- startIndex++;
653
- }
654
- let rowIndex = 0;
655
- for (let i = this.selectedCell.rowIndex; i < (this.selectedCell.rowIndex + data.length); i++) {
656
- let valIndex = 0;
657
- const values = _.values(data[rowIndex]);
658
- for (let j = this.selectedCell.rowColIndex; j < (values.length + this.selectedCell.rowColIndex); j++) {
659
- if (this.columns[j]) {
660
- this.rows[i][this.columns[j].name] = values[valIndex] || '';
661
- }
662
- valIndex++;
663
- }
664
- rowIndex++;
665
- }
666
- }
667
- displayError(code) {
668
- let message = 'There was an error creating/editing your data source. Please check and try again.';
669
- switch (Number(code)) {
670
- case 23000:
671
- message = 'Duplicate Unique Key Found. Please check for duplicate values in unique identity column.';
672
- break;
673
- }
674
- this.snackbar.open(message, null, {
675
- duration: 5000,
676
- verticalPosition: 'top'
677
- });
678
- }
679
- selectColumnPickFromDatasource(column) {
680
- const dialogRef = this.dialog.open(CreateDatasetComponent, {
681
- width: '1200px',
682
- height: '800px',
683
- data: {}
684
- });
685
- dialogRef.afterClosed().subscribe(async (res) => {
686
- if (res) {
687
- column.typeConfig = {
688
- datasetInstanceId: res.datasetInstanceId,
689
- datasourceInstanceKey: res.datasourceInstanceKey
690
- };
691
- // Populate the column pick from
692
- this.populateColumnPickFrom(column);
693
- }
694
- });
695
- }
696
- // Pick from datasets
697
- populateColumnPickFrom(column) {
698
- this.datasetService.evaluateDataset(column.typeConfig, '0', '10000000').then((dataset) => {
699
- this.columnPickFromDatasets[column.name] = dataset;
700
- });
701
- }
702
- }
703
- CreateDatasourceComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CreateDatasourceComponent, deps: [{ token: i1.MatLegacyDialog }, { token: i2.ActivatedRoute }, { token: i3.DatasourceService }, { token: i4.DatasetService }, { token: i5.MatLegacySnackBar }, { token: i6.Location }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
704
- CreateDatasourceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CreateDatasourceComponent, selector: "ki-create-datasource", inputs: { sidenavService: "sidenavService", backURL: "backURL", reloadURL: "reloadURL", backendURL: "backendURL", namePrefix: "namePrefix", readonly: "readonly", automaticImportKey: "automaticImportKey", hideAPIAccess: "hideAPIAccess", editColumns: "editColumns", filterJunction: "filterJunction" }, ngImport: i0, template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div *ngIf=\"!readonly\"\n class=\"leading-5 flex items-center px-4 text-xs w-96 uppercase tracking-wider font-medium text-gray-600\">\n Name\n <input type=\"text\" class=\"w-full py-1.5 ml-4\" placeholder=\"Enter datasource name\"\n [ngClass]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n </div>\n <div *ngIf=\"readonly\"\n class=\"leading-5 font-medium text-lg px-4\">{{datasourceUpdate.title.replace((namePrefix || ''), '')}}</div>\n <div class=\"flex-1 flex items-center flex-wrap w-full justify-end bg-white\">\n <ng-template [ngIf]=\"_.some(rows, '_selected')\">\n <button (click)=\"deleteSelectedEntries()\"\n class=\"w-28 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">delete_forever</mat-icon>\n delete selected\n </button>\n <div class=\"divider\"></div>\n </ng-template>\n\n <button *ngIf=\"!editMode\" (click)=\"showFilters = !showFilters\"\n [ngStyle]=\"{'background-color': this.showFilters ? '#00000012' : ''}\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">filter_alt</mat-icon>\n filter\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n <button *ngIf=\"!editMode\" (click)=\"advancedSettings()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">tune</mat-icon>\n advanced\n </button>\n <button *ngIf=\"!editMode && !hideAPIAccess\" (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button *ngIf=\"!editMode\" (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n\n <button *ngIf=\"editMode\" (click)=\"cancelChanges()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">cancel</mat-icon>\n cancel edit\n </button>\n\n <button (click)=\"save()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div *ngIf=\"showFilters\" class=\"dataset-filters\">\n <div class=\"dataset-filter border-b border-gray-200\">\n\n <ki-dataset-filters *ngIf=\"columns.length\" [filterFields]=\"filterFields\"\n [openSide]=\"openSide\"\n [filterJunction]=\"filterJunction\"></ki-dataset-filters>\n\n <div class=\"flex items-center apply-filter\">\n <button mat-stroked-button class=\"mr-2 bg-white\" color=\"warn\"\n (click)=\"clearFilter()\">\n Clear Filter\n </button>\n <button mat-flat-button class=\"mr-2\" color=\"primary\"\n (click)=\"applyFilter()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filter\n </button>\n </div>\n\n\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <table class=\"datasource-table table-fixed w-full overflow-scroll\">\n <thead>\n <tr>\n <th class=\"w-10 relative cursor-pointer bg-gray-100 p-0 sticky text-xs\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"selectAll\" (ngModelChange)=\"updateSelectAll()\">\n </div>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"columns\" let-colIndex=index>\n <th [id]=\"column.type + colIndex\" *ngIf=\"column.type === 'id' ? showAutoIncrement : true\"\n class=\"w-64 relative cursor-pointer bg-gray-100 p-2 sticky text-xs\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === colIndex, 'border-r-0': (colIndex + 1) === columns.length}\">\n <div class=\"pr-8 w-full header-title\" (click)=\"selectColumn(column, colIndex)\">\n {{ column.title }}&nbsp;\n <svg *ngIf=\"column.keyField || column.type ==='id'\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"w-5 h-5 text-yellow-500\">\n <path fill-rule=\"evenodd\"\n d=\"M8 7a5 5 0 113.61 4.804l-1.903 1.903A1 1 0 019 14H8v1a1 1 0 01-1 1H6v1a1 1 0 01-1 1H3a1 1 0 01-1-1v-2a1 1 0 01.293-.707L8.196 8.39A5.002 5.002 0 018 7zm5-3a.75.75 0 000 1.5A1.5 1.5 0 0114.5 7 .75.75 0 0016 7a3 3 0 00-3-3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <button mat-icon-button [matMenuTriggerFor]=\"header\"\n class=\"absolute header-actions\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #header=\"matMenu\">\n <button mat-menu-item (click)=\"sortColumn(column, 'asc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Ascending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12\"/>\n </svg>\n </div>\n </button>\n <button mat-menu-item (click)=\"sortColumn(column, 'desc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Descending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0-3.75-3.75M17.25 21 21 17.25\"/>\n </svg>\n </div>\n </button>\n <ng-template [ngIf]=\"column.type !== 'id' && editColumns\">\n <button mat-menu-item (click)=\"addColumn(colIndex === 0 ? 0 : colIndex - 1)\">\n Insert column before\n </button>\n </ng-template>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"addColumn(colIndex + 1)\">Insert column after</button>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"deleteColumn(colIndex)\">Delete column</button>\n </mat-menu>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody>\n <tr class=\"table-rows\" [ngClass]=\"{'bg-gray-200 opacity-30': this.deletes.indexOf(rowIndex) > -1,\n 'bg-green-50': this.adds.indexOf(rowIndex) > -1, 'bg-indigo-100': this.updates.indexOf(rowIndex) > -1}\"\n *ngFor=\"let row of rows; let rowIndex = index\">\n <td class=\"p-0 row-cell text-center\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"row._selected\" (ngModelChange)=\"updateSelected()\">\n </div>\n </td>\n <ng-template ngFor let-rowColumn [ngForOf]=\"columns\" let-rowColIndex=index>\n <td *ngIf=\"rowColumn.type === 'id' ? showAutoIncrement : true\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === rowColIndex,\n 'w-24 bg-gray-100': columns[rowColIndex].type === 'id',\n 'bg-gray-100': columns[rowColIndex].keyField && this.adds.indexOf(rowIndex) === -1}\"\n class=\"p-0 row-cell\">\n <div\n class=\"py-1 px-2 h-full w-full border border-transparent input-wrapper flex items-center justify-between relative\">\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n [type]=\"inputTypeForField(rowColumn)\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n [max]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.maximumValue : null\"\n [min]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.minimumValue : null\"\n *ngIf=\"columns[rowColIndex].type !== 'id' && columns[rowColIndex].type !== 'pickfromsource' && columns[rowColIndex].type !== 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n type=\"checkbox\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n *ngIf=\"columns[rowColIndex].type === 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <div\n *ngIf=\"columns[rowColIndex].type == 'pickfromsource' && columnPickFromDatasets[rowColumn.name]\"\n class=\"w-full pr-10\">\n <select\n class=\"p-0 border-none w-full bg-transparent cell-input outline-none ring-0\"\n #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n <option\n *ngFor=\"let pickFrom of columnPickFromDatasets[rowColumn.name].allData\"\n [value]=\"pickFrom[rowColumn.typeConfig.valueFieldName]\">\n {{pickFrom[rowColumn.typeConfig.labelFieldName]}}\n </option>\n </select>\n </div>\n\n\n <ng-template [ngIf]=\"columns[rowColIndex].type === 'id'\">\n <div\n class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] || '<\\generated\\>' }}\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"columns[rowColIndex].keyField\">\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) > -1\">\n <input class=\"p-0 border-none w-full bg-transparent pr-5 cell-input\"\n type=\"text\" #field=\"ngModel\" [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n </ng-template>\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) === -1\">\n <div class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] }}</div>\n </ng-template>\n\n </ng-template>\n\n <span\n class=\"absolute material-symbols-outlined right-0 w-10 text-orange-500 text-lg\"\n *ngIf=\"invalidItems[rowIndex] && invalidItems[rowIndex][rowColumn.name]\"\n [matTooltip]=\"invalidItems[rowIndex][rowColumn.name]\">warning</span>\n\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\n class=\"absolute cell-actions\" tabindex=\"-1\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"addRow(rowIndex + 1)\">Add row</button>\n <button mat-menu-item (click)=\"deleteRow(rowIndex)\">Delete row</button>\n <button *ngIf=\"columns[rowColIndex].type !== 'id'\"\n mat-menu-item (click)=\"clearCell(rowIndex, rowColIndex)\">Clear cell\n </button>\n </mat-menu>\n </div>\n\n </td>\n </ng-template>\n\n </tr>\n </tbody>\n </table>\n <div (click)=\"addRow()\" title=\"Add Row\"\n class=\"cursor-pointer flex items-center text-sm m-2 p-1 bg-gray-100 rounded-md\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\">\n <mat-icon>add_circle</mat-icon>\n </button>\n Add new row\n </div>\n </div>\n\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\" title=\"Add Row\" (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div *ngIf=\"!editMode\" class=\"flex items-center\">\n <div class=\"text-xs text-gray-400 mr-10\">\n Showing {{offset + 1}}\n - {{(page * limit) - (limit - rows.length)}}</div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" title=\"Add Column\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div *ngIf=\"Object.keys(selectedItem).length\" class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n\n <hr class=\"my-4\">\n\n <ng-template [ngIf]=\"selectedItem._tableType\">\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label *ngIf=\"datasourceUpdate.instanceImportKey\" class=\"mb-4\">\n Column Key\n <input type=\"text\" [(ngModel)]=\"selectedItem.name\" disabled>\n </label>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n\n <ng-template [ngIf]=\"selectedItem.type === 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedItem.type !== 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" (ngModelChange)=\"setTypeConfig()\">\n <option [value]=\"null\">-- Select column type --</option>\n <option *ngFor=\"let type of Object.keys(datasourceTypes)\" [value]=\"type\">\n {{ datasourceTypes[type] }}\n </option>\n </select>\n </label>\n </ng-template>\n\n <div class=\"flex items-center gap-2\"\n *ngIf=\"selectedItem.typeConfig && selectedItem.type == 'integer' || selectedItem.type == 'float'\">\n <label class=\"mb-4 w-32\">\n Minimum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.minimumValue\" placeholder=\"Enter value\" />\n </label>\n\n <label class=\"mb-4 w-32\">\n Maximum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.maximumValue\" placeholder=\"Enter value\" />\n </label>\n </div>\n\n <div *ngIf=\"selectedItem.type == 'pickfromsource'\" class=\"mb-4\">\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\"\n class=\"mb-4\">\n Datasource: <span\n class=\"text-gray-500\">{{ columnPickFromDatasets[selectedItem.name].instanceTitle }}</span>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"selectColumnPickFromDatasource(selectedItem)\">\n Select Datasource\n </button>\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\" class=\"mt-4\">\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Label column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.labelFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Value column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.valueFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n\n </div>\n\n </div>\n\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.required\">\n Required\n </mat-checkbox>\n </div>\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.valueExpressionOnNullOnly\" (change)=\"!($event.checked) ? selectedItem.valueExpression = '' : null\">\n Has Default Value\n </mat-checkbox>\n </div>\n\n <label *ngIf=\"selectedItem.valueExpressionOnNullOnly\" class=\"mb-4\">\n Default Value\n <input type=\"text\" [(ngModel)]=\"selectedItem.valueExpression\" placeholder=\"Enter default value\">\n </label>\n\n\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.divider{width:1px;height:36px;background-color:#cecece}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i7.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: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatLegacyMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i9.MatLegacyMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatLegacyMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i10.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i10.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: i10.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i10.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i10.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i11.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i12.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i13.DatasetFiltersComponent, selector: "ki-dataset-filters", inputs: ["filterJunction", "filterFields", "joinFilterFields", "joinFieldsName", "openSide", "parameterValues"] }] });
705
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CreateDatasourceComponent, decorators: [{
706
- type: Component,
707
- args: [{ selector: 'ki-create-datasource', template: "<div class=\"border-b w-full flex items-center justify-between \">\n <div *ngIf=\"!readonly\"\n class=\"leading-5 flex items-center px-4 text-xs w-96 uppercase tracking-wider font-medium text-gray-600\">\n Name\n <input type=\"text\" class=\"w-full py-1.5 ml-4\" placeholder=\"Enter datasource name\"\n [ngClass]=\"{'border border-red-500': !datasourceUpdate.title}\"\n [(ngModel)]=\"datasourceUpdate.title\">\n </div>\n <div *ngIf=\"readonly\"\n class=\"leading-5 font-medium text-lg px-4\">{{datasourceUpdate.title.replace((namePrefix || ''), '')}}</div>\n <div class=\"flex-1 flex items-center flex-wrap w-full justify-end bg-white\">\n <ng-template [ngIf]=\"_.some(rows, '_selected')\">\n <button (click)=\"deleteSelectedEntries()\"\n class=\"w-28 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">delete_forever</mat-icon>\n delete selected\n </button>\n <div class=\"divider\"></div>\n </ng-template>\n\n <button *ngIf=\"!editMode\" (click)=\"showFilters = !showFilters\"\n [ngStyle]=\"{'background-color': this.showFilters ? '#00000012' : ''}\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">filter_alt</mat-icon>\n filter\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n <button *ngIf=\"!editMode\" (click)=\"advancedSettings()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">tune</mat-icon>\n advanced\n </button>\n <button *ngIf=\"!editMode && !hideAPIAccess\" (click)=\"apiAccess()\" [disabled]=\"!datasourceInstanceKey\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">api</mat-icon>\n api access\n </button>\n <button *ngIf=\"!editMode\" (click)=\"import()\"\n class=\"w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">upload_file</mat-icon>\n upload\n </button>\n <div *ngIf=\"!editMode\" class=\"divider\"></div>\n\n <button *ngIf=\"editMode\" (click)=\"cancelChanges()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">cancel</mat-icon>\n cancel edit\n </button>\n\n <button (click)=\"save()\"\n class=\"disabled:opacity-50 w-20 flex flex-col items-center justify-center py-1 px-2 text-xs text-gray-600 cursor-pointer hover:bg-gray-100\">\n <mat-icon class=\"text-xl\">save</mat-icon>\n save\n </button>\n </div>\n</div>\n<div *ngIf=\"showFilters\" class=\"dataset-filters\">\n <div class=\"dataset-filter border-b border-gray-200\">\n\n <ki-dataset-filters *ngIf=\"columns.length\" [filterFields]=\"filterFields\"\n [openSide]=\"openSide\"\n [filterJunction]=\"filterJunction\"></ki-dataset-filters>\n\n <div class=\"flex items-center apply-filter\">\n <button mat-stroked-button class=\"mr-2 bg-white\" color=\"warn\"\n (click)=\"clearFilter()\">\n Clear Filter\n </button>\n <button mat-flat-button class=\"mr-2\" color=\"primary\"\n (click)=\"applyFilter()\" [disabled]=\"!filterJunction.filters.length\">\n Apply Filter\n </button>\n </div>\n\n\n </div>\n</div>\n<div class=\"flex create-datasource-container\">\n <div class=\"flex-1 relative overflow-y-scroll table-scroll\">\n\n <div class=\"create-datasource\">\n <div id=\"tableWrapper\" class=\"flex-1 overflow-y-scroll relative\">\n <table class=\"datasource-table table-fixed w-full overflow-scroll\">\n <thead>\n <tr>\n <th class=\"w-10 relative cursor-pointer bg-gray-100 p-0 sticky text-xs\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"selectAll\" (ngModelChange)=\"updateSelectAll()\">\n </div>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"columns\" let-colIndex=index>\n <th [id]=\"column.type + colIndex\" *ngIf=\"column.type === 'id' ? showAutoIncrement : true\"\n class=\"w-64 relative cursor-pointer bg-gray-100 p-2 sticky text-xs\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === colIndex, 'border-r-0': (colIndex + 1) === columns.length}\">\n <div class=\"pr-8 w-full header-title\" (click)=\"selectColumn(column, colIndex)\">\n {{ column.title }}&nbsp;\n <svg *ngIf=\"column.keyField || column.type ==='id'\"\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\n class=\"w-5 h-5 text-yellow-500\">\n <path fill-rule=\"evenodd\"\n d=\"M8 7a5 5 0 113.61 4.804l-1.903 1.903A1 1 0 019 14H8v1a1 1 0 01-1 1H6v1a1 1 0 01-1 1H3a1 1 0 01-1-1v-2a1 1 0 01.293-.707L8.196 8.39A5.002 5.002 0 018 7zm5-3a.75.75 0 000 1.5A1.5 1.5 0 0114.5 7 .75.75 0 0016 7a3 3 0 00-3-3z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </div>\n <button mat-icon-button [matMenuTriggerFor]=\"header\"\n class=\"absolute header-actions\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #header=\"matMenu\">\n <button mat-menu-item (click)=\"sortColumn(column, 'asc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Ascending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12\"/>\n </svg>\n </div>\n </button>\n <button mat-menu-item (click)=\"sortColumn(column, 'desc')\">\n <div class=\"flex items-center justify-between w-full\">\n Sort Descending\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\" stroke=\"currentColor\"\n class=\"h-6 w-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n d=\"M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0-3.75-3.75M17.25 21 21 17.25\"/>\n </svg>\n </div>\n </button>\n <ng-template [ngIf]=\"column.type !== 'id' && editColumns\">\n <button mat-menu-item (click)=\"addColumn(colIndex === 0 ? 0 : colIndex - 1)\">\n Insert column before\n </button>\n </ng-template>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"addColumn(colIndex + 1)\">Insert column after</button>\n <button *ngIf=\"editColumns\" mat-menu-item (click)=\"deleteColumn(colIndex)\">Delete column</button>\n </mat-menu>\n </th>\n </ng-template>\n </tr>\n </thead>\n <tbody>\n <tr class=\"table-rows\" [ngClass]=\"{'bg-gray-200 opacity-30': this.deletes.indexOf(rowIndex) > -1,\n 'bg-green-50': this.adds.indexOf(rowIndex) > -1, 'bg-indigo-100': this.updates.indexOf(rowIndex) > -1}\"\n *ngFor=\"let row of rows; let rowIndex = index\">\n <td class=\"p-0 row-cell text-center\">\n <div class=\"flex items-center justify-center\">\n <input type=\"checkbox\" [(ngModel)]=\"row._selected\" (ngModelChange)=\"updateSelected()\">\n </div>\n </td>\n <ng-template ngFor let-rowColumn [ngForOf]=\"columns\" let-rowColIndex=index>\n <td *ngIf=\"rowColumn.type === 'id' ? showAutoIncrement : true\"\n [ngClass]=\"{'bg-indigo-50': selectedItem._index === rowColIndex,\n 'w-24 bg-gray-100': columns[rowColIndex].type === 'id',\n 'bg-gray-100': columns[rowColIndex].keyField && this.adds.indexOf(rowIndex) === -1}\"\n class=\"p-0 row-cell\">\n <div\n class=\"py-1 px-2 h-full w-full border border-transparent input-wrapper flex items-center justify-between relative\">\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n [type]=\"inputTypeForField(rowColumn)\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n [max]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.maximumValue : null\"\n [min]=\"columns[rowColIndex].typeConfig ? columns[rowColIndex].typeConfig.minimumValue : null\"\n *ngIf=\"columns[rowColIndex].type !== 'id' && columns[rowColIndex].type !== 'pickfromsource' && columns[rowColIndex].type !== 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <input class=\"p-0 border-none w-full bg-transparent pr-10 cell-input\"\n type=\"checkbox\" #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n [step]=\"1\"\n *ngIf=\"columns[rowColIndex].type === 'boolean' && !columns[rowColIndex].keyField\"\n (change)=\"updateField(rowColumn, rowIndex, $event)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n\n\n <div\n *ngIf=\"columns[rowColIndex].type == 'pickfromsource' && columnPickFromDatasets[rowColumn.name]\"\n class=\"w-full pr-10\">\n <select\n class=\"p-0 border-none w-full bg-transparent cell-input outline-none ring-0\"\n #field=\"ngModel\"\n [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n <option\n *ngFor=\"let pickFrom of columnPickFromDatasets[rowColumn.name].allData\"\n [value]=\"pickFrom[rowColumn.typeConfig.valueFieldName]\">\n {{pickFrom[rowColumn.typeConfig.labelFieldName]}}\n </option>\n </select>\n </div>\n\n\n <ng-template [ngIf]=\"columns[rowColIndex].type === 'id'\">\n <div\n class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] || '<\\generated\\>' }}\n </div>\n </ng-template>\n\n <ng-template [ngIf]=\"columns[rowColIndex].keyField\">\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) > -1\">\n <input class=\"p-0 border-none w-full bg-transparent pr-5 cell-input\"\n type=\"text\" #field=\"ngModel\" [(ngModel)]=\"row[rowColumn.name]\"\n (change)=\"updateField(field, rowIndex)\"\n (focus)=\"focusCell($event, rowIndex, rowColIndex)\"\n (keyup.enter)=\"enterCell(rowIndex, rowColIndex, $event)\">\n </ng-template>\n <ng-template [ngIf]=\"this.adds.indexOf(rowIndex) === -1\">\n <div class=\"text-gray-500 text-xs\">{{ row[rowColumn.name] }}</div>\n </ng-template>\n\n </ng-template>\n\n <span\n class=\"absolute material-symbols-outlined right-0 w-10 text-orange-500 text-lg\"\n *ngIf=\"invalidItems[rowIndex] && invalidItems[rowIndex][rowColumn.name]\"\n [matTooltip]=\"invalidItems[rowIndex][rowColumn.name]\">warning</span>\n\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\n class=\"absolute cell-actions\" tabindex=\"-1\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"addRow(rowIndex + 1)\">Add row</button>\n <button mat-menu-item (click)=\"deleteRow(rowIndex)\">Delete row</button>\n <button *ngIf=\"columns[rowColIndex].type !== 'id'\"\n mat-menu-item (click)=\"clearCell(rowIndex, rowColIndex)\">Clear cell\n </button>\n </mat-menu>\n </div>\n\n </td>\n </ng-template>\n\n </tr>\n </tbody>\n </table>\n <div (click)=\"addRow()\" title=\"Add Row\"\n class=\"cursor-pointer flex items-center text-sm m-2 p-1 bg-gray-100 rounded-md\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\">\n <mat-icon>add_circle</mat-icon>\n </button>\n Add new row\n </div>\n </div>\n\n\n <div class=\"border-t bg-gray-50 py-2 flex align-center justify-between\">\n <button class=\"ml-2\" mat-icon-button color=\"primary\" title=\"Add Row\" (click)=\"addRow()\">\n <mat-icon>add_circle</mat-icon>\n </button>\n <div *ngIf=\"!editMode\" class=\"flex items-center\">\n <div class=\"text-xs text-gray-400 mr-10\">\n Showing {{offset + 1}}\n - {{(page * limit) - (limit - rows.length)}}</div>\n <select [value]=\"limit\" (change)=\"pageSizeChange($event.target.value)\"\n class=\"mr-8 p-2\">\n <option [value]=\"10\">10</option>\n <option [value]=\"25\">25</option>\n <option [value]=\"50\">50</option>\n <option [value]=\"100\">100</option>\n <option [value]=\"250\">250</option>\n <option [value]=\"1000\">1000</option>\n </select>\n <button mat-icon-button class=\"mr-4\" (click)=\"decreaseOffset()\" [disabled]=\"page <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button mat-icon-button (click)=\"increaseOffset()\" [disabled]=\"endOfResults\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"border-l border-r bg-gray-50 -ml-2.5\">\n <button mat-icon-button color=\"primary\" title=\"Add Column\" (click)=\"addColumn()\"\n class=\"-mt-0.5\">\n <mat-icon>add_circle</mat-icon>\n </button>\n </div>\n\n <div *ngIf=\"Object.keys(selectedItem).length\" class=\"bg-gray-100 w-72 h-full p-3 flex justify-between flex-col\">\n <div>\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Settings\n </div>\n\n <hr class=\"my-4\">\n\n <ng-template [ngIf]=\"selectedItem._tableType\">\n <div class=\"uppercase font-medium tracking-wider mb-4 text-xs text-gray-600\">\n Column\n </div>\n <label *ngIf=\"datasourceUpdate.instanceImportKey\" class=\"mb-4\">\n Column Key\n <input type=\"text\" [(ngModel)]=\"selectedItem.name\" disabled>\n </label>\n <label class=\"mb-4\">\n Column Title\n <input type=\"text\" [(ngModel)]=\"selectedItem.title\" placeholder=\"Enter column title\"\n (change)=\"updateColumnName()\">\n </label>\n\n <ng-template [ngIf]=\"selectedItem.type === 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" disabled>\n <option [value]=\"'id'\">ID</option>\n </select>\n </label>\n </ng-template>\n\n <ng-template [ngIf]=\"selectedItem.type !== 'id'\">\n <label class=\"mb-4\">\n Column Type\n <select [(ngModel)]=\"selectedItem.type\" (ngModelChange)=\"setTypeConfig()\">\n <option [value]=\"null\">-- Select column type --</option>\n <option *ngFor=\"let type of Object.keys(datasourceTypes)\" [value]=\"type\">\n {{ datasourceTypes[type] }}\n </option>\n </select>\n </label>\n </ng-template>\n\n <div class=\"flex items-center gap-2\"\n *ngIf=\"selectedItem.typeConfig && selectedItem.type == 'integer' || selectedItem.type == 'float'\">\n <label class=\"mb-4 w-32\">\n Minimum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.minimumValue\" placeholder=\"Enter value\" />\n </label>\n\n <label class=\"mb-4 w-32\">\n Maximum Value\n <input type=\"number\" class=\"py-1 px-2\"\n [(ngModel)]=\"selectedItem.typeConfig.maximumValue\" placeholder=\"Enter value\" />\n </label>\n </div>\n\n <div *ngIf=\"selectedItem.type == 'pickfromsource'\" class=\"mb-4\">\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\"\n class=\"mb-4\">\n Datasource: <span\n class=\"text-gray-500\">{{ columnPickFromDatasets[selectedItem.name].instanceTitle }}</span>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"selectColumnPickFromDatasource(selectedItem)\">\n Select Datasource\n </button>\n\n <div *ngIf=\"selectedItem.typeConfig && columnPickFromDatasets[selectedItem.name]\" class=\"mt-4\">\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Label column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.labelFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n <label class=\"block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2\">\n Value column\n </label>\n <div class=\"mt-1 sm:col-span-2 sm:mt-0\">\n <select [(ngModel)]=\"selectedItem.typeConfig.valueFieldName\"\n class=\"block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm py-1 px-2\">\n <option *ngFor=\"let column of columnPickFromDatasets[selectedItem.name].columns\"\n [value]=\"column.name\">\n {{column.title}}\n </option>\n </select>\n </div>\n\n\n </div>\n\n </div>\n\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.required\">\n Required\n </mat-checkbox>\n </div>\n\n <div>\n <mat-checkbox class=\"mb-4\"\n [(ngModel)]=\"selectedItem.valueExpressionOnNullOnly\" (change)=\"!($event.checked) ? selectedItem.valueExpression = '' : null\">\n Has Default Value\n </mat-checkbox>\n </div>\n\n <label *ngIf=\"selectedItem.valueExpressionOnNullOnly\" class=\"mb-4\">\n Default Value\n <input type=\"text\" [(ngModel)]=\"selectedItem.valueExpression\" placeholder=\"Enter default value\">\n </label>\n\n\n <div>\n <button mat-button color=\"warn\" (click)=\"deleteSelectedColumn()\">Delete Column</button>\n </div>\n\n <hr class=\"my-4\">\n </ng-template>\n </div>\n\n <button mat-flat-button color=\"primary\" (click)=\"save(true)\">\n Save & Exit\n </button>\n </div>\n</div>\n\n\n", styles: [":host{display:block;background-color:#fff;height:calc(100vh - 104px)}.divider{width:1px;height:36px;background-color:#cecece}.action-toolbar{display:flex;align-items:center;flex-wrap:wrap;width:100%;justify-content:flex-end;background-color:#fff;border-bottom:1px solid #ddd}.action-toolbar button{min-width:50px;padding:0 13px;color:#505050}.cell-header{width:100%;display:flex;align-items:center;justify-content:space-between}.cell-header.end{justify-content:flex-end}.cell-header.sorting{min-height:43px}.transformation-listing{display:flex;align-items:center;width:100%;background-color:#00000012;border-bottom:1px solid #ddd;min-height:47px}.transformation-listing .list-title{text-transform:uppercase;font-size:.75rem;padding:0 1rem;border-right:2px solid #ddd;color:#4c4c4c;font-weight:500;letter-spacing:1px}.transformation-listing .badge-item{display:flex;align-items:center;margin-left:1rem;padding-left:1rem;border-radius:20px;background-color:#fff;border:1px solid #ddd;height:30px}.transformation-listing .badge-item.exclude{opacity:.8}.transformation-listing .badge-item:hover{background-color:#fcfcfc}.transformation-listing .badge-item span{margin-right:.5rem;color:#0000008a}.transformation-listing .badge-item button.mat-icon-button{width:33px;height:33px;line-height:33px}.transformation-listing .badge-item button.mat-icon-button mat-icon{font-size:20px;height:20px;width:20px;line-height:20px;color:#0000008a}.dataset-filters{position:relative;overflow-y:scroll;flex:none!important;max-height:400px}.dataset-filters .dataset-filter{position:relative}.dataset-filters .dataset-filter .apply-filter{position:absolute;bottom:.5rem;right:0;z-index:10}.dataset-filters .dataset-filter .remove-filter{position:absolute;top:.5rem;right:0;z-index:10}.create-datasource-container{min-width:1024px;height:calc(100% - 49px)}.create-datasource-container .table-scroll::-webkit-scrollbar{width:.75em;background:transparent}.create-datasource-container .table-scroll::-webkit-scrollbar-thumb{background:#d2d2d2}.create-datasource-container .add-column{position:absolute;top:0;right:0}.create-datasource-container .create-datasource{margin-left:-1px;margin-top:-1px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.create-datasource-container .create-datasource table.datasource-table td,.create-datasource-container .create-datasource table.datasource-table th{border:1px solid #ddd;vertical-align:middle;padding:.5rem}.create-datasource-container .create-datasource table.datasource-table th{font-weight:500}.create-datasource-container .create-datasource table.datasource-table th .header-title{min-height:20px;display:flex;align-items:center}.create-datasource-container .create-datasource table.datasource-table th .header-title mat-icon{height:20px;width:20px;font-size:20px;line-height:20px;color:#ffc400b3}.create-datasource-container .create-datasource table.datasource-table th button.header-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray}.create-datasource-container .create-datasource table.datasource-table th button.header-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions{width:30px;height:30px;line-height:30px;top:50%;transform:translateY(-50%);right:0;color:gray;display:none}.create-datasource-container .create-datasource table.datasource-table .input-wrapper button.cell-actions mat-icon{line-height:20px;height:20px;width:20px;font-size:20px}.create-datasource-container .create-datasource table.datasource-table .input-wrapper:hover button.cell-actions{display:block}\n"] }]
708
- }], ctorParameters: function () { return [{ type: i1.MatLegacyDialog }, { type: i2.ActivatedRoute }, { type: i3.DatasourceService }, { type: i4.DatasetService }, { type: i5.MatLegacySnackBar }, { type: i6.Location }, { type: i2.Router }]; }, propDecorators: { sidenavService: [{
709
- type: Input
710
- }], backURL: [{
711
- type: Input
712
- }], reloadURL: [{
713
- type: Input
714
- }], backendURL: [{
715
- type: Input
716
- }], namePrefix: [{
717
- type: Input
718
- }], readonly: [{
719
- type: Input
720
- }], automaticImportKey: [{
721
- type: Input
722
- }], hideAPIAccess: [{
723
- type: Input
724
- }], editColumns: [{
725
- type: Input
726
- }], filterJunction: [{
727
- type: Input
728
- }] } });
729
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcta2luaW50ZWwvc3JjL2xpYi9jb21wb25lbnRzL2RhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UvY3JlYXRlLWRhdGFzb3VyY2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFnQixTQUFTLEVBQUUsS0FBSyxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUlqQyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx3REFBd0QsQ0FBQztBQU0zRixPQUFPLEVBQ0gsa0JBQWtCLEVBQ3JCLE1BQU0sc0RBQXNELENBQUM7QUFDOUQsT0FBTyxFQUNILHlCQUF5QixFQUM1QixNQUFNLG9FQUFvRSxDQUFDO0FBQzVFLE9BQU8sRUFDSCxxQkFBcUIsRUFDeEIsTUFBTSx3RUFBd0UsQ0FBQztBQUNoRixPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHVEQUF1RCxDQUFDO0FBQzdGLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7Ozs7O0FBbkJuQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO0FBNkJ6QixNQUFNLE9BQU8seUJBQXlCO0lBMkZsQyxZQUFvQixNQUFpQixFQUNqQixLQUFxQixFQUNyQixpQkFBb0MsRUFDcEMsY0FBOEIsRUFDOUIsUUFBcUIsRUFDckIsUUFBa0Is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QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0ksc0JBQXNCOzRRQU12QixjQUFjO3NCQUF0QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IF8gPSBsb2Rhc2guZGVmYXVsdDtcbmltcG9ydCB7TWF0TGVnYWN5RGlhbG9nIGFzIE1hdERpYWxvZ30gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbGVnYWN5LWRpYWxvZyc7XG5pbXBvcnQge0ltcG9ydERhdGFDb21wb25lbnR9IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2ltcG9ydC1kYXRhL2ltcG9ydC1kYXRhLmNvbXBvbmVudCc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge0RhdGFzb3VyY2VTZXJ2aWNlLCBEYXRhc291cmNlVXBkYXRlfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9kYXRhc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtEYXRhc2V0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGF0YXNldC5zZXJ2aWNlJztcbmltcG9ydCB7TWF0TGVnYWN5U25hY2tCYXIgYXMgTWF0U25hY2tCYXJ9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXInO1xuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQXBpQWNjZXNzQ29tcG9uZW50XG59IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2FwaS1hY2Nlc3MvYXBpLWFjY2Vzcy5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgICBBZHZhbmNlZFNldHRpbmdzQ29tcG9uZW50XG59IGZyb20gJy4uL2NyZWF0ZS1kYXRhc291cmNlL2FkdmFuY2VkLXNldHRpbmdzL2FkdmFuY2VkLXNldHRpbmdzLmNvbXBvbmVudCc7XG5pbXBvcnQge1xuICAgIEltcG9ydFdpemFyZENvbXBvbmVudFxufSBmcm9tICcuLi9jcmVhdGUtZGF0YXNvdXJjZS9pbXBvcnQtZGF0YS9pbXBvcnQtd2l6YXJkL2ltcG9ydC13aXphcmQuY29tcG9uZW50JztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q3JlYXRlRGF0YXNldENvbXBvbmVudH0gZnJvbSAnLi4vLi4vZGF0YXNldC9jcmVhdGUtZGF0YXNldC9jcmVhdGUtZGF0YXNldC5jb21wb25lbnQnO1xuaW1wb3J0IHNob3J0SGFzaCBmcm9tICdzaG9ydC1oYXNoJztcblxuXG5kZWNsYXJlIHZhciB3aW5kb3c6IGFueTtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdraS1jcmVhdGUtZGF0YXNvdXJjZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NyZWF0ZS1kYXRhc291cmNlLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jcmVhdGUtZGF0YXNvdXJjZS5jb21wb25lbnQuc2FzcyddXG59KVxuZXhwb3J0IGNsYXNzIENyZWF0ZURhdGFzb3VyY2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cbiAgICBASW5wdXQoKSBzaWRlbmF2U2VydmljZTogYW55O1xuICAgIEBJbnB1dCgpIGJhY2tVUkwgPSAnL2ltcG9ydGVkLWRhdGEnO1xuICAgIEBJbnB1dCgpIHJlbG9hZFVSTCA9ICdpbXBvcnQtZGF0YSc7XG4gICAgQElucHV0KCkgYmFja2VuZFVSTDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG5hbWVQcmVmaXggPSAnJztcbiAgICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGF1dG9tYXRpY0ltcG9ydEtleTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGhpZGVBUElBY2Nlc3M6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBlZGl0Q29sdW1ucyA9IHRydWU7XG4gICAgQElucHV0KCkgZmlsdGVySnVuY3Rpb24gPSB7XG4gICAgICAgIGxvZ2ljOiAnQU5EJyxcbiAgICAgICAgZmlsdGVyczogW3tcbiAgICAgICAgICAgIGxoc0V4cHJlc3Npb246ICcnLFxuICAgICAgICAgICAgcmhzRXhwcmVzc2lvbjogW10sXG4gICAgICAgICAgICBmaWx0ZXJUeXBlOiAnJ1xuICAgICAgICB9XSxcbiAgICAgICAgZmlsdGVySnVuY3Rpb25zOiBbXVxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YXNvdXJjZVR5cGVzOiBhbnkgPSB7XG4gICAgICAgIHN0cmluZzogJ1RleHQgKHVwIHRvIDI1NSBjaGFycyknLFxuICAgICAgICBtZWRpdW1zdHJpbmc6ICdNZWRpdW0gVGV4dCAodXAgdG8gMzI3NjcgY2hhcnMpJyxcbiAgICAgICAgbG9uZ3N0cmluZzogJ0xvbmcgVGV4dCAobW9yZSB0aGFuIDMyNzY3IGNoYXJzKScsXG4gICAgICAgIGludGVnZXI6ICdOdW1iZXIgKHdob2xlIG51bWJlciknLFxuICAgICAgICBiaWdpbnRlZ2VyOiAnTnVtYmVyIChsYXJnZSBudW1iZXIpJyxcbiAgICAgICAgYm9vbGVhbjogJ1RpY2sgKFllcyAvIE5vKScsXG4gICAgICAgIGZsb2F0OiAnRGVjaW1hbCBudW1iZXInLFxuICAgICAgICBkYXRlOiAnRGF0ZScsXG4gICAgICAgIGRhdGV0aW1lOiAnRGF0ZSBhbmQgVGltZScsXG4gICAgICAgIHBpY2tmcm9tc291cmNlOiAnUGljayBGcm9tIExpc3QgKHVzaW5nIGFub3RoZXIgc291cmNlKScsXG4gICAgICAgIGpzb246ICdOZXN0ZWQgSlNPTiBPYmplY3QnXG4gICAgfTtcblxuICAgIHB1YmxpYyByb3dzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgY29sdW1uczogYW55ID0gW1xuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ0NvbHVtbiAxJyxcbiAgICAgICAgICAgIG5hbWU6ICdjb2x1bW5fMScsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB0aXRsZTogJ0NvbHVtbiAyJyxcbiAgICAgICAgICAgIG5hbWU6ICdjb2x1bW5fMicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9XG4gICAgXTtcbiAgICBwdWJsaWMgc2VsZWN0ZWRJdGVtOiBhbnkgPSB7fTtcbiAgICBwdWJsaWMgXyA9IF87XG4gICAgcHVibGljIHNob3dVcGxvYWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaGVhZGVyUm93ID0gZmFsc2U7XG4gICAgcHVibGljIGFkZHM6IGFueSA9IFtdO1xuICAgIHB1YmxpYyB1cGRhdGVzOiBhbnkgPSBbXTtcbiAgICBwdWJsaWMgZGVsZXRlczogYW55ID0gW107XG4gICAgcHVibGljIGludmFsaWRJdGVtczogYW55ID0gW107XG4gICAgcHVibGljIGVkaXRNb2RlID0gZmFsc2U7XG4gICAgcHVibGljIGF1dG9JbmNyZW1lbnRDb2x1bW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiBzdHJpbmc7XG4gICAgcHVibGljIGRhdGFzb3VyY2VVcGRhdGU6IGFueSA9IHtcbiAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICBpbnN0YW5jZUltcG9ydEtleTogJycsXG4gICAgICAgIGZpZWxkczogW10sXG4gICAgICAgIGFkZHM6IFtdLFxuICAgICAgICB1cGRhdGVzOiBbXSxcbiAgICAgICAgZGVsZXRlczogW11cbiAgICB9O1xuICAgIHB1YmxpYyBvZmZzZXQgPSAwO1xuICAgIHB1YmxpYyBsaW1pdCA9IDI1O1xuICAgIHB1YmxpYyBwYWdlID0gMTtcbiAgICBwdWJsaWMgZW5kT2ZSZXN1bHRzID0gZmFsc2U7XG4gICAgcHVibGljIHNob3dBdXRvSW5jcmVtZW50ID0gZmFsc2U7XG4gICAgcHVibGljIHNlbGVjdEFsbCA9IGZhbHNlO1xuICAgIHB1YmxpYyBzaG93RmlsdGVycyA9IGZhbHNlO1xuICAgIHB1YmxpYyBmaWx0ZXJGaWVsZHMgPSBbXTtcbiAgICBwdWJsaWMgc29ydENvbmZpZyA9IG51bGw7XG4gICAgcHVibGljIG9wZW5TaWRlID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG4gICAgcHVibGljIE9iamVjdCA9IE9iamVjdDtcblxuXG4gICAgcHJpdmF0ZSBpc01vdXNlRG93biA9IGZhbHNlO1xuICAgIHByaXZhdGUgc3RhcnRSb3dJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBzdGFydENlbGxJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBlbmRSb3dJbmRleCA9IG51bGw7XG4gICAgcHJpdmF0ZSBlbmRDZWxsSW5kZXggPSBudWxsO1xuICAgIHByaXZhdGUgc2VsZWN0ZWRDZWxsID0gbnVsbDtcblxuICAgIC8vIEFzc29jaWF0aXZlIGxpc3Qgb2YgcGljayBmcm9tIGRhdGFzZXRzIHVzZWQgZm9yIGxpc3Qgc2VsZWN0aW9uXG4gICAgcHJpdmF0ZSBjb2x1bW5QaWNrRnJvbURhdGFzZXRzID0ge307XG5cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc291cmNlU2VydmljZTogRGF0YXNvdXJjZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBkYXRhc2V0U2VydmljZTogRGF0YXNldFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBzbmFja2JhcjogTWF0U25hY2tCYXIsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlclxuICAgICkge1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1zLmtleTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXkpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSArICdfc2hvd19pZCcpID09PSAndHJ1ZSc7XG4gICAgICAgICAgICB0aGlzLmxvYWREYXRhc291cmNlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEltcG9ydFdpemFyZENvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgICAgIGhlaWdodDogJzkwMHB4JyxcbiAgICAgICAgICAgICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zOiB0aGlzLmNvbHVtbnMsXG4gICAgICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VVcGRhdGU6IHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgcm93czogdGhpcy5yb3dzLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgICAgICByZWxvYWRVUkw6IHRoaXMucmVsb2FkVVJMLFxuICAgICAgICAgICAgICAgICAgICBuYW1lUHJlZml4OiB0aGlzLm5hbWVQcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpY0ltcG9ydEtleTogdGhpcy5hdXRvbWF0aWNJbXBvcnRLZXlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXMgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYXRpb24uYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBpZiAodGhpcy5zaWRlbmF2U2VydmljZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaWRlbmF2U2VydmljZS5jbG9zZSgpO1xuICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzTW91c2VEb3duID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5zaWRlbmF2U2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5zaWRlbmF2U2VydmljZS5vcGVuKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYXJGaWx0ZXIoKSB7XG4gICAgICAgIHRoaXMuZmlsdGVySnVuY3Rpb24gPSB7XG4gICAgICAgICAgICBsb2dpYzogJ0FORCcsXG4gICAgICAgICAgICBmaWx0ZXJzOiBbe1xuICAgICAgICAgICAgICAgIGxoc0V4cHJlc3Npb246ICcnLFxuICAgICAgICAgICAgICAgIHJoc0V4cHJlc3Npb246IFtdLFxuICAgICAgICAgICAgICAgIGZpbHRlclR5cGU6ICcnXG4gICAgICAgICAgICB9XSxcbiAgICAgICAgICAgIGZpbHRlckp1bmN0aW9uczogW11cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhcHBseUZpbHRlcigpIHtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzb3J0Q29sdW1uKGNvbHVtbjogYW55LCBkaXJlY3Rpb246IHN0cmluZykge1xuICAgICAgICB0aGlzLnNvcnRDb25maWcgPSB7ZmllbGROYW1lOiBjb2x1bW4ubmFtZSwgZGlyZWN0aW9ufTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVTZWxlY3RBbGwoKSB7XG4gICAgICAgIHRoaXMucm93cy5tYXAocm93ID0+IHtcbiAgICAgICAgICAgIHJvdy5fc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdEFsbDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZVNlbGVjdGVkKCkge1xuICAgICAgICB0aGlzLnNlbGVjdEFsbCA9IF8uZXZlcnkodGhpcy5yb3dzLCAnX3NlbGVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUF1dG9JbmNyZW1lbnRDb2x1bW4odmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMubWFwKGNvbHVtbiA9PiB7XG4gICAgICAgICAgICAgICAgY29sdW1uLmtleUZpZWxkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbjtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMudW5zaGlmdCh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdJRCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ2lkJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnaWQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIF8ucmVtb3ZlKHRoaXMuY29sdW1ucywge3R5cGU6ICdpZCd9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRDb2x1bW4oaW5kZXg/KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtID0ge1xuICAgICAgICAgICAgX3RhYmxlVHlwZTogJ2NvbHVtbicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKGluZGV4LCAwLCB0aGlzLnNlbGVjdGVkSXRlbSk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbS5faW5kZXggPSBpbmRleDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1ucy5wdXNoKHRoaXMuc2VsZWN0ZWRJdGVtKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCA9IHRoaXMuY29sdW1ucy5sZW5ndGggLSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnNlbGVjdGVkSXRlbS50eXBlICsgdGhpcy5zZWxlY3RlZEl0ZW0uX2luZGV4KS5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW1wb3J0KCkge1xuICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEltcG9ydERhdGFDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnOTAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGNvbHVtbnM6IHRoaXMuY29sdW1ucyxcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlVXBkYXRlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUsXG4gICAgICAgICAgICAgICAgcm93czogdGhpcy5yb3dzLFxuICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VJbnN0YW5jZUtleTogdGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXksXG4gICAgICAgICAgICAgICAgcmVsb2FkVVJMOiB0aGlzLnJlbG9hZFVSTFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkQ2VsbCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByb3dDb2xJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDZWxsID0ge3Jvd0luZGV4OiAwLCByb3dDb2xJbmRleH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5oZWFkZXJSb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29sdW1ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICByZXMuZGF0YVswXS5mb3JFYWNoKGhlYWRlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBoZWFkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXy5zbmFrZUNhc2UoaGVhZGVyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zO1xuICAgICAgICAgICAgICAgICAgICByZXMuZGF0YS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydENlbGxEYXRhKHJlcy5kYXRhKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Q2VsbERhdGEocmVzLmRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGRlbGV0ZVNlbGVjdGVkRW50cmllcygpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICdBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gcmVtb3ZlIGFsbCBvZiB0aGUgc2VsZWN0ZWQgZW50cmllcz8gVGhpcyBhY3Rpb24gY2Fubm90IGJlIHJldmVyc2VkLic7XG4gICAgICAgIGlmICh3aW5kb3cuY29uZmlybShtZXNzYWdlKSkge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBfLmZpbHRlcih0aGlzLnJvd3MsICdfc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UudXBkYXRlQ3VzdG9tRGF0YXNvdXJjZSh0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUudGl0bGUsXG4gICAgICAgICAgICAgICAgaW1wb3J0S2V5OiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5zdGFuY2VJbXBvcnRLZXkgfHwgJycsXG4gICAgICAgICAgICAgICAgZmllbGRzOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZmllbGRzLFxuICAgICAgICAgICAgICAgIGFkZHM6IFtdLFxuICAgICAgICAgICAgICAgIHVwZGF0ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGRlbGV0ZXM6IHNlbGVjdGVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdGhpcy5yZWxvYWRVUkwgKyAnLycgKyB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhZGRGaWx0ZXIoKSB7XG5cbiAgICB9XG5cbiAgICBwdWJsaWMgYWR2YW5jZWRTZXR0aW5ncygpIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihBZHZhbmNlZFNldHRpbmdzQ29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzgwMHB4JyxcbiAgICAgICAgICAgIGhlaWdodDogJzkwMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlVXBkYXRlOiB0aGlzLmRhdGFzb3VyY2VVcGRhdGUsXG4gICAgICAgICAgICAgICAgZGF0YXNvdXJjZUluc3RhbmNlS2V5OiB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICBiYWNrZW5kVVJMOiB0aGlzLmJhY2tlbmRVUkwsXG4gICAgICAgICAgICAgICAgY29sdW1uczogdGhpcy5jb2x1bW5zLFxuICAgICAgICAgICAgICAgIHNob3dBdXRvSW5jcmVtZW50OiB0aGlzLnNob3dBdXRvSW5jcmVtZW50XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoYWR2YW5jZWRTZXR0aW5ncyA9PiB7XG4gICAgICAgICAgICBpZiAoYWR2YW5jZWRTZXR0aW5ncykge1xuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IGFkdmFuY2VkU2V0dGluZ3MuY29sdW1ucztcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5kZXhlcyA9IGFkdmFuY2VkU2V0dGluZ3MuZGF0YXNvdXJjZVVwZGF0ZS5pbmRleGVzO1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQgPSBhZHZhbmNlZFNldHRpbmdzLnNob3dBdXRvSW5jcmVtZW50O1xuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5ICsgJ19zaG93X2lkJywgU3RyaW5nKHRoaXMuc2hvd0F1dG9JbmNyZW1lbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFwaUFjY2VzcygpIHtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihBcGlBY2Nlc3NDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnOTAwcHgnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGRhdGFzb3VyY2VVcGRhdGU6IHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSxcbiAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHRoaXMuZGF0YXNvdXJjZUluc3RhbmNlS2V5LFxuICAgICAgICAgICAgICAgIGJhY2tlbmRVUkw6IHRoaXMuYmFja2VuZFVSTCxcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB0aGlzLmNvbHVtbnNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgcHVibGljIHNlbGVjdENvbHVtbihjb2x1bW4sIGluZGV4KSB7XG4gICAgICAgIGlmICh0aGlzLmVkaXRDb2x1bW5zICYmICFjb2x1bW4uYXV0b0luY3JlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZENlbGwgPSBudWxsO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRhdGFzb3VyY2UtdGFibGUgLmJnLWluZGlnby01MCcpLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdiZy1pbmRpZ28tNTAnKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtID0ge307XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbHVtbi5fdGFibGVUeXBlID0gJ2NvbHVtbic7XG4gICAgICAgICAgICAgICAgY29sdW1uLl9pbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgICAgIGlmICghY29sdW1uLnByZXZpb3VzTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4ucHJldmlvdXNOYW1lID0gY29sdW1uLm5hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0gPSBjb2x1bW47XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUNlbGxGb2N1c0JvcmRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZUNvbHVtbihpbmRleCkge1xuICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkUm93KGluZGV4Pykge1xuICAgICAgICBjb25zdCByb3cgPSB7fTtcbiAgICAgICAgdGhpcy5jb2x1bW5zLmZvckVhY2goY29sdW1uID0+IHtcbiAgICAgICAgICAgIHJvd1tjb2x1bW4ubmFtZV0gPSBudWxsO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnNwbGljZShpbmRleCwgMCwgcm93KTtcbiAgICAgICAgICAgIHRoaXMuYWRkcy5wdXNoKGluZGV4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucm93cy5wdXNoKHJvdyk7XG4gICAgICAgICAgICB0aGlzLmFkZHMucHVzaCh0aGlzLnJvd3MubGVuZ3RoIC0gMSk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhYmxlV3JhcHBlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0YWJsZVdyYXBwZXInKTtcbiAgICAgICAgICAgIHRhYmxlV3JhcHBlci5zY3JvbGxUb3AgPSB0YWJsZVdyYXBwZXIuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9LCAwKTtcblxuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGVSb3cocm93SW5kZXgpIHtcbiAgICAgICAgY29uc3QgaW5BZGRzID0gdGhpcy5hZGRzLmluZGV4T2Yocm93SW5kZXgpO1xuICAgICAgICBpZiAoaW5BZGRzID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucm93cy5zcGxpY2Uocm93SW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnBvcCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWxldGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5VcGRhdGVzID0gdGhpcy51cGRhdGVzLmluZGV4T2Yocm93SW5kZXgpO1xuICAgICAgICBpZiAoaW5VcGRhdGVzID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlcy5zcGxpY2UoaW5VcGRhdGVzLCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBmb2N1c0NlbGwoZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbCA9IHtyb3dJbmRleCwgcm93Q29sSW5kZXh9O1xuICAgICAgICB0aGlzLnJlbW92ZUNlbGxGb2N1c0JvcmRlcigpO1xuICAgICAgICBldmVudC50YXJnZXQucGFyZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdib3JkZXInLCAnYm9yZGVyLWJsdWUtNTAwJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGJsdXJDZWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbCA9IG51bGw7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2VsbEZvY3VzQm9yZGVyKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNsZWFyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgpIHtcbiAgICAgICAgY29uc3QgY29sdW1uTmFtZSA9IHRoaXMuY29sdW1uc1tyb3dDb2xJbmRleF0ubmFtZTtcbiAgICAgICAgdGhpcy5yb3dzW3Jvd0luZGV4XVtjb2x1bW5OYW1lXSA9ICcnO1xuICAgICAgICBpZiAodGhpcy5hZGRzLmluZGV4T2Yocm93SW5kZXgpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZUZpZWxkKGZpZWxkLCByb3dJbmRleCwgZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnVwZGF0ZXMuaW5kZXhPZihyb3dJbmRleCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVzLnB1c2gocm93SW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGltcGxpY2l0IGZhbHNlIHZhbHVlcyBmb3IgYm9vbGVhbnMgYW5kIGltcGxpY2l0IG51bGxzIGZvciBvdGhlciBmaWVsZHNcbiAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICB0aGlzLnJvd3Nbcm93SW5kZXhdW2ZpZWxkLm5hbWVdID0gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5yb3dzW3Jvd0luZGV4XVtmaWVsZC5uYW1lXSA9PT0gJycpXG4gICAgICAgICAgICAgICAgdGhpcy5yb3dzW3Jvd0luZGV4XVtmaWVsZC5uYW1lXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVkaXRNb2RlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlQ29sdW1uTmFtZSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0ubmFtZSA9IF8uc25ha2VDYXNlKHRoaXMuc2VsZWN0ZWRJdGVtLnRpdGxlKTtcbiAgICAgICAgdGhpcy5yb3dzLm1hcChyb3cgPT4ge1xuICAgICAgICAgICAgcm93W3RoaXMuc2VsZWN0ZWRJdGVtLm5hbWVdID0gcm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV0gfHwgJyc7XG4gICAgICAgICAgICBpZiAocm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV0pIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgcm93W3RoaXMuc2VsZWN0ZWRJdGVtLnByZXZpb3VzTmFtZV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByb3c7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbnRlckNlbGwocm93SW5kZXgsIHJvd0NvbEluZGV4LCBldmVudCkge1xuICAgICAgICBjb25zdCByb3cgPSB7fTtcbiAgICAgICAgbGV0IHJvd0VsZW1lbnQgPSBudWxsO1xuICAgICAgICBsZXQgcm93RWxlbWVudEluZGV4O1xuICAgICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgcm93W2NvbHVtbi5uYW1lXSA9ICcnO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJvd0luZGV4ID09PSB0aGlzLnJvd3MubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnB1c2gocm93KTtcbiAgICAgICAgICAgIHJvd0VsZW1lbnRJbmRleCA9IHRoaXMucm93cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnB1c2godGhpcy5yb3dzLmxlbmd0aCAtIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcm93RWxlbWVudEluZGV4ID0gcm93SW5kZXggKyAxO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByb3dFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRhYmxlLXJvd3MnKS5pdGVtKHJvd0VsZW1lbnRJbmRleCk7XG4gICAgICAgICAgICBjb25zdCByb3dDZWxsOiBhbnkgPSByb3dFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5yb3ctY2VsbCcpLml0ZW0odGhpcy5zaG93QXV0b0luY3JlbWVudCA/IHJvd0NvbEluZGV4ICsgMSA6IHJvd0NvbEluZGV4KTtcbiAgICAgICAgICAgIHJvd0NlbGwucXVlcnlTZWxlY3RvckFsbCgnLmNlbGwtaW5wdXQnKS5pdGVtKDApLmZvY3VzKCk7XG4gICAgICAgIH0sIDApO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzYXZlKGV4aXQgPSBmYWxzZSkge1xuICAgICAgICBpZiAoIXRoaXMuZGF0YXNvdXJjZVVwZGF0ZS50aXRsZSkge1xuICAgICAgICAgICAgd2luZG93LmFsZXJ0KCdQbGVhc2UgZW50ZXIgYSB0aXRsZSBmb3IgdGhpcyBEYXRhc291cmNlLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFfLmZpbmQodGhpcy5jb2x1bW5zLCB7a2V5RmllbGQ6IHRydWV9KSAmJlxuICAgICAgICAgICAgIV8uZmluZCh0aGlzLmNvbHVtbnMsIHt0eXBlOiAnaWQnfSkpIHtcbiAgICAgICAgICAgIHdpbmRvdy5hbGVydCgnUGxlYXNlIHNlbGVjdCBvbmUgb2YgeW91ciBmaWVsZHMgYXMgdGhlIFwiVW5pcXVlIEtleVwiJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZmllbGRzID0gdGhpcy5jb2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgaWYgKGNvbHVtbi5uYW1lID09PSBjb2x1bW4ucHJldmlvdXNOYW1lKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNvbHVtbi5wcmV2aW91c05hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY29sdW1uO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjaGFuZ2VzID0gWydhZGRzJywgJ3VwZGF0ZXMnLCAnZGVsZXRlcyddO1xuICAgICAgICBjaGFuZ2VzLmZvckVhY2goY2hhbmdlID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZVtjaGFuZ2VdID0gXy5tYXAoXy51bmlxKHRoaXNbY2hhbmdlXSksIHJvd0luZGV4ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3dzW3Jvd0luZGV4XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5uYW1lUHJlZml4ICYmICF0aGlzLmRhdGFzb3VyY2VVcGRhdGUudGl0bGUuaW5jbHVkZXModGhpcy5uYW1lUHJlZml4KSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlVXBkYXRlLnRpdGxlID0gdGhpcy5uYW1lUHJlZml4ICsgdGhpcy5kYXRhc291cmNlVXBkYXRlLnRpdGxlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzZXQgaW52YWxpZCBpdGVtc1xuICAgICAgICB0aGlzLmludmFsaWRJdGVtcyA9IFtdO1xuXG5cbiAgICAgICAgaWYgKCF0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRvbWF0aWNJbXBvcnRLZXkpe1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbXBvcnRLZXkgPSBzaG9ydEhhc2goRGF0ZS5ub3coKS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5kYXRhc291cmNlU2VydmljZS5jcmVhdGVDdXN0b21EYXRhc291cmNlKHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSkudGhlbihrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZXhpdCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHRoaXMucmVsb2FkVVJMICsgJy8nICsga2V5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JDb2RlID0gKGVyci5lcnJvciAmJiBlcnIuZXJyb3Iuc3FsU3RhdGVDb2RlKSA/IGVyci5lcnJvci5zcWxTdGF0ZUNvZGUgOiAwO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheUVycm9yKGVycm9yQ29kZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbXBvcnRLZXkgPSB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5zdGFuY2VJbXBvcnRLZXk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRhdGFzb3VyY2VTZXJ2aWNlLnVwZGF0ZUN1c3RvbURhdGFzb3VyY2UodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXksIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZSlcbiAgICAgICAgICAgICAgICAudGhlbihhc3luYyAocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQucmVqZWN0ZWQgJiYgcmVzdWx0LnJlamVjdGVkID4gMCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNuYWNrYmFyLm9wZW4oJ1RoZXJlIHdlcmUgdmFsaWRhdGlvbiBwcm9ibGVtcyB3aXRoIG9uZSBvciBtb3JlIG9mIHlvdXIgcm93cyAtIHNlZSBoaWdobGlnaHRlZCBjZWxscyBiZWxvdycsIG51bGwsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogNTAwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uOiAndG9wJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW52YWxpZEFkZFJvd3MgPSBfLm1hcChyZXN1bHQudmFsaWRhdGlvbkVycm9ycy5hZGQgfHwgW10sICdpdGVtTnVtYmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5hZGRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludmFsaWRBZGRSb3dzLmluY2x1ZGVzKGkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZEl0ZW1zW3RoaXMuYWRkc1tpXV0gPSBfLmZpbmQocmVzdWx0LnZhbGlkYXRpb25FcnJvcnMuYWRkLCB7aXRlbU51bWJlcjogaX0pLnZhbGlkYXRpb25FcnJvcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludmFsaWRVcGRhdGVSb3dzID0gXy5tYXAocmVzdWx0LnZhbGlkYXRpb25FcnJvcnMudXBkYXRlIHx8IFtdLCAnaXRlbU51bWJlcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMudXBkYXRlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnZhbGlkVXBkYXRlUm93cy5pbmNsdWRlcyhpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRJdGVtc1t0aGlzLnVwZGF0ZXNbaV1dID0gXy5maW5kKHJlc3VsdC52YWxpZGF0aW9uRXJyb3JzLnVwZGF0ZSwge2l0ZW1OdW1iZXI6IGl9KS52YWxpZGF0aW9uRXJyb3JzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGVzID0gW107XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdFUlJPUicsIGVycik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yQ29kZSA9IChlcnIuZXJyb3IgJiYgZXJyLmVycm9yLnNxbFN0YXRlQ29kZSkgPyBlcnIuZXJyb3Iuc3FsU3RhdGVDb2RlIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoZXJyb3JDb2RlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChleGl0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3RoaXMuYmFja1VSTF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNhbmNlbENoYW5nZXMoKSB7XG4gICAgICAgIHRoaXMuYWRkcyA9IFtdO1xuICAgICAgICB0aGlzLnVwZGF0ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5kZWxldGVzID0gW107XG5cbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRUeXBlQ29uZmlnKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRJdGVtLnR5cGVDb25maWcgfHwgQXJyYXkuaXNBcnJheSh0aGlzLnNlbGVjdGVkSXRlbS50eXBlQ29uZmlnKSkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0udHlwZUNvbmZpZyA9IHt9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZVNlbGVjdGVkQ29sdW1uKCkge1xuICAgICAgICB0aGlzLmNvbHVtbnMuc3BsaWNlKHRoaXMuc2VsZWN0ZWRJdGVtLl9pbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcHVibGljIHBhZ2VTaXplQ2hhbmdlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMubGltaXQgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5sb2FkRGF0YXNvdXJjZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZWFzZU9mZnNldCgpIHtcbiAgICAgICAgdGhpcy5wYWdlID0gdGhpcy5wYWdlICsgMTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAodGhpcy5saW1pdCAqIHRoaXMucGFnZSkgLSB0aGlzLmxpbWl0O1xuICAgICAgICB0aGlzLmxvYWREYXRhc291cmNlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlY3JlYXNlT2Zmc2V0KCkge1xuICAgICAgICB0aGlzLnBhZ2UgPSB0aGlzLnBhZ2UgPD0gMSA/IDEgOiB0aGlzLnBhZ2UgLSAxO1xuICAgICAgICB0aGlzLm9mZnNldCA9ICh0aGlzLmxpbWl0ICogdGhpcy5wYWdlKSAtIHRoaXMubGltaXQ7XG4gICAgICAgIHRoaXMubG9hZERhdGFzb3VyY2UoKTtcbiAgICB9XG5cblxuICAgIC8vIEdldCBpbnB1dCB0eXBlIGZvciBmaWVsZFxuICAgIHB1YmxpYyBpbnB1dFR5cGVGb3JGaWVsZChmaWVsZDogYW55KSB7XG4gICAgICAgIHN3aXRjaCAoZmllbGQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW50ZWdlcic6XG4gICAgICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdjaGVja2JveCc7XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2RhdGUnO1xuICAgICAgICAgICAgY2FzZSAnZGF0ZXRpbWUnOlxuICAgICAgICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUtbG9jYWwnO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGxvYWREYXRhc291cmNlKCkge1xuICAgICAgICBpZiAodGhpcy5kYXRhc291cmNlSW5zdGFuY2VLZXkpIHtcblxuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGZpbHRlciBpbiB1c2UsIGFwcGx5IGl0IHRvIHRoZSBuZXh0IGxvYWQuLi5cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzID0gW107XG4gICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJKdW5jdGlvbi5maWx0ZXJKdW5jdGlvbnMubGVuZ3RoIHx8IHRoaXMuZmlsdGVySnVuY3Rpb24uZmlsdGVyc1swXS5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb25JbnN0YW5jZXMucHVzaCh7dHlwZTogJ2ZpbHRlcicsIGNvbmZpZzogdGhpcy5maWx0ZXJKdW5jdGlvbn0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc29ydENvbmZpZykge1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uSW5zdGFuY2VzLnB1c2goe3R5cGU6ICdtdWx0aXNvcnQnLCBjb25maWc6IHtzb3J0czogW3RoaXMuc29ydENvbmZpZ119fSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlZERhdGFzb3VyY2UgPSB7XG4gICAgICAgICAgICAgICAga2V5OiB0aGlzLmRhdGFzb3VyY2VJbnN0YW5jZUtleSxcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1hdGlvbkluc3RhbmNlcyxcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJWYWx1ZXM6IHt9LFxuICAgICAgICAgICAgICAgIG9mZnNldDogdGhpcy5vZmZzZXQsXG4gICAgICAgICAgICAgICAgbGltaXQ6IHRoaXMubGltaXRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVNlcnZpY2UuZXZhbHVhdGVEYXRhc291cmNlKGV2YWx1YXRlZERhdGFzb3VyY2UpLnRoZW4oKHJlczogYW55KSA9PiB7XG5cbiAgICAgICAgICAgICAgICBsZXQganNvbkNvbHVtbnMgPSBbXTtcblxuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IHJlcy5jb2x1bW5zLm1hcChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4ucHJldmlvdXNOYW1lID0gY29sdW1uLm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbi50eXBlID09PSAncGlja2Zyb21zb3VyY2UnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29sdW1uUGlja0Zyb21EYXRhc2V0c1tjb2x1bW4ubmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gJ2pzb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqc29uQ29sdW1ucy5wdXNoKGNvbHVtbi5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2x1bW47XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJGaWVsZHMgPSBfLm1hcCh0aGlzLmNvbHVtbnMsIGNvbHVtbiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogY29sdW1uLnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogY29sdW1uLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJvd3MgPSByZXMuYWxsRGF0YTtcblxuICAgICAgICAgICAgICAgIC8vIElmIEpTT04gQ29sdW1ucywgZW5zdXJlIHdlIGRlc2VyaWFsaXNlIEpTT04gdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKGpzb25Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd3MuZm9yRWFjaChyb3cgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAganNvbkNvbHVtbnMuZm9yRWFjaChqc29uQ29sdW1uID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93W2pzb25Db2x1bW5dIHx8IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd1tqc29uQ29sdW1uXSA9IEpTT04uc3RyaW5naWZ5KHJvd1tqc29uQ29sdW1uXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRPZlJlc3VsdHMgPSB0aGlzLnJvd3MubGVuZ3RoIDwgdGhpcy5saW1pdDtcblxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS50aXRsZSA9IHJlcy5pbnN0YW5jZVRpdGxlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5pbnN0YW5jZUltcG9ydEtleSA9IHJlcy5pbnN0YW5jZUltcG9ydEtleTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuaW5kZXhlcyA9IHJlcy5pbmRleGVzO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZVVwZGF0ZS5hZGRzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlVXBkYXRlLnVwZGF0ZXMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2VVcGRhdGUuZGVsZXRlcyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5hdXRvSW5jcmVtZW50Q29sdW1uID0gXy5zb21lKHRoaXMuY29sdW1ucywge3R5cGU6ICdpZCd9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0QWxsID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVkaXRNb2RlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZWxlY3RDZWxsKHJvd0luZGV4LCBjZWxsSW5kZXgpIHtcbiAgICAgICAgbGV0IHJvd1N0YXJ0LCByb3dFbmQsIGNlbGxTdGFydCwgY2VsbEVuZDtcblxuICAgICAgICBpZiAocm93SW5kZXggPCB0aGlzLnN0YXJ0Um93SW5kZXgpIHtcbiAgICAgICAgICAgIHJvd1N0YXJ0ID0gcm93SW5kZXg7XG4gICAgICAgICAgICByb3dFbmQgPSB0aGlzLnN0YXJ0Um93SW5kZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByb3dTdGFydCA9IHRoaXMuc3RhcnRSb3dJbmRleDtcbiAgICAgICAgICAgIHJvd0VuZCA9IHJvd0luZGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNlbGxJbmRleCA8IHRoaXMuc3RhcnRDZWxsSW5kZXgpIHtcbiAgICAgICAgICAgIGNlbGxTdGFydCA9IGNlbGxJbmRleDtcbiAgICAgICAgICAgIGNlbGxFbmQgPSB0aGlzLnN0YXJ0Q2VsbEluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2VsbFN0YXJ0ID0gdGhpcy5zdGFydENlbGxJbmRleDtcbiAgICAgICAgICAgIGNlbGxFbmQgPSBjZWxsSW5kZXg7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gcm93U3RhcnQ7IGkgPD0gcm93RW5kOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJvd0VsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGFibGUtcm93cycpLml0ZW0oaSk7XG4gICAgICAgICAgICBjb25zdCByb3dDZWxscyA9IHJvd0VsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgndGQnKTtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBjZWxsU3RhcnQ7IGogPD0gY2VsbEVuZDsgaisrKSB7XG4gICAgICAgICAgICAgICAgcm93Q2VsbHMuaXRlbShqKS5jbGFzc0xpc3QuYWRkKCdiZy1pbmRpZ28tNTAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlQ2VsbEZvY3VzQm9yZGVyKCkge1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuaW5wdXQtd3JhcHBlci5ib3JkZXItYmx1ZS01MDAnKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdib3JkZXItYmx1ZS01MDAnKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbnNlcnRDZWxsRGF0YShkYXRhKSB7XG4gICAgICAgIGNvbnN0IHJvdyA9IHt9O1xuICAgICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgcm93W2NvbHVtbi5uYW1lXSA9ICcnO1xuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgc3RhcnRJbmRleCA9IHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4O1xuICAgICAgICB3aGlsZSAodGhpcy5yb3dzLmxlbmd0aCA8IChkYXRhLmxlbmd0aCArIHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4KSkge1xuICAgICAgICAgICAgdGhpcy5yb3dzLnB1c2goXy5jbG9uZShyb3cpKTtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlcy5zcGxpY2Uoc3RhcnRJbmRleCwgMSk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZXMuc3BsaWNlKHN0YXJ0SW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5hZGRzLnNwbGljZShzdGFydEluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMuYWRkcy5wdXNoKHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgc3RhcnRJbmRleCsrO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJvd0luZGV4ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4OyBpIDwgKHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0luZGV4ICsgZGF0YS5sZW5ndGgpOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB2YWxJbmRleCA9IDA7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBfLnZhbHVlcyhkYXRhW3Jvd0luZGV4XSk7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gdGhpcy5zZWxlY3RlZENlbGwucm93Q29sSW5kZXg7IGogPCAodmFsdWVzLmxlbmd0aCArIHRoaXMuc2VsZWN0ZWRDZWxsLnJvd0NvbEluZGV4KTsgaisrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29sdW1uc1tqXSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd3NbaV1bdGhpcy5jb2x1bW5zW2pdLm5hbWVdID0gdmFsdWVzW3ZhbEluZGV4XSB8fCAnJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFsSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJvd0luZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRpc3BsYXlFcnJvcihjb2RlOiBhbnkpIHtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSAnVGhlcmUgd2FzIGFuIGVycm9yIGNyZWF0aW5nL2VkaXRpbmcgeW91ciBkYXRhIHNvdXJjZS4gUGxlYXNlIGNoZWNrIGFuZCB0cnkgYWdhaW4uJztcblxuICAgICAgICBzd2l0Y2ggKE51bWJlcihjb2RlKSkge1xuICAgICAgICAgICAgY2FzZSAyMzAwMDpcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gJ0R1cGxpY2F0ZSBVbmlxdWUgS2V5IEZvdW5kLiBQbGVhc2UgY2hlY2sgZm9yIGR1cGxpY2F0ZSB2YWx1ZXMgaW4gdW5pcXVlIGlkZW50aXR5IGNvbHVtbi4nO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zbmFja2Jhci5vcGVuKG1lc3NhZ2UsIG51bGwsIHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiA1MDAwLFxuICAgICAgICAgICAgdmVydGljYWxQb3NpdGlvbjogJ3RvcCdcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNlbGVjdENvbHVtblBpY2tGcm9tRGF0YXNvdXJjZShjb2x1bW46IGFueSkge1xuXG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ3JlYXRlRGF0YXNldENvbXBvbmVudCwge1xuICAgICAgICAgICAgd2lkdGg6ICcxMjAwcHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnODAwcHgnLFxuICAgICAgICAgICAgZGF0YToge31cbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShhc3luYyByZXMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgIGNvbHVtbi50eXBlQ29uZmlnID0ge1xuICAgICAgICAgICAgICAgICAgICBkYXRhc2V0SW5zdGFuY2VJZDogcmVzLmRhdGFzZXRJbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICBkYXRhc291cmNlSW5zdGFuY2VLZXk6IHJlcy5kYXRhc291cmNlSW5zdGFuY2VLZXlcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gUG9wdWxhdGUgdGhlIGNvbHVtbiBwaWNrIGZyb21cbiAgICAgICAgICAgICAgICB0aGlzLnBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvLyBQaWNrIGZyb20gZGF0YXNldHNcbiAgICBwcml2YXRlIHBvcHVsYXRlQ29sdW1uUGlja0Zyb20oY29sdW1uOiBhbnkpIHtcbiAgICAgICAgdGhpcy5kYXRhc2V0U2VydmljZS5ldmFsdWF0ZURhdGFzZXQoY29sdW1uLnR5cGVDb25maWcsICcwJywgJzEwMDAwMDAwJykudGhlbigoZGF0YXNldCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb2x1bW5QaWNrRnJvbURhdGFzZXRzW2NvbHVtbi5uYW1lXSA9IGRhdGFzZXQ7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJib3JkZXItYiB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIFwiPlxuICAgIDxkaXYgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICAgICAgY2xhc3M9XCJsZWFkaW5nLTUgZmxleCBpdGVtcy1jZW50ZXIgcHgtNCB0ZXh0LXhzIHctOTYgdXBwZXJjYXNlIHRyYWNraW5nLXdpZGVyIGZvbnQtbWVkaXVtIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgTmFtZVxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInctZnVsbCBweS0xLjUgbWwtNFwiIHBsYWNlaG9sZGVyPVwiRW50ZXIgZGF0YXNvdXJjZSBuYW1lXCJcbiAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYm9yZGVyIGJvcmRlci1yZWQtNTAwJzogIWRhdGFzb3VyY2VVcGRhdGUudGl0bGV9XCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0YXNvdXJjZVVwZGF0ZS50aXRsZVwiPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJyZWFkb25seVwiXG4gICAgICAgICBjbGFzcz1cImxlYWRpbmctNSBmb250LW1lZGl1bSB0ZXh0LWxnIHB4LTRcIj57e2RhdGFzb3VyY2VVcGRhdGUudGl0bGUucmVwbGFjZSgobmFtZVByZWZpeCB8fCAnJyksICcnKX19PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZsZXgtMSBmbGV4IGl0ZW1zLWNlbnRlciBmbGV4LXdyYXAgdy1mdWxsIGp1c3RpZnktZW5kIGJnLXdoaXRlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJfLnNvbWUocm93cywgJ19zZWxlY3RlZCcpXCI+XG4gICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJkZWxldGVTZWxlY3RlZEVudHJpZXMoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0yOCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPmRlbGV0ZV9mb3JldmVyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICBkZWxldGUgc2VsZWN0ZWRcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIWVkaXRNb2RlXCIgKGNsaWNrKT1cInNob3dGaWx0ZXJzID0gIXNob3dGaWx0ZXJzXCJcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7J2JhY2tncm91bmQtY29sb3InOiB0aGlzLnNob3dGaWx0ZXJzID8gJyMwMDAwMDAxMicgOiAnJ31cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidy0yMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ0ZXh0LXhsXCI+ZmlsdGVyX2FsdDwvbWF0LWljb24+XG4gICAgICAgICAgICBmaWx0ZXJcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIhZWRpdE1vZGVcIiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cIiFlZGl0TW9kZVwiIChjbGljayk9XCJhZHZhbmNlZFNldHRpbmdzKClcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2VJbnN0YW5jZUtleVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIHctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPnR1bmU8L21hdC1pY29uPlxuICAgICAgICAgICAgYWR2YW5jZWRcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCIhZWRpdE1vZGUgJiYgIWhpZGVBUElBY2Nlc3NcIiAoY2xpY2spPVwiYXBpQWNjZXNzKClcIiBbZGlzYWJsZWRdPVwiIWRhdGFzb3VyY2VJbnN0YW5jZUtleVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkaXNhYmxlZDpvcGFjaXR5LTUwIHctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPmFwaTwvbWF0LWljb24+XG4gICAgICAgICAgICBhcGkgYWNjZXNzXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIWVkaXRNb2RlXCIgKGNsaWNrKT1cImltcG9ydCgpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInctMjAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcHktMSBweC0yIHRleHQteHMgdGV4dC1ncmF5LTYwMCBjdXJzb3ItcG9pbnRlciBob3ZlcjpiZy1ncmF5LTEwMFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC14bFwiPnVwbG9hZF9maWxlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIHVwbG9hZFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFlZGl0TW9kZVwiIGNsYXNzPVwiZGl2aWRlclwiPjwvZGl2PlxuXG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJlZGl0TW9kZVwiIChjbGljayk9XCJjYW5jZWxDaGFuZ2VzKClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZGlzYWJsZWQ6b3BhY2l0eS01MCB3LTIwIGZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHB5LTEgcHgtMiB0ZXh0LXhzIHRleHQtZ3JheS02MDAgY3Vyc29yLXBvaW50ZXIgaG92ZXI6YmctZ3JheS0xMDBcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQteGxcIj5jYW5jZWw8L21hdC1pY29uPlxuICAgICAgICAgICAgY2FuY2VsIGVkaXRcbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwic2F2ZSgpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImRpc2FibGVkOm9wYWNpdHktNTAgdy0yMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBweS0xIHB4LTIgdGV4dC14cyB0ZXh0LWdyYXktNjAwIGN1cnNvci1wb2ludGVyIGhvdmVyOmJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJ0ZXh0LXhsXCI+c2F2ZTwvbWF0LWljb24+XG4gICAgICAgICAgICBzYXZlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuPC9kaXY+XG48ZGl2ICpuZ0lmPVwic2hvd0ZpbHRlcnNcIiBjbGFzcz1cImRhdGFzZXQtZmlsdGVyc1wiPlxuICAgIDxkaXYgY2xhc3M9XCJkYXRhc2V0LWZpbHRlciBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5cblxuICAgICAgICA8a2ktZGF0YXNldC1maWx0ZXJzICpuZ0lmPVwiY29sdW1ucy5sZW5ndGhcIiBbZmlsdGVyRmllbGRzXT1cImZpbHRlckZpZWxkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wZW5TaWRlXT1cIm9wZW5TaWRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsdGVySnVuY3Rpb25dPVwiZmlsdGVySnVuY3Rpb25cIj48L2tpLWRhdGFzZXQtZmlsdGVycz5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgYXBwbHktZmlsdGVyXCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjbGFzcz1cIm1yLTIgYmctd2hpdGVcIiBjb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJGaWx0ZXIoKVwiPlxuICAgICAgICAgICAgICAgIENsZWFyIEZpbHRlclxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiBjbGFzcz1cIm1yLTJcIiBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlGaWx0ZXIoKVwiIFtkaXNhYmxlZF09XCIhZmlsdGVySnVuY3Rpb24uZmlsdGVycy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICBBcHBseSBGaWx0ZXJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuXG4gICAgPC9kaXY+XG48L2Rpdj5cbjxkaXYgY2xhc3M9XCJmbGV4IGNyZWF0ZS1kYXRhc291cmNlLWNvbnRhaW5lclwiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4LTEgcmVsYXRpdmUgb3ZlcmZsb3cteS1zY3JvbGwgdGFibGUtc2Nyb2xsXCI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNyZWF0ZS1kYXRhc291cmNlXCI+XG4gICAgICAgICAgICA8ZGl2IGlkPVwidGFibGVXcmFwcGVyXCIgY2xhc3M9XCJmbGV4LTEgb3ZlcmZsb3cteS1zY3JvbGwgcmVsYXRpdmVcIj5cbiAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJkYXRhc291cmNlLXRhYmxlIHRhYmxlLWZpeGVkIHctZnVsbCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ3LTEwIHJlbGF0aXZlIGN1cnNvci1wb2ludGVyIGJnLWdyYXktMTAwIHAtMCBzdGlja3kgdGV4dC14c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RBbGxcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTZWxlY3RBbGwoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtY29sdW1uIFtuZ0Zvck9mXT1cImNvbHVtbnNcIiBsZXQtY29sSW5kZXg9aW5kZXg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIFtpZF09XCJjb2x1bW4udHlwZSArIGNvbEluZGV4XCIgKm5nSWY9XCJjb2x1bW4udHlwZSA9PT0gJ2lkJyA/IHNob3dBdXRvSW5jcmVtZW50IDogdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy02NCByZWxhdGl2ZSBjdXJzb3ItcG9pbnRlciBiZy1ncmF5LTEwMCBwLTIgc3RpY2t5IHRleHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2JnLWluZGlnby01MCc6IHNlbGVjdGVkSXRlbS5faW5kZXggPT09IGNvbEluZGV4LCAnYm9yZGVyLXItMCc6IChjb2xJbmRleCArIDEpID09PSBjb2x1bW5zLmxlbmd0aH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByLTggdy1mdWxsIGhlYWRlci10aXRsZVwiIChjbGljayk9XCJzZWxlY3RDb2x1bW4oY29sdW1uLCBjb2xJbmRleClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbHVtbi50aXRsZSB9fSZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cImNvbHVtbi5rZXlGaWVsZCB8fCBjb2x1bW4udHlwZSA9PT0naWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTUgaC01IHRleHQteWVsbG93LTUwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNOCA3YTUgNSAwIDExMy42MSA0LjgwNGwtMS45MDMgMS45MDNBMSAxIDAgMDE5IDE0SDh2MWExIDEgMCAwMS0xIDFINnYxYTEgMSAwIDAxLTEgMUgzYTEgMSAwIDAxLTEtMXYtMmExIDEgMCAwMS4yOTMtLjcwN0w4LjE5NiA4LjM5QTUuMDAyIDUuMDAyIDAgMDE4IDd6bTUtM2EuNzUuNzUgMCAwMDAgMS41QTEuNSAxLjUgMCAwMTE0LjUgNyAuNzUuNzUgMCAwMDE2IDdhMyAzIDAgMDAtMy0zelwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcC1ydWxlPVwiZXZlbm9kZFwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImhlYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSBoZWFkZXItYWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPm1vcmVfdmVydDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW1lbnUgI2hlYWRlcj1cIm1hdE1lbnVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwic29ydENvbHVtbihjb2x1bW4sICdhc2MnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvcnQgQXNjZW5kaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImgtNiB3LTZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTMgNC41aDE0LjI1TTMgOWg5Ljc1TTMgMTMuNWg1LjI1bTUuMjUtLjc1TDE3LjI1IDltMCAwTDIxIDEyLjc1TTE3LjI1IDl2MTJcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cInNvcnRDb2x1bW4oY29sdW1uLCAnZGVzYycpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29ydCBEZXNjZW5kaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImgtNiB3LTZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTMgNC41aDE0LjI1TTMgOWg5Ljc1TTMgMTMuNWg5Ljc1bTQuNS00LjV2MTJtMCAwLTMuNzUtMy43NU0xNy4yNSAyMSAyMSAxNy4yNVwiLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJjb2x1bW4udHlwZSAhPT0gJ2lkJyAmJiBlZGl0Q29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiYWRkQ29sdW1uKGNvbEluZGV4ID09PSAwID8gMCA6IGNvbEluZGV4IC0gMSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zZXJ0IGNvbHVtbiBiZWZvcmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZWRpdENvbHVtbnNcIiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJhZGRDb2x1bW4oY29sSW5kZXggKyAxKVwiPkluc2VydCBjb2x1bW4gYWZ0ZXI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJlZGl0Q29sdW1uc1wiIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImRlbGV0ZUNvbHVtbihjb2xJbmRleClcIj5EZWxldGUgY29sdW1uPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW1lbnU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwidGFibGUtcm93c1wiIFtuZ0NsYXNzXT1cInsnYmctZ3JheS0yMDAgb3BhY2l0eS0zMCc6IHRoaXMuZGVsZXRlcy5pbmRleE9mKHJvd0luZGV4KSA+IC0xLFxuICAgICAgICAgICAgICAgICAgICAnYmctZ3JlZW4tNTAnOiB0aGlzLmFkZHMuaW5kZXhPZihyb3dJbmRleCkgPiAtMSwgJ2JnLWluZGlnby0xMDAnOiB0aGlzLnVwZGF0ZXMuaW5kZXhPZihyb3dJbmRleCkgPiAtMX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHJvdyBvZiByb3dzOyBsZXQgcm93SW5kZXggPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0wIHJvdy1jZWxsIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInJvdy5fc2VsZWN0ZWRcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTZWxlY3RlZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1yb3dDb2x1bW4gW25nRm9yT2ZdPVwiY29sdW1uc1wiIGxldC1yb3dDb2xJbmRleD1pbmRleD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJyb3dDb2x1bW4udHlwZSA9PT0gJ2lkJyA/IHNob3dBdXRvSW5jcmVtZW50IDogdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYmctaW5kaWdvLTUwJzogc2VsZWN0ZWRJdGVtLl9pbmRleCA9PT0gcm93Q29sSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ctMjQgYmctZ3JheS0xMDAnOiBjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlID09PSAnaWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdiZy1ncmF5LTEwMCc6IGNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkICYmIHRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA9PT0gLTF9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwLTAgcm93LWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJweS0xIHB4LTIgaC1mdWxsIHctZnVsbCBib3JkZXIgYm9yZGVyLXRyYW5zcGFyZW50IGlucHV0LXdyYXBwZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIHJlbGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJwLTAgYm9yZGVyLW5vbmUgdy1mdWxsIGJnLXRyYW5zcGFyZW50IHByLTEwIGNlbGwtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImlucHV0VHlwZUZvckZpZWxkKHJvd0NvbHVtbilcIiAjZmllbGQ9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd1tyb3dDb2x1bW4ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdGVwXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwiY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZUNvbmZpZyA/IGNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGVDb25maWcubWF4aW11bVZhbHVlIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlQ29uZmlnID8gY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZUNvbmZpZy5taW5pbXVtVmFsdWUgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgIT09ICdpZCcgJiYgY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZSAhPT0gJ3BpY2tmcm9tc291cmNlJyAgJiYgY29sdW1uc1tyb3dDb2xJbmRleF0udHlwZSAhPT0gJ2Jvb2xlYW4nICYmICFjb2x1bW5zW3Jvd0NvbEluZGV4XS5rZXlGaWVsZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ1cGRhdGVGaWVsZChyb3dDb2x1bW4sIHJvd0luZGV4LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwiZm9jdXNDZWxsKCRldmVudCwgcm93SW5kZXgsIHJvd0NvbEluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cImVudGVyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgsICRldmVudClcIj5cblxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJwLTAgYm9yZGVyLW5vbmUgdy1mdWxsIGJnLXRyYW5zcGFyZW50IHByLTEwIGNlbGwtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiICNmaWVsZD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0ZXBdPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlID09PSAnYm9vbGVhbicgJiYgIWNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUZpZWxkKHJvd0NvbHVtbiwgcm93SW5kZXgsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJmb2N1c0NlbGwoJGV2ZW50LCByb3dJbmRleCwgcm93Q29sSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwiZW50ZXJDZWxsKHJvd0luZGV4LCByb3dDb2xJbmRleCwgJGV2ZW50KVwiPlxuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgPT0gJ3BpY2tmcm9tc291cmNlJyAmJiBjb2x1bW5QaWNrRnJvbURhdGFzZXRzW3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LWZ1bGwgcHItMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC0wIGJvcmRlci1ub25lIHctZnVsbCBiZy10cmFuc3BhcmVudCBjZWxsLWlucHV0IG91dGxpbmUtbm9uZSByaW5nLTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZmllbGQ9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dbcm93Q29sdW1uLm5hbWVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ1cGRhdGVGaWVsZChmaWVsZCwgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzQ2VsbCgkZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwiZW50ZXJDZWxsKHJvd0luZGV4LCByb3dDb2xJbmRleCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgcGlja0Zyb20gb2YgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tyb3dDb2x1bW4ubmFtZV0uYWxsRGF0YVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGlja0Zyb21bcm93Q29sdW1uLnR5cGVDb25maWcudmFsdWVGaWVsZE5hbWVdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BpY2tGcm9tW3Jvd0NvbHVtbi50eXBlQ29uZmlnLmxhYmVsRmllbGROYW1lXX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbnNbcm93Q29sSW5kZXhdLnR5cGUgPT09ICdpZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1ncmF5LTUwMCB0ZXh0LXhzXCI+e3sgcm93W3Jvd0NvbHVtbi5uYW1lXSB8fCAnPFxcZ2VuZXJhdGVkXFw+JyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbHVtbnNbcm93Q29sSW5kZXhdLmtleUZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInRoaXMuYWRkcy5pbmRleE9mKHJvd0luZGV4KSA+IC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cInAtMCBib3JkZXItbm9uZSB3LWZ1bGwgYmctdHJhbnNwYXJlbnQgcHItNSBjZWxsLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgI2ZpZWxkPVwibmdNb2RlbFwiIFsobmdNb2RlbCldPVwicm93W3Jvd0NvbHVtbi5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUZpZWxkKGZpZWxkLCByb3dJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cImZvY3VzQ2VsbCgkZXZlbnQsIHJvd0luZGV4LCByb3dDb2xJbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cImVudGVyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ0aGlzLmFkZHMuaW5kZXhPZihyb3dJbmRleCkgPT09IC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWdyYXktNTAwIHRleHQteHNcIj57eyByb3dbcm93Q29sdW1uLm5hbWVdIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIG1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgcmlnaHQtMCB3LTEwIHRleHQtb3JhbmdlLTUwMCB0ZXh0LWxnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImludmFsaWRJdGVtc1tyb3dJbmRleF0gJiYgaW52YWxpZEl0ZW1zW3Jvd0luZGV4XVtyb3dDb2x1bW4ubmFtZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImludmFsaWRJdGVtc1tyb3dJbmRleF1bcm93Q29sdW1uLm5hbWVdXCI+d2FybmluZzwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIGNlbGwtYWN0aW9uc1wiIHRhYmluZGV4PVwiLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiYWRkUm93KHJvd0luZGV4ICsgMSlcIj5BZGQgcm93PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIChjbGljayk9XCJkZWxldGVSb3cocm93SW5kZXgpXCI+RGVsZXRlIHJvdzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJjb2x1bW5zW3Jvd0NvbEluZGV4XS50eXBlICE9PSAnaWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cImNsZWFyQ2VsbChyb3dJbmRleCwgcm93Q29sSW5kZXgpXCI+Q2xlYXIgY2VsbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwiYWRkUm93KClcIiB0aXRsZT1cIkFkZCBSb3dcIlxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBmbGV4IGl0ZW1zLWNlbnRlciB0ZXh0LXNtIG0tMiBwLTEgYmctZ3JheS0xMDAgcm91bmRlZC1tZFwiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwibWwtMlwiIG1hdC1pY29uLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hZGRfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIEFkZCBuZXcgcm93XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLXQgYmctZ3JheS01MCBweS0yIGZsZXggYWxpZ24tY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJtbC0yXCIgbWF0LWljb24tYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHRpdGxlPVwiQWRkIFJvd1wiIChjbGljayk9XCJhZGRSb3coKVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFlZGl0TW9kZVwiIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgdGV4dC1ncmF5LTQwMCBtci0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgU2hvd2luZyB7e29mZnNldCArIDF9fVxuICAgICAgICAgICAgICAgICAgICAgICAgLSB7eyhwYWdlICogbGltaXQpIC0gKGxpbWl0IC0gcm93cy5sZW5ndGgpfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbdmFsdWVdPVwibGltaXRcIiAoY2hhbmdlKT1cInBhZ2VTaXplQ2hhbmdlKCRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1yLTggcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMFwiPjEwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIyNVwiPjI1PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCI1MFwiPjUwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCIxMDBcIj4xMDA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIjI1MFwiPjI1MDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiMTAwMFwiPjEwMDA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNsYXNzPVwibXItNFwiIChjbGljayk9XCJkZWNyZWFzZU9mZnNldCgpXCIgW2Rpc2FibGVkXT1cInBhZ2UgPD0gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmNoZXZyb25fbGVmdDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwiaW5jcmVhc2VPZmZzZXQoKVwiIFtkaXNhYmxlZF09XCJlbmRPZlJlc3VsdHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jaGV2cm9uX3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWwgYm9yZGVyLXIgYmctZ3JheS01MCAtbWwtMi41XCI+XG4gICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHRpdGxlPVwiQWRkIENvbHVtblwiIChjbGljayk9XCJhZGRDb2x1bW4oKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCItbXQtMC41XCI+XG4gICAgICAgICAgICA8bWF0LWljb24+YWRkX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cIk9iamVjdC5rZXlzKHNlbGVjdGVkSXRlbSkubGVuZ3RoXCIgY2xhc3M9XCJiZy1ncmF5LTEwMCB3LTcyIGgtZnVsbCBwLTMgZmxleCBqdXN0aWZ5LWJldHdlZW4gZmxleC1jb2xcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1cHBlcmNhc2UgZm9udC1tZWRpdW0gdHJhY2tpbmctd2lkZXIgbWItNCB0ZXh0LXhzIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgICAgICAgICBTZXR0aW5nc1xuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxociBjbGFzcz1cIm15LTRcIj5cblxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cInNlbGVjdGVkSXRlbS5fdGFibGVUeXBlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInVwcGVyY2FzZSBmb250LW1lZGl1bSB0cmFja2luZy13aWRlciBtYi00IHRleHQteHMgdGV4dC1ncmF5LTYwMFwiPlxuICAgICAgICAgICAgICAgICAgICBDb2x1bW5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgKm5nSWY9XCJkYXRhc291cmNlVXBkYXRlLmluc3RhbmNlSW1wb3J0S2V5XCIgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgIENvbHVtbiBLZXlcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0ubmFtZVwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICBDb2x1bW4gVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udGl0bGVcIiBwbGFjZWhvbGRlcj1cIkVudGVyIGNvbHVtbiB0aXRsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZUNvbHVtbk5hbWUoKVwiPlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwic2VsZWN0ZWRJdGVtLnR5cGUgPT09ICdpZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uIFR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udHlwZVwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIidpZCdcIj5JRDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJzZWxlY3RlZEl0ZW0udHlwZSAhPT0gJ2lkJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW4gVHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS50eXBlXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VHlwZUNvbmZpZygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPi0tIFNlbGVjdCBjb2x1bW4gdHlwZSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHR5cGUgb2YgT2JqZWN0LmtleXMoZGF0YXNvdXJjZVR5cGVzKVwiIFt2YWx1ZV09XCJ0eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFzb3VyY2VUeXBlc1t0eXBlXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMlwiXG4gICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkSXRlbS50eXBlQ29uZmlnICYmIHNlbGVjdGVkSXRlbS50eXBlID09ICdpbnRlZ2VyJyB8fCBzZWxlY3RlZEl0ZW0udHlwZSA9PSAnZmxvYXQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1iLTQgdy0zMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgTWluaW11bSBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cInB5LTEgcHgtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEl0ZW0udHlwZUNvbmZpZy5taW5pbXVtVmFsdWVcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHZhbHVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtYi00IHctMzJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1heGltdW0gVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJweS0xIHB4LTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcubWF4aW11bVZhbHVlXCIgcGxhY2Vob2xkZXI9XCJFbnRlciB2YWx1ZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnR5cGUgPT0gJ3BpY2tmcm9tc291cmNlJ1wiIGNsYXNzPVwibWItNFwiPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZEl0ZW0udHlwZUNvbmZpZyAmJiBjb2x1bW5QaWNrRnJvbURhdGFzZXRzW3NlbGVjdGVkSXRlbS5uYW1lXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBEYXRhc291cmNlOiA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWdyYXktNTAwXCI+e3sgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV0uaW5zdGFuY2VUaXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInNlbGVjdENvbHVtblBpY2tGcm9tRGF0YXNvdXJjZShzZWxlY3RlZEl0ZW0pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3QgRGF0YXNvdXJjZVxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcgJiYgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV1cIiBjbGFzcz1cIm10LTRcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwIHNtOm10LXB4IHNtOnB0LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYWJlbCBjb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSBzbTpjb2wtc3Bhbi0yIHNtOm10LTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnR5cGVDb25maWcubGFiZWxGaWVsZE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJibG9jayB3LWZ1bGwgbWF4LXctbGcgcm91bmRlZC1tZCBib3JkZXItZ3JheS0zMDAgc2hhZG93LXNtIGZvY3VzOmJvcmRlci1pbmRpZ28tNTAwIGZvY3VzOnJpbmctaW5kaWdvLTUwMCBzbTptYXgtdy14cyBzbTp0ZXh0LXNtIHB5LTEgcHgtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sdW1uUGlja0Zyb21EYXRhc2V0c1tzZWxlY3RlZEl0ZW0ubmFtZV0uY29sdW1uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi50aXRsZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMCBzbTptdC1weCBzbTpwdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgY29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTEgc206Y29sLXNwYW4tMiBzbTptdC0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS50eXBlQ29uZmlnLnZhbHVlRmllbGROYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYmxvY2sgdy1mdWxsIG1heC13LWxnIHJvdW5kZWQtbWQgYm9yZGVyLWdyYXktMzAwIHNoYWRvdy1zbSBmb2N1czpib3JkZXItaW5kaWdvLTUwMCBmb2N1czpyaW5nLWluZGlnby01MDAgc206bWF4LXcteHMgc206dGV4dC1zbSBweS0xIHB4LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtblBpY2tGcm9tRGF0YXNldHNbc2VsZWN0ZWRJdGVtLm5hbWVdLmNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb2x1bW4ubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb2x1bW4udGl0bGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjbGFzcz1cIm1iLTRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRJdGVtLnJlcXVpcmVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBSZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggY2xhc3M9XCJtYi00XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb25Pbk51bGxPbmx5XCIgKGNoYW5nZSk9XCIhKCRldmVudC5jaGVja2VkKSA/IHNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb24gPSAnJyA6IG51bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEhhcyBEZWZhdWx0IFZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGxhYmVsICpuZ0lmPVwic2VsZWN0ZWRJdGVtLnZhbHVlRXhwcmVzc2lvbk9uTnVsbE9ubHlcIiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkSXRlbS52YWx1ZUV4cHJlc3Npb25cIiBwbGFjZWhvbGRlcj1cIkVudGVyIGRlZmF1bHQgdmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY29sb3I9XCJ3YXJuXCIgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGVkQ29sdW1uKClcIj5EZWxldGUgQ29sdW1uPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJteS00XCI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwic2F2ZSh0cnVlKVwiPlxuICAgICAgICAgICAgU2F2ZSAmIEV4aXRcbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuXG4iXX0=