coer-elements 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. package/components/index.d.ts +5 -0
  2. package/components/lib/coer-button/coer-button.component.d.ts +44 -0
  3. package/components/lib/coer-checkbox/coer-checkbox.component.d.ts +28 -0
  4. package/components/lib/coer-filebox/coer-filebox.component.d.ts +33 -0
  5. package/components/lib/coer-form/coer-form.component.d.ts +33 -0
  6. package/components/lib/coer-grid/coer-grid.component.d.ts +53 -0
  7. package/components/lib/coer-grid/coer-grid.extension.d.ts +103 -0
  8. package/components/lib/coer-grid/coer-grid.templates.d.ts +9 -0
  9. package/components/lib/coer-modal/coer-modal.component.d.ts +38 -0
  10. package/components/lib/coer-numberbox/coer-numberbox.component.d.ts +55 -0
  11. package/components/lib/coer-page-title/coer-page-title.component.d.ts +12 -0
  12. package/components/lib/coer-selectbox/coer-selectbox.component.d.ts +75 -0
  13. package/components/lib/coer-switch/coer-switch.component.d.ts +31 -0
  14. package/components/lib/coer-tab/coer-tab.component.d.ts +35 -0
  15. package/components/lib/coer-textarea/coer-textarea.component.d.ts +51 -0
  16. package/components/lib/coer-textbox/coer-textbox.component.d.ts +57 -0
  17. package/components/lib/components.module.d.ts +30 -0
  18. package/components/public-api.d.ts +15 -0
  19. package/directives/index.d.ts +5 -0
  20. package/directives/lib/coer-ref.directive.d.ts +14 -0
  21. package/directives/lib/directives.module.d.ts +8 -0
  22. package/directives/lib/life-cycle.directive.d.ts +16 -0
  23. package/directives/public-api.d.ts +3 -0
  24. package/esm2022/components/coer-elements-components.mjs +5 -0
  25. package/esm2022/components/lib/coer-button/coer-button.component.mjs +133 -0
  26. package/esm2022/components/lib/coer-checkbox/coer-checkbox.component.mjs +83 -0
  27. package/esm2022/components/lib/coer-filebox/coer-filebox.component.mjs +102 -0
  28. package/esm2022/components/lib/coer-form/coer-form.component.mjs +101 -0
  29. package/esm2022/components/lib/coer-grid/coer-grid.component.mjs +512 -0
  30. package/esm2022/components/lib/coer-grid/coer-grid.extension.mjs +408 -0
  31. package/esm2022/components/lib/coer-grid/coer-grid.templates.mjs +30 -0
  32. package/esm2022/components/lib/coer-modal/coer-modal.component.mjs +107 -0
  33. package/esm2022/components/lib/coer-numberbox/coer-numberbox.component.mjs +258 -0
  34. package/esm2022/components/lib/coer-page-title/coer-page-title.component.mjs +44 -0
  35. package/esm2022/components/lib/coer-selectbox/coer-selectbox.component.mjs +338 -0
  36. package/esm2022/components/lib/coer-switch/coer-switch.component.mjs +93 -0
  37. package/esm2022/components/lib/coer-tab/coer-tab.component.mjs +116 -0
  38. package/esm2022/components/lib/coer-textarea/coer-textarea.component.mjs +156 -0
  39. package/esm2022/components/lib/coer-textbox/coer-textbox.component.mjs +195 -0
  40. package/esm2022/components/lib/components.module.mjs +129 -0
  41. package/esm2022/components/public-api.mjs +16 -0
  42. package/esm2022/directives/coer-elements-directives.mjs +5 -0
  43. package/esm2022/directives/lib/coer-ref.directive.mjs +23 -0
  44. package/esm2022/directives/lib/directives.module.mjs +25 -0
  45. package/esm2022/directives/lib/life-cycle.directive.mjs +33 -0
  46. package/esm2022/directives/public-api.mjs +4 -0
  47. package/esm2022/interfaces/coer-elements-interfaces.mjs +5 -0
  48. package/esm2022/interfaces/lib/app-source.interface.mjs +2 -0
  49. package/esm2022/interfaces/lib/coer-filebox/file-image.interface.mjs +2 -0
  50. package/esm2022/interfaces/lib/coer-filebox/file.interface.mjs +2 -0
  51. package/esm2022/interfaces/lib/coer-grid/grid-button-by-row.interface.mjs +2 -0
  52. package/esm2022/interfaces/lib/coer-grid/grid-checkbox.interface.mjs +2 -0
  53. package/esm2022/interfaces/lib/coer-grid/grid-coer-numberbox.interface.mjs +2 -0
  54. package/esm2022/interfaces/lib/coer-grid/grid-coer-selectbox.interface.mjs +2 -0
  55. package/esm2022/interfaces/lib/coer-grid/grid-coer-switch.interface.mjs +2 -0
  56. package/esm2022/interfaces/lib/coer-grid/grid-coer-textbox.interface.mjs +2 -0
  57. package/esm2022/interfaces/lib/coer-grid/grid-column.interface.mjs +2 -0
  58. package/esm2022/interfaces/lib/coer-grid/grid-data-source.interface.mjs +2 -0
  59. package/esm2022/interfaces/lib/coer-grid/grid-header-button.interface.mjs +2 -0
  60. package/esm2022/interfaces/lib/coer-grid/grid-header-export-button.interface.mjs +2 -0
  61. package/esm2022/interfaces/lib/coer-grid/grid-header.interface.mjs +2 -0
  62. package/esm2022/interfaces/lib/coer-grid/grid-import.interface.mjs +2 -0
  63. package/esm2022/interfaces/lib/coer-grid/grid-input-checkbox.interface.mjs +2 -0
  64. package/esm2022/interfaces/lib/coer-grid/grid-input-switch-change.interface.mjs +2 -0
  65. package/esm2022/interfaces/lib/coer-grid/grid-input-textbox.interface.mjs +2 -0
  66. package/esm2022/interfaces/lib/coer-grid/grid-item.interface.mjs +2 -0
  67. package/esm2022/interfaces/lib/coer-grid/grid-keyup-enter.interface.mjs +2 -0
  68. package/esm2022/interfaces/lib/coer-grid/grid-length.interface.mjs +2 -0
  69. package/esm2022/interfaces/lib/coer-grid/grid-search.interface.mjs +2 -0
  70. package/esm2022/interfaces/lib/coer-grid/grid-sort.interface.mjs +2 -0
  71. package/esm2022/interfaces/lib/coer-menu/menu-option-selected.interface.mjs +2 -0
  72. package/esm2022/interfaces/lib/coer-menu/menu-selected.interface.mjs +2 -0
  73. package/esm2022/interfaces/lib/coer-menu/menu.interface.mjs +2 -0
  74. package/esm2022/interfaces/lib/coer-ref.interface.mjs +2 -0
  75. package/esm2022/interfaces/lib/page-title/breadcrumb.interface.mjs +2 -0
  76. package/esm2022/interfaces/lib/page-title/go-back.interface.mjs +2 -0
  77. package/esm2022/interfaces/lib/screen-size.interface.mjs +2 -0
  78. package/esm2022/interfaces/lib/service/http-request.interface.mjs +2 -0
  79. package/esm2022/interfaces/lib/service/http-response.interface.mjs +2 -0
  80. package/esm2022/interfaces/lib/service/patch.interface.mjs +2 -0
  81. package/esm2022/interfaces/public-api.mjs +39 -0
  82. package/esm2022/pipes/coer-elements-pipes.mjs +5 -0
  83. package/esm2022/pipes/lib/html.pipe.mjs +18 -0
  84. package/esm2022/pipes/lib/no-image.pipe.mjs +23 -0
  85. package/esm2022/pipes/lib/numeric-format.pipe.mjs +15 -0
  86. package/esm2022/pipes/lib/pipes.module.mjs +31 -0
  87. package/esm2022/pipes/public-api.mjs +5 -0
  88. package/esm2022/signals/coer-elements-signals.mjs +5 -0
  89. package/esm2022/signals/lib/breakpoint.signal.mjs +4 -0
  90. package/esm2022/signals/lib/is-loading.signal.mjs +3 -0
  91. package/esm2022/signals/lib/is-menu-open.signal.mjs +3 -0
  92. package/esm2022/signals/lib/is-modal-open.signal.mjs +3 -0
  93. package/esm2022/signals/lib/menu.signal.mjs +3 -0
  94. package/esm2022/signals/public-api.mjs +6 -0
  95. package/esm2022/tools/coer-elements-tools.mjs +5 -0
  96. package/esm2022/tools/lib/breadcrumbs.class.mjs +63 -0
  97. package/esm2022/tools/lib/coer-alert/coer-alert.component.mjs +228 -0
  98. package/esm2022/tools/lib/control-value.class.mjs +46 -0
  99. package/esm2022/tools/lib/date-time.class.mjs +29 -0
  100. package/esm2022/tools/lib/files.class.mjs +91 -0
  101. package/esm2022/tools/lib/menu.class.mjs +23 -0
  102. package/esm2022/tools/lib/page.class.mjs +156 -0
  103. package/esm2022/tools/lib/screen.class.mjs +51 -0
  104. package/esm2022/tools/lib/service.class.mjs +247 -0
  105. package/esm2022/tools/lib/source.class.mjs +80 -0
  106. package/esm2022/tools/lib/tools.mjs +220 -0
  107. package/esm2022/tools/public-api.mjs +12 -0
  108. package/fesm2022/coer-elements-components.mjs +2718 -0
  109. package/fesm2022/coer-elements-components.mjs.map +1 -0
  110. package/fesm2022/coer-elements-directives.mjs +82 -0
  111. package/fesm2022/coer-elements-directives.mjs.map +1 -0
  112. package/fesm2022/coer-elements-interfaces.mjs +6 -0
  113. package/fesm2022/coer-elements-interfaces.mjs.map +1 -0
  114. package/fesm2022/coer-elements-pipes.mjs +83 -0
  115. package/fesm2022/coer-elements-pipes.mjs.map +1 -0
  116. package/fesm2022/coer-elements-signals.mjs +19 -0
  117. package/fesm2022/coer-elements-signals.mjs.map +1 -0
  118. package/fesm2022/coer-elements-tools.mjs +1223 -0
  119. package/fesm2022/coer-elements-tools.mjs.map +1 -0
  120. package/interfaces/index.d.ts +5 -0
  121. package/interfaces/lib/app-source.interface.d.ts +4 -0
  122. package/interfaces/lib/coer-filebox/file-image.interface.d.ts +14 -0
  123. package/interfaces/lib/coer-filebox/file.interface.d.ts +5 -0
  124. package/interfaces/lib/coer-grid/grid-button-by-row.interface.d.ts +6 -0
  125. package/interfaces/lib/coer-grid/grid-checkbox.interface.d.ts +5 -0
  126. package/interfaces/lib/coer-grid/grid-coer-numberbox.interface.d.ts +12 -0
  127. package/interfaces/lib/coer-grid/grid-coer-selectbox.interface.d.ts +9 -0
  128. package/interfaces/lib/coer-grid/grid-coer-switch.interface.d.ts +6 -0
  129. package/interfaces/lib/coer-grid/grid-coer-textbox.interface.d.ts +11 -0
  130. package/interfaces/lib/coer-grid/grid-column.interface.d.ts +22 -0
  131. package/interfaces/lib/coer-grid/grid-data-source.interface.d.ts +6 -0
  132. package/interfaces/lib/coer-grid/grid-header-button.interface.d.ts +8 -0
  133. package/interfaces/lib/coer-grid/grid-header-export-button.interface.d.ts +10 -0
  134. package/interfaces/lib/coer-grid/grid-header.interface.d.ts +5 -0
  135. package/interfaces/lib/coer-grid/grid-import.interface.d.ts +4 -0
  136. package/interfaces/lib/coer-grid/grid-input-checkbox.interface.d.ts +5 -0
  137. package/interfaces/lib/coer-grid/grid-input-switch-change.interface.d.ts +5 -0
  138. package/interfaces/lib/coer-grid/grid-input-textbox.interface.d.ts +5 -0
  139. package/interfaces/lib/coer-grid/grid-item.interface.d.ts +5 -0
  140. package/interfaces/lib/coer-grid/grid-keyup-enter.interface.d.ts +6 -0
  141. package/interfaces/lib/coer-grid/grid-length.interface.d.ts +5 -0
  142. package/interfaces/lib/coer-grid/grid-search.interface.d.ts +4 -0
  143. package/interfaces/lib/coer-grid/grid-sort.interface.d.ts +5 -0
  144. package/interfaces/lib/coer-menu/menu-option-selected.interface.d.ts +9 -0
  145. package/interfaces/lib/coer-menu/menu-selected.interface.d.ts +10 -0
  146. package/interfaces/lib/coer-menu/menu.interface.d.ts +6 -0
  147. package/interfaces/lib/coer-ref.interface.d.ts +10 -0
  148. package/interfaces/lib/page-title/breadcrumb.interface.d.ts +6 -0
  149. package/interfaces/lib/page-title/go-back.interface.d.ts +6 -0
  150. package/interfaces/lib/screen-size.interface.d.ts +5 -0
  151. package/interfaces/lib/service/http-request.interface.d.ts +10 -0
  152. package/interfaces/lib/service/http-response.interface.d.ts +6 -0
  153. package/interfaces/lib/service/patch.interface.d.ts +5 -0
  154. package/interfaces/public-api.d.ts +33 -0
  155. package/package.json +37 -1
  156. package/pipes/index.d.ts +5 -0
  157. package/pipes/lib/html.pipe.d.ts +10 -0
  158. package/pipes/lib/no-image.pipe.d.ts +7 -0
  159. package/pipes/lib/numeric-format.pipe.d.ts +7 -0
  160. package/pipes/lib/pipes.module.d.ts +9 -0
  161. package/pipes/public-api.d.ts +4 -0
  162. package/signals/index.d.ts +5 -0
  163. package/signals/lib/breakpoint.signal.d.ts +1 -0
  164. package/signals/lib/is-loading.signal.d.ts +1 -0
  165. package/signals/lib/is-menu-open.signal.d.ts +1 -0
  166. package/signals/lib/is-modal-open.signal.d.ts +1 -0
  167. package/signals/lib/menu.signal.d.ts +2 -0
  168. package/signals/public-api.d.ts +5 -0
  169. package/tools/index.d.ts +5 -0
  170. package/tools/lib/breadcrumbs.class.d.ts +18 -0
  171. package/tools/lib/coer-alert/coer-alert.component.d.ts +23 -0
  172. package/tools/lib/control-value.class.d.ts +25 -0
  173. package/tools/lib/date-time.class.d.ts +13 -0
  174. package/tools/lib/files.class.d.ts +16 -0
  175. package/tools/lib/menu.class.d.ts +8 -0
  176. package/tools/lib/page.class.d.ts +60 -0
  177. package/tools/lib/screen.class.d.ts +13 -0
  178. package/tools/lib/service.class.d.ts +39 -0
  179. package/tools/lib/source.class.d.ts +20 -0
  180. package/tools/lib/tools.d.ts +34 -0
  181. package/tools/public-api.d.ts +11 -0
