coer-elements 0.0.22 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. package/esm2022/coer-elements.mjs +2 -2
  2. package/esm2022/index.mjs +2 -0
  3. package/fesm2022/coer-elements.mjs +0 -4081
  4. package/fesm2022/coer-elements.mjs.map +1 -1
  5. package/index.d.ts +1 -5
  6. package/package.json +1 -1
  7. package/styles/angular-material.scss +8 -11
  8. package/styles/bootstrap.scss +3 -3
  9. package/components/index.d.ts +0 -16
  10. package/components/lib/coer-alert/coer-alert.component.d.ts +0 -23
  11. package/components/lib/coer-button/coer-button.component.d.ts +0 -44
  12. package/components/lib/coer-checkbox/coer-checkbox.component.d.ts +0 -28
  13. package/components/lib/coer-filebox/coer-filebox.component.d.ts +0 -33
  14. package/components/lib/coer-form/coer-form.component.d.ts +0 -33
  15. package/components/lib/coer-grid/coer-grid.component.d.ts +0 -53
  16. package/components/lib/coer-grid/coer-grid.extension.d.ts +0 -105
  17. package/components/lib/coer-grid/coer-grid.templates.d.ts +0 -9
  18. package/components/lib/coer-modal/coer-modal.component.d.ts +0 -38
  19. package/components/lib/coer-numberbox/coer-numberbox.component.d.ts +0 -56
  20. package/components/lib/coer-page-title/coer-page-title.component.d.ts +0 -12
  21. package/components/lib/coer-selectbox/coer-selectbox.component.d.ts +0 -75
  22. package/components/lib/coer-switch/coer-switch.component.d.ts +0 -31
  23. package/components/lib/coer-tab/coer-tab.component.d.ts +0 -35
  24. package/components/lib/coer-textarea/coer-textarea.component.d.ts +0 -51
  25. package/components/lib/coer-textbox/coer-textbox.component.d.ts +0 -57
  26. package/components/lib/components.module.d.ts +0 -31
  27. package/directives/index.d.ts +0 -3
  28. package/directives/lib/coer-ref.directive.d.ts +0 -14
  29. package/directives/lib/directives.module.d.ts +0 -8
  30. package/directives/lib/life-cycle.directive.d.ts +0 -16
  31. package/esm2022/components/index.mjs +0 -17
  32. package/esm2022/components/lib/coer-alert/coer-alert.component.mjs +0 -227
  33. package/esm2022/components/lib/coer-button/coer-button.component.mjs +0 -133
  34. package/esm2022/components/lib/coer-checkbox/coer-checkbox.component.mjs +0 -84
  35. package/esm2022/components/lib/coer-filebox/coer-filebox.component.mjs +0 -104
  36. package/esm2022/components/lib/coer-form/coer-form.component.mjs +0 -102
  37. package/esm2022/components/lib/coer-grid/coer-grid.component.mjs +0 -515
  38. package/esm2022/components/lib/coer-grid/coer-grid.extension.mjs +0 -412
  39. package/esm2022/components/lib/coer-grid/coer-grid.templates.mjs +0 -30
  40. package/esm2022/components/lib/coer-modal/coer-modal.component.mjs +0 -108
  41. package/esm2022/components/lib/coer-numberbox/coer-numberbox.component.mjs +0 -260
  42. package/esm2022/components/lib/coer-page-title/coer-page-title.component.mjs +0 -44
  43. package/esm2022/components/lib/coer-selectbox/coer-selectbox.component.mjs +0 -339
  44. package/esm2022/components/lib/coer-switch/coer-switch.component.mjs +0 -94
  45. package/esm2022/components/lib/coer-tab/coer-tab.component.mjs +0 -116
  46. package/esm2022/components/lib/coer-textarea/coer-textarea.component.mjs +0 -157
  47. package/esm2022/components/lib/coer-textbox/coer-textbox.component.mjs +0 -196
  48. package/esm2022/components/lib/components.module.mjs +0 -134
  49. package/esm2022/directives/index.mjs +0 -4
  50. package/esm2022/directives/lib/coer-ref.directive.mjs +0 -23
  51. package/esm2022/directives/lib/directives.module.mjs +0 -25
  52. package/esm2022/directives/lib/life-cycle.directive.mjs +0 -33
  53. package/esm2022/interfaces/index.mjs +0 -39
  54. package/esm2022/interfaces/lib/app-source.interface.mjs +0 -2
  55. package/esm2022/interfaces/lib/coer-filebox/file-image.interface.mjs +0 -2
  56. package/esm2022/interfaces/lib/coer-filebox/file.interface.mjs +0 -2
  57. package/esm2022/interfaces/lib/coer-grid/grid-button-by-row.interface.mjs +0 -2
  58. package/esm2022/interfaces/lib/coer-grid/grid-checkbox.interface.mjs +0 -2
  59. package/esm2022/interfaces/lib/coer-grid/grid-coer-numberbox.interface.mjs +0 -2
  60. package/esm2022/interfaces/lib/coer-grid/grid-coer-selectbox.interface.mjs +0 -2
  61. package/esm2022/interfaces/lib/coer-grid/grid-coer-switch.interface.mjs +0 -2
  62. package/esm2022/interfaces/lib/coer-grid/grid-coer-textbox.interface.mjs +0 -2
  63. package/esm2022/interfaces/lib/coer-grid/grid-column.interface.mjs +0 -2
  64. package/esm2022/interfaces/lib/coer-grid/grid-data-source.interface.mjs +0 -2
  65. package/esm2022/interfaces/lib/coer-grid/grid-header-button.interface.mjs +0 -2
  66. package/esm2022/interfaces/lib/coer-grid/grid-header-export-button.interface.mjs +0 -2
  67. package/esm2022/interfaces/lib/coer-grid/grid-header.interface.mjs +0 -2
  68. package/esm2022/interfaces/lib/coer-grid/grid-import.interface.mjs +0 -2
  69. package/esm2022/interfaces/lib/coer-grid/grid-input-checkbox.interface.mjs +0 -2
  70. package/esm2022/interfaces/lib/coer-grid/grid-input-switch-change.interface.mjs +0 -2
  71. package/esm2022/interfaces/lib/coer-grid/grid-input-textbox.interface.mjs +0 -2
  72. package/esm2022/interfaces/lib/coer-grid/grid-item.interface.mjs +0 -2
  73. package/esm2022/interfaces/lib/coer-grid/grid-keyup-enter.interface.mjs +0 -2
  74. package/esm2022/interfaces/lib/coer-grid/grid-length.interface.mjs +0 -2
  75. package/esm2022/interfaces/lib/coer-grid/grid-search.interface.mjs +0 -2
  76. package/esm2022/interfaces/lib/coer-grid/grid-sort.interface.mjs +0 -2
  77. package/esm2022/interfaces/lib/coer-menu/menu-option-selected.interface.mjs +0 -2
  78. package/esm2022/interfaces/lib/coer-menu/menu-selected.interface.mjs +0 -2
  79. package/esm2022/interfaces/lib/coer-menu/menu.interface.mjs +0 -2
  80. package/esm2022/interfaces/lib/coer-ref.interface.mjs +0 -2
  81. package/esm2022/interfaces/lib/page-title/breadcrumb.interface.mjs +0 -2
  82. package/esm2022/interfaces/lib/page-title/go-back.interface.mjs +0 -2
  83. package/esm2022/interfaces/lib/screen-size.interface.mjs +0 -2
  84. package/esm2022/interfaces/lib/service/http-request.interface.mjs +0 -2
  85. package/esm2022/interfaces/lib/service/http-response.interface.mjs +0 -2
  86. package/esm2022/interfaces/lib/service/patch.interface.mjs +0 -2
  87. package/esm2022/pipes/index.mjs +0 -5
  88. package/esm2022/pipes/lib/html.pipe.mjs +0 -18
  89. package/esm2022/pipes/lib/no-image.pipe.mjs +0 -23
  90. package/esm2022/pipes/lib/numeric-format.pipe.mjs +0 -15
  91. package/esm2022/pipes/lib/pipes.module.mjs +0 -31
  92. package/esm2022/public_api.mjs +0 -6
  93. package/esm2022/signals/index.mjs +0 -6
  94. package/esm2022/signals/lib/breakpoint.signal.mjs +0 -4
  95. package/esm2022/signals/lib/is-loading.signal.mjs +0 -3
  96. package/esm2022/signals/lib/is-menu-open.signal.mjs +0 -3
  97. package/esm2022/signals/lib/is-modal-open.signal.mjs +0 -3
  98. package/esm2022/signals/lib/menu.signal.mjs +0 -3
  99. package/esm2022/tools/index.mjs +0 -11
  100. package/esm2022/tools/lib/breadcrumbs.class.mjs +0 -63
  101. package/esm2022/tools/lib/control-value.class.mjs +0 -46
  102. package/esm2022/tools/lib/date-time.class.mjs +0 -29
  103. package/esm2022/tools/lib/files.class.mjs +0 -91
  104. package/esm2022/tools/lib/menu.class.mjs +0 -23
  105. package/esm2022/tools/lib/page.class.mjs +0 -156
  106. package/esm2022/tools/lib/screen.class.mjs +0 -51
  107. package/esm2022/tools/lib/service.class.mjs +0 -248
  108. package/esm2022/tools/lib/source.class.mjs +0 -80
  109. package/esm2022/tools/lib/tools.mjs +0 -220
  110. package/interfaces/index.d.ts +0 -33
  111. package/interfaces/lib/app-source.interface.d.ts +0 -4
  112. package/interfaces/lib/coer-filebox/file-image.interface.d.ts +0 -14
  113. package/interfaces/lib/coer-filebox/file.interface.d.ts +0 -5
  114. package/interfaces/lib/coer-grid/grid-button-by-row.interface.d.ts +0 -6
  115. package/interfaces/lib/coer-grid/grid-checkbox.interface.d.ts +0 -5
  116. package/interfaces/lib/coer-grid/grid-coer-numberbox.interface.d.ts +0 -12
  117. package/interfaces/lib/coer-grid/grid-coer-selectbox.interface.d.ts +0 -9
  118. package/interfaces/lib/coer-grid/grid-coer-switch.interface.d.ts +0 -6
  119. package/interfaces/lib/coer-grid/grid-coer-textbox.interface.d.ts +0 -11
  120. package/interfaces/lib/coer-grid/grid-column.interface.d.ts +0 -22
  121. package/interfaces/lib/coer-grid/grid-data-source.interface.d.ts +0 -6
  122. package/interfaces/lib/coer-grid/grid-header-button.interface.d.ts +0 -8
  123. package/interfaces/lib/coer-grid/grid-header-export-button.interface.d.ts +0 -10
  124. package/interfaces/lib/coer-grid/grid-header.interface.d.ts +0 -5
  125. package/interfaces/lib/coer-grid/grid-import.interface.d.ts +0 -4
  126. package/interfaces/lib/coer-grid/grid-input-checkbox.interface.d.ts +0 -5
  127. package/interfaces/lib/coer-grid/grid-input-switch-change.interface.d.ts +0 -5
  128. package/interfaces/lib/coer-grid/grid-input-textbox.interface.d.ts +0 -5
  129. package/interfaces/lib/coer-grid/grid-item.interface.d.ts +0 -5
  130. package/interfaces/lib/coer-grid/grid-keyup-enter.interface.d.ts +0 -6
  131. package/interfaces/lib/coer-grid/grid-length.interface.d.ts +0 -5
  132. package/interfaces/lib/coer-grid/grid-search.interface.d.ts +0 -4
  133. package/interfaces/lib/coer-grid/grid-sort.interface.d.ts +0 -5
  134. package/interfaces/lib/coer-menu/menu-option-selected.interface.d.ts +0 -9
  135. package/interfaces/lib/coer-menu/menu-selected.interface.d.ts +0 -10
  136. package/interfaces/lib/coer-menu/menu.interface.d.ts +0 -6
  137. package/interfaces/lib/coer-ref.interface.d.ts +0 -10
  138. package/interfaces/lib/page-title/breadcrumb.interface.d.ts +0 -6
  139. package/interfaces/lib/page-title/go-back.interface.d.ts +0 -6
  140. package/interfaces/lib/screen-size.interface.d.ts +0 -5
  141. package/interfaces/lib/service/http-request.interface.d.ts +0 -10
  142. package/interfaces/lib/service/http-response.interface.d.ts +0 -6
  143. package/interfaces/lib/service/patch.interface.d.ts +0 -5
  144. package/pipes/index.d.ts +0 -4
  145. package/pipes/lib/html.pipe.d.ts +0 -10
  146. package/pipes/lib/no-image.pipe.d.ts +0 -7
  147. package/pipes/lib/numeric-format.pipe.d.ts +0 -7
  148. package/pipes/lib/pipes.module.d.ts +0 -9
  149. package/public_api.d.ts +0 -5
  150. package/signals/index.d.ts +0 -5
  151. package/signals/lib/breakpoint.signal.d.ts +0 -1
  152. package/signals/lib/is-loading.signal.d.ts +0 -1
  153. package/signals/lib/is-menu-open.signal.d.ts +0 -1
  154. package/signals/lib/is-modal-open.signal.d.ts +0 -1
  155. package/signals/lib/menu.signal.d.ts +0 -2
  156. package/tools/index.d.ts +0 -10
  157. package/tools/lib/breadcrumbs.class.d.ts +0 -18
  158. package/tools/lib/control-value.class.d.ts +0 -25
  159. package/tools/lib/date-time.class.d.ts +0 -13
  160. package/tools/lib/files.class.d.ts +0 -16
  161. package/tools/lib/menu.class.d.ts +0 -8
  162. package/tools/lib/page.class.d.ts +0 -60
  163. package/tools/lib/screen.class.d.ts +0 -13
  164. package/tools/lib/service.class.d.ts +0 -39
  165. package/tools/lib/source.class.d.ts +0 -20
  166. package/tools/lib/tools.d.ts +0 -34
