spiderly 19.0.0 → 19.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 (219) hide show
  1. package/fesm2022/spiderly.mjs +1996 -2189
  2. package/fesm2022/spiderly.mjs.map +1 -1
  3. package/lib/components/auth/login/login.component.d.ts +1 -1
  4. package/lib/components/auth/registration/registration.component.d.ts +1 -1
  5. package/lib/components/spiderly-buttons/spiderly-button-base/spiderly-button-base.d.ts +1 -1
  6. package/lib/entities/primeng-option.d.ts +3 -3
  7. package/lib/interceptors/http-loading.interceptor.d.ts +2 -11
  8. package/lib/interceptors/json-parser.interceptor.d.ts +2 -11
  9. package/lib/interceptors/jwt.interceptor.d.ts +2 -11
  10. package/lib/interceptors/unauthorized.interceptor.d.ts +2 -16
  11. package/lib/modules/core.module.d.ts +2 -13
  12. package/lib/modules/primeng.module.d.ts +4 -4
  13. package/lib/modules/spiderly-transloco.module.d.ts +2 -1
  14. package/package.json +15 -16
  15. package/public-api.d.ts +2 -1
  16. package/styles/components/spiderly-data-table/spiderly-data-table.component.scss +15 -0
  17. package/styles/components/spiderly-panels/panel-footer/panel-footer.component.scss +3 -3
  18. package/styles/components/spiderly-panels/spiderly-panel/spiderly-panel.component.scss +11 -0
  19. package/styles/styles/layout/_config.scss +2 -2
  20. package/styles/styles/layout/_content.scss +2 -0
  21. package/styles/styles/layout/_footer.scss +2 -0
  22. package/styles/styles/layout/_main.scss +6 -3
  23. package/styles/styles/layout/_menu.scss +10 -7
  24. package/styles/styles/layout/_mixins.scss +2 -2
  25. package/styles/styles/layout/_preloading.scss +1 -1
  26. package/styles/styles/layout/_responsive.scss +2 -0
  27. package/styles/styles/layout/_spiderly-controls.scss +2 -0
  28. package/styles/styles/layout/_topbar.scss +16 -11
  29. package/styles/styles/layout/_typography.scss +1 -1
  30. package/styles/styles/layout/_utils.scss +1 -1
  31. package/styles/styles/layout/_variables.scss +59 -53
  32. package/styles/styles/layout/layout.scss +13 -13
  33. package/styles/styles/shared.scss +70 -42
  34. package/styles/styles/styles.scss +2 -5
  35. package/esm2022/lib/components/auth/auth.module.mjs +0 -65
  36. package/esm2022/lib/components/auth/login/login.component.mjs +0 -60
  37. package/esm2022/lib/components/auth/partials/auth.component.mjs +0 -53
  38. package/esm2022/lib/components/auth/partials/login-verification.component.mjs +0 -39
  39. package/esm2022/lib/components/auth/partials/registration-verification.component.mjs +0 -37
  40. package/esm2022/lib/components/auth/partials/verification-wrapper.component.mjs +0 -74
  41. package/esm2022/lib/components/auth/registration/registration.component.mjs +0 -59
  42. package/esm2022/lib/components/base-details/role-base-details.component.mjs +0 -171
  43. package/esm2022/lib/components/base-form/base-form copy.mjs +0 -247
  44. package/esm2022/lib/components/card-skeleton/card-skeleton.component.mjs +0 -25
  45. package/esm2022/lib/components/footer/footer.component.mjs +0 -16
  46. package/esm2022/lib/components/index-card/index-card.component.mjs +0 -57
  47. package/esm2022/lib/components/info-card/info-card.component.mjs +0 -29
  48. package/esm2022/lib/components/layout/layout-base.component.mjs +0 -121
  49. package/esm2022/lib/components/layout/sidebar/menuitem.component.mjs +0 -161
  50. package/esm2022/lib/components/layout/sidebar/sidebar-menu.component.mjs +0 -34
  51. package/esm2022/lib/components/layout/sidebar/sidebar-menu.service.mjs +0 -26
  52. package/esm2022/lib/components/layout/sidebar/sidebar.component.mjs +0 -21
  53. package/esm2022/lib/components/layout/topbar/topbar.component.mjs +0 -115
  54. package/esm2022/lib/components/not-found/not-found.component.mjs +0 -20
  55. package/esm2022/lib/components/required/required.component.mjs +0 -12
  56. package/esm2022/lib/components/spiderly-buttons/google-button/google-button.component.mjs +0 -43
  57. package/esm2022/lib/components/spiderly-buttons/return-button/return-button.component.mjs +0 -37
  58. package/esm2022/lib/components/spiderly-buttons/spiderly-button/spiderly-button.component.mjs +0 -20
  59. package/esm2022/lib/components/spiderly-buttons/spiderly-button-base/spiderly-button-base.mjs +0 -68
  60. package/esm2022/lib/components/spiderly-buttons/spiderly-split-button/spiderly-split-button.component.mjs +0 -22
  61. package/esm2022/lib/components/spiderly-data-table/spiderly-data-table.component.mjs +0 -501
  62. package/esm2022/lib/components/spiderly-delete-dialog/spiderly-delete-confirmation.component.mjs +0 -42
  63. package/esm2022/lib/components/spiderly-form-control/spiderly-form-control.mjs +0 -36
  64. package/esm2022/lib/components/spiderly-panels/panel-body/panel-body.component.mjs +0 -19
  65. package/esm2022/lib/components/spiderly-panels/panel-footer/panel-footer.component.mjs +0 -14
  66. package/esm2022/lib/components/spiderly-panels/panel-header/panel-header.component.mjs +0 -49
  67. package/esm2022/lib/components/spiderly-panels/spiderly-card/spiderly-card.component.mjs +0 -20
  68. package/esm2022/lib/components/spiderly-panels/spiderly-panel/spiderly-panel.component.mjs +0 -63
  69. package/esm2022/lib/components/spiderly-panels/spiderly-panels.module.mjs +0 -49
  70. package/esm2022/lib/controls/base-autocomplete-control.mjs +0 -18
  71. package/esm2022/lib/controls/base-control.mjs +0 -62
  72. package/esm2022/lib/controls/base-dropdown-control.mjs +0 -37
  73. package/esm2022/lib/controls/spiderly-autocomplete/spiderly-autocomplete.component.mjs +0 -60
  74. package/esm2022/lib/controls/spiderly-calendar/spiderly-calendar.component.mjs +0 -39
  75. package/esm2022/lib/controls/spiderly-checkbox/spiderly-checkbox.component.mjs +0 -45
  76. package/esm2022/lib/controls/spiderly-colorpick/spiderly-colorpick.component.mjs +0 -40
  77. package/esm2022/lib/controls/spiderly-controls.module.mjs +0 -112
  78. package/esm2022/lib/controls/spiderly-dropdown/spiderly-dropdown.component.mjs +0 -40
  79. package/esm2022/lib/controls/spiderly-editor/spiderly-editor.component.mjs +0 -59
  80. package/esm2022/lib/controls/spiderly-file/spiderly-file.component.mjs +0 -106
  81. package/esm2022/lib/controls/spiderly-multiautocomplete/spiderly-multiautocomplete.component.mjs +0 -38
  82. package/esm2022/lib/controls/spiderly-multiselect/spiderly-multiselect.component.mjs +0 -34
  83. package/esm2022/lib/controls/spiderly-number/spiderly-number.component.mjs +0 -44
  84. package/esm2022/lib/controls/spiderly-password/spiderly-password.component.mjs +0 -37
  85. package/esm2022/lib/controls/spiderly-textarea/spiderly-textarea.component.mjs +0 -34
  86. package/esm2022/lib/controls/spiderly-textbox/spiderly-textbox.component.mjs +0 -45
  87. package/esm2022/lib/entities/base-entity.mjs +0 -18
  88. package/esm2022/lib/entities/codebook.mjs +0 -10
  89. package/esm2022/lib/entities/init-company-auth-dialog-details.mjs +0 -9
  90. package/esm2022/lib/entities/init-top-bar-data.mjs +0 -12
  91. package/esm2022/lib/entities/is-authorized-for-save-event.mjs +0 -9
  92. package/esm2022/lib/entities/last-menu-icon-index-clicked.mjs +0 -8
  93. package/esm2022/lib/entities/lazy-load-selected-ids-result.mjs +0 -11
  94. package/esm2022/lib/entities/menuchangeevent.mjs +0 -3
  95. package/esm2022/lib/entities/mime-type.mjs +0 -15
  96. package/esm2022/lib/entities/namebook.mjs +0 -9
  97. package/esm2022/lib/entities/primeng-option.mjs +0 -9
  98. package/esm2022/lib/entities/security-entities.mjs +0 -169
  99. package/esm2022/lib/entities/simple-save-result.mjs +0 -9
  100. package/esm2022/lib/entities/spiderly-button.mjs +0 -11
  101. package/esm2022/lib/entities/table-filter-context.mjs +0 -3
  102. package/esm2022/lib/entities/table-filter-sort-meta.mjs +0 -3
  103. package/esm2022/lib/entities/table-filter.mjs +0 -15
  104. package/esm2022/lib/entities/table-response.mjs +0 -3
  105. package/esm2022/lib/enums/security-enums.mjs +0 -26
  106. package/esm2022/lib/enums/verification-type-codes.mjs +0 -6
  107. package/esm2022/lib/guards/auth.guard.mjs +0 -40
  108. package/esm2022/lib/guards/not-auth.guard.mjs +0 -32
  109. package/esm2022/lib/handlers/spiderly-error-handler.mjs +0 -30
  110. package/esm2022/lib/handlers/spiderly-transloco-fallback-strategy.mjs +0 -24
  111. package/esm2022/lib/interceptors/http-loading.interceptor.mjs +0 -27
  112. package/esm2022/lib/interceptors/json-parser.interceptor.mjs +0 -47
  113. package/esm2022/lib/interceptors/jwt.interceptor.mjs +0 -27
  114. package/esm2022/lib/interceptors/unauthorized.interceptor.mjs +0 -64
  115. package/esm2022/lib/modules/core.module.mjs +0 -140
  116. package/esm2022/lib/modules/primeng.module.mjs +0 -278
  117. package/esm2022/lib/modules/spiderly-transloco.module.mjs +0 -42
  118. package/esm2022/lib/services/api.service.security.mjs +0 -86
  119. package/esm2022/lib/services/app-initializer.mjs +0 -6
  120. package/esm2022/lib/services/app-layout-base.service.mjs +0 -132
  121. package/esm2022/lib/services/auth-base.service.mjs +0 -220
  122. package/esm2022/lib/services/base-form.service.mjs +0 -124
  123. package/esm2022/lib/services/config-base.service.mjs +0 -33
  124. package/esm2022/lib/services/helper-functions.mjs +0 -229
  125. package/esm2022/lib/services/spiderly-message.service.mjs +0 -64
  126. package/esm2022/lib/services/spiderly-transloco-loader.mjs +0 -20
  127. package/esm2022/lib/services/translate-labels-abstract.service.mjs +0 -15
  128. package/esm2022/lib/services/validator-abstract.service.mjs +0 -51
  129. package/esm2022/public-api.mjs +0 -94
  130. package/esm2022/spiderly.mjs +0 -5
  131. package/lib/components/auth/auth.module.d.ts +0 -17
  132. package/styles/styles/theme/base/_colors.scss +0 -18
  133. package/styles/styles/theme/base/_common.scss +0 -75
  134. package/styles/styles/theme/base/_components.scss +0 -106
  135. package/styles/styles/theme/base/_mixins.scss +0 -343
  136. package/styles/styles/theme/base/components/button/_button.scss +0 -564
  137. package/styles/styles/theme/base/components/button/_speeddial.scss +0 -96
  138. package/styles/styles/theme/base/components/button/_splitbutton.scss +0 -381
  139. package/styles/styles/theme/base/components/data/_carousel.scss +0 -37
  140. package/styles/styles/theme/base/components/data/_datatable.scss +0 -338
  141. package/styles/styles/theme/base/components/data/_dataview.scss +0 -55
  142. package/styles/styles/theme/base/components/data/_filter.scss +0 -138
  143. package/styles/styles/theme/base/components/data/_orderlist.scss +0 -103
  144. package/styles/styles/theme/base/components/data/_organizationchart.scss +0 -50
  145. package/styles/styles/theme/base/components/data/_paginator.scss +0 -92
  146. package/styles/styles/theme/base/components/data/_picklist.scss +0 -103
  147. package/styles/styles/theme/base/components/data/_timeline.scss +0 -81
  148. package/styles/styles/theme/base/components/data/_tree.scss +0 -149
  149. package/styles/styles/theme/base/components/data/_treetable.scss +0 -256
  150. package/styles/styles/theme/base/components/data/_virtualscroller.scss +0 -28
  151. package/styles/styles/theme/base/components/file/_fileupload.scss +0 -64
  152. package/styles/styles/theme/base/components/input/_autocomplete.scss +0 -118
  153. package/styles/styles/theme/base/components/input/_calendar.scss +0 -263
  154. package/styles/styles/theme/base/components/input/_cascadeselect.scss +0 -130
  155. package/styles/styles/theme/base/components/input/_checkbox.scss +0 -90
  156. package/styles/styles/theme/base/components/input/_chips.scss +0 -55
  157. package/styles/styles/theme/base/components/input/_colorpicker.scss +0 -26
  158. package/styles/styles/theme/base/components/input/_dropdown.scss +0 -152
  159. package/styles/styles/theme/base/components/input/_editor.scss +0 -122
  160. package/styles/styles/theme/base/components/input/_inputgroup.scss +0 -75
  161. package/styles/styles/theme/base/components/input/_inputmask.scss +0 -16
  162. package/styles/styles/theme/base/components/input/_inputnumber.scss +0 -28
  163. package/styles/styles/theme/base/components/input/_inputswitch.scss +0 -60
  164. package/styles/styles/theme/base/components/input/_inputtext.scss +0 -100
  165. package/styles/styles/theme/base/components/input/_listbox.scss +0 -82
  166. package/styles/styles/theme/base/components/input/_multiselect.scss +0 -173
  167. package/styles/styles/theme/base/components/input/_password.scss +0 -52
  168. package/styles/styles/theme/base/components/input/_radiobutton.scss +0 -78
  169. package/styles/styles/theme/base/components/input/_rating.scss +0 -55
  170. package/styles/styles/theme/base/components/input/_selectbutton.scss +0 -50
  171. package/styles/styles/theme/base/components/input/_slider.scss +0 -71
  172. package/styles/styles/theme/base/components/input/_togglebutton.scss +0 -48
  173. package/styles/styles/theme/base/components/input/_treeselect.scss +0 -139
  174. package/styles/styles/theme/base/components/menu/_breadcrumb.scss +0 -42
  175. package/styles/styles/theme/base/components/menu/_contextmenu.scss +0 -39
  176. package/styles/styles/theme/base/components/menu/_dock.scss +0 -95
  177. package/styles/styles/theme/base/components/menu/_megamenu.scss +0 -55
  178. package/styles/styles/theme/base/components/menu/_menu.scss +0 -37
  179. package/styles/styles/theme/base/components/menu/_menubar.scss +0 -141
  180. package/styles/styles/theme/base/components/menu/_panelmenu.scss +0 -153
  181. package/styles/styles/theme/base/components/menu/_slidemenu.scss +0 -59
  182. package/styles/styles/theme/base/components/menu/_steps.scss +0 -56
  183. package/styles/styles/theme/base/components/menu/_tabmenu.scss +0 -74
  184. package/styles/styles/theme/base/components/menu/_tieredmenu.scss +0 -43
  185. package/styles/styles/theme/base/components/messages/_inlinemessage.scss +0 -69
  186. package/styles/styles/theme/base/components/messages/_message.scss +0 -107
  187. package/styles/styles/theme/base/components/messages/_toast.scss +0 -103
  188. package/styles/styles/theme/base/components/misc/_avatar.scss +0 -30
  189. package/styles/styles/theme/base/components/misc/_badge.scss +0 -48
  190. package/styles/styles/theme/base/components/misc/_blockui.scss +0 -0
  191. package/styles/styles/theme/base/components/misc/_chip.scss +0 -42
  192. package/styles/styles/theme/base/components/misc/_inplace.scss +0 -17
  193. package/styles/styles/theme/base/components/misc/_progressbar.scss +0 -17
  194. package/styles/styles/theme/base/components/misc/_scrolltop.scss +0 -25
  195. package/styles/styles/theme/base/components/misc/_skeleton.scss +0 -8
  196. package/styles/styles/theme/base/components/misc/_tag.scss +0 -40
  197. package/styles/styles/theme/base/components/misc/_terminal.scss +0 -12
  198. package/styles/styles/theme/base/components/multimedia/_galleria.scss +0 -155
  199. package/styles/styles/theme/base/components/multimedia/_image.scss +0 -49
  200. package/styles/styles/theme/base/components/overlay/_confirmpopup.scss +0 -72
  201. package/styles/styles/theme/base/components/overlay/_dialog.scss +0 -73
  202. package/styles/styles/theme/base/components/overlay/_overlaypanel.scss +0 -64
  203. package/styles/styles/theme/base/components/overlay/_sidebar.scss +0 -27
  204. package/styles/styles/theme/base/components/overlay/_tooltip.scss +0 -33
  205. package/styles/styles/theme/base/components/panel/_accordion.scss +0 -119
  206. package/styles/styles/theme/base/components/panel/_card.scss +0 -30
  207. package/styles/styles/theme/base/components/panel/_divider.scss +0 -31
  208. package/styles/styles/theme/base/components/panel/_fieldset.scss +0 -47
  209. package/styles/styles/theme/base/components/panel/_panel.scss +0 -58
  210. package/styles/styles/theme/base/components/panel/_scrollpanel.scss +0 -6
  211. package/styles/styles/theme/base/components/panel/_splitter.scss +0 -19
  212. package/styles/styles/theme/base/components/panel/_tabview.scss +0 -82
  213. package/styles/styles/theme/base/components/panel/_toolbar.scss +0 -11
  214. package/styles/styles/theme/saga/_extensions.scss +0 -27
  215. package/styles/styles/theme/saga/_variables.scss +0 -1
  216. package/styles/styles/theme/saga/saga-blue/_extensions.scss +0 -2
  217. package/styles/styles/theme/saga/saga-blue/_fonts.scss +0 -1
  218. package/styles/styles/theme/saga/saga-blue/_variables.scss +0 -1
  219. package/styles/styles/theme/saga/saga-blue/theme.scss +0 -4