@@ -0,0 +1,512 @@
1
+ import { Component, computed } from '@angular/core';
2
+ import { CoerGridExtension } from './coer-grid.extension';
3
+ import { CONTROL_VALUE, Files, Tools } from 'coer-elements/tools';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ import * as i2 from "@angular/forms";
7
+ import * as i3 from "../coer-button/coer-button.component";
8
+ import * as i4 from "../coer-checkbox/coer-checkbox.component";
9
+ import * as i5 from "../coer-numberbox/coer-numberbox.component";
10
+ import * as i6 from "../coer-selectbox/coer-selectbox.component";
11
+ import * as i7 from "../coer-switch/coer-switch.component";
12
+ import * as i8 from "../coer-textbox/coer-textbox.component";
13
+ import * as i9 from "coer-elements/pipes";
14
+ export class CoerGrid extends CoerGridExtension {
15
+ constructor() {
16
+ super(...arguments);
17
+ //computed
18
+ this.dataSource = computed(() => {
19
+ return Tools.BreakReference(this.value_signal()).map(item => {
20
+ if (item.hasOwnProperty('checked'))
21
+ delete item.checked;
22
+ if (item.hasOwnProperty('indexRow'))
23
+ delete item.indexRow;
24
+ return item;
25
+ });
26
+ });
27
+ //computed
28
+ this.selectedItems = computed(() => {
29
+ return Tools.BreakReference(this.value_signal()).filter(item => item.checked).map(item => {
30
+ if (item.hasOwnProperty('checked'))
31
+ delete item.checked;
32
+ if (item.hasOwnProperty('indexRow'))
33
+ delete item.indexRow;
34
+ return item;
35
+ });
36
+ });
37
+ //computed
38
+ this.gridLength = computed(() => {
39
+ return {
40
+ dataSource: this.value_signal()?.length || 0,
41
+ dataSourceFiltered: this.gridDataSourceFiltered()?.length || 0,
42
+ dataSourceSelected: this.selectedItems()?.length || 0
43
+ };
44
+ });
45
+ }
46
+ //getter
47
+ get isValid() {
48
+ return (this.coerTextboxList().length > 0 ? this.coerTextboxList().every(x => !x.isInvalid()) : true)
49
+ && (this.coerNumberboxList().length > 0 ? this.coerNumberboxList().every(x => !x.isInvalid()) : true)
50
+ && (this.coerSelectboxList().length > 0 ? this.coerSelectboxList().every(x => !x.isInvalid()) : true);
51
+ }
52
+ //computed
53
+ //protected _columnsFiltered = computed<IGridHeader[]>(() => {
54
+ // return this.isGrouped() && !this.showColumnGrouped
55
+ // ? this._columns().filter(x => x.columnName.toUpperCase() != this.groupBy.toUpperCase())
56
+ // : this._columns();
57
+ //});
58
+ /** */
59
+ FocusSearch() {
60
+ Tools.Sleep(0).then(() => {
61
+ if (this.inputSearch)
62
+ this.inputSearch().Focus();
63
+ });
64
+ }
65
+ /** */
66
+ SelectSearch() {
67
+ Tools.Sleep(0).then(() => {
68
+ if (this.inputSearch)
69
+ this.inputSearch().Select();
70
+ });
71
+ }
72
+ /** */
73
+ GetRowBy(callback) {
74
+ const row = this._value.find(callback);
75
+ return (row === undefined) ? null : row;
76
+ }
77
+ /** */
78
+ async Import(event = null) {
79
+ if (this.importButton?.preventDefault) {
80
+ this.onClickImport.emit({ data: [], file: null });
81
+ return;
82
+ }
83
+ if (event === null) {
84
+ this.inputFile().nativeElement.value = null;
85
+ this.inputFile().nativeElement.click();
86
+ return;
87
+ }
88
+ else if (event.target.files.length > 0) {
89
+ this._isLoading = true;
90
+ const [selectedFile] = event.target.files;
91
+ if (Files.IsExcel(selectedFile)) {
92
+ const { rows } = await Files.ReadExcel(selectedFile);
93
+ if (Tools.IsNull(this.importButton?.Autofill) || this.importButton.Autofill) {
94
+ this.SetValue(rows.concat(this._value));
95
+ this.onClickImport.emit({ data: this._value, file: selectedFile });
96
+ }
97
+ else {
98
+ this.onClickImport.emit({ data: rows, file: selectedFile });
99
+ }
100
+ }
101
+ else {
102
+ let message = 'Allowed extensions:';
103
+ for (const extension of Files.EXCEL_EXTENSIONS) {
104
+ message += ` <b>${extension}</b>,`;
105
+ }
106
+ message = message.substring(0, message.length - 1);
107
+ this.alert.Warning(message, 'Invalid File Type', 'bi bi-filetype-xlsx fa-lg');
108
+ this.onClickImport.emit({ data: [], file: null });
109
+ }
110
+ this.inputFile().nativeElement.value = null;
111
+ Tools.Sleep(1000).then(() => this._isLoading = false);
112
+ }
113
+ }
114
+ /** */
115
+ Export(exportFile = true) {
116
+ let item = {};
117
+ this._isLoading = true;
118
+ const FILE_NAME = (this.exportButton?.fileName || 'COER Report') + '.xlsx';
119
+ let ROW_DATA_SOURCE = (this.exportButton.hasOwnProperty('onlyRowFiltered') && !this.exportButton.onlyRowFiltered)
120
+ ? this.value_signal() : this.gridDataSourceFiltered();
121
+ const COLUMN_DATA_SOURCE = new Set();
122
+ if (this.exportButton.hasOwnProperty('onlyColumnFiltered') && !this.exportButton.onlyColumnFiltered) {
123
+ for (const row of this.value_signal()) {
124
+ for (const columnName in row) {
125
+ if (columnName == 'indexRow')
126
+ continue;
127
+ COLUMN_DATA_SOURCE.add(Tools.FirstCharToLower(columnName));
128
+ }
129
+ }
130
+ }
131
+ else {
132
+ for (const { columnName } of this.gridColumns()) {
133
+ if (columnName == 'indexRow')
134
+ continue;
135
+ COLUMN_DATA_SOURCE.add(Tools.FirstCharToLower(columnName));
136
+ }
137
+ }
138
+ const EXPORT_DATA = [];
139
+ for (const row of ROW_DATA_SOURCE) {
140
+ for (const column of COLUMN_DATA_SOURCE) {
141
+ item = Object.assign(item, { [this._GetColumnName(column)]: row[column] });
142
+ }
143
+ EXPORT_DATA.push(item);
144
+ item = Tools.BreakReference({});
145
+ }
146
+ if (exportFile) {
147
+ Files.ExportExcel(EXPORT_DATA, FILE_NAME);
148
+ }
149
+ this.onClickExport.emit(EXPORT_DATA);
150
+ Tools.Sleep(3000).then(() => this._isLoading = false);
151
+ }
152
+ /** */
153
+ InputChange(indexRow, columnName, value, input) {
154
+ if (input === 'coer-textbox-search') {
155
+ if (this._isLoading)
156
+ return;
157
+ Tools.Sleep(0, `coerGridInputChange${columnName}`).then(async (_) => {
158
+ this._gridSearch.set(value);
159
+ if (this.checkbox.show) {
160
+ this._isLoadingMessage = true;
161
+ await Tools.Sleep();
162
+ for (const row of this._value.filter((x) => x.checked)) {
163
+ this.CheckBy((x) => x.indexRow == row.indexRow);
164
+ }
165
+ await Tools.Sleep();
166
+ this._isLoadingMessage = false;
167
+ }
168
+ });
169
+ return;
170
+ }
171
+ const property = Tools.FirstCharToLower(columnName);
172
+ const row = this._value[indexRow];
173
+ row[property] = value;
174
+ if (input === 'coer-switch') {
175
+ this.onSwitchChange.emit({ property, row: Tools.BreakReference(row), value });
176
+ }
177
+ else if (input === 'coer-textbox') {
178
+ this.onTextboxChange.emit({ property, row: Tools.BreakReference(row), value });
179
+ }
180
+ else if (input === 'coer-selectbox') {
181
+ this.onSelectboxChange.emit({ property, row: Tools.BreakReference(row), value });
182
+ }
183
+ else if (input === 'coer-numberbox') {
184
+ this.onTextboxChange.emit({ property, row: Tools.BreakReference(row), value });
185
+ }
186
+ Tools.Sleep(1000, `coerGridInputChange${indexRow}${columnName}`).then(_ => {
187
+ this._UpdateValue(this._value);
188
+ this.value_signal.set(this._value);
189
+ });
190
+ }
191
+ /** */
192
+ KeyupEnter(indexColumn, row, input, value) {
193
+ if (['coer-textbox', 'coer-numberbox', 'coer-selectbox'].includes(input)) {
194
+ this.onKeyupEnter.emit({
195
+ id: this._GetId(indexColumn, row.indexRow, input),
196
+ input, row: Tools.BreakReference(row), value
197
+ });
198
+ this.NextInput(indexColumn, row.indexRow);
199
+ }
200
+ else if (input == 'coer-textbox-search') {
201
+ this.onKeyupEnter.emit({
202
+ id: this._GetId(indexColumn, row.indexRow, input),
203
+ input, row: null, value
204
+ });
205
+ }
206
+ }
207
+ /** */
208
+ NextInput(indexColumn, indexRow) {
209
+ const INPUT_TEXT = this.columns().filter(x => Tools.IsNotNull(x.coerTextbox)).map(x => x.property);
210
+ const INPUT_NUMBER = this.columns().filter(x => Tools.IsNotNull(x.coerNumberbox)).map(x => x.property);
211
+ const INPUT_SELECT = this.columns().filter(x => Tools.IsNotNull(x.coerSelectbox)).map(x => x.property);
212
+ let index = 0;
213
+ const COLUMNS = [];
214
+ const INPUT_COLUMNS = [];
215
+ for (const { columnName } of this.gridColumns()) {
216
+ if (INPUT_TEXT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
217
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
218
+ INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
219
+ }
220
+ else if (INPUT_NUMBER.some(property => property.toUpperCase() == columnName.toUpperCase())) {
221
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
222
+ INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
223
+ }
224
+ else if (INPUT_SELECT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
225
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
226
+ INPUT_COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
227
+ }
228
+ else {
229
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'default-cell' });
230
+ }
231
+ ++index;
232
+ }
233
+ let lastRow = -1;
234
+ for (const { rows } of this.gridDataSource()) {
235
+ lastRow += rows.length;
236
+ }
237
+ let firstColumn = -1;
238
+ if (INPUT_COLUMNS.length > 0) {
239
+ firstColumn = [...INPUT_COLUMNS].shift().indexColumn;
240
+ }
241
+ let lastColumn = -1;
242
+ if (INPUT_COLUMNS.length > 0) {
243
+ lastColumn = [...INPUT_COLUMNS].pop().indexColumn;
244
+ }
245
+ //Is Last Row & Last Input Column?
246
+ if (indexRow == lastRow && indexColumn == lastColumn) {
247
+ this.onKeyupEnterLast.emit();
248
+ }
249
+ //Is Last Input Column?
250
+ else if (indexColumn == lastColumn) {
251
+ this.FocusInput((indexRow + 1), firstColumn);
252
+ }
253
+ //Next Column?
254
+ else {
255
+ for (index = (indexColumn + 1); index < COLUMNS.length; index++) {
256
+ for (const input of COLUMNS) {
257
+ if (index == input.indexColumn && ['coerTextbox', 'coerNumberbox', 'coerSelectbox'].includes(input.type)) {
258
+ this.FocusInput(indexRow, input.indexColumn);
259
+ return;
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ /** */
266
+ FocusInput(indexRow = -1, indexColumn = -1) {
267
+ Tools.Sleep(0, 'FocusInput').then(() => {
268
+ if (this._isDisabled())
269
+ return;
270
+ if (indexRow < 0 || indexColumn < 0) {
271
+ const INPUT_TEXT = this.columns().filter(x => Tools.IsNotNull(x.coerTextbox)).map(x => x.property);
272
+ const INPUT_NUMBER = this.columns().filter(x => Tools.IsNotNull(x.coerNumberbox)).map(x => x.property);
273
+ const INPUT_SELECT = this.columns().filter(x => Tools.IsNotNull(x.coerSelectbox)).map(x => x.property);
274
+ let index = 0;
275
+ const COLUMNS = [];
276
+ for (const { columnName } of this.gridColumns()) {
277
+ if (INPUT_TEXT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
278
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerTextbox' });
279
+ }
280
+ else if (INPUT_NUMBER.some(property => property.toUpperCase() == columnName.toUpperCase())) {
281
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerNumberbox' });
282
+ }
283
+ else if (INPUT_SELECT.some(property => property.toUpperCase() == columnName.toUpperCase())) {
284
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'coerSelectbox' });
285
+ }
286
+ else {
287
+ COLUMNS.push({ indexColumn: index, property: columnName, type: 'default-cell' });
288
+ }
289
+ ++index;
290
+ }
291
+ if (this.gridLength().dataSourceFiltered > 0) {
292
+ const FIRST_INPUT_COLUMN = COLUMNS.find(x => ['coerTextbox', 'coerNumberbox', 'coerSelectbox'].includes(x.type));
293
+ if (Tools.IsNotNull(FIRST_INPUT_COLUMN)) {
294
+ this.FocusInput(0, FIRST_INPUT_COLUMN.indexColumn);
295
+ }
296
+ }
297
+ }
298
+ else {
299
+ const id = this._GetId(indexRow, indexColumn);
300
+ let element;
301
+ this._indexFocus.set(indexRow);
302
+ //Focus Textbox
303
+ element = this.coerTextboxList().find(x => x.id == id);
304
+ if (element) {
305
+ element.Select();
306
+ return;
307
+ }
308
+ //Focus Numberbox
309
+ element = this.coerNumberboxList().find(x => x.id == id);
310
+ if (element) {
311
+ element.Select();
312
+ return;
313
+ }
314
+ //Focus Selectbox
315
+ element = this.coerSelectboxList().find(x => x.id == id);
316
+ if (element) {
317
+ Tools.Sleep(100).then(_ => element.Focus());
318
+ return;
319
+ }
320
+ }
321
+ });
322
+ }
323
+ /** */
324
+ FocusRow(callback) {
325
+ Tools.Sleep().then(_ => {
326
+ if (this._value.length > 0) {
327
+ const row = Tools.BreakReference(this._value.find(callback));
328
+ if (Tools.IsNotNull(row))
329
+ this._indexFocus.set(row.indexRow);
330
+ }
331
+ });
332
+ }
333
+ /** */
334
+ async Sort(columnName) {
335
+ if (this.enableSort()) {
336
+ if (this._isLoading)
337
+ return;
338
+ this._isLoading = true;
339
+ this._isLoadingMessage = true;
340
+ const { direction } = this._sort();
341
+ let dataSource = Tools.BreakReference(this._value);
342
+ for (const checkbox of this.coerCheckboxList())
343
+ checkbox.Uncheck();
344
+ if (direction == 'descendant') {
345
+ Tools.SortByDesc(dataSource, columnName);
346
+ this._sort.set({ columnName, direction: 'ascendant', icon: 'fa-solid fa-arrow-down-short-wide' });
347
+ }
348
+ else {
349
+ Tools.SortBy(dataSource, columnName);
350
+ this._sort.set({ columnName, direction: 'descendant', icon: 'fa-solid fa-arrow-up-wide-short' });
351
+ }
352
+ let indexRow = 0;
353
+ dataSource = Tools.BreakReference(dataSource).map((item) => Object.assign(item, { indexRow: indexRow++ }));
354
+ this.SetValue(dataSource);
355
+ this._isLoading = false;
356
+ await Tools.Sleep();
357
+ for (const row of dataSource.filter((x) => x.checked)) {
358
+ this.CheckBy((x) => x.indexRow == row.indexRow);
359
+ }
360
+ this._isLoadingMessage = false;
361
+ }
362
+ return;
363
+ }
364
+ /** */
365
+ ClickCheck(id, checked, all, row = null) {
366
+ if (!this._isLoading)
367
+ Tools.Sleep().then(async (_) => {
368
+ this._isLoading = true;
369
+ let element = this.coerCheckboxList().find(x => x.id() == id);
370
+ if (Tools.IsNotNull(element)) {
371
+ let response = { all, checked, rows: [] };
372
+ //All Checkbox
373
+ if (all) {
374
+ if (checked)
375
+ this.CheckAll();
376
+ else
377
+ this.UncheckAll();
378
+ //Event
379
+ response.rows = this.selectedItems();
380
+ this.onCheckboxChange.emit(response);
381
+ }
382
+ //One Checkbox
383
+ else {
384
+ if (this._onlyOneCheck) {
385
+ for (const row of this._value) {
386
+ row.checked = false;
387
+ }
388
+ for (const checkbox of this.coerCheckboxList()) {
389
+ if (checkbox.id() != id)
390
+ checkbox.Uncheck();
391
+ }
392
+ }
393
+ this._value[row.indexRow].checked = checked;
394
+ this.SetValue(this._value);
395
+ //Mark All checkbox
396
+ const checkboxAll = this.coerCheckboxList().find(x => x.id() == this._GetId(0, 0, 'checkboxAll'));
397
+ if (this.value_signal().every((x) => x.checked)) {
398
+ checkboxAll?.Check();
399
+ }
400
+ else {
401
+ checkboxAll?.Uncheck();
402
+ }
403
+ //Event
404
+ response.rows = [{ ...row }];
405
+ this.onCheckboxChange.emit(response);
406
+ this._isLoading = false;
407
+ }
408
+ }
409
+ });
410
+ }
411
+ /** */
412
+ CheckAll() {
413
+ this._isLoading = true;
414
+ for (const row of this._value) {
415
+ row.checked = true;
416
+ }
417
+ this.SetValue(this._value);
418
+ for (const checkbox of this.coerCheckboxList()) {
419
+ checkbox.Check();
420
+ }
421
+ this._isLoading = false;
422
+ }
423
+ /** */
424
+ UncheckAll() {
425
+ this._isLoading = true;
426
+ for (const row of this._value) {
427
+ row.checked = false;
428
+ }
429
+ this.SetValue(this._value);
430
+ for (const checkbox of this.coerCheckboxList()) {
431
+ checkbox.Uncheck();
432
+ }
433
+ this._isLoading = false;
434
+ }
435
+ /** */
436
+ CheckBy(callback) {
437
+ Tools.Sleep().then(_ => {
438
+ if (this._value.length > 0) {
439
+ const rowList = Tools.BreakReference(this._value.filter(callback));
440
+ let element;
441
+ for (const { indexRow } of rowList) {
442
+ element = this.coerCheckboxList().find(x => x.id() == this._GetId(indexRow, 0, 'checkbox'));
443
+ if (Tools.IsNotNull(element)) {
444
+ element?.Check();
445
+ }
446
+ }
447
+ }
448
+ });
449
+ }
450
+ /** */
451
+ UncheckBy(callback) {
452
+ Tools.Sleep().then(_ => {
453
+ if (this._value.length > 0) {
454
+ const rowList = Tools.BreakReference(this._value.filter(callback));
455
+ let element;
456
+ for (const { indexRow } of rowList) {
457
+ element = this.coerCheckboxList().find(x => x.id() == this._GetId(indexRow, 0, 'checkbox'));
458
+ if (Tools.IsNotNull(element)) {
459
+ element?.Uncheck();
460
+ }
461
+ }
462
+ }
463
+ });
464
+ }
465
+ /** */
466
+ ClickOnRow(row) {
467
+ if (this._isDisabled())
468
+ return;
469
+ if (Tools.IsNotNull(this.checkbox.checkOnRow) && this.checkbox.checkOnRow) {
470
+ this.CheckBy((x) => x.indexRow == row.indexRow);
471
+ }
472
+ this.onClickRow.emit(row);
473
+ }
474
+ /** Inserts new elements at the start */
475
+ Unshift(row) {
476
+ const dataSource = Tools.BreakReference(this._value);
477
+ dataSource.unshift(row);
478
+ this.SetValue(dataSource);
479
+ this.FocusInput();
480
+ }
481
+ /** Appends new elements to the end */
482
+ Push(row) {
483
+ const dataSource = Tools.BreakReference(this._value);
484
+ dataSource.push(row);
485
+ this.SetValue(dataSource);
486
+ this.FocusInput();
487
+ }
488
+ /** Delete Row By index */
489
+ async DeleteRow(indexRow) {
490
+ const dataSource = Tools.BreakReference(this._value);
491
+ dataSource.splice(indexRow, 1);
492
+ this.SetValue(dataSource);
493
+ }
494
+ /** Delete row list by callback */
495
+ async DeleteRowsBy(callback) {
496
+ const indexList = Tools.BreakReference(this._value.filter(callback).map((item) => item.indexRow));
497
+ let dataSource = [];
498
+ for (const indexRow of indexList) {
499
+ dataSource = Tools.BreakReference(this._value);
500
+ dataSource.splice(indexRow, 1);
501
+ this.SetValue(dataSource);
502
+ await Tools.Sleep();
503
+ }
504
+ }
505
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CoerGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
506
+ 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: i9.NumericFormatPipe, name: "numericFormat" }] }); }
507
+ }
508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CoerGrid, decorators: [{
509
+ type: Component,
510
+ 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"] }]
511
+ }] });
512
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29lci1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvZXItZWxlbWVudHMvY29tcG9uZW50cy9saWIvY29lci1ncmlkL2NvZXItZ3JpZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb2VyLWVsZW1lbnRzL2NvbXBvbmVudHMvbGliL2NvZXItZ3JpZC9jb2VyLWdyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDcEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFNMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7Ozs7Ozs7O0FBU2xFLE1BQU0sT0FBTyxRQUFZLFNBQVEsaUJBQW9CO0lBTnJEOztRQVFJLFVBQVU7UUFDSCxlQUFVLEdBQUcsUUFBUSxDQUFNLEdBQUcsRUFBRTtZQUNuQyxPQUFPLEtBQUssQ0FBQyxjQUFjLENBQVEsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMvRCxJQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDO29CQUFFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDdkQsSUFBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztvQkFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ3pELE9BQU8sSUFBSSxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7UUFHSCxVQUFVO1FBQ0gsa0JBQWEsR0FBRyxRQUFRLENBQU0sR0FBRyxFQUFFO1lBQ3RDLE9BQU8sS0FBSyxDQUFDLGNBQWMs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QUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFHRCxrQ0FBa0M7SUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUE2QjtRQUNuRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFeEgsSUFBSSxVQUFVLEdBQVUsRUFBRSxDQUFDO1FBQzNCLEtBQUksTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDOUIsVUFBVSxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUIsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsQ0FBQztJQUNMLENBQUM7K0dBbG1CUSxRQUFRO21HQUFSLFFBQVEsb0NBRk4sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsaURDZHhDLDA0dkJBNFhNOzs0RkQ1V08sUUFBUTtrQkFOcEIsU0FBUzsrQkFDSSxXQUFXLGFBR1YsQ0FBQyxhQUFhLFVBQVUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29lckdyaWRFeHRlbnNpb24gfSBmcm9tICcuL2NvZXItZ3JpZC5leHRlbnNpb24nO1xyXG5pbXBvcnQgeyBDb2VyQ2hlY2tib3ggfSBmcm9tICcuLi8uLi9saWIvY29lci1jaGVja2JveC9jb2VyLWNoZWNrYm94LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvZXJUZXh0Qm94IH0gZnJvbSAnLi4vLi4vbGliL2NvZXItdGV4dGJveC9jb2VyLXRleHRib3guY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29lck51bWJlckJveCB9IGZyb20gJy4uLy4uL2xpYi9jb2VyLW51bWJlcmJveC9jb2VyLW51bWJlcmJveC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb2VyU2VsZWN0Ym94IH0gZnJvbSAnLi4vLi4vbGliL2NvZXItc2VsZWN0Ym94L2NvZXItc2VsZWN0Ym94LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IElHcmlkTGVuZ3RoLCBJR3JpZElucHV0Q2hlY2tib3ggfSBmcm9tICdjb2VyLWVsZW1lbnRzL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQgeyBDT05UUk9MX1ZBTFVFLCBGaWxlcywgVG9vbHMgfSBmcm9tICdjb2VyLWVsZW1lbnRzL3Rvb2xzJztcclxuXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnY29lci1ncmlkJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9jb2VyLWdyaWQuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmw6ICcuL2NvZXItZ3JpZC5jb21wb25lbnQuc2NzcycsXHJcbiAgICBwcm92aWRlcnM6IFtDT05UUk9MX1ZBTFVFKENvZXJHcmlkKV0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb2VyR3JpZDxUPiBleHRlbmRzIENvZXJHcmlkRXh0ZW5zaW9uPFQ+IHtcclxuXHJcbiAgICAvL2NvbXB1dGVkXHJcbiAgICBwdWJsaWMgZGF0YVNvdXJjZSA9IGNvbXB1dGVkPFRbXT4oKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiBUb29scy5CcmVha1JlZmVyZW5jZTxhbnlbXT4odGhpcy52YWx1ZV9zaWduYWwoKSkubWFwKGl0ZW0gPT4ge1xyXG4gICAgICAgICAgICBpZihpdGVtLmhhc093blByb3BlcnR5KCdjaGVja2VkJykpIGRlbGV0ZSBpdGVtLmNoZWNrZWQ7XHJcbiAgICAgICAgICAgIGlmKGl0ZW0uaGFzT3duUHJvcGVydHkoJ2luZGV4Um93JykpIGRlbGV0ZSBpdGVtLmluZGV4Um93O1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuXHJcbiAgICAvL2NvbXB1dGVkXHJcbiAgICBwdWJsaWMgc2VsZWN0ZWRJdGVtcyA9IGNvbXB1dGVkPFRbXT4oKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiBUb29scy5CcmVha1JlZmVyZW5jZTxhbnlbXT4odGhpcy52YWx1ZV9zaWduYWwoKSkuZmlsdGVyKGl0ZW0gPT4gaXRlbS5jaGVja2VkKS5tYXAoaXRlbSA9PiB7XHJcbiAgICAgICAgICAgIGlmKGl0ZW0uaGFzT3duUHJvcGVydHkoJ2NoZWNrZWQnKSkgZGVsZXRlIGl0ZW0uY2hlY2tlZDtcclxuICAgICAgICAgICAgaWYoaXRlbS5oYXNPd25Qcm9wZXJ0eSgnaW5kZXhSb3cnKSkgZGVsZXRlIGl0ZW0uaW5kZXhSb3c7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG5cclxuICAgIC8vZ2V0dGVyXHJcbiAgICBwdWJsaWMgZ2V0IGlzVmFsaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmNvZXJUZXh0Ym94TGlzdCgpLmxlbmd0aCA+IDAgPyB0aGlzLmNvZXJUZXh0Ym94TGlzdCgpLmV2ZXJ5KHggPT4gIXguaXNJbnZhbGlkKCkpIDogdHJ1ZSlcclxuICAgICAgICAgICAgJiYgKHRoaXMuY29lck51bWJlcmJveExpc3QoKS5sZW5ndGggPiAwID8gdGhpcy5jb2VyTnVtYmVyYm94TGlzdCgpLmV2ZXJ5KHggPT4gIXguaXNJbnZhbGlkKCkpIDogdHJ1ZSlcclxuICAgICAgICAgICAgJiYgKHRoaXMuY29lclNlbGVjdGJveExpc3QoKS5sZW5ndGggPiAwID8gdGhpcy5jb2VyU2VsZWN0Ym94TGlzdCgpLmV2ZXJ5KHggPT4gIXguaXNJbnZhbGlkKCkpIDogdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vY29tcHV0ZWRcclxuICAgIHByb3RlY3RlZCBncmlkTGVuZ3RoID0gY29tcHV0ZWQ8SUdyaWRMZW5ndGg+KCgpID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkYXRhU291cmNlOiB0aGlzLnZhbHVlX3NpZ25hbCgpPy5sZW5ndGggfHwgMCxcclxuICAgICAgICAgICAgZGF0YVNvdXJjZUZpbHRlcmVkOiB0aGlzLmdyaWREYXRhU291cmNlRmlsdGVyZWQoKT8ubGVuZ3RoIHx8IDAsXHJcbiAgICAgICAgICAgIGRhdGFTb3VyY2VTZWxlY3RlZDogdGhpcy5zZWxlY3RlZEl0ZW1zKCk/Lmxlbmd0aCB8fCAwXHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG5cclxuXHJcblxyXG4gICAgLy9jb21wdXRlZFxyXG4gICAgLy9wcm90ZWN0ZWQgX2NvbHVtbnNGaWx0ZXJlZCA9IGNvbXB1dGVkPElHcmlkSGVhZGVyW10+KCgpID0+IHtcclxuICAgIC8vICAgIHJldHVybiB0aGlzLmlzR3JvdXBlZCgpICYmICF0aGlzLnNob3dDb2x1bW5Hcm91cGVkXHJcbiAgICAvLyAgICAgICAgPyB0aGlzLl9jb2x1bW5zKCkuZmlsdGVyKHggPT4geC5jb2x1bW5OYW1lLnRvVXBwZXJDYXNlKCkgIT0gdGhpcy5ncm91cEJ5LnRvVXBwZXJDYXNlKCkpXHJcbiAgICAvLyAgICAgICAgOiB0aGlzLl9jb2x1bW5zKCk7XHJcbiAgICAvL30pO1xyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBGb2N1c1NlYXJjaCgpOiB2b2lkIHtcclxuICAgICAgICBUb29scy5TbGVlcCgwKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgaWYodGhpcy5pbnB1dFNlYXJjaCkgdGhpcy5pbnB1dFNlYXJjaCgpLkZvY3VzKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIFNlbGVjdFNlYXJjaCgpOiB2b2lkIHtcclxuICAgICAgICBUb29scy5TbGVlcCgwKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgaWYodGhpcy5pbnB1dFNlYXJjaCkgdGhpcy5pbnB1dFNlYXJjaCgpLlNlbGVjdCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBHZXRSb3dCeTxUPihjYWxsYmFjazogKHJvdzogVCkgPT4gYm9vbGVhbik6IFQgfCBudWxsIHtcclxuICAgICAgICBjb25zdCByb3cgPSB0aGlzLl92YWx1ZS5maW5kKGNhbGxiYWNrIGFzIGFueSk7XHJcbiAgICAgICAgcmV0dXJuIChyb3cgPT09IHVuZGVmaW5lZCkgPyBudWxsIDogcm93IGFzIFQ7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIGFzeW5jIEltcG9ydChldmVudDogYW55ID0gbnVsbCkge1xyXG4gICAgICAgIGlmICh0aGlzLmltcG9ydEJ1dHRvbj8ucHJldmVudERlZmF1bHQpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkNsaWNrSW1wb3J0LmVtaXQoeyBkYXRhOiBbXSwgZmlsZTogbnVsbCB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGV2ZW50ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5wdXRGaWxlKCkubmF0aXZlRWxlbWVudC52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuaW5wdXRGaWxlKCkubmF0aXZlRWxlbWVudC5jbGljaygpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlIGlmIChldmVudC50YXJnZXQhLmZpbGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgY29uc3QgW3NlbGVjdGVkRmlsZV0gPSBldmVudC50YXJnZXQuZmlsZXMgYXMgRmlsZVtdO1xyXG5cclxuICAgICAgICAgICAgaWYoRmlsZXMuSXNFeGNlbChzZWxlY3RlZEZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IEZpbGVzLlJlYWRFeGNlbDxUPihzZWxlY3RlZEZpbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChUb29scy5Jc051bGwodGhpcy5pbXBvcnRCdXR0b24/LkF1dG9maWxsKSB8fCB0aGlzLmltcG9ydEJ1dHRvbi5BdXRvZmlsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuU2V0VmFsdWUocm93cy5jb25jYXQodGhpcy5fdmFsdWUpKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2xpY2tJbXBvcnQuZW1pdCh7IGRhdGE6IHRoaXMuX3ZhbHVlLCBmaWxlOiBzZWxlY3RlZEZpbGUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNsaWNrSW1wb3J0LmVtaXQoeyBkYXRhOiByb3dzLCBmaWxlOiBzZWxlY3RlZEZpbGUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSAnQWxsb3dlZCBleHRlbnNpb25zOic7XHJcbiAgICAgICAgICAgICAgICBmb3IoY29uc3QgZXh0ZW5zaW9uIG9mIEZpbGVzLkVYQ0VMX0VYVEVOU0lPTlMpIHtcclxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlICs9IGAgPGI+JHtleHRlbnNpb259PC9iPixgXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2Uuc3Vic3RyaW5nKDAsIG1lc3NhZ2UubGVuZ3RoIC0gMSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0Lldhcm5pbmcobWVzc2FnZSwgJ0ludmFsaWQgRmlsZSBUeXBlJywgJ2JpIGJpLWZpbGV0eXBlLXhsc3ggZmEtbGcnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMub25DbGlja0ltcG9ydC5lbWl0KHsgZGF0YTogW10sIGZpbGU6IG51bGwgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuaW5wdXRGaWxlKCkubmF0aXZlRWxlbWVudC52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgICAgIFRvb2xzLlNsZWVwKDEwMDApLnRoZW4oKCkgPT4gdGhpcy5faXNMb2FkaW5nID0gZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgRXhwb3J0KGV4cG9ydEZpbGU6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSB0cnVlKTogdm9pZCB7XHJcbiAgICAgICAgbGV0IGl0ZW06IGFueSA9IHt9O1xyXG4gICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgY29uc3QgRklMRV9OQU1FID0gKHRoaXMuZXhwb3J0QnV0dG9uPy5maWxlTmFtZSB8fCAnQ09FUiBSZXBvcnQnKSArICcueGxzeCc7XHJcblxyXG4gICAgICAgIGxldCBST1dfREFUQV9TT1VSQ0UgPSAodGhpcy5leHBvcnRCdXR0b24uaGFzT3duUHJvcGVydHkoJ29ubHlSb3dGaWx0ZXJlZCcpICYmICF0aGlzLmV4cG9ydEJ1dHRvbi5vbmx5Um93RmlsdGVyZWQpXHJcbiAgICAgICAgICAgID8gdGhpcy52YWx1ZV9zaWduYWwoKSA6IHRoaXMuZ3JpZERhdGFTb3VyY2VGaWx0ZXJlZCgpO1xyXG5cclxuICAgICAgICBjb25zdCBDT0xVTU5fREFUQV9TT1VSQ0UgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICAgICAgICBpZiAodGhpcy5leHBvcnRCdXR0b24uaGFzT3duUHJvcGVydHkoJ29ubHlDb2x1bW5GaWx0ZXJlZCcpICYmICF0aGlzLmV4cG9ydEJ1dHRvbi5vbmx5Q29sdW1uRmlsdGVyZWQpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy52YWx1ZV9zaWduYWwoKSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb2x1bW5OYW1lIGluIHJvdykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5OYW1lID09ICdpbmRleFJvdycpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIENPTFVNTl9EQVRBX1NPVVJDRS5hZGQoVG9vbHMuRmlyc3RDaGFyVG9Mb3dlcihjb2x1bW5OYW1lKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgY29sdW1uTmFtZSB9IG9mIHRoaXMuZ3JpZENvbHVtbnMoKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbk5hbWUgPT0gJ2luZGV4Um93JykgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBDT0xVTU5fREFUQV9TT1VSQ0UuYWRkKFRvb2xzLkZpcnN0Q2hhclRvTG93ZXIoY29sdW1uTmFtZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBFWFBPUlRfREFUQTogVFtdID0gW107XHJcbiAgICAgICAgZm9yIChjb25zdCByb3cgb2YgUk9XX0RBVEFfU09VUkNFKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIENPTFVNTl9EQVRBX1NPVVJDRSkge1xyXG4gICAgICAgICAgICAgICAgaXRlbSA9IE9iamVjdC5hc3NpZ24oaXRlbSwgeyBbdGhpcy5fR2V0Q29sdW1uTmFtZShjb2x1bW4pXTogKHJvdyBhcyBhbnkpW2NvbHVtbl0gfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIEVYUE9SVF9EQVRBLnB1c2goaXRlbSk7XHJcbiAgICAgICAgICAgIGl0ZW0gPSBUb29scy5CcmVha1JlZmVyZW5jZSh7fSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZXhwb3J0RmlsZSkge1xyXG4gICAgICAgICAgICBGaWxlcy5FeHBvcnRFeGNlbChFWFBPUlRfREFUQSwgRklMRV9OQU1FKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMub25DbGlja0V4cG9ydC5lbWl0KEVYUE9SVF9EQVRBKTtcclxuICAgICAgICBUb29scy5TbGVlcCgzMDAwKS50aGVuKCgpID0+IHRoaXMuX2lzTG9hZGluZyA9IGZhbHNlKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcm90ZWN0ZWQgSW5wdXRDaGFuZ2UoaW5kZXhSb3c6IG51bWJlciwgY29sdW1uTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCBpbnB1dDogJ2NvZXItdGV4dGJveCcgfCAnY29lci1udW1iZXJib3gnIHwgJ2NvZXItc2VsZWN0Ym94JyB8ICdjb2VyLXN3aXRjaCcgfCAnY29lci10ZXh0Ym94LXNlYXJjaCcpOiB2b2lkIHtcclxuICAgICAgICBpZiAoaW5wdXQgPT09ICdjb2VyLXRleHRib3gtc2VhcmNoJykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5faXNMb2FkaW5nKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBUb29scy5TbGVlcCgwLCBgY29lckdyaWRJbnB1dENoYW5nZSR7Y29sdW1uTmFtZX1gKS50aGVuKGFzeW5jIF8gPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZ3JpZFNlYXJjaC5zZXQodmFsdWUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmKHRoaXMuY2hlY2tib3guc2hvdykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2lzTG9hZGluZ01lc3NhZ2UgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBUb29scy5TbGVlcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcihjb25zdCByb3cgb2YgdGhpcy5fdmFsdWUuZmlsdGVyKCh4OiBhbnkpID0+IHguY2hlY2tlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5DaGVja0J5KCh4OiBhbnkpID0+IHguaW5kZXhSb3cgPT0gKHJvdyBhcyBhbnkpLmluZGV4Um93KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IFRvb2xzLlNsZWVwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nTWVzc2FnZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb3BlcnR5ID0gVG9vbHMuRmlyc3RDaGFyVG9Mb3dlcihjb2x1bW5OYW1lKTtcclxuXHJcbiAgICAgICAgY29uc3Qgcm93OiBhbnkgPSB0aGlzLl92YWx1ZVtpbmRleFJvd107XHJcbiAgICAgICAgcm93W3Byb3BlcnR5XSA9IHZhbHVlO1xyXG5cclxuICAgICAgICBpZiAoaW5wdXQgPT09ICdjb2VyLXN3aXRjaCcpIHtcclxuICAgICAgICAgICAgdGhpcy5vblN3aXRjaENoYW5nZS5lbWl0KHsgcHJvcGVydHksIHJvdzogVG9vbHMuQnJlYWtSZWZlcmVuY2Uocm93KSwgdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlIGlmIChpbnB1dCA9PT0gJ2NvZXItdGV4dGJveCcpIHtcclxuICAgICAgICAgICAgdGhpcy5vblRleHRib3hDaGFuZ2UuZW1pdCh7IHByb3BlcnR5LCByb3c6IFRvb2xzLkJyZWFrUmVmZXJlbmNlKHJvdyksIHZhbHVlIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxzZSBpZiAoaW5wdXQgPT09ICdjb2VyLXNlbGVjdGJveCcpIHtcclxuICAgICAgICAgICAgdGhpcy5vblNlbGVjdGJveENoYW5nZS5lbWl0KHsgcHJvcGVydHksIHJvdzogVG9vbHMuQnJlYWtSZWZlcmVuY2Uocm93KSwgdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlIGlmIChpbnB1dCA9PT0gJ2NvZXItbnVtYmVyYm94Jykge1xyXG4gICAgICAgICAgICB0aGlzLm9uVGV4dGJveENoYW5nZS5lbWl0KHsgcHJvcGVydHksIHJvdzogVG9vbHMuQnJlYWtSZWZlcmVuY2Uocm93KSwgdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBUb29scy5TbGVlcCgxMDAwLCBgY29lckdyaWRJbnB1dENoYW5nZSR7aW5kZXhSb3d9JHtjb2x1bW5OYW1lfWApLnRoZW4oXyA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX1VwZGF0ZVZhbHVlKHRoaXMuX3ZhbHVlKTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZV9zaWduYWwuc2V0KHRoaXMuX3ZhbHVlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcm90ZWN0ZWQgS2V5dXBFbnRlcihpbmRleENvbHVtbjogbnVtYmVyLCByb3c6IGFueSwgaW5wdXQ6ICdjb2VyLXRleHRib3gnIHwgJ2NvZXItbnVtYmVyYm94JyB8ICdjb2VyLXRleHRib3gtc2VhcmNoJyB8ICdjb2VyLXNlbGVjdGJveCcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoWydjb2VyLXRleHRib3gnLCAnY29lci1udW1iZXJib3gnLCAnY29lci1zZWxlY3Rib3gnXS5pbmNsdWRlcyhpbnB1dCkpIHtcclxuICAgICAgICAgICAgdGhpcy5vbktleXVwRW50ZXIuZW1pdCh7XHJcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5fR2V0SWQoaW5kZXhDb2x1bW4sIHJvdy5pbmRleFJvdywgaW5wdXQpLFxyXG4gICAgICAgICAgICAgICAgaW5wdXQsIHJvdzogVG9vbHMuQnJlYWtSZWZlcmVuY2Uocm93KSwgdmFsdWVcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLk5leHRJbnB1dChpbmRleENvbHVtbiwgcm93LmluZGV4Um93KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKGlucHV0ID09ICdjb2VyLXRleHRib3gtc2VhcmNoJykge1xyXG4gICAgICAgICAgICB0aGlzLm9uS2V5dXBFbnRlci5lbWl0KHtcclxuICAgICAgICAgICAgICAgIGlkOiB0aGlzLl9HZXRJZChpbmRleENvbHVtbiwgcm93LmluZGV4Um93LCBpbnB1dCksXHJcbiAgICAgICAgICAgICAgICBpbnB1dCwgcm93OiBudWxsLCB2YWx1ZVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJpdmF0ZSBOZXh0SW5wdXQoaW5kZXhDb2x1bW46IG51bWJlciwgaW5kZXhSb3c6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IElOUFVUX1RFWFQgPSB0aGlzLmNvbHVtbnMoKS5maWx0ZXIoeCA9PiBUb29scy5Jc05vdE51bGwoeC5jb2VyVGV4dGJveCkpLm1hcCh4ID0+IHgucHJvcGVydHkpO1xyXG4gICAgICAgIGNvbnN0IElOUFVUX05VTUJFUiA9IHRoaXMuY29sdW1ucygpLmZpbHRlcih4ID0+IFRvb2xzLklzTm90TnVsbCh4LmNvZXJOdW1iZXJib3gpKS5tYXAoeCA9PiB4LnByb3BlcnR5KTtcclxuICAgICAgICBjb25zdCBJTlBVVF9TRUxFQ1QgPSB0aGlzLmNvbHVtbnMoKS5maWx0ZXIoeCA9PiBUb29scy5Jc05vdE51bGwoeC5jb2VyU2VsZWN0Ym94KSkubWFwKHggPT4geC5wcm9wZXJ0eSk7XHJcblxyXG4gICAgICAgIGxldCBpbmRleCA9IDBcclxuICAgICAgICBjb25zdCBDT0xVTU5TID0gW11cclxuICAgICAgICBjb25zdCBJTlBVVF9DT0xVTU5TID0gW11cclxuICAgICAgICBmb3IgKGNvbnN0IHsgY29sdW1uTmFtZSB9IG9mIHRoaXMuZ3JpZENvbHVtbnMoKSkge1xyXG4gICAgICAgICAgICBpZiAoSU5QVVRfVEVYVC5zb21lKHByb3BlcnR5ID0+IHByb3BlcnR5LnRvVXBwZXJDYXNlKCkgPT0gY29sdW1uTmFtZS50b1VwcGVyQ2FzZSgpKSkge1xyXG4gICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJUZXh0Ym94JyB9KTtcclxuICAgICAgICAgICAgICAgIElOUFVUX0NPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdjb2VyVGV4dGJveCcgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKElOUFVUX05VTUJFUi5zb21lKHByb3BlcnR5ID0+IHByb3BlcnR5LnRvVXBwZXJDYXNlKCkgPT0gY29sdW1uTmFtZS50b1VwcGVyQ2FzZSgpKSkge1xyXG4gICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJOdW1iZXJib3gnIH0pO1xyXG4gICAgICAgICAgICAgICAgSU5QVVRfQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJOdW1iZXJib3gnIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbHNlIGlmIChJTlBVVF9TRUxFQ1Quc29tZShwcm9wZXJ0eSA9PiBwcm9wZXJ0eS50b1VwcGVyQ2FzZSgpID09IGNvbHVtbk5hbWUudG9VcHBlckNhc2UoKSkpIHtcclxuICAgICAgICAgICAgICAgIENPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdjb2VyU2VsZWN0Ym94JyB9KTtcclxuICAgICAgICAgICAgICAgIElOUFVUX0NPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdjb2VyU2VsZWN0Ym94JyB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBDT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnZGVmYXVsdC1jZWxsJyB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgKytpbmRleDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBsYXN0Um93ID0gLTFcclxuICAgICAgICBmb3IoY29uc3QgeyByb3dzIH0gb2YgdGhpcy5ncmlkRGF0YVNvdXJjZSgpKSB7XHJcbiAgICAgICAgICAgIGxhc3RSb3cgKz0gcm93cy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgZmlyc3RDb2x1bW4gPSAtMTtcclxuICAgICAgICBpZiAoSU5QVVRfQ09MVU1OUy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGZpcnN0Q29sdW1uID0gWy4uLklOUFVUX0NPTFVNTlNdLnNoaWZ0KCkhLmluZGV4Q29sdW1uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGxhc3RDb2x1bW4gPSAtMTtcclxuICAgICAgICBpZiAoSU5QVVRfQ09MVU1OUy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGxhc3RDb2x1bW4gPSBbLi4uSU5QVVRfQ09MVU1OU10ucG9wKCkhLmluZGV4Q29sdW1uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9JcyBMYXN0IFJvdyAmIExhc3QgSW5wdXQgQ29sdW1uP1xyXG4gICAgICAgIGlmIChpbmRleFJvdyA9PSBsYXN0Um93ICYmIGluZGV4Q29sdW1uID09IGxhc3RDb2x1bW4pIHtcclxuICAgICAgICAgICAgdGhpcy5vbktleXVwRW50ZXJMYXN0LmVtaXQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vSXMgTGFzdCBJbnB1dCBDb2x1bW4/XHJcbiAgICAgICAgZWxzZSBpZiAoaW5kZXhDb2x1bW4gPT0gbGFzdENvbHVtbikge1xyXG4gICAgICAgICAgICB0aGlzLkZvY3VzSW5wdXQoKGluZGV4Um93ICsgMSksIGZpcnN0Q29sdW1uKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9OZXh0IENvbHVtbj9cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZm9yIChpbmRleCA9IChpbmRleENvbHVtbiArIDEpOyBpbmRleCA8IENPTFVNTlMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IoY29uc3QgaW5wdXQgb2YgQ09MVU1OUykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKGluZGV4ID09IGlucHV0LmluZGV4Q29sdW1uICYmIFsnY29lclRleHRib3gnLCAnY29lck51bWJlcmJveCcsICdjb2VyU2VsZWN0Ym94J10uaW5jbHVkZXMoaW5wdXQudHlwZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5Gb2N1c0lucHV0KGluZGV4Um93LCBpbnB1dC5pbmRleENvbHVtbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIEZvY3VzSW5wdXQoaW5kZXhSb3cgPSAtMSwgaW5kZXhDb2x1bW4gPSAtMSkge1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKDAsICdGb2N1c0lucHV0JykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0Rpc2FibGVkKCkpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGlmIChpbmRleFJvdyA8IDAgfHwgaW5kZXhDb2x1bW4gPCAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBJTlBVVF9URVhUID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKHggPT4gVG9vbHMuSXNOb3ROdWxsKHguY29lclRleHRib3gpKS5tYXAoeCA9PiB4LnByb3BlcnR5KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IElOUFVUX05VTUJFUiA9IHRoaXMuY29sdW1ucygpLmZpbHRlcih4ID0+IFRvb2xzLklzTm90TnVsbCh4LmNvZXJOdW1iZXJib3gpKS5tYXAoeCA9PiB4LnByb3BlcnR5KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IElOUFVUX1NFTEVDVCA9IHRoaXMuY29sdW1ucygpLmZpbHRlcih4ID0+IFRvb2xzLklzTm90TnVsbCh4LmNvZXJTZWxlY3Rib3gpKS5tYXAoeCA9PiB4LnByb3BlcnR5KTtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgQ09MVU1OUyA9IFtdXHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHsgY29sdW1uTmFtZSB9IG9mIHRoaXMuZ3JpZENvbHVtbnMoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChJTlBVVF9URVhULnNvbWUocHJvcGVydHkgPT4gcHJvcGVydHkudG9VcHBlckNhc2UoKSA9PSBjb2x1bW5OYW1lLnRvVXBwZXJDYXNlKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdjb2VyVGV4dGJveCcgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChJTlBVVF9OVU1CRVIuc29tZShwcm9wZXJ0eSA9PiBwcm9wZXJ0eS50b1VwcGVyQ2FzZSgpID09IGNvbHVtbk5hbWUudG9VcHBlckNhc2UoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09MVU1OUy5wdXNoKHsgaW5kZXhDb2x1bW46IGluZGV4LCBwcm9wZXJ0eTogY29sdW1uTmFtZSwgdHlwZTogJ2NvZXJOdW1iZXJib3gnIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoSU5QVVRfU0VMRUNULnNvbWUocHJvcGVydHkgPT4gcHJvcGVydHkudG9VcHBlckNhc2UoKSA9PSBjb2x1bW5OYW1lLnRvVXBwZXJDYXNlKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTFVNTlMucHVzaCh7IGluZGV4Q29sdW1uOiBpbmRleCwgcHJvcGVydHk6IGNvbHVtbk5hbWUsIHR5cGU6ICdjb2VyU2VsZWN0Ym94JyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT0xVTU5TLnB1c2goeyBpbmRleENvbHVtbjogaW5kZXgsIHByb3BlcnR5OiBjb2x1bW5OYW1lLCB0eXBlOiAnZGVmYXVsdC1jZWxsJyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYodGhpcy5ncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZUZpbHRlcmVkID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IEZJUlNUX0lOUFVUX0NPTFVNTiA9IENPTFVNTlMuZmluZCh4ID0+IFsnY29lclRleHRib3gnLCAnY29lck51bWJlcmJveCcsICdjb2VyU2VsZWN0Ym94J10uaW5jbHVkZXMoeC50eXBlKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChUb29scy5Jc05vdE51bGwoRklSU1RfSU5QVVRfQ09MVU1OKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkZvY3VzSW5wdXQoMCwgRklSU1RfSU5QVVRfQ09MVU1OIS5pbmRleENvbHVtbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5fR2V0SWQoaW5kZXhSb3csIGluZGV4Q29sdW1uKTtcclxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50OiBDb2VyVGV4dEJveCB8IENvZXJOdW1iZXJCb3ggfCBDb2VyU2VsZWN0Ym94PGFueT4gfCB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9pbmRleEZvY3VzLnNldChpbmRleFJvdyk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9Gb2N1cyBUZXh0Ym94XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5jb2VyVGV4dGJveExpc3QoKS5maW5kKHggPT4geC5pZCA9PSBpZCk7XHJcbiAgICAgICAgICAgICAgICBpZihlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5TZWxlY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy9Gb2N1cyBOdW1iZXJib3hcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmNvZXJOdW1iZXJib3hMaXN0KCkuZmluZCh4ID0+IHguaWQgPT0gaWQpO1xyXG4gICAgICAgICAgICAgICAgaWYoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuU2VsZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vRm9jdXMgU2VsZWN0Ym94XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5jb2VyU2VsZWN0Ym94TGlzdCgpLmZpbmQoeCA9PiB4LmlkID09IGlkKTtcclxuICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5TbGVlcCgxMDApLnRoZW4oXyA9PiBlbGVtZW50LkZvY3VzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBGb2N1c1JvdyhjYWxsYmFjazogKHJvdzogVCkgPT4gYm9vbGVhbik6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLlNsZWVwKCkudGhlbihfID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvdyA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueT4odGhpcy5fdmFsdWUuZmluZChjYWxsYmFjayBhcyBhbnkpKTtcclxuICAgICAgICAgICAgICAgIGlmIChUb29scy5Jc05vdE51bGwocm93KSkgdGhpcy5faW5kZXhGb2N1cy5zZXQocm93LmluZGV4Um93KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBhc3luYyBTb3J0KGNvbHVtbk5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICh0aGlzLmVuYWJsZVNvcnQoKSkge1xyXG4gICAgICAgICAgICBpZih0aGlzLl9pc0xvYWRpbmcpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX2lzTG9hZGluZ01lc3NhZ2UgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zdCB7IGRpcmVjdGlvbiB9ID0gdGhpcy5fc29ydCgpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGRhdGFTb3VyY2UgPSBUb29scy5CcmVha1JlZmVyZW5jZTxhbnk+KHRoaXMuX3ZhbHVlKTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBjaGVja2JveCBvZiB0aGlzLmNvZXJDaGVja2JveExpc3QoKSkgY2hlY2tib3guVW5jaGVjaygpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PSAnZGVzY2VuZGFudCcpIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLlNvcnRCeURlc2MoZGF0YVNvdXJjZSwgY29sdW1uTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zb3J0LnNldCh7IGNvbHVtbk5hbWUsIGRpcmVjdGlvbjogJ2FzY2VuZGFudCcsIGljb246ICdmYS1zb2xpZCBmYS1hcnJvdy1kb3duLXNob3J0LXdpZGUnIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLlNvcnRCeShkYXRhU291cmNlLCBjb2x1bW5OYW1lKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NvcnQuc2V0KHsgY29sdW1uTmFtZSwgZGlyZWN0aW9uOiAnZGVzY2VuZGFudCcsIGljb246ICdmYS1zb2xpZCBmYS1hcnJvdy11cC13aWRlLXNob3J0JyB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGluZGV4Um93ID0gMDtcclxuICAgICAgICAgICAgZGF0YVNvdXJjZSA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueT4oZGF0YVNvdXJjZSkubWFwKChpdGVtOiBhbnkpID0+IE9iamVjdC5hc3NpZ24oaXRlbSwgeyBpbmRleFJvdzogaW5kZXhSb3crKyB9KSk7XHJcbiAgICAgICAgICAgIHRoaXMuU2V0VmFsdWUoZGF0YVNvdXJjZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGF3YWl0IFRvb2xzLlNsZWVwKCk7XHJcbiAgICAgICAgICAgIGZvcihjb25zdCByb3cgb2YgZGF0YVNvdXJjZS5maWx0ZXIoKHg6IGFueSkgPT4geC5jaGVja2VkKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5DaGVja0J5KCh4OiBhbnkpID0+IHguaW5kZXhSb3cgPT0gcm93LmluZGV4Um93KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nTWVzc2FnZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHByb3RlY3RlZCBDbGlja0NoZWNrKGlkOiBzdHJpbmcsIGNoZWNrZWQ6IGJvb2xlYW4sIGFsbDogYm9vbGVhbiwgcm93OiBhbnkgPSBudWxsKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9pc0xvYWRpbmcpIFRvb2xzLlNsZWVwKCkudGhlbihhc3luYyBfID0+IHtcclxuICAgICAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gdGhpcy5jb2VyQ2hlY2tib3hMaXN0KCkuZmluZCh4ID0+IHguaWQoKSA9PSBpZCk7XHJcblxyXG4gICAgICAgICAgICBpZihUb29scy5Jc05vdE51bGwoZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgICAgIGxldCByZXNwb25zZTogSUdyaWRJbnB1dENoZWNrYm94PFQ+ID0geyBhbGwsIGNoZWNrZWQsIHJvd3M6IFtdIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLy9BbGwgQ2hlY2tib3hcclxuICAgICAgICAgICAgICAgIGlmIChhbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZihjaGVja2VkKSB0aGlzLkNoZWNrQWxsKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB0aGlzLlVuY2hlY2tBbGwoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9FdmVudFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnJvd3MgPSB0aGlzLnNlbGVjdGVkSXRlbXMoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2hlY2tib3hDaGFuZ2UuZW1pdChyZXNwb25zZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy9PbmUgQ2hlY2tib3hcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX29ubHlPbmVDaGVjaykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLl92YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJvdyBhcyBhbnkpLmNoZWNrZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjaGVja2JveCBvZiB0aGlzLmNvZXJDaGVja2JveExpc3QoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hlY2tib3guaWQoKSAhPSBpZCkgY2hlY2tib3guVW5jaGVjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAodGhpcy5fdmFsdWVbcm93LmluZGV4Um93XSBhcyBhbnkpLmNoZWNrZWQgPSBjaGVja2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuU2V0VmFsdWUodGhpcy5fdmFsdWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL01hcmsgQWxsIGNoZWNrYm94XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hlY2tib3hBbGwgPSB0aGlzLmNvZXJDaGVja2JveExpc3QoKS5maW5kKHggPT4geC5pZCgpID09IHRoaXMuX0dldElkKDAsIDAsICdjaGVja2JveEFsbCcpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy52YWx1ZV9zaWduYWwoKS5ldmVyeSgoeDogYW55KSA9PiB4LmNoZWNrZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrYm94QWxsPy5DaGVjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrYm94QWxsPy5VbmNoZWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0V2ZW50XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Uucm93cyA9IFt7IC4uLnJvdyB9XTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2hlY2tib3hDaGFuZ2UuZW1pdChyZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIENoZWNrQWxsKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMuX3ZhbHVlKSB7XHJcbiAgICAgICAgICAgIChyb3cgYXMgYW55KS5jaGVja2VkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuU2V0VmFsdWUodGhpcy5fdmFsdWUpO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGNoZWNrYm94IG9mIHRoaXMuY29lckNoZWNrYm94TGlzdCgpKSB7XHJcbiAgICAgICAgICAgIGNoZWNrYm94LkNoZWNrKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgVW5jaGVja0FsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLl92YWx1ZSkge1xyXG4gICAgICAgICAgICAocm93IGFzIGFueSkuY2hlY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5TZXRWYWx1ZSh0aGlzLl92YWx1ZSk7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2hlY2tib3ggb2YgdGhpcy5jb2VyQ2hlY2tib3hMaXN0KCkpIHtcclxuICAgICAgICAgICAgY2hlY2tib3guVW5jaGVjaygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5faXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIENoZWNrQnkoY2FsbGJhY2s6IChyb3c6IFQpID0+IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgICAgICBUb29scy5TbGVlcCgpLnRoZW4oXyA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl92YWx1ZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3dMaXN0ID0gVG9vbHMuQnJlYWtSZWZlcmVuY2U8YW55Pih0aGlzLl92YWx1ZS5maWx0ZXIoY2FsbGJhY2sgYXMgYW55KSk7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQ6IENvZXJDaGVja2JveCB8IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIGZvcihjb25zdCB7IGluZGV4Um93IH0gb2Ygcm93TGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmNvZXJDaGVja2JveExpc3QoKS5maW5kKHggPT4geC5pZCgpID09IHRoaXMuX0dldElkKGluZGV4Um93LCAwLCAnY2hlY2tib3gnKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChUb29scy5Jc05vdE51bGwoZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudD8uQ2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgVW5jaGVja0J5KGNhbGxiYWNrOiAocm93OiBUKSA9PiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgVG9vbHMuU2xlZXAoKS50aGVuKF8gPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdmFsdWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgcm93TGlzdCA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlPGFueT4odGhpcy5fdmFsdWUuZmlsdGVyKGNhbGxiYWNrIGFzIGFueSkpO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50OiBDb2VyQ2hlY2tib3ggfCB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBmb3IoY29uc3QgeyBpbmRleFJvdyB9IG9mIHJvd0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5jb2VyQ2hlY2tib3hMaXN0KCkuZmluZCh4ID0+IHguaWQoKSA9PSB0aGlzLl9HZXRJZChpbmRleFJvdywgMCwgJ2NoZWNrYm94JykpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoVG9vbHMuSXNOb3ROdWxsKGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ/LlVuY2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcm90ZWN0ZWQgQ2xpY2tPblJvdyhyb3c6IFQpOiB2b2lkIHtcclxuICAgICAgICBpZih0aGlzLl9pc0Rpc2FibGVkKCkpIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYoVG9vbHMuSXNOb3ROdWxsKHRoaXMuY2hlY2tib3guY2hlY2tPblJvdykgJiYgdGhpcy5jaGVja2JveC5jaGVja09uUm93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuQ2hlY2tCeSgoeDogYW55KSA9PiB4LmluZGV4Um93ID09IChyb3cgYXMgYW55KS5pbmRleFJvdyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLm9uQ2xpY2tSb3cuZW1pdChyb3cpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogSW5zZXJ0cyBuZXcgZWxlbWVudHMgYXQgdGhlIHN0YXJ0ICovXHJcbiAgICBwdWJsaWMgVW5zaGlmdChyb3c6IFQpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gVG9vbHMuQnJlYWtSZWZlcmVuY2UodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgIGRhdGFTb3VyY2UudW5zaGlmdChyb3cpO1xyXG4gICAgICAgIHRoaXMuU2V0VmFsdWUoZGF0YVNvdXJjZSk7XHJcbiAgICAgICAgdGhpcy5Gb2N1c0lucHV0KCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiBBcHBlbmRzIG5ldyBlbGVtZW50cyB0byB0aGUgZW5kICovXHJcbiAgICBwdWJsaWMgUHVzaChyb3c6IFQpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gVG9vbHMuQnJlYWtSZWZlcmVuY2UodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgIGRhdGFTb3VyY2UucHVzaChyb3cpO1xyXG4gICAgICAgIHRoaXMuU2V0VmFsdWUoZGF0YVNvdXJjZSk7XHJcbiAgICAgICAgdGhpcy5Gb2N1c0lucHV0KCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKiBEZWxldGUgUm93IEJ5IGluZGV4ICovXHJcbiAgICBwdWJsaWMgYXN5bmMgRGVsZXRlUm93KGluZGV4Um93OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gVG9vbHMuQnJlYWtSZWZlcmVuY2UodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgIGRhdGFTb3VyY2Uuc3BsaWNlKGluZGV4Um93LCAxKTtcclxuICAgICAgICB0aGlzLlNldFZhbHVlKGRhdGFTb3VyY2UpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKiogRGVsZXRlIHJvdyBsaXN0IGJ5IGNhbGxiYWNrICovXHJcbiAgICBwdWJsaWMgYXN5bmMgRGVsZXRlUm93c0J5KGNhbGxiYWNrOiAocm93OiBUKSA9PiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgaW5kZXhMaXN0ID0gVG9vbHMuQnJlYWtSZWZlcmVuY2U8bnVtYmVyW10+KHRoaXMuX3ZhbHVlLmZpbHRlcihjYWxsYmFjayBhcyBhbnkpLm1hcCgoaXRlbTogYW55KSA9PiBpdGVtLmluZGV4Um93KSk7XHJcblxyXG4gICAgICAgIGxldCBkYXRhU291cmNlOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIGZvcihjb25zdCBpbmRleFJvdyBvZiBpbmRleExpc3QpIHtcclxuICAgICAgICAgICAgZGF0YVNvdXJjZSA9IFRvb2xzLkJyZWFrUmVmZXJlbmNlKHRoaXMuX3ZhbHVlKTtcclxuICAgICAgICAgICAgZGF0YVNvdXJjZS5zcGxpY2UoaW5kZXhSb3csIDEpO1xyXG4gICAgICAgICAgICB0aGlzLlNldFZhbHVlKGRhdGFTb3VyY2UpO1xyXG4gICAgICAgICAgICBhd2FpdCBUb29scy5TbGVlcCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsIjxkaXYgY2xhc3M9XCJjb2VyLWdyaWRcIiBbbmdTdHlsZV09XCJ7ICd3aWR0aCc6IHdpZHRoKCksICdtaW4tV2lkdGgnOiBNaW5XaWR0aCgpLCAnbWF4LVdpZHRoJzogTWF4V2lkdGgoKSwgJ21hcmdpbic6IG1hcmdpbigpIH1cIj5cclxuICAgIDxoZWFkZXIgW2lkXT1cIl9pZCArICctaGVhZGVyJ1wiIGNsYXNzPVwicm93XCI+XHJcbiAgICAgICAgPCEtLSBTbG90IC0tPlxyXG4gICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuXHJcbiAgICAgICAgPCEtLSBFeHBvcnQgQnV0dG9uIC0tPlxyXG4gICAgICAgIEBpZihleHBvcnRCdXR0b24uc2hvdyAmJiBncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZSA+IDApIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICBpY29uPVwiZXhjZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgIFt0b29sdGlwXT1cIl9pc0xvYWRpbmcgPyAnTG9hZGluZycgOiAoZXhwb3J0QnV0dG9uLnRvb2x0aXAgfHwgJ0V4cG9ydCcpXCJcclxuICAgICAgICAgICAgICAgICAgICBbcGF0aF09XCIoZXhwb3J0QnV0dG9uICYmIGV4cG9ydEJ1dHRvbi5wYXRoKSA/IGV4cG9ydEJ1dHRvbi5wYXRoIDogW11cIlxyXG4gICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZyB8fCAoZXhwb3J0QnV0dG9uLmlzRGlzYWJsZWQgfHwgZmFsc2UpXCJcclxuICAgICAgICAgICAgICAgICAgICBbaXNMb2FkaW5nXT1cIl9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwiX2VuYWJsZUFuaW1hdGlvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgIChvbkNsaWNrKT1cIkV4cG9ydCghZXhwb3J0QnV0dG9uLnByZXZlbnREZWZhdWx0KVwiXHJcbiAgICAgICAgICAgICAgICA+PC9jb2VyLWJ1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA8IS0tIEltcG9ydCBCdXR0b24gLS0+XHJcbiAgICAgICAgQGlmKGltcG9ydEJ1dHRvbi5zaG93KSB7XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxyXG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgI2lucHV0RmlsZVJlZiBbbXVsdGlwbGVdPVwiZmFsc2VcIiAoY2hhbmdlKT1cIkltcG9ydCgkZXZlbnQpXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgPGNvZXItYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImljb25cIlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibmF2aWdhdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgaWNvbj1cImltcG9ydFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiaW1wb3J0QnV0dG9uLnRvb2x0aXAgfHwgJ0ltcG9ydCdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtwYXRoXT1cIihpbXBvcnRCdXR0b24gJiYgaW1wb3J0QnV0dG9uLnBhdGgpID8gaW1wb3J0QnV0dG9uLnBhdGggOiBbXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiaW1wb3J0QnV0dG9uLmlzRGlzYWJsZWQgfHwgZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwiX2VuYWJsZUFuaW1hdGlvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgIChvbkNsaWNrKT1cIkltcG9ydCgpXCJcclxuICAgICAgICAgICAgICAgID48L2NvZXItYnV0dG9uPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDwhLS0gQWRkIEJ1dHRvbiAtLT5cclxuICAgICAgICBAaWYoYWRkQnV0dG9uLnNob3cpIHtcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICA8Y29lci1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJuYXZpZ2F0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICBpY29uPVwibmV3XCJcclxuICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcF09XCJhZGRCdXR0b24udG9vbHRpcCB8fCAnTmV3J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW3BhdGhdPVwiKGFkZEJ1dHRvbiAmJiBhZGRCdXR0b24ucGF0aCkgPyBhZGRCdXR0b24ucGF0aCA6IFtdXCJcclxuICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJhZGRCdXR0b24uaXNEaXNhYmxlZCB8fCBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJfZW5hYmxlQW5pbWF0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwib25DbGlja0FkZC5lbWl0KClcIlxyXG4gICAgICAgICAgICAgICAgPjwvY29lci1idXR0b24+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgPCEtLSBTZWFyY2ggLS0+XHJcbiAgICAgICAgQGlmKHNlYXJjaC5zaG93KSB7XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxyXG4gICAgICAgICAgICAgICAgPGNvZXItdGV4dGJveFxyXG4gICAgICAgICAgICAgICAgICAgICNpbnB1dFNlYXJjaFxyXG4gICAgICAgICAgICAgICAgICAgIFtpZF09XCJfR2V0SWQoLTEsIC0xLCAnc2VhcmNoJylcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIl9ncmlkU2VhcmNoKClcIlxyXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoXCJcclxuICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJfaXNEaXNhYmxlZCgpIHx8IF9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzZWxlY3RPbkZvY3VzXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoPVwiMjUwcHhcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzaG93U2VhcmNoSWNvbl09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICBbc2hvd0NsZWFySWNvbl09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAob25JbnB1dCk9XCJJbnB1dENoYW5nZSgtMSwgJ1NlYXJjaCcsICRldmVudCwgJ2NvZXItdGV4dGJveC1zZWFyY2gnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2tDbGVhcik9XCJJbnB1dENoYW5nZSgtMSwgJ1NlYXJjaCcsICcnLCAnY29lci10ZXh0Ym94LXNlYXJjaCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAob25LZXl1cEVudGVyKT1cIktleXVwRW50ZXIoLTEsIHsgaW5kZXhSb3c6IC0xIH0sICdjb2VyLXRleHRib3gtc2VhcmNoJywgJGV2ZW50KTtcIlxyXG4gICAgICAgICAgICAgICAgPjwvY29lci10ZXh0Ym94PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICB9XHJcbiAgICA8L2hlYWRlcj5cclxuXHJcbiAgICA8c2VjdGlvbiBbbmdDbGFzc109XCJ7ICdncmlkLWNvbnRhaW5lcic6IHRydWUsICdpbnZpc2libGUnOiBpc0ludmlzaWJsZSgpIH1cIj5cclxuICAgICAgICA8ZGl2IFtuZ1N0eWxlXT1cInsgJ2hlaWdodCc6IF9oZWlnaHQsICdtaW4taGVpZ2h0JzogbWluSGVpZ2h0KCksICdtYXgtaGVpZ2h0JzogbWF4SGVpZ2h0KCkgfVwiPlxyXG4gICAgICAgICAgICBAaWYoaXNMb2FkaW5nKCkpIHtcclxuICAgICAgICAgICAgICAgIDwhLS0gR3JpZCBNZXNzYWdlIC0tPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInNwaW5uZXItYm9yZGVyXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmEtZmFkZVwiPkxvYWRpbmc8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgQGVsc2UgaWYoIV9pc0Rpc2FibGVkKCkgJiYgZ3JpZExlbmd0aCgpLmRhdGFTb3VyY2UgPD0gMCkge1xyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vLWRhdGFcIj4gTm8gRGF0YSA8L2Rpdj5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc20gdGFibGUtcmVzcG9uc2l2ZSB0YWJsZS1zdHJpcGVkXCI+XHJcbiAgICAgICAgICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYoY2hlY2tib3guc2hvdyAmJiBncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ2hlY2tCb3ggQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgY2xhc3M9XCJjaGVjay1ib3hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIV9vbmx5T25lQ2hlY2tcIiBbbmdDbGFzc109XCJ7ICdpbnZpc2libGUnOiBfaXNMb2FkaW5nTWVzc2FnZSB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2VyLWNoZWNrYm94XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKDAsIDAsICdjaGVja2JveEFsbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZ25vcmVNb2RlbF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwiQ2xpY2tDaGVjayhfR2V0SWQoMCwgMCwgJ2NoZWNrYm94QWxsJyksICRldmVudCwgdHJ1ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEeW5hbWljIEdyaWQgQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yKGhlYWRlciBvZiBncmlkQ29sdW1ucygpOyB0cmFjayBoZWFkZXIuaW5kZXhDb2x1bW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiIChkYmxjbGljayk9XCJTb3J0KGhlYWRlci5jb2x1bW5OYW1lKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbm8tc2VsZWN0aW9uJzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2N1cnNvci1kZWZhdWx0JzogIWVuYWJsZVNvcnQoKSAmJiAhX2lzTG9hZGluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2N1cnNvci1wb2ludGVyJzogZW5hYmxlU29ydCgpICYmICFfaXNMb2FkaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY3Vyc29yLXdhaXQnOiBfaXNMb2FkaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOiBoZWFkZXIud2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWFsaWduJzogR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCBudWxsLCAndGV4dEFsaWduJywgJ2RlZmF1bC1jZWxsJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vLXNlbGVjdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBfR2V0Q29sdW1uTmFtZShoZWFkZXIuY29sdW1uTmFtZSkgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cIl9HZXRTaG9ydEljb24oaGVhZGVyLmNvbHVtbk5hbWUpXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIENvbHVtbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmKEJ1dHRvbkJ5Um93KCdzaG93RGVsZXRlQnV0dG9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiIGNsYXNzPVwiYWN0aW9uLWJ1dHRvblwiPjwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRWRpdCBCdXR0b24gQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dFZGl0QnV0dG9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiIGNsYXNzPVwiYWN0aW9uLWJ1dHRvblwiPjwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRWRpdCBCdXR0b24gQ29sdW1uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dHb0J1dHRvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjbGFzcz1cImFjdGlvbi1idXR0b25cIj48L3RoPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgICAgIDwvdGhlYWQ+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBib2R5IC0tPlxyXG4gICAgICAgICAgICAgICAgQGZvcihncm91cCBvZiBncmlkRGF0YVNvdXJjZSgpOyB0cmFjayBncm91cC5pbmRleEdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tPHRyIHYtaWY9XCJfaXNHcm91cGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmNvbHNwYW49XCJfY29sc3BhblwiIGNsYXNzPVwiZ3JvdXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8TWVzQWNjb3JkaW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpyZWY9XCJgYWNjb3JkaW9uJHtncm91cC5pbmRleEdyb3VwfS0ke2lkfWBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6dGl0bGU9XCJgJHtfQ2xlYW5IZWFkZXJOYW1lKGdyb3VwQnkpfSAoJHtncm91cC5sZW5ndGh9KTogICR7Z3JvdXAuZ3JvdXBCeX1gXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOmlzTG9hZGluZz1cIl9pc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZXhwYW5kZWQ9XCJfVG9vZ2xlQWNjb3JkaW9uKGdyb3VwLmdyb3VwQnksIHRydWUsIGdyb3VwLmluZGV4R3JvdXApXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNvbGxhcHNlZD1cIl9Ub29nbGVBY2NvcmRpb24oZ3JvdXAuZ3JvdXBCeSwgZmFsc2UsIGdyb3VwLmluZGV4R3JvdXApXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9NZXNBY2NvcmRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPi0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvcihyb3cgb2YgZ3JvdXAucm93czsgdHJhY2sgcm93LmluZGV4Um93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgW2lkXT1cIl9HZXRJZChyb3cuaW5kZXhSb3csIDAsICdyb3cnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnbG9hZGluZyc6IGlzTG9hZGluZygpLCAnZC1ub25lJzogX0hpZGVSb3coZ3JvdXApLCAncm93LWZvY3VzJzogKHJvdy5pbmRleFJvdyA9PSBfaW5kZXhGb2N1cygpICYmIGVuYWJsZVJvd0ZvY3VzKCkpIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJfaW5kZXhGb2N1cy5zZXQocm93LmluZGV4Um93KVwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYoY2hlY2tib3guc2hvdykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENoZWNrQm94IENvbHVtbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY2hlY2stYm94XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsgJ2ludmlzaWJsZSc6IF9pc0xvYWRpbmdNZXNzYWdlIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1jaGVja2JveFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgMCwgJ2NoZWNrYm94JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWdub3JlTW9kZWxdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIl9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJDbGlja0NoZWNrKF9HZXRJZChyb3cuaW5kZXhSb3csIDAsICdjaGVja2JveCcpLCAkZXZlbnQsIGZhbHNlLCByb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7ICdpbnZpc2libGUnOiAhX2lzTG9hZGluZ01lc3NhZ2UgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRHluYW1pYyBDb2x1bW4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvcihoZWFkZXIgb2YgZ3JpZENvbHVtbnMoKTsgdHJhY2sgaGVhZGVyLmluZGV4Q29sdW1uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndGVtcGxhdGUnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJfaXNEaXNhYmxlZCgpID8gbnVsbCA6IG9uQ2xpY2tSb3cuZW1pdChyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGJsY2xpY2spPVwiX2lzRGlzYWJsZWQoKSA/IG51bGwgOiBvbkRvdWJsZUNsaWNrUm93LmVtaXQocm93KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3RlbXBsYXRlJywgJ2RlZmF1bC1jZWxsJykgfCBodG1sXCIgY2xhc3M9XCJ0ZW1wbGF0ZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2UgaWYoX0lzQ2VsbFR5cGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvZXJUZXh0Ym94JykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gY29lci10ZXh0Ym94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29lci10ZXh0Ym94XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItdGV4dGJveFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgaGVhZGVyLmluZGV4Q29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W2hlYWRlci5jb2x1bW5OYW1lXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNEaXNhYmxlZCcsICdjb2VyVGV4dGJveCcpIHx8IF9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc1ZhbGlkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNWYWxpZCcsICdjb2VyVGV4dGJveCcpIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52YWxpZF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2lzSW52YWxpZCcsICdjb2VyVGV4dGJveCcpIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdE9uRm9jdXNdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdzZWxlY3RPbkZvY3VzJywgJ2NvZXJUZXh0Ym94JykgfHwgdHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3BsYWNlaG9sZGVyJywgJ2NvZXJUZXh0Ym94JykgfHwgKCdUeXBlICcgKyBoZWFkZXIuY29sdW1uTmFtZSArICcuLi4nKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0ZXh0UG9zaXRpb25dPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICd0ZXh0UG9zaXRpb24nLCAnY29lclRleHRib3gnKSB8fCAnbGVmdCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluTGVuZ3RoXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnbWluTGVuZ3RoJywgJ2NvZXJUZXh0Ym94JykgfHwgMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhMZW5ndGhdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdtYXhMZW5ndGgnLCAnY29lclRleHRib3gnKSB8fCA1MFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbklucHV0KT1cIklucHV0Q2hhbmdlKHJvdy5pbmRleFJvdywgaGVhZGVyLmNvbHVtbk5hbWUsICRldmVudCwgJ2NvZXItdGV4dGJveCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uS2V5dXBFbnRlcik9XCJLZXl1cEVudGVyKGhlYWRlci5pbmRleENvbHVtbiwgcm93LCAnY29lci10ZXh0Ym94JywgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvY29lci10ZXh0Ym94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBlbHNlIGlmKF9Jc0NlbGxUeXBlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdjb2VyTnVtYmVyYm94JykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gY29lci1udW1iZXJib3ggLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2VyLW51bWJlcmJveFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2VyLW51bWJlcmJveFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiX0dldElkKHJvdy5pbmRleFJvdywgaGVhZGVyLmluZGV4Q29sdW1uKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93W2hlYWRlci5jb2x1bW5OYW1lXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0Rpc2FibGVkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNEaXNhYmxlZCcsICdjb2VyTnVtYmVyYm94JykgfHwgX2lzRGlzYWJsZWQoKSB8fCBfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzVmFsaWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc1ZhbGlkJywgJ2NvZXJOdW1iZXJib3gnKSB8fCBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmFsaWRdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdpc0ludmFsaWQnLCAnY29lck51bWJlcmJveCcpIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdE9uRm9jdXNdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdzZWxlY3RPbkZvY3VzJywgJ2NvZXJOdW1iZXJib3gnKSB8fCB0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAncGxhY2Vob2xkZXInLCAnY29lck51bWJlcmJveCcpIHx8ICcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RleHRQb3NpdGlvbl09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ3RleHRQb3NpdGlvbicsICdjb2VyTnVtYmVyYm94JykgfHwgJ3JpZ2h0J1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdtaW4nLCAnY29lck51bWJlcmJveCcpIHx8IDBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4XT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnbWF4JywgJ2NvZXJOdW1iZXJib3gnKSB8fCAyMTQ3NDgzNjQ3XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RlY2ltYWxzXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnZGVjaW1hbHMnLCAnY29lck51bWJlcmJveCcpIHx8IDBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25JbnB1dCk9XCJJbnB1dENoYW5nZShyb3cuaW5kZXhSb3csIGhlYWRlci5jb2x1bW5OYW1lLCAkZXZlbnQsICdjb2VyLW51bWJlcmJveCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uS2V5dXBFbnRlcik9XCJLZXl1cEVudGVyKGhlYWRlci5pbmRleENvbHVtbiwgcm93LCAnY29lci1udW1iZXJib3gnLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLW51bWJlcmJveD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnY29lclNlbGVjdGJveCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGNvZXItbnVtYmVyYm94IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29lci1zZWxlY3Rib3hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1zZWxlY3Rib3hcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cIl9HZXRJZChyb3cuaW5kZXhSb3csIGhlYWRlci5pbmRleENvbHVtbilcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd1toZWFkZXIuY29sdW1uTmFtZV1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2lzRGlzYWJsZWQnLCAnY29lclNlbGVjdGJveCcpIHx8IF9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc1ZhbGlkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNWYWxpZCcsICdjb2VyU2VsZWN0Ym94JykgfHwgZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNJbnZhbGlkXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnaXNJbnZhbGlkJywgJ2NvZXJTZWxlY3Rib3gnKSB8fCBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhU291cmNlXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnZGF0YVNvdXJjZScsICdjb2VyU2VsZWN0Ym94JykgfHwgW11cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdwbGFjZWhvbGRlcicsICdjb2VyU2VsZWN0Ym94JykgfHwgJy0tIFNlbGVjdCAtLSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcERpc3BsYXldPVwiR2V0QXR0cmlidXRlKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdwcm9wRGlzcGxheScsICdjb2VyU2VsZWN0Ym94JykgfHwgJ25hbWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uU2VsZWN0ZWQpPVwiSW5wdXRDaGFuZ2Uocm93LmluZGV4Um93LCBoZWFkZXIuY29sdW1uTmFtZSwgJGV2ZW50LCAnY29lci1zZWxlY3Rib3gnKTsgS2V5dXBFbnRlcihoZWFkZXIuaW5kZXhDb2x1bW4sIHJvdywgJ2NvZXItc2VsZWN0Ym94JywgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvY29lci1zZWxlY3Rib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2UgaWYoX0lzQ2VsbFR5cGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvZXJTd2l0Y2gnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBjb2VyLXN3aXRjaCAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29lci1zd2l0Y2hcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cIl9HZXRJZChyb3cuaW5kZXhSb3csIGhlYWRlci5pbmRleENvbHVtbilcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd1toZWFkZXIuY29sdW1uTmFtZV1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJHZXRBdHRyaWJ1dGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2lzRGlzYWJsZWQnLCAnY29lclN3aXRjaCcpIHx8IF9pc0Rpc2FibGVkKCkgfHwgX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndG9vbHRpcCcsICdjb2VyU3dpdGNoJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcFBvc2l0aW9uXT1cIkdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndG9vbHRpcFBvc2l0aW9uJywgJ2NvZXJTd2l0Y2gnKSB8fCAnbGVmdCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNJbnZpc2libGVdPVwiX2lzRGlzYWJsZWQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJJbnB1dENoYW5nZShyb3cuaW5kZXhSb3csIGhlYWRlci5jb2x1bW5OYW1lLCAkZXZlbnQsICdjb2VyLXN3aXRjaCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLXN3aXRjaD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRGVmYXVsdCBDZWxsIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiZGVmYXVsdC1jZWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiQ2xpY2tPblJvdyhyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGJsY2xpY2spPVwiX2lzRGlzYWJsZWQoKSA/IG51bGwgOiBvbkRvdWJsZUNsaWNrUm93LmVtaXQocm93KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1hbGlnbic6IEdldEF0dHJpYnV0ZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAndGV4dEFsaWduJywgJ2RlZmF1bC1jZWxsJyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aGl0ZS1zcGFjZSc6ICdub3JtYWwnXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtpZF09XCJfR2V0SWQocm93LmluZGV4Um93LCBoZWFkZXIuaW5kZXhDb2x1bW4pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtYmx1ZS1ib2xkJzogX0lzQ2VsbENvbG9yKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdjb2xvckJsdWUnKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LWdyZWVuLWJvbGQnOiBfSXNDZWxsQ29sb3IoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvbG9yR3JlZW4nKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0LXllbGxvdy1ib2xkJzogX0lzQ2VsbENvbG9yKGhlYWRlci5jb2x1bW5OYW1lLCByb3csICdjb2xvclllbGxvdycpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtcmVkLWJvbGQnOiBfSXNDZWxsQ29sb3IoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2NvbG9yUmVkJyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAndGV4dC1yaWdodC1ib2xkJzogX0lzQ2VsbFR5cGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ251bWJlcicpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihfSXNDZWxsVHlwZShoZWFkZXIuY29sdW1uTmFtZSwgcm93LCAnbnVtYmVyJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPiB7eyBHZXROdW1lcmljRm9ybWF0KHJvd1toZWFkZXIuY29sdW1uTmFtZV0pIH19IDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2UgaWYoX0lzQ2VsbFR5cGUoaGVhZGVyLmNvbHVtbk5hbWUsIHJvdywgJ2RhdGUnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+IHt7IEdldERhdGVGb3JtYXQocm93W2hlYWRlci5jb2x1bW5OYW1lXSkgfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj4ge3sgX0dldENlbGxWYWx1ZShyb3csIGhlYWRlci5jb2x1bW5OYW1lKSB9fSA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIEJ1dHRvbiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dEZWxldGVCdXR0b24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhY3Rpb24tYnV0dG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYoQnV0dG9uQnlSb3coJ3Nob3dEZWxldGVCdXR0b24nLCByb3cpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJpY29uLW5vLWJvcmRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibmF2aWdhdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJkZWxldGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdG9vbHRpcF09XCJfR2V0VG9vbHRpcCgnRGVsZXRlJywgcm93KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ludmlzaWJsZV09XCJfaXNEaXNhYmxlZCgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzRGlzYWJsZWRdPVwiX2lzTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNsaWNrKT1cIm9uQ2xpY2tEZWxldGVSb3cuZW1pdChyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRWRpdCBCdXR0b24gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKEJ1dHRvbkJ5Um93KCdzaG93RWRpdEJ1dHRvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImFjdGlvbi1idXR0b25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0VkaXRCdXR0b24nLCByb3cpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJpY29uLW5vLWJvcmRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibmF2aWdhdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJlZGl0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Rvb2x0aXBdPVwiX0dldFRvb2x0aXAoJ0VkaXQnLCByb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52aXNpYmxlXT1cIl9pc0Rpc2FibGVkKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwib25DbGlja0VkaXRSb3cuZW1pdChyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gR08gQnV0dG9uIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZihCdXR0b25CeVJvdygnc2hvd0dvQnV0dG9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYWN0aW9uLWJ1dHRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKEJ1dHRvbkJ5Um93KCdzaG93R29CdXR0b24nLCByb3cpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZXItYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJpY29uLW5vLWJvcmRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibmF2aWdhdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb249XCJnb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0b29sdGlwXT1cIl9HZXRUb29sdGlwKCdHbyB0bycsIHJvdywgJ2RldGFpbCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzSW52aXNpYmxlXT1cIl9pc0Rpc2FibGVkKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNEaXNhYmxlZF09XCJfaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwib25DbGlja0VkaXRSb3cuZW1pdChyb3cpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2VyLWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgPC90YWJsZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvc2VjdGlvbj5cclxuXHJcbiAgICBAaWYoc2hvd0Zvb3RlcigpKSB7XHJcbiAgICAgICAgPGZvb3RlciBjbGFzcz1cImdyaWQtZm9vdGVyXCI+XHJcbiAgICAgICAgICAgIDxzcGFuPlxyXG4gICAgICAgICAgICAgICAgQGlmKF9pc0xvYWRpbmdNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmYS1mYWRlXCI+IExvYWRpbmcgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIEBlbHNlIGlmKGdyaWRMZW5ndGgoKS5kYXRhU291cmNlU2VsZWN0ZWQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hlY2syLXNxdWFyZSBtcy0xXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBncmlkTGVuZ3RoKCkuZGF0YVNvdXJjZVNlbGVjdGVkIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA8L3NwYW4+XHJcblxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1lLTFcIj4ge3sgZ3JpZExlbmd0aCgpLmRhdGFTb3VyY2VGaWx0ZXJlZCB8IG51bWVyaWNGb3JtYXQgfX0gUm93cyA8L3NwYW4+XHJcbiAgICAgICAgPC9mb290ZXI+XHJcbiAgICB9XHJcbjwvZGl2PiJdfQ==