@@ -1,515 +0,0 @@
1
- import { Component, computed } from '@angular/core';
2
- import { CoerGridExtension } from './coer-grid.extension';
3
- import { CONTROL_VALUE } from '../../../tools/lib/control-value.class';
4
- import { Files } from '../../../tools/lib/files.class';
5
- import { Tools } from '../../../tools/lib/tools';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/common";
8
- import * as i2 from "@angular/forms";
9
- import * as i3 from "../coer-button/coer-button.component";
10
- import * as i4 from "../coer-checkbox/coer-checkbox.component";
11
- import * as i5 from "../coer-numberbox/coer-numberbox.component";
12
- import * as i6 from "../coer-selectbox/coer-selectbox.component";
13
- import * as i7 from "../coer-switch/coer-switch.component";
14
- import * as i8 from "../coer-textbox/coer-textbox.component";
15
- import * as i9 from "../../../pipes/lib/html.pipe";
16
- import * as i10 from "../../../pipes/lib/numeric-format.pipe";
17
- export class CoerGrid extends CoerGridExtension {
18
- constructor() {
19
- super(...arguments);
20
- //computed
21
- this.dataSource = computed(() => {
22
- return Tools.BreakReference(this.value_signal()).map(item => {
23
- if (item.hasOwnProperty('checked'))
24
- delete item.checked;
25
- if (item.hasOwnProperty('indexRow'))
26
- delete item.indexRow;
27
- return item;
28
- });
29
- });
30
- //computed
31
- this.selectedItems = computed(() => {
32
- return Tools.BreakReference(this.value_signal()).filter(item => item.checked).map(item => {
33
- if (item.hasOwnProperty('checked'))
34
- delete item.checked;
35
- if (item.hasOwnProperty('indexRow'))
36
- delete item.indexRow;
37
- return item;
38
- });
39
- });
40
- //computed
41
- this.gridLength = computed(() => {
42
- return {
43
- dataSource: this.value_signal()?.length || 0,
44
- dataSourceFiltered: this.gridDataSourceFiltered()?.length || 0,
45
- dataSourceSelected: this.selectedItems()?.length || 0
46
- };
47
- });
48
- }
49
- //getter
50
- get isValid() {
51
- return (this.coerTextboxList().length > 0 ? this.coerTextboxList().every(x => !x.isInvalid()) : true)
52
- && (this.coerNumberboxList().length > 0 ? this.coerNumberboxList().every(x => !x.isInvalid()) : true)
53
- && (this.coerSelectboxList().length > 0 ? this.coerSelectboxList().every(x => !x.isInvalid()) : true);
54
- }
55
- //computed
56
- //protected _columnsFiltered = computed<IGridHeader[]>(() => {
57
- // return this.isGrouped() && !this.showColumnGrouped
58
- // ? this._columns().filter(x => x.columnName.toUpperCase() != this.groupBy.toUpperCase())
59
- // : this._columns();
60
- //});
61
- /** */
62
- FocusSearch() {
63
- Tools.Sleep(0).then(() => {
64
- if (this.inputSearch)
65
- this.inputSearch().Focus();
66
- });
67
- }
68
- /** */
69
- SelectSearch() {
70
- Tools.Sleep(0).then(() => {
71
- if (this.inputSearch)
72
- this.inputSearch().Select();
73
- });
74
- }
75
- /** */
76
- GetRowBy(callback) {
77
- const row = this._value.find(callback);
78
- return (row === undefined) ? null : row;
79
- }
80
- /** */
81
- async Import(event = null) {
82
- if (this.importButton?.preventDefault) {
83
- this.onClickImport.emit({ data: [], file: null });
84
- return;
85
- }
86
- if (event === null) {
87
- this.inputFile().nativeElement.value = null;
88
- this.inputFile().nativeElement.click();
89
- return;
90
- }
91
- else if (event.target.files.length > 0) {
92
- this._isLoading = true;
93
- const [selectedFile] = event.target.files;
94
- if (Files.IsExcel(selectedFile)) {
95
- const { rows } = await Files.ReadExcel(selectedFile);
96
- if (Tools.IsNull(this.importButton?.Autofill) || this.importButton.Autofill) {
97
- this.SetValue(rows.concat(this._value));
98
- this.onClickImport.emit({ data: this._value, file: selectedFile });
99
- }
100
- else {
101
- this.onClickImport.emit({ data: rows, file: selectedFile });
102
- }
103
- }
104
- else {
105
- let message = 'Allowed extensions:';
106
- for (const extension of Files.EXCEL_EXTENSIONS) {
107
- message += ` <b>${extension}</b>,`;
108
- }
109
- message = message.substring(0, message.length - 1);
110
- this.alert.Warning(message, 'Invalid File Type', 'bi bi-filetype-xlsx fa-lg');
111
- this.onClickImport.emit({ data: [], file: null });
112
- }
113
- this.inputFile().nativeElement.value = null;
114
- Tools.Sleep(1000).then(() => this._isLoading = false);
115
- }
116
- }
117
- /** */
118
- Export(exportFile = true) {
119
- let item = {};
120
- this._isLoading = true;
121
- const FILE_NAME = (this.exportButton?.fileName || 'COER Report') + '.xlsx';
122
- let ROW_DATA_SOURCE = (this.exportButton.hasOwnProperty('onlyRowFiltered') && !this.exportButton.onlyRowFiltered)
123
- ? this.value_signal() : this.gridDataSourceFiltered();
124
- const COLUMN_DATA_SOURCE = new Set();
125
- if (this.exportButton.hasOwnProperty('onlyColumnFiltered') && !this.exportButton.onlyColumnFiltered) {
126
- for (const row of this.value_signal()) {
127
- for (const columnName in row) {
128
- if (columnName == 'indexRow')
129
- continue;
130
- COLUMN_DATA_SOURCE.add(Tools.FirstCharToLower(columnName));
131
- }
132
- }
133
- }
134
- else {
135
- for (const { columnName } of this.gridColumns()) {
136
- if (columnName == 'indexRow')
137
- continue;
138
- COLUMN_DATA_SOURCE.add(Tools.FirstCharToLower(columnName));
139
- }
140
- }
141
- const EXPORT_DATA = [];
142
- for (const row of ROW_DATA_SOURCE) {
143
- for (const column of COLUMN_DATA_SOURCE) {
144
- item = Object.assign(item, { [this._GetColumnName(column)]: row[column] });
145
- }
146
- EXPORT_DATA.push(item);
147
- item = Tools.BreakReference({});
148
- }
149
- if (exportFile) {
150
- Files.ExportExcel(EXPORT_DATA, FILE_NAME);
151
- }
152
- this.onClickExport.emit(EXPORT_DATA);
153
- Tools.Sleep(3000).then(() => this._isLoading = false);
154
- }
155
- /** */
156
- InputChange(indexRow, columnName, value, input) {
157
- if (input === 'coer-textbox-search') {
158
- if (this._isLoading)
159
- return;
160
- Tools.Sleep(0, `coerGridInputChange${columnName}`).then(async (_) => {
161
- this._gridSearch.set(value);
162
- if (this.checkbox.show) {
163
- this._isLoadingMessage = true;
164
- await Tools.Sleep();
165
- for (const row of this._value.filter((x) => x.checked)) {
166
- this.CheckBy((x) => x.indexRow == row.indexRow);
167
- }
168
- await Tools.Sleep();
169
- this._isLoadingMessage = false;
170
- }
171
- });
172
- return;
173
- }
174
- const property = Tools.FirstCharToLower(columnName);
175
- const row = this._value[indexRow];
176
- row[property] = value;
177
- if (input === 'coer-switch') {
178
- this.onSwitchChange.emit({ property, row: Tools.BreakReference(row), value });
179
- }
180
- else if (input === 'coer-textbox') {
181
- this.onTextboxChange.emit({ property, row: Tools.BreakReference(row), value });
182
- }
183
- else if (input === 'coer-selectbox') {
184
- this.onSelectboxChange.emit({ property, row: Tools.BreakReference(row), value });
185
- }
186
- else if (input === 'coer-numberbox') {
187
- this.onTextboxChange.emit({ property, row: Tools.BreakReference(row), value });
188
- }
189
- Tools.Sleep(1000, `coerGridInputChange${indexRow}${columnName}`).then(_ => {
190
- this._UpdateValue(this._value);
191
- this.value_signal.set(this._value);
192
- });
193
- }
194
- /** */
195
- KeyupEnter(indexColumn, row, input, value) {
196
- if (['coer-textbox', 'coer-numberbox', 'coer-selectbox'].includes(input)) {
197
- this.onKeyupEnter.emit({
198
- id: this._GetId(indexColumn, row.indexRow, input),
199
- input, row: Tools.BreakReference(row), value
200
- });
201
- this.NextInput(indexColumn, row.indexRow);
202
- }
203
- else if (input == 'coer-textbox-search') {
204
- this.onKeyupEnter.emit({
205
- id: this._GetId(indexColumn, row.indexRow, input),
206
- input, row: null, value
207
- });
208
- }
209
- }
210
- /** */
211
- NextInput(indexColumn, indexRow) {
212
- const INPUT_TEXT = this.columns().filter(x => Tools.IsNotNull(x.coerTextbox)).map(x => x.property);
213
- const INPUT_NUMBER = this.columns().filter(x => Tools.IsNotNull(x.coerNumberbox)).map(x => x.property);
214
- const INPUT_SELECT = this.columns().filter(x => Tools.IsNotNull(x.coerSelectbox)).map(x => x.property);
215
- let index = 0;
216
- const COLUMNS = [];
217
- const INPUT_COLUMNS = [];
218
- for (const { columnName } of this.gridColumns()) {
219
- if (INPUT_TEXT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
220
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
221
- INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
222
- }
223
- else if (INPUT_NUMBER.some(property => property.toUpperCase() == columnName.toUpperCase())) {
224
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
225
- INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
226
- }
227
- else if (INPUT_SELECT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
228
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
229
- INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
230
- }
231
- else {
232
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'default-cell' });
233
- }
234
- ++index;
235
- }
236
- let lastRow = -1;
237
- for (const { rows } of this.gridDataSource()) {
238
- lastRow += rows.length;
239
- }
240
- let firstColumn = -1;
241
- if (INPUT_COLUMNS.length > 0) {
242
- firstColumn = [...INPUT_COLUMNS].shift().indexColumn;
243
- }
244
- let lastColumn = -1;
245
- if (INPUT_COLUMNS.length > 0) {
246
- lastColumn = [...INPUT_COLUMNS].pop().indexColumn;
247
- }
248
- //Is Last Row & Last Input Column?
249
- if (indexRow == lastRow && indexColumn == lastColumn) {
250
- this.onKeyupEnterLast.emit();
251
- }
252
- //Is Last Input Column?
253
- else if (indexColumn == lastColumn) {
254
- this.FocusInput((indexRow + 1), firstColumn);
255
- }
256
- //Next Column?
257
- else {
258
- for (index = (indexColumn + 1); index < COLUMNS.length; index++) {
259
- for (const input of COLUMNS) {
260
- if (index == input.indexColumn && ['coerTextbox', 'coerNumberbox', 'coerSelectbox'].includes(input.type)) {
261
- this.FocusInput(indexRow, input.indexColumn);
262
- return;
263
- }
264
- }
265
- }
266
- }
267
- }
268
- /** */
269
- FocusInput(indexRow = -1, indexColumn = -1) {
270
- Tools.Sleep(0, 'FocusInput').then(() => {
271
- if (this._isDisabled())
272
- return;
273
- if (indexRow < 0 || indexColumn < 0) {
274
- const INPUT_TEXT = this.columns().filter(x => Tools.IsNotNull(x.coerTextbox)).map(x => x.property);
275
- const INPUT_NUMBER = this.columns().filter(x => Tools.IsNotNull(x.coerNumberbox)).map(x => x.property);
276
- const INPUT_SELECT = this.columns().filter(x => Tools.IsNotNull(x.coerSelectbox)).map(x => x.property);
277
- let index = 0;
278
- const COLUMNS = [];
279
- for (const { columnName } of this.gridColumns()) {
280
- if (INPUT_TEXT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
281
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
282
- }
283
- else if (INPUT_NUMBER.some(property => property.toUpperCase() == columnName.toUpperCase())) {
284
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
285
- }
286
- else if (INPUT_SELECT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
287
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
288
- }
289
- else {
290
- COLUMNS.push({ indexColumn: index, property: columnName, type: 'default-cell' });
291
- }
292
- ++index;
293
- }
294
- if (this.gridLength().dataSourceFiltered > 0) {
295
- const FIRST_INPUT_COLUMN = COLUMNS.find(x => ['coerTextbox', 'coerNumberbox', 'coerSelectbox'].includes(x.type));
296
- if (Tools.IsNotNull(FIRST_INPUT_COLUMN)) {
297
- this.FocusInput(0, FIRST_INPUT_COLUMN.indexColumn);
298
- }
299
- }
300
- }
301
- else {
302
- const id = this._GetId(indexRow, indexColumn);
303
- let element;
304
- this._indexFocus.set(indexRow);
305
- //Focus Textbox
306
- element = this.coerTextboxList().find(x => x.id == id);
307
- if (element) {
308
- element.Select();
309
- return;
310
- }
311
- //Focus Numberbox
312
- element = this.coerNumberboxList().find(x => x.id == id);
313
- if (element) {
314
- element.Select();
315
- return;
316
- }
317
- //Focus Selectbox
318
- element = this.coerSelectboxList().find(x => x.id == id);
319
- if (element) {
320
- Tools.Sleep(100).then(_ => element.Focus());
321
- return;
322
- }
323
- }
324
- });
325
- }
326
- /** */
327
- FocusRow(callback) {
328
- Tools.Sleep().then(_ => {
329
- if (this._value.length > 0) {
330
- const row = Tools.BreakReference(this._value.find(callback));
331
- if (Tools.IsNotNull(row))
332
- this._indexFocus.set(row.indexRow);
333
- }
334
- });
335
- }
336
- /** */
337
- async Sort(columnName) {
338
- if (this.enableSort()) {
339
- if (this._isLoading)
340
- return;
341
- this._isLoading = true;
342
- this._isLoadingMessage = true;
343
- const { direction } = this._sort();
344
- let dataSource = Tools.BreakReference(this._value);
345
- for (const checkbox of this.coerCheckboxList())
346
- checkbox.Uncheck();
347
- if (direction == 'descendant') {
348
- Tools.SortByDesc(dataSource, columnName);
349
- this._sort.set({ columnName, direction: 'ascendant', icon: 'fa-solid fa-arrow-down-short-wide' });
350
- }
351
- else {
352
- Tools.SortBy(dataSource, columnName);
353
- this._sort.set({ columnName, direction: 'descendant', icon: 'fa-solid fa-arrow-up-wide-short' });
354
- }
355
- let indexRow = 0;
356
- dataSource = Tools.BreakReference(dataSource).map((item) => Object.assign(item, { indexRow: indexRow++ }));
357
- this.SetValue(dataSource);
358
- this._isLoading = false;
359
- await Tools.Sleep();
360
- for (const row of dataSource.filter((x) => x.checked)) {
361
- this.CheckBy((x) => x.indexRow == row.indexRow);
362
- }
363
- this._isLoadingMessage = false;
364
- }
365
- return;
366
- }
367
- /** */
368
- ClickCheck(id, checked, all, row = null) {
369
- if (!this._isLoading)
370
- Tools.Sleep().then(async (_) => {
371
- this._isLoading = true;
372
- let element = this.coerCheckboxList().find(x => x.id() == id);
373
- if (Tools.IsNotNull(element)) {
374
- let response = { all, checked, rows: [] };
375
- //All Checkbox
376
- if (all) {
377
- if (checked)
378
- this.CheckAll();
379
- else
380
- this.UncheckAll();
381
- //Event
382
- response.rows = this.selectedItems();
383
- this.onCheckboxChange.emit(response);
384
- }
385
- //One Checkbox
386
- else {
387
- if (this._onlyOneCheck) {
388
- for (const row of this._value) {
389
- row.checked = false;
390
- }
391
- for (const checkbox of this.coerCheckboxList()) {
392
- if (checkbox.id() != id)
393
- checkbox.Uncheck();
394
- }
395
- }
396
- this._value[row.indexRow].checked = checked;
397
- this.SetValue(this._value);
398
- //Mark All checkbox
399
- const checkboxAll = this.coerCheckboxList().find(x => x.id() == this._GetId(0, 0, 'checkboxAll'));
400
- if (this.value_signal().every((x) => x.checked)) {
401
- checkboxAll?.Check();
402
- }
403
- else {
404
- checkboxAll?.Uncheck();
405
- }
406
- //Event
407
- response.rows = [{ ...row }];
408
- this.onCheckboxChange.emit(response);
409
- this._isLoading = false;
410
- }
411
- }
412
- });
413
- }
414
- /** */
415
- CheckAll() {
416
- this._isLoading = true;
417
- for (const row of this._value) {
418
- row.checked = true;
419
- }
420
- this.SetValue(this._value);
421
- for (const checkbox of this.coerCheckboxList()) {
422
- checkbox.Check();
423
- }
424
- this._isLoading = false;
425
- }
426
- /** */
427
- UncheckAll() {
428
- this._isLoading = true;
429
- for (const row of this._value) {
430
- row.checked = false;
431
- }
432
- this.SetValue(this._value);
433
- for (const checkbox of this.coerCheckboxList()) {
434
- checkbox.Uncheck();
435
- }
436
- this._isLoading = false;
437
- }
438
- /** */
439
- CheckBy(callback) {
440
- Tools.Sleep().then(_ => {
441
- if (this._value.length > 0) {
442
- const rowList = Tools.BreakReference(this._value.filter(callback));
443
- let element;
444
- for (const { indexRow } of rowList) {
445
- element = this.coerCheckboxList().find(x => x.id() == this._GetId(indexRow, 0, 'checkbox'));
446
- if (Tools.IsNotNull(element)) {
447
- element?.Check();
448
- }
449
- }
450
- }
451
- });
452
- }
453
- /** */
454
- UncheckBy(callback) {
455
- Tools.Sleep().then(_ => {
456
- if (this._value.length > 0) {
457
- const rowList = Tools.BreakReference(this._value.filter(callback));
458
- let element;
459
- for (const { indexRow } of rowList) {
460
- element = this.coerCheckboxList().find(x => x.id() == this._GetId(indexRow, 0, 'checkbox'));
461
- if (Tools.IsNotNull(element)) {
462
- element?.Uncheck();
463
- }
464
- }
465
- }
466
- });
467
- }
468
- /** */
469
- ClickOnRow(row) {
470
- if (this._isDisabled())
471
- return;
472
- if (Tools.IsNotNull(this.checkbox.checkOnRow) && this.checkbox.checkOnRow) {
473
- this.CheckBy((x) => x.indexRow == row.indexRow);
474
- }
475
- this.onClickRow.emit(row);
476
- }
477
- /** Inserts new elements at the start */
478
- Unshift(row) {
479
- const dataSource = Tools.BreakReference(this._value);
480
- dataSource.unshift(row);
481
- this.SetValue(dataSource);
482
- this.FocusInput();
483
- }
484
- /** Appends new elements to the end */
485
- Push(row) {
486
- const dataSource = Tools.BreakReference(this._value);
487
- dataSource.push(row);
488
- this.SetValue(dataSource);
489
- this.FocusInput();
490
- }
491
- /** Delete Row By index */
492
- async DeleteRow(indexRow) {
493
- const dataSource = Tools.BreakReference(this._value);
494
- dataSource.splice(indexRow, 1);
495
- this.SetValue(dataSource);
496
- }
497
- /** Delete row list by callback */
498
- async DeleteRowsBy(callback) {
499
- const indexList = Tools.BreakReference(this._value.filter(callback).map((item) => item.indexRow));
500
- let dataSource = [];
501
- for (const indexRow of indexList) {
502
- dataSource = Tools.BreakReference(this._value);
503
- dataSource.splice(indexRow, 1);
504
- this.SetValue(dataSource);
505
- await Tools.Sleep();
506
- }
507
- }
508
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CoerGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
509
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CoerGrid, selector: "coer-grid", providers: [CONTROL_VALUE(CoerGrid)], usesInheritance: true, ngImport: i0, template: "<div class=\"coer-grid\" [ngStyle]=\"{ 'width': width(), 'min-Width': MinWidth(), 'max-Width': MaxWidth(), 'margin': margin() }\">\r\n <header [id]=\"_id + '-header'\" class=\"row\">\r\n <!-- Slot -->\r\n <ng-content></ng-content>\r\n\r\n <!-- Export Button -->\r\n @if(exportButton.show && gridLength().dataSource > 0) {\r\n <div class=\"col-auto\">\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"excel\"\r\n [tooltip]=\"_isLoading ? 'Loading' : (exportButton.tooltip || 'Export')\"\r\n [path]=\"(exportButton && exportButton.path) ? exportButton.path : []\"\r\n [isDisabled]=\"_isDisabled() || _isLoading || (exportButton.isDisabled || false)\"\r\n [isLoading]=\"_isLoading\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"Export(!exportButton.preventDefault)\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Import Button -->\r\n @if(importButton.show) {\r\n <div class=\"col-auto\">\r\n <input type=\"file\" #inputFileRef [multiple]=\"false\" (change)=\"Import($event)\">\r\n\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"import\"\r\n [tooltip]=\"importButton.tooltip || 'Import'\"\r\n [path]=\"(importButton && importButton.path) ? importButton.path : []\"\r\n [isDisabled]=\"importButton.isDisabled || false\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"Import()\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Add Button -->\r\n @if(addButton.show) {\r\n <div class=\"col-auto\">\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"new\"\r\n [tooltip]=\"addButton.tooltip || 'New'\"\r\n [path]=\"(addButton && addButton.path) ? addButton.path : []\"\r\n [isDisabled]=\"addButton.isDisabled || false\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"onClickAdd.emit()\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Search -->\r\n @if(search.show) {\r\n <div class=\"col-auto\">\r\n <coer-textbox\r\n #inputSearch\r\n [id]=\"_GetId(-1, -1, 'search')\"\r\n [ngModel]=\"_gridSearch()\"\r\n placeholder=\"Search\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n [selectOnFocus]=\"true\"\r\n width=\"250px\"\r\n [showSearchIcon]=\"true\"\r\n [showClearIcon]=\"true\"\r\n (onInput)=\"InputChange(-1, 'Search', $event, 'coer-textbox-search')\"\r\n (onClickClear)=\"InputChange(-1, 'Search', '', 'coer-textbox-search')\"\r\n (onKeyupEnter)=\"KeyupEnter(-1, { indexRow: -1 }, 'coer-textbox-search', $event);\"\r\n ></coer-textbox>\r\n </div>\r\n }\r\n </header>\r\n\r\n <section [ngClass]=\"{ 'grid-container': true, 'invisible': isInvisible() }\">\r\n <div [ngStyle]=\"{ 'height': _height, 'min-height': minHeight(), 'max-height': maxHeight() }\">\r\n @if(isLoading()) {\r\n <!-- Grid Message -->\r\n <div class=\"loading\">\r\n <i class=\"spinner-border\"></i>\r\n <span class=\"fa-fade\">Loading</span>\r\n </div>\r\n }\r\n\r\n @else if(!_isDisabled() && gridLength().dataSource <= 0) {\r\n <div class=\"no-data\"> No Data </div>\r\n }\r\n\r\n <table class=\"table table-sm table-responsive table-striped\">\r\n <thead>\r\n <tr>\r\n @if(checkbox.show && gridLength().dataSource > 0) {\r\n <!-- CheckBox Column -->\r\n <th scope=\"col\" class=\"check-box\">\r\n <div *ngIf=\"!_onlyOneCheck\" [ngClass]=\"{ 'invisible': _isLoadingMessage }\">\r\n <coer-checkbox\r\n [id]=\"_GetId(0, 0, 'checkboxAll')\"\r\n [ignoreModel]=\"true\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n (onChange)=\"ClickCheck(_GetId(0, 0, 'checkboxAll'), $event, true)\"\r\n ></coer-checkbox>\r\n </div>\r\n </th>\r\n }\r\n\r\n <!-- Dynamic Grid Column -->\r\n @for(header of gridColumns(); track header.indexColumn) {\r\n <th scope=\"col\" (dblclick)=\"Sort(header.columnName)\"\r\n [ngClass]=\"{\r\n 'no-selection': true,\r\n 'cursor-default': !enableSort() && !_isLoading,\r\n 'cursor-pointer': enableSort() && !_isLoading,\r\n 'cursor-wait': _isLoading\r\n }\"\r\n [ngStyle]=\"{\r\n 'width': header.width,\r\n 'text-align': GetAttribute(header.columnName, null, 'textAlign', 'defaul-cell')\r\n }\">\r\n <div class=\"no-selection\">\r\n {{ _GetColumnName(header.columnName) }}\r\n <i [class]=\"_GetShortIcon(header.columnName)\"></i>\r\n </div>\r\n </th>\r\n }\r\n\r\n <!-- Delete Button Column -->\r\n @if(ButtonByRow('showDeleteButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n\r\n <!-- Edit Button Column -->\r\n @if(ButtonByRow('showEditButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n\r\n <!-- Edit Button Column -->\r\n @if(ButtonByRow('showGoButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- body -->\r\n @for(group of gridDataSource(); track group.indexGroup) {\r\n <tbody>\r\n <!--<tr v-if=\"_isGrouped\">\r\n <td :colspan=\"_colspan\" class=\"group\">\r\n <MesAccordion\r\n :ref=\"`accordion${group.indexGroup}-${id}`\"\r\n :title=\"`${_CleanHeaderName(groupBy)} (${group.length}): ${group.groupBy}`\"\r\n :isLoading=\"_isLoading\"\r\n @expanded=\"_ToogleAccordion(group.groupBy, true, group.indexGroup)\"\r\n @collapsed=\"_ToogleAccordion(group.groupBy, false, group.indexGroup)\"\r\n ></MesAccordion>\r\n </td>\r\n </tr>-->\r\n\r\n @for(row of group.rows; track row.indexRow) {\r\n <tr [id]=\"_GetId(row.indexRow, 0, 'row')\"\r\n [ngClass]=\"{ 'loading': isLoading(), 'd-none': _HideRow(group), 'row-focus': (row.indexRow == _indexFocus() && enableRowFocus()) }\"\r\n (click)=\"_indexFocus.set(row.indexRow)\">\r\n\r\n @if(checkbox.show) {\r\n <!-- CheckBox Column -->\r\n <td class=\"check-box\">\r\n <div [ngClass]=\"{ 'invisible': _isLoadingMessage }\">\r\n <coer-checkbox\r\n [id]=\"_GetId(row.indexRow, 0, 'checkbox')\"\r\n [ignoreModel]=\"true\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n (onChange)=\"ClickCheck(_GetId(row.indexRow, 0, 'checkbox'), $event, false, row)\"\r\n ></coer-checkbox>\r\n </div>\r\n\r\n <div [ngClass]=\"{ 'invisible': !_isLoadingMessage }\">\r\n <i class=\"spinner-border\"></i>\r\n </div>\r\n </td>\r\n }\r\n\r\n <!-- Dynamic Column -->\r\n @for(header of gridColumns(); track header.indexColumn) {\r\n @if(_IsCellType(header.columnName, row, 'template')) {\r\n <td class=\"template\"\r\n (click)=\"_isDisabled() ? null : onClickRow.emit(row)\"\r\n (dblclick)=\"_isDisabled() ? null : onDoubleClickRow.emit(row)\">\r\n <div [innerHTML]=\"GetAttribute(header.columnName, row, 'template', 'defaul-cell') | html\" class=\"template\"></div>\r\n </td>\r\n }\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerTextbox')) {\r\n <!-- coer-textbox -->\r\n <td class=\"coer-textbox\">\r\n <coer-textbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerTextbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerTextbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerTextbox') || false\"\r\n [selectOnFocus]=\"GetAttribute(header.columnName, row, 'selectOnFocus', 'coerTextbox') || true\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerTextbox') || ('Type ' + header.columnName + '...')\"\r\n [textPosition]=\"GetAttribute(header.columnName, row, 'textPosition', 'coerTextbox') || 'left'\"\r\n [minLength]=\"GetAttribute(header.columnName, row, 'minLength', 'coerTextbox') || 0\"\r\n [maxLength]=\"GetAttribute(header.columnName, row, 'maxLength', 'coerTextbox') || 50\"\r\n (onInput)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-textbox')\"\r\n (onKeyupEnter)=\"KeyupEnter(header.indexColumn, row, 'coer-textbox', $event)\"\r\n ></coer-textbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerNumberbox')) {\r\n <!-- coer-numberbox -->\r\n <td class=\"coer-numberbox\">\r\n <coer-numberbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerNumberbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerNumberbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerNumberbox') || false\"\r\n [selectOnFocus]=\"GetAttribute(header.columnName, row, 'selectOnFocus', 'coerNumberbox') || true\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerNumberbox') || ''\"\r\n [textPosition]=\"GetAttribute(header.columnName, row, 'textPosition', 'coerNumberbox') || 'right'\"\r\n [min]=\"GetAttribute(header.columnName, row, 'min', 'coerNumberbox') || 0\"\r\n [max]=\"GetAttribute(header.columnName, row, 'max', 'coerNumberbox') || 2147483647\"\r\n [decimals]=\"GetAttribute(header.columnName, row, 'decimals', 'coerNumberbox') || 0\"\r\n (onInput)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-numberbox')\"\r\n (onKeyupEnter)=\"KeyupEnter(header.indexColumn, row, 'coer-numberbox', $event)\"\r\n ></coer-numberbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerSelectbox')) {\r\n <!-- coer-numberbox -->\r\n <td class=\"coer-selectbox\">\r\n <coer-selectbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerSelectbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerSelectbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerSelectbox') || false\"\r\n [dataSource]=\"GetAttribute(header.columnName, row, 'dataSource', 'coerSelectbox') || []\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerSelectbox') || '-- Select --'\"\r\n [propDisplay]=\"GetAttribute(header.columnName, row, 'propDisplay', 'coerSelectbox') || 'name'\"\r\n (onSelected)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-selectbox'); KeyupEnter(header.indexColumn, row, 'coer-selectbox', $event)\"\r\n ></coer-selectbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerSwitch')) {\r\n <!-- coer-switch -->\r\n <td>\r\n <coer-switch\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerSwitch') || _isDisabled() || _isLoading\"\r\n [tooltip]=\"GetAttribute(header.columnName, row, 'tooltip', 'coerSwitch')\"\r\n [tooltipPosition]=\"GetAttribute(header.columnName, row, 'tooltipPosition', 'coerSwitch') || 'left'\"\r\n [isInvisible]=\"_isDisabled()\"\r\n (onChange)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-switch')\"\r\n ></coer-switch>\r\n </td>\r\n }\r\n\r\n @else {\r\n <!-- Default Cell -->\r\n <td class=\"default-cell\"\r\n (click)=\"ClickOnRow(row)\"\r\n (dblclick)=\"_isDisabled() ? null : onDoubleClickRow.emit(row)\"\r\n [ngStyle]=\"{\r\n 'text-align': GetAttribute(header.columnName, row, 'textAlign', 'defaul-cell'),\r\n 'white-space': 'normal'\r\n }\">\r\n\r\n <div [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [ngClass]=\"{\r\n 'text-blue-bold': _IsCellColor(header.columnName, row, 'colorBlue'),\r\n 'text-green-bold': _IsCellColor(header.columnName, row, 'colorGreen'),\r\n 'text-yellow-bold': _IsCellColor(header.columnName, row, 'colorYellow'),\r\n 'text-red-bold': _IsCellColor(header.columnName, row, 'colorRed'),\r\n 'text-right-bold': _IsCellType(header.columnName, row, 'number')\r\n }\">\r\n\r\n @if(_IsCellType(header.columnName, row, 'number')) {\r\n <span> {{ GetNumericFormat(row[header.columnName]) }} </span>\r\n }\r\n\r\n @else if(_IsCellType(header.columnName, row, 'date')) {\r\n <span> {{ GetDateFormat(row[header.columnName]) }} </span>\r\n }\r\n\r\n @else {\r\n <span> {{ _GetCellValue(row, header.columnName) }} </span>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if(ButtonByRow('showDeleteButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showDeleteButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"delete\"\r\n [tooltip]=\"_GetTooltip('Delete', row)\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickDeleteRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if(ButtonByRow('showEditButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showEditButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"edit\"\r\n [tooltip]=\"_GetTooltip('Edit', row)\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickEditRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n\r\n <!-- GO Button -->\r\n @if(ButtonByRow('showGoButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showGoButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"go\"\r\n [tooltip]=\"_GetTooltip('Go to', row, 'detail')\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickEditRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n }\r\n </table>\r\n </div>\r\n </section>\r\n\r\n @if(showFooter()) {\r\n <footer class=\"grid-footer\">\r\n <span>\r\n @if(_isLoadingMessage) {\r\n <span class=\"fa-fade\"> Loading </span>\r\n }\r\n\r\n @else if(gridLength().dataSourceSelected > 0) {\r\n <span>\r\n <i class=\"bi bi-check2-square ms-1\"></i>\r\n {{ gridLength().dataSourceSelected }}\r\n </span>\r\n }\r\n </span>\r\n\r\n <span class=\"me-1\"> {{ gridLength().dataSourceFiltered | numericFormat }} Rows </span>\r\n </footer>\r\n }\r\n</div>", styles: ["div.coer-grid *{--blue: #0d6efd;--gray: #6c757d;--green: #198754;--yellow: #ffc107;--red: #dc3545;--white: #f5f5f5;--black: #252525;--orange: #fd6031}div.coer-grid .text-blue{color:#0d6efd!important}div.coer-grid .text-blue-bold{color:#0d6efd!important;font-weight:700!important}div.coer-grid .background-blue{background-color:#0d6efd!important}div.coer-grid .background-border-blue{background-color:#0d6efd!important;border-color:#0d6efd!important}div.coer-grid .border-blue{border-color:#0d6efd!important}div.coer-grid .text-gray{color:#6c757d!important}div.coer-grid .text-gray-bold{color:#6c757d!important;font-weight:700!important}div.coer-grid .background-gray{background-color:#6c757d!important}div.coer-grid .background-border-gray{background-color:#6c757d!important;border-color:#6c757d!important}div.coer-grid .border-gray{border-color:#6c757d!important}div.coer-grid .text-green{color:#198754!important}div.coer-grid .text-green-bold{color:#198754!important;font-weight:700!important}div.coer-grid .background-green{background-color:#198754!important}div.coer-grid .background-border-green{background-color:#198754!important;border-color:#198754!important}div.coer-grid .border-green{border-color:#198754!important}div.coer-grid .text-yellow{color:#ffc107!important}div.coer-grid .text-yellow-bold{color:#ffc107!important;font-weight:700!important}div.coer-grid .background-yellow{background-color:#ffc107!important}div.coer-grid .background-border-yellow{background-color:#ffc107!important;border-color:#ffc107!important}div.coer-grid .border-yellow{border-color:#ffc107!important}div.coer-grid .text-red{color:#dc3545!important}div.coer-grid .text-red-bold{color:#dc3545!important;font-weight:700!important}div.coer-grid .background-red{background-color:#dc3545!important}div.coer-grid .background-border-red{background-color:#dc3545!important;border-color:#dc3545!important}div.coer-grid .border-red{border-color:#dc3545!important}div.coer-grid .text-white{color:#f5f5f5!important}div.coer-grid .text-white-bold{color:#f5f5f5!important;font-weight:700!important}div.coer-grid .background-white{background-color:#f5f5f5!important}div.coer-grid .background-border-white{background-color:#f5f5f5!important;border-color:#f5f5f5!important}div.coer-grid .border-white{border-color:#f5f5f5!important}div.coer-grid .text-black{color:#252525!important}div.coer-grid .text-black-bold{color:#252525!important;font-weight:700!important}div.coer-grid .background-black{background-color:#252525!important}div.coer-grid .background-border-black{background-color:#252525!important;border-color:#252525!important}div.coer-grid .border-black{border-color:#252525!important}div.coer-grid .text-orange{color:#fd6031!important}div.coer-grid .text-orange-bold{color:#fd6031!important;font-weight:700!important}div.coer-grid .background-orange{background-color:#fd6031!important}div.coer-grid .background-border-orange{background-color:#fd6031!important;border-color:#fd6031!important}div.coer-grid .border-orange{border-color:#fd6031!important}div.coer-grid header{align-items:flex-end;justify-content:flex-end;padding-right:8px;margin:0}div.coer-grid header>div{padding:0 0 10px 10px;display:flex;align-items:baseline}div.coer-grid header>div a{height:40px!important}div.coer-grid table{table-layout:auto;border-collapse:separate;border-spacing:1px 0px;margin:0;font-size:14px}div.coer-grid table thead tr th{position:sticky!important;z-index:100!important;top:0!important;background-color:#6c757d!important;color:#f5f5f5!important;padding:5px!important;vertical-align:middle!important;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;min-width:50px!important;white-space:nowrap!important}div.coer-grid table tbody{border:0px!important}div.coer-grid table tbody tr:not(.row-focus):hover td{color:#000!important;background-color:#f1f6ff!important}div.coer-grid table tbody tr td{border:0px!important;padding:5px!important;vertical-align:middle!important;white-space:break-spaces;text-overflow:ellipsis;overflow:hidden}div.coer-grid table tbody tr.row-focus td{background-color:#cde1ff}div.coer-grid table tbody tr td.coer-textbox,div.coer-grid table tbody tr td.coer-numberbox,div.coer-grid table tbody tr td.coer-selectbox{padding:0!important;overflow:visible!important}div.coer-grid table tbody tr td.default-cell{cursor:pointer!important}div.coer-grid table tbody tr td.template{display:block!important;white-space:nowrap!important;cursor:pointer!important;height:31px}div.coer-grid table tbody tr td.template>div.template{display:block!important}div.coer-grid table thead tr th.action-button,div.coer-grid table thead tr td.action-button,div.coer-grid table thead tr th.check-box,div.coer-grid table thead tr td.check-box,div.coer-grid table tbody tr th.action-button,div.coer-grid table tbody tr td.action-button,div.coer-grid table tbody tr th.check-box table tbody tr td.check-box{text-align:center!important;cursor:default!important;min-width:40px!important;max-width:40px!important;width:40px!important;padding:0!important}div.coer-grid footer.grid-footer{display:flex;align-items:center;justify-content:space-between;font-size:small;color:#999;padding-top:5px}div.coer-grid section.grid-container{position:relative;overflow:auto}div.coer-grid div.loading,div.coer-grid div.no-data{position:absolute;display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:25px;color:gray}div.coer-grid div.loading{background-color:#bbbbbb83!important;flex-direction:column!important;gap:10px!important}div.coer-grid div.loading span.fa-fade{position:relative!important;top:50px!important}div.coer-grid tr.loading{background-color:#bbbbbb83!important}div.coer-grid div.loading i.spinner-border{color:#fd6031!important;width:70px!important;height:70px!important;font-size:20px!important;position:absolute!important}div.coer-grid td.check-box i.spinner-border{width:15px!important;height:15px!important;color:#fd6031!important}div.coer-grid table thead tr th.check-box>div,div.coer-grid table tbody tr td.check-box>div{display:flex;align-items:center;justify-content:center;cursor:default!important}div.coer-grid input.form-check-input{box-shadow:none!important;margin:0}div.coer-grid input[type=checkbox]{cursor:pointer!important}div.coer-grid td.group{padding:0!important;margin:0!important}div.coer-grid td.group>*{border-top:1px solid #6c757d!important;border-bottom:1px solid #6c757d!important;padding:0!important;margin:0!important}div.coer-grid .template,div.coer-grid .template div{white-space:nowrap!important;display:flex!important;align-items:center!important;gap:5px!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.CoerButton, selector: "coer-button", inputs: ["id", "color", "type", "icon", "iconPosition", "animation", "isLoading", "isDisabled", "isInvisible", "width", "minWidth", "height", "minHeight", "marginTop", "marginRight", "marginBottom", "marginLeft", "path", "tooltipPosition", "tooltip"], outputs: ["onClick"] }, { kind: "component", type: i4.CoerCheckbox, selector: "coer-checkbox", inputs: ["value", "id", "label", "labelPosition", "isDisabled", "isLoading", "isInvisible", "ignoreModel"], outputs: ["onChange"] }, { kind: "component", type: i5.CoerNumberBox, selector: "coer-numberbox", inputs: ["value", "id", "label", "placeholder", "min", "max", "decimals", "width", "minWidth", "maxWidth", "marginTop", "marginRight", "marginBottom", "marginLeft", "isInvalid", "isValid", "isDisabled", "isReadonly", "isLoading", "selectOnFocus", "textPosition"], outputs: ["onKeyupEnter", "onInput"] }, { kind: "component", type: i6.CoerSelectbox, selector: "coer-selectbox", inputs: ["value", "id", "label", "dataSource", "propDisplay", "rowsByPage", "placeholder", "width", "minWidth", "maxWidth", "marginTop", "marginRight", "marginBottom", "marginLeft", "isInvalid", "isValid", "isDisabled", "isReadonly", "isLoading"], outputs: ["onSelected"] }, { kind: "component", type: i7.CoerSwitch, selector: "coer-switch", inputs: ["value", "id", "label", "labelPosition", "isDisabled", "isLoading", "isInvisible", "tooltipPosition", "tooltip"], outputs: ["onChange"] }, { kind: "component", type: i8.CoerTextBox, selector: "coer-textbox", inputs: ["value", "id", "label", "placeholder", "minLength", "maxLength", "showSearchIcon", "showClearIcon", "width", "minWidth", "maxWidth", "marginTop", "marginRight", "marginBottom", "marginLeft", "isInvalid", "isValid", "isDisabled", "isReadonly", "isLoading", "selectOnFocus", "textPosition"], outputs: ["onKeyupEnter", "onInput", "onClickClear"] }, { kind: "pipe", type: i9.HtmlPipe, name: "html" }, { kind: "pipe", type: i10.NumericFormatPipe, name: "numericFormat" }] }); }
510
- }
511
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CoerGrid, decorators: [{
512
- type: Component,
513
- args: [{ selector: 'coer-grid', providers: [CONTROL_VALUE(CoerGrid)], template: "<div class=\"coer-grid\" [ngStyle]=\"{ 'width': width(), 'min-Width': MinWidth(), 'max-Width': MaxWidth(), 'margin': margin() }\">\r\n <header [id]=\"_id + '-header'\" class=\"row\">\r\n <!-- Slot -->\r\n <ng-content></ng-content>\r\n\r\n <!-- Export Button -->\r\n @if(exportButton.show && gridLength().dataSource > 0) {\r\n <div class=\"col-auto\">\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"excel\"\r\n [tooltip]=\"_isLoading ? 'Loading' : (exportButton.tooltip || 'Export')\"\r\n [path]=\"(exportButton && exportButton.path) ? exportButton.path : []\"\r\n [isDisabled]=\"_isDisabled() || _isLoading || (exportButton.isDisabled || false)\"\r\n [isLoading]=\"_isLoading\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"Export(!exportButton.preventDefault)\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Import Button -->\r\n @if(importButton.show) {\r\n <div class=\"col-auto\">\r\n <input type=\"file\" #inputFileRef [multiple]=\"false\" (change)=\"Import($event)\">\r\n\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"import\"\r\n [tooltip]=\"importButton.tooltip || 'Import'\"\r\n [path]=\"(importButton && importButton.path) ? importButton.path : []\"\r\n [isDisabled]=\"importButton.isDisabled || false\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"Import()\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Add Button -->\r\n @if(addButton.show) {\r\n <div class=\"col-auto\">\r\n <coer-button\r\n type=\"icon\"\r\n color=\"navigation\"\r\n icon=\"new\"\r\n [tooltip]=\"addButton.tooltip || 'New'\"\r\n [path]=\"(addButton && addButton.path) ? addButton.path : []\"\r\n [isDisabled]=\"addButton.isDisabled || false\"\r\n [animation]=\"_enableAnimations\"\r\n (onClick)=\"onClickAdd.emit()\"\r\n ></coer-button>\r\n </div>\r\n }\r\n\r\n <!-- Search -->\r\n @if(search.show) {\r\n <div class=\"col-auto\">\r\n <coer-textbox\r\n #inputSearch\r\n [id]=\"_GetId(-1, -1, 'search')\"\r\n [ngModel]=\"_gridSearch()\"\r\n placeholder=\"Search\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n [selectOnFocus]=\"true\"\r\n width=\"250px\"\r\n [showSearchIcon]=\"true\"\r\n [showClearIcon]=\"true\"\r\n (onInput)=\"InputChange(-1, 'Search', $event, 'coer-textbox-search')\"\r\n (onClickClear)=\"InputChange(-1, 'Search', '', 'coer-textbox-search')\"\r\n (onKeyupEnter)=\"KeyupEnter(-1, { indexRow: -1 }, 'coer-textbox-search', $event);\"\r\n ></coer-textbox>\r\n </div>\r\n }\r\n </header>\r\n\r\n <section [ngClass]=\"{ 'grid-container': true, 'invisible': isInvisible() }\">\r\n <div [ngStyle]=\"{ 'height': _height, 'min-height': minHeight(), 'max-height': maxHeight() }\">\r\n @if(isLoading()) {\r\n <!-- Grid Message -->\r\n <div class=\"loading\">\r\n <i class=\"spinner-border\"></i>\r\n <span class=\"fa-fade\">Loading</span>\r\n </div>\r\n }\r\n\r\n @else if(!_isDisabled() && gridLength().dataSource <= 0) {\r\n <div class=\"no-data\"> No Data </div>\r\n }\r\n\r\n <table class=\"table table-sm table-responsive table-striped\">\r\n <thead>\r\n <tr>\r\n @if(checkbox.show && gridLength().dataSource > 0) {\r\n <!-- CheckBox Column -->\r\n <th scope=\"col\" class=\"check-box\">\r\n <div *ngIf=\"!_onlyOneCheck\" [ngClass]=\"{ 'invisible': _isLoadingMessage }\">\r\n <coer-checkbox\r\n [id]=\"_GetId(0, 0, 'checkboxAll')\"\r\n [ignoreModel]=\"true\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n (onChange)=\"ClickCheck(_GetId(0, 0, 'checkboxAll'), $event, true)\"\r\n ></coer-checkbox>\r\n </div>\r\n </th>\r\n }\r\n\r\n <!-- Dynamic Grid Column -->\r\n @for(header of gridColumns(); track header.indexColumn) {\r\n <th scope=\"col\" (dblclick)=\"Sort(header.columnName)\"\r\n [ngClass]=\"{\r\n 'no-selection': true,\r\n 'cursor-default': !enableSort() && !_isLoading,\r\n 'cursor-pointer': enableSort() && !_isLoading,\r\n 'cursor-wait': _isLoading\r\n }\"\r\n [ngStyle]=\"{\r\n 'width': header.width,\r\n 'text-align': GetAttribute(header.columnName, null, 'textAlign', 'defaul-cell')\r\n }\">\r\n <div class=\"no-selection\">\r\n {{ _GetColumnName(header.columnName) }}\r\n <i [class]=\"_GetShortIcon(header.columnName)\"></i>\r\n </div>\r\n </th>\r\n }\r\n\r\n <!-- Delete Button Column -->\r\n @if(ButtonByRow('showDeleteButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n\r\n <!-- Edit Button Column -->\r\n @if(ButtonByRow('showEditButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n\r\n <!-- Edit Button Column -->\r\n @if(ButtonByRow('showGoButton')) {\r\n <th scope=\"col\" class=\"action-button\"></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- body -->\r\n @for(group of gridDataSource(); track group.indexGroup) {\r\n <tbody>\r\n <!--<tr v-if=\"_isGrouped\">\r\n <td :colspan=\"_colspan\" class=\"group\">\r\n <MesAccordion\r\n :ref=\"`accordion${group.indexGroup}-${id}`\"\r\n :title=\"`${_CleanHeaderName(groupBy)} (${group.length}): ${group.groupBy}`\"\r\n :isLoading=\"_isLoading\"\r\n @expanded=\"_ToogleAccordion(group.groupBy, true, group.indexGroup)\"\r\n @collapsed=\"_ToogleAccordion(group.groupBy, false, group.indexGroup)\"\r\n ></MesAccordion>\r\n </td>\r\n </tr>-->\r\n\r\n @for(row of group.rows; track row.indexRow) {\r\n <tr [id]=\"_GetId(row.indexRow, 0, 'row')\"\r\n [ngClass]=\"{ 'loading': isLoading(), 'd-none': _HideRow(group), 'row-focus': (row.indexRow == _indexFocus() && enableRowFocus()) }\"\r\n (click)=\"_indexFocus.set(row.indexRow)\">\r\n\r\n @if(checkbox.show) {\r\n <!-- CheckBox Column -->\r\n <td class=\"check-box\">\r\n <div [ngClass]=\"{ 'invisible': _isLoadingMessage }\">\r\n <coer-checkbox\r\n [id]=\"_GetId(row.indexRow, 0, 'checkbox')\"\r\n [ignoreModel]=\"true\"\r\n [isDisabled]=\"_isDisabled() || _isLoading\"\r\n (onChange)=\"ClickCheck(_GetId(row.indexRow, 0, 'checkbox'), $event, false, row)\"\r\n ></coer-checkbox>\r\n </div>\r\n\r\n <div [ngClass]=\"{ 'invisible': !_isLoadingMessage }\">\r\n <i class=\"spinner-border\"></i>\r\n </div>\r\n </td>\r\n }\r\n\r\n <!-- Dynamic Column -->\r\n @for(header of gridColumns(); track header.indexColumn) {\r\n @if(_IsCellType(header.columnName, row, 'template')) {\r\n <td class=\"template\"\r\n (click)=\"_isDisabled() ? null : onClickRow.emit(row)\"\r\n (dblclick)=\"_isDisabled() ? null : onDoubleClickRow.emit(row)\">\r\n <div [innerHTML]=\"GetAttribute(header.columnName, row, 'template', 'defaul-cell') | html\" class=\"template\"></div>\r\n </td>\r\n }\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerTextbox')) {\r\n <!-- coer-textbox -->\r\n <td class=\"coer-textbox\">\r\n <coer-textbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerTextbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerTextbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerTextbox') || false\"\r\n [selectOnFocus]=\"GetAttribute(header.columnName, row, 'selectOnFocus', 'coerTextbox') || true\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerTextbox') || ('Type ' + header.columnName + '...')\"\r\n [textPosition]=\"GetAttribute(header.columnName, row, 'textPosition', 'coerTextbox') || 'left'\"\r\n [minLength]=\"GetAttribute(header.columnName, row, 'minLength', 'coerTextbox') || 0\"\r\n [maxLength]=\"GetAttribute(header.columnName, row, 'maxLength', 'coerTextbox') || 50\"\r\n (onInput)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-textbox')\"\r\n (onKeyupEnter)=\"KeyupEnter(header.indexColumn, row, 'coer-textbox', $event)\"\r\n ></coer-textbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerNumberbox')) {\r\n <!-- coer-numberbox -->\r\n <td class=\"coer-numberbox\">\r\n <coer-numberbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerNumberbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerNumberbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerNumberbox') || false\"\r\n [selectOnFocus]=\"GetAttribute(header.columnName, row, 'selectOnFocus', 'coerNumberbox') || true\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerNumberbox') || ''\"\r\n [textPosition]=\"GetAttribute(header.columnName, row, 'textPosition', 'coerNumberbox') || 'right'\"\r\n [min]=\"GetAttribute(header.columnName, row, 'min', 'coerNumberbox') || 0\"\r\n [max]=\"GetAttribute(header.columnName, row, 'max', 'coerNumberbox') || 2147483647\"\r\n [decimals]=\"GetAttribute(header.columnName, row, 'decimals', 'coerNumberbox') || 0\"\r\n (onInput)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-numberbox')\"\r\n (onKeyupEnter)=\"KeyupEnter(header.indexColumn, row, 'coer-numberbox', $event)\"\r\n ></coer-numberbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerSelectbox')) {\r\n <!-- coer-numberbox -->\r\n <td class=\"coer-selectbox\">\r\n <coer-selectbox\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerSelectbox') || _isDisabled() || _isLoading\"\r\n [isValid]=\"GetAttribute(header.columnName, row, 'isValid', 'coerSelectbox') || false\"\r\n [isInvalid]=\"GetAttribute(header.columnName, row, 'isInvalid', 'coerSelectbox') || false\"\r\n [dataSource]=\"GetAttribute(header.columnName, row, 'dataSource', 'coerSelectbox') || []\"\r\n [placeholder]=\"GetAttribute(header.columnName, row, 'placeholder', 'coerSelectbox') || '-- Select --'\"\r\n [propDisplay]=\"GetAttribute(header.columnName, row, 'propDisplay', 'coerSelectbox') || 'name'\"\r\n (onSelected)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-selectbox'); KeyupEnter(header.indexColumn, row, 'coer-selectbox', $event)\"\r\n ></coer-selectbox>\r\n </td>\r\n }\r\n\r\n\r\n @else if(_IsCellType(header.columnName, row, 'coerSwitch')) {\r\n <!-- coer-switch -->\r\n <td>\r\n <coer-switch\r\n [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [(ngModel)]=\"row[header.columnName]\"\r\n [isDisabled]=\"GetAttribute(header.columnName, row, 'isDisabled', 'coerSwitch') || _isDisabled() || _isLoading\"\r\n [tooltip]=\"GetAttribute(header.columnName, row, 'tooltip', 'coerSwitch')\"\r\n [tooltipPosition]=\"GetAttribute(header.columnName, row, 'tooltipPosition', 'coerSwitch') || 'left'\"\r\n [isInvisible]=\"_isDisabled()\"\r\n (onChange)=\"InputChange(row.indexRow, header.columnName, $event, 'coer-switch')\"\r\n ></coer-switch>\r\n </td>\r\n }\r\n\r\n @else {\r\n <!-- Default Cell -->\r\n <td class=\"default-cell\"\r\n (click)=\"ClickOnRow(row)\"\r\n (dblclick)=\"_isDisabled() ? null : onDoubleClickRow.emit(row)\"\r\n [ngStyle]=\"{\r\n 'text-align': GetAttribute(header.columnName, row, 'textAlign', 'defaul-cell'),\r\n 'white-space': 'normal'\r\n }\">\r\n\r\n <div [id]=\"_GetId(row.indexRow, header.indexColumn)\"\r\n [ngClass]=\"{\r\n 'text-blue-bold': _IsCellColor(header.columnName, row, 'colorBlue'),\r\n 'text-green-bold': _IsCellColor(header.columnName, row, 'colorGreen'),\r\n 'text-yellow-bold': _IsCellColor(header.columnName, row, 'colorYellow'),\r\n 'text-red-bold': _IsCellColor(header.columnName, row, 'colorRed'),\r\n 'text-right-bold': _IsCellType(header.columnName, row, 'number')\r\n }\">\r\n\r\n @if(_IsCellType(header.columnName, row, 'number')) {\r\n <span> {{ GetNumericFormat(row[header.columnName]) }} </span>\r\n }\r\n\r\n @else if(_IsCellType(header.columnName, row, 'date')) {\r\n <span> {{ GetDateFormat(row[header.columnName]) }} </span>\r\n }\r\n\r\n @else {\r\n <span> {{ _GetCellValue(row, header.columnName) }} </span>\r\n }\r\n </div>\r\n </td>\r\n }\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if(ButtonByRow('showDeleteButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showDeleteButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"delete\"\r\n [tooltip]=\"_GetTooltip('Delete', row)\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickDeleteRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if(ButtonByRow('showEditButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showEditButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"edit\"\r\n [tooltip]=\"_GetTooltip('Edit', row)\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickEditRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n\r\n <!-- GO Button -->\r\n @if(ButtonByRow('showGoButton')) {\r\n <td class=\"action-button\">\r\n @if(ButtonByRow('showGoButton', row)) {\r\n <coer-button\r\n type=\"icon-no-border\"\r\n color=\"navigation\"\r\n icon=\"go\"\r\n [tooltip]=\"_GetTooltip('Go to', row, 'detail')\"\r\n [isInvisible]=\"_isDisabled()\"\r\n [isDisabled]=\"_isLoading\"\r\n (onClick)=\"onClickEditRow.emit(row)\"\r\n ></coer-button>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n }\r\n </table>\r\n </div>\r\n </section>\r\n\r\n @if(showFooter()) {\r\n <footer class=\"grid-footer\">\r\n <span>\r\n @if(_isLoadingMessage) {\r\n <span class=\"fa-fade\"> Loading </span>\r\n }\r\n\r\n @else if(gridLength().dataSourceSelected > 0) {\r\n <span>\r\n <i class=\"bi bi-check2-square ms-1\"></i>\r\n {{ gridLength().dataSourceSelected }}\r\n </span>\r\n }\r\n </span>\r\n\r\n <span class=\"me-1\"> {{ gridLength().dataSourceFiltered | numericFormat }} Rows </span>\r\n </footer>\r\n }\r\n</div>", styles: ["div.coer-grid *{--blue: #0d6efd;--gray: #6c757d;--green: #198754;--yellow: #ffc107;--red: #dc3545;--white: #f5f5f5;--black: #252525;--orange: #fd6031}div.coer-grid .text-blue{color:#0d6efd!important}div.coer-grid .text-blue-bold{color:#0d6efd!important;font-weight:700!important}div.coer-grid .background-blue{background-color:#0d6efd!important}div.coer-grid .background-border-blue{background-color:#0d6efd!important;border-color:#0d6efd!important}div.coer-grid .border-blue{border-color:#0d6efd!important}div.coer-grid .text-gray{color:#6c757d!important}div.coer-grid .text-gray-bold{color:#6c757d!important;font-weight:700!important}div.coer-grid .background-gray{background-color:#6c757d!important}div.coer-grid .background-border-gray{background-color:#6c757d!important;border-color:#6c757d!important}div.coer-grid .border-gray{border-color:#6c757d!important}div.coer-grid .text-green{color:#198754!important}div.coer-grid .text-green-bold{color:#198754!important;font-weight:700!important}div.coer-grid .background-green{background-color:#198754!important}div.coer-grid .background-border-green{background-color:#198754!important;border-color:#198754!important}div.coer-grid .border-green{border-color:#198754!important}div.coer-grid .text-yellow{color:#ffc107!important}div.coer-grid .text-yellow-bold{color:#ffc107!important;font-weight:700!important}div.coer-grid .background-yellow{background-color:#ffc107!important}div.coer-grid .background-border-yellow{background-color:#ffc107!important;border-color:#ffc107!important}div.coer-grid .border-yellow{border-color:#ffc107!important}div.coer-grid .text-red{color:#dc3545!important}div.coer-grid .text-red-bold{color:#dc3545!important;font-weight:700!important}div.coer-grid .background-red{background-color:#dc3545!important}div.coer-grid .background-border-red{background-color:#dc3545!important;border-color:#dc3545!important}div.coer-grid .border-red{border-color:#dc3545!important}div.coer-grid .text-white{color:#f5f5f5!important}div.coer-grid .text-white-bold{color:#f5f5f5!important;font-weight:700!important}div.coer-grid .background-white{background-color:#f5f5f5!important}div.coer-grid .background-border-white{background-color:#f5f5f5!important;border-color:#f5f5f5!important}div.coer-grid .border-white{border-color:#f5f5f5!important}div.coer-grid .text-black{color:#252525!important}div.coer-grid .text-black-bold{color:#252525!important;font-weight:700!important}div.coer-grid .background-black{background-color:#252525!important}div.coer-grid .background-border-black{background-color:#252525!important;border-color:#252525!important}div.coer-grid .border-black{border-color:#252525!important}div.coer-grid .text-orange{color:#fd6031!important}div.coer-grid .text-orange-bold{color:#fd6031!important;font-weight:700!important}div.coer-grid .background-orange{background-color:#fd6031!important}div.coer-grid .background-border-orange{background-color:#fd6031!important;border-color:#fd6031!important}div.coer-grid .border-orange{border-color:#fd6031!important}div.coer-grid header{align-items:flex-end;justify-content:flex-end;padding-right:8px;margin:0}div.coer-grid header>div{padding:0 0 10px 10px;display:flex;align-items:baseline}div.coer-grid header>div a{height:40px!important}div.coer-grid table{table-layout:auto;border-collapse:separate;border-spacing:1px 0px;margin:0;font-size:14px}div.coer-grid table thead tr th{position:sticky!important;z-index:100!important;top:0!important;background-color:#6c757d!important;color:#f5f5f5!important;padding:5px!important;vertical-align:middle!important;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;min-width:50px!important;white-space:nowrap!important}div.coer-grid table tbody{border:0px!important}div.coer-grid table tbody tr:not(.row-focus):hover td{color:#000!important;background-color:#f1f6ff!important}div.coer-grid table tbody tr td{border:0px!important;padding:5px!important;vertical-align:middle!important;white-space:break-spaces;text-overflow:ellipsis;overflow:hidden}div.coer-grid table tbody tr.row-focus td{background-color:#cde1ff}div.coer-grid table tbody tr td.coer-textbox,div.coer-grid table tbody tr td.coer-numberbox,div.coer-grid table tbody tr td.coer-selectbox{padding:0!important;overflow:visible!important}div.coer-grid table tbody tr td.default-cell{cursor:pointer!important}div.coer-grid table tbody tr td.template{display:block!important;white-space:nowrap!important;cursor:pointer!important;height:31px}div.coer-grid table tbody tr td.template>div.template{display:block!important}div.coer-grid table thead tr th.action-button,div.coer-grid table thead tr td.action-button,div.coer-grid table thead tr th.check-box,div.coer-grid table thead tr td.check-box,div.coer-grid table tbody tr th.action-button,div.coer-grid table tbody tr td.action-button,div.coer-grid table tbody tr th.check-box table tbody tr td.check-box{text-align:center!important;cursor:default!important;min-width:40px!important;max-width:40px!important;width:40px!important;padding:0!important}div.coer-grid footer.grid-footer{display:flex;align-items:center;justify-content:space-between;font-size:small;color:#999;padding-top:5px}div.coer-grid section.grid-container{position:relative;overflow:auto}div.coer-grid div.loading,div.coer-grid div.no-data{position:absolute;display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:25px;color:gray}div.coer-grid div.loading{background-color:#bbbbbb83!important;flex-direction:column!important;gap:10px!important}div.coer-grid div.loading span.fa-fade{position:relative!important;top:50px!important}div.coer-grid tr.loading{background-color:#bbbbbb83!important}div.coer-grid div.loading i.spinner-border{color:#fd6031!important;width:70px!important;height:70px!important;font-size:20px!important;position:absolute!important}div.coer-grid td.check-box i.spinner-border{width:15px!important;height:15px!important;color:#fd6031!important}div.coer-grid table thead tr th.check-box>div,div.coer-grid table tbody tr td.check-box>div{display:flex;align-items:center;justify-content:center;cursor:default!important}div.coer-grid input.form-check-input{box-shadow:none!important;margin:0}div.coer-grid input[type=checkbox]{cursor:pointer!important}div.coer-grid td.group{padding:0!important;margin:0!important}div.coer-grid td.group>*{border-top:1px solid #6c757d!important;border-bottom:1px solid #6c757d!important;padding:0!important;margin:0!important}div.coer-grid .template,div.coer-grid .template div{white-space:nowrap!important;display:flex!important;align-items:center!important;gap:5px!important}\n"] }]
514
- }] });
515
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29lci1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvZXItZWxlbWVudHMvc3JjL2NvbXBvbmVudHMvbGliL2NvZXItZ3JpZC9jb2VyLWdyaWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29lci1lbGVtZW50cy9zcmMvY29tcG9uZW50cy9saWIvY29lci1ncmlkL2NvZXItZ3JpZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQU0xRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDdkUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7O0FBU2pELE1BQU0sT0FBTyxRQUFZLFNBQVEsaUJBQW9CO0lBTnJEOztRQVFJLFVBQVU7UUFDSCxlQUFVLEdBQUcsUUFBUSxDQUFNLEdBQUcsRUFBRTtZQUNuQyxPQUFPLEtBQUssQ0FBQyxjQUFjLENBQVEsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMvRCxJQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDO29CQUFFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDdkQsSUFBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztvQkFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ3pELE9BQU8sSUFBSSxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENB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LENBQUMsQ0FBQztRQUNyRCxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFHRCxrQ0FBa0M7SUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUE2QjtRQUNuRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFeEgsSUFBSSxVQUFVLEdBQVUsRUFBRSxDQUFDO1FBQzNCLEtBQUksTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDOUIsVUFBVSxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUIsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsQ0FBQztJQUNMLENBQUM7K0dBbG1CUSxRQUFRO21HQUFSLFFBQVEsb0NBRk4sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsaURDaEJ4QywwNHZCQTRYTTs7NEZEMVdPLFFBQVE7a0JBTnBCLFNBQVM7K0JBQ0ksV0FBVyxhQUdWLENBQUMsYUFBYSxVQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvZXJHcmlkRXh0ZW5zaW9uIH0gZnJvbSAnLi9jb2VyLWdyaWQuZXh0ZW5zaW9uJztcclxuaW1wb3J0IHsgSUdyaWRMZW5ndGgsIElHcmlkSW5wdXRDaGVja2JveCB9IGZyb20gJy4uLy4uLy4uL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQgeyBDb2VyQ2hlY2tib3ggfSBmcm9tICcuLi8uLi9saWIvY29lci1jaGVja2JveC9jb2VyLWNoZWNrYm94LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvZXJUZXh0Qm94IH0gZnJvbSAnLi4vLi4vbGliL2NvZXItdGV4dGJveC9jb2VyLXRleHRib3guY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29lck51bWJlckJveCB9IGZyb20gJy4uLy4uL2xpYi9jb2VyLW51bWJlcmJveC9jb2VyLW51bWJlcmJveC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb2VyU2VsZWN0Ym94IH0gZnJvbSAnLi4vLi4vbGliL2NvZXItc2VsZWN0Ym94L2NvZXItc2VsZWN0Ym94LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENPTlRST0xfVkFMVUUgfSBmcm9tICcuLi8uLi8uLi90b29scy9saWIvY29udHJvbC12YWx1ZS5jbGFzcyc7XHJcbmltcG9ydCB7IEZpbGVzIH0gZnJvbSAnLi4vLi4vLi4vdG9vbHMvbGliL2ZpbGVzLmNsYXNzJztcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tICcuLi8uLi8uLi90b29scy9saWIvdG9vbHMnO1xyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdjb2VyLWdyaWQnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NvZXItZ3JpZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybDogJy4vY29lci1ncmlkLmNvbXBvbmVudC5zY3NzJyxcclxuICAgIHByb3ZpZGVyczogW0NPTlRST0xfVkFMVUUoQ29lckdyaWQpXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIENvZXJHcmlkPFQ+IGV4dGVuZHMgQ29lckdyaWRFeHRlbnNpb248VD4ge1xyXG5cclxuICAgIC8vY29tcHV0ZWRcclxuICAgIHB1YmxpYyBkYXRhU291cmNlID0gY29tcHV0ZWQ8VFtdPigoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueVtdPih0aGlzLnZhbHVlX3NpZ25hbCgpKS5tYXAoaXRlbSA9PiB7XHJcbiAgICAgICAgICAgIGlmKGl0ZW0uaGFzT3duUHJvcGVydHkoJ2NoZWNrZWQnKSkgZGVsZXRlIGl0ZW0uY2hlY2tlZDtcclxuICAgICAgICAgICAgaWYoaXRlbS5oYXNPd25Qcm9wZXJ0eSgnaW5kZXhSb3cnKSkgZGVsZXRlIGl0ZW0uaW5kZXhSb3c7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG5cclxuICAgIC8vY29tcHV0ZWRcclxuICAgIHB1YmxpYyBzZWxlY3RlZEl0ZW1zID0gY29tcHV0ZWQ8VFtdPigoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueVtdPih0aGlzLnZhbHVlX3NpZ25hbCgpKS5maWx0ZXIoaXRlbSA9PiBpdGVtLmNoZWNrZWQpLm1hcChpdGVtID0+IHtcclxuICAgICAgICAgICAgaWYoaXRlbS5oYXNPd25Qcm9wZXJ0eSgnY2hlY2tlZCcpKSBkZWxldGUgaXRlbS5jaGVja2VkO1xyXG4gICAgICAgICAgICBpZihpdGVtLmhhc093blByb3BlcnR5KCdpbmRleFJvdycpKSBkZWxldGUgaXRlbS5pbmRleFJvdztcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcblxyXG4gICAgLy9nZXR0ZXJcclxuICAgIHB1YmxpYyBnZXQgaXNWYWxpZCgpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuY29lclRleHRib3hMaXN0KCkubGVuZ3RoID4gMCA/IHRoaXMuY29lclRleHRib3hMaXN0KCkuZXZlcnkoeCA9PiAheC5pc0ludmFsaWQoKSkgOiB0cnVlKVxyXG4gICAgICAgICAgICAmJiAodGhpcy5jb2VyTnVtYmVyYm94TGlzdCgpLmxlbmd0aCA+IDAgPyB0aGlzLmNvZXJOdW1iZXJib3hMaXN0KCkuZXZlcnkoeCA9PiAheC5pc0ludmFsaWQoKSkgOiB0cnVlKVxyXG4gICAgICAgICAgICAmJiAodGhpcy5jb2VyU2VsZWN0Ym94TGlzdCgpLmxlbmd0aCA+IDAgPyB0aGlzLmNvZXJTZWxlY3Rib3hMaXN0KCkuZXZlcnkoeCA9PiAheC5pc0ludmFsaWQoKSkgOiB0cnVlKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLy9jb21wdXRlZFxyXG4gICAgcHJvdGVjdGVkIGdyaWRMZW5ndGggPSBjb21wdXRlZDxJR3JpZExlbmd0aD4oKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGRhdGFTb3VyY2U6IHRoaXMudmFsdWVfc2lnbmFsKCk/Lmxlbmd0aCB8fCAwLFxyXG4gICAgICAgICAgICBkYXRhU291cmNlRmlsdGVyZWQ6IHRoaXMuZ3JpZERhdGFTb3VyY2VGaWx0ZXJlZCgpPy5sZW5ndGggfHwgMCxcclxuICAgICAgICAgICAgZGF0YVNvdXJjZVNlbGVjdGVkOiB0aGlzLnNlbGVjdGVkSXRlbXMoKT8ubGVuZ3RoIHx8IDBcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcblxyXG5cclxuXHJcbiAgICAvL2NvbXB1dGVkXHJcbiAgICAvL3Byb3RlY3RlZCBfY29sdW1uc0ZpbHRlcmVkID0gY29tcHV0ZWQ8SUdyaWRIZWFkZXJbXT4oKCkgPT4ge1xyXG4gICAgLy8gICAgcmV0dXJuIHRoaXMuaXNHcm91cGVkKCkgJiYgIXRoaXMuc2hvd0NvbHVtbkdyb3VwZWRcclxuICAgIC8vICAgICAgICA/IHRoaXMuX2NvbHVtbnMoKS5maWx0ZXIoeCA9PiB4LmNvbHVtbk5hbWUudG9VcHBlckNhc2UoKSAhPSB0aGlzLmdyb3VwQnkudG9VcHBlckNhc2UoKSlcclxuICAgIC8vICAgICAgICA6IHRoaXMuX2NvbHVtbnMoKTtcclxuICAgIC8vfSk7XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIEZvY3VzU2VhcmNoKCk6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKDApLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBpZih0aGlzLmlucHV0U2VhcmNoKSB0aGlzLmlucHV0U2VhcmNoKCkuRm9jdXMoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgU2VsZWN0U2VhcmNoKCk6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKDApLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBpZih0aGlzLmlucHV0U2VhcmNoKSB0aGlzLmlucHV0U2VhcmNoKCkuU2VsZWN0KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIEdldFJvd0J5PFQ+KGNhbGxiYWNrOiAocm93OiBUKSA9PiBib29sZWFuKTogVCB8IG51bGwge1xyXG4gICAgICAgIGNvbnN0IHJvdyA9IHRoaXMuX3ZhbHVlLmZpbmQoY2FsbGJhY2sgYXMgYW55KTtcclxuICAgICAgICByZXR1cm4gKHJvdyA9PT0gdW5kZWZpbmVkKSA/IG51bGwgOiByb3cgYXMgVDtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgYXN5bmMgSW1wb3J0KGV2ZW50OiBhbnkgPSBudWxsKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaW1wb3J0QnV0dG9uPy5wcmV2ZW50RGVmYXVsdCkge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2tJbXBvcnQuZW1pdCh7IGRhdGE6IFtdLCBmaWxlOiBudWxsIH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZXZlbnQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhpcy5pbnB1dEZpbGUoKS5uYXRpdmVFbGVtZW50LnZhbHVlID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5pbnB1dEZpbGUoKS5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnRhcmdldCEuZmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zdCBbc2VsZWN0ZWRGaWxlXSA9IGV2ZW50LnRhcmdldC5maWxlcyBhcyBGaWxlW107XHJcblxyXG4gICAgICAgICAgICBpZihGaWxlcy5Jc0V4Y2VsKHNlbGVjdGVkRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgRmlsZXMuUmVhZEV4Y2VsPFQ+KHNlbGVjdGVkRmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKFRvb2xzLklzTnVsbCh0aGlzLmltcG9ydEJ1dHRvbj8uQXV0b2ZpbGwpIHx8IHRoaXMuaW1wb3J0QnV0dG9uLkF1dG9maWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5TZXRWYWx1ZShyb3dzLmNvbmNhdCh0aGlzLl92YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25DbGlja0ltcG9ydC5lbWl0KHsgZGF0YTogdGhpcy5fdmFsdWUsIGZpbGU6IHNlbGVjdGVkRmlsZSB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2xpY2tJbXBvcnQuZW1pdCh7IGRhdGE6IHJvd3MsIGZpbGU6IHNlbGVjdGVkRmlsZSB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9ICdBbGxvd2VkIGV4dGVuc2lvbnM6JztcclxuICAgICAgICAgICAgICAgIGZvcihjb25zdCBleHRlbnNpb24gb2YgRmlsZXMuRVhDRUxfRVhURU5TSU9OUykge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCA8Yj4ke2V4dGVuc2lvbn08L2I+LGBcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5zdWJzdHJpbmcoMCwgbWVzc2FnZS5sZW5ndGggLSAxKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQuV2FybmluZyhtZXNzYWdlLCAnSW52YWxpZCBGaWxlIFR5cGUnLCAnYmkgYmktZmlsZXR5cGUteGxzeCBmYS1sZycpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNsaWNrSW1wb3J0LmVtaXQoeyBkYXRhOiBbXSwgZmlsZTogbnVsbCB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5pbnB1dEZpbGUoKS5uYXRpdmVFbGVtZW50LnZhbHVlID0gbnVsbDtcclxuICAgICAgICAgICAgVG9vbHMuU2xlZXAoMTAwMCkudGhlbigoKSA9PiB0aGlzLl9pc0xvYWRpbmcgPSBmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBFeHBvcnQoZXhwb3J0RmlsZTogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHRydWUpOiB2b2lkIHtcclxuICAgICAgICBsZXQgaXRlbTogYW55ID0ge307XHJcbiAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICBjb25zdCBGSUxFX05BTUUgPSAodGhpcy5leHBvcnRCdXR0b24/LmZpbGVOYW1lIHx8ICdDT0VSIFJlcG9ydCcpICsgJy54bHN4JztcclxuXHJcbiAgICAgICAgbGV0IFJPV19EQVRBX1NPVVJDRSA9ICh0aGlzLmV4cG9ydEJ1dHRvbi5oYXNPd25Qcm9wZXJ0eSgnb25seVJvd0ZpbHRlcmVkJykgJiYgIXRoaXMuZXhwb3J0QnV0dG9uLm9ubHlSb3dGaWx0ZXJlZClcclxuICAgICAgICAgICAgPyB0aGlzLnZhbHVlX3NpZ25hbCgpIDogdGhpcy5ncmlkRGF0YVNvdXJjZUZpbHRlcmVkKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IENPTFVNTl9EQVRBX1NPVVJDRSA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG4gICAgICAgIGlmICh0aGlzLmV4cG9ydEJ1dHRvbi5oYXNPd25Qcm9wZXJ0eSgnb25seUNvbHVtbkZpbHRlcmVkJykgJiYgIXRoaXMuZXhwb3J0QnV0dG9uLm9ubHlDb2x1bW5GaWx0ZXJlZCkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnZhbHVlX3NpZ25hbCgpKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbHVtbk5hbWUgaW4gcm93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbk5hbWUgPT0gJ2luZGV4Um93JykgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgQ09MVU1OX0RBVEFfU09VUkNFLmFkZChUb29scy5GaXJzdENoYXJUb0xvd2VyKGNvbHVtbk5hbWUpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgeyBjb2x1bW5OYW1lIH0gb2YgdGhpcy5ncmlkQ29sdW1ucygpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1uTmFtZSA9PSAnaW5kZXhSb3cnKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIENPTFVNTl9EQVRBX1NPVVJDRS5hZGQoVG9vbHMuRmlyc3RDaGFyVG9Mb3dlcihjb2x1bW5OYW1lKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IEVYUE9SVF9EQVRBOiBUW10gPSBbXTtcclxuICAgICAgICBmb3IgKGNvbnN0IHJvdyBvZiBST1dfREFUQV9TT1VSQ0UpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgQ09MVU1OX0RBVEFfU09VUkNFKSB7XHJcbiAgICAgICAgICAgICAgICBpdGVtID0gT2JqZWN0LmFzc2lnbihpdGVtLCB7IFt0aGlzLl9HZXRDb2x1bW5OYW1lKGNvbHVtbildOiAocm93IGFzIGFueSlbY29sdW1uXSB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgRVhQT1JUX0RBVEEucHVzaChpdGVtKTtcclxuICAgICAgICAgICAgaXRlbSA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlKHt9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChleHBvcnRGaWxlKSB7XHJcbiAgICAgICAgICAgIEZpbGVzLkV4cG9ydEV4Y2VsKEVYUE9SVF9EQVRBLCBGSUxFX05BTUUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5vbkNsaWNrRXhwb3J0LmVtaXQoRVhQT1JUX0RBVEEpO1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKDMwMDApLnRoZW4oKCkgPT4gdGhpcy5faXNMb2FkaW5nID0gZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHByb3RlY3RlZCBJbnB1dENoYW5nZShpbmRleFJvdzogbnVtYmVyLCBjb2x1bW5OYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnksIGlucHV0OiAnY29lci10ZXh0Ym94JyB8ICdjb2VyLW51bWJlcmJveCcgfCAnY29lci1zZWxlY3Rib3gnIHwgJ2NvZXItc3dpdGNoJyB8ICdjb2VyLXRleHRib3gtc2VhcmNoJyk6IHZvaWQge1xyXG4gICAgICAgIGlmIChpbnB1dCA9PT0gJ2NvZXItdGV4dGJveC1zZWFyY2gnKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0xvYWRpbmcpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIFRvb2xzLlNsZWVwKDAsIGBjb2VyR3JpZElucHV0Q2hhbmdlJHtjb2x1bW5OYW1lfWApLnRoZW4oYXN5bmMgXyA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ncmlkU2VhcmNoLnNldCh2YWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYodGhpcy5jaGVja2JveC5zaG93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nTWVzc2FnZSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IFRvb2xzLlNsZWVwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yKGNvbnN0IHJvdyBvZiB0aGlzLl92YWx1ZS5maWx0ZXIoKHg6IGFueSkgPT4geC5jaGVja2VkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkNoZWNrQnkoKHg6IGFueSkgPT4geC5pbmRleFJvdyA9PSAocm93IGFzIGFueSkuaW5kZXhSb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgVG9vbHMuU2xlZXAoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc0xvYWRpbmdNZXNzYWdlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvcGVydHkgPSBUb29scy5GaXJzdENoYXJUb0xvd2VyKGNvbHVtbk5hbWUpO1xyXG5cclxuICAgICAgICBjb25zdCByb3c6IGFueSA9IHRoaXMuX3ZhbHVlW2luZGV4Um93XTtcclxuICAgICAgICByb3dbcHJvcGVydHldID0gdmFsdWU7XHJcblxyXG4gICAgICAgIGlmIChpbnB1dCA9PT0gJ2NvZXItc3dpdGNoJykge1xyXG4gICAgICAgICAgICB0aGlzLm9uU3dpdGNoQ2hhbmdlLmVtaXQoeyBwcm9wZXJ0eSwgcm93OiBUb29scy5CcmVha1JlZmVyZW5jZShyb3cpLCB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKGlucHV0ID09PSAnY29lci10ZXh0Ym94Jykge1xyXG4gICAgICAgICAgICB0aGlzLm9uVGV4dGJveENoYW5nZS5lbWl0KHsgcHJvcGVydHksIHJvdzogVG9vbHMuQnJlYWtSZWZlcmVuY2Uocm93KSwgdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlIGlmIChpbnB1dCA9PT0gJ2NvZXItc2VsZWN0Ym94Jykge1xyXG4gICAgICAgICAgICB0aGlzLm9uU2VsZWN0Ym94Q2hhbmdlLmVtaXQoeyBwcm9wZXJ0eSwgcm93OiBUb29scy5CcmVha1JlZmVyZW5jZShyb3cpLCB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKGlucHV0ID09PSAnY29lci1udW1iZXJib3gnKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25UZXh0Ym94Q2hhbmdlLmVtaXQoeyBwcm9wZXJ0eSwgcm93OiBUb29scy5CcmVha1JlZmVyZW5jZShyb3cpLCB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIFRvb2xzLlNsZWVwKDEwMDAsIGBjb2VyR3JpZElucHV0Q2hhbmdlJHtpbmRleFJvd30ke2NvbHVtbk5hbWV9YCkudGhlbihfID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fVXBkYXRlVmFsdWUodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlX3NpZ25hbC5zZXQodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHByb3RlY3RlZCBLZXl1cEVudGVyKGluZGV4Q29sdW1uOiBudW1iZXIsIHJvdzogYW55LCBpbnB1dDogJ2NvZXItdGV4dGJveCcgfCAnY29lci1udW1iZXJib3gnIHwgJ2NvZXItdGV4dGJveC1zZWFyY2gnIHwgJ2NvZXItc2VsZWN0Ym94JywgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIGlmIChbJ2NvZXItdGV4dGJveCcsICdjb2VyLW51bWJlcmJveCcsICdjb2VyLXNlbGVjdGJveCddLmluY2x1ZGVzKGlucHV0KSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uS2V5dXBFbnRlci5lbWl0KHtcclxuICAgICAgICAgICAgICAgIGlkOiB0aGlzLl9HZXRJZChpbmRleENvbHVtbiwgcm93LmluZGV4Um93LCBpbnB1dCksXHJcbiAgICAgICAgICAgICAgICBpbnB1dCwgcm93OiBUb29scy5CcmVha1JlZmVyZW5jZShyb3cpLCB2YWx1ZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuTmV4dElucHV0KGluZGV4Q29sdW1uLCByb3cuaW5kZXhSb3cpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxzZSBpZiAoaW5wdXQgPT0gJ2NvZXItdGV4dGJveC1zZWFyY2gnKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25LZXl1cEVudGVyLmVtaXQoe1xyXG4gICAgICAgICAgICAgICAgaWQ6IHRoaXMuX0dldElkKGluZGV4Q29sdW1uLCByb3cuaW5kZXhSb3csIGlucHV0KSxcclxuICAgICAgICAgICAgICAgIGlucHV0LCByb3c6IG51bGwsIHZhbHVlXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcml2YXRlIE5leHRJbnB1dChpbmRleENvbHVtbjogbnVtYmVyLCBpbmRleFJvdzogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgSU5QVVRfVEVYVCA9IHRoaXMuY29sdW1ucygpLmZpbHRlcih4ID0+IFRvb2xzLklzTm90TnVsbCh4LmNvZXJUZXh0Ym94KSkubWFwKHggPT4geC5wcm9wZXJ0eSk7XHJcbiAgICAgICAgY29uc3QgSU5QVVRfTlVNQkVSID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKHggPT4gVG9vbHMuSXNOb3ROdWxsKHguY29lck51bWJlcmJveCkpLm1hcCh4ID0+IHgucHJvcGVydHkpO1xyXG4gICAgICAgIGNvbnN0IElOUFVUX1NFTEVDVCA9IHRoaXMuY29sdW1ucygpLmZpbHRlcih4ID0+IFRvb2xzLklzTm90TnVsbCh4LmNvZXJTZWxlY3Rib3gpKS5tYXAoeCA9PiB4LnByb3BlcnR5KTtcclxuXHJcbiAgICAgICAgbGV0IGluZGV4ID0gMFxyXG4gICAgICAgIGNvbnN0IENPTFVNTlMgPSBbXVxyXG4gICAgICAgIGNvbnN0IElOUFVUX0NPTFVNTlMgPSBbXVxyXG4gICAgICAgIGZvciAoY29uc3QgeyBjb2x1bW5OYW1lIH0gb2YgdGhpcy5ncmlkQ29sdW1ucygpKSB7XHJcbiAgICAgICAgICAgIGlmIChJTlBVVF9URVhULnNvbWUocHJvcGVydHkgPT4gcHJvcGVydHkudG9VcHBlckNhc2UoKSA9PSBjb2x1bW5OYW1lLnRvVXBwZXJDYXNlKCkpKSB7XHJcbiAgICAgICAgICAgICAgICBDT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnY29lclRleHRib3gnIH0pO1xyXG4gICAgICAgICAgICAgICAgSU5QVVRfQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJUZXh0Ym94JyB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZWxzZSBpZiAoSU5QVVRfTlVNQkVSLnNvbWUocHJvcGVydHkgPT4gcHJvcGVydHkudG9VcHBlckNhc2UoKSA9PSBjb2x1bW5OYW1lLnRvVXBwZXJDYXNlKCkpKSB7XHJcbiAgICAgICAgICAgICAgICBDT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnY29lck51bWJlcmJveCcgfSk7XHJcbiAgICAgICAgICAgICAgICBJTlBVVF9DT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnY29lck51bWJlcmJveCcgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKElOUFVUX1NFTEVDVC5zb21lKHByb3BlcnR5ID0+IHByb3BlcnR5LnRvVXBwZXJDYXNlKCkgPT0gY29sdW1uTmFtZS50b1VwcGVyQ2FzZSgpKSkge1xyXG4gICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJTZWxlY3Rib3gnIH0pO1xyXG4gICAgICAgICAgICAgICAgSU5QVVRfQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJTZWxlY3Rib3gnIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIENPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdkZWZhdWx0LWNlbGwnIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICArK2luZGV4O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGxhc3RSb3cgPSAtMVxyXG4gICAgICAgIGZvcihjb25zdCB7IHJvd3MgfSBvZiB0aGlzLmdyaWREYXRhU291cmNlKCkpIHtcclxuICAgICAgICAgICAgbGFzdFJvdyArPSByb3dzLmxlbmd0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBmaXJzdENvbHVtbiA9IC0xO1xyXG4gICAgICAgIGlmIChJTlBVVF9DT0xVTU5TLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZmlyc3RDb2x1bW4gPSBbLi4uSU5QVVRfQ09MVU1OU10uc2hpZnQoKSEuaW5kZXhDb2x1bW47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgbGFzdENvbHVtbiA9IC0xO1xyXG4gICAgICAgIGlmIChJTlBVVF9DT0xVTU5TLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGFzdENvbHVtbiA9IFsuLi5JTlBVVF9DT0xVTU5TXS5wb3AoKSEuaW5kZXhDb2x1bW47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvL0lzIExhc3QgUm93ICYgTGFzdCBJbnB1dCBDb2x1bW4/XHJcbiAgICAgICAgaWYgKGluZGV4Um93ID09IGxhc3RSb3cgJiYgaW5kZXhDb2x1bW4gPT0gbGFzdENvbHVtbikge1xyXG4gICAgICAgICAgICB0aGlzLm9uS2V5dXBFbnRlckxhc3QuZW1pdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9JcyBMYXN0IElucHV0IENvbHVtbj9cclxuICAgICAgICBlbHNlIGlmIChpbmRleENvbHVtbiA9PSBsYXN0Q29sdW1uKSB7XHJcbiAgICAgICAgICAgIHRoaXMuRm9jdXNJbnB1dCgoaW5kZXhSb3cgKyAxKSwgZmlyc3RDb2x1bW4pXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvL05leHQgQ29sdW1uP1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmb3IgKGluZGV4ID0gKGluZGV4Q29sdW1uICsgMSk7IGluZGV4IDwgQ09MVU1OUy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgICAgIGZvcihjb25zdCBpbnB1dCBvZiBDT0xVTU5TKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggPT0gaW5wdXQuaW5kZXhDb2x1bW4gJiYgWydjb2VyVGV4dGJveCcsICdjb2VyTnVtYmVyYm94JywgJ2NvZXJTZWxlY3Rib3gnXS5pbmNsdWRlcyhpbnB1dC50eXBlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkZvY3VzSW5wdXQoaW5kZXhSb3csIGlucHV0LmluZGV4Q29sdW1uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgRm9jdXNJbnB1dChpbmRleFJvdyA9IC0xLCBpbmRleENvbHVtbiA9IC0xKSB7XHJcbiAgICAgICAgVG9vbHMuU2xlZXAoMCwgJ0ZvY3VzSW5wdXQnKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzRGlzYWJsZWQoKSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaWYgKGluZGV4Um93IDwgMCB8fCBpbmRleENvbHVtbiA8IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IElOUFVUX1RFWFQgPSB0aGlzLmNvbHVtbnMoKS5maWx0ZXIoeCA9PiBUb29scy5Jc05vdE51bGwoeC5jb2VyVGV4dGJveCkpLm1hcCh4ID0+IHgucHJvcGVydHkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgSU5QVVRfTlVNQkVSID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKHggPT4gVG9vbHMuSXNOb3ROdWxsKHguY29lck51bWJlcmJveCkpLm1hcCh4ID0+IHgucHJvcGVydHkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgSU5QVVRfU0VMRUNUID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKHggPT4gVG9vbHMuSXNOb3ROdWxsKHguY29lclNlbGVjdGJveCkpLm1hcCh4ID0+IHgucHJvcGVydHkpO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IDA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBDT0xVTU5TID0gW11cclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgeyBjb2x1bW5OYW1lIH0gb2YgdGhpcy5ncmlkQ29sdW1ucygpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKElOUFVUX1RFWFQuc29tZShwcm9wZXJ0eSA9PiBwcm9wZXJ0eS50b1VwcGVyQ2FzZSgpID09IGNvbHVtbk5hbWUudG9VcHBlckNhc2UoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJUZXh0Ym94JyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKElOUFVUX05VTUJFUi5zb21lKHByb3BlcnR5ID0+IHByb3BlcnR5LnRvVXBwZXJDYXNlKCkgPT0gY29sdW1uTmFtZS50b1VwcGVyQ2FzZSgpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnY29lck51bWJlcmJveCcgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChJTlBVVF9TRUxFQ1Quc29tZShwcm9wZXJ0eSA9PiBwcm9wZXJ0eS50b1VwcGVyQ2FzZSgpID09IGNvbHVtbk5hbWUudG9VcHBlckNhc2UoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJTZWxlY3Rib3gnIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdkZWZhdWx0LWNlbGwnIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgKytpbmRleDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZih0aGlzLmdyaWRMZW5ndGgoKS5kYXRhU291cmNlRmlsdGVyZWQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgRklSU1RfSU5QVVRfQ09MVU1OID0gQ09MVU1OUy5maW5kKHggPT4gWydjb2VyVGV4dGJveCcsICdjb2VyTnVtYmVyYm94JywgJ2NvZXJTZWxlY3Rib3gnXS5pbmNsdWRlcyh4LnR5cGUpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKFRvb2xzLklzTm90TnVsbChGSVJTVF9JTlBVVF9DT0xVTU4pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRm9jdXNJbnB1dCgwLCBGSVJTVF9JTlBVVF9DT0xVTU4hLmluZGV4Q29sdW1uKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLl9HZXRJZChpbmRleFJvdywgaW5kZXhDb2x1bW4pO1xyXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQ6IENvZXJUZXh0Qm94IHwgQ29lck51bWJlckJveCB8IENvZXJTZWxlY3Rib3g8YW55PiB8IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4Rm9jdXMuc2V0KGluZGV4Um93KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0ZvY3VzIFRleHRib3hcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmNvZXJUZXh0Ym94TGlzdCgpLmZpbmQoeCA9PiB4LmlkID09IGlkKTtcclxuICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LlNlbGVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvL0ZvY3VzIE51bWJlcmJveFxyXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuY29lck51bWJlcmJveExpc3QoKS5maW5kKHggPT4geC5pZCA9PSBpZCk7XHJcbiAgICAgICAgICAgICAgICBpZihlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5TZWxlY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy9Gb2N1cyBTZWxlY3Rib3hcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmNvZXJTZWxlY3Rib3hMaXN0KCkuZmluZCh4ID0+IHguaWQgPT0gaWQpO1xyXG4gICAgICAgICAgICAgICAgaWYoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIFRvb2xzLlNsZWVwKDEwMCkudGhlbihfID0+IGVsZW1lbnQuRm9jdXMoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIEZvY3VzUm93KGNhbGxiYWNrOiAocm93OiBUKSA9PiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgVG9vbHMuU2xlZXAoKS50aGVuKF8gPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdmFsdWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgcm93ID0gVG9vbHMuQnJlYWtSZWZlcmVuY2U8YW55Pih0aGlzLl92YWx1ZS5maW5kKGNhbGxiYWNrIGFzIGFueSkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKFRvb2xzLklzTm90TnVsbChyb3cpKSB0aGlzLl9pbmRleEZvY3VzLnNldChyb3cuaW5kZXhSb3cpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIGFzeW5jIFNvcnQoY29sdW1uTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlU29ydCgpKSB7XHJcbiAgICAgICAgICAgIGlmKHRoaXMuX2lzTG9hZGluZykgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nTWVzc2FnZSA9IHRydWU7XHJcbiAgICAgICAgICAgIGNvbnN0IHsgZGlyZWN0aW9uIH0gPSB0aGlzLl9zb3J0KCk7XHJcblxyXG4gICAgICAgICAgICBsZXQgZGF0YVNvdXJjZSA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueT4odGhpcy5fdmFsdWUpO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNoZWNrYm94IG9mIHRoaXMuY29lckNoZWNrYm94TGlzdCgpKSBjaGVja2JveC5VbmNoZWNrKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZGlyZWN0aW9uID09ICdkZXNjZW5kYW50Jykge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuU29ydEJ5RGVzYyhkYXRhU291cmNlLCBjb2x1bW5OYW1lKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NvcnQuc2V0KHsgY29sdW1uTmFtZSwgZGlyZWN0aW9uOiAnYXNjZW5kYW50JywgaWNvbjogJ2ZhLXNvbGlkIGZhLWFycm93LWRvd24tc2hvcnQtd2lkZScgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuU29ydEJ5KGRhdGFTb3VyY2UsIGNvbHVtbk5hbWUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc29ydC5zZXQoeyBjb2x1bW5OYW1lLCBkaXJlY3Rpb246ICdkZXNjZW5kYW50JywgaWNvbjogJ2ZhLXNvbGlkIGZhLWFycm93LXVwLXdpZGUtc2hvcnQnIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgaW5kZXhSb3cgPSAwO1xyXG4gICAgICAgICAgICBkYXRhU291cmNlID0gVG9vbHMuQnJlYWtSZWZlcmVuY2U8YW55PihkYXRhU291cmNlKS5tYXAoKGl0ZW06IGFueSkgPT4gT2JqZWN0LmFzc2lnbihpdGVtLCB7IGluZGV4Um93OiBpbmRleFJvdysrIH0pKTtcclxuICAgICAgICAgICAgdGhpcy5TZXRWYWx1ZShkYXRhU291cmNlKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgYXdhaXQgVG9vbHMuU2xlZXAoKTtcclxuICAgICAgICAgICAgZm9yKGNvbnN0IHJvdyBvZiBkYXRhU291cmNlLmZpbHRlcigoeDogYW55KSA9PiB4LmNoZWNrZWQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLkNoZWNrQnkoKHg6IGFueSkgPT4geC5pbmRleFJvdyA9PSByb3cuaW5kZXhSb3cpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pc0xvYWRpbmdNZXNzYWdlID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJvdGVjdGVkIENsaWNrQ2hlY2soaWQ6IHN0cmluZywgY2hlY2tlZDogYm9vbGVhbiwgYWxsOiBib29sZWFuLCByb3c6IGFueSA9IG51bGwpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2lzTG9hZGluZykgVG9vbHMuU2xlZXAoKS50aGVuKGFzeW5jIF8gPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSB0aGlzLmNvZXJDaGVja2JveExpc3QoKS5maW5kKHggPT4geC5pZCgpID09IGlkKTtcclxuXHJcbiAgICAgICAgICAgIGlmKFRvb2xzLklzTm90TnVsbChlbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlOiBJR3JpZElucHV0Q2hlY2tib3g8VD4gPSB7IGFsbCwgY2hlY2tlZCwgcm93czogW10gfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0FsbCBDaGVja2JveFxyXG4gICAgICAgICAgICAgICAgaWYgKGFsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKGNoZWNrZWQpIHRoaXMuQ2hlY2tBbGwoKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHRoaXMuVW5jaGVja0FsbCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0V2ZW50XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Uucm93cyA9IHRoaXMuc2VsZWN0ZWRJdGVtcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25DaGVja2JveENoYW5nZS5lbWl0KHJlc3BvbnNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvL09uZSBDaGVja2JveFxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fb25seU9uZUNoZWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMuX3ZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocm93IGFzIGFueSkuY2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoZWNrYm94IG9mIHRoaXMuY29lckNoZWNrYm94TGlzdCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjaGVja2JveC5pZCgpICE9IGlkKSBjaGVja2JveC5VbmNoZWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLl92YWx1ZVtyb3cuaW5kZXhSb3ddIGFzIGFueSkuY2hlY2tlZCA9IGNoZWNrZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5TZXRWYWx1ZSh0aGlzLl92YWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vTWFyayBBbGwgY2hlY2tib3hcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGVja2JveEFsbCA9IHRoaXMuY29lckNoZWNrYm94TGlzdCgpLmZpbmQoeCA9PiB4LmlkKCkgPT0gdGhpcy5fR2V0SWQoMCwgMCwgJ2NoZWNrYm94QWxsJykpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnZhbHVlX3NpZ25hbCgpLmV2ZXJ5KCh4OiBhbnkpID0+IHguY2hlY2tlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tib3hBbGw/LkNoZWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tib3hBbGw/LlVuY2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vRXZlbnRcclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5yb3dzID0gW3sgLi4ucm93IH1dO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25DaGVja2JveENoYW5nZS5lbWl0KHJlc3BvbnNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgQ2hlY2tBbGwoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5fdmFsdWUpIHtcclxuICAgICAgICAgICAgKHJvdyBhcyBhbnkpLmNoZWNrZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5TZXRWYWx1ZSh0aGlzLl92YWx1ZSk7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2hlY2tib3ggb2YgdGhpcy5jb2VyQ2hlY2tib3hMaXN0KCkpIHtcclxuICAgICAgICAgICAgY2hlY2tib3guQ2hlY2soKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBVbmNoZWNrQWxsKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMuX3ZhbHVlKSB7XHJcbiAgICAgICAgICAgIChyb3cgYXMgYW55KS5jaGVja2VkID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLlNldFZhbHVlKHRoaXMuX3ZhbHVlKTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBjaGVja2JveCBvZiB0aGlzLmNvZXJDaGVja2JveExpc3QoKSkge1xyXG4gICAgICAgICAgICBjaGVja2JveC5VbmNoZWNrKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgQ2hlY2tCeShjYWxsYmFjazogKHJvdzogVCkgPT4gYm9vbGVhbik6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKCkudGhlbihfID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvd0xpc3QgPSBUb29scy5CcmVha1JlZmVyZW5jZTxhbnk+KHRoaXMuX3ZhbHVlLmZpbHRlcihjYWxsYmFjayBhcyBhbnkpKTtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudDogQ29lckNoZWNrYm94IHwgdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgZm9yKGNvbnN0IHsgaW5kZXhSb3cgfSBvZiByb3dMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuY29lckNoZWNrYm94TGlzdCgpLmZpbmQoeCA9PiB4LmlkKCkgPT0gdGhpcy5fR2V0SWQoaW5kZXhSb3csIDAsICdjaGVja2JveCcpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKFRvb2xzLklzTm90TnVsbChlbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50Py5DaGVjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBVbmNoZWNrQnkoY2FsbGJhY2s6IChyb3c6IFQpID0+IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgICAgICBUb29scy5TbGVlcCgpLnRoZW4oXyA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl92YWx1ZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3dMaXN0ID0gVG9vbHMuQnJlYWtSZWZlcmVuY2U8YW55Pih0aGlzLl92YWx1ZS5maWx0ZXIoY2FsbGJhY2sgYXMgYW55KSk7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQ6IENvZXJDaGVja2JveCB8IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIGZvcihjb25zdCB7IGluZGV4Um93IH0gb2Ygcm93TGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmNvZXJDaGVja2JveExpc3QoKS5maW5kKHggPT4geC5pZCgpID09IHRoaXMuX0dldElkKGluZGV4Um93LCAwLCAnY2hlY2tib3gnKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChUb29scy5Jc05vdE51bGwoZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudD8uVW5jaGVjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHByb3RlY3RlZCBDbGlja09uUm93KHJvdzogVCk6IHZvaWQge1xyXG4gICAgICAgIGlmKHRoaXMuX2lzRGlzYWJsZWQoKSkgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZihUb29scy5Jc05vdE51bGwodGhpcy5jaGVja2JveC5jaGVja09uUm93KSAmJiB0aGlzLmNoZWNrYm94LmNoZWNrT25Sb3cpIHtcclxuICAgICAgICAgICAgdGhpcy5DaGVja0J5KCh4OiBhbnkpID0+IHguaW5kZXhSb3cgPT0gKHJvdyBhcyBhbnkpLmluZGV4Um93KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMub25DbGlja1Jvdy5lbWl0KHJvdyk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiBJbnNlcnRzIG5ldyBlbGVtZW50cyBhdCB0aGUgc3RhcnQgKi9cclxuICAgIHB1YmxpYyBVbnNoaWZ0KHJvdzogVCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBUb29scy5CcmVha1JlZmVyZW5jZSh0aGlzLl92YWx1ZSk7XHJcbiAgICAgICAgZGF0YVNvdXJjZS51bnNoaWZ0KHJvdyk7XHJcbiAgICAgICAgdGhpcy5TZXRWYWx1ZShkYXRhU291cmNlKTtcclxuICAgICAgICB0aGlzLkZvY3VzSW5wdXQoKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqIEFwcGVuZHMgbmV3IGVsZW1lbnRzIHRvIHRoZSBlbmQgKi9cclxuICAgIHB1YmxpYyBQdXNoKHJvdzogVCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBUb29scy5CcmVha1JlZmVyZW5jZSh0aGlzLl92YWx1ZSk7XHJcbiAgICAgICAgZGF0YVNvdXJjZS5wdXNoKHJvdyk7XHJcbiAgICAgICAgdGhpcy5TZXRWYWx1ZShkYXRhU291cmNlKTtcclxuICAgICAgICB0aGlzLkZvY3VzSW5wdXQoKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqIERlbGV0ZSBSb3cgQnkgaW5kZXggKi9cclxuICAgIHB1YmxpYyBhc3luYyBEZWxldGVSb3coaW5kZXhSb3c6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBUb29scy5CcmVha1JlZmVyZW5jZSh0aGlzLl92YWx1ZSk7XHJcbiAgICAgICAgZGF0YVNvdXJjZS5zcGxpY2UoaW5kZXhSb3csIDEpO1xyXG4gICAgICAgIHRoaXMuU2V0VmFsdWUoZGF0YVNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiBEZWxldGUgcm93IGxpc3QgYnkgY2FsbGJhY2sgKi9cclxuICAgIHB1YmxpYyBhc3luYyBEZWxldGVSb3dzQnkoY2FsbGJhY2s6IChyb3c6IFQpID0+IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBpbmRleExpc3QgPSBUb29scy5CcmVha1JlZmVyZW5jZTxudW1iZXJbXT4odGhpcy5fdmFsdWUuZmlsdGVyKGNhbGxiYWNrIGFzIGFueSkubWFwKChpdGVtOiBhbnkpID0+IGl0ZW0uaW5kZXhSb3cpKTtcclxuXHJcbiAgICAgICAgbGV0IGRhdGFTb3VyY2U6IGFueVtdID0gW107XHJcbiAgICAgICAgZm9yKGNvbnN0IGluZGV4Um93IG9mIGluZGV4TGlzdCkge1xyXG4gICAgICAgICAgICBkYXRhU291cmNlID0gVG9vbHMuQnJlYWtSZWZlcmVuY2UodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgICAgICBkYXRhU291cmNlLnNwbGljZShpbmRleFJvdywgMSk7XHJcbiAgICAgICAgICAgIHRoaXMuU2V0VmFsdWUoZGF0YVNvdXJjZSk7XHJcbiAgICAgICAgICAgIGF3YWl0IFRvb2xzLlNsZWVwKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59IiwiPGRpdiBjbGFzcz1cImNvZXItZ3JpZFwiIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJzogd2lkdGgoKSwgJ21pbi1XaWR0aCc6IE1pbldpZHRoKCksICdtYXgtV2lkdGgnOiBNYXhXaWR0aCgpLCAnbWFyZ2luJzogbWFyZ2luKCkgfVwiPlxyXG4gICAgPGhlYWRlciBbaWRdPVwiX2lkICsgJy1oZWFkZXInXCIgY2xhc3M9XCJyb3dcIj5cclxuICAgICAgICA8IS0tIFNsb3QgLS0+XHJcbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG5cclxuICAgICAgICA8IS0tIEV4cG9ydCBCdXR0b24gLS0+XHJcbiAgICAgICAgQGlmKGV4cG9ydEJ1dHRvbi5zaG93ICYmIGdyaWRMZW5ndGgoKS5kYXRhU291cmNlID4gMCkge1xyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLWF1dG9cIj5cclxuICAgICAgICAgICAgICAgIDxjb2VyLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJpY29uXCJcclxuICAgICAgICAgICAgICAgICAgICBjb2xvcj1cIm5hdmlnYXRpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgIGljb249XCJleGNlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiX2lzTG9hZGluZyA/ICdMb2FkaW5nJyA6IChleHBvcnRCdXR0b24udG9vbHRpcCB8fCAnRXhwb3J0JylcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtwYXRoXT1cIihleHBvcnRCdXR0b24gJiYgZXhwb3J0QnV0dG9uLnBhdGgpID8gZXhwb3J0QnV0dG9uLnBhdGggOiBbXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nIHx8IChleHBvcnRCdXR0b24uaXNEaXNhYmxlZCB8fCBmYWxzZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtpc0xvYWRpbmddPVwiX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJfZW5hYmxlQW5pbWF0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwiRXhwb3J0KCFleHBvcnRCdXR0b24ucHJldmVudERlZmF1bHQpXCJcclxuICAgICAgICAgICAgICAgID48L2NvZXItYnV0dG9uPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDwhLS0gSW1wb3J0IEJ1dHRvbiAtLT5cclxuICAgICAgICBAaWYoaW1wb3J0QnV0dG9uLnNob3cpIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiAjaW5wdXRGaWxlUmVmIFttdWx0aXBsZV09XCJmYWxzZVwiIChjaGFuZ2UpPVwiSW1wb3J0KCRldmVudClcIj5cclxuXHJcbiAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICBpY29uPVwiaW1wb3J0XCJcclxuICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcF09XCJpbXBvcnRCdXR0b24udG9vbHRpcCB8fCAnSW1wb3J0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW3BhdGhdPVwiKGltcG9ydEJ1dHRvbiAmJiBpbXBvcnRCdXR0b24ucGF0aCkgPyBpbXBvcnRCdXR0b24ucGF0aCA6IFtdXCJcclxuICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJpbXBvcnRCdXR0b24uaXNEaXNhYmxlZCB8fCBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJfZW5hYmxlQW5pbWF0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwiSW1wb3J0KClcIlxyXG4gICAgICAgICAgICAgICAgPjwvY29lci1idXR0b24+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgPCEtLSBBZGQgQnV0dG9uIC0tPlxyXG4gICAgICAgIEBpZihhZGRCdXR0b24uc2hvdykge1xyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLWF1dG9cIj5cclxuICAgICAgICAgICAgICAgIDxjb2VyLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJpY29uXCJcclxuICAgICAgICAgICAgICAgICAgICBjb2xvcj1cIm5hdmlnYXRpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgIGljb249XCJuZXdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFt0b29sdGlwXT1cImFkZEJ1dHRvbi50b29sdGlwIHx8ICdOZXcnXCJcclxuICAgICAgICAgICAgICAgICAgICBbcGF0aF09XCIoYWRkQnV0dG9uICYmIGFkZEJ1dHRvbi5wYXRoKSA/IGFkZEJ1dHRvbi5wYXRoIDogW11cIlxyXG4gICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cImFkZEJ1dHRvbi5pc0Rpc2FibGVkIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cIl9lbmFibGVBbmltYXRpb25zXCJcclxuICAgICAgICAgICAgICAgICAgICAob25DbGljayk9XCJvbkNsaWNrQWRkLmVtaXQoKVwiXHJcbiAgICAgICAgICAgICAgICA+PC9jb2VyLWJ1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA8IS0tIFNlYXJjaCAtLT5cclxuICAgICAgICBAaWYoc2VhcmNoLnNob3cpIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICA8Y29lci10ZXh0Ym94XHJcbiAgICAgICAgICAgICAgICAgICAgI2lucHV0U2VhcmNoXHJcbiAgICAgICAgICAgICAgICAgICAgW2lkXT1cIl9HZXRJZCgtMSwgLTEsICdzZWFyY2gnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiX2dyaWRTZWFyY2goKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2hcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NlbGVjdE9uRm9jdXNdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIyNTBweFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Nob3dTZWFyY2hJY29uXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJJY29uXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIChvbklucHV0KT1cIklucHV0Q2hhbmdlKC0xLCAnU2VhcmNoJywgJGV2ZW50LCAnY29lci10ZXh0Ym94LXNlYXJjaCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAob25DbGlja0NsZWFyKT1cIklucHV0Q2hhbmdlKC0xLCAnU2VhcmNoJywgJycsICdjb2VyLXRleHRib3gtc2VhcmNoJylcIlxyXG4gICAgICAgICAgICAgICAgICAgIChvbktleXVwRW50ZXIpPVwiS2V5dXBFbnRlcigtMSwgeyBpbmRleFJvdzogLTEgfSwgJ2NvZXItdGV4dGJveC1zZWFyY2gnLCAkZXZlbnQpO1wiXHJcbiAgICAgICAgICAgICAgICA+PC9jb2VyLXRleHRib3g+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIH1cclxuICAgIDwvaGVhZGVyPlxyXG5cclxuICAgIDxzZWN0aW9uIFtuZ0NsYXNzXT1cInsgJ2dyaWQtY29udGFpbmVyJzogdHJ1ZSwgJ2ludmlzaWJsZSc6IGlzSW52aXNpYmxlKCkgfVwiPlxyXG4gICAgICAgIDxkaXYgW25nU3R5bGVdPVwieyAnaGVpZ2h0JzogX2hlaWdodCwgJ21pbi1oZWlnaHQnOiBtaW5IZWlnaHQoKSwgJ21heC1oZWlnaHQnOiBtYXhIZWlnaHQoKSB9XCI+XHJcbiAgICAgICAgICAgIEBpZihpc0xvYWRpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgPCEtLSBHcmlkIE1lc3NhZ2UgLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9hZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmYS1mYWRlXCI+TG9hZGluZzwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBAZWxzZSBpZighX2lzRGlzYWJsZWQoKSAmJiBncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZSA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibm8tZGF0YVwiPiBObyBEYXRhIDwvZGl2PlxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1yZXNwb25zaXZlIHRhYmxlLXN0cmlwZWRcIj5cclxuICAgICAgICAgICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZihjaGVja2JveC5zaG93ICYmIGdyaWRMZW5ndGgoKS5kYXRhU291cmNlID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDaGVja0JveCBDb2x1bW4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjbGFzcz1cImNoZWNrLWJveFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhX29ubHlPbmVDaGVja1wiIFtuZ0NsYXNzXT1cInsgJ2ludmlzaWJsZSc6IF9pc0xvYWRpbmdNZXNzYWdlIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItY2hlY2tib3hcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJfR2V0SWQoMCwgMCwgJ2NoZWNrYm94QWxsJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lnbm9yZU1vZGVsXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJDbGlja0NoZWNrKF9HZXRJZCgwLCAwLCAnY2hlY2tib3hBbGwnKSwgJGV2ZW50LCB0cnVlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIER5bmFtaWMgR3JpZCBDb2x1bW4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IoaGVhZGVyIG9mIGdyaWRDb2x1bW5zKCk7IHRyYWNrIGhlYWRlci5pbmRleENvbHVtbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgKGRibGNsaWNrKT1cIlNvcnQoaGVhZGVyLmNvbHVtbk5hbWUpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICduby1zZWxlY3Rpb24nOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY3Vyc29yLWRlZmF1bHQnOiAhZW5hYmxlU29ydCgpICYmICFfaXNMb2FkaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY3Vyc29yLXBvaW50ZXInOiBlbmFibGVTb3J0KCkgJiYgIV9pc0xvYWRpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjdXJzb3Itd2FpdCc6IF9pc0xvYWRpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IGhlYWRlci53aWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtYWxpZ24nOiBHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIG51bGwsICd0ZXh0QWxpZ24nLCAnZGVmYXVsLWNlbGwnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibm8tc2VsZWN0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IF9HZXRDb2x1bW5OYW1lKGhlYWRlci5jb2x1bW5OYW1lKSB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwiX0dldFNob3J0SWNvbihoZWFkZXIuY29sdW1uTmFtZSlcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIERlbGV0ZSBCdXR0b24gQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dEZWxldGVCdXR0b24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgY2xhc3M9XCJhY3Rpb24tYnV0dG9uXCI+PC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IEJ1dHRvbiBDb2x1bW4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0VkaXRCdXR0b24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgY2xhc3M9XCJhY3Rpb24tYnV0dG9uXCI+PC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IEJ1dHRvbiBDb2x1bW4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0dvQnV0dG9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiIGNsYXNzPVwiYWN0aW9uLWJ1dHRvblwiPjwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICAgICAgPC90aGVhZD5cclxuXHJcbiAgICAgICAgICAgICAgICA8IS0tIGJvZHkgLS0+XHJcbiAgICAgICAgICAgICAgICBAZm9yKGdyb3VwIG9mIGdyaWREYXRhU291cmNlKCk7IHRyYWNrIGdyb3VwLmluZGV4R3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS08dHIgdi1pZj1cIl9pc0dyb3VwZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCA6Y29sc3Bhbj1cIl9jb2xzcGFuXCIgY2xhc3M9XCJncm91cFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxNZXNBY2NvcmRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOnJlZj1cImBhY2NvcmRpb24ke2dyb3VwLmluZGV4R3JvdXB9LSR7aWR9YFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDp0aXRsZT1cImAke19DbGVhbkhlYWRlck5hbWUoZ3JvdXBCeSl9ICgke2dyb3VwLmxlbmd0aH0pOiAgJHtncm91cC5ncm91cEJ5fWBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6aXNMb2FkaW5nPVwiX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBleHBhbmRlZD1cIl9Ub29nbGVBY2NvcmRpb24oZ3JvdXAuZ3JvdXBCeSwgdHJ1ZSwgZ3JvdXAuaW5kZXhHcm91cClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAY29sbGFwc2VkPVwiX1Rvb2dsZUFjY29yZGlvbihncm91cC5ncm91cEJ5LCBmYWxzZSwgZ3JvdXAuaW5kZXhHcm91cClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L01lc0FjY29yZGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+LS0+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yKHJvdyBvZiBncm91cC5yb3dzOyB0cmFjayByb3cuaW5kZXhSb3cpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgMCwgJ3JvdycpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdsb2FkaW5nJzogaXNMb2FkaW5nKCksICdkLW5vbmUnOiBfSGlkZVJvdyhncm91cCksICdyb3ctZm9jdXMnOiAocm93LmluZGV4Um93ID09IF9pbmRleEZvY3VzKCkgJiYgZW5hYmxlUm93Rm9jdXMoKSkgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIl9pbmRleEZvY3VzLnNldChyb3cuaW5kZXhSb3cpXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihjaGVja2JveC5zaG93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ2hlY2tCb3ggQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjaGVjay1ib3hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieyAnaW52aXNpYmxlJzogX2lzTG9hZGluZ01lc3NhZ2UgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2VyLWNoZWNrYm94XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJfR2V0SWQocm93LmluZGV4Um93LCAwLCAnY2hlY2tib3gnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZ25vcmVNb2RlbF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIkNsaWNrQ2hlY2soX0dldElkKHJvdy5pbmRleFJvdywgMCwgJ2NoZWNrYm94JyksICRldmVudCwgZmFsc2UsIHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsgJ2ludmlzaWJsZSc6ICFfaXNMb2FkaW5nTWVzc2FnZSB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJzcGlubmVyLWJvcmRlclwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEeW5hbWljIENvbHVtbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yKGhlYWRlciBvZiBncmlkQ29sdW1ucygpOyB0cmFjayBoZWFkZXIuaW5kZXhDb2x1bW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKF9Jc0NlbGxUeXBlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICd0ZW1wbGF0ZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIl9pc0Rpc2FibGVkKCkgPyBudWxsIDogb25DbGlja1Jvdy5lbWl0KHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJfaXNEaXNhYmxlZCgpID8gbnVsbCA6IG9uRG91YmxlQ2xpY2tSb3cuZW1pdChyb3cpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbaW5uZXJIVE1MXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndGVtcGxhdGUnLCAnZGVmYXVsLWNlbGwnKSB8IGh0bWxcIiBjbGFzcz1cInRlbXBsYXRlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnY29lclRleHRib3gnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBjb2VyLXRleHRib3ggLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2VyLXRleHRib3hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci10ZXh0Ym94XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJfR2V0SWQocm93LmluZGV4Um93LCBoZWFkZXIuaW5kZXhDb2x1bW4pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dbaGVhZGVyLmNvbHVtbk5hbWVdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc0Rpc2FibGVkJywgJ2NvZXJUZXh0Ym94JykgfHwgX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzVmFsaWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc1ZhbGlkJywgJ2NvZXJUZXh0Ym94JykgfHwgZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNJbnZhbGlkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNJbnZhbGlkJywgJ2NvZXJUZXh0Ym94JykgfHwgZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VsZWN0T25Gb2N1c109XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3NlbGVjdE9uRm9jdXMnLCAnY29lclRleHRib3gnKSB8fCB0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAncGxhY2Vob2xkZXInLCAnY29lclRleHRib3gnKSB8fCAoJ1R5cGUgJyArIGhlYWRlci5jb2x1bW5OYW1lICsgJy4uLicpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RleHRQb3NpdGlvbl09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3RleHRQb3NpdGlvbicsICdjb2VyVGV4dGJveCcpIHx8ICdsZWZ0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5MZW5ndGhdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdtaW5MZW5ndGgnLCAnY29lclRleHRib3gnKSB8fCAwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heExlbmd0aF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ21heExlbmd0aCcsICdjb2VyVGV4dGJveCcpIHx8IDUwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uSW5wdXQpPVwiSW5wdXRDaGFuZ2Uocm93LmluZGV4Um93LCBoZWFkZXIuY29sdW1uTmFtZSwgJGV2ZW50LCAnY29lci10ZXh0Ym94JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25LZXl1cEVudGVyKT1cIktleXVwRW50ZXIoaGVhZGVyLmluZGV4Q29sdW1uLCByb3csICdjb2VyLXRleHRib3gnLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLXRleHRib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2UgaWYoX0lzQ2VsbFR5cGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvZXJOdW1iZXJib3gnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBjb2VyLW51bWJlcmJveCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvZXItbnVtYmVyYm94XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItbnVtYmVyYm94XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJfR2V0SWQocm93LmluZGV4Um93LCBoZWFkZXIuaW5kZXhDb2x1bW4pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dbaGVhZGVyLmNvbHVtbk5hbWVdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc0Rpc2FibGVkJywgJ2NvZXJOdW1iZXJib3gnKSB8fCBfaXNEaXNhYmxlZCgpIHx8IF9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNWYWxpZF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2lzVmFsaWQnLCAnY29lck51bWJlcmJveCcpIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52YWxpZF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2lzSW52YWxpZCcsICdjb2VyTnVtYmVyYm94JykgfHwgZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VsZWN0T25Gb2N1c109XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3NlbGVjdE9uRm9jdXMnLCAnY29lck51bWJlcmJveCcpIHx8IHRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdwbGFjZWhvbGRlcicsICdjb2VyTnVtYmVyYm94JykgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dFBvc2l0aW9uXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndGV4dFBvc2l0aW9uJywgJ2NvZXJOdW1iZXJib3gnKSB8fCAncmlnaHQnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ21pbicsICdjb2VyTnVtYmVyYm94JykgfHwgMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdtYXgnLCAnY29lck51bWJlcmJveCcpIHx8IDIxNDc0ODM2NDdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGVjaW1hbHNdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdkZWNpbWFscycsICdjb2VyTnVtYmVyYm94JykgfHwgMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbklucHV0KT1cIklucHV0Q2hhbmdlKHJvdy5pbmRleFJvdywgaGVhZGVyLmNvbHVtbk5hbWUsICRldmVudCwgJ2NvZXItbnVtYmVyYm94JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25LZXl1cEVudGVyKT1cIktleXVwRW50ZXIoaGVhZGVyLmluZGV4Q29sdW1uLCByb3csICdjb2VyLW51bWJlcmJveCcsICRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItbnVtYmVyYm94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBlbHNlIGlmKF9Jc0NlbGxUeXBlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdjb2VyU2VsZWN0Ym94JykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gY29lci1udW1iZXJib3ggLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2VyLXNlbGVjdGJveFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2VyLXNlbGVjdGJveFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgaGVhZGVyLmluZGV4Q29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W2hlYWRlci5jb2x1bW5OYW1lXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNEaXNhYmxlZCcsICdjb2VyU2VsZWN0Ym94JykgfHwgX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzVmFsaWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc1ZhbGlkJywgJ2NvZXJTZWxlY3Rib3gnKSB8fCBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmFsaWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc0ludmFsaWQnLCAnY29lclNlbGVjdGJveCcpIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFTb3VyY2VdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdkYXRhU291cmNlJywgJ2NvZXJTZWxlY3Rib3gnKSB8fCBbXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3BsYWNlaG9sZGVyJywgJ2NvZXJTZWxlY3Rib3gnKSB8fCAnLS0gU2VsZWN0IC0tJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wRGlzcGxheV09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3Byb3BEaXNwbGF5JywgJ2NvZXJTZWxlY3Rib3gnKSB8fCAnbmFtZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25TZWxlY3RlZCk9XCJJbnB1dENoYW5nZShyb3cuaW5kZXhSb3csIGhlYWRlci5jb2x1bW5OYW1lLCAkZXZlbnQsICdjb2VyLXNlbGVjdGJveCcpOyBLZXl1cEVudGVyKGhlYWRlci5pbmRleENvbHVtbiwgcm93LCAnY29lci1zZWxlY3Rib3gnLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLXNlbGVjdGJveD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnY29lclN3aXRjaCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGNvZXItc3dpdGNoIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2VyLXN3aXRjaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgaGVhZGVyLmluZGV4Q29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W2hlYWRlci5jb2x1bW5OYW1lXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNEaXNhYmxlZCcsICdjb2VyU3dpdGNoJykgfHwgX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICd0b29sdGlwJywgJ2NvZXJTd2l0Y2gnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwUG9zaXRpb25dPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICd0b29sdGlwUG9zaXRpb24nLCAnY29lclN3aXRjaCcpIHx8ICdsZWZ0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmlzaWJsZV09XCJfaXNEaXNhYmxlZCgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIklucHV0Q2hhbmdlKHJvdy5pbmRleFJvdywgaGVhZGVyLmNvbHVtbk5hbWUsICRldmVudCwgJ2NvZXItc3dpdGNoJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItc3dpdGNoPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWZhdWx0IENlbGwgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJkZWZhdWx0LWNlbGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJDbGlja09uUm93KHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJfaXNEaXNhYmxlZCgpID8gbnVsbCA6IG9uRG91YmxlQ2xpY2tSb3cuZW1pdChyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWFsaWduJzogR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICd0ZXh0QWxpZ24nLCAnZGVmYXVsLWNlbGwnKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3doaXRlLXNwYWNlJzogJ25vcm1hbCdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW2lkXT1cIl9HZXRJZChyb3cuaW5kZXhSb3csIGhlYWRlci5pbmRleENvbHVtbilcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1ibHVlLWJvbGQnOiBfSXNDZWxsQ29sb3IoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvbG9yQmx1ZScpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtZ3JlZW4tYm9sZCc6IF9Jc0NlbGxDb2xvcihoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnY29sb3JHcmVlbicpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQteWVsbG93LWJvbGQnOiBfSXNDZWxsQ29sb3IoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvbG9yWWVsbG93JyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yZWQtYm9sZCc6IF9Jc0NlbGxDb2xvcihoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnY29sb3JSZWQnKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LXJpZ2h0LWJvbGQnOiBfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKF9Jc0NlbGxUeXBlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdudW1iZXInKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+IHt7IEdldE51bWVyaWNGb3JtYXQocm93W2hlYWRlci5jb2x1bW5OYW1lXSkgfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnZGF0ZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj4ge3sgR2V0RGF0ZUZvcm1hdChyb3dbaGVhZGVyLmNvbHVtbk5hbWVdKSB9fSA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPiB7eyBfR2V0Q2VsbFZhbHVlKHJvdywgaGVhZGVyLmNvbHVtbk5hbWUpIH19IDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0RlbGV0ZUJ1dHRvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImFjdGlvbi1idXR0b25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0RlbGV0ZUJ1dHRvbicsIHJvdykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImljb24tbm8tYm9yZGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cImRlbGV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwXT1cIl9HZXRUb29sdGlwKCdEZWxldGUnLCByb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52aXNpYmxlXT1cIl9pc0Rpc2FibGVkKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwib25DbGlja0RlbGV0ZVJvdy5lbWl0KHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IEJ1dHRvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dFZGl0QnV0dG9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYWN0aW9uLWJ1dHRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKEJ1dHRvbkJ5Um93KCdzaG93RWRpdEJ1dHRvbicsIHJvdykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImljb24tbm8tYm9yZGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cImVkaXRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcF09XCJfR2V0VG9vbHRpcCgnRWRpdCcsIHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNJbnZpc2libGVdPVwiX2lzRGlzYWJsZWQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGljayk9XCJvbkNsaWNrRWRpdFJvdy5lbWl0KHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBHTyBCdXR0b24gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKEJ1dHRvbkJ5Um93KCdzaG93R29CdXR0b24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhY3Rpb24tYnV0dG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dHb0J1dHRvbicsIHJvdykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImljb24tbm8tYm9yZGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cImdvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiX0dldFRvb2x0aXAoJ0dvIHRvJywgcm93LCAnZGV0YWlsJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNJbnZpc2libGVdPVwiX2lzRGlzYWJsZWQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DbGljayk9XCJvbkNsaWNrRWRpdFJvdy5lbWl0KHJvdylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2NvZXItYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9zZWN0aW9uPlxyXG5cclxuICAgIEBpZihzaG93Rm9vdGVyKCkpIHtcclxuICAgICAgICA8Zm9vdGVyIGNsYXNzPVwiZ3JpZC1mb290ZXJcIj5cclxuICAgICAgICAgICAgPHNwYW4+XHJcbiAgICAgICAgICAgICAgICBAaWYoX2lzTG9hZGluZ01lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZhLWZhZGVcIj4gTG9hZGluZyA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgQGVsc2UgaWYoZ3JpZExlbmd0aCgpLmRhdGFTb3VyY2VTZWxlY3RlZCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jaGVjazItc3F1YXJlIG1zLTFcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGdyaWRMZW5ndGgoKS5kYXRhU291cmNlU2VsZWN0ZWQgfX1cclxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvc3Bhbj5cclxuXHJcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWUtMVwiPiB7eyBncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZUZpbHRlcmVkIHwgbnVtZXJpY0Zvcm1hdCB9fSBSb3dzIDwvc3Bhbj5cclxuICAgICAgICA8L2Zvb3Rlcj5cclxuICAgIH1cclxuPC9kaXY+Il19