@@ -1,501 +0,0 @@
1
- import { Component, EventEmitter, Inject, Input, LOCALE_ID, Output, ViewChild } from '@angular/core';
2
- import { SpiderlyDeleteConfirmationComponent } from '../spiderly-delete-dialog/spiderly-delete-confirmation.component';
3
- import { CommonModule, formatDate } from '@angular/common';
4
- import { FormsModule } from '@angular/forms';
5
- import { firstValueFrom } from 'rxjs';
6
- import { TranslocoDirective } from '@jsverse/transloco';
7
- import { SpiderlyControlsModule } from '../../controls/spiderly-controls.module';
8
- import { exportListToExcel } from '../../services/helper-functions';
9
- import { PrimengModule } from '../../modules/primeng.module';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/router";
12
- import * as i2 from "primeng/dynamicdialog";
13
- import * as i3 from "../../services/spiderly-message.service";
14
- import * as i4 from "@jsverse/transloco";
15
- import * as i5 from "@angular/forms";
16
- import * as i6 from "@angular/common";
17
- import * as i7 from "primeng/table";
18
- import * as i8 from "primeng/api";
19
- import * as i9 from "primeng/button";
20
- import * as i10 from "primeng/multiselect";
21
- import * as i11 from "primeng/tooltip";
22
- import * as i12 from "primeng/checkbox";
23
- import * as i13 from "../spiderly-buttons/spiderly-button/spiderly-button.component";
24
- import * as i14 from "../../controls/spiderly-number/spiderly-number.component";
25
- export class SpiderlyDataTableComponent {
26
- constructor(router, dialogService, route, messageService, translocoService, locale) {
27
- this.router = router;
28
- this.dialogService = dialogService;
29
- this.route = route;
30
- this.messageService = messageService;
31
- this.translocoService = translocoService;
32
- this.locale = locale;
33
- this.tableIcon = 'pi pi-list';
34
- this.rows = 10;
35
- this.showPaginator = true; // FT: Pass only when hasLazyLoad === false
36
- this.showCardWrapper = true;
37
- this.readonly = false;
38
- this.onTotalRecordsChange = new EventEmitter();
39
- this.loading = true;
40
- this.newlySelectedItems = [];
41
- this.fakeSelectedItems = []; // FT: Only for showing checkboxes, we will not send this to the backend
42
- this.currentPageSelectedItemsFromDb = []; // FT: Made so we can add only newly selected items to the newlySelectedItems
43
- this.unselectedItems = [];
44
- this.onLazyLoad = new EventEmitter();
45
- this.rowsSelectedNumber = 0;
46
- this.isAllSelected = null;
47
- this.fakeIsAllSelected = false; // FT: Only for showing checkboxes, we will not send this to the backend
48
- this.isFirstTimeLazyLoad = true;
49
- this.onIsAllSelectedChange = new EventEmitter();
50
- this.matchModeDateOptions = [];
51
- this.matchModeNumberOptions = [];
52
- this.showAddButton = true;
53
- this.showExportToExcelButton = true;
54
- this.showReloadTableButton = false;
55
- this.hasLazyLoad = true;
56
- this.selectedItemIds = []; // FT: Pass only when hasLazyLoad === false, it's enough if the M2M association hasn't additional fields
57
- this.selectedItems = []; // FT: Pass only when hasLazyLoad === false
58
- this.onRowSelect = new EventEmitter();
59
- this.onRowUnselect = new EventEmitter();
60
- this.clientFilterCount = 0;
61
- }
62
- ngOnInit() {
63
- this.matchModeDateOptions = [
64
- { label: this.translocoService.translate('OnDate'), value: 'equals' },
65
- { label: this.translocoService.translate('DatesBefore'), value: 'dateBefore' },
66
- { label: this.translocoService.translate('DatesAfter'), value: 'dateAfter' },
67
- ];
68
- this.matchModeNumberOptions = [
69
- { label: this.translocoService.translate('Equals'), value: 'equals' },
70
- { label: this.translocoService.translate('MoreThan'), value: 'gte' },
71
- { label: this.translocoService.translate('LessThan'), value: 'lte' },
72
- ];
73
- if (this.hasLazyLoad === false) {
74
- this.clientLoad();
75
- }
76
- }
77
- lazyLoad(event) {
78
- this.lastLazyLoadEvent = event;
79
- let tableFilter = event;
80
- tableFilter.additionalFilterIdLong = this.additionalFilterIdLong;
81
- this.onLazyLoad.next(tableFilter);
82
- this.getTableDataObservableMethod(tableFilter).subscribe({
83
- next: async (res) => {
84
- this.items = res.data;
85
- this.totalRecords = res.totalRecords;
86
- this.onTotalRecordsChange.next(res.totalRecords);
87
- if (this.selectedLazyLoadObservableMethod != null) {
88
- let selectedRowsMethodResult = await firstValueFrom(this.selectedLazyLoadObservableMethod(tableFilter));
89
- this.currentPageSelectedItemsFromDb = [...selectedRowsMethodResult.selectedIds];
90
- if (this.isFirstTimeLazyLoad == true) {
91
- this.rowsSelectedNumber = selectedRowsMethodResult.totalRecordsSelected;
92
- this.setFakeIsAllSelected();
93
- this.isFirstTimeLazyLoad = false;
94
- }
95
- if (this.isAllSelected == true) {
96
- let idsToInsert = [...this.items.map(x => x.id)];
97
- idsToInsert = idsToInsert.filter(x => this.unselectedItems.includes(x) == false);
98
- this.fakeSelectedItems = [...idsToInsert]; // FT: Only for showing checkboxes, we will not send this to the backend
99
- }
100
- else if (this.isAllSelected == false) {
101
- this.fakeSelectedItems = [...this.newlySelectedItems]; // FT: Only for showing checkboxes, we will not send this to the backend
102
- }
103
- else if (this.isAllSelected == null) {
104
- let idsToInsert = [...selectedRowsMethodResult.selectedIds, ...this.newlySelectedItems];
105
- idsToInsert = idsToInsert.filter(x => this.unselectedItems.includes(x) == false);
106
- this.fakeSelectedItems = [...idsToInsert];
107
- }
108
- }
109
- this.loading = false;
110
- },
111
- error: () => {
112
- this.loading = false;
113
- },
114
- });
115
- }
116
- clientLoad() {
117
- this.loading = false;
118
- this.loadFormArrayItems();
119
- this.totalRecords = this.items.length;
120
- this.onTotalRecordsChange.next(this.items.length);
121
- if (this.getAlreadySelectedItemIds) {
122
- this.selectedItemIds = this.getAlreadySelectedItemIds(this.additionalIndexes);
123
- }
124
- if (this.getAlreadySelectedItems) {
125
- this.selectedItems = this.getAlreadySelectedItems(this.additionalIndexes);
126
- }
127
- this.rowsSelectedNumber = this.selectedItemIds.length;
128
- this.setFakeIsAllSelected();
129
- }
130
- filter(event) {
131
- if (this.hasLazyLoad && this.selectionMode === 'multiple')
132
- this.selectAll(false); // FT: We need to do it like this because: totalRecords: 1 -> selectedRecords from earlyer selection 2 -> unselect current -> all checkbox is set to true
133
- if (this.hasLazyLoad === false && this.selectionMode === 'multiple') {
134
- if (this.clientFilterCount === 0) {
135
- this.loadFormArrayItems();
136
- this.clientFilterCount++;
137
- }
138
- else {
139
- this.clientFilterCount--;
140
- }
141
- }
142
- }
143
- loadFormArrayItems() {
144
- this.items = this.getFormArrayItems(this.additionalIndexes);
145
- this.items.forEach((item, index) => {
146
- item.index = index;
147
- });
148
- }
149
- getColHeaderWidth(filterType) {
150
- switch (filterType) {
151
- case 'text':
152
- return 'min-width: 12rem;';
153
- case 'date':
154
- return 'min-width: 10rem;';
155
- case 'multiselect':
156
- return 'min-width: 12rem;';
157
- case 'boolean':
158
- return 'min-width: 8rem;';
159
- case 'numeric':
160
- return 'min-width: 12rem;';
161
- default:
162
- return 'width: 0rem;'; // fitting content of the row like this
163
- }
164
- }
165
- getColMatchModeOptions(filterType) {
166
- switch (filterType) {
167
- case 'text':
168
- return null;
169
- case 'date':
170
- return this.matchModeDateOptions;
171
- case 'multiselect':
172
- return null;
173
- case 'boolean':
174
- return null;
175
- case 'numeric':
176
- return this.matchModeNumberOptions;
177
- default:
178
- return null;
179
- }
180
- }
181
- getColMatchMode(filterType) {
182
- switch (filterType) {
183
- case 'text':
184
- return 'contains';
185
- case 'date':
186
- return null;
187
- case 'multiselect':
188
- return 'in';
189
- case 'boolean':
190
- return 'equals';
191
- case 'numeric':
192
- return null;
193
- default:
194
- return null;
195
- }
196
- }
197
- isDropOrMulti(filterType) {
198
- if (filterType == 'dropdown' || filterType == 'multiselect') {
199
- return true;
200
- }
201
- else {
202
- return false;
203
- }
204
- }
205
- navigateToDetails(rowId) {
206
- this.router.navigate([rowId], { relativeTo: this.route });
207
- }
208
- deleteObject(rowId) {
209
- this.deleteRef = this.dialogService.open(SpiderlyDeleteConfirmationComponent, {
210
- header: this.translocoService.translate('AreYouSure'),
211
- width: '400px',
212
- data: { deleteItemFromTableObservableMethod: this.deleteItemFromTableObservableMethod, id: rowId, }
213
- });
214
- this.deleteRef.onClose.subscribe((deletedSuccessfully) => {
215
- if (deletedSuccessfully === true) {
216
- this.messageService.successMessage(this.translocoService.translate('SuccessfullyDeletedMessage'));
217
- this.reload();
218
- }
219
- });
220
- }
221
- reload() {
222
- this.loading = true;
223
- this.items = null;
224
- this.lazyLoad(this.lastLazyLoadEvent);
225
- }
226
- showActions() {
227
- return this.cols.some(x => x.actions?.length > 0);
228
- }
229
- getStyleForBodyColumn(col) {
230
- switch (col.filterType) {
231
- case 'numeric':
232
- return 'text-align: right;';
233
- default:
234
- return null;
235
- }
236
- }
237
- getClassForAction(action) {
238
- switch (action.field) {
239
- case 'Details':
240
- return 'pi pi-pencil text-lg cursor-pointer primary-color';
241
- case 'Delete':
242
- return 'pi pi-trash text-lg text-red-500 cursor-pointer';
243
- default:
244
- return `${action.icon} ${action.style} text-lg cursor-pointer`;
245
- }
246
- }
247
- getMethodForAction(action, rowData) {
248
- switch (action.field) {
249
- case 'Details':
250
- return this.navigateToDetails(rowData.id);
251
- case 'Delete':
252
- return this.deleteObject(rowData.id);
253
- default:
254
- return action.onClick(rowData.id);
255
- }
256
- }
257
- getRowData(rowData, col) {
258
- switch (col.filterType) {
259
- case 'text':
260
- return rowData[col.field];
261
- case 'date':
262
- if (rowData[col.field] == null)
263
- return null;
264
- if (col.showTime)
265
- return formatDate(rowData[col.field], 'dd.MM.yyyy. HH:mm', this.locale);
266
- else
267
- return formatDate(rowData[col.field], 'dd.MM.yyyy.', this.locale);
268
- case 'multiselect':
269
- return rowData[col.field];
270
- case 'boolean':
271
- return rowData[col.field] == true ? this.translocoService.translate('Yes') : this.translocoService.translate('No');
272
- case 'numeric':
273
- // TODO FT: make decimal pipe
274
- return rowData[col.field];
275
- default:
276
- return null;
277
- }
278
- }
279
- colTrackByFn(index, item) {
280
- return item.field;
281
- }
282
- actionTrackByFn(index, item) {
283
- return `${index}${item.field}`;
284
- }
285
- exportListToExcel() {
286
- let tableFilter = this.lastLazyLoadEvent;
287
- tableFilter.additionalFilterIdLong = this.additionalFilterIdLong;
288
- exportListToExcel(this.exportTableDataToExcelObservableMethod, tableFilter);
289
- }
290
- clear(table) {
291
- table.clear();
292
- }
293
- //#region Selection
294
- setFakeIsAllSelected() {
295
- if (this.rowsSelectedNumber == this.totalRecords)
296
- this.fakeIsAllSelected = true;
297
- else
298
- this.fakeIsAllSelected = false;
299
- }
300
- selectAll(checked) {
301
- this.unselectedItems.length = 0;
302
- this.newlySelectedItems.length = 0;
303
- if (checked == true) {
304
- this.isAllSelected = true;
305
- this.fakeIsAllSelected = true;
306
- this.onIsAllSelectedChange.next(new AllClickEvent({ checked: true, additionalIndexes: this.additionalIndexes }));
307
- this.rowsSelectedNumber = this.totalRecords;
308
- this.fakeSelectedItems = [...this.items.map(x => x.id)];
309
- this.selectedItemIds = [...this.items.map(x => x.id)];
310
- }
311
- else {
312
- this.isAllSelected = false;
313
- this.fakeIsAllSelected = false;
314
- this.onIsAllSelectedChange.next(new AllClickEvent({ checked: false, additionalIndexes: this.additionalIndexes }));
315
- this.rowsSelectedNumber = 0;
316
- this.fakeSelectedItems = [];
317
- this.selectedItemIds = [];
318
- }
319
- }
320
- selectRow(id, index) {
321
- if (this.isRowSelected(id)) {
322
- this.rowUnselect(id);
323
- this.onRowUnselect.next(new RowClickEvent({ index: index, id: id, additionalIndexes: this.additionalIndexes }));
324
- }
325
- else {
326
- this.rowSelect(id);
327
- this.onRowSelect.next(new RowClickEvent({ index: index, id: id, additionalIndexes: this.additionalIndexes }));
328
- }
329
- }
330
- isRowSelected(id) {
331
- if (this.hasLazyLoad) {
332
- return this.fakeSelectedItems.find(x => x === id) != undefined;
333
- }
334
- else {
335
- return this.selectedItemIds.find(x => x === id) != undefined;
336
- }
337
- }
338
- rowSelect(id) {
339
- if (this.isAllSelected == false || this.currentPageSelectedItemsFromDb.includes(id) == false) {
340
- this.newlySelectedItems.push(id);
341
- }
342
- if (this.hasLazyLoad) {
343
- this.fakeSelectedItems.push(id);
344
- }
345
- else {
346
- this.selectedItemIds.push(id);
347
- }
348
- this.rowsSelectedNumber++;
349
- const index = this.unselectedItems.indexOf(id);
350
- if (index !== -1) {
351
- this.unselectedItems.splice(index, 1); // FT: Splice is mutating the array
352
- }
353
- this.setFakeIsAllSelected();
354
- }
355
- rowUnselect(id) {
356
- if (this.isAllSelected == true || this.currentPageSelectedItemsFromDb.includes(id) == true) {
357
- this.unselectedItems.push(id);
358
- }
359
- this.rowsSelectedNumber--;
360
- const index = this.newlySelectedItems.indexOf(id);
361
- const fakeIndex = this.fakeSelectedItems.indexOf(id);
362
- const nonLazyLoadIndex = this.selectedItemIds.indexOf(id);
363
- if (index !== -1) {
364
- this.newlySelectedItems.splice(index, 1); // FT: Splice is mutating the array
365
- }
366
- if (fakeIndex !== -1) {
367
- this.fakeSelectedItems.splice(fakeIndex, 1); // FT: Splice is mutating the array
368
- }
369
- if (nonLazyLoadIndex !== -1) {
370
- this.selectedItemIds.splice(nonLazyLoadIndex, 1); // FT: Splice is mutating the array
371
- }
372
- this.setFakeIsAllSelected();
373
- }
374
- //#endregion
375
- //#region Client side table
376
- // FT: Can do it with Id also, because we are never adding the new record in the table at the same page.
377
- getFormArrayControlByIndex(formControlName, index) {
378
- if (this.getFormControl) {
379
- return this.getFormControl(formControlName, index, this.additionalIndexes);
380
- }
381
- else {
382
- return null;
383
- }
384
- }
385
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpiderlyDataTableComponent, deps: [{ token: i1.Router }, { token: i2.DialogService }, { token: i1.ActivatedRoute }, { token: i3.SpiderlyMessageService }, { token: i4.TranslocoService }, { token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Component }); }
386
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SpiderlyDataTableComponent, isStandalone: true, selector: "spiderly-data-table", inputs: { tableTitle: "tableTitle", tableIcon: "tableIcon", items: "items", rows: "rows", cols: "cols", showPaginator: "showPaginator", showCardWrapper: "showCardWrapper", readonly: "readonly", getTableDataObservableMethod: "getTableDataObservableMethod", exportTableDataToExcelObservableMethod: "exportTableDataToExcelObservableMethod", deleteItemFromTableObservableMethod: "deleteItemFromTableObservableMethod", newlySelectedItems: "newlySelectedItems", unselectedItems: "unselectedItems", selectionMode: "selectionMode", selectedLazyLoadObservableMethod: "selectedLazyLoadObservableMethod", additionalFilterIdLong: "additionalFilterIdLong", showAddButton: "showAddButton", showExportToExcelButton: "showExportToExcelButton", showReloadTableButton: "showReloadTableButton", getFormArrayItems: "getFormArrayItems", hasLazyLoad: "hasLazyLoad", getAlreadySelectedItemIds: "getAlreadySelectedItemIds", getAlreadySelectedItems: "getAlreadySelectedItems", getFormControl: "getFormControl", additionalIndexes: "additionalIndexes" }, outputs: { onTotalRecordsChange: "onTotalRecordsChange", onLazyLoad: "onLazyLoad", onIsAllSelectedChange: "onIsAllSelectedChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect" }, viewQueries: [{ propertyName: "table", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div [class]=\"showCardWrapper ? 'card responsive-card-padding overflow-auto' : ''\">\r\n <p-table #dt [value]=\"items\" [rows]=\"rows\" [rowHover]=\"true\" styleClass=\"p-datatable-gridlines\" [paginator]=\"showPaginator\" responsiveLayout=\"scroll\" [lazy]=\"hasLazyLoad\"\r\n (onLazyLoad)=\"lazyLoad($event)\" [totalRecords]=\"totalRecords\" class=\"spiderly-table\" [loading]=\"(items === undefined || loading === true)\" [selectionMode]=\"selectionMode\" dataKey=\"id\" \r\n (onFilter)=\"filter($event)\"> \r\n <ng-template pTemplate=\"caption\">\r\n <div class=\"table-header overflow-auto\">\r\n <div style=\"display: flex; align-items: center; gap: 8px;\">\r\n <i class=\"{{tableIcon}} text-2xl primary-color\"></i>\r\n <h5 style=\"margin: 0px;\">{{tableTitle}}</h5>\r\n </div>\r\n <div style=\"display: flex; gap: 8px;\">\r\n <button pButton [label]=\"t('ClearFilters')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-filter-slash\" (click)=\"clear(dt)\"></button>\r\n <button pButton *ngIf=\"showExportToExcelButton\" [label]=\"t('ExportToExcel')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-download\" (click)=\"exportListToExcel()\"></button>\r\n <button pButton *ngIf=\"showReloadTableButton\" [label]=\"t('Reload')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-refresh\" (click)=\"reload()\"></button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"header\">\r\n <tr>\r\n <th style=\"width: 0rem;\" *ngIf=\"selectionMode == 'multiple'\">\r\n <div style=\"display: flex; gap: 8px;\">\r\n <p-checkbox [disabled]=\"readonly\" (onChange)=\"selectAll($event.checked)\" [(ngModel)]=\"fakeIsAllSelected\" [binary]=\"true\"></p-checkbox> ({{rowsSelectedNumber}})\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let col of cols; trackBy: colTrackByFn\">\r\n <th [style]=\"getColHeaderWidth(col.filterType)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n {{col.name}}\r\n <!-- <p-sortIcon field=\"\"></p-sortIcon> -->\r\n <!-- <p-columnFilter type=\"date\" field=\"date\" display=\"menu\"></p-columnFilter> -->\r\n <p-columnFilter *ngIf=\"col.filterType != null\" [type]=\"col.filterType\" [field]=\"col.filterField ?? col.field\" display=\"menu\" [placeholder]=\"col.filterPlaceholder\" \r\n [showOperator]=\"false\" [showMatchModes]=\"col.showMatchModes\" [showAddButton]=\"col.showAddButton\" [matchModeOptions]=\"getColMatchModeOptions(col.filterType)\"\r\n [matchMode]=\"getColMatchMode(col.filterType)\"\r\n >\r\n <ng-container *ngIf=\"isDropOrMulti(col.filterType)\">\r\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\r\n <p-multiSelect [ngModel]=\"value\" [options]=\"col.dropdownOrMultiselectValues\" [placeholder]=\"t('All')\" (onChange)=\"filter($event.value)\" optionLabel=\"label\" optionValue=\"value\" [style]=\"{'width':'240px'}\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <div class=\"p-multiselect-representative-option\">\r\n <span class=\"ml-2\">{{ item.label }}</span>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </ng-container>\r\n </p-columnFilter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-index=\"rowIndex\" let-editing=\"editing\">\r\n <tr>\r\n <td *ngIf=\"selectionMode == 'multiple'\">\r\n <p-checkbox [disabled]=\"readonly\" (onChange)=\"selectRow(rowData.id, rowData.index)\" [ngModel]=\"isRowSelected(rowData.id)\" [binary]=\"true\"></p-checkbox>\r\n </td>\r\n <ng-container *ngFor=\"let col of cols; trackBy: colTrackByFn\">\r\n <td [pTooltip]=\"getRowData(rowData, col)\" [style]=\"getStyleForBodyColumn(col)\" *ngIf=\"!col.editable\">\r\n <div style=\"display: flex; align-items: center; justify-content: center; gap: 18px;\">\r\n <ng-container *ngFor=\"let action of col.actions; trackBy: actionTrackByFn\" >\r\n <span [pTooltip]=\"action.name\" [class]=\"getClassForAction(action)\" (click)=\"getMethodForAction(action, rowData)\"></span>\r\n </ng-container>\r\n </div>\r\n {{getRowData(rowData, col)}}\r\n </td>\r\n <td *ngIf=\"col.editable\">\r\n <spiderly-number [control]=\"getFormArrayControlByIndex(col.field, rowData.index)\" [showLabel]=\"false\"></spiderly-number>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td [attr.colspan]=\"cols?.length + (selectionMode === 'multiple' ? 1 : 0)\">{{t('NoRecordsFound')}}</td>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"loadingbody\">\r\n <tr>\r\n <td [attr.colspan]=\"cols?.length + (selectionMode === 'multiple' ? 1 : 0)\">{{t('Loading')}}...</td>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"paginatorleft\">\r\n {{t('TotalRecords')}}: {{totalRecords}}\r\n </ng-template>\r\n <ng-template pTemplate=\"paginatorright\">\r\n <div style=\"display: flex; justify-content: end; gap: 10px;\">\r\n <spiderly-button *ngIf=\"showAddButton\" [label]=\"t('AddNew')\" icon=\"pi pi-plus\" (onClick)=\"navigateToDetails(0)\"></spiderly-button>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n </div>\r\n</ng-container>", styles: [".table-header{display:flex;justify-content:space-between;align-items:center}@media (max-width: 640px){.table-header{display:flex;flex-direction:column;align-items:start;gap:14px}}.spiderly-table .p-paginator{padding:1rem}@media (min-width: 1400px){.spiderly-table .p-paginator-left-content{position:absolute;padding:14px;left:0}}@media (min-width: 1400px){.spiderly-table .p-paginator-right-content{position:absolute;padding:14px;right:0}}\n", ":is() :is(.remove-button-border-focus:focus,.remove-button-border-focus:enabled:focus){box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;background-color:var(--gray-200)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: PrimengModule }, { kind: "component", type: i7.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i7.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i9.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i10.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "directive", type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i12.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: SpiderlyControlsModule }, { kind: "component", type: i13.SpiderlyButtonComponent, selector: "spiderly-button" }, { kind: "component", type: i14.SpiderlyNumberComponent, selector: "spiderly-number", inputs: ["prefix", "showButtons", "decimal", "maxFractionDigits"] }] }); }
387
- }
388
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpiderlyDataTableComponent, decorators: [{
389
- type: Component,
390
- args: [{ selector: 'spiderly-data-table', imports: [
391
- FormsModule,
392
- CommonModule,
393
- PrimengModule,
394
- TranslocoDirective,
395
- SpiderlyControlsModule,
396
- ], standalone: true, template: "<ng-container *transloco=\"let t\">\r\n <div [class]=\"showCardWrapper ? 'card responsive-card-padding overflow-auto' : ''\">\r\n <p-table #dt [value]=\"items\" [rows]=\"rows\" [rowHover]=\"true\" styleClass=\"p-datatable-gridlines\" [paginator]=\"showPaginator\" responsiveLayout=\"scroll\" [lazy]=\"hasLazyLoad\"\r\n (onLazyLoad)=\"lazyLoad($event)\" [totalRecords]=\"totalRecords\" class=\"spiderly-table\" [loading]=\"(items === undefined || loading === true)\" [selectionMode]=\"selectionMode\" dataKey=\"id\" \r\n (onFilter)=\"filter($event)\"> \r\n <ng-template pTemplate=\"caption\">\r\n <div class=\"table-header overflow-auto\">\r\n <div style=\"display: flex; align-items: center; gap: 8px;\">\r\n <i class=\"{{tableIcon}} text-2xl primary-color\"></i>\r\n <h5 style=\"margin: 0px;\">{{tableTitle}}</h5>\r\n </div>\r\n <div style=\"display: flex; gap: 8px;\">\r\n <button pButton [label]=\"t('ClearFilters')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-filter-slash\" (click)=\"clear(dt)\"></button>\r\n <button pButton *ngIf=\"showExportToExcelButton\" [label]=\"t('ExportToExcel')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-download\" (click)=\"exportListToExcel()\"></button>\r\n <button pButton *ngIf=\"showReloadTableButton\" [label]=\"t('Reload')\" class=\"p-button-outlined remove-button-border-focus\" style=\"flex: none;\" icon=\"pi pi-refresh\" (click)=\"reload()\"></button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"header\">\r\n <tr>\r\n <th style=\"width: 0rem;\" *ngIf=\"selectionMode == 'multiple'\">\r\n <div style=\"display: flex; gap: 8px;\">\r\n <p-checkbox [disabled]=\"readonly\" (onChange)=\"selectAll($event.checked)\" [(ngModel)]=\"fakeIsAllSelected\" [binary]=\"true\"></p-checkbox> ({{rowsSelectedNumber}})\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let col of cols; trackBy: colTrackByFn\">\r\n <th [style]=\"getColHeaderWidth(col.filterType)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n {{col.name}}\r\n <!-- <p-sortIcon field=\"\"></p-sortIcon> -->\r\n <!-- <p-columnFilter type=\"date\" field=\"date\" display=\"menu\"></p-columnFilter> -->\r\n <p-columnFilter *ngIf=\"col.filterType != null\" [type]=\"col.filterType\" [field]=\"col.filterField ?? col.field\" display=\"menu\" [placeholder]=\"col.filterPlaceholder\" \r\n [showOperator]=\"false\" [showMatchModes]=\"col.showMatchModes\" [showAddButton]=\"col.showAddButton\" [matchModeOptions]=\"getColMatchModeOptions(col.filterType)\"\r\n [matchMode]=\"getColMatchMode(col.filterType)\"\r\n >\r\n <ng-container *ngIf=\"isDropOrMulti(col.filterType)\">\r\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\r\n <p-multiSelect [ngModel]=\"value\" [options]=\"col.dropdownOrMultiselectValues\" [placeholder]=\"t('All')\" (onChange)=\"filter($event.value)\" optionLabel=\"label\" optionValue=\"value\" [style]=\"{'width':'240px'}\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <div class=\"p-multiselect-representative-option\">\r\n <span class=\"ml-2\">{{ item.label }}</span>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </ng-container>\r\n </p-columnFilter>\r\n </div>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-index=\"rowIndex\" let-editing=\"editing\">\r\n <tr>\r\n <td *ngIf=\"selectionMode == 'multiple'\">\r\n <p-checkbox [disabled]=\"readonly\" (onChange)=\"selectRow(rowData.id, rowData.index)\" [ngModel]=\"isRowSelected(rowData.id)\" [binary]=\"true\"></p-checkbox>\r\n </td>\r\n <ng-container *ngFor=\"let col of cols; trackBy: colTrackByFn\">\r\n <td [pTooltip]=\"getRowData(rowData, col)\" [style]=\"getStyleForBodyColumn(col)\" *ngIf=\"!col.editable\">\r\n <div style=\"display: flex; align-items: center; justify-content: center; gap: 18px;\">\r\n <ng-container *ngFor=\"let action of col.actions; trackBy: actionTrackByFn\" >\r\n <span [pTooltip]=\"action.name\" [class]=\"getClassForAction(action)\" (click)=\"getMethodForAction(action, rowData)\"></span>\r\n </ng-container>\r\n </div>\r\n {{getRowData(rowData, col)}}\r\n </td>\r\n <td *ngIf=\"col.editable\">\r\n <spiderly-number [control]=\"getFormArrayControlByIndex(col.field, rowData.index)\" [showLabel]=\"false\"></spiderly-number>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td [attr.colspan]=\"cols?.length + (selectionMode === 'multiple' ? 1 : 0)\">{{t('NoRecordsFound')}}</td>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"loadingbody\">\r\n <tr>\r\n <td [attr.colspan]=\"cols?.length + (selectionMode === 'multiple' ? 1 : 0)\">{{t('Loading')}}...</td>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"paginatorleft\">\r\n {{t('TotalRecords')}}: {{totalRecords}}\r\n </ng-template>\r\n <ng-template pTemplate=\"paginatorright\">\r\n <div style=\"display: flex; justify-content: end; gap: 10px;\">\r\n <spiderly-button *ngIf=\"showAddButton\" [label]=\"t('AddNew')\" icon=\"pi pi-plus\" (onClick)=\"navigateToDetails(0)\"></spiderly-button>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n </div>\r\n</ng-container>", styles: [".table-header{display:flex;justify-content:space-between;align-items:center}@media (max-width: 640px){.table-header{display:flex;flex-direction:column;align-items:start;gap:14px}}.spiderly-table .p-paginator{padding:1rem}@media (min-width: 1400px){.spiderly-table .p-paginator-left-content{position:absolute;padding:14px;left:0}}@media (min-width: 1400px){.spiderly-table .p-paginator-right-content{position:absolute;padding:14px;right:0}}\n", ":is() :is(.remove-button-border-focus:focus,.remove-button-border-focus:enabled:focus){box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;background-color:var(--gray-200)}\n"] }]
397
- }], ctorParameters: () => [{ type: i1.Router }, { type: i2.DialogService }, { type: i1.ActivatedRoute }, { type: i3.SpiderlyMessageService }, { type: i4.TranslocoService }, { type: undefined, decorators: [{
398
- type: Inject,
399
- args: [LOCALE_ID]
400
- }] }], propDecorators: { table: [{
401
- type: ViewChild,
402
- args: ['dt']
403
- }], tableTitle: [{
404
- type: Input
405
- }], tableIcon: [{
406
- type: Input
407
- }], items: [{
408
- type: Input
409
- }], rows: [{
410
- type: Input
411
- }], cols: [{
412
- type: Input
413
- }], showPaginator: [{
414
- type: Input
415
- }], showCardWrapper: [{
416
- type: Input
417
- }], readonly: [{
418
- type: Input
419
- }], onTotalRecordsChange: [{
420
- type: Output
421
- }], getTableDataObservableMethod: [{
422
- type: Input
423
- }], exportTableDataToExcelObservableMethod: [{
424
- type: Input
425
- }], deleteItemFromTableObservableMethod: [{
426
- type: Input
427
- }], newlySelectedItems: [{
428
- type: Input
429
- }], unselectedItems: [{
430
- type: Input
431
- }], selectionMode: [{
432
- type: Input
433
- }], onLazyLoad: [{
434
- type: Output
435
- }], onIsAllSelectedChange: [{
436
- type: Output
437
- }], selectedLazyLoadObservableMethod: [{
438
- type: Input
439
- }], additionalFilterIdLong: [{
440
- type: Input
441
- }], showAddButton: [{
442
- type: Input
443
- }], showExportToExcelButton: [{
444
- type: Input
445
- }], showReloadTableButton: [{
446
- type: Input
447
- }], getFormArrayItems: [{
448
- type: Input
449
- }], hasLazyLoad: [{
450
- type: Input
451
- }], getAlreadySelectedItemIds: [{
452
- type: Input
453
- }], getAlreadySelectedItems: [{
454
- type: Input
455
- }], getFormControl: [{
456
- type: Input
457
- }], additionalIndexes: [{
458
- type: Input
459
- }], onRowSelect: [{
460
- type: Output
461
- }], onRowUnselect: [{
462
- type: Output
463
- }] } });
464
- export class Action {
465
- constructor({ name, field, icon, style, onClick, } = {}) {
466
- this.name = name;
467
- this.field = field;
468
- this.icon = icon;
469
- this.style = style;
470
- this.onClick = onClick;
471
- }
472
- }
473
- export class Column {
474
- constructor({ name, field, filterField, filterType, filterPlaceholder, showMatchModes, showAddButton, dropdownOrMultiselectValues, actions, editable, showTime, } = {}) {
475
- this.name = name;
476
- this.field = field;
477
- this.filterField = filterField;
478
- this.filterType = filterType;
479
- this.filterPlaceholder = filterPlaceholder;
480
- this.showMatchModes = showMatchModes;
481
- this.showAddButton = showAddButton;
482
- this.dropdownOrMultiselectValues = dropdownOrMultiselectValues;
483
- this.actions = actions;
484
- this.editable = editable;
485
- this.showTime = showTime;
486
- }
487
- }
488
- export class RowClickEvent {
489
- constructor({ index, id, additionalIndexes } = {}) {
490
- this.index = index;
491
- this.id = id;
492
- this.additionalIndexes = additionalIndexes;
493
- }
494
- }
495
- export class AllClickEvent {
496
- constructor({ checked, additionalIndexes } = {}) {
497
- this.checked = checked;
498
- this.additionalIndexes = additionalIndexes;
499
- }
500
- }
501
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BpZGVybHktZGF0YS10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGlkZXJseS9zcmMvbGliL2NvbXBvbmVudHMvc3BpZGVybHktZGF0YS10YWJsZS9zcGlkZXJseS1kYXRhLXRhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwaWRlcmx5L3NyYy9saWIvY29tcG9uZW50cy9zcGlkZXJseS1kYXRhLXRhYmxlL3NwaWRlcmx5LWRhdGEtdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUs3RyxPQUFPLEVBQUUsbUNBQW1DLEVBQUUsTUFBTSxrRUFBa0UsQ0FBQztBQUN2SCxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsY0FBYyxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBRWxELE9BQU8sRUFBRSxrQkFBa0IsRUFBb0IsTUFBTSxvQkFBb0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUlqRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0QjdELE1BQU0sT0FBTywwQkFBMEI7SUF1RHJDLFlBQ1UsTUFBYyxFQUNkLGFBQTRCLEVBQzVCLEtBQXFCLEVBQ3JCLGNBQXNDLEVBQ3RDLGdCQUFrQyxFQUNmLE1B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LEdBQUcsaUJBQWlCLENBQUM7UUFDM0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDckMsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLDJCQUEyQixHQUFHLDJCQUEyQixDQUFDO1FBQy9ELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxhQUFhO0lBS3hCLFlBQ0UsRUFDRSxLQUFLLEVBQ0wsRUFBRSxFQUNGLGlCQUFpQixLQUtmLEVBQUU7UUFFTixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8sYUFBYTtJQUl4QixZQUNFLEVBQ0UsT0FBTyxFQUNQLGlCQUFpQixLQUlmLEVBQUU7UUFFTixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7SUFDN0MsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIExPQ0FMRV9JRCwgT25Jbml0LCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgU2VsZWN0SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcclxuaW1wb3J0IHsgVGFibGUsIFRhYmxlRmlsdGVyRXZlbnQsIFRhYmxlTGF6eUxvYWRFdmVudCB9IGZyb20gJ3ByaW1lbmcvdGFibGUnO1xyXG5pbXBvcnQgeyBEaWFsb2dTZXJ2aWNlLCBEeW5hbWljRGlhbG9nUmVmIH0gZnJvbSAncHJpbWVuZy9keW5hbWljZGlhbG9nJztcclxuaW1wb3J0IHsgU3BpZGVybHlEZWxldGVDb25maXJtYXRpb25Db21wb25lbnQgfSBmcm9tICcuLi9zcGlkZXJseS1kZWxldGUtZGlhbG9nL3NwaWRlcmx5LWRlbGV0ZS1jb25maXJtYXRpb24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlLCBmb3JtYXREYXRlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IFNwaWRlcmx5TWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zcGlkZXJseS1tZXNzYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBQcmltZW5nT3B0aW9uIH0gZnJvbSAnLi4vLi4vZW50aXRpZXMvcHJpbWVuZy1vcHRpb24nO1xyXG5pbXBvcnQgeyBUcmFuc2xvY29EaXJlY3RpdmUsIFRyYW5zbG9jb1NlcnZpY2UgfSBmcm9tICdAanN2ZXJzZS90cmFuc2xvY28nO1xyXG5pbXBvcnQgeyBTcGlkZXJseUNvbnRyb2xzTW9kdWxlIH0gZnJvbSAnLi4vLi4vY29udHJvbHMvc3BpZGVybHktY29udHJvbHMubW9kdWxlJztcclxuaW1wb3J0IHsgU3BpZGVybHlGb3JtQ29udHJvbCB9IGZyb20gJy4uL3NwaWRlcmx5LWZvcm0tY29udHJvbC9zcGlkZXJseS1mb3JtLWNvbnRyb2wnO1xyXG5pbXBvcnQgeyBUYWJsZVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vZW50aXRpZXMvdGFibGUtcmVzcG9uc2UnO1xyXG5pbXBvcnQgeyBMYXp5TG9hZFNlbGVjdGVkSWRzUmVzdWx0IH0gZnJvbSAnLi4vLi4vZW50aXRpZXMvbGF6eS1sb2FkLXNlbGVjdGVkLWlkcy1yZXN1bHQnO1xyXG5pbXBvcnQgeyBleHBvcnRMaXN0VG9FeGNlbCB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2hlbHBlci1mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBUYWJsZUZpbHRlciB9IGZyb20gJy4uLy4uL2VudGl0aWVzL3RhYmxlLWZpbHRlcic7XHJcbmltcG9ydCB7IFByaW1lbmdNb2R1bGUgfSBmcm9tICcuLi8uLi9tb2R1bGVzL3ByaW1lbmcubW9kdWxlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc3BpZGVybHktZGF0YS10YWJsZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NwaWRlcmx5LWRhdGEtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnc3BpZGVybHktZGF0YS10YWJsZS5jb21wb25lbnQuc2NzcycsXHJcbiAgc3R5bGVzOiBbYFxyXG4gIFx0Omhvc3Qge1xyXG5cdFx0ICA6Om5nLWRlZXAge1xyXG5cdFx0ICAgIC5yZW1vdmUtYnV0dG9uLWJvcmRlci1mb2N1czpmb2N1cywgXHJcbiAgICAgICAgLnJlbW92ZS1idXR0b24tYm9yZGVyLWZvY3VzOmVuYWJsZWQ6Zm9jdXMge1xyXG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XHJcbiAgICAgICAgLXdlYmtpdC1ib3gtc2hhZG93OiBub25lO1xyXG4gICAgICAgIC1tb3otYm94LXNoYWRvdzogbm9uZTtcclxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ncmF5LTIwMCk7XHJcblx0XHQgICAgfVxyXG5cdFx0ICB9XHJcblx0ICB9XHJcbiAgYF0sXHJcbiAgaW1wb3J0czogW1xyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBQcmltZW5nTW9kdWxlLFxyXG4gICAgVHJhbnNsb2NvRGlyZWN0aXZlLFxyXG4gICAgU3BpZGVybHlDb250cm9sc01vZHVsZSxcclxuICBdLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTcGlkZXJseURhdGFUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQFZpZXdDaGlsZCgnZHQnKSB0YWJsZTogVGFibGU7XHJcbiAgQElucHV0KCkgdGFibGVUaXRsZTogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIHRhYmxlSWNvbjogc3RyaW5nID0gJ3BpIHBpLWxpc3QnO1xyXG4gIEBJbnB1dCgpIGl0ZW1zOiBhbnlbXTsgLy8gRlQ6IFBhc3Mgb25seSB3aGVuIGhhc0xhenlMb2FkID09PSBmYWxzZVxyXG4gIEBJbnB1dCgpIHJvd3M6IG51bWJlciA9IDEwO1xyXG4gIEBJbnB1dCgpIGNvbHM6IENvbHVtbltdO1xyXG4gIEBJbnB1dCgpIHNob3dQYWdpbmF0b3I6IGJvb2xlYW4gPSB0cnVlOyAvLyBGVDogUGFzcyBvbmx5IHdoZW4gaGFzTGF6eUxvYWQgPT09IGZhbHNlXHJcbiAgQElucHV0KCkgc2hvd0NhcmRXcmFwcGVyOiBib29sZWFuID0gdHJ1ZTtcclxuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHRvdGFsUmVjb3JkczogbnVtYmVyO1xyXG4gIEBPdXRwdXQoKSBvblRvdGFsUmVjb3Jkc0NoYW5nZTogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgXHJcbiAgQElucHV0KCkgZ2V0VGFibGVEYXRhT2JzZXJ2YWJsZU1ldGhvZDogKHRhYmxlRmlsdGVyOiBUYWJsZUZpbHRlcikgPT4gT2JzZXJ2YWJsZTxUYWJsZVJlc3BvbnNlPjtcclxuICBASW5wdXQoKSBleHBvcnRUYWJsZURhdGFUb0V4Y2VsT2JzZXJ2YWJsZU1ldGhvZDogKHRhYmxlRmlsdGVyOiBUYWJsZUZpbHRlcikgPT4gT2JzZXJ2YWJsZTxhbnk+O1xyXG4gIEBJbnB1dCgpIGRlbGV0ZUl0ZW1Gcm9tVGFibGVPYnNlcnZhYmxlTWV0aG9kOiAocm93SWQ6IG51bWJlcikgPT4gT2JzZXJ2YWJsZTxhbnk+O1xyXG5cclxuICBsYXN0TGF6eUxvYWRFdmVudDogVGFibGVMYXp5TG9hZEV2ZW50O1xyXG4gIGxvYWRpbmc6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIFxyXG4gIEBJbnB1dCgpIG5ld2x5U2VsZWN0ZWRJdGVtczogbnVtYmVyW10gPSBbXTtcclxuICBmYWtlU2VsZWN0ZWRJdGVtczogbnVtYmVyW10gPSBbXTsgLy8gRlQ6IE9ubHkgZm9yIHNob3dpbmcgY2hlY2tib3hlcywgd2Ugd2lsbCBub3Qgc2VuZCB0aGlzIHRvIHRoZSBiYWNrZW5kXHJcbiAgY3VycmVudFBhZ2VTZWxlY3RlZEl0ZW1zRnJvbURiOiBudW1iZXJbXSA9IFtdOyAvLyBGVDogTWFkZSBzbyB3ZSBjYW4gYWRkIG9ubHkgbmV3bHkgc2VsZWN0ZWQgaXRlbXMgdG8gdGhlIG5ld2x5U2VsZWN0ZWRJdGVtc1xyXG4gIEBJbnB1dCgpIHVuc2VsZWN0ZWRJdGVtczogbnVtYmVyW10gPSBbXTtcclxuICBASW5wdXQoKSBzZWxlY3Rpb25Nb2RlOiAnc2luZ2xlJyB8ICdtdWx0aXBsZScgfCB1bmRlZmluZWQgfCBudWxsO1xyXG4gIEBPdXRwdXQoKSBvbkxhenlMb2FkOiBFdmVudEVtaXR0ZXI8VGFibGVGaWx0ZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIHJvd3NTZWxlY3RlZE51bWJlcjogbnVtYmVyID0gMDtcclxuICBpc0FsbFNlbGVjdGVkOiBib29sZWFuID0gbnVsbDtcclxuICBmYWtlSXNBbGxTZWxlY3RlZDogYm9vbGVhbiA9IGZhbHNlOyAvLyBGVDogT25seSBmb3Igc2hvd2luZyBjaGVja2JveGVzLCB3ZSB3aWxsIG5vdCBzZW5kIHRoaXMgdG8gdGhlIGJhY2tlbmRcclxuICBpc0ZpcnN0VGltZUxhenlMb2FkOiBib29sZWFuID0gdHJ1ZTtcclxuICBAT3V0cHV0KCkgb25Jc0FsbFNlbGVjdGVkQ2hhbmdlOiBFdmVudEVtaXR0ZXI8QWxsQ2xpY2tFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgQElucHV0KCkgc2VsZWN0ZWRMYXp5TG9hZE9ic2VydmFibGVNZXRob2Q6ICh0YWJsZUZpbHRlcjogVGFibGVGaWx0ZXIpID0+IE9ic2VydmFibGU8TGF6eUxvYWRTZWxlY3RlZElkc1Jlc3VsdD47XHJcbiAgQElucHV0KCkgYWRkaXRpb25hbEZpbHRlcklkTG9uZzogbnVtYmVyO1xyXG4gIFxyXG4gIG1hdGNoTW9kZURhdGVPcHRpb25zOiBTZWxlY3RJdGVtW10gPSBbXTtcclxuICBtYXRjaE1vZGVOdW1iZXJPcHRpb25zOiBTZWxlY3RJdGVtW10gPSBbXTtcclxuICBASW5wdXQoKSBzaG93QWRkQnV0dG9uOiBib29sZWFuID0gdHJ1ZTsgXHJcbiAgQElucHV0KCkgc2hvd0V4cG9ydFRvRXhjZWxCdXR0b246IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIHNob3dSZWxvYWRUYWJsZUJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBkZWxldGVSZWY6IER5bmFtaWNEaWFsb2dSZWY7XHJcblxyXG4gIC8vIENsaWVudCBzaWRlIHRhYmxlXHJcbiAgLy8gQElucHV0KCkgZm9ybUFycmF5SXRlbXM6IGFueVtdOyAvLyBGVDogUGFzcyB0aGlzIG9ubHkgaWYgeW91IGhhdmUgc29tZSBhZGRpdGlvbmFsIGxvZ2ljIGZvciBzaG93aW5nIGRhdGFcclxuICBASW5wdXQoKSBnZXRGb3JtQXJyYXlJdGVtczogKGFkZGl0aW9uYWxJbmRleGVzPzogYW55KSA9PiBhbnlbXTtcclxuICBASW5wdXQoKSBoYXNMYXp5TG9hZDogYm9vbGVhbiA9IHRydWU7IFxyXG4gIHNlbGVjdGVkSXRlbUlkczogbnVtYmVyW10gPSBbXTsgLy8gRlQ6IFBhc3Mgb25seSB3aGVuIGhhc0xhenlMb2FkID09PSBmYWxzZSwgaXQncyBlbm91Z2ggaWYgdGhlIE0yTSBhc3NvY2lhdGlvbiBoYXNuJ3QgYWRkaXRpb25hbCBmaWVsZHNcclxuICBASW5wdXQoKSBnZXRBbHJlYWR5U2VsZWN0ZWRJdGVtSWRzOiAoYWRkaXRpb25hbEluZGV4ZXM/OiBhbnkpID0+IG51bWJlcltdOyAvLyBGVDogUGFzcyBvbmx5IHdoZW4gaGFzTGF6eUxvYWQgPT09IGZhbHNlLCBpdCdzIGVub3VnaCBpZiB0aGUgTTJNIGFzc29jaWF0aW9uIGhhc24ndCBhZGRpdGlvbmFsIGZpZWxkc1xyXG4gIHNlbGVjdGVkSXRlbXM6IGFueVtdID0gW107IC8vIEZUOiBQYXNzIG9ubHkgd2hlbiBoYXNMYXp5TG9hZCA9PT0gZmFsc2VcclxuICBASW5wdXQoKSBnZXRBbHJlYWR5U2VsZWN0ZWRJdGVtczogKGFkZGl0aW9uYWxJbmRleGVzPzogYW55KSA9PiBhbnlbXTsgLy8gRlQ6IFBhc3Mgb25seSB3aGVuIGhhc0xhenlMb2FkID09PSBmYWxzZSwgaXQncyBlbm91Z2ggaWYgdGhlIE0yTSBhc3NvY2lhdGlvbiBoYXNuJ3QgYWRkaXRpb25hbCBmaWVsZHNcclxuICBASW5wdXQoKSBnZXRGb3JtQ29udHJvbDogKGZvcm1Db250cm9sTmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBhZGRpdGlvbmFsSW5kZXhlcz86IGFueSkgPT4gU3BpZGVybHlGb3JtQ29udHJvbDtcclxuICBASW5wdXQoKSBhZGRpdGlvbmFsSW5kZXhlczogYW55O1xyXG4gIEBPdXRwdXQoKSBvblJvd1NlbGVjdDogRXZlbnRFbWl0dGVyPFJvd0NsaWNrRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSBvblJvd1Vuc2VsZWN0OiBFdmVudEVtaXR0ZXI8Um93Q2xpY2tFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgIHByaXZhdGUgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcclxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHJpdmF0ZSBtZXNzYWdlU2VydmljZTogU3BpZGVybHlNZXNzYWdlU2VydmljZSxcclxuICAgIHByaXZhdGUgdHJhbnNsb2NvU2VydmljZTogVHJhbnNsb2NvU2VydmljZSxcclxuICAgIEBJbmplY3QoTE9DQUxFX0lEKSBwcml2YXRlIGxvY2FsZTogc3RyaW5nXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMubWF0Y2hNb2RlRGF0ZU9wdGlvbnMgPSBbXHJcbiAgICAgIHsgbGFiZWw6IHRoaXMudHJhbnNsb2NvU2VydmljZS50cmFuc2xhdGUoJ09uRGF0ZScpLCB2YWx1ZTogJ2VxdWFscycgfSxcclxuICAgICAgeyBsYWJlbDogdGhpcy50cmFuc2xvY29TZXJ2aWNlLnRyYW5zbGF0ZSgnRGF0ZXNCZWZvcmUnKSwgdmFsdWU6ICdkYXRlQmVmb3JlJyB9LFxyXG4gICAgICB7IGxhYmVsOiB0aGlzLnRyYW5zbG9jb1NlcnZpY2UudHJhbnNsYXRlKCdEYXRlc0FmdGVyJyksIHZhbHVlOiAnZGF0ZUFmdGVyJyB9LFxyXG4gICAgXTtcclxuXHJcbiAgICB0aGlzLm1hdGNoTW9kZU51bWJlck9wdGlvbnMgPSBbXHJcbiAgICAgIHsgbGFiZWw6IHRoaXMudHJhbnNsb2NvU2VydmljZS50cmFuc2xhdGUoJ0VxdWFscycpLCB2YWx1ZTogJ2VxdWFscycgfSxcclxuICAgICAgeyBsYWJlbDogdGhpcy50cmFuc2xvY29TZXJ2aWNlLnRyYW5zbGF0ZSgnTW9yZVRoYW4nKSwgdmFsdWU6ICdndGUnIH0sXHJcbiAgICAgIHsgbGFiZWw6IHRoaXMudHJhbnNsb2NvU2VydmljZS50cmFuc2xhdGUoJ0xlc3NUaGFuJyksIHZhbHVlOiAnbHRlJyB9LFxyXG4gICAgXTtcclxuXHJcbiAgICBpZiAodGhpcy5oYXNMYXp5TG9hZCA9PT0gZmFsc2UpIHtcclxuICAgICAgdGhpcy5jbGllbnRMb2FkKCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIGxhenlMb2FkKGV2ZW50OiBUYWJsZUxhenlMb2FkRXZlbnQpIHtcclxuICAgIHRoaXMubGFzdExhenlMb2FkRXZlbnQgPSBldmVudDtcclxuXHJcbiAgICBsZXQgdGFibGVGaWx0ZXI6IFRhYmxlRmlsdGVyID0gZXZlbnQgYXMgdW5rbm93biBhcyBUYWJsZUZpbHRlcjtcclxuICAgIHRhYmxlRmlsdGVyLmFkZGl0aW9uYWxGaWx0ZXJJZExvbmcgPSB0aGlzLmFkZGl0aW9uYWxGaWx0ZXJJZExvbmc7XHJcblxyXG4gICAgdGhpcy5vbkxhenlMb2FkLm5leHQodGFibGVGaWx0ZXIpO1xyXG4gICAgXHJcbiAgICB0aGlzLmdldFRhYmxlRGF0YU9ic2VydmFibGVNZXRob2QodGFibGVGaWx0ZXIpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IGFzeW5jIChyZXMpID0+IHsgXHJcbiAgICAgICAgdGhpcy5pdGVtcyA9IHJlcy5kYXRhO1xyXG4gICAgICAgIHRoaXMudG90YWxSZWNvcmRzID0gcmVzLnRvdGFsUmVjb3JkcztcclxuICAgICAgICB0aGlzLm9uVG90YWxSZWNvcmRzQ2hhbmdlLm5leHQocmVzLnRvdGFsUmVjb3Jkcyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRMYXp5TG9hZE9ic2VydmFibGVNZXRob2QgIT0gbnVsbCkge1xyXG4gICAgICAgICAgbGV0IHNlbGVjdGVkUm93c01ldGhvZFJlc3VsdDogTGF6eUxvYWRTZWxlY3RlZElkc1Jlc3VsdCA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuc2VsZWN0ZWRMYXp5TG9hZE9ic2VydmFibGVNZXRob2QodGFibGVGaWx0ZXIpKTtcclxuICBcclxuICAgICAgICAgIHRoaXMuY3VycmVudFBhZ2VTZWxlY3RlZEl0ZW1zRnJvbURiID0gWy4uLnNlbGVjdGVkUm93c01ldGhvZFJlc3VsdC5zZWxlY3RlZElkc107XHJcblxyXG4gICAgICAgICAgaWYgKHRoaXMuaXNGaXJzdFRpbWVMYXp5TG9hZCA9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMucm93c1NlbGVjdGVkTnVtYmVyID0gc2VsZWN0ZWRSb3dzTWV0aG9kUmVzdWx0LnRvdGFsUmVjb3Jkc1NlbGVjdGVkO1xyXG4gICAgICAgICAgICB0aGlzLnNldEZha2VJc0FsbFNlbGVjdGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMuaXNGaXJzdFRpbWVMYXp5TG9hZCA9IGZhbHNlO1xyXG4gICAgICAgICAgfVxyXG4gIFxyXG4gICAgICAgICAgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCA9PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIGxldCBpZHNUb0luc2VydCA9IFsuLi50aGlzLml0ZW1zLm1hcCh4ID0+IHguaWQpXTtcclxuICAgICAgICAgICAgaWRzVG9JbnNlcnQgPSBpZHNUb0luc2VydC5maWx0ZXIoeCA9PiB0aGlzLnVuc2VsZWN0ZWRJdGVtcy5pbmNsdWRlcyh4KSA9PSBmYWxzZSk7XHJcbiAgICAgICAgICAgIHRoaXMuZmFrZVNlbGVjdGVkSXRlbXMgPSBbLi4uaWRzVG9JbnNlcnRdOyAvLyBGVDogT25seSBmb3Igc2hvd2luZyBjaGVja2JveGVzLCB3ZSB3aWxsIG5vdCBzZW5kIHRoaXMgdG8gdGhlIGJhY2tlbmRcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGVsc2UgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCA9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZha2VTZWxlY3RlZEl0ZW1zID0gWy4uLnRoaXMubmV3bHlTZWxlY3RlZEl0ZW1zXTsgLy8gRlQ6IE9ubHkgZm9yIHNob3dpbmcgY2hlY2tib3hlcywgd2Ugd2lsbCBub3Qgc2VuZCB0aGlzIHRvIHRoZSBiYWNrZW5kXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlbHNlIGlmICh0aGlzLmlzQWxsU2VsZWN0ZWQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsZXQgaWRzVG9JbnNlcnQgPSBbLi4uc2VsZWN0ZWRSb3dzTWV0aG9kUmVzdWx0LnNlbGVjdGVkSWRzLCAuLi50aGlzLm5ld2x5U2VsZWN0ZWRJdGVtc107XHJcbiAgICAgICAgICAgIGlkc1RvSW5zZXJ0ID0gaWRzVG9JbnNlcnQuZmlsdGVyKHggPT4gdGhpcy51bnNlbGVjdGVkSXRlbXMuaW5jbHVkZXMoeCkgPT0gZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLmZha2VTZWxlY3RlZEl0ZW1zID0gWy4uLmlkc1RvSW5zZXJ0XTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBjbGllbnRMb2FkKCl7XHJcbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLmxvYWRGb3JtQXJyYXlJdGVtcygpO1xyXG4gICAgdGhpcy50b3RhbFJlY29yZHMgPSB0aGlzLml0ZW1zLmxlbmd0aDtcclxuICAgIHRoaXMub25Ub3RhbFJlY29yZHNDaGFuZ2UubmV4dCh0aGlzLml0ZW1zLmxlbmd0aCk7XHJcblxyXG4gICAgaWYgKHRoaXMuZ2V0QWxyZWFkeVNlbGVjdGVkSXRlbUlkcykge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbUlkcyA9IHRoaXMuZ2V0QWxyZWFkeVNlbGVjdGVkSXRlbUlkcyh0aGlzLmFkZGl0aW9uYWxJbmRleGVzKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmdldEFscmVhZHlTZWxlY3RlZEl0ZW1zKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IHRoaXMuZ2V0QWxyZWFkeVNlbGVjdGVkSXRlbXModGhpcy5hZGRpdGlvbmFsSW5kZXhlcyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnJvd3NTZWxlY3RlZE51bWJlciA9IHRoaXMuc2VsZWN0ZWRJdGVtSWRzLmxlbmd0aDtcclxuICAgIHRoaXMuc2V0RmFrZUlzQWxsU2VsZWN0ZWQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xpZW50RmlsdGVyQ291bnQgPSAwO1xyXG5cclxuICBmaWx0ZXIoZXZlbnQ6IFRhYmxlRmlsdGVyRXZlbnQpe1xyXG4gICAgaWYgKHRoaXMuaGFzTGF6eUxvYWQgJiYgdGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnKVxyXG4gICAgICB0aGlzLnNlbGVjdEFsbChmYWxzZSk7IC8vIEZUOiBXZSBuZWVkIHRvIGRvIGl0IGxpa2UgdGhpcyBiZWNhdXNlOiB0b3RhbFJlY29yZHM6IDEgLT4gc2VsZWN0ZWRSZWNvcmRzIGZyb20gZWFybHllciBzZWxlY3Rpb24gMiAtPiB1bnNlbGVjdCBjdXJyZW50IC0+IGFsbCBjaGVja2JveCBpcyBzZXQgdG8gdHJ1ZVxyXG5cclxuICAgIGlmICh0aGlzLmhhc0xhenlMb2FkID09PSBmYWxzZSAmJiB0aGlzLnNlbGVjdGlvbk1vZGUgPT09ICdtdWx0aXBsZScpIHtcclxuICAgICAgaWYgKHRoaXMuY2xpZW50RmlsdGVyQ291bnQgPT09IDApIHtcclxuICAgICAgICB0aGlzLmxvYWRGb3JtQXJyYXlJdGVtcygpO1xyXG4gICAgICAgIHRoaXMuY2xpZW50RmlsdGVyQ291bnQrKztcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgdGhpcy5jbGllbnRGaWx0ZXJDb3VudC0tO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGxvYWRGb3JtQXJyYXlJdGVtcygpe1xyXG4gICAgdGhpcy5pdGVtcyA9IHRoaXMuZ2V0Rm9ybUFycmF5SXRlbXModGhpcy5hZGRpdGlvbmFsSW5kZXhlcyk7XHJcbiAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XHJcbiAgICAgIGl0ZW0uaW5kZXggPSBpbmRleDtcclxuICAgIH0pO1xyXG4gIH1cclxuICBcclxuICBnZXRDb2xIZWFkZXJXaWR0aChmaWx0ZXJUeXBlOiBzdHJpbmcpIHtcclxuICAgIHN3aXRjaCAoZmlsdGVyVHlwZSkge1xyXG4gICAgICBjYXNlICd0ZXh0JzpcclxuICAgICAgICByZXR1cm4gJ21pbi13aWR0aDogMTJyZW07JztcclxuICAgICAgY2FzZSAnZGF0ZSc6XHJcbiAgICAgICAgcmV0dXJuICdtaW4td2lkdGg6IDEwcmVtOyc7XHJcbiAgICAgIGNhc2UgJ211bHRpc2VsZWN0JzpcclxuICAgICAgICByZXR1cm4gJ21pbi13aWR0aDogMTJyZW07JztcclxuICAgICAgY2FzZSAnYm9vbGVhbic6XHJcbiAgICAgICAgcmV0dXJuICdtaW4td2lkdGg6IDhyZW07JztcclxuICAgICAgY2FzZSAnbnVtZXJpYyc6XHJcbiAgICAgICAgcmV0dXJuICdtaW4td2lkdGg6IDEycmVtOyc7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuICd3aWR0aDogMHJlbTsnOyAvLyBmaXR0aW5nIGNvbnRlbnQgb2YgdGhlIHJvdyBsaWtlIHRoaXNcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldENvbE1hdGNoTW9kZU9wdGlvbnMoZmlsdGVyVHlwZTogc3RyaW5nKXtcclxuICAgIHN3aXRjaCAoZmlsdGVyVHlwZSkge1xyXG4gICAgICAgIGNhc2UgJ3RleHQnOlxyXG4gICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgY2FzZSAnZGF0ZSc6XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5tYXRjaE1vZGVEYXRlT3B0aW9ucztcclxuICAgICAgICBjYXNlICdtdWx0aXNlbGVjdCc6XHJcbiAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICBjYXNlICdib29sZWFuJzpcclxuICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIGNhc2UgJ251bWVyaWMnOlxyXG4gICAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hNb2RlTnVtYmVyT3B0aW9ucztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgIH1cclxuICB9XHJcbiAgXHJcbiAgZ2V0Q29sTWF0Y2hNb2RlKGZpbHRlclR5cGU6IHN0cmluZyl7XHJcbiAgICBzd2l0Y2ggKGZpbHRlclR5cGUpIHtcclxuICAgICAgICBjYXNlICd0ZXh0JzpcclxuICAgICAgICAgIHJldHVybiAnY29udGFpbnMnO1xyXG4gICAgICAgIGNhc2UgJ2RhdGUnOlxyXG4gICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgY2FzZSAnbXVsdGlzZWxlY3QnOlxyXG4gICAgICAgICAgcmV0dXJuICdpbic7XHJcbiAgICAgICAgY2FzZSAnYm9vbGVhbic6XHJcbiAgICAgICAgICByZXR1cm4gJ2VxdWFscyc7XHJcbiAgICAgICAgY2FzZSAnbnVtZXJpYyc6XHJcbiAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGlzRHJvcE9yTXVsdGkoZmlsdGVyVHlwZTogc3RyaW5nKXtcclxuICAgIGlmIChmaWx0ZXJUeXBlID09ICdkcm9wZG93bicgfHwgZmlsdGVyVHlwZSA9PSAnbXVsdGlzZWxlY3QnKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IFxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmF2aWdhdGVUb0RldGFpbHMocm93SWQ6IG51bWJlcil7XHJcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbcm93SWRdLCB7cmVsYXRpdmVUbzogdGhpcy5yb3V0ZX0pO1xyXG4gIH1cclxuXHJcbiAgZGVsZXRlT2JqZWN0KHJvd0lkOiBudW1iZXIpe1xyXG4gICAgdGhpcy5kZWxldGVSZWYgPSB0aGlzLmRpYWxvZ1NlcnZpY2Uub3BlbihTcGlkZXJseURlbGV0ZUNvbmZpcm1hdGlvbkNvbXBvbmVudCwgXHJcbiAgICAgIHsgXHJcbiAgICAgICAgaGVhZGVyOiB0aGlzLnRyYW5zbG9jb1NlcnZpY2UudHJhbnNsYXRlKCdBcmVZb3VTdXJlJyksXHJcbiAgICAgICAgd2lkdGg6ICc0MDBweCcsXHJcbiAgICAgICAgZGF0YTp7IGRlbGV0ZUl0ZW1Gcm9tVGFibGVPYnNlcnZhYmxlTWV0aG9kOiB0aGlzLmRlbGV0ZUl0ZW1Gcm9tVGFibGVPYnNlcnZhYmxlTWV0aG9kLCBpZDogcm93SWQsIH0gXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgdGhpcy5kZWxldGVSZWYub25DbG9zZS5zdWJzY3JpYmUoKGRlbGV0ZWRTdWNjZXNzZnVsbHk6IGJvb2xlYW4pPT57XHJcbiAgICAgICAgaWYoZGVsZXRlZFN1Y2Nlc3NmdWxseSA9PT0gdHJ1ZSl7XHJcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLnN1Y2Nlc3NNZXNzYWdlKHRoaXMudHJhbnNsb2NvU2VydmljZS50cmFuc2xhdGUoJ1N1Y2Nlc3NmdWxseURlbGV0ZWRNZXNzYWdlJykpO1xyXG4gICAgICAgICAgdGhpcy5yZWxvYWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmVsb2FkKCl7XHJcbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xyXG4gICAgdGhpcy5pdGVtcyA9IG51bGw7XHJcbiAgICB0aGlzLmxhenlMb2FkKHRoaXMubGFzdExhenlMb2FkRXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgc2hvd0FjdGlvbnMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb2xzLnNvbWUoeCA9PiB4LmFjdGlvbnM/Lmxlbmd0aCA+IDApO1xyXG4gIH1cclxuXHJcbiAgZ2V0U3R5bGVGb3JCb2R5Q29sdW1uKGNvbDogQ29sdW1uPGFueT4pIHtcclxuICAgIHN3aXRjaChjb2wuZmlsdGVyVHlwZSl7XHJcbiAgICAgIGNhc2UgJ251bWVyaWMnOlxyXG4gICAgICAgIHJldHVybiAndGV4dC1hbGlnbjogcmlnaHQ7JztcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldENsYXNzRm9yQWN0aW9uKGFjdGlvbjogQWN0aW9uKTogc3RyaW5ne1xyXG4gICAgc3dpdGNoKGFjdGlvbi5maWVsZCl7XHJcbiAgICAgIGNhc2UgJ0RldGFpbHMnOlxyXG4gICAgICAgIHJldHVybiAncGkgcGktcGVuY2lsIHRleHQtbGcgY3Vyc29yLXBvaW50ZXIgcHJpbWFyeS1jb2xvcic7XHJcbiAgICAgIGNhc2UgJ0RlbGV0ZSc6XHJcbiAgICAgICAgcmV0dXJuICdwaSBwaS10cmFzaCB0ZXh0LWxnIHRleHQtcmVkLTUwMCBjdXJzb3ItcG9pbnRlcic7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuIGAke2FjdGlvbi5pY29ufSAke2FjdGlvbi5zdHlsZX0gdGV4dC1sZyBjdXJzb3ItcG9pbnRlcmA7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRNZXRob2RGb3JBY3Rpb24oYWN0aW9uOiBBY3Rpb24sIHJvd0RhdGE6IGFueSl7XHJcbiAgICBzd2l0Y2goYWN0aW9uLmZpZWxkKXtcclxuICAgICAgY2FzZSAnRGV0YWlscyc6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmF2aWdhdGVUb0RldGFpbHMocm93RGF0YS5pZCk7XHJcbiAgICAgIGNhc2UgJ0RlbGV0ZSc6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlT2JqZWN0KHJvd0RhdGEuaWQpO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybiBhY3Rpb24ub25DbGljayhyb3dEYXRhLmlkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldFJvd0RhdGEocm93RGF0YTogYW55LCBjb2w6IENvbHVtbik6IHN0cmluZ3tcclxuICAgICAgc3dpdGNoIChjb2wuZmlsdGVyVHlwZSkge1xyXG4gICAgICAgIGNhc2UgJ3RleHQnOlxyXG4gICAgICAgICAgcmV0dXJuIHJvd0RhdGFbY29sLmZpZWxkXTtcclxuICAgICAgICBjYXNlICdkYXRlJzpcclxuICAgICAgICAgIGlmIChyb3dEYXRhW2NvbC5maWVsZF0gPT0gbnVsbClcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICBcclxuICAgICAgICAgIGlmIChjb2wuc2hvd1RpbWUpXHJcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXREYXRlKHJvd0RhdGFbY29sLmZpZWxkXSwgJ2RkLk1NLnl5eXkuIEhIOm1tJywgdGhpcy5sb2NhbGUpO1xyXG4gICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0RGF0ZShyb3dEYXRhW2NvbC5maWVsZF0sICdkZC5NTS55eXl5LicsIHRoaXMubG9jYWxlKTtcclxuICAgICAgICBjYXNlICdtdWx0aXNlbGVjdCc6XHJcbiAgICAgICAgICByZXR1cm4gcm93RGF0YVtjb2wuZmllbGRdO1xyXG4gICAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxyXG4gICAgICAgICAgcmV0dXJuIHJvd0RhdGFbY29sLmZpZWxkXSA9PSB0cnVlID8gdGhpcy50cmFuc2xvY29TZXJ2aWNlLnRyYW5zbGF0ZSgnWWVzJykgOiB0aGlzLnRyYW5zbG9jb1NlcnZpY2UudHJhbnNsYXRlKCdObycpO1xyXG4gICAgICAgIGNhc2UgJ251bWVyaWMnOlxyXG4gICAgICAgICAgLy8gVE9ETyBGVDogbWFrZSBkZWNpbWFsIHBpcGVcclxuICAgICAgICAgIHJldHVybiByb3dEYXRhW2NvbC5maWVsZF07XHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICBjb2xUcmFja0J5Rm4oaW5kZXgsIGl0ZW0pe1xyXG4gICAgcmV0dXJuIGl0ZW0uZmllbGQ7XHJcbiAgfVxyXG5cclxuICBhY3Rpb25UcmFja0J5Rm4oaW5kZXgsIGl0ZW06IEFjdGlvbil7XHJcbiAgICByZXR1cm4gYCR7aW5kZXh9JHtpdGVtLmZpZWxkfWBcclxuICB9XHJcblxyXG4gIGV4cG9ydExpc3RUb0V4Y2VsKCkge1xyXG4gICAgbGV0IHRhYmxlRmlsdGVyOiBUYWJsZUZpbHRlciA9IHRoaXMubGFzdExhenlMb2FkRXZlbnQgYXMgdW5rbm93biBhcyBUYWJsZUZpbHRlcjtcclxuICAgIHRhYmxlRmlsdGVyLmFkZGl0aW9uYWxGaWx0ZXJJZExvbmcgPSB0aGlzLmFkZGl0aW9uYWxGaWx0ZXJJZExvbmc7XHJcblxyXG4gICAgZXhwb3J0TGlzdFRvRXhjZWwodGhpcy5leHBvcnRUYWJsZURhdGFUb0V4Y2VsT2JzZXJ2YWJsZU1ldGhvZCwgdGFibGVGaWx0ZXIpO1xyXG4gIH1cclxuXHJcbiAgY2xlYXIodGFibGU6IFRhYmxlKSB7XHJcbiAgICB0YWJsZS5jbGVhcigpO1xyXG4gIH1cclxuXHJcbiAgLy8jcmVnaW9uIFNlbGVjdGlvblxyXG5cclxuICBzZXRGYWtlSXNBbGxTZWxlY3RlZCgpe1xyXG4gICAgaWYodGhpcy5yb3dzU2VsZWN0ZWROdW1iZXIgPT0gdGhpcy50b3RhbFJlY29yZHMpXHJcbiAgICAgIHRoaXMuZmFrZUlzQWxsU2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgZWxzZVxyXG4gICAgICB0aGlzLmZha2VJc0FsbFNlbGVjdGVkID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RBbGwoY2hlY2tlZDogYm9vbGVhbil7XHJcbiAgICB0aGlzLnVuc2VsZWN0ZWRJdGVtcy5sZW5ndGggPSAwO1xyXG4gICAgdGhpcy5uZXdseVNlbGVjdGVkSXRlbXMubGVuZ3RoID0gMDtcclxuXHJcbiAgICBpZiAoY2hlY2tlZCA9PSB0cnVlKSB7XHJcbiAgICAgIHRoaXMuaXNBbGxTZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMuZmFrZUlzQWxsU2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLm9uSXNBbGxTZWxlY3RlZENoYW5nZS5uZXh0KG5ldyBBbGxDbGlja0V2ZW50KHtjaGVja2VkOiB0cnVlLCBhZGRpdGlvbmFsSW5kZXhlczogdGhpcy5hZGRpdGlvbmFsSW5kZXhlc30pKTtcclxuICAgICAgdGhpcy5yb3dzU2VsZWN0ZWROdW1iZXIgPSB0aGlzLnRvdGFsUmVjb3JkcztcclxuICAgICAgdGhpcy5mYWtlU2VsZWN0ZWRJdGVtcyA9IFsuLi50aGlzLml0ZW1zLm1hcCh4ID0+IHguaWQpXTtcclxuICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1JZHMgPSBbLi4udGhpcy5pdGVtcy5tYXAoeCA9PiB4LmlkKV1cclxuICAgIH1cclxuICAgIGVsc2V7XHJcbiAgICAgIHRoaXMuaXNBbGxTZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmZha2VJc0FsbFNlbGVjdGVkID0gZmFsc2U7XHJcbiAgICAgIHRoaXMub25Jc0FsbFNlbGVjdGVkQ2hhbmdlLm5leHQobmV3IEFsbENsaWNrRXZlbnQoe2NoZWNrZWQ6IGZhbHNlLCBhZGRpdGlvbmFsSW5kZXhlczogdGhpcy5hZGRpdGlvbmFsSW5kZXhlc30pKTtcclxuICAgICAgdGhpcy5yb3dzU2VsZWN0ZWROdW1iZXIgPSAwO1xyXG4gICAgICB0aGlzLmZha2VTZWxlY3RlZEl0ZW1zID0gW107XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtSWRzID0gW107XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZWxlY3RSb3coaWQ6IG51bWJlciwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuaXNSb3dTZWxlY3RlZChpZCkpIHtcclxuICAgICAgdGhpcy5yb3dVbnNlbGVjdChpZCk7XHJcbiAgICAgIHRoaXMub25Sb3dVbnNlbGVjdC5uZXh0KG5ldyBSb3dDbGlja0V2ZW50KHsgaW5kZXg6IGluZGV4LCBpZDogaWQsIGFkZGl0aW9uYWxJbmRleGVzOiB0aGlzLmFkZGl0aW9uYWxJbmRleGVzIH0pKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucm93U2VsZWN0KGlkKTtcclxuICAgICAgdGhpcy5vblJvd1NlbGVjdC5uZXh0KG5ldyBSb3dDbGlja0V2ZW50KHsgaW5kZXg6IGluZGV4LCBpZDogaWQsIGFkZGl0aW9uYWxJbmRleGVzOiB0aGlzLmFkZGl0aW9uYWxJbmRleGVzIH0pKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlzUm93U2VsZWN0ZWQoaWQ6IG51bWJlcil7XHJcbiAgICBpZiAodGhpcy5oYXNMYXp5TG9hZCl7XHJcbiAgICAgIHJldHVybiB0aGlzLmZha2VTZWxlY3RlZEl0ZW1zLmZpbmQoeCA9PiB4ID09PSBpZCkgIT0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSXRlbUlkcy5maW5kKHggPT4geCA9PT0gaWQpICE9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJvd1NlbGVjdChpZDogbnVtYmVyKXtcclxuICAgIGlmICh0aGlzLmlzQWxsU2VsZWN0ZWQgPT0gZmFsc2UgfHwgdGhpcy5jdXJyZW50UGFnZVNlbGVjdGVkSXRlbXNGcm9tRGIuaW5jbHVkZXMoaWQpID09IGZhbHNlKSB7XHJcbiAgICAgIHRoaXMubmV3bHlTZWxlY3RlZEl0ZW1zLnB1c2goaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmhhc0xhenlMb2FkKXtcclxuICAgICAgdGhpcy5mYWtlU2VsZWN0ZWRJdGVtcy5wdXNoKGlkKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbUlkcy5wdXNoKGlkKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5yb3dzU2VsZWN0ZWROdW1iZXIrKztcclxuXHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMudW5zZWxlY3RlZEl0ZW1zLmluZGV4T2YoaWQpO1xyXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICB0aGlzLnVuc2VsZWN0ZWRJdGVtcy5zcGxpY2UoaW5kZXgsIDEpOyAvLyBGVDogU3BsaWNlIGlzIG11dGF0aW5nIHRoZSBhcnJheVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc2V0RmFrZUlzQWxsU2VsZWN0ZWQoKTtcclxuICB9XHJcbiAgXHJcbiAgcm93VW5zZWxlY3QoaWQ6IG51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCA9PSB0cnVlIHx8IHRoaXMuY3VycmVudFBhZ2VTZWxlY3RlZEl0ZW1zRnJvbURiLmluY2x1ZGVzKGlkKSA9PSB0cnVlKSB7XHJcbiAgICAgIHRoaXMudW5zZWxlY3RlZEl0ZW1zLnB1c2goaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucm93c1NlbGVjdGVkTnVtYmVyLS07XHJcblxyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm5ld2x5U2VsZWN0ZWRJdGVtcy5pbmRleE9mKGlkKTtcclxuICAgIGNvbnN0IGZha2VJbmRleCA9IHRoaXMuZmFrZVNlbGVjdGVkSXRlbXMuaW5kZXhPZihpZCk7XHJcbiAgICBjb25zdCBub25MYXp5TG9hZEluZGV4ID0gdGhpcy5zZWxlY3RlZEl0ZW1JZHMuaW5kZXhPZihpZCk7XHJcblxyXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICB0aGlzLm5ld2x5U2VsZWN0ZWRJdGVtcy5zcGxpY2UoaW5kZXgsIDEpOyAvLyBGVDogU3BsaWNlIGlzIG11dGF0aW5nIHRoZSBhcnJheVxyXG4gICAgfVxyXG4gICAgaWYgKGZha2VJbmRleCAhPT0gLTEpIHtcclxuICAgICAgdGhpcy5mYWtlU2VsZWN0ZWRJdGVtcy5zcGxpY2UoZmFrZUluZGV4LCAxKTsgLy8gRlQ6IFNwbGljZSBpcyBtdXRhdGluZyB0aGUgYXJyYXlcclxuICAgIH1cclxuICAgIGlmIChub25MYXp5TG9hZEluZGV4ICE9PSAtMSkge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbUlkcy5zcGxpY2Uobm9uTGF6eUxvYWRJbmRleCwgMSk7IC8vIEZUOiBTcGxpY2UgaXMgbXV0YXRpbmcgdGhlIGFycmF5XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zZXRGYWtlSXNBbGxTZWxlY3RlZCgpO1xyXG4gIH1cclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgLy8jcmVnaW9uIENsaWVudCBzaWRlIHRhYmxlXHJcblxyXG4gIC8vIEZUOiBDYW4gZG8gaXQgd2l0aCBJZCBhbHNvLCBiZWNhdXNlIHdlIGFyZSBuZXZlciBhZGRpbmcgdGhlIG5ldyByZWNvcmQgaW4gdGhlIHRhYmxlIGF0IHRoZSBzYW1lIHBhZ2UuXHJcbiAgZ2V0Rm9ybUFycmF5Q29udHJvbEJ5SW5kZXgoZm9ybUNvbnRyb2xOYW1lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpOiBTcGlkZXJseUZvcm1Db250cm9se1xyXG4gICAgaWYgKHRoaXMuZ2V0Rm9ybUNvbnRyb2wpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuZ2V0Rm9ybUNvbnRyb2woZm9ybUNvbnRyb2xOYW1lLCBpbmRleCwgdGhpcy5hZGRpdGlvbmFsSW5kZXhlcyk7XHJcbiAgICB9XHJcbiAgICBlbHNle1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vI2VuZHJlZ2lvblxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQWN0aW9uIHtcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIGZpZWxkPzogc3RyaW5nO1xyXG4gIGljb24/OiBzdHJpbmc7XHJcbiAgc3R5bGU/OiBzdHJpbmc7XHJcbiAgb25DbGljaz86IChpZDogbnVtYmVyKSA9PiB2b2lkO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHtcclxuICAgICAgbmFtZSxcclxuICAgICAgZmllbGQsXHJcbiAgICAgIGljb24sXHJcbiAgICAgIHN0eWxlLFxyXG4gICAgICBvbkNsaWNrLFxyXG4gICAgfTp7XHJcbiAgICAgIG5hbWU/OiBzdHJpbmc7XHJcbiAgICAgIGZpZWxkPzogc3RyaW5nO1xyXG4gICAgICBpY29uPzogc3RyaW5nO1xyXG4gICAgICBzdHlsZT86IHN0cmluZztcclxuICAgICAgb25DbGljaz86ICgpID0+IHZvaWQ7XHJcbiAgICB9ID0ge31cclxuICAgICkge1xyXG4gICAgICB0aGlzLm5hbWUgPSBuYW1lO1xyXG4gICAgICB0aGlzLmZpZWxkID0gZmllbGQ7XHJcbiAgICAgIHRoaXMuaWNvbiA9IGljb247XHJcbiAgICAgIHRoaXMuc3R5bGUgPSBzdHlsZTtcclxuICAgICAgdGhpcy5vbkNsaWNrID0gb25DbGljaztcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDb2x1bW48VCA9IGFueT4ge1xyXG4gIG5hbWU6IHN0cmluZztcclxuICBmaWVsZD86IHN0cmluZyAmIGtleW9mIFQ7XHJcbiAgZmlsdGVyRmllbGQ/OiBzdHJpbmcgJiBrZXlvZiBUOyAvLyBGVDogTWFkZSBzcGVjaWZpY2FseSBmb3IgbXVsdGlhdXRvY29tcGxldGUsIG1heWJlIGZvciBzb21ldGhpbmcgbW9yZSBpbiB0aGUgZnV0dXJlXHJcbiAgZmlsdGVyVHlwZT86ICd0ZXh0JyB8ICdkYXRlJyB8ICdtdWx0aXNlbGVjdCcgfCAnYm9vbGVhbicgfCAnbnVtZXJpYyc7XHJcbiAgZmlsdGVyUGxhY2Vob2xkZXI/OiBzdHJpbmc7XHJcbiAgc2hvd01hdGNoTW9kZXM/OiBib29sZWFuO1xyXG4gIHNob3dBZGRCdXR0b24/OiBib29sZWFuO1xyXG4gIGRyb3Bkb3duT3JNdWx0aXNlbGVjdFZhbHVlcz86IFByaW1lbmdPcHRpb25bXTtcclxuICBhY3Rpb25zPzogQWN0aW9uW107XHJcbiAgZWRpdGFibGU/OiBib29sZWFuO1xyXG4gIHNob3dUaW1lPzogYm9vbGVhbjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICB7XHJcbiAgICAgIG5hbWUsXHJcbiAgICAgIGZpZWxkLFxyXG4gICAgICBmaWx0ZXJGaWVsZCxcclxuICAgICAgZmlsdGVyVHlwZSxcclxuICAgICAgZmlsdGVyUGxhY2Vob2xkZXIsXHJcbiAgICAgIHNob3dNYXRjaE1vZGVzLFxyXG4gICAgICBzaG93QWRkQnV0dG9uLFxyXG4gICAgICBkcm9wZG93bk9yTXVsdGlzZWxlY3RWYWx1ZXMsXHJcbiAgICAgIGFjdGlvbnMsXHJcbiAgICAgIGVkaXRhYmxlLFxyXG4gICAgICBzaG93VGltZSxcclxuICAgIH06e1xyXG4gICAgICBuYW1lPzogc3RyaW5nO1xyXG4gICAgICBmaWVsZD86IHN0cmluZyAmIGtleW9mIFQ7XHJcbiAgICAgIGZpbHRlckZpZWxkPzogc3RyaW5nICYga2V5b2YgVDsgLy8gRlQ6IE1hZGUgc3BlY2lmaWNhbHkgZm9yIG11bHRpYXV0b2NvbXBsZXRlLCBtYXliZSBmb3Igc29tZXRoaW5nIG1vcmUgaW4gdGhlIGZ1dHVyZTtcclxuICAgICAgZmlsdGVyVHlwZT86ICd0ZXh0JyB8ICdkYXRlJyB8ICdtdWx0aXNlbGVjdCcgfCAnYm9vbGVhbicgfCAnbnVtZXJpYyc7XHJcbiAgICAgIGZpbHRlclBsYWNlaG9sZGVyPzogc3RyaW5nO1xyXG4gICAgICBzaG93TWF0Y2hNb2Rlcz86IGJvb2xlYW47XHJcbiAgICAgIHNob3dBZGRCdXR0b24/OiBib29sZWFuO1xyXG4gICAgICBkcm9wZG93bk9yTXVsdGlzZWxlY3RWYWx1ZXM/OiBQcmltZW5nT3B0aW9uW107XHJcbiAgICAgIGFjdGlvbnM/OiBBY3Rpb25bXTtcclxuICAgICAgZWRpdGFibGU/OiBib29sZWFuO1xyXG4gICAgICBzaG93VGltZT86IGJvb2xlYW47XHJcbiAgICB9ID0ge31cclxuICAgICkge1xyXG4gICAgICB0aGlzLm5hbWUgPSBuYW1lO1xyXG4gICAgICB0aGlzLmZpZWxkID0gZmllbGQ7XHJcbiAgICAgIHRoaXMuZmlsdGVyRmllbGQgPSBmaWx0ZXJGaWVsZDtcclxuICAgICAgdGhpcy5maWx0ZXJUeXBlID0gZmlsdGVyVHlwZTtcclxuICAgICAgdGhpcy5maWx0ZXJQbGFjZWhvbGRlciA9IGZpbHRlclBsYWNlaG9sZGVyO1xyXG4gICAgICB0aGlzLnNob3dNYXRjaE1vZGVzID0gc2hvd01hdGNoTW9kZXM7XHJcbiAgICAgIHRoaXMuc2hvd0FkZEJ1dHRvbiA9IHNob3dBZGRCdXR0b247XHJcbiAgICAgIHRoaXMuZHJvcGRvd25Pck11bHRpc2VsZWN0VmFsdWVzID0gZHJvcGRvd25Pck11bHRpc2VsZWN0VmFsdWVzO1xyXG4gICAgICB0aGlzLmFjdGlvbnMgPSBhY3Rpb25zO1xyXG4gICAgICB0aGlzLmVkaXRhYmxlID0gZWRpdGFibGU7XHJcbiAgICAgIHRoaXMuc2hvd1RpbWUgPSBzaG93VGltZTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBSb3dDbGlja0V2ZW50IHtcclxuICBpbmRleD86IG51bWJlcjtcclxuICBpZD86IG51bWJlcjtcclxuICBhZGRpdGlvbmFsSW5kZXhlcz86IGFueTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICB7XHJcbiAgICAgIGluZGV4LCBcclxuICAgICAgaWQsIFxyXG4gICAgICBhZGRpdGlvbmFsSW5kZXhlc1xyXG4gICAgfTp7XHJcbiAgICAgIGluZGV4PzogbnVtYmVyOyBcclxuICAgICAgaWQ/OiBudW1iZXI7IFxyXG4gICAgICBhZGRpdGlvbmFsSW5kZXhlcz86IGFueTtcclxuICAgIH0gPSB7fVxyXG4gICAgKSB7XHJcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XHJcbiAgICB0aGlzLmlkID0gaWQ7XHJcbiAgICB0aGlzLmFkZGl0aW9uYWxJbmRleGVzID0gYWRkaXRpb25hbEluZGV4ZXM7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQWxsQ2xpY2tFdmVudCB7XHJcbiAgY2hlY2tlZD86IGJvb2xlYW47XHJcbiAgYWRkaXRpb25hbEluZGV4ZXM/OiBhbnk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAge1xyXG4gICAgICBjaGVja2VkLCBcclxuICAgICAgYWRkaXRpb25hbEluZGV4ZXNcclxuICAgIH06e1xyXG4gICAgICBjaGVja2VkPzogYm9vbGVhbjsgXHJcbiAgICAgIGFkZGl0aW9uYWxJbmRleGVzPzogYW55O1xyXG4gICAgfSA9IHt9XHJcbiAgICApIHtcclxuICAgIHRoaXMuY2hlY2tlZCA9IGNoZWNrZWQ7XHJcbiAgICB0aGlzLmFkZGl0aW9uYWxJbmRleGVzID0gYWRkaXRpb25hbEluZGV4ZXM7XHJcbiAgfVxyXG59IiwiPG5nLWNvbnRhaW5lciAqdHJhbnNsb2NvPVwibGV0IHRcIj5cclxuICA8ZGl2IFtjbGFzc109XCJzaG93Q2FyZFdyYXBwZXIgPyAnY2FyZCByZXNwb25zaXZlLWNhcmQtcGFkZGluZyBvdmVyZmxvdy1hdXRvJyA6ICcnXCI+XHJcbiAgICA8cC10YWJsZSAjZHQgW3ZhbHVlXT1cIml0ZW1zXCIgW3Jvd3NdPVwicm93c1wiIFtyb3dIb3Zlcl09XCJ0cnVlXCIgc3R5bGVDbGFzcz1cInAtZGF0YXRhYmxlLWdyaWRsaW5lc1wiIFtwYWdpbmF0b3JdPVwic2hvd1BhZ2luYXRvclwiIHJlc3BvbnNpdmVMYXlvdXQ9XCJzY3JvbGxcIiBbbGF6eV09XCJoYXNMYXp5TG9hZFwiXHJcbiAgICAob25MYXp5TG9hZCk9XCJsYXp5TG9hZCgkZXZlbnQpXCIgW3RvdGFsUmVjb3Jkc109XCJ0b3RhbFJlY29yZHNcIiBjbGFzcz1cInNwaWRlcmx5LXRhYmxlXCIgW2xvYWRpbmddPVwiKGl0ZW1zID09PSB1bmRlZmluZWQgfHwgbG9hZGluZyA9PT0gdHJ1ZSlcIiBbc2VsZWN0aW9uTW9kZV09XCJzZWxlY3Rpb25Nb2RlXCIgZGF0YUtleT1cImlkXCIgXHJcbiAgICAob25GaWx0ZXIpPVwiZmlsdGVyKCRldmVudClcIj4gXHJcbiAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWhlYWRlciBvdmVyZmxvdy1hdXRvXCI+XHJcbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XHJcbiAgICAgICAgICAgIDxpIGNsYXNzPVwie3t0YWJsZUljb259fSB0ZXh0LTJ4bCBwcmltYXJ5LWNvbG9yXCI+PC9pPlxyXG4gICAgICAgICAgICA8aDUgc3R5bGU9XCJtYXJnaW46IDBweDtcIj57e3RhYmxlVGl0bGV9fTwvaDU+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDtcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIFtsYWJlbF09XCJ0KCdDbGVhckZpbHRlcnMnKVwiIGNsYXNzPVwicC1idXR0b24tb3V0bGluZWQgcmVtb3ZlLWJ1dHRvbi1ib3JkZXItZm9jdXNcIiBzdHlsZT1cImZsZXg6IG5vbmU7XCIgaWNvbj1cInBpIHBpLWZpbHRlci1zbGFzaFwiIChjbGljayk9XCJjbGVhcihkdClcIj48L2J1dHRvbj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uICpuZ0lmPVwic2hvd0V4cG9ydFRvRXhjZWxCdXR0b25cIiBbbGFiZWxdPVwidCgnRXhwb3J0VG9FeGNlbCcpXCIgY2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZCByZW1vdmUtYnV0dG9uLWJvcmRlci1mb2N1c1wiIHN0eWxlPVwiZmxleDogbm9uZTtcIiBpY29uPVwicGkgcGktZG93bmxvYWRcIiAoY2xpY2spPVwiZXhwb3J0TGlzdFRvRXhjZWwoKVwiPjwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gKm5nSWY9XCJzaG93UmVsb2FkVGFibGVCdXR0b25cIiBbbGFiZWxdPVwidCgnUmVsb2FkJylcIiBjbGFzcz1cInAtYnV0dG9uLW91dGxpbmVkIHJlbW92ZS1idXR0b24tYm9yZGVyLWZvY3VzXCIgc3R5bGU9XCJmbGV4OiBub25lO1wiIGljb249XCJwaSBwaS1yZWZyZXNoXCIgKGNsaWNrKT1cInJlbG9hZCgpXCI+PC9idXR0b24+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImhlYWRlclwiPlxyXG4gICAgICAgIDx0cj5cclxuICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAwcmVtO1wiICpuZ0lmPVwic2VsZWN0aW9uTW9kZSA9PSAnbXVsdGlwbGUnXCI+XHJcbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDhweDtcIj5cclxuICAgICAgICAgICAgICA8cC1jaGVja2JveCBbZGlzYWJsZWRdPVwicmVhZG9ubHlcIiAob25DaGFuZ2UpPVwic2VsZWN0QWxsKCRldmVudC5jaGVja2VkKVwiIFsobmdNb2RlbCldPVwiZmFrZUlzQWxsU2VsZWN0ZWRcIiBbYmluYXJ5XT1cInRydWVcIj48L3AtY2hlY2tib3g+ICh7e3Jvd3NTZWxlY3RlZE51bWJlcn19KVxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sczsgdHJhY2tCeTogY29sVHJhY2tCeUZuXCI+XHJcbiAgICAgICAgICAgIDx0aCBbc3R5bGVdPVwiZ2V0Q29sSGVhZGVyV2lkdGgoY29sLmZpbHRlclR5cGUpXCI+XHJcbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cclxuICAgICAgICAgICAgICAgIHt7Y29sLm5hbWV9fVxyXG4gICAgICAgICAgICAgICAgPCEtLSA8cC1zb3J0SWNvbiBmaWVsZD1cIlwiPjwvcC1zb3J0SWNvbj4gLS0+XHJcbiAgICAgICAgICAgICAgICA8IS0tIDxwLWNvbHVtbkZpbHRlciB0eXBlPVwiZGF0ZVwiIGZpZWxkPVwiZGF0ZVwiIGRpc3BsYXk9XCJtZW51XCI+PC9wLWNvbHVtbkZpbHRlcj4gLS0+XHJcbiAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXIgKm5nSWY9XCJjb2wuZmlsdGVyVHlwZSAhPSBudWxsXCIgW3R5cGVdPVwiY29sLmZpbHRlclR5cGVcIiBbZmllbGRdPVwiY29sLmZpbHRlckZpZWxkID8/IGNvbC5maWVsZFwiIGRpc3BsYXk9XCJtZW51XCIgW3BsYWNlaG9sZGVyXT1cImNvbC5maWx0ZXJQbGFjZWhvbGRlclwiIFxyXG4gICAgICAgICAgICAgICAgW3Nob3dPcGVyYXRvcl09XCJmYWxzZVwiIFtzaG93TWF0Y2hNb2Rlc109XCJjb2wuc2hvd01hdGNoTW9kZXNcIiBbc2hvd0FkZEJ1dHRvbl09XCJjb2wuc2hvd0FkZEJ1dHRvblwiIFttYXRjaE1vZGVPcHRpb25zXT1cImdldENvbE1hdGNoTW9kZU9wdGlvbnMoY29sLmZpbHRlclR5cGUpXCJcclxuICAgICAgICAgICAgICAgIFttYXRjaE1vZGVdPVwiZ2V0Q29sTWF0Y2hNb2RlKGNvbC5maWx0ZXJUeXBlKVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNEcm9wT3JNdWx0aShjb2wuZmlsdGVyVHlwZSlcIj5cclxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImZpbHRlclwiIGxldC12YWx1ZSBsZXQtZmlsdGVyPVwiZmlsdGVyQ2FsbGJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdCBbbmdNb2RlbF09XCJ2YWx1ZVwiIFtvcHRpb25zXT1cImNvbC5kcm9wZG93bk9yTXVsdGlzZWxlY3RWYWx1ZXNcIiBbcGxhY2Vob2xkZXJdPVwidCgnQWxsJylcIiAob25DaGFuZ2UpPVwiZmlsdGVyKCRldmVudC52YWx1ZSlcIiBvcHRpb25MYWJlbD1cImxhYmVsXCIgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiIFtzdHlsZV09XCJ7J3dpZHRoJzonMjQwcHgnfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIGxldC1pdGVtIHBUZW1wbGF0ZT1cIml0ZW1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtbXVsdGlzZWxlY3QtcmVwcmVzZW50YXRpdmUtb3B0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgIDwvcC1jb2x1bW5GaWx0ZXI+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1yb3dEYXRhIGxldC1pbmRleD1cInJvd0luZGV4XCIgbGV0LWVkaXRpbmc9XCJlZGl0aW5nXCI+XHJcbiAgICAgICAgPHRyPlxyXG4gICAgICAgICAgPHRkICpuZ0lmPVwic2VsZWN0aW9uTW9kZSA9PSAnbXVsdGlwbGUnXCI+XHJcbiAgICAgICAgICAgICAgPHAtY2hlY2tib3ggW2Rpc2FibGVkXT1cInJlYWRvbmx5XCIgKG9uQ2hhbmdlKT1cInNlbGVjdFJvdyhyb3dEYXRhLmlkLCByb3dEYXRhLmluZGV4KVwiIFtuZ01vZGVsXT1cImlzUm93U2VsZWN0ZWQocm93RGF0YS5pZClcIiBbYmluYXJ5XT1cInRydWVcIj48L3AtY2hlY2tib3g+XHJcbiAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHM7IHRyYWNrQnk6IGNvbFRyYWNrQnlGblwiPlxyXG4gICAgICAgICAgICA8dGQgW3BUb29sdGlwXT1cImdldFJvd0RhdGEocm93RGF0YSwgY29sKVwiIFtzdHlsZV09XCJnZXRTdHlsZUZvckJvZHlDb2x1bW4oY29sKVwiICpuZ0lmPVwiIWNvbC5lZGl0YWJsZVwiPlxyXG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgZ2FwOiAxOHB4O1wiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYWN0aW9uIG9mIGNvbC5hY3Rpb25zOyB0cmFja0J5OiBhY3Rpb25UcmFja0J5Rm5cIiA+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuIFtwVG9vbHRpcF09XCJhY3Rpb24ubmFtZVwiIFtjbGFzc109XCJnZXRDbGFzc0ZvckFjdGlvbihhY3Rpb24pXCIgKGNsaWNrKT1cImdldE1ldGhvZEZvckFjdGlvbihhY3Rpb24sIHJvd0RhdGEpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAge3tnZXRSb3dEYXRhKHJvd0RhdGEsIGNvbCl9fVxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJjb2wuZWRpdGFibGVcIj5cclxuICAgICAgICAgICAgICA8c3BpZGVybHktbnVtYmVyIFtjb250cm9sXT1cImdldEZvcm1BcnJheUNvbnRyb2xCeUluZGV4KGNvbC5maWVsZCwgcm93RGF0YS5pbmRleClcIiBbc2hvd0xhYmVsXT1cImZhbHNlXCI+PC9zcGlkZXJseS1udW1iZXI+XHJcbiAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZW1wdHltZXNzYWdlXCI+XHJcbiAgICAgICAgPHRyPlxyXG4gICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29scz8ubGVuZ3RoICsgKHNlbGVjdGlvbk1vZGUgPT09ICdtdWx0aXBsZScgPyAxIDogMClcIj57e3QoJ05vUmVjb3Jkc0ZvdW5kJyl9fTwvdGQ+XHJcbiAgICAgICAgPC90cj5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImxvYWRpbmdib2R5XCI+XHJcbiAgICAgICAgPHRyPlxyXG4gICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29scz8ubGVuZ3RoICsgKHNlbGVjdGlvbk1vZGUgPT09ICdtdWx0aXBsZScgPyAxIDogMClcIj57e3QoJ0xvYWRpbmcnKX19Li4uPC90ZD5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwicGFnaW5hdG9ybGVmdFwiPlxyXG4gICAgICAgIHt7dCgnVG90YWxSZWNvcmRzJyl9fToge3t0b3RhbFJlY29yZHN9fVxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwicGFnaW5hdG9ycmlnaHRcIj5cclxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBlbmQ7IGdhcDogMTBweDtcIj5cclxuICAgICAgICAgIDxzcGlkZXJseS1idXR0b24gKm5nSWY9XCJzaG93QWRkQnV0dG9uXCIgW2xhYmVsXT1cInQoJ0FkZE5ldycpXCIgaWNvbj1cInBpIHBpLXBsdXNcIiAob25DbGljayk9XCJuYXZpZ2F0ZVRvRGV0YWlscygwKVwiPjwvc3BpZGVybHktYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgPC9wLXRhYmxlPlxyXG4gIDwvZGl2PlxyXG48L25nLWNvbnRhaW5lcj4iXX0=