@angular-generic-table/core 5.0.0-alpha.1 → 5.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.md +13 -134
  2. package/angular-generic-table-core.d.ts +2 -19
  3. package/esm2020/angular-generic-table-core.mjs +5 -0
  4. package/esm2020/lib/core.component.mjs +122 -0
  5. package/esm2020/lib/core.module.mjs +23 -0
  6. package/esm2020/lib/core.service.mjs +14 -0
  7. package/esm2020/lib/enums/order.enum.mjs +6 -0
  8. package/esm2020/lib/models/table-column.interface.mjs +2 -0
  9. package/esm2020/lib/models/table-config.interface.mjs +2 -0
  10. package/esm2020/lib/models/table-info.interface.mjs +2 -0
  11. package/esm2020/lib/models/table-meta.interface.mjs +2 -0
  12. package/esm2020/lib/models/table-row.interface.mjs +2 -0
  13. package/esm2020/lib/models/table-sort.interface.mjs +2 -0
  14. package/esm2020/lib/pagination/pagination.component.mjs +63 -0
  15. package/esm2020/lib/pagination/pagination.module.mjs +18 -0
  16. package/esm2020/lib/pipes/capital-case.pipe.mjs +17 -0
  17. package/esm2020/lib/pipes/dash-case.pipe.mjs +17 -0
  18. package/esm2020/lib/pipes/dynamic.pipe.mjs +25 -0
  19. package/esm2020/lib/pipes/highlight.pipe.mjs +48 -0
  20. package/esm2020/lib/pipes/sort-class.pipe.mjs +16 -0
  21. package/esm2020/lib/utilities/utilities.mjs +39 -0
  22. package/esm2020/public-api.mjs +15 -0
  23. package/fesm2015/angular-generic-table-core.mjs +384 -0
  24. package/fesm2015/angular-generic-table-core.mjs.map +1 -0
  25. package/fesm2020/angular-generic-table-core.mjs +381 -0
  26. package/fesm2020/angular-generic-table-core.mjs.map +1 -0
  27. package/lib/core.component.d.ts +33 -0
  28. package/lib/core.module.d.ts +12 -1
  29. package/lib/core.service.d.ts +6 -0
  30. package/lib/enums/order.enum.d.ts +4 -0
  31. package/lib/models/table-column.interface.d.ts +15 -0
  32. package/lib/models/table-config.interface.d.ts +15 -0
  33. package/lib/models/table-info.interface.d.ts +4 -0
  34. package/lib/models/table-meta.interface.d.ts +8 -0
  35. package/lib/models/table-row.interface.d.ts +4 -0
  36. package/lib/models/table-sort.interface.d.ts +5 -0
  37. package/lib/pagination/pagination.component.d.ts +14 -0
  38. package/lib/pagination/pagination.module.d.ts +8 -0
  39. package/lib/pipes/capital-case.pipe.d.ts +7 -0
  40. package/lib/pipes/dash-case.pipe.d.ts +4 -1
  41. package/lib/pipes/dynamic.pipe.d.ts +9 -0
  42. package/lib/pipes/highlight.pipe.d.ts +7 -0
  43. package/lib/pipes/sort-class.pipe.d.ts +11 -0
  44. package/lib/utilities/utilities.d.ts +6 -0
  45. package/package.json +26 -24
  46. package/public-api.d.ts +11 -0
  47. package/scss/index.scss +102 -0
  48. package/CHANGELOG.md +0 -461
  49. package/LICENSE.md +0 -201
  50. package/angular-generic-table-core.metadata.json +0 -1
  51. package/bundles/angular-generic-table-core.umd.js +0 -3675
  52. package/bundles/angular-generic-table-core.umd.js.map +0 -1
  53. package/bundles/angular-generic-table-core.umd.min.js +0 -2
  54. package/bundles/angular-generic-table-core.umd.min.js.map +0 -1
  55. package/css/generic-table.css +0 -168
  56. package/css/generic-table.css.map +0 -9
  57. package/css/generic-table.min.css +0 -2
  58. package/css/generic-table.min.css.map +0 -1
  59. package/esm2015/angular-generic-table-core.js +0 -28
  60. package/esm2015/angular-generic-table-core.metadata.json +0 -1
  61. package/esm2015/lib/components/generic-table/generic-table.component.js +0 -1738
  62. package/esm2015/lib/components/generic-table/generic-table.component.metadata.json +0 -1
  63. package/esm2015/lib/components/gt-checkbox/gt-checkbox.component.js +0 -88
  64. package/esm2015/lib/components/gt-checkbox/gt-checkbox.component.metadata.json +0 -1
  65. package/esm2015/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.js +0 -112
  66. package/esm2015/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.metadata.json +0 -1
  67. package/esm2015/lib/components/gt-drilldown/gt-drilldown.component.js +0 -53
  68. package/esm2015/lib/components/gt-drilldown/gt-drilldown.component.metadata.json +0 -1
  69. package/esm2015/lib/components/gt-dropdown/gt-dropdown.component.js +0 -176
  70. package/esm2015/lib/components/gt-dropdown/gt-dropdown.component.metadata.json +0 -1
  71. package/esm2015/lib/components/gt-expanding-row/gt-expanding-row.component.js +0 -147
  72. package/esm2015/lib/components/gt-expanding-row/gt-expanding-row.component.metadata.json +0 -1
  73. package/esm2015/lib/components/gt-pagination/gt-pagination.component.js +0 -141
  74. package/esm2015/lib/components/gt-pagination/gt-pagination.component.metadata.json +0 -1
  75. package/esm2015/lib/components/gt-table-info/gt-table-info.component.js +0 -103
  76. package/esm2015/lib/components/gt-table-info/gt-table-info.component.metadata.json +0 -1
  77. package/esm2015/lib/core.module.js +0 -96
  78. package/esm2015/lib/core.module.metadata.json +0 -1
  79. package/esm2015/lib/directives/component-anchor.directive.js +0 -65
  80. package/esm2015/lib/directives/component-anchor.directive.metadata.json +0 -1
  81. package/esm2015/lib/directives/gt-column-width.directive.js +0 -73
  82. package/esm2015/lib/directives/gt-column-width.directive.metadata.json +0 -1
  83. package/esm2015/lib/interfaces/gt-config-field.js +0 -96
  84. package/esm2015/lib/interfaces/gt-config-field.metadata.json +0 -1
  85. package/esm2015/lib/interfaces/gt-config-setting.js +0 -41
  86. package/esm2015/lib/interfaces/gt-config-setting.metadata.json +0 -1
  87. package/esm2015/lib/interfaces/gt-config-total.js +0 -20
  88. package/esm2015/lib/interfaces/gt-config-total.metadata.json +0 -1
  89. package/esm2015/lib/interfaces/gt-config.js +0 -24
  90. package/esm2015/lib/interfaces/gt-config.metadata.json +0 -1
  91. package/esm2015/lib/interfaces/gt-event.js +0 -16
  92. package/esm2015/lib/interfaces/gt-event.metadata.json +0 -1
  93. package/esm2015/lib/interfaces/gt-information.js +0 -38
  94. package/esm2015/lib/interfaces/gt-information.metadata.json +0 -1
  95. package/esm2015/lib/interfaces/gt-options.js +0 -55
  96. package/esm2015/lib/interfaces/gt-options.metadata.json +0 -1
  97. package/esm2015/lib/interfaces/gt-render-field.js +0 -29
  98. package/esm2015/lib/interfaces/gt-render-field.metadata.json +0 -1
  99. package/esm2015/lib/interfaces/gt-row-meta.js +0 -18
  100. package/esm2015/lib/interfaces/gt-row-meta.metadata.json +0 -1
  101. package/esm2015/lib/interfaces/gt-row.js +0 -20
  102. package/esm2015/lib/interfaces/gt-row.metadata.json +0 -1
  103. package/esm2015/lib/interfaces/gt-texts.js +0 -36
  104. package/esm2015/lib/interfaces/gt-texts.metadata.json +0 -1
  105. package/esm2015/lib/pipes/dash-case.pipe.js +0 -30
  106. package/esm2015/lib/pipes/dash-case.pipe.metadata.json +0 -1
  107. package/esm2015/lib/pipes/gt-chunk.pipe.js +0 -52
  108. package/esm2015/lib/pipes/gt-chunk.pipe.metadata.json +0 -1
  109. package/esm2015/lib/pipes/gt-column-class.pipe.js +0 -51
  110. package/esm2015/lib/pipes/gt-column-class.pipe.metadata.json +0 -1
  111. package/esm2015/lib/pipes/gt-filter.pipe.js +0 -60
  112. package/esm2015/lib/pipes/gt-filter.pipe.metadata.json +0 -1
  113. package/esm2015/lib/pipes/gt-highlight.pipe.js +0 -72
  114. package/esm2015/lib/pipes/gt-highlight.pipe.metadata.json +0 -1
  115. package/esm2015/lib/pipes/gt-is-editable.pipe.js +0 -37
  116. package/esm2015/lib/pipes/gt-is-editable.pipe.metadata.json +0 -1
  117. package/esm2015/lib/pipes/gt-is-observable.pipe.js +0 -31
  118. package/esm2015/lib/pipes/gt-is-observable.pipe.metadata.json +0 -1
  119. package/esm2015/lib/pipes/gt-meta.pipe.js +0 -54
  120. package/esm2015/lib/pipes/gt-meta.pipe.metadata.json +0 -1
  121. package/esm2015/lib/pipes/gt-order-by.pipe.js +0 -202
  122. package/esm2015/lib/pipes/gt-order-by.pipe.metadata.json +0 -1
  123. package/esm2015/lib/pipes/gt-property.pipe.js +0 -52
  124. package/esm2015/lib/pipes/gt-property.pipe.metadata.json +0 -1
  125. package/esm2015/lib/pipes/gt-render.pipe.js +0 -173
  126. package/esm2015/lib/pipes/gt-render.pipe.metadata.json +0 -1
  127. package/esm2015/lib/pipes/gt-row-class.pipe.js +0 -66
  128. package/esm2015/lib/pipes/gt-row-class.pipe.metadata.json +0 -1
  129. package/esm2015/lib/pipes/gt-search.pipe.js +0 -114
  130. package/esm2015/lib/pipes/gt-search.pipe.metadata.json +0 -1
  131. package/esm2015/lib/pipes/gt-totals-position.pipe.js +0 -35
  132. package/esm2015/lib/pipes/gt-totals-position.pipe.metadata.json +0 -1
  133. package/esm2015/lib/pipes/gt-totals.pipe.js +0 -46
  134. package/esm2015/lib/pipes/gt-totals.pipe.metadata.json +0 -1
  135. package/esm2015/lib/pipes/gt-visible.pipe.js +0 -71
  136. package/esm2015/lib/pipes/gt-visible.pipe.metadata.json +0 -1
  137. package/esm2015/public_api.js +0 -18
  138. package/esm2015/public_api.metadata.json +0 -1
  139. package/esm5/angular-generic-table-core.js +0 -28
  140. package/esm5/angular-generic-table-core.metadata.json +0 -1
  141. package/esm5/lib/components/generic-table/generic-table.component.js +0 -1813
  142. package/esm5/lib/components/generic-table/generic-table.component.metadata.json +0 -1
  143. package/esm5/lib/components/gt-checkbox/gt-checkbox.component.js +0 -100
  144. package/esm5/lib/components/gt-checkbox/gt-checkbox.component.metadata.json +0 -1
  145. package/esm5/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.js +0 -136
  146. package/esm5/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.metadata.json +0 -1
  147. package/esm5/lib/components/gt-drilldown/gt-drilldown.component.js +0 -41
  148. package/esm5/lib/components/gt-drilldown/gt-drilldown.component.metadata.json +0 -1
  149. package/esm5/lib/components/gt-dropdown/gt-dropdown.component.js +0 -179
  150. package/esm5/lib/components/gt-dropdown/gt-dropdown.component.metadata.json +0 -1
  151. package/esm5/lib/components/gt-expanding-row/gt-expanding-row.component.js +0 -173
  152. package/esm5/lib/components/gt-expanding-row/gt-expanding-row.component.metadata.json +0 -1
  153. package/esm5/lib/components/gt-pagination/gt-pagination.component.js +0 -149
  154. package/esm5/lib/components/gt-pagination/gt-pagination.component.metadata.json +0 -1
  155. package/esm5/lib/components/gt-table-info/gt-table-info.component.js +0 -111
  156. package/esm5/lib/components/gt-table-info/gt-table-info.component.metadata.json +0 -1
  157. package/esm5/lib/core.module.js +0 -100
  158. package/esm5/lib/core.module.metadata.json +0 -1
  159. package/esm5/lib/directives/component-anchor.directive.js +0 -66
  160. package/esm5/lib/directives/component-anchor.directive.metadata.json +0 -1
  161. package/esm5/lib/directives/gt-column-width.directive.js +0 -81
  162. package/esm5/lib/directives/gt-column-width.directive.metadata.json +0 -1
  163. package/esm5/lib/interfaces/gt-config-field.js +0 -96
  164. package/esm5/lib/interfaces/gt-config-field.metadata.json +0 -1
  165. package/esm5/lib/interfaces/gt-config-setting.js +0 -41
  166. package/esm5/lib/interfaces/gt-config-setting.metadata.json +0 -1
  167. package/esm5/lib/interfaces/gt-config-total.js +0 -20
  168. package/esm5/lib/interfaces/gt-config-total.metadata.json +0 -1
  169. package/esm5/lib/interfaces/gt-config.js +0 -24
  170. package/esm5/lib/interfaces/gt-config.metadata.json +0 -1
  171. package/esm5/lib/interfaces/gt-event.js +0 -16
  172. package/esm5/lib/interfaces/gt-event.metadata.json +0 -1
  173. package/esm5/lib/interfaces/gt-information.js +0 -38
  174. package/esm5/lib/interfaces/gt-information.metadata.json +0 -1
  175. package/esm5/lib/interfaces/gt-options.js +0 -55
  176. package/esm5/lib/interfaces/gt-options.metadata.json +0 -1
  177. package/esm5/lib/interfaces/gt-render-field.js +0 -29
  178. package/esm5/lib/interfaces/gt-render-field.metadata.json +0 -1
  179. package/esm5/lib/interfaces/gt-row-meta.js +0 -18
  180. package/esm5/lib/interfaces/gt-row-meta.metadata.json +0 -1
  181. package/esm5/lib/interfaces/gt-row.js +0 -20
  182. package/esm5/lib/interfaces/gt-row.metadata.json +0 -1
  183. package/esm5/lib/interfaces/gt-texts.js +0 -36
  184. package/esm5/lib/interfaces/gt-texts.metadata.json +0 -1
  185. package/esm5/lib/pipes/dash-case.pipe.js +0 -38
  186. package/esm5/lib/pipes/dash-case.pipe.metadata.json +0 -1
  187. package/esm5/lib/pipes/gt-chunk.pipe.js +0 -70
  188. package/esm5/lib/pipes/gt-chunk.pipe.metadata.json +0 -1
  189. package/esm5/lib/pipes/gt-column-class.pipe.js +0 -61
  190. package/esm5/lib/pipes/gt-column-class.pipe.metadata.json +0 -1
  191. package/esm5/lib/pipes/gt-filter.pipe.js +0 -73
  192. package/esm5/lib/pipes/gt-filter.pipe.metadata.json +0 -1
  193. package/esm5/lib/pipes/gt-highlight.pipe.js +0 -77
  194. package/esm5/lib/pipes/gt-highlight.pipe.metadata.json +0 -1
  195. package/esm5/lib/pipes/gt-is-editable.pipe.js +0 -47
  196. package/esm5/lib/pipes/gt-is-editable.pipe.metadata.json +0 -1
  197. package/esm5/lib/pipes/gt-is-observable.pipe.js +0 -39
  198. package/esm5/lib/pipes/gt-is-observable.pipe.metadata.json +0 -1
  199. package/esm5/lib/pipes/gt-meta.pipe.js +0 -65
  200. package/esm5/lib/pipes/gt-meta.pipe.metadata.json +0 -1
  201. package/esm5/lib/pipes/gt-order-by.pipe.js +0 -223
  202. package/esm5/lib/pipes/gt-order-by.pipe.metadata.json +0 -1
  203. package/esm5/lib/pipes/gt-property.pipe.js +0 -63
  204. package/esm5/lib/pipes/gt-property.pipe.metadata.json +0 -1
  205. package/esm5/lib/pipes/gt-render.pipe.js +0 -182
  206. package/esm5/lib/pipes/gt-render.pipe.metadata.json +0 -1
  207. package/esm5/lib/pipes/gt-row-class.pipe.js +0 -75
  208. package/esm5/lib/pipes/gt-row-class.pipe.metadata.json +0 -1
  209. package/esm5/lib/pipes/gt-search.pipe.js +0 -125
  210. package/esm5/lib/pipes/gt-search.pipe.metadata.json +0 -1
  211. package/esm5/lib/pipes/gt-totals-position.pipe.js +0 -45
  212. package/esm5/lib/pipes/gt-totals-position.pipe.metadata.json +0 -1
  213. package/esm5/lib/pipes/gt-totals.pipe.js +0 -57
  214. package/esm5/lib/pipes/gt-totals.pipe.metadata.json +0 -1
  215. package/esm5/lib/pipes/gt-visible.pipe.js +0 -79
  216. package/esm5/lib/pipes/gt-visible.pipe.metadata.json +0 -1
  217. package/esm5/public_api.js +0 -18
  218. package/esm5/public_api.metadata.json +0 -1
  219. package/fesm2015/angular-generic-table-core.js +0 -3285
  220. package/fesm2015/angular-generic-table-core.js.map +0 -1
  221. package/fesm5/angular-generic-table-core.js +0 -3574
  222. package/fesm5/angular-generic-table-core.js.map +0 -1
  223. package/lib/components/generic-table/generic-table.component.d.ts +0 -282
  224. package/lib/components/gt-checkbox/gt-checkbox.component.d.ts +0 -12
  225. package/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.d.ts +0 -27
  226. package/lib/components/gt-drilldown/gt-drilldown.component.d.ts +0 -6
  227. package/lib/components/gt-dropdown/gt-dropdown.component.d.ts +0 -21
  228. package/lib/components/gt-expanding-row/gt-expanding-row.component.d.ts +0 -34
  229. package/lib/components/gt-pagination/gt-pagination.component.d.ts +0 -11
  230. package/lib/components/gt-table-info/gt-table-info.component.d.ts +0 -15
  231. package/lib/directives/component-anchor.directive.d.ts +0 -10
  232. package/lib/directives/gt-column-width.directive.d.ts +0 -11
  233. package/lib/interfaces/gt-config-field.d.ts +0 -87
  234. package/lib/interfaces/gt-config-setting.d.ts +0 -21
  235. package/lib/interfaces/gt-config-total.d.ts +0 -8
  236. package/lib/interfaces/gt-config.d.ts +0 -12
  237. package/lib/interfaces/gt-event.d.ts +0 -4
  238. package/lib/interfaces/gt-information.d.ts +0 -15
  239. package/lib/interfaces/gt-options.d.ts +0 -27
  240. package/lib/interfaces/gt-render-field.d.ts +0 -19
  241. package/lib/interfaces/gt-row-meta.d.ts +0 -5
  242. package/lib/interfaces/gt-row.d.ts +0 -6
  243. package/lib/interfaces/gt-texts.d.ts +0 -14
  244. package/lib/pipes/gt-chunk.pipe.d.ts +0 -8
  245. package/lib/pipes/gt-column-class.pipe.d.ts +0 -6
  246. package/lib/pipes/gt-filter.pipe.d.ts +0 -5
  247. package/lib/pipes/gt-highlight.pipe.d.ts +0 -7
  248. package/lib/pipes/gt-is-editable.pipe.d.ts +0 -4
  249. package/lib/pipes/gt-is-observable.pipe.d.ts +0 -4
  250. package/lib/pipes/gt-meta.pipe.d.ts +0 -5
  251. package/lib/pipes/gt-order-by.pipe.d.ts +0 -11
  252. package/lib/pipes/gt-property.pipe.d.ts +0 -7
  253. package/lib/pipes/gt-render.pipe.d.ts +0 -19
  254. package/lib/pipes/gt-row-class.pipe.d.ts +0 -5
  255. package/lib/pipes/gt-search.pipe.d.ts +0 -10
  256. package/lib/pipes/gt-totals-position.pipe.d.ts +0 -5
  257. package/lib/pipes/gt-totals.pipe.d.ts +0 -4
  258. package/lib/pipes/gt-visible.pipe.d.ts +0 -9
  259. package/public_api.d.ts +0 -18
  260. package/scss/generic-table.scss +0 -246
@@ -1,3574 +0,0 @@
1
- import { Pipe, Component, EventEmitter, Input, Output, Renderer2, ChangeDetectorRef, HostBinding, ComponentFactoryResolver, Directive, ViewContainerRef, ElementRef, HostListener, NgModule } from '@angular/core';
2
- import { __spread, __extends, __assign } from 'tslib';
3
- import { Subject, ReplaySubject, Observable } from 'rxjs';
4
- import * as Tether from 'tether';
5
- import { DomSanitizer } from '@angular/platform-browser';
6
- import { CommonModule } from '@angular/common';
7
- import { FormsModule } from '@angular/forms';
8
-
9
- /**
10
- * @fileoverview added by tsickle
11
- * @suppress {checkTypes} checked by tsc
12
- */
13
- var GtMetaPipe = /** @class */ (function () {
14
- function GtMetaPipe() {
15
- }
16
- /**
17
- * @param {?} allRows
18
- * @param {?=} rowIndex
19
- * @param {?=} page
20
- * @param {?=} recordLength
21
- * @return {?}
22
- */
23
- GtMetaPipe.prototype.transform = /**
24
- * @param {?} allRows
25
- * @param {?=} rowIndex
26
- * @param {?=} page
27
- * @param {?=} recordLength
28
- * @return {?}
29
- */
30
- function (allRows, rowIndex, page, recordLength) {
31
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
32
- if (!allRows[i].$$gtRowId) {
33
- allRows[i].$$gtRowId = rowIndex
34
- ? allRows[i][rowIndex]
35
- : page
36
- ? page * recordLength +
37
- i +
38
- '_' +
39
- Math.random()
40
- .toString(36)
41
- .substr(2, 16)
42
- : i +
43
- '_' +
44
- Math.random()
45
- .toString(36)
46
- .substr(2, 16);
47
- }
48
- if (!allRows[i].$$gtInitialRowIndex) {
49
- allRows[i].$$gtInitialRowIndex = i;
50
- }
51
- }
52
- return allRows;
53
- };
54
- GtMetaPipe.decorators = [
55
- { type: Pipe, args: [{
56
- name: 'gtMeta'
57
- },] }
58
- ];
59
- return GtMetaPipe;
60
- }());
61
-
62
- /**
63
- * @fileoverview added by tsickle
64
- * @suppress {checkTypes} checked by tsc
65
- */
66
- // unsupported: template constraints.
67
- // unsupported: template constraints.
68
- /**
69
- * @template R, C
70
- */
71
- var GenericTableComponent = /** @class */ (function () {
72
- function GenericTableComponent(renderer, gtMetaPipe) {
73
- var _this = this;
74
- this.renderer = renderer;
75
- this.gtMetaPipe = gtMetaPipe;
76
- this.columnWidth = {};
77
- this.sortOrder = [];
78
- this.metaInfo = {};
79
- this.selectedRows = [];
80
- this.openRows = [];
81
- this._gtSettings = [];
82
- this._gtFields = [];
83
- this.gtDefaultTexts = {
84
- loading: 'Loading...',
85
- noData: 'No data',
86
- noMatchingData: 'No data matching results found',
87
- noVisibleColumnsHeading: 'No visible columns',
88
- noVisibleColumns: 'Please select at least one column to be visible.',
89
- tableInfo: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries.',
90
- tableInfoAfterSearch: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries (filtered from a total of #recordsAll entries).',
91
- csvDownload: 'download',
92
- sortLabel: 'Sort:',
93
- paginateNext: 'Next page',
94
- paginatePrevious: 'Previous page',
95
- inlineEditEdited: 'Press enter to save'
96
- };
97
- this.gtTexts = this.gtDefaultTexts;
98
- this.gtEvent = new EventEmitter();
99
- this.gtDefaultOptions = {
100
- csvDelimiter: ';',
101
- stack: false,
102
- lazyLoad: false,
103
- cache: false,
104
- debounceTime: 200,
105
- highlightSearch: false,
106
- rowSelection: false,
107
- rowSelectionAllowMultiple: true,
108
- rowExpandAllowMultiple: true,
109
- numberOfRows: 10,
110
- reportColumnWidth: false,
111
- allowUnsorted: true,
112
- mutateData: true
113
- };
114
- this._gtOptions = this.gtDefaultOptions;
115
- this.store = [];
116
- this.loading = true;
117
- this.debounceTimer = null;
118
- this.lazyAllSelected = false;
119
- this.gtInfo = {
120
- pageCurrent: 1,
121
- pageTotal: 0,
122
- recordFrom: 0,
123
- recordTo: 0,
124
- recordLength: this.gtOptions.numberOfRows,
125
- recordsAll: 0,
126
- recordsAfterFilter: 0,
127
- recordsAfterSearch: 0
128
- };
129
- this.refreshPipe = false;
130
- this.refreshTotals = false;
131
- this.refreshSorting = false;
132
- this.refreshFilter = false;
133
- this.refreshPageArray = false;
134
- this.editedRows = {};
135
- this.data = { exportData: [] };
136
- /**
137
- * Sort table by object key.
138
- * @param objectKey - name of key to sort on.
139
- * @param event - such as key press during sorting.
140
- */
141
- this.gtSort = function (objectKey, event) {
142
- this.inlineEditCancel(); // cancel inline editing
143
- // loop through current settings
144
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
145
- if (this._gtSettings[i].objectKey === objectKey) {
146
- // check if sorting is disabled...
147
- if (this._gtSettings[i].sort &&
148
- this._gtSettings[i].sort.indexOf('disable') !== -1) {
149
- // ...if so, exit function without applying any sorting
150
- return;
151
- }
152
- else if (/* check if sorting is undefined... */ typeof this._gtSettings[i]
153
- .sort === 'undefined') {
154
- // ...is so, set sorting property to enable
155
- this._gtSettings[i].sort = 'enable';
156
- }
157
- }
158
- }
159
- // check length
160
- var /** @type {?} */ ctrlKey = event.metaKey || event.ctrlKey;
161
- var /** @type {?} */ sort = this.sortOrder.slice(0);
162
- var /** @type {?} */ match = -1;
163
- var /** @type {?} */ matchDesc = -1;
164
- var /** @type {?} */ pos = -1;
165
- // check if property already exits
166
- for (var /** @type {?} */ i = 0; i < sort.length; i++) {
167
- var /** @type {?} */ hit = sort[i].indexOf(objectKey);
168
- if (hit !== -1) {
169
- match = this.sortOrder.indexOf(objectKey);
170
- matchDesc =
171
- match === -1 ? this.sortOrder.indexOf('-' + objectKey) : match;
172
- pos = Math.max(match, matchDesc);
173
- }
174
- }
175
- // if ctrl key or meta key is press together with sort...
176
- if (ctrlKey) {
177
- if (this.sortOrder[this.sortOrder.length - 1] === '$$gtInitialRowIndex') {
178
- this.sortOrder.pop();
179
- }
180
- switch (pos) {
181
- // ...and property is not sorted before...
182
- case -1:
183
- // ...add property to sorting
184
- this.sortOrder.push(objectKey);
185
- break;
186
- default:
187
- // ...and property is sorted before...
188
- if (match !== -1) {
189
- // ...change from asc to desc if sorted asc
190
- this.sortOrder[pos] = '-' + objectKey;
191
- }
192
- else if (this.sortOrder.length > 1) {
193
- // ...remove sorting if sorted desc
194
- if (ctrlKey) {
195
- this.sortOrder[pos] = objectKey;
196
- }
197
- else {
198
- this.sortOrder.splice(pos, 1);
199
- }
200
- }
201
- else if (this.sortOrder.length === 1) {
202
- // ...set sorting to asc if only sorted property
203
- this.sortOrder[pos] = objectKey;
204
- }
205
- break;
206
- }
207
- }
208
- else {
209
- /* if ctrl key or meta key is not press together with sort... */
210
- switch (pos) {
211
- // ...and property is not sorted before...
212
- case -1:
213
- // ...sort by property
214
- this.sortOrder = [objectKey];
215
- break;
216
- default:
217
- // ...change from desc to asc and vise versa
218
- this.sortOrder =
219
- match !== -1
220
- ? ['-' + objectKey]
221
- : ctrlKey || !this.gtOptions.allowUnsorted
222
- ? [objectKey]
223
- : [];
224
- break;
225
- }
226
- }
227
- // update settings object with new sorting information
228
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
229
- if (this._gtSettings[i].objectKey === objectKey) {
230
- switch (this._gtSettings[i].sort) {
231
- // if sorted asc...
232
- case 'asc':
233
- // ...change to desc
234
- this._gtSettings[i].sort = 'desc';
235
- break;
236
- // if sorted desc...
237
- case 'desc':
238
- // ...change to asc if it's the only sorted property otherwise remove sorting
239
- this._gtSettings[i].sort =
240
- (this.sortOrder.length === 1 && sort.length < 2) ||
241
- ctrlKey ||
242
- !this.gtOptions.allowUnsorted
243
- ? 'asc'
244
- : 'enable';
245
- break;
246
- // if sorting enabled...
247
- case 'enable':
248
- // ...change to asc
249
- this._gtSettings[i].sort = 'asc';
250
- break;
251
- }
252
- this._gtSettings[i].sortOrder =
253
- this._gtSettings[i].sort === 'enable'
254
- ? this._gtSettings.length - 1
255
- : this.sortOrder.indexOf(objectKey) === -1
256
- ? this.sortOrder.indexOf('-' + objectKey)
257
- : this.sortOrder.indexOf(objectKey);
258
- }
259
- else if (this._gtSettings[i].sort &&
260
- this._gtSettings[i].sort.indexOf('disable') === -1 &&
261
- this.sortOrder.indexOf(this._gtSettings[i].objectKey) === -1 &&
262
- this.sortOrder.indexOf('-' + this._gtSettings[i].objectKey) === -1) {
263
- this._gtSettings[i].sort = 'enable';
264
- this._gtSettings[i].sortOrder = this._gtSettings.length - 1;
265
- }
266
- }
267
- // refresh sorting pipe
268
- this.refreshSorting = !this.refreshSorting;
269
- this.refreshPageArray = !this.refreshPageArray;
270
- // sort by initial sort order as last resort
271
- this.sortOrder.push('$$gtInitialRowIndex');
272
- // emit sort event
273
- this.gtEvent.emit({
274
- name: 'gt-sorting-applied',
275
- value: this.sortOrder
276
- });
277
- };
278
- /**
279
- * Change number of rows to be displayed.
280
- * @param rowLength - total number of rows.
281
- * @param reset - should page be reset to first page.
282
- */
283
- this.changeRowLength = function (rowLength, reset) {
284
- var /** @type {?} */ lengthValue = isNaN(parseInt(rowLength, 10))
285
- ? 0
286
- : parseInt(rowLength, 10);
287
- var /** @type {?} */ newPosition = 1;
288
- if (!lengthValue && this.gtData) {
289
- lengthValue = this.gtData.length;
290
- }
291
- // if reset is not true and we're not lazy loading data...
292
- if (reset !== true && this._gtOptions.lazyLoad !== true) {
293
- // ...get current position in record set
294
- var /** @type {?} */ currentRecord = this.gtInfo.recordLength * (this.gtInfo.pageCurrent - 1);
295
- var /** @type {?} */ currentPosition = this._gtData.indexOf(this._gtData[currentRecord]) + 1;
296
- // ...get new position
297
- newPosition = Math.ceil(currentPosition / lengthValue);
298
- }
299
- // change row length
300
- this.gtInfo.recordLength = lengthValue;
301
- // go to new position
302
- this.gtInfo.pageCurrent = newPosition;
303
- // if lazy loading data...
304
- if (this._gtOptions.lazyLoad) {
305
- // ...replace data with place holders for new data
306
- this._gtData[0] = this.loadingContent(lengthValue);
307
- // ...empty current store
308
- this.store = [];
309
- }
310
- // this.updateRecordRange();
311
- this.gtEvent.emit({
312
- name: 'gt-row-length-changed',
313
- value: lengthValue
314
- });
315
- };
316
- /**
317
- * Force a redraw of table rows.
318
- * As the table uses pure pipes, we need to force a redraw if an object in the array is changed to see the changes.
319
- */
320
- this.redraw = function ($event) {
321
- this.refreshSorting = !this.refreshSorting;
322
- this.refreshPageArray = !this.refreshPageArray;
323
- this.refreshPipe = !this.refreshPipe;
324
- };
325
- /**
326
- * Go to next page.
327
- */
328
- this.nextPage = function () {
329
- var /** @type {?} */ page = this.gtInfo.pageCurrent === this.gtInfo.pageTotal
330
- ? this.gtInfo.pageTotal
331
- : this.gtInfo.pageCurrent + 1;
332
- this.goToPage(page);
333
- };
334
- /**
335
- * Go to previous page.
336
- */
337
- this.previousPage = function () {
338
- var /** @type {?} */ page = this.gtInfo.pageCurrent === 1 ? 1 : this.gtInfo.pageCurrent - 1;
339
- this.goToPage(page);
340
- };
341
- /**
342
- * Request more data (used when lazy loading)
343
- */
344
- this.getData = function () {
345
- // ...emit event requesting for more data
346
- this.gtEvent.emit({
347
- name: 'gt-page-changed-lazy',
348
- value: {
349
- pageCurrent: this.gtInfo.pageCurrent,
350
- recordLength: this.gtInfo.recordLength
351
- }
352
- });
353
- };
354
- /**
355
- * Go to specific page.
356
- * @param page - page number.
357
- */
358
- this.goToPage = function (page) {
359
- var _this = this;
360
- var /** @type {?} */ previousPage = this.gtInfo.pageCurrent;
361
- this.gtInfo.pageCurrent = page;
362
- this.inlineEditCancel(); // cancel inline edit
363
- // if lazy loading and if page contains no records...
364
- if (this._gtOptions.lazyLoad) {
365
- // ...if data for current page contains no entries...
366
- if (this._gtOptions.cache === false ||
367
- this._gtData[this.gtInfo.pageCurrent - 1].length === 0) {
368
- // ...create temporary content while waiting for data
369
- this._gtData[this.gtInfo.pageCurrent - 1] = this.loadingContent(this.gtInfo.recordLength);
370
- this.loading = true; // loading true
371
- }
372
- // ...if first entry in current page equals our loading placeholder...
373
- if (this._gtData[this.gtInfo.pageCurrent - 1][0][this.loadingProperty] ===
374
- this.gtTexts.loading) {
375
- // ...get data
376
- clearTimeout(this.debounceTimer);
377
- this.debounceTimer = setTimeout(function () {
378
- _this.getData();
379
- }, this._gtOptions.debounceTime);
380
- }
381
- }
382
- // this.updateRecordRange();
383
- // ...emit page change event
384
- if (previousPage !== page) {
385
- this.gtEvent.emit({
386
- name: 'gt-page-changed',
387
- value: {
388
- pageCurrent: this.gtInfo.pageCurrent,
389
- pagePrevious: previousPage,
390
- recordLength: this.gtInfo.recordLength
391
- }
392
- });
393
- }
394
- };
395
- /**
396
- * Sort by sort order
397
- */
398
- this.getSortOrder = function (a, b) {
399
- if (a.sortOrder < b.sortOrder) {
400
- return -1;
401
- }
402
- if (a.sortOrder > b.sortOrder || typeof a.sortOrder === 'undefined') {
403
- return 1;
404
- }
405
- return 0;
406
- };
407
- /**
408
- * Sort by column order
409
- */
410
- this.getColumnOrder = function (a, b) {
411
- if (a.columnOrder === undefined) {
412
- return -1;
413
- }
414
- if (a.columnOrder < b.columnOrder) {
415
- return -1;
416
- }
417
- if (a.columnOrder > b.columnOrder) {
418
- return 1;
419
- }
420
- return 0;
421
- };
422
- /**
423
- * Create a deep copy of data
424
- */
425
- this.cloneDeep = function (o) {
426
- return JSON.parse(JSON.stringify(o));
427
- };
428
- /**
429
- * Return property
430
- */
431
- this.getProperty = function (array, key) {
432
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
433
- if (array[i].objectKey === key) {
434
- return array[i];
435
- }
436
- }
437
- };
438
- this.restructureSorting = function () {
439
- /**
440
- * Check and store sort order upon initialization.
441
- * This is done by checking sort properties in the settings array of the table, if no sorting is defined
442
- * we'll sort the data by the first visible and enabled column in the table(ascending). Please note that actually
443
- * sorting have to be done server side when lazy loading data for obvious reasons.
444
- */
445
- var /** @type {?} */ sorting = [];
446
- if (this._gtSettings) {
447
- // ...sort settings by sort order
448
- this._gtSettings.sort(this.getSortOrder);
449
- // ...loop through settings
450
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
451
- var /** @type {?} */ setting = this._gtSettings[i];
452
- // ...if sorted ascending...
453
- if (setting.sort === 'asc') {
454
- // ... add to sorting
455
- sorting.push(setting.objectKey);
456
- }
457
- else if (setting.sort === 'desc') {
458
- /* ...else if sorted descending... */
459
- // ... add to sorting
460
- sorting.push('-' + setting.objectKey);
461
- }
462
- }
463
- // ...if no sorting applied...
464
- if (sorting.length === 0) {
465
- sorting.push('$$gtRowId');
466
- /*// ...sort settings by column order
467
- this._gtSettings.sort(this.getColumnOrder);
468
-
469
- // ...loop through settings
470
- for (let i = 0; i < this._gtSettings.length; i++) {
471
- const setting = this._gtSettings[i];
472
-
473
- // ...if column is enabled and visible...
474
- if (setting.enabled !== false && setting.visible !== false) {
475
- // ...add first match and exit function
476
- this.sortOrder = [this._gtSettings[i].objectKey];
477
- return;
478
- }
479
- }*/
480
- }
481
- }
482
- if (this.sortOrder.length === 0) {
483
- this.sortOrder = sorting;
484
- }
485
- };
486
- /**
487
- * Extend object function.
488
- */
489
- this.extend = function (a, b) {
490
- for (var /** @type {?} */ key in b) {
491
- if (b.hasOwnProperty(key)) {
492
- a[key] = b[key];
493
- }
494
- }
495
- return a;
496
- };
497
- this.gtEvent.subscribe(function ($event) {
498
- if ($event.name === 'gt-info') {
499
- _this.updateRecordRange();
500
- }
501
- if ($event.name === 'gt-row-updated') {
502
- _this.updateTotals();
503
- }
504
- });
505
- }
506
- Object.defineProperty(GenericTableComponent.prototype, "gtRowComponent", {
507
- get: /**
508
- * @return {?}
509
- */
510
- function () {
511
- return this._gtRowComponent;
512
- },
513
- set: /**
514
- * @param {?} value
515
- * @return {?}
516
- */
517
- function (value) {
518
- console.warn('GtRowComponent has been deprecated and support will be removed in a future release, see https://github.com/hjalmers/angular-generic-table/issues/34');
519
- this._gtRowComponent = value;
520
- },
521
- enumerable: true,
522
- configurable: true
523
- });
524
- Object.defineProperty(GenericTableComponent.prototype, "hasEdits", {
525
- get: /**
526
- * @return {?}
527
- */
528
- function () {
529
- return Object.keys(this.editedRows).length > 0;
530
- },
531
- enumerable: true,
532
- configurable: true
533
- });
534
- Object.defineProperty(GenericTableComponent.prototype, "gtOptions", {
535
- get: /**
536
- * @return {?}
537
- */
538
- function () {
539
- return this._gtOptions;
540
- },
541
- set: /**
542
- * @param {?} value
543
- * @return {?}
544
- */
545
- function (value) {
546
- this._gtOptions = value;
547
- // if number of rows is passed and if number of rows differs from current record length...
548
- if (this.gtOptions.numberOfRows &&
549
- this.gtInfo.recordLength !== this.gtOptions.numberOfRows) {
550
- // ...update record length and redraw table
551
- this.gtInfo.recordLength = this.gtOptions.numberOfRows;
552
- this.redraw();
553
- }
554
- // ...extend gtOptions default values with values passed into component
555
- this._gtOptions = /** @type {?} */ (this.extend(this.gtDefaultOptions, this._gtOptions));
556
- },
557
- enumerable: true,
558
- configurable: true
559
- });
560
- Object.defineProperty(GenericTableComponent.prototype, "gtTotals", {
561
- get: /**
562
- * @return {?}
563
- */
564
- function () {
565
- return this._gtTotals;
566
- },
567
- set: /**
568
- * @param {?} value
569
- * @return {?}
570
- */
571
- function (value) {
572
- this._gtTotals = value;
573
- },
574
- enumerable: true,
575
- configurable: true
576
- });
577
- Object.defineProperty(GenericTableComponent.prototype, "gtFields", {
578
- get: /**
579
- * @return {?}
580
- */
581
- function () {
582
- return this._gtFields;
583
- },
584
- set: /**
585
- * @param {?} value
586
- * @return {?}
587
- */
588
- function (value) {
589
- this._gtFields = value;
590
- var /** @type {?} */ COLUMNS_WITH_CLASS_NAMES = this._gtFields
591
- .map(function (column) { return column; })
592
- .filter(function (column) { return column.classNames; });
593
- // TODO: remove deprecated warning when setting has been removed
594
- if (COLUMNS_WITH_CLASS_NAMES.length > 0) {
595
- console.warn('Field setting "classNames" have been deprecated in favor for "columnClass" and will be removed in the future, please update field settings for column with object key: ' +
596
- COLUMNS_WITH_CLASS_NAMES[0].objectKey);
597
- }
598
- },
599
- enumerable: true,
600
- configurable: true
601
- });
602
- Object.defineProperty(GenericTableComponent.prototype, "gtSettings", {
603
- get: /**
604
- * @return {?}
605
- */
606
- function () {
607
- return this._gtSettings;
608
- },
609
- set: /**
610
- * @param {?} value
611
- * @return {?}
612
- */
613
- function (value) {
614
- this._gtSettings = value;
615
- // loop through current settings
616
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
617
- // set sort enabled/disabled setting
618
- this._gtSettings[i].sortEnabled =
619
- this._gtSettings[i].sortEnabled !== false
620
- ? (this._gtSettings[i].sortEnabled = !(this._gtSettings[i].sort &&
621
- this._gtSettings[i].sort.indexOf('disable') !== -1))
622
- : false;
623
- // check if sorting is undefined...
624
- if (typeof this._gtSettings[i].sort === 'undefined') {
625
- // ...is so, set sorting property to enable
626
- this._gtSettings[i].sort = 'enable';
627
- }
628
- // check if column order is undefined...
629
- if (typeof this._gtSettings[i].columnOrder === 'undefined' &&
630
- this._gtSettings[i].enabled !== false) {
631
- // ...is so, set sorting property to enable
632
- this._gtSettings[i].columnOrder = this._gtSettings[i - 1]
633
- ? this._gtSettings[i - 1].columnOrder + 1
634
- : 0;
635
- }
636
- // check if column lock settings are undefined...
637
- if (typeof this._gtSettings[i].lockSettings === 'undefined') {
638
- // ...if so, set lock settings to false unless field is disabled (enable === false)
639
- this._gtSettings[i].lockSettings =
640
- this._gtSettings[i].enabled === false || false;
641
- }
642
- }
643
- this.restructureSorting();
644
- },
645
- enumerable: true,
646
- configurable: true
647
- });
648
- Object.defineProperty(GenericTableComponent.prototype, "gtData", {
649
- get: /**
650
- * @return {?}
651
- */
652
- function () {
653
- return this._gtData;
654
- },
655
- set: /**
656
- * @param {?} initialData
657
- * @return {?}
658
- */
659
- function (initialData) {
660
- var _this = this;
661
- var /** @type {?} */ data = this._gtOptions.mutateData
662
- ? __spread(initialData) : this.cloneDeep(initialData);
663
- if (this.gtOptions.lazyLoad && this.gtInfo) {
664
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex, this.gtInfo.pageCurrent - 1, this.gtInfo.recordLength);
665
- if (this.lazyAllSelected) {
666
- var /** @type {?} */ UNIQUE_ROWS_1 = this.selectedRows.map(function (row) { return row.$$gtRowId; });
667
- data.map(function (row) {
668
- if (UNIQUE_ROWS_1.indexOf(row.$$gtRowId) === -1) {
669
- _this.selectedRows.push(row);
670
- }
671
- });
672
- this._updateMetaInfo(this.selectedRows, 'isSelected', true);
673
- }
674
- }
675
- else {
676
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex);
677
- }
678
- if (this.gtOptions.rowSelectionInitialState) {
679
- data.map(function (row) {
680
- var /** @type {?} */ selected = typeof _this.gtOptions.rowSelectionInitialState === 'function'
681
- ? _this.gtOptions.rowSelectionInitialState(row)
682
- : _this.gtOptions.rowSelectionInitialState;
683
- if (selected) {
684
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
685
- _this.metaInfo[row.$$gtRowId] = { isSelected: true };
686
- }
687
- else {
688
- _this.metaInfo[row.$$gtRowId].isSelected = true;
689
- }
690
- _this.selectedRows.push(row);
691
- }
692
- });
693
- }
694
- if (this.gtOptions.rowExpandInitialState &&
695
- this.gtOptions.rowExpandInitialComponent) {
696
- data.map(function (row) {
697
- var /** @type {?} */ expanded = typeof _this.gtOptions.rowExpandInitialState === 'function'
698
- ? _this.gtOptions.rowExpandInitialState(row)
699
- : _this.gtOptions.rowExpandInitialState;
700
- _this.expandedRow = _this.gtOptions.rowExpandInitialComponent;
701
- if (expanded) {
702
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
703
- _this.metaInfo[row.$$gtRowId] = { isOpen: true };
704
- }
705
- else {
706
- _this.metaInfo[row.$$gtRowId].isOpen = true;
707
- }
708
- }
709
- });
710
- }
711
- this._gtData = data;
712
- },
713
- enumerable: true,
714
- configurable: true
715
- });
716
- /**
717
- * Update record range.
718
- * @return {?}
719
- */
720
- GenericTableComponent.prototype.updateRecordRange = /**
721
- * Update record range.
722
- * @return {?}
723
- */
724
- function () {
725
- this.gtInfo.recordFrom =
726
- this.gtInfo.recordsAfterSearch === 0
727
- ? 0
728
- : (this.gtInfo.pageCurrent - 1) * this.gtInfo.recordLength + 1;
729
- this.gtInfo.recordTo =
730
- this.gtInfo.recordsAfterSearch <
731
- this.gtInfo.pageCurrent * this.gtInfo.recordLength
732
- ? this.gtInfo.recordsAfterSearch
733
- : this.gtInfo.pageCurrent * this.gtInfo.recordLength;
734
- };
735
- /**
736
- * Update totals.
737
- * @return {?}
738
- */
739
- GenericTableComponent.prototype.updateTotals = /**
740
- * Update totals.
741
- * @return {?}
742
- */
743
- function () {
744
- this.refreshTotals = !this.refreshTotals;
745
- };
746
- /**
747
- * Get meta data for row.
748
- * @param {?} row
749
- * @return {?}
750
- */
751
- GenericTableComponent.prototype.getRowState = /**
752
- * Get meta data for row.
753
- * @param {?} row
754
- * @return {?}
755
- */
756
- function (row) {
757
- return typeof this.metaInfo[row.$$gtRowId] === 'undefined'
758
- ? null
759
- : this.metaInfo[row.$$gtRowId];
760
- };
761
- /**
762
- * Expand all rows.
763
- * @param {?} expandedRow - component to render when rows are expanded.
764
- * @return {?}
765
- */
766
- GenericTableComponent.prototype.expandAllRows = /**
767
- * Expand all rows.
768
- * @param {?} expandedRow - component to render when rows are expanded.
769
- * @return {?}
770
- */
771
- function (expandedRow) {
772
- this.expandedRow = expandedRow;
773
- this._toggleAllRowProperty('isOpen', true);
774
- };
775
- /**
776
- * Collapse all rows.
777
- * @return {?}
778
- */
779
- GenericTableComponent.prototype.collapseAllRows = /**
780
- * Collapse all rows.
781
- * @return {?}
782
- */
783
- function () {
784
- this._toggleAllRowProperty('isOpen', false);
785
- };
786
- /**
787
- * Select all rows.
788
- * @return {?}
789
- */
790
- GenericTableComponent.prototype.selectAllRows = /**
791
- * Select all rows.
792
- * @return {?}
793
- */
794
- function () {
795
- this._toggleAllRowProperty('isSelected', true);
796
- };
797
- /**
798
- * Deselect all rows.
799
- * @return {?}
800
- */
801
- GenericTableComponent.prototype.deselectAllRows = /**
802
- * Deselect all rows.
803
- * @return {?}
804
- */
805
- function () {
806
- this._toggleAllRowProperty('isSelected', false);
807
- };
808
- /**
809
- * Toggle all rows.
810
- * @return {?}
811
- */
812
- GenericTableComponent.prototype.toggleAllRows = /**
813
- * Toggle all rows.
814
- * @return {?}
815
- */
816
- function () {
817
- if (this._gtOptions.lazyLoad) {
818
- if (!this.lazyAllSelected || this.selectedRows.length === 0) {
819
- this.selectAllRows();
820
- this.lazyAllSelected = true;
821
- }
822
- else {
823
- this.deselectAllRows();
824
- this.lazyAllSelected = false;
825
- }
826
- }
827
- else {
828
- if (this.selectedRows.length !== this.gtData.length) {
829
- this.selectAllRows();
830
- }
831
- else {
832
- this.deselectAllRows();
833
- }
834
- }
835
- };
836
- /**
837
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
838
- * @param {?} row - row object that should be expanded/collapsed.
839
- * @param {?=} expandedRow - component to render when row is expanded.
840
- * @return {?}
841
- */
842
- GenericTableComponent.prototype.toggleCollapse = /**
843
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
844
- * @param {?} row - row object that should be expanded/collapsed.
845
- * @param {?=} expandedRow - component to render when row is expanded.
846
- * @return {?}
847
- */
848
- function (row, expandedRow) {
849
- if (expandedRow) {
850
- this.expandedRow = expandedRow;
851
- }
852
- this._toggleRowProperty(row, 'isOpen');
853
- };
854
- /**
855
- * Toggle row selected state ie. selected or not.
856
- * @param {?} row - row object that should be selected/deselected.
857
- * @return {?}
858
- */
859
- GenericTableComponent.prototype.toggleSelect = /**
860
- * Toggle row selected state ie. selected or not.
861
- * @param {?} row - row object that should be selected/deselected.
862
- * @return {?}
863
- */
864
- function (row) {
865
- this._toggleRowProperty(row, 'isSelected');
866
- };
867
- /**
868
- * @param {?} row
869
- * @param {?} $event
870
- * @return {?}
871
- */
872
- GenericTableComponent.prototype.rowClick = /**
873
- * @param {?} row
874
- * @param {?} $event
875
- * @return {?}
876
- */
877
- function (row, $event) {
878
- this.gtEvent.emit({
879
- name: 'gt-row-clicked',
880
- value: { row: row, event: $event }
881
- });
882
- };
883
- /**
884
- * Update row data.
885
- * @param {?} row - row object that has been edited.
886
- * @param {?} oldValue - row object before edit.
887
- * @return {?}
888
- */
889
- GenericTableComponent.prototype.updateRow = /**
890
- * Update row data.
891
- * @param {?} row - row object that has been edited.
892
- * @param {?} oldValue - row object before edit.
893
- * @return {?}
894
- */
895
- function (row, oldValue) {
896
- this._toggleRowProperty(row, 'isUpdated', oldValue);
897
- };
898
- /**
899
- * removes a row from the table
900
- * @param {?} row - the row object to remove
901
- * @return {?}
902
- */
903
- GenericTableComponent.prototype.removeRow = /**
904
- * removes a row from the table
905
- * @param {?} row - the row object to remove
906
- * @return {?}
907
- */
908
- function (row) {
909
- if (this.isRowSelected(row)) {
910
- this.toggleSelect(row);
911
- }
912
- var /** @type {?} */ index = this._gtData.indexOf(row);
913
- this._gtData.splice(index, 1);
914
- };
915
- /**
916
- * check if a row is selected
917
- * @param {?} row - row object
918
- * @return {?}
919
- */
920
- GenericTableComponent.prototype.isRowSelected = /**
921
- * check if a row is selected
922
- * @param {?} row - row object
923
- * @return {?}
924
- */
925
- function (row) {
926
- return (this.metaInfo[row.$$gtRowId] && this.metaInfo[row.$$gtRowId].isSelected);
927
- };
928
- /**
929
- * Update meta info for all rows, ie. isSelected, isOpen.
930
- * @param {?} array - array that holds rows that need to be updated.
931
- * @param {?} property - name of property that should be changed/toggled.
932
- * @param {?} active - should rows be expanded/open, selected.
933
- * @param {?=} exception - update all rows except this one.
934
- * @return {?}
935
- */
936
- GenericTableComponent.prototype._updateMetaInfo = /**
937
- * Update meta info for all rows, ie. isSelected, isOpen.
938
- * @param {?} array - array that holds rows that need to be updated.
939
- * @param {?} property - name of property that should be changed/toggled.
940
- * @param {?} active - should rows be expanded/open, selected.
941
- * @param {?=} exception - update all rows except this one.
942
- * @return {?}
943
- */
944
- function (array, property, active, exception) {
945
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
946
- if (!this.metaInfo[array[i].$$gtRowId]) {
947
- this.metaInfo[array[i].$$gtRowId] = {};
948
- }
949
- if (exception && array[i].$$gtRowId === exception.$$gtRowId) ;
950
- else {
951
- this.metaInfo[array[i].$$gtRowId][property] = active;
952
- }
953
- }
954
- };
955
- /**
956
- * Push selected/expanded lazy loaded rows to array with meta data.
957
- * @param {?} target - array to which rows should be added.
958
- * @param {?} source - array that holds rows that should be added.
959
- * @return {?} array with added rows.
960
- */
961
- GenericTableComponent.prototype._pushLazyRows = /**
962
- * Push selected/expanded lazy loaded rows to array with meta data.
963
- * @param {?} target - array to which rows should be added.
964
- * @param {?} source - array that holds rows that should be added.
965
- * @return {?} array with added rows.
966
- */
967
- function (target, source) {
968
- var /** @type {?} */ UNIQUE_ROWS = target.map(function (row) { return row.$$gtRowId; });
969
- for (var /** @type {?} */ i = 0; i < source.length; i++) {
970
- // only add if not already in list
971
- if (UNIQUE_ROWS.indexOf(source[i].$$gtRowId) === -1) {
972
- target.push(source[i]);
973
- }
974
- }
975
- return target;
976
- };
977
- /**
978
- * Toggle meta info for all rows, ie. isSelected, isOpen.
979
- * @param {?} property - name of property that should be changed/toggled.
980
- * @param {?} active - should rows be expanded/open, selected.
981
- * @return {?}
982
- */
983
- GenericTableComponent.prototype._toggleAllRowProperty = /**
984
- * Toggle meta info for all rows, ie. isSelected, isOpen.
985
- * @param {?} property - name of property that should be changed/toggled.
986
- * @param {?} active - should rows be expanded/open, selected.
987
- * @return {?}
988
- */
989
- function (property, active) {
990
- var /** @type {?} */ eventName;
991
- var /** @type {?} */ eventValue;
992
- switch (property) {
993
- case 'isOpen':
994
- // check if multiple expanded rows are allowed...
995
- if (this._gtOptions.rowExpandAllowMultiple === false) {
996
- // ...if not, exit function
997
- console.log('feature disabled: enable by setting "rowExpandAllowMultiple = true"');
998
- return;
999
- }
1000
- if (active) {
1001
- eventName = 'expand-all';
1002
- this.openRows = this._gtOptions.lazyLoad
1003
- ? this._pushLazyRows(this.openRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
1004
- : this._gtData.slice();
1005
- this._updateMetaInfo(this.openRows, property, active);
1006
- }
1007
- else {
1008
- eventName = 'collapse-all';
1009
- this._updateMetaInfo(this.openRows, property, active);
1010
- this.openRows = [];
1011
- }
1012
- eventValue = {
1013
- expandedRows: this.openRows,
1014
- changedRow: 'all'
1015
- };
1016
- break;
1017
- case 'isSelected':
1018
- // check if multi row selection is allowed...
1019
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
1020
- // ...if not, exit function
1021
- console.log('feature disabled: enable by setting "rowSelectionAllowMultiple = true"');
1022
- return;
1023
- }
1024
- if (active) {
1025
- eventName = 'select-all';
1026
- this.selectedRows = this._gtOptions.lazyLoad
1027
- ? this._pushLazyRows(this.selectedRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
1028
- : this._gtData.slice();
1029
- this._updateMetaInfo(this.selectedRows, property, active);
1030
- }
1031
- else {
1032
- eventName = 'deselect-all';
1033
- this._updateMetaInfo(this.selectedRows, property, active);
1034
- this.selectedRows = [];
1035
- }
1036
- eventValue = {
1037
- selectedRows: this.selectedRows,
1038
- changedRow: 'all'
1039
- };
1040
- break;
1041
- }
1042
- this.gtEvent.emit({
1043
- name: 'gt-row-' + eventName,
1044
- value: eventValue
1045
- });
1046
- };
1047
- /**
1048
- * Toggle meta info for row, ie. isSelected, isOpen.
1049
- * @param {?} row - row object.
1050
- * @param {?} property - name of property that should be changed/toggled.
1051
- * @param {?=} propertyValues - optional property values that can be passed.
1052
- * @return {?}
1053
- */
1054
- GenericTableComponent.prototype._toggleRowProperty = /**
1055
- * Toggle meta info for row, ie. isSelected, isOpen.
1056
- * @param {?} row - row object.
1057
- * @param {?} property - name of property that should be changed/toggled.
1058
- * @param {?=} propertyValues - optional property values that can be passed.
1059
- * @return {?}
1060
- */
1061
- function (row, property, propertyValues) {
1062
- var /** @type {?} */ eventName;
1063
- var /** @type {?} */ eventValue;
1064
- // make sure gtRowId exists on row object
1065
- if (typeof row.$$gtRowId !== 'undefined') {
1066
- // check if meta info exists for row
1067
- if (!this.metaInfo[row.$$gtRowId]) {
1068
- // if not, add object to store meta info
1069
- this.metaInfo[row.$$gtRowId] = {};
1070
- }
1071
- switch (property) {
1072
- case 'isOpen':
1073
- var /** @type {?} */ opened = this.metaInfo[row.$$gtRowId][property];
1074
- // check if multiple expanded rows are allowed...
1075
- if (this._gtOptions.rowExpandAllowMultiple === false) {
1076
- // ...if not, collapse all rows except current row
1077
- this._updateMetaInfo(this.openRows, property, false, row);
1078
- this.openRows = [];
1079
- }
1080
- // check if row is expanded
1081
- if (!opened) {
1082
- eventName = 'expand';
1083
- // add row to expanded rows
1084
- this.openRows.push(row);
1085
- }
1086
- else {
1087
- eventName = 'collapse';
1088
- // loop through expanded rows...
1089
- for (var /** @type {?} */ i = 0; i < this.openRows.length; i++) {
1090
- // if expanded row equals passed row...
1091
- if (this.openRows[i].$$gtRowId === row.$$gtRowId) {
1092
- // ...remove row from expanded rows...
1093
- this.openRows.splice(i, 1);
1094
- // ...and exit loop
1095
- break;
1096
- }
1097
- }
1098
- }
1099
- eventValue = {
1100
- expandedRows: this.openRows,
1101
- changedRow: row
1102
- };
1103
- break;
1104
- case 'isSelected':
1105
- var /** @type {?} */ selected = this.metaInfo[row.$$gtRowId][property];
1106
- // check if multi row selection is allowed...
1107
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
1108
- // ...if not, deselect all rows except current row
1109
- this._updateMetaInfo(this.selectedRows, property, false, row);
1110
- this.selectedRows = [];
1111
- }
1112
- // check if row is selected
1113
- if (!selected) {
1114
- eventName = 'select';
1115
- // add row to selected rows
1116
- this.selectedRows.push(row);
1117
- }
1118
- else {
1119
- if (this.gtOptions.lazyLoad && this.lazyAllSelected) {
1120
- this.lazyAllSelected = false;
1121
- }
1122
- eventName = 'deselect';
1123
- // loop through selected rows...
1124
- for (var /** @type {?} */ i = 0; i < this.selectedRows.length; i++) {
1125
- // if selected row equals passed row...
1126
- if (this.selectedRows[i].$$gtRowId === row.$$gtRowId) {
1127
- // ...remove row from selected rows...
1128
- this.selectedRows.splice(i, 1);
1129
- // ...and exit loop
1130
- break;
1131
- }
1132
- }
1133
- }
1134
- eventValue = {
1135
- selectedRows: this.selectedRows,
1136
- changedRow: row
1137
- };
1138
- break;
1139
- case 'isUpdated':
1140
- eventName = 'updated';
1141
- var /** @type {?} */ oldValue = propertyValues;
1142
- // check if edit object exists for row
1143
- if (typeof this.metaInfo[row.$$gtRowId][property] === 'undefined') {
1144
- this.metaInfo[row.$$gtRowId][property] = {
1145
- originalValue: oldValue,
1146
- oldValue: oldValue,
1147
- newValue: row
1148
- };
1149
- }
1150
- else {
1151
- this.metaInfo[row.$$gtRowId][property].oldValue = oldValue;
1152
- this.metaInfo[row.$$gtRowId][property].newValue = row;
1153
- }
1154
- eventValue = this.metaInfo[row.$$gtRowId][property];
1155
- this.redraw();
1156
- this.inlineEditCancel(row);
1157
- // this.gtData = [...this.gtData.map((r) => { return{...r}; })];
1158
- break;
1159
- }
1160
- this.gtEvent.emit({
1161
- name: 'gt-row-' + eventName,
1162
- value: eventValue
1163
- });
1164
- if (property !== 'isUpdated') {
1165
- this.metaInfo[row.$$gtRowId][property] = !this.metaInfo[row.$$gtRowId][property];
1166
- }
1167
- }
1168
- };
1169
- /**
1170
- * Update column.
1171
- * @param {?} $event - key up event.
1172
- * @param {?} row - row object.
1173
- * @param {?} column - column object.
1174
- * @return {?}
1175
- */
1176
- GenericTableComponent.prototype.gtUpdateColumn = /**
1177
- * Update column.
1178
- * @param {?} $event - key up event.
1179
- * @param {?} row - row object.
1180
- * @param {?} column - column object.
1181
- * @return {?}
1182
- */
1183
- function ($event, row, column) {
1184
- this._editRow(row, column);
1185
- };
1186
- /**
1187
- * Dropdown select.
1188
- * @param {?} row - row object.
1189
- * @param {?} column - column object.
1190
- * @return {?}
1191
- */
1192
- GenericTableComponent.prototype.gtDropdownSelect = /**
1193
- * Dropdown select.
1194
- * @param {?} row - row object.
1195
- * @param {?} column - column object.
1196
- * @return {?}
1197
- */
1198
- function (row, column) {
1199
- var /** @type {?} */ oldValue = __assign({}, row);
1200
- row[column.objectKey] = column.renderValue;
1201
- this.updateRow(row, oldValue);
1202
- };
1203
- /**
1204
- * @param {?} row
1205
- * @param {?} column
1206
- * @return {?}
1207
- */
1208
- GenericTableComponent.prototype._editRow = /**
1209
- * @param {?} row
1210
- * @param {?} column
1211
- * @return {?}
1212
- */
1213
- function (row, column) {
1214
- var /** @type {?} */ OBJECT_KEY = column.objectKey; // declare object key which contains changes
1215
- // check if cell has changed value
1216
- column.edited = row[column.objectKey] !== column.renderValue;
1217
- // check if row contains changes...
1218
- if (!this.editedRows[row.$$gtRowId]) {
1219
- // if not, create an object for the changed row
1220
- this.editedRows[row.$$gtRowId] = {
1221
- changes: {},
1222
- // create placeholder for changes
1223
- row: row // store reference to the row that should be updated
1224
- };
1225
- }
1226
- // store changed column under changes if it has been edited
1227
- if (column.edited) {
1228
- this.editedRows[row.$$gtRowId].changes[OBJECT_KEY] = column;
1229
- }
1230
- else {
1231
- // delete change object if column is unchanged
1232
- delete this.editedRows[row.$$gtRowId].changes[OBJECT_KEY];
1233
- // check how many columns have been changed
1234
- var /** @type {?} */ CHANGED_COLUMNS = Object.keys(this.editedRows[row.$$gtRowId].changes).length;
1235
- if (CHANGED_COLUMNS === 0) {
1236
- // delete row from edited rows if no columns have been edited
1237
- delete this.editedRows[row.$$gtRowId];
1238
- }
1239
- }
1240
- // if no listener is present...
1241
- if (!this.globalInlineEditListener) {
1242
- // ...listen for update event
1243
- this._listenForKeydownEvent();
1244
- }
1245
- };
1246
- /**
1247
- * Listen for key down event - listen for key down event during inline edit.
1248
- * @return {?}
1249
- */
1250
- GenericTableComponent.prototype._listenForKeydownEvent = /**
1251
- * Listen for key down event - listen for key down event during inline edit.
1252
- * @return {?}
1253
- */
1254
- function () {
1255
- var _this = this;
1256
- // add global listener for key down events
1257
- this.globalInlineEditListener = this.renderer.listen('document', 'keydown', function ($event) {
1258
- switch ($event.key) {
1259
- case 'Enter': // update data object
1260
- // update data object
1261
- _this.inlineEditUpdate();
1262
- break;
1263
- case 'Escape': // cancel
1264
- // cancel
1265
- _this.inlineEditCancel();
1266
- break;
1267
- }
1268
- });
1269
- };
1270
- /**
1271
- * Inline edit update - accept changes and update row values.
1272
- * @return {?}
1273
- */
1274
- GenericTableComponent.prototype.inlineEditUpdate = /**
1275
- * Inline edit update - accept changes and update row values.
1276
- * @return {?}
1277
- */
1278
- function () {
1279
- var _this = this;
1280
- // loop through rows that have been edited
1281
- Object.keys(this.editedRows).map(function (key) {
1282
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
1283
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
1284
- // loop through changes in row
1285
- Object.keys(CHANGES).map(function (objectKey) {
1286
- var /** @type {?} */ oldValue = __assign({}, ROW);
1287
- ROW[objectKey] = CHANGES[objectKey].renderValue; // update data value
1288
- _this.updateRow(ROW, oldValue); // update meta info for row and send event
1289
- CHANGES[objectKey].edited = false; // disable edit mode
1290
- });
1291
- });
1292
- // clear rows marked as edited as the rows have been updated
1293
- this.editedRows = {};
1294
- // remove listener
1295
- this._stopListeningForKeydownEvent();
1296
- };
1297
- /**
1298
- * Inline edit cancel - cancel and reset inline edits.
1299
- * @param {?=} row
1300
- * @return {?}
1301
- */
1302
- GenericTableComponent.prototype.inlineEditCancel = /**
1303
- * Inline edit cancel - cancel and reset inline edits.
1304
- * @param {?=} row
1305
- * @return {?}
1306
- */
1307
- function (row) {
1308
- var _this = this;
1309
- if (row) {
1310
- delete this.editedRows[row.$$gtRowId];
1311
- // remove listener
1312
- this._stopListeningForKeydownEvent();
1313
- return;
1314
- }
1315
- // loop through rows that have been edited
1316
- Object.keys(this.editedRows).map(function (key) {
1317
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
1318
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
1319
- // loop through changes in row
1320
- Object.keys(CHANGES).map(function (objectKey) {
1321
- CHANGES[objectKey].renderValue = ROW[objectKey]; // reset rendered value
1322
- CHANGES[objectKey].edited = false; // disable edit mode
1323
- });
1324
- });
1325
- // clear rows marked as edited as the rows have been updated
1326
- this.editedRows = {};
1327
- // remove listener
1328
- this._stopListeningForKeydownEvent();
1329
- };
1330
- /**
1331
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
1332
- * @return {?}
1333
- */
1334
- GenericTableComponent.prototype._stopListeningForKeydownEvent = /**
1335
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
1336
- * @return {?}
1337
- */
1338
- function () {
1339
- if (this.globalInlineEditListener) {
1340
- this.globalInlineEditListener();
1341
- this.globalInlineEditListener = null;
1342
- }
1343
- };
1344
- /**
1345
- * Apply filter(s).
1346
- * @param {?} filter - object containing key value pairs, where value should be array of values.
1347
- * @return {?}
1348
- */
1349
- GenericTableComponent.prototype.gtApplyFilter = /**
1350
- * Apply filter(s).
1351
- * @param {?} filter - object containing key value pairs, where value should be array of values.
1352
- * @return {?}
1353
- */
1354
- function (filter) {
1355
- this.gtInfo.filter = filter;
1356
- // go to first page
1357
- this.goToPage(1);
1358
- this.updateTotals();
1359
- };
1360
- /**
1361
- * Clear/remove applied filter(s).
1362
- * @return {?}
1363
- */
1364
- GenericTableComponent.prototype.gtClearFilter = /**
1365
- * Clear/remove applied filter(s).
1366
- * @return {?}
1367
- */
1368
- function () {
1369
- this.gtInfo.filter = false;
1370
- this.updateTotals();
1371
- // this.updateRecordRange();
1372
- };
1373
- /**
1374
- * Search
1375
- * @param {?} value - string containing one or more words
1376
- * @return {?}
1377
- */
1378
- GenericTableComponent.prototype.gtSearch = /**
1379
- * Search
1380
- * @param {?} value - string containing one or more words
1381
- * @return {?}
1382
- */
1383
- function (value) {
1384
- this.gtInfo.searchTerms = value;
1385
- // always go to first page when searching
1386
- this.goToPage(1);
1387
- this.updateTotals();
1388
- };
1389
- /**
1390
- * Add rows
1391
- * @param {?} rows - rows to add
1392
- * @return {?} new data array.
1393
- */
1394
- GenericTableComponent.prototype.gtAdd = /**
1395
- * Add rows
1396
- * @param {?} rows - rows to add
1397
- * @return {?} new data array.
1398
- */
1399
- function (rows) {
1400
- this.gtData = __spread(this.gtData, rows);
1401
- return __spread(this.gtData);
1402
- };
1403
- /**
1404
- * Delete row
1405
- * @param {?} objectKey - object key you want to find match with
1406
- * @param {?} value - the value that should be deleted
1407
- * @param {?=} match - all: delete all matches, first: delete first match (default)
1408
- * @return {?} new data array.
1409
- */
1410
- GenericTableComponent.prototype.gtDelete = /**
1411
- * Delete row
1412
- * @param {?} objectKey - object key you want to find match with
1413
- * @param {?} value - the value that should be deleted
1414
- * @param {?=} match - all: delete all matches, first: delete first match (default)
1415
- * @return {?} new data array.
1416
- */
1417
- function (objectKey, value, match) {
1418
- if (match === void 0) { match = 'first'; }
1419
- if (match === 'first') {
1420
- for (var /** @type {?} */ i = 0; i < this.gtData.length; i++) {
1421
- if (this.gtData[i][objectKey] === value) {
1422
- if (this.isRowSelected(this.gtData[i])) {
1423
- this.toggleSelect(this.gtData[i]);
1424
- }
1425
- this.gtData.splice(i, 1);
1426
- this.gtData = __spread(this.gtData);
1427
- if (match === 'first') {
1428
- break;
1429
- }
1430
- }
1431
- }
1432
- }
1433
- else {
1434
- for (var /** @type {?} */ i = this.gtData.length; i > 0; i--) {
1435
- if (this.gtData[i - 1][objectKey] === value) {
1436
- if (this.isRowSelected(this.gtData[i - 1])) {
1437
- this.toggleSelect(this.gtData[i - 1]);
1438
- }
1439
- this.gtData.splice(i - 1, 1);
1440
- this.gtData = __spread(this.gtData);
1441
- }
1442
- }
1443
- }
1444
- return __spread(this.gtData);
1445
- };
1446
- /**
1447
- * Create store to hold previously loaded records.
1448
- * @param {?} records - total number of records in store.
1449
- * @param {?} perPage - how many records to show per page.
1450
- * @return {?} a nested array to hold records per page.
1451
- */
1452
- GenericTableComponent.prototype.createStore = /**
1453
- * Create store to hold previously loaded records.
1454
- * @param {?} records - total number of records in store.
1455
- * @param {?} perPage - how many records to show per page.
1456
- * @return {?} a nested array to hold records per page.
1457
- */
1458
- function (records, perPage) {
1459
- var /** @type {?} */ stores = Math.ceil(records / perPage);
1460
- var /** @type {?} */ store = [];
1461
- for (var /** @type {?} */ i = 0; i < stores; i++) {
1462
- store[i] = [];
1463
- }
1464
- return store;
1465
- };
1466
- /**
1467
- * Create placeholders for rows while loading data from back-end.
1468
- * @param {?} perPage - how many records to show per page.
1469
- * @return {?} an array containing empty records to be presented while fetching real data.
1470
- */
1471
- GenericTableComponent.prototype.loadingContent = /**
1472
- * Create placeholders for rows while loading data from back-end.
1473
- * @param {?} perPage - how many records to show per page.
1474
- * @return {?} an array containing empty records to be presented while fetching real data.
1475
- */
1476
- function (perPage) {
1477
- // create row object
1478
- var /** @type {?} */ rowObject = {
1479
- $$loading: true
1480
- };
1481
- var /** @type {?} */ order = 0;
1482
- // sort settings by column order
1483
- this._gtSettings.sort(this.getColumnOrder);
1484
- // loop through all settings objects...
1485
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1486
- var /** @type {?} */ setting = this._gtSettings[i];
1487
- // ...if column is visible and enabled...
1488
- if (setting.visible !== false && setting.enabled !== false) {
1489
- // ...if first column, set value to loading text otherwise leave it empty
1490
- if (order === 0) {
1491
- rowObject[setting.objectKey] = this.gtTexts.loading;
1492
- this.loadingProperty = setting.objectKey;
1493
- }
1494
- else {
1495
- rowObject[setting.objectKey] = '';
1496
- }
1497
- order++;
1498
- }
1499
- else {
1500
- rowObject[setting.objectKey] = '';
1501
- }
1502
- }
1503
- // create content placeholder
1504
- var /** @type {?} */ contentPlaceholder = [];
1505
- // create equal number of rows as rows per page
1506
- for (var /** @type {?} */ i = 0; i < perPage; i++) {
1507
- // ...add temporary row object
1508
- contentPlaceholder.push(rowObject);
1509
- }
1510
- return contentPlaceholder;
1511
- };
1512
- /**
1513
- * Export data as CSV
1514
- * @param {?=} fileName - optional file name (overrides default file name).
1515
- * @param {?=} useBOM - use BOM (byte order marker).
1516
- * @return {?}
1517
- */
1518
- GenericTableComponent.prototype.exportCSV = /**
1519
- * Export data as CSV
1520
- * @param {?=} fileName - optional file name (overrides default file name).
1521
- * @param {?=} useBOM - use BOM (byte order marker).
1522
- * @return {?}
1523
- */
1524
- function (fileName, useBOM) {
1525
- var _this = this;
1526
- if (useBOM === void 0) { useBOM = false; }
1527
- var /** @type {?} */ data = this.data.exportData;
1528
- var /** @type {?} */ csv = '';
1529
- var /** @type {?} */ BOM = '\uFEFF';
1530
- // csv export headers
1531
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1532
- if (this._gtSettings[i].export !== false) {
1533
- csv += this.getProperty(this._gtFields, this._gtSettings[i].objectKey)
1534
- .name;
1535
- if (i < this._gtSettings.length - 1) {
1536
- csv += this._gtOptions.csvDelimiter;
1537
- }
1538
- }
1539
- }
1540
- // csv export body
1541
- data.forEach(function (row) {
1542
- csv += '\n';
1543
- for (var /** @type {?} */ i = 0; i < _this._gtSettings.length; i++) {
1544
- if (_this._gtSettings[i].export !== false) {
1545
- // get field settings
1546
- var /** @type {?} */ fieldSetting = _this.getProperty(_this._gtFields, _this._gtSettings[i].objectKey);
1547
- // get export value, if export function is defined use it otherwise check for value function and as a last resort export raw data
1548
- var /** @type {?} */ exportValue = fieldSetting.export && typeof fieldSetting.export === 'function'
1549
- ? fieldSetting.export(row)
1550
- : fieldSetting.value && typeof fieldSetting.value === 'function'
1551
- ? fieldSetting.value(row)
1552
- : row[_this._gtSettings[i].objectKey];
1553
- // escape export value using double quotes (") if export value contains delimiter
1554
- exportValue =
1555
- typeof exportValue === 'string' &&
1556
- exportValue.indexOf(_this._gtOptions.csvDelimiter) !== -1
1557
- ? '"' + exportValue + '"'
1558
- : exportValue;
1559
- csv += exportValue;
1560
- if (i < _this._gtSettings.length - 1) {
1561
- csv += _this._gtOptions.csvDelimiter;
1562
- }
1563
- }
1564
- }
1565
- });
1566
- var /** @type {?} */ blob = new Blob([(useBOM ? BOM : '') + csv], {
1567
- type: 'text/csv;charset=utf-8'
1568
- });
1569
- if (window.navigator.msSaveOrOpenBlob) {
1570
- navigator.msSaveOrOpenBlob(blob, fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
1571
- }
1572
- else {
1573
- var /** @type {?} */ link = document.createElement('a');
1574
- link.style.display = 'none';
1575
- document.body.appendChild(link);
1576
- if (link.download !== undefined) {
1577
- link.setAttribute('href', 'data:text/csv;charset=utf-8,' +
1578
- encodeURIComponent((useBOM ? BOM : '') + csv)); // URL.createObjectURL(blob));
1579
- link.setAttribute('download', fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
1580
- document.body.appendChild(link);
1581
- link.click();
1582
- }
1583
- else {
1584
- csv = 'data:text/csv;charset=utf-8,' + (useBOM ? BOM : '') + csv;
1585
- window.open(encodeURIComponent(csv));
1586
- }
1587
- document.body.removeChild(link);
1588
- }
1589
- // emit export event
1590
- this.gtEvent.emit({
1591
- name: 'gt-exported-csv',
1592
- value: fileName ? fileName : this.gtTexts.csvDownload + '.csv'
1593
- });
1594
- };
1595
- /**
1596
- * @return {?}
1597
- */
1598
- GenericTableComponent.prototype.ngOnInit = /**
1599
- * @return {?}
1600
- */
1601
- function () {
1602
- // if number of row to display from start is set to null or 0...
1603
- if (!this.gtOptions.numberOfRows) {
1604
- // ...change row length
1605
- this.changeRowLength(this.gtOptions.numberOfRows);
1606
- }
1607
- this.restructureSorting();
1608
- };
1609
- /**
1610
- * @param {?} changes
1611
- * @return {?}
1612
- */
1613
- GenericTableComponent.prototype.ngOnChanges = /**
1614
- * @param {?} changes
1615
- * @return {?}
1616
- */
1617
- function (changes) {
1618
- // if gt texts have changed...
1619
- if (changes['gtTexts']) {
1620
- // ...extend gtOptions default values with values passed into component
1621
- this.gtTexts = /** @type {?} */ (this.extend(this.gtDefaultTexts, this.gtTexts));
1622
- }
1623
- // if lazy loading data and paging information is available...
1624
- if (this.gtOptions.lazyLoad && this.gtInfo) {
1625
- // ...calculate total number of pages
1626
- this.gtInfo.pageTotal = Math.ceil(this.gtInfo.recordsAfterSearch / this.gtInfo.recordLength);
1627
- // ...declare store position
1628
- var /** @type {?} */ storePosition = this.gtInfo.pageCurrent - 1;
1629
- // ...and if store is empty or page length has changed...
1630
- if (this.store.length === 0 ||
1631
- this.store[0].length !== this.gtInfo.recordLength) {
1632
- // ...create store
1633
- this.store = this.createStore(this.gtInfo.recordsAfterSearch, this.gtInfo.recordLength);
1634
- }
1635
- // ...store retrieved data in store at store position
1636
- this.store[storePosition] = this.gtData;
1637
- this.gtInfo.visibleRecords = __spread(this.gtData); // add visible rows
1638
- // replace data with store
1639
- this._gtData = this.store;
1640
- this.loading = false;
1641
- this.updateRecordRange();
1642
- this.gtEvent.emit({
1643
- name: 'gt-info',
1644
- value: this.gtInfo
1645
- });
1646
- }
1647
- else if (this._gtData &&
1648
- this._gtData.length >= 0 &&
1649
- changes['gtData'] &&
1650
- changes['gtData'].previousValue) {
1651
- this.loading = false;
1652
- }
1653
- else if (changes['gtData'] &&
1654
- changes['gtData'].firstChange &&
1655
- this._gtData &&
1656
- this._gtData.length > 0) {
1657
- this.loading = false;
1658
- }
1659
- };
1660
- /**
1661
- * @param {?} index
1662
- * @param {?} item
1663
- * @return {?}
1664
- */
1665
- GenericTableComponent.prototype.trackByFn = /**
1666
- * @param {?} index
1667
- * @param {?} item
1668
- * @return {?}
1669
- */
1670
- function (index, item) {
1671
- return item.$$gtRowId;
1672
- };
1673
- /**
1674
- * @param {?} index
1675
- * @param {?} item
1676
- * @return {?}
1677
- */
1678
- GenericTableComponent.prototype.trackByColumnFn = /**
1679
- * @param {?} index
1680
- * @param {?} item
1681
- * @return {?}
1682
- */
1683
- function (index, item) {
1684
- return item.objectKey;
1685
- };
1686
- /**
1687
- * @return {?}
1688
- */
1689
- GenericTableComponent.prototype.ngOnDestroy = /**
1690
- * @return {?}
1691
- */
1692
- function () {
1693
- // remove listener
1694
- this._stopListeningForKeydownEvent();
1695
- };
1696
- GenericTableComponent.decorators = [
1697
- { type: Component, args: [{
1698
- selector: 'generic-table',
1699
- template: "<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length > 0\">\n <thead>\n <tr>\n <th class=\"gt-sort-label\" *ngIf=\"gtOptions.stack\">{{gtTexts.sortLabel}}</th>\n <th *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{column.sortEnabled ? 'sort-'+column.sort:''}} {{column.sortEnabled && column.sortOrder >= 0 ? 'sort-order-'+column.sortOrder:''}} {{ gtFields | gtColumnClass:column }}\"\n (click)=\"column.sortEnabled ? gtSort(column.objectKey,$event):'';\">\n <span *ngIf=\"!(gtFields | gtProperty:column.objectKey:'header')\">{{gtFields | gtProperty:column.objectKey:'name'}}</span>\n <gt-custom-component-factory *ngIf=\"(gtFields | gtProperty:column.objectKey:'header')\"\n [type]=\"(gtFields | gtProperty:column.objectKey:'header')?.type\"\n [injector]=\"(gtFields | gtProperty:column.objectKey:'header')?.injector\"\n [column]=\"gtFields | gtProperty:column.objectKey:'name'\"></gt-custom-component-factory>\n <gt-checkbox *ngIf=\"(gtFields | gtProperty:column.objectKey:'columnComponent')?.type === 'checkbox'\" [checked]=\"(gtOptions.lazyLoad ? lazyAllSelected:selectedRows.length === gtData.length)\" (changed)=\"toggleAllRows()\"></gt-checkbox>\n </th>\n </tr>\n </thead>\n <ng-template\n [ngIf]=\"gtTotals && (gtOptions.lazyLoad === false ? (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length).length > 0 : gtData.length > 0)\">\n <thead class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </thead>\n <tfoot class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition:'footer'\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </tfoot>\n </ng-template>\n <tbody *ngIf=\"gtData && gtInfo\">\n <ng-template class=\"table-rows\" ngFor let-row let-last=\"last\" [ngForTrackBy]=\"trackByFn\"\n [ngForOf]=\"gtOptions.lazyLoad && gtInfo ? (gtData[gtInfo.pageCurrent-1]) : (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length | gtOrderBy:sortOrder:gtFields:refreshSorting:gtData.length | gtChunk:gtInfo:gtInfo.recordLength:gtInfo.pageCurrent:refreshPageArray:gtData.length:gtEvent:data | gtRowClass:gtFields)\">\n <tr [ngClass]=\"{'row-selected':metaInfo[row.$$gtRowId]?.isSelected, 'row-open':metaInfo[row.$$gtRowId]?.isOpen, 'row-loading':loading, 'row-expandable':gtRowComponent}\"\n class=\"{{row.$$gtRowClass}}\"\n (click)=\"gtOptions.rowSelection ? toggleSelect(row):rowClick(row, $event)\">\n <td *ngFor=\"let column of row | gtRender:gtSettings:gtFields:refreshPipe:loading:gtOptions.highlightSearch:gtInfo.searchTerms;trackBy:trackByColumnFn\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{(gtFields | gtProperty:column.objectKey:'inlineEdit') ? 'gt-inline-edit':''}} {{column.edited ? 'gt-edited':''}} {{ gtFields | gtColumnClass:column:row }}\">\n <span class=\"gt-row-label\"\n *ngIf=\"gtOptions.stack\">{{(gtFields | gtProperty:column.objectKey:'stackedHeading') ? (gtFields | gtProperty:column.objectKey:'stackedHeading') : (gtFields | gtProperty:column.objectKey:'name')}}</span>\n <gt-custom-component-factory *ngIf=\"column.columnComponent && column.columnComponent.type !== 'checkbox'\" class=\"gt-row-content\"\n [type]=\"column.columnComponent.type\"\n [injector]=\"column.columnComponent.injector\" [row]=\"row\"\n [column]=\"column\" (redrawEvent)=\"redraw($event)\"\n [searchTerms]=\"gtInfo.searchTerms\" (searchEvent)=\"redraw($event)\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></gt-custom-component-factory>\n <span *ngIf=\"!column.columnComponent && (!(gtFields | gtProperty:column.objectKey:'inlineEdit') || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || (!((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe)))\"\n class=\"gt-row-content\" [innerHTML]=\"column.renderValue\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></span>\n <ng-template\n [ngIf]=\"!column.columnComponent && (((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe))\">\n <ng-template [ngIf]=\"([true,'email','number','password', 'text'].indexOf((gtFields | gtProperty:column.objectKey:'inlineEdit').type) !== -1) || !(gtFields | gtProperty:column.objectKey:'inlineEdit').type\">\n <input class=\"inline-edit\" [attr.type]=\"!(gtFields | gtProperty:column.objectKey:'inlineEdit').type ? 'text' : !((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type:(gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(((gtFields | gtProperty:column.objectKey:'inlineEdit').type) && ((gtFields | gtProperty:column.objectKey:'inlineEdit').type).length > 0) || ((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable)\"\n [options]=\"!((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type : (gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <ng-template [ngIf]=\"!column.columnComponent && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active) \">\n <ng-template\n [ngIf]=\"[true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') !== -1\">\n <input class=\"inline-edit\" [attr.type]=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') === true ? 'text':(gtFields | gtProperty:column.objectKey:'inlineEdit')\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') && [true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') === -1\"\n [options]=\"gtFields | gtProperty:column.objectKey:'inlineEdit'\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <gt-checkbox *ngIf=\"column.columnComponent && column.columnComponent.type === 'checkbox'\" [checked]=\"metaInfo[row.$$gtRowId]?.isSelected\" (changed)=\"toggleSelect(row)\"></gt-checkbox>\n </td>\n </tr>\n <tr class=\"row-expanded\" *ngIf=\"metaInfo[row.$$gtRowId]?.isOpen\">\n <td [attr.colspan]=\"(gtFields | gtVisible:gtSettings:refreshPipe).length\">\n <gt-expanding-row [row]=\"row\"\n [type]=\"expandedRow.component ? expandedRow.component:gtRowComponent\"\n [columnWidth]=\"columnWidth\"\n [gtFields]=\"gtFields\"\n [gtOptions]=\"gtOptions\"\n [gtEvent]=\"gtEvent\"\n [gtInfo]=\"gtInfo\"\n [gtSettings]=\"gtSettings\"\n [data]=\"expandedRow.data ? expandedRow.data:row\"\n (redrawEvent)=\"redraw($event)\"\n (toggleRowEvent)=\"toggleCollapse($event)\"></gt-expanding-row>\n </td>\n </tr>\n <tr *ngIf=\"gtOptions.reportColumnWidth && last\">\n <td style=\"padding: 0; border:none;\"\n *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\" gtColumnWidth\n [objectKey]=\"column.objectKey\" [widths]=\"columnWidth\"></td>\n </tr>\n </ng-template>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && (gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-matching-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">\n {{gtTexts.noMatchingData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && !(gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.noData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && loading\">\n <td class=\"gt-loading-data\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.loading}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length === 0\">\n <thead>\n <tr>\n <th class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumnsHeading}}</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumns}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"!gtFields || !gtSettings\">\n <thead>\n <tr>\n <th class=\"gt-loading-config\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-loading-config\">&nbsp;</td>\n </tr>\n </tbody>\n</table>\n"
1700
- }] }
1701
- ];
1702
- /** @nocollapse */
1703
- GenericTableComponent.ctorParameters = function () { return [
1704
- { type: Renderer2, },
1705
- { type: GtMetaPipe, },
1706
- ]; };
1707
- GenericTableComponent.propDecorators = {
1708
- "gtOptions": [{ type: Input },],
1709
- "gtTotals": [{ type: Input },],
1710
- "gtFields": [{ type: Input },],
1711
- "gtSettings": [{ type: Input },],
1712
- "gtData": [{ type: Input },],
1713
- "gtRowComponent": [{ type: Input },],
1714
- "gtTexts": [{ type: Input },],
1715
- "gtClasses": [{ type: Input },],
1716
- "gtEvent": [{ type: Output },],
1717
- "gtInfo": [{ type: Input },],
1718
- };
1719
- return GenericTableComponent;
1720
- }());
1721
-
1722
- /**
1723
- * @fileoverview added by tsickle
1724
- * @suppress {checkTypes} checked by tsc
1725
- */
1726
- var GtTableInfoComponent = /** @class */ (function () {
1727
- function GtTableInfoComponent(_changeDetectionRef) {
1728
- this._changeDetectionRef = _changeDetectionRef;
1729
- }
1730
- /**
1731
- * @return {?}
1732
- */
1733
- GtTableInfoComponent.prototype.ngAfterViewChecked = /**
1734
- * @return {?}
1735
- */
1736
- function () {
1737
- this._changeDetectionRef.detectChanges();
1738
- };
1739
- GtTableInfoComponent.decorators = [
1740
- { type: Component, args: [{
1741
- selector: 'gt-table-info',
1742
- template: "\n\t\t<span *ngIf=\"genericTable.gtInfo\">{{(customText? customText:genericTable.gtTexts) | gtTableInfo:\n\t\t\tgenericTable.gtInfo:\n\t\t\tgenericTable.gtInfo.recordsAfterSearch:\n\t\t\tgenericTable.gtInfo.recordFrom:\n\t\t\tgenericTable.gtInfo.recordTo:\n\t\t\tgenericTable.gtInfo.recordsAll:\n\t\t\tgenericTable.gtTexts.loading:\n\t\t\tgenericTable.gtTexts.tableInfoAfterSearch}}</span>\n "
1743
- }] }
1744
- ];
1745
- /** @nocollapse */
1746
- GtTableInfoComponent.ctorParameters = function () { return [
1747
- { type: ChangeDetectorRef, },
1748
- ]; };
1749
- GtTableInfoComponent.propDecorators = {
1750
- "genericTable": [{ type: Input },],
1751
- "customText": [{ type: Input },],
1752
- };
1753
- return GtTableInfoComponent;
1754
- }());
1755
- var TableInfoPipe = /** @class */ (function () {
1756
- function TableInfoPipe() {
1757
- }
1758
- /**
1759
- * @param {?} texts
1760
- * @param {?} keys
1761
- * @param {?} recordsAfterSearch
1762
- * @param {?} recordFrom
1763
- * @param {?} recordTo
1764
- * @param {?} recordsAll
1765
- * @param {?} loading
1766
- * @param {?} tableInfoAfterSearch
1767
- * @return {?}
1768
- */
1769
- TableInfoPipe.prototype.transform = /**
1770
- * @param {?} texts
1771
- * @param {?} keys
1772
- * @param {?} recordsAfterSearch
1773
- * @param {?} recordFrom
1774
- * @param {?} recordTo
1775
- * @param {?} recordsAll
1776
- * @param {?} loading
1777
- * @param {?} tableInfoAfterSearch
1778
- * @return {?}
1779
- */
1780
- function (texts, keys, recordsAfterSearch, recordFrom, recordTo, recordsAll, loading, tableInfoAfterSearch) {
1781
- var /** @type {?} */ text = typeof texts === 'object' ? texts.tableInfo : '';
1782
- if (keys.recordsAfterSearch !== keys.recordsAll) {
1783
- text = typeof texts === 'object' ? texts.tableInfoAfterSearch : '';
1784
- }
1785
- for (var /** @type {?} */ key in keys) {
1786
- if (keys.hasOwnProperty(key)) {
1787
- var /** @type {?} */ searchString = new RegExp('#' + key, 'g');
1788
- text = text.replace(searchString, keys[key]);
1789
- }
1790
- }
1791
- return text;
1792
- };
1793
- TableInfoPipe.decorators = [
1794
- { type: Pipe, args: [{
1795
- name: 'gtTableInfo'
1796
- },] }
1797
- ];
1798
- return TableInfoPipe;
1799
- }());
1800
-
1801
- /**
1802
- * @fileoverview added by tsickle
1803
- * @suppress {checkTypes} checked by tsc
1804
- */
1805
- var GtPaginationComponent = /** @class */ (function () {
1806
- function GtPaginationComponent() {
1807
- this.ready = false;
1808
- }
1809
- Object.defineProperty(GtPaginationComponent.prototype, "genericTable", {
1810
- get: /**
1811
- * @return {?}
1812
- */
1813
- function () {
1814
- return this._genericTable;
1815
- },
1816
- set: /**
1817
- * @param {?} value
1818
- * @return {?}
1819
- */
1820
- function (value) {
1821
- var _this = this;
1822
- if (value) {
1823
- value.gtEvent.subscribe(function (res) {
1824
- if (res.name === 'gt-info' && res.value.pageTotal > 0) {
1825
- _this.ready = true;
1826
- }
1827
- });
1828
- }
1829
- this._genericTable = value;
1830
- },
1831
- enumerable: true,
1832
- configurable: true
1833
- });
1834
- GtPaginationComponent.decorators = [
1835
- { type: Component, args: [{
1836
- selector: 'gt-pagination',
1837
- template: "\n\t\t<nav class=\"gt-pagination\" aria-label=\"Table navigation\" *ngIf=\"genericTable && genericTable.gtInfo && ready && genericTable.gtData?.length > 0\" [ngClass]=\"{'no-data':genericTable.gtInfo.pageTotal === 0}\">\n\t\t\t<ul class=\"pagination\" [ngClass]=\"gtClasses\">\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.gtInfo.pageCurrent === 1 || genericTable.loading }\"><a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"genericTable.gtInfo.pageCurrent > 1 && genericTable.previousPage()\" [attr.aria-label]=\"genericTable.gtTexts.paginatePrevious\"><span aria-hidden=\"true\">&laquo;</span><span class=\"sr-only\">{{genericTable.gtTexts.paginatePrevious}}</span></a></li>\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.loading && genericTable.gtInfo.pageCurrent !== page, 'active' : genericTable.gtInfo.pageCurrent === page }\" *ngFor=\"let page of genericTable.gtInfo.pageTotal | gtPaginationPipe:genericTable.gtInfo.pageCurrent\"><a class=\"page-link\" [tabindex]=\"page === true ? -1:0\" href=\"javascript:void(0);\" (click)=\"page === true ? '':genericTable.goToPage(page)\">{{page === true ? '&hellip;':page}}</a></li>\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.gtInfo.pageCurrent === genericTable.gtInfo.pageTotal || genericTable.loading }\"><a class=\"page-link gt-link\" href=\"javascript:void(0);\" (click)=\"genericTable.gtInfo.pageCurrent !== genericTable.gtInfo.pageTotal && genericTable.nextPage()\" [attr.aria-label]=\"genericTable.gtTexts.paginateNext\"><span aria-hidden=\"true\">&raquo;</span><span class=\"sr-only\">{{genericTable.gtTexts.paginateNext}}</span></a></li>\n\t\t\t</ul>\n\t\t</nav>\n ",
1838
- styles: [".gt-link {cursor: pointer;}"]
1839
- }] }
1840
- ];
1841
- /** @nocollapse */
1842
- GtPaginationComponent.propDecorators = {
1843
- "genericTable": [{ type: Input },],
1844
- "gtClasses": [{ type: Input },],
1845
- };
1846
- return GtPaginationComponent;
1847
- }());
1848
- var PaginationPipe = /** @class */ (function () {
1849
- function PaginationPipe() {
1850
- }
1851
- /**
1852
- * @param {?} totalPages
1853
- * @param {?} currentPage
1854
- * @return {?}
1855
- */
1856
- PaginationPipe.prototype.transform = /**
1857
- * @param {?} totalPages
1858
- * @param {?} currentPage
1859
- * @return {?}
1860
- */
1861
- function (totalPages, currentPage) {
1862
- if (totalPages === 0) {
1863
- return [1];
1864
- }
1865
- var /** @type {?} */ pagination = []; // create new empty array for pagination
1866
- var /** @type {?} */ siblings = 2; // sibling elements ie. number of elements on each side of current page
1867
- var /** @type {?} */ paginationLength = totalPages < siblings * 2 + 1 ? totalPages : siblings * 2 + 1; // number of elements in pagination array
1868
- var /** @type {?} */ start = currentPage <= siblings ? 1 : currentPage - siblings; // starting position for array
1869
- var /** @type {?} */ modifier = totalPages - (currentPage + siblings) <= 0
1870
- ? totalPages - (currentPage + siblings)
1871
- : 0; // modifier for pagination values
1872
- var /** @type {?} */ modifiedPosition = start + modifier <= 0 ? 1 : start + modifier;
1873
- // push pages to pagination array
1874
- for (var /** @type {?} */ i = 0; i < paginationLength; i++) {
1875
- pagination.push(modifiedPosition + i);
1876
- }
1877
- // if first page is not included in pagination...
1878
- if (pagination.indexOf(1) === -1) {
1879
- // ...check if second page is in pagination...
1880
- if (pagination.indexOf(2) === -1) {
1881
- // ...if not check if total number of pages equals seven and number of siblings are two...
1882
- if (totalPages === 7 && siblings === 2) {
1883
- // ...add second page and don't convert page number to ellipsis
1884
- pagination.unshift(2);
1885
- }
1886
- else {
1887
- // ...if not, use this placeholder for ellipsis instead of actual page number
1888
- pagination[0] = true;
1889
- }
1890
- }
1891
- // ...add first page as first array item
1892
- pagination.unshift(1);
1893
- }
1894
- else if (totalPages > paginationLength) {
1895
- // if first page is included add extra page to keep number of items consistent
1896
- pagination.splice(paginationLength, 0, paginationLength + 1);
1897
- }
1898
- // check if last page is included in pagination...
1899
- if (pagination.indexOf(totalPages) === -1) {
1900
- // ...if not, page next to last should either show ellipsis or actual page number for the page
1901
- pagination[pagination.length - 1] =
1902
- pagination[pagination.length - 1] === totalPages - 1
1903
- ? totalPages - 1
1904
- : true;
1905
- // ...add last page to pagination
1906
- pagination.push(totalPages);
1907
- }
1908
- return pagination;
1909
- };
1910
- PaginationPipe.decorators = [
1911
- { type: Pipe, args: [{
1912
- name: 'gtPaginationPipe'
1913
- },] }
1914
- ];
1915
- return PaginationPipe;
1916
- }());
1917
-
1918
- /**
1919
- * @fileoverview added by tsickle
1920
- * @suppress {checkTypes} checked by tsc
1921
- */
1922
- // unsupported: template constraints.
1923
- /**
1924
- * @template R
1925
- */
1926
- var
1927
- // unsupported: template constraints.
1928
- /**
1929
- * @template R
1930
- */
1931
- GtExpandedRow = /** @class */ (function () {
1932
- function GtExpandedRow() {
1933
- this.redrawEvent = new EventEmitter();
1934
- this.toggleRowEvent = new EventEmitter();
1935
- }
1936
- /**
1937
- * @return {?}
1938
- */
1939
- GtExpandedRow.prototype.$hide = /**
1940
- * @return {?}
1941
- */
1942
- function () {
1943
- this.toggleRowEvent.emit(this.row);
1944
- };
1945
- /**
1946
- * @param {?=} $event
1947
- * @return {?}
1948
- */
1949
- GtExpandedRow.prototype.$redraw = /**
1950
- * @param {?=} $event
1951
- * @return {?}
1952
- */
1953
- function ($event) {
1954
- this.redrawEvent.emit(this.row);
1955
- };
1956
- /**
1957
- * @param {?} row
1958
- * @param {?} $event
1959
- * @return {?}
1960
- */
1961
- GtExpandedRow.prototype.$rowClick = /**
1962
- * @param {?} row
1963
- * @param {?} $event
1964
- * @return {?}
1965
- */
1966
- function (row, $event) {
1967
- this.gtEvent.emit({
1968
- name: 'gt-row-clicked',
1969
- value: { row: row, event: $event }
1970
- });
1971
- };
1972
- return GtExpandedRow;
1973
- }());
1974
- // unsupported: template constraints.
1975
- // unsupported: template constraints.
1976
- /**
1977
- * @template R, C
1978
- */
1979
- var GtExpandingRowComponent = /** @class */ (function () {
1980
- function GtExpandingRowComponent() {
1981
- this.redrawEvent = new EventEmitter();
1982
- this.toggleRowEvent = new EventEmitter();
1983
- }
1984
- /**
1985
- * @param {?} instance
1986
- * @return {?}
1987
- */
1988
- GtExpandingRowComponent.prototype.newInstance = /**
1989
- * @param {?} instance
1990
- * @return {?}
1991
- */
1992
- function (instance) {
1993
- instance.row = this.row;
1994
- instance.columnWidth = this.columnWidth;
1995
- instance.gtSettings = this.gtSettings;
1996
- instance.gtFields = this.gtFields;
1997
- instance.gtOptions = this.gtOptions;
1998
- instance.gtInfo = this.gtInfo;
1999
- instance.data =
2000
- typeof this.data === 'function' ? this.data(this.row) : this.data;
2001
- instance.redrawEvent.subscribe(this.redrawEvent);
2002
- instance.toggleRowEvent.subscribe(this.toggleRowEvent);
2003
- instance.gtEvent = this.gtEvent;
2004
- };
2005
- GtExpandingRowComponent.decorators = [
2006
- { type: Component, args: [{
2007
- selector: 'gt-expanding-row',
2008
- template: "\n\t\t<div gtComponentAnchor\n\t\t\t [ctor]=\"type\" (instance)=\"newInstance($event)\"></div>\n "
2009
- }] }
2010
- ];
2011
- /** @nocollapse */
2012
- GtExpandingRowComponent.propDecorators = {
2013
- "type": [{ type: Input },],
2014
- "row": [{ type: Input },],
2015
- "columnWidth": [{ type: Input },],
2016
- "gtSettings": [{ type: Input },],
2017
- "gtFields": [{ type: Input },],
2018
- "gtOptions": [{ type: Input },],
2019
- "gtInfo": [{ type: Input },],
2020
- "data": [{ type: Input },],
2021
- "redrawEvent": [{ type: Output },],
2022
- "toggleRowEvent": [{ type: Output },],
2023
- "gtEvent": [{ type: Input },],
2024
- };
2025
- return GtExpandingRowComponent;
2026
- }());
2027
-
2028
- /**
2029
- * @fileoverview added by tsickle
2030
- * @suppress {checkTypes} checked by tsc
2031
- */
2032
- var GtDropdownComponent = /** @class */ (function () {
2033
- function GtDropdownComponent(renderer) {
2034
- this.renderer = renderer;
2035
- this.selectedChange = new EventEmitter();
2036
- this.active = false; // is dropdown active or not
2037
- this.state = new Subject(); // current state of dropdown
2038
- }
2039
- Object.defineProperty(GtDropdownComponent.prototype, "selected", {
2040
- get: /**
2041
- * @return {?}
2042
- */
2043
- function () {
2044
- return this._selected;
2045
- },
2046
- set: /**
2047
- * @param {?} selection
2048
- * @return {?}
2049
- */
2050
- function (selection) {
2051
- this._selected = selection;
2052
- },
2053
- enumerable: true,
2054
- configurable: true
2055
- });
2056
- /**
2057
- * @param {?} option
2058
- * @return {?}
2059
- */
2060
- GtDropdownComponent.prototype.select = /**
2061
- * @param {?} option
2062
- * @return {?}
2063
- */
2064
- function (option) {
2065
- this.active = false;
2066
- this.state.next(this.active);
2067
- if (this._selected !== option) {
2068
- this.selectedChange.emit(option);
2069
- }
2070
- };
2071
- /**
2072
- * @return {?}
2073
- */
2074
- GtDropdownComponent.prototype.toggleDropdown = /**
2075
- * @return {?}
2076
- */
2077
- function () {
2078
- var _this = this;
2079
- this.active = !this.active;
2080
- setTimeout(function () {
2081
- _this.state.next(_this.active);
2082
- }, 0);
2083
- };
2084
- /**
2085
- * @return {?}
2086
- */
2087
- GtDropdownComponent.prototype.ngOnInit = /**
2088
- * @return {?}
2089
- */
2090
- function () {
2091
- var _this = this;
2092
- this.state.subscribe(function (state) {
2093
- if (state) {
2094
- _this.tether = new Tether({
2095
- element: '#' + _this.id + '_menu',
2096
- target: '#' + _this.id,
2097
- attachment: 'top left',
2098
- targetAttachment: 'bottom left',
2099
- constraints: [
2100
- {
2101
- to: 'window',
2102
- attachment: 'together'
2103
- }
2104
- ]
2105
- });
2106
- _this.tether.position();
2107
- // set up click listener and listen for click outside dropdown
2108
- _this.clickListener = _this.renderer.listen('document', 'click', function (event) {
2109
- _this.active = false;
2110
- _this.state.next(_this.active);
2111
- });
2112
- // set up keyboard listener and listen for escape key up
2113
- _this.keyupListener = _this.renderer.listen('document', 'keyup', function (event) {
2114
- switch (event.key) {
2115
- case 'Escape':
2116
- _this.active = false;
2117
- _this.state.next(_this.active);
2118
- break;
2119
- }
2120
- });
2121
- }
2122
- else {
2123
- _this.tether.destroy();
2124
- _this.removeListeners();
2125
- }
2126
- });
2127
- };
2128
- /**
2129
- * @return {?}
2130
- */
2131
- GtDropdownComponent.prototype.ngOnDestroy = /**
2132
- * @return {?}
2133
- */
2134
- function () {
2135
- this.removeListeners();
2136
- };
2137
- /**
2138
- * @return {?}
2139
- */
2140
- GtDropdownComponent.prototype.removeListeners = /**
2141
- * @return {?}
2142
- */
2143
- function () {
2144
- if (this.clickListener) {
2145
- this.clickListener();
2146
- }
2147
- if (this.keyupListener) {
2148
- this.keyupListener();
2149
- }
2150
- };
2151
- GtDropdownComponent.decorators = [
2152
- { type: Component, args: [{
2153
- selector: 'gt-dropdown',
2154
- template: "\n\t\t<div class=\"dropdown gt-dropdown\" [ngClass]=\"{'show':active}\" [attr.id]=\"id\">\n\t\t\t<div class=\"dropdown-toggle\" (click)=\"toggleDropdown()\" [attr.aria-expanded]=\"active\">{{selected}}</div>\n\t\t\t<div class=\"gt-dropdown-menu dropdown-menu\" *ngIf=\"active\" [ngClass]=\"{'show':active}\" [attr.id]=\"id+'_menu'\">\n\t\t\t\t<button *ngFor=\"let option of options;\" class=\"dropdown-item\" (click)=\"select(option)\" [ngClass]=\"{'active':option === selected}\">{{option}}</button>\n\t\t\t</div>\n\t\t</div>\n ",
2155
- styles: ["\n\t\t.gt-dropdown .dropdown-toggle {\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.gt-dropdown .dropdown-toggle::after {\n\t\t\ttransition: opacity 0.4s ease-in-out;\n\t\t\topacity: 0;\n\t\t}\n\t\t.gt-dropdown .dropdown-toggle:hover::after {\n\t\t\topacity: 1;\n\t\t}\n\t"]
2156
- }] }
2157
- ];
2158
- /** @nocollapse */
2159
- GtDropdownComponent.ctorParameters = function () { return [
2160
- { type: Renderer2, },
2161
- ]; };
2162
- GtDropdownComponent.propDecorators = {
2163
- "selected": [{ type: Input },],
2164
- "options": [{ type: Input },],
2165
- "id": [{ type: Input },],
2166
- "selectedChange": [{ type: Output },],
2167
- };
2168
- return GtDropdownComponent;
2169
- }());
2170
-
2171
- /**
2172
- * @fileoverview added by tsickle
2173
- * @suppress {checkTypes} checked by tsc
2174
- */
2175
- var GtDrilldownComponent = /** @class */ (function (_super) {
2176
- __extends(GtDrilldownComponent, _super);
2177
- function GtDrilldownComponent() {
2178
- return _super.call(this) || this;
2179
- }
2180
- /**
2181
- * @return {?}
2182
- */
2183
- GtDrilldownComponent.prototype.ngOnInit = /**
2184
- * @return {?}
2185
- */
2186
- function () { };
2187
- GtDrilldownComponent.decorators = [
2188
- { type: Component, args: [{
2189
- selector: 'gt-drilldown',
2190
- template: "\n\t\t<table class=\"table\">\n\t\t\t<tr *ngFor=\"let row of data\" (click)=\"$rowClick(row, $event)\">\n\t\t\t\t<td *ngFor=\"let column of row | gtRender:gtSettings:gtFields:null:null:gtOptions.highlightSearch:gtInfo.searchTerms;\"\n\t\t\t\t\tngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{(gtFields | gtProperty:column.objectKey:'inlineEdit') ? 'gt-inline-edit':''}} {{column.edited ? 'gt-edited':''}} {{ gtFields | gtColumnClass:row:column }}\" [style.width]=\"columnWidth[column.objectKey]\" [style.max-width]=\"columnWidth[column.objectKey]\">\n <span class=\"gt-row-label\"\n\t\t\t\t\t\t\t *ngIf=\"gtOptions.stack\">{{(gtFields | gtProperty:column.objectKey:'stackedHeading') ? (gtFields | gtProperty:column.objectKey:'stackedHeading') : (gtFields | gtProperty:column.objectKey:'name')}}</span>\n\t\t\t\t\t<gt-custom-component-factory *ngIf=\"column.columnComponent\" class=\"gt-row-content\"\n\t\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.columnComponent.type\"\n\t\t\t\t\t\t\t\t\t\t\t\t [injector]=\"column.columnComponent.injector\" [row]=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\t [column]=\"column\" (redrawEvent)=\"$redraw($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"column.click ? column.click(row,column,$event):'';\"></gt-custom-component-factory>\n\t\t\t\t\t<span *ngIf=\"!column.columnComponent\"\n\t\t\t\t\t\t class=\"gt-row-content\" [innerHTML]=\"column.renderValue\"\n\t\t\t\t\t\t (click)=\"column.click ? column.click(row,column,$event):''\"></span>\n\t\t\t\t</td>\n\n\t\t\t</tr>\n\t\t</table>\n "
2191
- }] }
2192
- ];
2193
- /** @nocollapse */
2194
- GtDrilldownComponent.ctorParameters = function () { return []; };
2195
- return GtDrilldownComponent;
2196
- }(GtExpandedRow));
2197
-
2198
- /**
2199
- * @fileoverview added by tsickle
2200
- * @suppress {checkTypes} checked by tsc
2201
- */
2202
- /**
2203
- * @abstract
2204
- * @template R
2205
- */
2206
- var /**
2207
- * @abstract
2208
- * @template R
2209
- */
2210
- GtCustomComponent = /** @class */ (function () {
2211
- function GtCustomComponent() {
2212
- this.redrawEvent = new EventEmitter();
2213
- this.$searchTerms = new ReplaySubject(1);
2214
- }
2215
- /**
2216
- * @param {?=} $event
2217
- * @return {?}
2218
- */
2219
- GtCustomComponent.prototype.$redraw = /**
2220
- * @param {?=} $event
2221
- * @return {?}
2222
- */
2223
- function ($event) {
2224
- this.redrawEvent.emit({ row: this.row, column: this.column });
2225
- };
2226
- /**
2227
- * @return {?}
2228
- */
2229
- GtCustomComponent.prototype.ngOnInit = /**
2230
- * @return {?}
2231
- */
2232
- function () {
2233
- var _this = this;
2234
- this.$searchTerms.subscribe(function (terms) { return (_this.searchTerms = terms); });
2235
- };
2236
- return GtCustomComponent;
2237
- }());
2238
- // unsupported: template constraints.
2239
- /**
2240
- * @template R, C
2241
- */
2242
- var GtCustomComponentFactory = /** @class */ (function () {
2243
- function GtCustomComponentFactory() {
2244
- this.$searchTerms = new ReplaySubject(1);
2245
- this.redrawEvent = new EventEmitter();
2246
- }
2247
- Object.defineProperty(GtCustomComponentFactory.prototype, "searchTerms", {
2248
- set: /**
2249
- * @param {?} value
2250
- * @return {?}
2251
- */
2252
- function (value) {
2253
- this.$searchTerms.next(value);
2254
- },
2255
- enumerable: true,
2256
- configurable: true
2257
- });
2258
- /**
2259
- * @param {?} instance
2260
- * @return {?}
2261
- */
2262
- GtCustomComponentFactory.prototype.instance = /**
2263
- * @param {?} instance
2264
- * @return {?}
2265
- */
2266
- function (instance) {
2267
- instance.row = this.row;
2268
- instance.column = this.column;
2269
- instance.$searchTerms = this.$searchTerms;
2270
- instance.redrawEvent.subscribe(this.redrawEvent);
2271
- };
2272
- GtCustomComponentFactory.decorators = [
2273
- { type: Component, args: [{
2274
- selector: 'gt-custom-component-factory',
2275
- template: "\n\t\t<div gtComponentAnchor [ctor]=\"type\"\n\t\t\t [injector]=\"injector\"\n\t\t\t (instance)=\"instance($event)\"></div>\n\t"
2276
- }] }
2277
- ];
2278
- /** @nocollapse */
2279
- GtCustomComponentFactory.propDecorators = {
2280
- "searchTerms": [{ type: Input },],
2281
- "type": [{ type: Input },],
2282
- "injector": [{ type: Input },],
2283
- "row": [{ type: Input },],
2284
- "column": [{ type: Input },],
2285
- "redrawEvent": [{ type: Output },],
2286
- };
2287
- return GtCustomComponentFactory;
2288
- }());
2289
-
2290
- /**
2291
- * @fileoverview added by tsickle
2292
- * @suppress {checkTypes} checked by tsc
2293
- */
2294
- var GtCheckboxComponent = /** @class */ (function () {
2295
- function GtCheckboxComponent() {
2296
- this.class = 'd-flex justify-content-end';
2297
- this.changed = new EventEmitter();
2298
- }
2299
- Object.defineProperty(GtCheckboxComponent.prototype, "initialValue", {
2300
- get: /**
2301
- * @return {?}
2302
- */
2303
- function () {
2304
- return this._initialValue;
2305
- },
2306
- set: /**
2307
- * @param {?} value
2308
- * @return {?}
2309
- */
2310
- function (value) {
2311
- this._initialValue = value;
2312
- },
2313
- enumerable: true,
2314
- configurable: true
2315
- });
2316
- Object.defineProperty(GtCheckboxComponent.prototype, "checked", {
2317
- get: /**
2318
- * @return {?}
2319
- */
2320
- function () {
2321
- return this._checked;
2322
- },
2323
- set: /**
2324
- * @param {?} value
2325
- * @return {?}
2326
- */
2327
- function (value) {
2328
- this._checked = value;
2329
- },
2330
- enumerable: true,
2331
- configurable: true
2332
- });
2333
- /**
2334
- * @return {?}
2335
- */
2336
- GtCheckboxComponent.prototype.ngOnInit = /**
2337
- * @return {?}
2338
- */
2339
- function () { };
2340
- /**
2341
- * @param {?} checked
2342
- * @return {?}
2343
- */
2344
- GtCheckboxComponent.prototype.toggle = /**
2345
- * @param {?} checked
2346
- * @return {?}
2347
- */
2348
- function (checked) {
2349
- this.changed.emit(this.checked);
2350
- };
2351
- GtCheckboxComponent.decorators = [
2352
- { type: Component, args: [{
2353
- selector: 'gt-checkbox',
2354
- template: "\n\t\t<label class=\"custom-control custom-checkbox p-0\" (click)=\"$event.stopPropagation()\">\n\t\t\t<input #checkbox type=\"checkbox\" class=\"custom-control-input\" [(checked)]=\"checked\" (change)=\"toggle($event);\">\n\t\t\t<span class=\"custom-control-label\"></span>\n\t\t</label>\n "
2355
- }] }
2356
- ];
2357
- /** @nocollapse */
2358
- GtCheckboxComponent.ctorParameters = function () { return []; };
2359
- GtCheckboxComponent.propDecorators = {
2360
- "class": [{ type: HostBinding, args: ['class',] },],
2361
- "initialValue": [{ type: Input },],
2362
- "checked": [{ type: Input },],
2363
- "changed": [{ type: Output },],
2364
- };
2365
- return GtCheckboxComponent;
2366
- }());
2367
-
2368
- /**
2369
- * @fileoverview added by tsickle
2370
- * @suppress {checkTypes} checked by tsc
2371
- */
2372
- // unsupported: template constraints.
2373
- /**
2374
- * @template R
2375
- */
2376
- var GtVisiblePipe = /** @class */ (function () {
2377
- function GtVisiblePipe() {
2378
- /**
2379
- * Sort by column order
2380
- */
2381
- this.getColumnOrder = function (a, b) {
2382
- if (a.columnOrder < b.columnOrder) {
2383
- return -1;
2384
- }
2385
- if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
2386
- return 1;
2387
- }
2388
- return 0;
2389
- };
2390
- }
2391
- /**
2392
- * @param {?} array
2393
- * @param {?} settings
2394
- * @param {?=} refreshPipe
2395
- * @return {?}
2396
- */
2397
- GtVisiblePipe.prototype.transform = /**
2398
- * @param {?} array
2399
- * @param {?} settings
2400
- * @param {?=} refreshPipe
2401
- * @return {?}
2402
- */
2403
- function (array, settings, refreshPipe) {
2404
- var /** @type {?} */ visibleColumns = settings
2405
- .sort(this.getColumnOrder)
2406
- .map(function (setting) {
2407
- if (setting.visible !== false && setting.enabled !== false) {
2408
- return setting.objectKey;
2409
- }
2410
- });
2411
- return array
2412
- .filter(function (column) {
2413
- return visibleColumns.indexOf(column.objectKey) !== -1;
2414
- })
2415
- .sort(function (a, b) {
2416
- return visibleColumns.indexOf(a.objectKey) <
2417
- visibleColumns.indexOf(b.objectKey)
2418
- ? -1
2419
- : 1;
2420
- });
2421
- };
2422
- GtVisiblePipe.decorators = [
2423
- { type: Pipe, args: [{
2424
- name: 'gtVisible'
2425
- },] }
2426
- ];
2427
- return GtVisiblePipe;
2428
- }());
2429
-
2430
- /**
2431
- * @fileoverview added by tsickle
2432
- * @suppress {checkTypes} checked by tsc
2433
- */
2434
- // unsupported: template constraints.
2435
- /**
2436
- * @template R
2437
- */
2438
- var GtSearchPipe = /** @class */ (function () {
2439
- function GtSearchPipe() {
2440
- /**
2441
- * Return property
2442
- */
2443
- this.getProperty = function (array, key) {
2444
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
2445
- if (array[i].objectKey === key) {
2446
- return array[i];
2447
- }
2448
- }
2449
- };
2450
- }
2451
- /**
2452
- * @param {?} allRows
2453
- * @param {?} searchTerms
2454
- * @param {?} gtInfo
2455
- * @param {?} settings
2456
- * @param {?} fields
2457
- * @param {?} refreshData
2458
- * @return {?}
2459
- */
2460
- GtSearchPipe.prototype.transform = /**
2461
- * @param {?} allRows
2462
- * @param {?} searchTerms
2463
- * @param {?} gtInfo
2464
- * @param {?} settings
2465
- * @param {?} fields
2466
- * @param {?} refreshData
2467
- * @return {?}
2468
- */
2469
- function (allRows, searchTerms, gtInfo, settings, fields, refreshData) {
2470
- // if no search terms are defined...
2471
- if (!searchTerms || searchTerms.replace(/"/g, '').length === 0) {
2472
- // ...return all rows
2473
- var /** @type {?} */ length_1 = allRows === null ? 0 : allRows.length;
2474
- gtInfo.recordsAfterSearch = length_1;
2475
- return allRows;
2476
- }
2477
- var /** @type {?} */ searchFunction = {};
2478
- var /** @type {?} */ fieldsTemp = [];
2479
- for (var /** @type {?} */ k = 0; k < fields.length; k++) {
2480
- var /** @type {?} */ field = fields[k];
2481
- // check if field should be included in global search
2482
- var /** @type {?} */ include = this.getProperty(settings, field.objectKey).search === false
2483
- ? false
2484
- : true;
2485
- // if include...
2486
- if (include) {
2487
- // ...and if search function is defined...
2488
- if (typeof field.search === 'function') {
2489
- // ...add it as search function for field
2490
- searchFunction[field.objectKey] = field.search;
2491
- }
2492
- // ...if no search function is defined but value function is defined...
2493
- else if (typeof field.value === 'function') {
2494
- // ...add it as search function for field
2495
- searchFunction[field.objectKey] = field.value;
2496
- }
2497
- // ...push it to our fields array
2498
- fieldsTemp.push(field);
2499
- }
2500
- }
2501
- var /** @type {?} */ filteredRows = [];
2502
- searchTerms = typeof searchTerms === 'undefined' ? '' : searchTerms;
2503
- var /** @type {?} */ searchTermsArray = searchTerms.toLowerCase().match(/(".*"|[^\s]+)/g);
2504
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
2505
- var /** @type {?} */ row = allRows[i];
2506
- var /** @type {?} */ string = '';
2507
- for (var /** @type {?} */ j = 0; j < fieldsTemp.length; j++) {
2508
- var /** @type {?} */ separator = j === 0 ? '' : ' & ';
2509
- string += searchFunction[fieldsTemp[j].objectKey]
2510
- ? separator + searchFunction[fieldsTemp[j].objectKey](row, j)
2511
- : separator + row[fieldsTemp[j].objectKey];
2512
- }
2513
- string = string.toLowerCase();
2514
- var /** @type {?} */ match = true;
2515
- for (var /** @type {?} */ k = 0; k < searchTermsArray.length; k++) {
2516
- var /** @type {?} */ term = searchTermsArray[k].replace(/"/g, '');
2517
- match = string.indexOf(term) !== -1;
2518
- if (!match) {
2519
- break;
2520
- }
2521
- }
2522
- if (match) {
2523
- filteredRows.push(row);
2524
- }
2525
- }
2526
- gtInfo.recordsAfterSearch = filteredRows.length;
2527
- // gtInfo.refresh(filteredRows.length,gt);
2528
- return filteredRows;
2529
- };
2530
- GtSearchPipe.decorators = [
2531
- { type: Pipe, args: [{
2532
- name: 'gtSearch'
2533
- },] }
2534
- ];
2535
- return GtSearchPipe;
2536
- }());
2537
-
2538
- /**
2539
- * @fileoverview added by tsickle
2540
- * @suppress {checkTypes} checked by tsc
2541
- */
2542
- var GtIsEditablePipe = /** @class */ (function () {
2543
- function GtIsEditablePipe() {
2544
- }
2545
- /**
2546
- * @param {?} property
2547
- * @param {?} row
2548
- * @param {?} refreshPipe
2549
- * @return {?}
2550
- */
2551
- GtIsEditablePipe.prototype.transform = /**
2552
- * @param {?} property
2553
- * @param {?} row
2554
- * @param {?} refreshPipe
2555
- * @return {?}
2556
- */
2557
- function (property, row, refreshPipe) {
2558
- if (typeof property === 'function') {
2559
- return property(row);
2560
- }
2561
- else {
2562
- return false;
2563
- }
2564
- };
2565
- GtIsEditablePipe.decorators = [
2566
- { type: Pipe, args: [{
2567
- name: 'gtIsEditable'
2568
- },] }
2569
- ];
2570
- return GtIsEditablePipe;
2571
- }());
2572
-
2573
- /**
2574
- * @fileoverview added by tsickle
2575
- * @suppress {checkTypes} checked by tsc
2576
- */
2577
- var GtIsObservablePipe = /** @class */ (function () {
2578
- function GtIsObservablePipe() {
2579
- }
2580
- /**
2581
- * @param {?} input
2582
- * @return {?}
2583
- */
2584
- GtIsObservablePipe.prototype.transform = /**
2585
- * @param {?} input
2586
- * @return {?}
2587
- */
2588
- function (input) {
2589
- return input instanceof Observable;
2590
- };
2591
- GtIsObservablePipe.decorators = [
2592
- { type: Pipe, args: [{
2593
- name: 'gtIsObservable'
2594
- },] }
2595
- ];
2596
- return GtIsObservablePipe;
2597
- }());
2598
-
2599
- /**
2600
- * @fileoverview added by tsickle
2601
- * @suppress {checkTypes} checked by tsc
2602
- */
2603
- var GtHighlightPipe = /** @class */ (function () {
2604
- function GtHighlightPipe(sanitizer) {
2605
- this.sanitizer = sanitizer;
2606
- }
2607
- /**
2608
- * @param {?} text
2609
- * @param {?} searchTerm
2610
- * @return {?}
2611
- */
2612
- GtHighlightPipe.prototype.transform = /**
2613
- * @param {?} text
2614
- * @param {?} searchTerm
2615
- * @return {?}
2616
- */
2617
- function (text, searchTerm) {
2618
- var /** @type {?} */ haystackAlwaysString = text + '';
2619
- var /** @type {?} */ highlightedText = haystackAlwaysString; // fallback
2620
- var /** @type {?} */ searchPattern;
2621
- try {
2622
- searchPattern = new RegExp('(' +
2623
- searchTerm
2624
- .toLowerCase()
2625
- .match(/".*?"|[^ ]+/g) // extract words
2626
- .map(function (needle) { return needle.replace(/"(.*?)"/, '$1'); } // strip away '"'
2627
- // strip away '"'
2628
- )
2629
- .join('|') + // combine words
2630
- ')', 'ig');
2631
- }
2632
- catch (/** @type {?} */ error) {
2633
- return this.sanitizer.bypassSecurityTrustHtml(highlightedText);
2634
- }
2635
- var /** @type {?} */ containsTagPattern = /(<.*?>)(.*)(<\/.*?>)/gi;
2636
- var /** @type {?} */ containsTagMatches = containsTagPattern.exec(haystackAlwaysString);
2637
- if (containsTagMatches) {
2638
- // tag exists in haystack
2639
- highlightedText =
2640
- containsTagMatches[1] +
2641
- containsTagMatches[2].replace(searchPattern, '<span class="gt-highlight-search">$1</span>') +
2642
- containsTagMatches[3];
2643
- }
2644
- else {
2645
- highlightedText = haystackAlwaysString.replace(searchPattern, '<span class="gt-highlight-search">$1</span>');
2646
- }
2647
- return this.sanitizer.bypassSecurityTrustHtml(highlightedText);
2648
- };
2649
- GtHighlightPipe.decorators = [
2650
- { type: Pipe, args: [{
2651
- name: 'gtHighlight'
2652
- },] }
2653
- ];
2654
- /** @nocollapse */
2655
- GtHighlightPipe.ctorParameters = function () { return [
2656
- { type: DomSanitizer, },
2657
- ]; };
2658
- return GtHighlightPipe;
2659
- }());
2660
-
2661
- /**
2662
- * @fileoverview added by tsickle
2663
- * @suppress {checkTypes} checked by tsc
2664
- */
2665
- var GtColumnClassPipe = /** @class */ (function () {
2666
- function GtColumnClassPipe() {
2667
- }
2668
- /**
2669
- * @param {?} gtFields
2670
- * @param {?} column
2671
- * @param {?=} row
2672
- * @return {?}
2673
- */
2674
- GtColumnClassPipe.prototype.transform = /**
2675
- * @param {?} gtFields
2676
- * @param {?} column
2677
- * @param {?=} row
2678
- * @return {?}
2679
- */
2680
- function (gtFields, column, row) {
2681
- // find columns with columnClass property defined
2682
- var /** @type {?} */ COLUMN_WITH_CLASS = gtFields
2683
- .map(function (field) { return field; })
2684
- .filter(function (field) { return field.columnClass && field.objectKey === column.objectKey; })[0];
2685
- if (!COLUMN_WITH_CLASS) {
2686
- return;
2687
- }
2688
- else if (typeof COLUMN_WITH_CLASS.columnClass === 'function') {
2689
- // if column class is a function, try using the function...
2690
- try {
2691
- return COLUMN_WITH_CLASS.columnClass(row, column);
2692
- }
2693
- catch (/** @type {?} */ error) {
2694
- console.log('Error when trying to get column class name using formula.', error);
2695
- }
2696
- }
2697
- else {
2698
- // if not a function, return plain string value
2699
- return COLUMN_WITH_CLASS.columnClass;
2700
- }
2701
- };
2702
- GtColumnClassPipe.decorators = [
2703
- { type: Pipe, args: [{
2704
- name: 'gtColumnClass'
2705
- },] }
2706
- ];
2707
- return GtColumnClassPipe;
2708
- }());
2709
-
2710
- /**
2711
- * @fileoverview added by tsickle
2712
- * @suppress {checkTypes} checked by tsc
2713
- */
2714
- var GtRowClassPipe = /** @class */ (function () {
2715
- function GtRowClassPipe() {
2716
- }
2717
- /**
2718
- * @param {?} array
2719
- * @param {?} gtFields
2720
- * @return {?}
2721
- */
2722
- GtRowClassPipe.prototype.transform = /**
2723
- * @param {?} array
2724
- * @param {?} gtFields
2725
- * @return {?}
2726
- */
2727
- function (array, gtFields) {
2728
- if (array) {
2729
- // find columns with rowClass property defined
2730
- var /** @type {?} */ COLUMNS_WITH_CLASS = gtFields
2731
- .map(function (column) { return column; })
2732
- .filter(function (column) { return column.rowClass; });
2733
- COLUMNS_WITH_CLASS.map(function (column) {
2734
- // for each column with rowClass property defined...
2735
- array.map(function (row) {
2736
- // loop through rows and set row class
2737
- if (typeof column.rowClass === 'function') {
2738
- // if row class is a function, try using the function...
2739
- try {
2740
- if (row.$$gtRowClass) {
2741
- row.$$gtRowClass = row.$$gtRowClass.concat(' ' + column.rowClass(row, column));
2742
- }
2743
- else {
2744
- row.$$gtRowClass = column.rowClass(row, column);
2745
- }
2746
- }
2747
- catch (/** @type {?} */ error) {
2748
- console.log('Error when trying to get row class name using formula.', error);
2749
- }
2750
- }
2751
- else {
2752
- // if not a function, return plain string value
2753
- if (row.$$gtRowClass) {
2754
- row.$$gtRowClass = row.$$gtRowClass.concat(' ' + column.rowClass);
2755
- }
2756
- else {
2757
- row.$$gtRowClass = column.rowClass;
2758
- }
2759
- }
2760
- });
2761
- });
2762
- }
2763
- return array;
2764
- };
2765
- GtRowClassPipe.decorators = [
2766
- { type: Pipe, args: [{
2767
- name: 'gtRowClass'
2768
- },] }
2769
- ];
2770
- return GtRowClassPipe;
2771
- }());
2772
-
2773
- /**
2774
- * @fileoverview added by tsickle
2775
- * @suppress {checkTypes} checked by tsc
2776
- */
2777
- var GtTotalsPositionPipe = /** @class */ (function () {
2778
- function GtTotalsPositionPipe() {
2779
- }
2780
- /**
2781
- * @param {?} array
2782
- * @param {?=} position
2783
- * @return {?}
2784
- */
2785
- GtTotalsPositionPipe.prototype.transform = /**
2786
- * @param {?} array
2787
- * @param {?=} position
2788
- * @return {?}
2789
- */
2790
- function (array, position) {
2791
- if (position === void 0) { position = 'header'; }
2792
- return array.filter(function (total) {
2793
- // if no position is defined assume position to be header
2794
- var /** @type {?} */ totalPosition = total.position ? total.position : 'header';
2795
- return totalPosition === position;
2796
- });
2797
- };
2798
- GtTotalsPositionPipe.decorators = [
2799
- { type: Pipe, args: [{
2800
- name: 'gtTotalsPosition'
2801
- },] }
2802
- ];
2803
- return GtTotalsPositionPipe;
2804
- }());
2805
-
2806
- /**
2807
- * @fileoverview added by tsickle
2808
- * @suppress {checkTypes} checked by tsc
2809
- */
2810
- var GtTotalsPipe = /** @class */ (function () {
2811
- function GtTotalsPipe() {
2812
- }
2813
- /**
2814
- * @param {?} value
2815
- * @param {?} data
2816
- * @param {?} objectKey
2817
- * @param {?} refresh
2818
- * @return {?}
2819
- */
2820
- GtTotalsPipe.prototype.transform = /**
2821
- * @param {?} value
2822
- * @param {?} data
2823
- * @param {?} objectKey
2824
- * @param {?} refresh
2825
- * @return {?}
2826
- */
2827
- function (value, data, objectKey, refresh) {
2828
- var /** @type {?} */ output;
2829
- if (data.length === 0) {
2830
- return;
2831
- }
2832
- if (typeof value === 'function') {
2833
- output = value(data, objectKey);
2834
- }
2835
- else if (value) {
2836
- output = value;
2837
- }
2838
- else {
2839
- output = '';
2840
- }
2841
- return output;
2842
- };
2843
- GtTotalsPipe.decorators = [
2844
- { type: Pipe, args: [{
2845
- name: 'gtTotals'
2846
- },] }
2847
- ];
2848
- return GtTotalsPipe;
2849
- }());
2850
-
2851
- /**
2852
- * @fileoverview added by tsickle
2853
- * @suppress {checkTypes} checked by tsc
2854
- */
2855
- // unsupported: template constraints.
2856
- /**
2857
- * @template R
2858
- */
2859
- var GtOrderByPipe = /** @class */ (function () {
2860
- function GtOrderByPipe() {
2861
- /**
2862
- * Return property
2863
- */
2864
- this.getProperty = function (array, key) {
2865
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
2866
- if (array[i].objectKey === key) {
2867
- return array[i];
2868
- }
2869
- }
2870
- };
2871
- }
2872
- /**
2873
- * @param {?} a
2874
- * @param {?} b
2875
- * @return {?}
2876
- */
2877
- GtOrderByPipe._orderByComparator = /**
2878
- * @param {?} a
2879
- * @param {?} b
2880
- * @return {?}
2881
- */
2882
- function (a, b) {
2883
- // sort boolean values as strings
2884
- if (typeof a === 'boolean') {
2885
- a = a.toString();
2886
- }
2887
- if (typeof b === 'boolean') {
2888
- b = b.toString();
2889
- }
2890
- if (isNaN(parseFloat(a)) ||
2891
- !isFinite(a) ||
2892
- (isNaN(parseFloat(b)) || !isFinite(b))) {
2893
- if (b === null ||
2894
- (typeof b === 'undefined' && (a !== null && typeof a !== 'undefined'))) {
2895
- return 1;
2896
- }
2897
- if (a === null ||
2898
- (typeof a === 'undefined' && (b !== null && typeof b !== 'undefined'))) {
2899
- return -1;
2900
- }
2901
- // isn't a number so lowercase the string to properly compare
2902
- try {
2903
- if (a.toLowerCase() < b.toLowerCase()) {
2904
- return -1;
2905
- }
2906
- if (a.toLowerCase() > b.toLowerCase()) {
2907
- return 1;
2908
- }
2909
- }
2910
- catch (/** @type {?} */ error) {
2911
- return 0;
2912
- }
2913
- }
2914
- else {
2915
- // parse strings as numbers to compare properly
2916
- if (parseFloat(a) < parseFloat(b)) {
2917
- return -1;
2918
- }
2919
- if (parseFloat(a) > parseFloat(b)) {
2920
- return 1;
2921
- }
2922
- }
2923
- return 0; // equal each other
2924
- };
2925
- /**
2926
- * Return sort function
2927
- * @param {?} field
2928
- * @return {?}
2929
- */
2930
- GtOrderByPipe.prototype.getSortFunction = /**
2931
- * Return sort function
2932
- * @param {?} field
2933
- * @return {?}
2934
- */
2935
- function (field) {
2936
- if (!field) {
2937
- // console.log('error trying to sort undefined field');
2938
- return false;
2939
- }
2940
- if (typeof field.sort === 'function') {
2941
- return field.sort;
2942
- }
2943
- else if (typeof field.value === 'function') {
2944
- return field.value;
2945
- }
2946
- else {
2947
- return false;
2948
- }
2949
- };
2950
- /**
2951
- * @param {?} input
2952
- * @param {?} sortByProperties
2953
- * @param {?} fields
2954
- * @param {?} refreshSorting
2955
- * @param {?} refreshData
2956
- * @return {?}
2957
- */
2958
- GtOrderByPipe.prototype.transform = /**
2959
- * @param {?} input
2960
- * @param {?} sortByProperties
2961
- * @param {?} fields
2962
- * @param {?} refreshSorting
2963
- * @param {?} refreshData
2964
- * @return {?}
2965
- */
2966
- function (input, sortByProperties, fields, refreshSorting, refreshData) {
2967
- var _this = this;
2968
- if (!Array.isArray(input) || input === null) {
2969
- return input;
2970
- }
2971
- if (!Array.isArray(sortByProperties) ||
2972
- (Array.isArray(sortByProperties) && sortByProperties.length === 1)) {
2973
- var /** @type {?} */ propertyToCheck = sortByProperties[0];
2974
- var /** @type {?} */ desc_1 = propertyToCheck.substr(0, 1) === '-';
2975
- // basic array
2976
- if (!propertyToCheck ||
2977
- propertyToCheck === '-' ||
2978
- propertyToCheck === '+') {
2979
- return !desc_1 ? input.sort() : input.sort().reverse();
2980
- }
2981
- else {
2982
- var /** @type {?} */ property_1 = propertyToCheck.substr(0, 1) === '+' ||
2983
- propertyToCheck.substr(0, 1) === '-'
2984
- ? propertyToCheck.substr(1)
2985
- : propertyToCheck;
2986
- // check if custom sort function is defined
2987
- var /** @type {?} */ sortFunction_1 = this.getSortFunction(this.getProperty(fields, property_1));
2988
- // console.log(property);
2989
- return input.sort(function (a, b) {
2990
- // use custom sort function if one is defined
2991
- var /** @type {?} */ propertyA = sortFunction_1 === false
2992
- ? property_1 === '$$gtRowId'
2993
- ? +a.$$gtRowId.split('_')[0]
2994
- : a[property_1]
2995
- : sortFunction_1(a);
2996
- var /** @type {?} */ propertyB = sortFunction_1 === false
2997
- ? property_1 === '$$gtRowId'
2998
- ? +b.$$gtRowId.split('_')[0]
2999
- : b[property_1]
3000
- : sortFunction_1(b);
3001
- // if both values are undefined...
3002
- if (typeof propertyA === 'undefined' &&
3003
- typeof propertyB === 'undefined') {
3004
- // ...skip comparison
3005
- return;
3006
- }
3007
- return !desc_1
3008
- ? GtOrderByPipe._orderByComparator(propertyA, propertyB)
3009
- : -GtOrderByPipe._orderByComparator(propertyA, propertyB);
3010
- });
3011
- }
3012
- }
3013
- else {
3014
- // loop over property of the array in order and sort
3015
- return input.sort(function (a, b) {
3016
- // console.log('multiple');
3017
- for (var /** @type {?} */ i = 0; i < sortByProperties.length; i++) {
3018
- var /** @type {?} */ desc = sortByProperties[i].substr(0, 1) === '-';
3019
- var /** @type {?} */ property = sortByProperties[i].substr(0, 1) === '+' ||
3020
- sortByProperties[i].substr(0, 1) === '-'
3021
- ? sortByProperties[i].substr(1)
3022
- : sortByProperties[i];
3023
- // console.log(property);
3024
- // check if custom sort function is defined
3025
- var /** @type {?} */ sortFunction = _this.getSortFunction(_this.getProperty(fields, property));
3026
- // use custom sort function if one is defined
3027
- var /** @type {?} */ propertyA = sortFunction === false
3028
- ? property === '$$gtRowId'
3029
- ? +a.$$gtRowId.split('_')[0]
3030
- : a[property]
3031
- : sortFunction(a);
3032
- var /** @type {?} */ propertyB = sortFunction === false
3033
- ? property === '$$gtRowId'
3034
- ? +b.$$gtRowId.split('_')[0]
3035
- : b[property]
3036
- : sortFunction(b);
3037
- var /** @type {?} */ comparison = !desc
3038
- ? GtOrderByPipe._orderByComparator(propertyA, propertyB)
3039
- : -GtOrderByPipe._orderByComparator(propertyA, propertyB);
3040
- // don't return 0 yet in case of needing to sort by next property
3041
- if (comparison !== 0) {
3042
- return comparison;
3043
- }
3044
- }
3045
- return 0; // equal each other
3046
- });
3047
- }
3048
- };
3049
- GtOrderByPipe.decorators = [
3050
- { type: Pipe, args: [{
3051
- name: 'gtOrderBy'
3052
- },] }
3053
- ];
3054
- return GtOrderByPipe;
3055
- }());
3056
-
3057
- /**
3058
- * @fileoverview added by tsickle
3059
- * @suppress {checkTypes} checked by tsc
3060
- */
3061
- var GtFilterPipe = /** @class */ (function () {
3062
- function GtFilterPipe() {
3063
- }
3064
- // @Output() filterInfo = new EventEmitter();
3065
- /**
3066
- * @param {?} allRows
3067
- * @param {?} filterBy
3068
- * @param {?} gtInfo
3069
- * @param {?} refreshFilter
3070
- * @param {?} refreshData
3071
- * @return {?}
3072
- */
3073
- GtFilterPipe.prototype.transform = /**
3074
- * @param {?} allRows
3075
- * @param {?} filterBy
3076
- * @param {?} gtInfo
3077
- * @param {?} refreshFilter
3078
- * @param {?} refreshData
3079
- * @return {?}
3080
- */
3081
- function (allRows, filterBy, gtInfo, refreshFilter, refreshData) {
3082
- // console.log(allRows,filterBy);
3083
- gtInfo.recordsAll = allRows.length;
3084
- if (!Array.isArray(allRows) || !filterBy) {
3085
- // gtInfo.filtered = false;
3086
- var /** @type {?} */ length_1 = allRows === null ? 0 : allRows.length;
3087
- gtInfo.recordsAfterFilter = length_1;
3088
- return allRows;
3089
- }
3090
- var /** @type {?} */ output = [];
3091
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
3092
- var /** @type {?} */ rowObject = allRows[i];
3093
- var /** @type {?} */ match = true;
3094
- for (var /** @type {?} */ property in filterBy) {
3095
- if (filterBy.hasOwnProperty(property)) {
3096
- // console.log(property);
3097
- // console.log(filter[property].indexOf(obj[property]));
3098
- if (filterBy[property].indexOf(rowObject[property]) === -1) {
3099
- match = false;
3100
- }
3101
- }
3102
- }
3103
- if (match) {
3104
- output.push(rowObject);
3105
- }
3106
- }
3107
- gtInfo.recordsAfterFilter = output.length; // .emit(output.length);
3108
- return output;
3109
- };
3110
- GtFilterPipe.decorators = [
3111
- { type: Pipe, args: [{
3112
- name: 'gtFilter'
3113
- },] }
3114
- ];
3115
- return GtFilterPipe;
3116
- }());
3117
-
3118
- /**
3119
- * @fileoverview added by tsickle
3120
- * @suppress {checkTypes} checked by tsc
3121
- */
3122
- var GtChunkPipe = /** @class */ (function () {
3123
- function GtChunkPipe() {
3124
- }
3125
- /**
3126
- * @param {?} array
3127
- * @param {?} gtInfo
3128
- * @param {?} chunkSize
3129
- * @param {?} page
3130
- * @param {?} refreshPageArray
3131
- * @param {?} refreshData
3132
- * @param {?} gtEvent
3133
- * @param {?} data
3134
- * @return {?}
3135
- */
3136
- GtChunkPipe.prototype.transform = /**
3137
- * @param {?} array
3138
- * @param {?} gtInfo
3139
- * @param {?} chunkSize
3140
- * @param {?} page
3141
- * @param {?} refreshPageArray
3142
- * @param {?} refreshData
3143
- * @param {?} gtEvent
3144
- * @param {?} data
3145
- * @return {?}
3146
- */
3147
- function (array, gtInfo, chunkSize, page, refreshPageArray, refreshData, gtEvent, data) {
3148
- if (!Array.isArray(array)) {
3149
- return array;
3150
- }
3151
- data.exportData = array; // store data for export
3152
- var /** @type {?} */ PAGES = [];
3153
- var /** @type {?} */ ENTRIES = array.length;
3154
- for (var /** @type {?} */ i = 0; i < ENTRIES; i += chunkSize) {
3155
- PAGES.push(array.slice(i, i + chunkSize));
3156
- }
3157
- gtInfo.visibleRecords = !PAGES[page - 1] ? [] : __spread(PAGES[page - 1]); // add visible rows
3158
- gtInfo.pageTotal = PAGES.length; // add number of pages
3159
- setTimeout(function () {
3160
- return gtEvent.emit({
3161
- name: 'gt-info',
3162
- value: gtInfo
3163
- });
3164
- }, 0);
3165
- return PAGES[page - 1];
3166
- };
3167
- GtChunkPipe.decorators = [
3168
- { type: Pipe, args: [{
3169
- name: 'gtChunk'
3170
- },] }
3171
- ];
3172
- return GtChunkPipe;
3173
- }());
3174
-
3175
- /**
3176
- * @fileoverview added by tsickle
3177
- * @suppress {checkTypes} checked by tsc
3178
- */
3179
- // unsupported: template constraints.
3180
- /**
3181
- * @template R
3182
- */
3183
- var GtPropertyPipe = /** @class */ (function () {
3184
- function GtPropertyPipe() {
3185
- }
3186
- /**
3187
- * @param {?} config
3188
- * @param {?} objectKey
3189
- * @param {?} property
3190
- * @param {?=} refresh
3191
- * @return {?}
3192
- */
3193
- GtPropertyPipe.prototype.transform = /**
3194
- * @param {?} config
3195
- * @param {?} objectKey
3196
- * @param {?} property
3197
- * @param {?=} refresh
3198
- * @return {?}
3199
- */
3200
- function (config, objectKey, property, refresh) {
3201
- var /** @type {?} */ output = null;
3202
- try {
3203
- for (var /** @type {?} */ i = 0; i < config.length; i++) {
3204
- if (config[i].objectKey === objectKey) {
3205
- output = config[i][property];
3206
- }
3207
- }
3208
- }
3209
- catch (/** @type {?} */ error) {
3210
- console.log('cannot read property: "' +
3211
- property +
3212
- '" on missing key: "' +
3213
- objectKey +
3214
- '" in config.', error);
3215
- }
3216
- return output;
3217
- };
3218
- GtPropertyPipe.decorators = [
3219
- { type: Pipe, args: [{
3220
- name: 'gtProperty'
3221
- },] }
3222
- ];
3223
- return GtPropertyPipe;
3224
- }());
3225
-
3226
- /**
3227
- * @fileoverview added by tsickle
3228
- * @suppress {checkTypes} checked by tsc
3229
- */
3230
- var DashCasePipe = /** @class */ (function () {
3231
- function DashCasePipe() {
3232
- }
3233
- /**
3234
- * @param {?} string
3235
- * @return {?}
3236
- */
3237
- DashCasePipe.prototype.transform = /**
3238
- * @param {?} string
3239
- * @return {?}
3240
- */
3241
- function (string) {
3242
- return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
3243
- };
3244
- DashCasePipe.decorators = [
3245
- { type: Pipe, args: [{
3246
- name: 'dashCase'
3247
- },] }
3248
- ];
3249
- return DashCasePipe;
3250
- }());
3251
-
3252
- /**
3253
- * @fileoverview added by tsickle
3254
- * @suppress {checkTypes} checked by tsc
3255
- */
3256
- // unsupported: template constraints.
3257
- /**
3258
- * @template R
3259
- */
3260
- var GtRenderPipe = /** @class */ (function () {
3261
- function GtRenderPipe(sanitizer, gtHighlightPipe) {
3262
- this.sanitizer = sanitizer;
3263
- this.gtHighlightPipe = gtHighlightPipe;
3264
- /**
3265
- * Sort by column order
3266
- */
3267
- this.getColumnOrder = function (a, b) {
3268
- if (a.columnOrder < b.columnOrder) {
3269
- return -1;
3270
- }
3271
- if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
3272
- return 1;
3273
- }
3274
- return 0;
3275
- };
3276
- /**
3277
- * Sort by length
3278
- */
3279
- this.getOrderByLength = function (a, b) {
3280
- return b.length - a.length;
3281
- };
3282
- /**
3283
- * Return property
3284
- */
3285
- this.getProperty = function (array, key) {
3286
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
3287
- if (array[i].objectKey === key) {
3288
- return array[i];
3289
- }
3290
- }
3291
- };
3292
- }
3293
- /**
3294
- * @param {?} row
3295
- * @param {?} settings
3296
- * @param {?} fields
3297
- * @param {?} updated
3298
- * @param {?} loading
3299
- * @param {?=} highlight
3300
- * @param {?=} searchString
3301
- * @return {?}
3302
- */
3303
- GtRenderPipe.prototype.transform = /**
3304
- * @param {?} row
3305
- * @param {?} settings
3306
- * @param {?} fields
3307
- * @param {?} updated
3308
- * @param {?} loading
3309
- * @param {?=} highlight
3310
- * @param {?=} searchString
3311
- * @return {?}
3312
- */
3313
- function (row, settings, fields, updated, loading, highlight, searchString) {
3314
- if (highlight === void 0) { highlight = false; }
3315
- // let arr = [{"temp":123,"name":"happy"},{"temp":456,"name":"dfgdfg"},{"temp":789,"name":"asdasd"}];
3316
- // console.log(arr,arr.map(function(item){return item.temp}));
3317
- // console.log(settings.map('objectKey'));
3318
- // console.log('render');
3319
- var /** @type {?} */ columns = [];
3320
- for (var /** @type {?} */ i = 0; i < settings.length; i++) {
3321
- if (settings[i].visible !== false && settings[i].enabled !== false) {
3322
- columns.push(settings[i].objectKey);
3323
- }
3324
- }
3325
- for (var /** @type {?} */ i = 0; i < fields.length; i++) {
3326
- // console.log(!row[fields[i].objectKey]);
3327
- if (fields[i].value &&
3328
- typeof fields[i].value === 'function' &&
3329
- !row.hasOwnProperty(fields[i].objectKey)) {
3330
- row[fields[i].objectKey] = loading ? '' : fields[i].value(row);
3331
- }
3332
- }
3333
- // console.log(row);
3334
- var /** @type {?} */ keys = [];
3335
- for (var /** @type {?} */ key in row) {
3336
- // console.log(key);
3337
- if (columns.indexOf(key) !== -1) {
3338
- var /** @type {?} */ fieldSetting = void 0;
3339
- for (var /** @type {?} */ i = 0; i < fields.length; i++) {
3340
- if (fields[i].objectKey === key) {
3341
- fieldSetting = fields[i];
3342
- // console.log(fieldSetting);
3343
- }
3344
- }
3345
- var /** @type {?} */ columnObject = {
3346
- objectKey: key,
3347
- sortValue: row[key]
3348
- };
3349
- // add component if defined
3350
- if (fieldSetting.columnComponent) {
3351
- columnObject.columnComponent = fieldSetting.columnComponent;
3352
- }
3353
- if (loading) {
3354
- columnObject.renderValue = row[key] !== null ? row[key] : '';
3355
- }
3356
- else if (highlight &&
3357
- searchString &&
3358
- this.getProperty(settings, key).search !== false) {
3359
- columnObject.renderValue =
3360
- fieldSetting.render && typeof fieldSetting.render === 'function'
3361
- ? this.gtHighlightPipe.transform(fieldSetting.render(row), searchString)
3362
- : this.gtHighlightPipe.transform(row[key] !== null ? row[key] : '', searchString);
3363
- }
3364
- else {
3365
- columnObject.renderValue =
3366
- fieldSetting.render && typeof fieldSetting.render === 'function'
3367
- ? this.sanitizer.bypassSecurityTrustHtml(fieldSetting.render(row))
3368
- : row[key] !== null
3369
- ? row[key]
3370
- : '';
3371
- }
3372
- if (fieldSetting.click && typeof fieldSetting.click === 'function') {
3373
- columnObject.click = fieldSetting.click;
3374
- }
3375
- if (fieldSetting.expand) {
3376
- columnObject.expand = fieldSetting.expand;
3377
- }
3378
- keys.push(columnObject);
3379
- }
3380
- }
3381
- keys.sort(function (a, b) {
3382
- return columns.indexOf(a.objectKey) < columns.indexOf(b.objectKey)
3383
- ? -1
3384
- : 1;
3385
- });
3386
- return keys;
3387
- };
3388
- GtRenderPipe.decorators = [
3389
- { type: Pipe, args: [{
3390
- name: 'gtRender'
3391
- },] }
3392
- ];
3393
- /** @nocollapse */
3394
- GtRenderPipe.ctorParameters = function () { return [
3395
- { type: DomSanitizer, },
3396
- { type: GtHighlightPipe, },
3397
- ]; };
3398
- return GtRenderPipe;
3399
- }());
3400
-
3401
- /**
3402
- * @fileoverview added by tsickle
3403
- * @suppress {checkTypes} checked by tsc
3404
- */
3405
- /**
3406
- * @template C
3407
- */
3408
- var ComponentAnchorDirective = /** @class */ (function () {
3409
- function ComponentAnchorDirective(componentFactoryResolver, viewContainer) {
3410
- this.componentFactoryResolver = componentFactoryResolver;
3411
- this.viewContainer = viewContainer;
3412
- this.instance = new EventEmitter();
3413
- }
3414
- /**
3415
- * @return {?}
3416
- */
3417
- ComponentAnchorDirective.prototype.ngOnInit = /**
3418
- * @return {?}
3419
- */
3420
- function () {
3421
- var /** @type {?} */ factory = this.componentFactoryResolver.resolveComponentFactory(this.ctor);
3422
- var /** @type {?} */ component = this.viewContainer.createComponent(factory, 0, this.injector);
3423
- this.instance.emit(component.instance);
3424
- };
3425
- ComponentAnchorDirective.decorators = [
3426
- { type: Directive, args: [{
3427
- selector: '[gtComponentAnchor]'
3428
- },] }
3429
- ];
3430
- /** @nocollapse */
3431
- ComponentAnchorDirective.ctorParameters = function () { return [
3432
- { type: ComponentFactoryResolver, },
3433
- { type: ViewContainerRef, },
3434
- ]; };
3435
- ComponentAnchorDirective.propDecorators = {
3436
- "ctor": [{ type: Input },],
3437
- "injector": [{ type: Input },],
3438
- "instance": [{ type: Output },],
3439
- };
3440
- return ComponentAnchorDirective;
3441
- }());
3442
-
3443
- /**
3444
- * @fileoverview added by tsickle
3445
- * @suppress {checkTypes} checked by tsc
3446
- */
3447
- var GtColumnWidthDirective = /** @class */ (function () {
3448
- function GtColumnWidthDirective(hostElement, cdRef) {
3449
- this.hostElement = hostElement;
3450
- this.cdRef = cdRef;
3451
- }
3452
- /**
3453
- * @param {?} $event
3454
- * @return {?}
3455
- */
3456
- GtColumnWidthDirective.prototype.onResize = /**
3457
- * @param {?} $event
3458
- * @return {?}
3459
- */
3460
- function ($event) {
3461
- this.checkSize();
3462
- };
3463
- /**
3464
- * @return {?}
3465
- */
3466
- GtColumnWidthDirective.prototype.ngOnInit = /**
3467
- * @return {?}
3468
- */
3469
- function () {
3470
- this.checkSize();
3471
- };
3472
- /**
3473
- * @return {?}
3474
- */
3475
- GtColumnWidthDirective.prototype.checkSize = /**
3476
- * @return {?}
3477
- */
3478
- function () {
3479
- this.widths[this.objectKey] = window
3480
- .getComputedStyle(this.hostElement.nativeElement, null)
3481
- .getPropertyValue('width');
3482
- this.cdRef.detectChanges();
3483
- };
3484
- GtColumnWidthDirective.decorators = [
3485
- { type: Directive, args: [{
3486
- selector: '[gtColumnWidth]'
3487
- },] }
3488
- ];
3489
- /** @nocollapse */
3490
- GtColumnWidthDirective.ctorParameters = function () { return [
3491
- { type: ElementRef, },
3492
- { type: ChangeDetectorRef, },
3493
- ]; };
3494
- GtColumnWidthDirective.propDecorators = {
3495
- "objectKey": [{ type: Input },],
3496
- "widths": [{ type: Input },],
3497
- "onResize": [{ type: HostListener, args: ['window:resize', ['$event'],] },],
3498
- };
3499
- return GtColumnWidthDirective;
3500
- }());
3501
-
3502
- /**
3503
- * @fileoverview added by tsickle
3504
- * @suppress {checkTypes} checked by tsc
3505
- */
3506
- var GenericTableModule = /** @class */ (function () {
3507
- function GenericTableModule() {
3508
- }
3509
- GenericTableModule.decorators = [
3510
- { type: NgModule, args: [{
3511
- declarations: [
3512
- ComponentAnchorDirective,
3513
- GenericTableComponent,
3514
- GtPaginationComponent,
3515
- GtVisiblePipe,
3516
- GtRenderPipe,
3517
- DashCasePipe,
3518
- GtPropertyPipe,
3519
- GtChunkPipe,
3520
- GtFilterPipe,
3521
- GtOrderByPipe,
3522
- GtExpandingRowComponent,
3523
- GtCustomComponentFactory,
3524
- GtSearchPipe,
3525
- PaginationPipe,
3526
- GtTableInfoComponent,
3527
- TableInfoPipe,
3528
- GtMetaPipe,
3529
- GtTotalsPipe,
3530
- GtTotalsPositionPipe,
3531
- GtRowClassPipe,
3532
- GtColumnClassPipe,
3533
- GtHighlightPipe,
3534
- GtIsObservablePipe,
3535
- GtIsEditablePipe,
3536
- GtDropdownComponent,
3537
- GtColumnWidthDirective,
3538
- GtDrilldownComponent,
3539
- GtCheckboxComponent
3540
- ],
3541
- imports: [CommonModule, FormsModule],
3542
- exports: [
3543
- GenericTableComponent,
3544
- GtPaginationComponent,
3545
- GtTableInfoComponent,
3546
- GtRenderPipe,
3547
- GtColumnClassPipe,
3548
- GtPropertyPipe,
3549
- GtHighlightPipe,
3550
- GtExpandingRowComponent,
3551
- GtDropdownComponent,
3552
- GtDrilldownComponent,
3553
- GtCheckboxComponent
3554
- ],
3555
- entryComponents: [GtDrilldownComponent, GtCheckboxComponent],
3556
- providers: [GtMetaPipe, GtHighlightPipe]
3557
- },] }
3558
- ];
3559
- return GenericTableModule;
3560
- }());
3561
-
3562
- /**
3563
- * @fileoverview added by tsickle
3564
- * @suppress {checkTypes} checked by tsc
3565
- */
3566
-
3567
- /**
3568
- * @fileoverview added by tsickle
3569
- * @suppress {checkTypes} checked by tsc
3570
- */
3571
-
3572
- export { GtTableInfoComponent, TableInfoPipe, GtPaginationComponent, PaginationPipe, GtExpandedRow, GtExpandingRowComponent, GtDropdownComponent, GtDrilldownComponent, GtCustomComponent, GtCustomComponentFactory, GtCheckboxComponent, GenericTableComponent, GenericTableModule, ComponentAnchorDirective as ɵb, GtColumnWidthDirective as ɵr, DashCasePipe as ɵf, GtChunkPipe as ɵh, GtColumnClassPipe as ɵo, GtFilterPipe as ɵi, GtHighlightPipe as ɵe, GtIsEditablePipe as ɵq, GtIsObservablePipe as ɵp, GtMetaPipe as ɵa, GtOrderByPipe as ɵj, GtPropertyPipe as ɵg, GtRenderPipe as ɵd, GtRowClassPipe as ɵn, GtSearchPipe as ɵk, GtTotalsPositionPipe as ɵm, GtTotalsPipe as ɵl, GtVisiblePipe as ɵc };
3573
-
3574
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1nZW5lcmljLXRhYmxlLWNvcmUuanMubWFwIiwic291cmNlcyI6WyJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtbWV0YS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ2VuZXJpYy10YWJsZS9nZW5lcmljLXRhYmxlLmNvbXBvbmVudC50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2d0LXRhYmxlLWluZm8vZ3QtdGFibGUtaW5mby5jb21wb25lbnQudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvY29tcG9uZW50cy9ndC1wYWdpbmF0aW9uL2d0LXBhZ2luYXRpb24uY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ3QtZXhwYW5kaW5nLXJvdy9ndC1leHBhbmRpbmctcm93LmNvbXBvbmVudC50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2d0LWRyb3Bkb3duL2d0LWRyb3Bkb3duLmNvbXBvbmVudC50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2d0LWRyaWxsZG93bi9ndC1kcmlsbGRvd24uY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5L2d0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeS5jb21wb25lbnQudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvY29tcG9uZW50cy9ndC1jaGVja2JveC9ndC1jaGVja2JveC5jb21wb25lbnQudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtdmlzaWJsZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXNlYXJjaC5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWlzLWVkaXRhYmxlLnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtaXMtb2JzZXJ2YWJsZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWhpZ2hsaWdodC5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWNvbHVtbi1jbGFzcy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXJvdy1jbGFzcy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXRvdGFscy1wb3NpdGlvbi5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXRvdGFscy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LW9yZGVyLWJ5LnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtZmlsdGVyLnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtY2h1bmsucGlwZS50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9waXBlcy9ndC1wcm9wZXJ0eS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2Rhc2gtY2FzZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXJlbmRlci5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2RpcmVjdGl2ZXMvY29tcG9uZW50LWFuY2hvci5kaXJlY3RpdmUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvZGlyZWN0aXZlcy9ndC1jb2x1bW4td2lkdGguZGlyZWN0aXZlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvcmUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndE1ldGEnXG59KVxuZXhwb3J0IGNsYXNzIEd0TWV0YVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKFxuXHRcdGFsbFJvd3M6IEFycmF5PEd0Um93Pixcblx0XHRyb3dJbmRleD86IHN0cmluZyxcblx0XHRwYWdlPzogbnVtYmVyLFxuXHRcdHJlY29yZExlbmd0aD86IG51bWJlclxuXHQpOiBBcnJheTxHdFJvdz4ge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYWxsUm93cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCFhbGxSb3dzW2ldLiQkZ3RSb3dJZCkge1xuXHRcdFx0XHRhbGxSb3dzW2ldLiQkZ3RSb3dJZCA9IHJvd0luZGV4XG5cdFx0XHRcdFx0PyBhbGxSb3dzW2ldW3Jvd0luZGV4XVxuXHRcdFx0XHRcdDogcGFnZVxuXHRcdFx0XHRcdFx0PyBwYWdlICogcmVjb3JkTGVuZ3RoICtcblx0XHRcdFx0XHRcdCAgaSArXG5cdFx0XHRcdFx0XHQgICdfJyArXG5cdFx0XHRcdFx0XHQgIE1hdGgucmFuZG9tKClcblx0XHRcdFx0XHRcdFx0XHQudG9TdHJpbmcoMzYpXG5cdFx0XHRcdFx0XHRcdFx0LnN1YnN0cigyLCAxNilcblx0XHRcdFx0XHRcdDogaSArXG5cdFx0XHRcdFx0XHQgICdfJyArXG5cdFx0XHRcdFx0XHQgIE1hdGgucmFuZG9tKClcblx0XHRcdFx0XHRcdFx0XHQudG9TdHJpbmcoMzYpXG5cdFx0XHRcdFx0XHRcdFx0LnN1YnN0cigyLCAxNik7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIWFsbFJvd3NbaV0uJCRndEluaXRpYWxSb3dJbmRleCkge1xuXHRcdFx0XHRhbGxSb3dzW2ldLiQkZ3RJbml0aWFsUm93SW5kZXggPSBpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gYWxsUm93cztcblx0fVxufVxuIiwiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRFdmVudEVtaXR0ZXIsXG5cdElucHV0LFxuXHRPbkNoYW5nZXMsXG5cdE9uRGVzdHJveSxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFJlbmRlcmVyMixcblx0U2ltcGxlQ2hhbmdlcyxcblx0VHlwZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuaW1wb3J0IHsgR3RFeHBhbmRlZFJvdyB9IGZyb20gJy4uL2d0LWV4cGFuZGluZy1yb3cvZ3QtZXhwYW5kaW5nLXJvdy5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3RPcHRpb25zIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1vcHRpb25zJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdENvbmZpZ1NldHRpbmcgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1zZXR0aW5nJztcbmltcG9ydCB7IEd0Um93TWV0YSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtcm93LW1ldGEnO1xuaW1wb3J0IHsgR3RUZXh0cyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtdGV4dHMnO1xuaW1wb3J0IHsgR3RDb25maWcgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWNvbmZpZyc7XG5pbXBvcnQgeyBHdEV2ZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1ldmVudCc7XG5pbXBvcnQgeyBHdEluZm9ybWF0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1pbmZvcm1hdGlvbic7XG5pbXBvcnQgeyBHdFJlbmRlckZpZWxkIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1yZW5kZXItZmllbGQnO1xuaW1wb3J0IHsgR3RNZXRhUGlwZSB9IGZyb20gJy4uLy4uL3BpcGVzL2d0LW1ldGEucGlwZSc7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2dlbmVyaWMtdGFibGUnLFxuXHR0ZW1wbGF0ZTogYDx0YWJsZSBjbGFzcz1cInRhYmxlXCIgbmdDbGFzcz1cInt7Z3RDbGFzc2VzfX0ge3tndE9wdGlvbnMuc3RhY2sgPyAndGFibGUtc3RhY2tlZCc6Jyd9fVwiXG4gICAgICAgKm5nSWY9XCJndEZpZWxkcyAmJiBndFNldHRpbmdzICYmIChndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlKS5sZW5ndGggPiAwXCI+XG4gIDx0aGVhZD5cbiAgPHRyPlxuICAgIDx0aCBjbGFzcz1cImd0LXNvcnQtbGFiZWxcIiAqbmdJZj1cImd0T3B0aW9ucy5zdGFja1wiPnt7Z3RUZXh0cy5zb3J0TGFiZWx9fTwvdGg+XG4gICAgPHRoICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZ3RTZXR0aW5ncyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlXCJcbiAgICAgICAgbmdDbGFzcz1cInt7Y29sdW1uLm9iamVjdEtleSArJy1jb2x1bW4nIHwgZGFzaENhc2V9fSB7e2d0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidjbGFzc05hbWVzJ319IHt7Y29sdW1uLnNvcnRFbmFibGVkID8gJ3NvcnQtJytjb2x1bW4uc29ydDonJ319IHt7Y29sdW1uLnNvcnRFbmFibGVkICYmIGNvbHVtbi5zb3J0T3JkZXIgPj0gMCAgPyAnc29ydC1vcmRlci0nK2NvbHVtbi5zb3J0T3JkZXI6Jyd9fSB7eyBndEZpZWxkcyB8IGd0Q29sdW1uQ2xhc3M6Y29sdW1uIH19XCJcbiAgICAgICAgKGNsaWNrKT1cImNvbHVtbi5zb3J0RW5hYmxlZCA/IGd0U29ydChjb2x1bW4ub2JqZWN0S2V5LCRldmVudCk6Jyc7XCI+XG4gICAgICA8c3BhbiAqbmdJZj1cIiEoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2hlYWRlcicpXCI+e3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZSd9fTwvc3Bhbj5cbiAgICAgIDxndC1jdXN0b20tY29tcG9uZW50LWZhY3RvcnkgKm5nSWY9XCIoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2hlYWRlcicpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKT8udHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbmplY3Rvcl09XCIoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2hlYWRlcicpPy5pbmplY3RvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb2x1bW5dPVwiZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J25hbWUnXCI+PC9ndC1jdXN0b20tY29tcG9uZW50LWZhY3Rvcnk+XG4gICAgICA8Z3QtY2hlY2tib3ggKm5nSWY9XCIoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2NvbHVtbkNvbXBvbmVudCcpPy50eXBlID09PSAnY2hlY2tib3gnXCIgW2NoZWNrZWRdPVwiKGd0T3B0aW9ucy5sYXp5TG9hZCA/IGxhenlBbGxTZWxlY3RlZDpzZWxlY3RlZFJvd3MubGVuZ3RoID09PSBndERhdGEubGVuZ3RoKVwiIChjaGFuZ2VkKT1cInRvZ2dsZUFsbFJvd3MoKVwiPjwvZ3QtY2hlY2tib3g+XG4gICAgPC90aD5cbiAgPC90cj5cbiAgPC90aGVhZD5cbiAgPG5nLXRlbXBsYXRlXG4gICAgW25nSWZdPVwiZ3RUb3RhbHMgJiYgKGd0T3B0aW9ucy5sYXp5TG9hZCA9PT0gZmFsc2UgPyAoZ3REYXRhIHwgZ3RGaWx0ZXI6Z3RJbmZvLmZpbHRlcjpndEluZm86cmVmcmVzaEZpbHRlcjpndERhdGEubGVuZ3RoIHwgZ3RTZWFyY2g6Z3RJbmZvLnNlYXJjaFRlcm1zOmd0SW5mbzpndFNldHRpbmdzOmd0RmllbGRzOmd0RGF0YS5sZW5ndGgpLmxlbmd0aCA+IDAgOiBndERhdGEubGVuZ3RoID4gMClcIj5cbiAgICA8dGhlYWQgY2xhc3M9XCJndC10b3RhbHNcIj5cbiAgICA8dHIgKm5nRm9yPVwibGV0IHRvdGFsIG9mIGd0VG90YWxzIHwgZ3RUb3RhbHNQb3NpdGlvblwiPlxuICAgICAgPHRkICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZ3RTZXR0aW5ncyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlO2xldCBpID0gaW5kZXg7XCJcbiAgICAgICAgICBuZ0NsYXNzPVwie3tjb2x1bW4ub2JqZWN0S2V5ICsnLXRvdGFscy1jb2x1bW4nIHwgZGFzaENhc2V9fSB7e2d0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidjbGFzc05hbWVzJ319IHt7IGd0RmllbGRzIHwgZ3RDb2x1bW5DbGFzczpjb2x1bW4gfX1cIj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJpID09PSAwXCIgY2xhc3M9XCJmbG9hdC1sZWZ0XCI+e3t0b3RhbC5uYW1lfX08L3NwYW4+PHNwYW5cbiAgICAgICAgW2lubmVySFRNTF09XCJ0b3RhbC5maWVsZHNbY29sdW1uLm9iamVjdEtleV0gfCBndFRvdGFsczoodG90YWwudXBkYXRlID09PSBmYWxzZSB8fCBndE9wdGlvbnMubGF6eUxvYWQgPT09IHRydWUpID8gZ3REYXRhOihndERhdGEgfCBndEZpbHRlcjpndEluZm8uZmlsdGVyOmd0SW5mbzpyZWZyZXNoRmlsdGVyOmd0RGF0YS5sZW5ndGggfCBndFNlYXJjaDpndEluZm8uc2VhcmNoVGVybXM6Z3RJbmZvOmd0U2V0dGluZ3M6Z3RGaWVsZHM6Z3REYXRhLmxlbmd0aCk6Y29sdW1uLm9iamVjdEtleTpyZWZyZXNoVG90YWxzXCI+PC9zcGFuPlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIDwvdGhlYWQ+XG4gICAgPHRmb290IGNsYXNzPVwiZ3QtdG90YWxzXCI+XG4gICAgPHRyICpuZ0Zvcj1cImxldCB0b3RhbCBvZiBndFRvdGFscyB8IGd0VG90YWxzUG9zaXRpb246J2Zvb3RlcidcIj5cbiAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZTtsZXQgaSA9IGluZGV4O1wiXG4gICAgICAgICAgbmdDbGFzcz1cInt7Y29sdW1uLm9iamVjdEtleSArJy10b3RhbHMtY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyBndEZpZWxkcyB8IGd0Q29sdW1uQ2xhc3M6Y29sdW1uIH19XCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaSA9PT0gMFwiIGNsYXNzPVwiZmxvYXQtbGVmdFwiPnt7dG90YWwubmFtZX19PC9zcGFuPjxzcGFuXG4gICAgICAgIFtpbm5lckhUTUxdPVwidG90YWwuZmllbGRzW2NvbHVtbi5vYmplY3RLZXldIHwgZ3RUb3RhbHM6KHRvdGFsLnVwZGF0ZSA9PT0gZmFsc2UgfHwgZ3RPcHRpb25zLmxhenlMb2FkID09PSB0cnVlKSA/IGd0RGF0YTooZ3REYXRhIHwgZ3RGaWx0ZXI6Z3RJbmZvLmZpbHRlcjpndEluZm86cmVmcmVzaEZpbHRlcjpndERhdGEubGVuZ3RoIHwgZ3RTZWFyY2g6Z3RJbmZvLnNlYXJjaFRlcm1zOmd0SW5mbzpndFNldHRpbmdzOmd0RmllbGRzOmd0RGF0YS5sZW5ndGgpOmNvbHVtbi5vYmplY3RLZXk6cmVmcmVzaFRvdGFsc1wiPjwvc3Bhbj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8L3Rmb290PlxuICA8L25nLXRlbXBsYXRlPlxuICA8dGJvZHkgKm5nSWY9XCJndERhdGEgJiYgZ3RJbmZvXCI+XG4gIDxuZy10ZW1wbGF0ZSBjbGFzcz1cInRhYmxlLXJvd3NcIiBuZ0ZvciBsZXQtcm93IGxldC1sYXN0PVwibGFzdFwiIFtuZ0ZvclRyYWNrQnldPVwidHJhY2tCeUZuXCJcbiAgICAgICAgICAgICAgIFtuZ0Zvck9mXT1cImd0T3B0aW9ucy5sYXp5TG9hZCAmJiBndEluZm8gPyAoZ3REYXRhW2d0SW5mby5wYWdlQ3VycmVudC0xXSkgOiAoZ3REYXRhIHwgZ3RGaWx0ZXI6Z3RJbmZvLmZpbHRlcjpndEluZm86cmVmcmVzaEZpbHRlcjpndERhdGEubGVuZ3RoIHwgZ3RTZWFyY2g6Z3RJbmZvLnNlYXJjaFRlcm1zOmd0SW5mbzpndFNldHRpbmdzOmd0RmllbGRzOmd0RGF0YS5sZW5ndGggfCBndE9yZGVyQnk6c29ydE9yZGVyOmd0RmllbGRzOnJlZnJlc2hTb3J0aW5nOmd0RGF0YS5sZW5ndGggfCBndENodW5rOmd0SW5mbzpndEluZm8ucmVjb3JkTGVuZ3RoOmd0SW5mby5wYWdlQ3VycmVudDpyZWZyZXNoUGFnZUFycmF5Omd0RGF0YS5sZW5ndGg6Z3RFdmVudDpkYXRhIHwgZ3RSb3dDbGFzczpndEZpZWxkcylcIj5cbiAgICA8dHIgW25nQ2xhc3NdPVwieydyb3ctc2VsZWN0ZWQnOm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdPy5pc1NlbGVjdGVkLCAncm93LW9wZW4nOm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdPy5pc09wZW4sICdyb3ctbG9hZGluZyc6bG9hZGluZywgJ3Jvdy1leHBhbmRhYmxlJzpndFJvd0NvbXBvbmVudH1cIlxuICAgICAgICBjbGFzcz1cInt7cm93LiQkZ3RSb3dDbGFzc319XCJcbiAgICAgICAgKGNsaWNrKT1cImd0T3B0aW9ucy5yb3dTZWxlY3Rpb24gPyB0b2dnbGVTZWxlY3Qocm93KTpyb3dDbGljayhyb3csICRldmVudClcIj5cbiAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHJvdyB8IGd0UmVuZGVyOmd0U2V0dGluZ3M6Z3RGaWVsZHM6cmVmcmVzaFBpcGU6bG9hZGluZzpndE9wdGlvbnMuaGlnaGxpZ2h0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczt0cmFja0J5OnRyYWNrQnlDb2x1bW5GblwiXG4gICAgICAgICAgbmdDbGFzcz1cInt7Y29sdW1uLm9iamVjdEtleSArJy1jb2x1bW4nIHwgZGFzaENhc2V9fSB7e2d0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidjbGFzc05hbWVzJ319IHt7KGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykgPyAnZ3QtaW5saW5lLWVkaXQnOicnfX0ge3tjb2x1bW4uZWRpdGVkID8gJ2d0LWVkaXRlZCc6Jyd9fSB7eyBndEZpZWxkcyB8IGd0Q29sdW1uQ2xhc3M6Y29sdW1uOnJvdyB9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndC1yb3ctbGFiZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJndE9wdGlvbnMuc3RhY2tcIj57eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA6IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfX08L3NwYW4+XG4gICAgICAgIDxndC1jdXN0b20tY29tcG9uZW50LWZhY3RvcnkgKm5nSWY9XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50ICYmIGNvbHVtbi5jb2x1bW5Db21wb25lbnQudHlwZSAhPT0gJ2NoZWNrYm94J1wiIGNsYXNzPVwiZ3Qtcm93LWNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImNvbHVtbi5jb2x1bW5Db21wb25lbnQudHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2luamVjdG9yXT1cImNvbHVtbi5jb2x1bW5Db21wb25lbnQuaW5qZWN0b3JcIiBbcm93XT1cInJvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbHVtbl09XCJjb2x1bW5cIiAocmVkcmF3RXZlbnQpPVwicmVkcmF3KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWFyY2hUZXJtc109XCJndEluZm8uc2VhcmNoVGVybXNcIiAgKHNlYXJjaEV2ZW50KT1cInJlZHJhdygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29sdW1uLmNsaWNrID8gY29sdW1uLmNsaWNrKHJvdyxjb2x1bW4sJGV2ZW50KTonJztjb2x1bW4uZXhwYW5kID8gdG9nZ2xlQ29sbGFwc2Uocm93LCBjb2x1bW4uZXhwYW5kKTonJ1wiPjwvZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5PlxuICAgICAgICA8c3BhbiAqbmdJZj1cIiFjb2x1bW4uY29sdW1uQ29tcG9uZW50ICYmICghKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykgfHwgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpPy5hY3RpdmUgfCBndElzT2JzZXJ2YWJsZSkgJiYgISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgYXN5bmMpIHx8ICghKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpPy5hY3RpdmUgfCBndElzT2JzZXJ2YWJsZSkgJiYgISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc0VkaXRhYmxlOnJvdzpyZWZyZXNoUGlwZSkpKVwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiZ3Qtcm93LWNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjb2x1bW4uY2xpY2sgPyBjb2x1bW4uY2xpY2socm93LGNvbHVtbiwkZXZlbnQpOicnO2NvbHVtbi5leHBhbmQgPyB0b2dnbGVDb2xsYXBzZShyb3csIGNvbHVtbi5leHBhbmQpOicnXCI+PC9zcGFuPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBbbmdJZl09XCIhY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiAoKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpPy5hY3RpdmUgfCBndElzT2JzZXJ2YWJsZSkgJiYgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpPy5hY3RpdmUgfCBhc3luYykgfHwgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpPy5hY3RpdmUgfCBndElzRWRpdGFibGU6cm93OnJlZnJlc2hQaXBlKSlcIj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiKFt0cnVlLCdlbWFpbCcsJ251bWJlcicsJ3Bhc3N3b3JkJywgJ3RleHQnXS5pbmRleE9mKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUpICE9PSAtMSkgfHwgIShndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGVcIj5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlubGluZS1lZGl0XCIgW2F0dHIudHlwZV09XCIhKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSA/ICd0ZXh0JyA6ICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSB8IGd0SXNPYnNlcnZhYmxlKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGU6KGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSB8IGFzeW5jXCIgWyhuZ01vZGVsKV09XCJjb2x1bW4ucmVuZGVyVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCJndFVwZGF0ZUNvbHVtbigkZXZlbnQscm93LCBjb2x1bW4pXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImd0LWlubGluZS1lZGl0LW5vdGljZVwiPnt7Z3RUZXh0cy5pbmxpbmVFZGl0RWRpdGVkfX08L3NwYW4+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8Z3QtZHJvcGRvd25cbiAgICAgICAgICAgICpuZ0lmPVwiKCgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlKSAmJiAoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSkubGVuZ3RoID4gMCkgfHwgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBndElzT2JzZXJ2YWJsZSlcIlxuICAgICAgICAgICAgW29wdGlvbnNdPVwiISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlIHwgZ3RJc09ic2VydmFibGUpID8gKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSA6IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBhc3luY1wiXG4gICAgICAgICAgICBbaWRdPVwiJ18nICsgcm93LiQkZ3RSb3dJZCArICdfJyArIGNvbHVtbi5vYmplY3RLZXlcIlxuICAgICAgICAgICAgWyhzZWxlY3RlZCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCIgKHNlbGVjdGVkQ2hhbmdlKT1cImd0RHJvcGRvd25TZWxlY3Qocm93LCBjb2x1bW4pXCI+QWRkXG4gICAgICAgICAgICBpbmxpbmUgZWRpdGluZyBtb2R1bGVcbiAgICAgICAgICA8L2d0LWRyb3Bkb3duPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIWNvbHVtbi5jb2x1bW5Db21wb25lbnQgJiYgISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlKSBcIj5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgIFtuZ0lmXT1cIlt0cnVlLCdlbWFpbCcsJ251bWJlcicsJ3Bhc3N3b3JkJ10uaW5kZXhPZihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpICE9PSAtMVwiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5saW5lLWVkaXRcIiBbYXR0ci50eXBlXT1cIihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID09PSB0cnVlID8gJ3RleHQnOihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpXCIgWyhuZ01vZGVsKV09XCJjb2x1bW4ucmVuZGVyVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCJndFVwZGF0ZUNvbHVtbigkZXZlbnQscm93LCBjb2x1bW4pXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImd0LWlubGluZS1lZGl0LW5vdGljZVwiPnt7Z3RUZXh0cy5pbmxpbmVFZGl0RWRpdGVkfX08L3NwYW4+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8Z3QtZHJvcGRvd25cbiAgICAgICAgICAgICpuZ0lmPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykgJiYgW3RydWUsJ2VtYWlsJywnbnVtYmVyJywncGFzc3dvcmQnXS5pbmRleE9mKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykgPT09IC0xXCJcbiAgICAgICAgICAgIFtvcHRpb25zXT1cImd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0J1wiXG4gICAgICAgICAgICBbaWRdPVwiJ18nICsgcm93LiQkZ3RSb3dJZCArICdfJyArIGNvbHVtbi5vYmplY3RLZXlcIlxuICAgICAgICAgICAgWyhzZWxlY3RlZCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCIgKHNlbGVjdGVkQ2hhbmdlKT1cImd0RHJvcGRvd25TZWxlY3Qocm93LCBjb2x1bW4pXCI+QWRkXG4gICAgICAgICAgICBpbmxpbmUgZWRpdGluZyBtb2R1bGVcbiAgICAgICAgICA8L2d0LWRyb3Bkb3duPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8Z3QtY2hlY2tib3ggKm5nSWY9XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50ICYmIGNvbHVtbi5jb2x1bW5Db21wb25lbnQudHlwZSA9PT0gJ2NoZWNrYm94J1wiIFtjaGVja2VkXT1cIm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdPy5pc1NlbGVjdGVkXCIgKGNoYW5nZWQpPVwidG9nZ2xlU2VsZWN0KHJvdylcIj48L2d0LWNoZWNrYm94PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIDx0ciBjbGFzcz1cInJvdy1leHBhbmRlZFwiICpuZ0lmPVwibWV0YUluZm9bcm93LiQkZ3RSb3dJZF0/LmlzT3BlblwiPlxuICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiKGd0RmllbGRzIHwgZ3RWaXNpYmxlOmd0U2V0dGluZ3M6cmVmcmVzaFBpcGUpLmxlbmd0aFwiPlxuICAgICAgICA8Z3QtZXhwYW5kaW5nLXJvdyBbcm93XT1cInJvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImV4cGFuZGVkUm93LmNvbXBvbmVudCA/IGV4cGFuZGVkUm93LmNvbXBvbmVudDpndFJvd0NvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb2x1bW5XaWR0aF09XCJjb2x1bW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndEZpZWxkc109XCJndEZpZWxkc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndE9wdGlvbnNdPVwiZ3RPcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2d0RXZlbnRdPVwiZ3RFdmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndEluZm9dPVwiZ3RJbmZvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2d0U2V0dGluZ3NdPVwiZ3RTZXR0aW5nc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhXT1cImV4cGFuZGVkUm93LmRhdGEgPyBleHBhbmRlZFJvdy5kYXRhOnJvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChyZWRyYXdFdmVudCk9XCJyZWRyYXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICh0b2dnbGVSb3dFdmVudCk9XCJ0b2dnbGVDb2xsYXBzZSgkZXZlbnQpXCI+PC9ndC1leHBhbmRpbmctcm93PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIDx0ciAqbmdJZj1cImd0T3B0aW9ucy5yZXBvcnRDb2x1bW5XaWR0aCAmJiBsYXN0XCI+XG4gICAgICA8dGQgc3R5bGU9XCJwYWRkaW5nOiAwOyBib3JkZXI6bm9uZTtcIlxuICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZ3RTZXR0aW5ncyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlXCIgZ3RDb2x1bW5XaWR0aFxuICAgICAgICAgIFtvYmplY3RLZXldPVwiY29sdW1uLm9iamVjdEtleVwiIFt3aWR0aHNdPVwiY29sdW1uV2lkdGhcIj48L3RkPlxuICAgIDwvdHI+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDx0ciAqbmdJZj1cImd0SW5mby5wYWdlVG90YWwgPT09IDAgJiYgKGd0SW5mby5zZWFyY2hUZXJtcyB8fCBndEluZm8uZmlsdGVyKSAmJiAhbG9hZGluZ1wiPlxuICAgIDx0ZCBjbGFzcz1cImd0LW5vLW1hdGNoaW5nLXJlc3VsdHNcIiBbYXR0ci5jb2xzcGFuXT1cIihndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzKS5sZW5ndGhcIj5cbiAgICAgIHt7Z3RUZXh0cy5ub01hdGNoaW5nRGF0YX19XG4gICAgPC90ZD5cbiAgPC90cj5cbiAgPHRyICpuZ0lmPVwiZ3RJbmZvLnBhZ2VUb3RhbCA9PT0gMCAmJiAhKGd0SW5mby5zZWFyY2hUZXJtcyB8fCBndEluZm8uZmlsdGVyKSAmJiAhbG9hZGluZ1wiPlxuICAgIDx0ZCBjbGFzcz1cImd0LW5vLXJlc3VsdHNcIiBbYXR0ci5jb2xzcGFuXT1cIihndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzKS5sZW5ndGhcIj57e2d0VGV4dHMubm9EYXRhfX1cbiAgICA8L3RkPlxuICA8L3RyPlxuICA8dHIgKm5nSWY9XCJndEluZm8ucGFnZVRvdGFsID09PSAwICYmIGxvYWRpbmdcIj5cbiAgICA8dGQgY2xhc3M9XCJndC1sb2FkaW5nLWRhdGFcIiBbYXR0ci5jb2xzcGFuXT1cIihndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzKS5sZW5ndGhcIj57e2d0VGV4dHMubG9hZGluZ319PC90ZD5cbiAgPC90cj5cbiAgPC90Ym9keT5cbjwvdGFibGU+XG48dGFibGUgY2xhc3M9XCJ0YWJsZVwiIG5nQ2xhc3M9XCJ7e2d0Q2xhc3Nlc319IHt7Z3RPcHRpb25zLnN0YWNrID8gJ3RhYmxlLXN0YWNrZWQnOicnfX1cIlxuICAgICAgICpuZ0lmPVwiZ3RGaWVsZHMgJiYgZ3RTZXR0aW5ncyAmJiAoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZSkubGVuZ3RoID09PSAwXCI+XG4gIDx0aGVhZD5cbiAgPHRyPlxuICAgIDx0aCBjbGFzcz1cImd0LW5vLXZpc2libGUtY29sdW1uc1wiPnt7Z3RUZXh0cy5ub1Zpc2libGVDb2x1bW5zSGVhZGluZ319PC90aD5cbiAgPC90cj5cbiAgPC90aGVhZD5cbiAgPHRib2R5PlxuICA8dHI+XG4gICAgPHRkIGNsYXNzPVwiZ3Qtbm8tdmlzaWJsZS1jb2x1bW5zXCI+e3tndFRleHRzLm5vVmlzaWJsZUNvbHVtbnN9fTwvdGQ+XG4gIDwvdHI+XG4gIDwvdGJvZHk+XG48L3RhYmxlPlxuPHRhYmxlIGNsYXNzPVwidGFibGVcIiBuZ0NsYXNzPVwie3tndENsYXNzZXN9fSB7e2d0T3B0aW9ucy5zdGFjayA/ICd0YWJsZS1zdGFja2VkJzonJ319XCJcbiAgICAgICAqbmdJZj1cIiFndEZpZWxkcyB8fCAhZ3RTZXR0aW5nc1wiPlxuICA8dGhlYWQ+XG4gIDx0cj5cbiAgICA8dGggY2xhc3M9XCJndC1sb2FkaW5nLWNvbmZpZ1wiPiZuYnNwOzwvdGg+XG4gIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDx0Ym9keT5cbiAgPHRyPlxuICAgIDx0ZCBjbGFzcz1cImd0LWxvYWRpbmctY29uZmlnXCI+Jm5ic3A7PC90ZD5cbiAgPC90cj5cbiAgPC90Ym9keT5cbjwvdGFibGU+XG5gXG59KVxuZXhwb3J0IGNsYXNzIEdlbmVyaWNUYWJsZUNvbXBvbmVudDxSIGV4dGVuZHMgR3RSb3csIEMgZXh0ZW5kcyBHdEV4cGFuZGVkUm93PFI+PlxuXHRpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXHRnZXQgZ3RSb3dDb21wb25lbnQoKTogVHlwZTxDPiB7XG5cdFx0cmV0dXJuIHRoaXMuX2d0Um93Q29tcG9uZW50O1xuXHR9XG5cblx0Z2V0IGhhc0VkaXRzKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmVkaXRlZFJvd3MpLmxlbmd0aCA+IDA7XG5cdH1cblxuXHRnZXQgZ3RPcHRpb25zKCk6IEd0T3B0aW9ucyB7XG5cdFx0cmV0dXJuIHRoaXMuX2d0T3B0aW9ucztcblx0fVxuXG5cdGdldCBndFRvdGFscygpOiBhbnkge1xuXHRcdHJldHVybiB0aGlzLl9ndFRvdGFscztcblx0fVxuXG5cdGdldCBndEZpZWxkcygpOiBHdENvbmZpZ0ZpZWxkPFIsIGFueT5bXSB7XG5cdFx0cmV0dXJuIHRoaXMuX2d0RmllbGRzO1xuXHR9XG5cblx0Z2V0IGd0U2V0dGluZ3MoKTogR3RDb25maWdTZXR0aW5nW10ge1xuXHRcdHJldHVybiB0aGlzLl9ndFNldHRpbmdzO1xuXHR9XG5cblx0Z2V0IGd0RGF0YSgpOiBBcnJheTxhbnk+IHtcblx0XHRyZXR1cm4gdGhpcy5fZ3REYXRhO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGd0T3B0aW9ucyh2YWx1ZTogR3RPcHRpb25zKSB7XG5cdFx0dGhpcy5fZ3RPcHRpb25zID0gdmFsdWU7XG5cblx0XHQvLyBpZiBudW1iZXIgb2Ygcm93cyBpcyBwYXNzZWQgYW5kIGlmIG51bWJlciBvZiByb3dzIGRpZmZlcnMgZnJvbSBjdXJyZW50IHJlY29yZCBsZW5ndGguLi5cblx0XHRpZiAoXG5cdFx0XHR0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3MgJiZcblx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCAhPT0gdGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzXG5cdFx0KSB7XG5cdFx0XHQvLyAuLi51cGRhdGUgcmVjb3JkIGxlbmd0aCBhbmQgcmVkcmF3IHRhYmxlXG5cdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGggPSB0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3M7XG5cdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdH1cblxuXHRcdC8vIC4uLmV4dGVuZCBndE9wdGlvbnMgZGVmYXVsdCB2YWx1ZXMgd2l0aCB2YWx1ZXMgcGFzc2VkIGludG8gY29tcG9uZW50XG5cdFx0dGhpcy5fZ3RPcHRpb25zID0gPEd0T3B0aW9ucz50aGlzLmV4dGVuZChcblx0XHRcdHRoaXMuZ3REZWZhdWx0T3B0aW9ucyxcblx0XHRcdHRoaXMuX2d0T3B0aW9uc1xuXHRcdCk7XG5cdH1cblxuXHRASW5wdXQoKVxuXHRzZXQgZ3RUb3RhbHModmFsdWU6IGFueSkge1xuXHRcdHRoaXMuX2d0VG90YWxzID0gdmFsdWU7XG5cdH1cblx0QElucHV0KClcblx0c2V0IGd0RmllbGRzKHZhbHVlOiBHdENvbmZpZ0ZpZWxkPFIsIGFueT5bXSkge1xuXHRcdHRoaXMuX2d0RmllbGRzID0gdmFsdWU7XG5cdFx0Y29uc3QgQ09MVU1OU19XSVRIX0NMQVNTX05BTUVTID0gdGhpcy5fZ3RGaWVsZHNcblx0XHRcdC5tYXAoY29sdW1uID0+IGNvbHVtbilcblx0XHRcdC5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi5jbGFzc05hbWVzKTtcblx0XHQvLyBUT0RPOiByZW1vdmUgZGVwcmVjYXRlZCB3YXJuaW5nIHdoZW4gc2V0dGluZyBoYXMgYmVlbiByZW1vdmVkXG5cdFx0aWYgKENPTFVNTlNfV0lUSF9DTEFTU19OQU1FUy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25zb2xlLndhcm4oXG5cdFx0XHRcdCdGaWVsZCBzZXR0aW5nIFwiY2xhc3NOYW1lc1wiIGhhdmUgYmVlbiBkZXByZWNhdGVkIGluIGZhdm9yIGZvciBcImNvbHVtbkNsYXNzXCIgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLCBwbGVhc2UgdXBkYXRlIGZpZWxkIHNldHRpbmdzIGZvciBjb2x1bW4gd2l0aCBvYmplY3Qga2V5OiAnICtcblx0XHRcdFx0XHRDT0xVTU5TX1dJVEhfQ0xBU1NfTkFNRVNbMF0ub2JqZWN0S2V5XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXHRASW5wdXQoKVxuXHRzZXQgZ3RTZXR0aW5ncyh2YWx1ZTogR3RDb25maWdTZXR0aW5nW10pIHtcblx0XHR0aGlzLl9ndFNldHRpbmdzID0gdmFsdWU7XG5cblx0XHQvLyBsb29wIHRocm91Z2ggY3VycmVudCBzZXR0aW5nc1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Ly8gc2V0IHNvcnQgZW5hYmxlZC9kaXNhYmxlZCBzZXR0aW5nXG5cdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnRFbmFibGVkID1cblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0RW5hYmxlZCAhPT0gZmFsc2Vcblx0XHRcdFx0XHQ/ICh0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnRFbmFibGVkID0gIShcblx0XHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ICYmXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydC5pbmRleE9mKCdkaXNhYmxlJykgIT09IC0xXG5cdFx0XHRcdFx0ICApKVxuXHRcdFx0XHRcdDogZmFsc2U7XG5cblx0XHRcdC8vIGNoZWNrIGlmIHNvcnRpbmcgaXMgdW5kZWZpbmVkLi4uXG5cdFx0XHRpZiAodHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0Ly8gLi4uaXMgc28sIHNldCBzb3J0aW5nIHByb3BlcnR5IHRvIGVuYWJsZVxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPSAnZW5hYmxlJztcblx0XHRcdH1cblxuXHRcdFx0Ly8gY2hlY2sgaWYgY29sdW1uIG9yZGVyIGlzIHVuZGVmaW5lZC4uLlxuXHRcdFx0aWYgKFxuXHRcdFx0XHR0eXBlb2YgdGhpcy5fZ3RTZXR0aW5nc1tpXS5jb2x1bW5PcmRlciA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5lbmFibGVkICE9PSBmYWxzZVxuXHRcdFx0KSB7XG5cdFx0XHRcdC8vIC4uLmlzIHNvLCBzZXQgc29ydGluZyBwcm9wZXJ0eSB0byBlbmFibGVcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5jb2x1bW5PcmRlciA9IHRoaXMuX2d0U2V0dGluZ3NbaSAtIDFdXG5cdFx0XHRcdFx0PyB0aGlzLl9ndFNldHRpbmdzW2kgLSAxXS5jb2x1bW5PcmRlciArIDFcblx0XHRcdFx0XHQ6IDA7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGNoZWNrIGlmIGNvbHVtbiBsb2NrIHNldHRpbmdzIGFyZSB1bmRlZmluZWQuLi5cblx0XHRcdGlmICh0eXBlb2YgdGhpcy5fZ3RTZXR0aW5nc1tpXS5sb2NrU2V0dGluZ3MgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdC8vIC4uLmlmIHNvLCBzZXQgbG9jayBzZXR0aW5ncyB0byBmYWxzZSB1bmxlc3MgZmllbGQgaXMgZGlzYWJsZWQgKGVuYWJsZSA9PT0gZmFsc2UpXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0ubG9ja1NldHRpbmdzID1cblx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLmVuYWJsZWQgPT09IGZhbHNlIHx8IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnJlc3RydWN0dXJlU29ydGluZygpO1xuXHR9XG5cdEBJbnB1dCgpXG5cdHNldCBndERhdGEoaW5pdGlhbERhdGE6IEFycmF5PGFueT4pIHtcblx0XHRjb25zdCBkYXRhID0gdGhpcy5fZ3RPcHRpb25zLm11dGF0ZURhdGFcblx0XHRcdD8gWy4uLmluaXRpYWxEYXRhXVxuXHRcdFx0OiB0aGlzLmNsb25lRGVlcChpbml0aWFsRGF0YSk7XG5cdFx0aWYgKHRoaXMuZ3RPcHRpb25zLmxhenlMb2FkICYmIHRoaXMuZ3RJbmZvKSB7XG5cdFx0XHR0aGlzLmd0TWV0YVBpcGUudHJhbnNmb3JtKFxuXHRcdFx0XHRkYXRhLFxuXHRcdFx0XHR0aGlzLmd0T3B0aW9ucy5yb3dJbmRleCxcblx0XHRcdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxLFxuXHRcdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdCk7XG5cdFx0XHRpZiAodGhpcy5sYXp5QWxsU2VsZWN0ZWQpIHtcblx0XHRcdFx0Y29uc3QgVU5JUVVFX1JPV1MgPSB0aGlzLnNlbGVjdGVkUm93cy5tYXAocm93ID0+IHJvdy4kJGd0Um93SWQpO1xuXHRcdFx0XHRkYXRhLm1hcChyb3cgPT4ge1xuXHRcdFx0XHRcdGlmIChVTklRVUVfUk9XUy5pbmRleE9mKHJvdy4kJGd0Um93SWQpID09PSAtMSkge1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MucHVzaChyb3cpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdHRoaXMuX3VwZGF0ZU1ldGFJbmZvKHRoaXMuc2VsZWN0ZWRSb3dzLCAnaXNTZWxlY3RlZCcsIHRydWUpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmd0TWV0YVBpcGUudHJhbnNmb3JtKGRhdGEsIHRoaXMuZ3RPcHRpb25zLnJvd0luZGV4KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkluaXRpYWxTdGF0ZSkge1xuXHRcdFx0ZGF0YS5tYXAocm93ID0+IHtcblx0XHRcdFx0Y29uc3Qgc2VsZWN0ZWQgPVxuXHRcdFx0XHRcdHR5cGVvZiB0aGlzLmd0T3B0aW9ucy5yb3dTZWxlY3Rpb25Jbml0aWFsU3RhdGUgPT09ICdmdW5jdGlvbidcblx0XHRcdFx0XHRcdD8gdGhpcy5ndE9wdGlvbnMucm93U2VsZWN0aW9uSW5pdGlhbFN0YXRlKHJvdylcblx0XHRcdFx0XHRcdDogdGhpcy5ndE9wdGlvbnMucm93U2VsZWN0aW9uSW5pdGlhbFN0YXRlO1xuXHRcdFx0XHRpZiAoc2VsZWN0ZWQpIHtcblx0XHRcdFx0XHRpZiAodHlwZW9mIHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID0geyBpc1NlbGVjdGVkOiB0cnVlIH07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0uaXNTZWxlY3RlZCA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdGlmIChcblx0XHRcdHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxTdGF0ZSAmJlxuXHRcdFx0dGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbENvbXBvbmVudFxuXHRcdCkge1xuXHRcdFx0ZGF0YS5tYXAocm93ID0+IHtcblx0XHRcdFx0Y29uc3QgZXhwYW5kZWQgPVxuXHRcdFx0XHRcdHR5cGVvZiB0aGlzLmd0T3B0aW9ucy5yb3dFeHBhbmRJbml0aWFsU3RhdGUgPT09ICdmdW5jdGlvbidcblx0XHRcdFx0XHRcdD8gdGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbFN0YXRlKHJvdylcblx0XHRcdFx0XHRcdDogdGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbFN0YXRlO1xuXHRcdFx0XHR0aGlzLmV4cGFuZGVkUm93ID0gdGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbENvbXBvbmVudDtcblxuXHRcdFx0XHRpZiAoZXhwYW5kZWQpIHtcblx0XHRcdFx0XHRpZiAodHlwZW9mIHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID0geyBpc09wZW46IHRydWUgfTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXS5pc09wZW4gPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRoaXMuX2d0RGF0YSA9IGRhdGE7XG5cdH1cblxuXHRASW5wdXQoKVxuXHRzZXQgZ3RSb3dDb21wb25lbnQodmFsdWU6IFR5cGU8Qz4pIHtcblx0XHRjb25zb2xlLndhcm4oXG5cdFx0XHQnR3RSb3dDb21wb25lbnQgaGFzIGJlZW4gZGVwcmVjYXRlZCBhbmQgc3VwcG9ydCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9oamFsbWVycy9hbmd1bGFyLWdlbmVyaWMtdGFibGUvaXNzdWVzLzM0J1xuXHRcdCk7XG5cdFx0dGhpcy5fZ3RSb3dDb21wb25lbnQgPSB2YWx1ZTtcblx0fVxuXG5cdHB1YmxpYyBjb2x1bW5XaWR0aDogT2JqZWN0ID0ge307XG5cdHB1YmxpYyBjb25maWdPYmplY3Q6IEd0Q29uZmlnPFI+O1xuXHRwdWJsaWMgc29ydE9yZGVyOiBBcnJheTxhbnk+ID0gW107XG5cdHB1YmxpYyBtZXRhSW5mbzogeyBbZ3RSb3dJZDogc3RyaW5nXTogR3RSb3dNZXRhIH0gPSB7fTtcblx0cHVibGljIHNlbGVjdGVkUm93czogQXJyYXk8R3RSb3c+ID0gW107XG5cdHB1YmxpYyBvcGVuUm93czogQXJyYXk8R3RSb3c+ID0gW107XG5cdHByaXZhdGUgX2d0U2V0dGluZ3M6IEd0Q29uZmlnU2V0dGluZ1tdID0gW107XG5cdHByaXZhdGUgX2d0RmllbGRzOiBHdENvbmZpZ0ZpZWxkPFIsIGFueT5bXSA9IFtdO1xuXHRwcml2YXRlIF9ndERhdGE6IEFycmF5PGFueT47XG5cdHByaXZhdGUgX2d0VG90YWxzOiBhbnk7XG5cdHByaXZhdGUgX2d0Um93Q29tcG9uZW50OiBUeXBlPEM+O1xuXHRwdWJsaWMgZXhwYW5kZWRSb3c6IHtcblx0XHRjb21wb25lbnQ6IFR5cGU8Qz47XG5cdFx0ZGF0YT86IEFycmF5PGFueT47XG5cdH07XG5cdHB1YmxpYyBndERlZmF1bHRUZXh0czogR3RUZXh0cyA9IHtcblx0XHRsb2FkaW5nOiAnTG9hZGluZy4uLicsXG5cdFx0bm9EYXRhOiAnTm8gZGF0YScsXG5cdFx0bm9NYXRjaGluZ0RhdGE6ICdObyBkYXRhIG1hdGNoaW5nIHJlc3VsdHMgZm91bmQnLFxuXHRcdG5vVmlzaWJsZUNvbHVtbnNIZWFkaW5nOiAnTm8gdmlzaWJsZSBjb2x1bW5zJyxcblx0XHRub1Zpc2libGVDb2x1bW5zOiAnUGxlYXNlIHNlbGVjdCBhdCBsZWFzdCBvbmUgY29sdW1uIHRvIGJlIHZpc2libGUuJyxcblx0XHR0YWJsZUluZm86XG5cdFx0XHQnU2hvd2luZyAjcmVjb3JkRnJvbSB0byAjcmVjb3JkVG8gb2YgI3JlY29yZHNBZnRlclNlYXJjaCBlbnRyaWVzLicsXG5cdFx0dGFibGVJbmZvQWZ0ZXJTZWFyY2g6XG5cdFx0XHQnU2hvd2luZyAgI3JlY29yZEZyb20gdG8gI3JlY29yZFRvIG9mICNyZWNvcmRzQWZ0ZXJTZWFyY2ggZW50cmllcyAoZmlsdGVyZWQgZnJvbSBhIHRvdGFsIG9mICNyZWNvcmRzQWxsIGVudHJpZXMpLicsXG5cdFx0Y3N2RG93bmxvYWQ6ICdkb3dubG9hZCcsXG5cdFx0c29ydExhYmVsOiAnU29ydDonLFxuXHRcdHBhZ2luYXRlTmV4dDogJ05leHQgcGFnZScsXG5cdFx0cGFnaW5hdGVQcmV2aW91czogJ1ByZXZpb3VzIHBhZ2UnLFxuXHRcdGlubGluZUVkaXRFZGl0ZWQ6ICdQcmVzcyBlbnRlciB0byBzYXZlJ1xuXHR9O1xuXHRASW5wdXQoKSBndFRleHRzOiBHdFRleHRzID0gdGhpcy5ndERlZmF1bHRUZXh0cztcblx0QElucHV0KCkgZ3RDbGFzc2VzOiBzdHJpbmc7XG5cdEBPdXRwdXQoKSBndEV2ZW50OiBFdmVudEVtaXR0ZXI8R3RFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cdHB1YmxpYyBndERlZmF1bHRPcHRpb25zOiBHdE9wdGlvbnMgPSB7XG5cdFx0Y3N2RGVsaW1pdGVyOiAnOycsXG5cdFx0c3RhY2s6IGZhbHNlLFxuXHRcdGxhenlMb2FkOiBmYWxzZSxcblx0XHRjYWNoZTogZmFsc2UsXG5cdFx0ZGVib3VuY2VUaW1lOiAyMDAsXG5cdFx0aGlnaGxpZ2h0U2VhcmNoOiBmYWxzZSxcblx0XHRyb3dTZWxlY3Rpb246IGZhbHNlLFxuXHRcdHJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGU6IHRydWUsXG5cdFx0cm93RXhwYW5kQWxsb3dNdWx0aXBsZTogdHJ1ZSxcblx0XHRudW1iZXJPZlJvd3M6IDEwLFxuXHRcdHJlcG9ydENvbHVtbldpZHRoOiBmYWxzZSxcblx0XHRhbGxvd1Vuc29ydGVkOiB0cnVlLFxuXHRcdG11dGF0ZURhdGE6IHRydWVcblx0fTtcblx0cHJpdmF0ZSBfZ3RPcHRpb25zOiBHdE9wdGlvbnMgPSB0aGlzLmd0RGVmYXVsdE9wdGlvbnM7XG5cdHB1YmxpYyBzdG9yZTogQXJyYXk8YW55PiA9IFtdO1xuXHRwdWJsaWMgbG9hZGluZyA9IHRydWU7XG5cdHByaXZhdGUgZGVib3VuY2VUaW1lcjogdm9pZCA9IG51bGw7XG5cdHB1YmxpYyBsb2FkaW5nUHJvcGVydHk6IHN0cmluZztcblx0cHVibGljIGxhenlBbGxTZWxlY3RlZCA9IGZhbHNlO1xuXG5cdEBJbnB1dCgpXG5cdGd0SW5mbzogR3RJbmZvcm1hdGlvbiA9IHtcblx0XHRwYWdlQ3VycmVudDogMSxcblx0XHRwYWdlVG90YWw6IDAsXG5cdFx0cmVjb3JkRnJvbTogMCxcblx0XHRyZWNvcmRUbzogMCxcblx0XHRyZWNvcmRMZW5ndGg6IHRoaXMuZ3RPcHRpb25zLm51bWJlck9mUm93cyxcblx0XHRyZWNvcmRzQWxsOiAwLFxuXHRcdHJlY29yZHNBZnRlckZpbHRlcjogMCxcblx0XHRyZWNvcmRzQWZ0ZXJTZWFyY2g6IDBcblx0fTtcblxuXHRwdWJsaWMgcmVmcmVzaFBpcGUgPSBmYWxzZTtcblx0cHVibGljIHJlZnJlc2hUb3RhbHMgPSBmYWxzZTtcblx0cHVibGljIHJlZnJlc2hTb3J0aW5nID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoRmlsdGVyID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoUGFnZUFycmF5ID0gZmFsc2U7XG5cdHByaXZhdGUgZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyOiBGdW5jdGlvbjtcblx0cHVibGljIGVkaXRlZFJvd3M6IHtcblx0XHRba2V5OiBzdHJpbmddOiB7XG5cdFx0XHRjaGFuZ2VzOiB7IFtrZXk6IHN0cmluZ106IEd0UmVuZGVyRmllbGQ8R3RSb3csIGFueT4gfTtcblx0XHRcdHJvdzogR3RSb3c7XG5cdFx0fTtcblx0fSA9IHt9O1xuXG5cdHB1YmxpYyBkYXRhOiB7IGV4cG9ydERhdGE6IEFycmF5PGFueT4gfSA9IHsgZXhwb3J0RGF0YTogW10gfTsgLy8gU3RvcmUgZmlsdGVyZWQgZGF0YSBmb3IgZXhwb3J0XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLCBwcml2YXRlIGd0TWV0YVBpcGU6IEd0TWV0YVBpcGUpIHtcblx0XHR0aGlzLmd0RXZlbnQuc3Vic2NyaWJlKCgkZXZlbnQ6IEd0RXZlbnQpID0+IHtcblx0XHRcdGlmICgkZXZlbnQubmFtZSA9PT0gJ2d0LWluZm8nKSB7XG5cdFx0XHRcdHRoaXMudXBkYXRlUmVjb3JkUmFuZ2UoKTtcblx0XHRcdH1cblx0XHRcdGlmICgkZXZlbnQubmFtZSA9PT0gJ2d0LXJvdy11cGRhdGVkJykge1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVRvdGFscygpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNvcnQgdGFibGUgYnkgb2JqZWN0IGtleS5cblx0ICogQHBhcmFtIG9iamVjdEtleSAtIG5hbWUgb2Yga2V5IHRvIHNvcnQgb24uXG5cdCAqIEBwYXJhbSBldmVudCAtIHN1Y2ggYXMga2V5IHByZXNzIGR1cmluZyBzb3J0aW5nLlxuXHQgKi9cblx0cHVibGljIGd0U29ydCA9IGZ1bmN0aW9uKG9iamVjdEtleTogc3RyaW5nLCBldmVudDogYW55KSB7XG5cdFx0dGhpcy5pbmxpbmVFZGl0Q2FuY2VsKCk7IC8vIGNhbmNlbCBpbmxpbmUgZWRpdGluZ1xuXG5cdFx0Ly8gbG9vcCB0aHJvdWdoIGN1cnJlbnQgc2V0dGluZ3Ncblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSA9PT0gb2JqZWN0S2V5KSB7XG5cdFx0XHRcdC8vIGNoZWNrIGlmIHNvcnRpbmcgaXMgZGlzYWJsZWQuLi5cblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCAmJlxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydC5pbmRleE9mKCdkaXNhYmxlJykgIT09IC0xXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdC8vIC4uLmlmIHNvLCBleGl0IGZ1bmN0aW9uIHdpdGhvdXQgYXBwbHlpbmcgYW55IHNvcnRpbmdcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRcdFx0LyogY2hlY2sgaWYgc29ydGluZyBpcyB1bmRlZmluZWQuLi4gKi8gdHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV1cblx0XHRcdFx0XHRcdC5zb3J0ID09PSAndW5kZWZpbmVkJ1xuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHQvLyAuLi5pcyBzbywgc2V0IHNvcnRpbmcgcHJvcGVydHkgdG8gZW5hYmxlXG5cdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2VuYWJsZSc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBjaGVjayBsZW5ndGhcblx0XHRjb25zdCBjdHJsS2V5ID0gZXZlbnQubWV0YUtleSB8fCBldmVudC5jdHJsS2V5O1xuXHRcdGNvbnN0IHNvcnQgPSB0aGlzLnNvcnRPcmRlci5zbGljZSgwKTtcblxuXHRcdGxldCBtYXRjaCA9IC0xO1xuXHRcdGxldCBtYXRjaERlc2MgPSAtMTtcblx0XHRsZXQgcG9zID0gLTE7XG5cblx0XHQvLyBjaGVjayBpZiBwcm9wZXJ0eSBhbHJlYWR5IGV4aXRzXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzb3J0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBoaXQgPSBzb3J0W2ldLmluZGV4T2Yob2JqZWN0S2V5KTtcblx0XHRcdGlmIChoaXQgIT09IC0xKSB7XG5cdFx0XHRcdG1hdGNoID0gdGhpcy5zb3J0T3JkZXIuaW5kZXhPZihvYmplY3RLZXkpO1xuXHRcdFx0XHRtYXRjaERlc2MgPVxuXHRcdFx0XHRcdG1hdGNoID09PSAtMSA/IHRoaXMuc29ydE9yZGVyLmluZGV4T2YoJy0nICsgb2JqZWN0S2V5KSA6IG1hdGNoO1xuXHRcdFx0XHRwb3MgPSBNYXRoLm1heChtYXRjaCwgbWF0Y2hEZXNjKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBpZiBjdHJsIGtleSBvciBtZXRhIGtleSBpcyBwcmVzcyB0b2dldGhlciB3aXRoIHNvcnQuLi5cblx0XHRpZiAoY3RybEtleSkge1xuXHRcdFx0aWYgKHRoaXMuc29ydE9yZGVyW3RoaXMuc29ydE9yZGVyLmxlbmd0aCAtIDFdID09PSAnJCRndEluaXRpYWxSb3dJbmRleCcpIHtcblx0XHRcdFx0dGhpcy5zb3J0T3JkZXIucG9wKCk7XG5cdFx0XHR9XG5cdFx0XHRzd2l0Y2ggKHBvcykge1xuXHRcdFx0XHQvLyAuLi5hbmQgcHJvcGVydHkgaXMgbm90IHNvcnRlZCBiZWZvcmUuLi5cblx0XHRcdFx0Y2FzZSAtMTpcblx0XHRcdFx0XHQvLyAuLi5hZGQgcHJvcGVydHkgdG8gc29ydGluZ1xuXHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyLnB1c2gob2JqZWN0S2V5KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHQvLyAuLi5hbmQgcHJvcGVydHkgaXMgc29ydGVkIGJlZm9yZS4uLlxuXHRcdFx0XHRcdGlmIChtYXRjaCAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSBmcm9tIGFzYyB0byBkZXNjIGlmIHNvcnRlZCBhc2Ncblx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyW3Bvc10gPSAnLScgKyBvYmplY3RLZXk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLnNvcnRPcmRlci5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5yZW1vdmUgc29ydGluZyBpZiBzb3J0ZWQgZGVzY1xuXHRcdFx0XHRcdFx0aWYgKGN0cmxLZXkpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5zb3J0T3JkZXJbcG9zXSA9IG9iamVjdEtleTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyLnNwbGljZShwb3MsIDEpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5zb3J0T3JkZXIubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5zZXQgc29ydGluZyB0byBhc2MgaWYgb25seSBzb3J0ZWQgcHJvcGVydHlcblx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyW3Bvc10gPSBvYmplY3RLZXk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvKiBpZiBjdHJsIGtleSBvciBtZXRhIGtleSBpcyBub3QgcHJlc3MgdG9nZXRoZXIgd2l0aCBzb3J0Li4uICovXG5cdFx0XHRzd2l0Y2ggKHBvcykge1xuXHRcdFx0XHQvLyAuLi5hbmQgcHJvcGVydHkgaXMgbm90IHNvcnRlZCBiZWZvcmUuLi5cblx0XHRcdFx0Y2FzZSAtMTpcblx0XHRcdFx0XHQvLyAuLi5zb3J0IGJ5IHByb3BlcnR5XG5cdFx0XHRcdFx0dGhpcy5zb3J0T3JkZXIgPSBbb2JqZWN0S2V5XTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHQvLyAuLi5jaGFuZ2UgZnJvbSBkZXNjIHRvIGFzYyBhbmQgdmlzZSB2ZXJzYVxuXHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyID1cblx0XHRcdFx0XHRcdG1hdGNoICE9PSAtMVxuXHRcdFx0XHRcdFx0XHQ/IFsnLScgKyBvYmplY3RLZXldXG5cdFx0XHRcdFx0XHRcdDogY3RybEtleSB8fCAhdGhpcy5ndE9wdGlvbnMuYWxsb3dVbnNvcnRlZFxuXHRcdFx0XHRcdFx0XHRcdD8gW29iamVjdEtleV1cblx0XHRcdFx0XHRcdFx0XHQ6IFtdO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHVwZGF0ZSBzZXR0aW5ncyBvYmplY3Qgd2l0aCBuZXcgc29ydGluZyBpbmZvcm1hdGlvblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHRoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5ID09PSBvYmplY3RLZXkpIHtcblx0XHRcdFx0c3dpdGNoICh0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQpIHtcblx0XHRcdFx0XHQvLyBpZiBzb3J0ZWQgYXNjLi4uXG5cdFx0XHRcdFx0Y2FzZSAnYXNjJzpcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSB0byBkZXNjXG5cdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPSAnZGVzYyc7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHQvLyBpZiBzb3J0ZWQgZGVzYy4uLlxuXHRcdFx0XHRcdGNhc2UgJ2Rlc2MnOlxuXHRcdFx0XHRcdFx0Ly8gLi4uY2hhbmdlIHRvIGFzYyBpZiBpdCdzIHRoZSBvbmx5IHNvcnRlZCBwcm9wZXJ0eSBvdGhlcndpc2UgcmVtb3ZlIHNvcnRpbmdcblx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9XG5cdFx0XHRcdFx0XHRcdCh0aGlzLnNvcnRPcmRlci5sZW5ndGggPT09IDEgJiYgc29ydC5sZW5ndGggPCAyKSB8fFxuXHRcdFx0XHRcdFx0XHRjdHJsS2V5IHx8XG5cdFx0XHRcdFx0XHRcdCF0aGlzLmd0T3B0aW9ucy5hbGxvd1Vuc29ydGVkXG5cdFx0XHRcdFx0XHRcdFx0PyAnYXNjJ1xuXHRcdFx0XHRcdFx0XHRcdDogJ2VuYWJsZSc7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHQvLyBpZiBzb3J0aW5nIGVuYWJsZWQuLi5cblx0XHRcdFx0XHRjYXNlICdlbmFibGUnOlxuXHRcdFx0XHRcdFx0Ly8gLi4uY2hhbmdlIHRvIGFzY1xuXHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2FzYyc7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnRPcmRlciA9XG5cdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID09PSAnZW5hYmxlJ1xuXHRcdFx0XHRcdFx0PyB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aCAtIDFcblx0XHRcdFx0XHRcdDogdGhpcy5zb3J0T3JkZXIuaW5kZXhPZihvYmplY3RLZXkpID09PSAtMVxuXHRcdFx0XHRcdFx0XHQ/IHRoaXMuc29ydE9yZGVyLmluZGV4T2YoJy0nICsgb2JqZWN0S2V5KVxuXHRcdFx0XHRcdFx0XHQ6IHRoaXMuc29ydE9yZGVyLmluZGV4T2Yob2JqZWN0S2V5KTtcblx0XHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCAmJlxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQuaW5kZXhPZignZGlzYWJsZScpID09PSAtMSAmJlxuXHRcdFx0XHR0aGlzLnNvcnRPcmRlci5pbmRleE9mKHRoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5KSA9PT0gLTEgJiZcblx0XHRcdFx0dGhpcy5zb3J0T3JkZXIuaW5kZXhPZignLScgKyB0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSkgPT09IC0xXG5cdFx0XHQpIHtcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2VuYWJsZSc7XG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydE9yZGVyID0gdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHJlZnJlc2ggc29ydGluZyBwaXBlXG5cdFx0dGhpcy5yZWZyZXNoU29ydGluZyA9ICF0aGlzLnJlZnJlc2hTb3J0aW5nO1xuXHRcdHRoaXMucmVmcmVzaFBhZ2VBcnJheSA9ICF0aGlzLnJlZnJlc2hQYWdlQXJyYXk7XG5cblx0XHQvLyBzb3J0IGJ5IGluaXRpYWwgc29ydCBvcmRlciBhcyBsYXN0IHJlc29ydFxuXHRcdHRoaXMuc29ydE9yZGVyLnB1c2goJyQkZ3RJbml0aWFsUm93SW5kZXgnKTtcblxuXHRcdC8vIGVtaXQgc29ydCBldmVudFxuXHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdG5hbWU6ICdndC1zb3J0aW5nLWFwcGxpZWQnLFxuXHRcdFx0dmFsdWU6IHRoaXMuc29ydE9yZGVyXG5cdFx0fSk7XG5cdH07XG5cblx0LyoqXG5cdCAqIENoYW5nZSBudW1iZXIgb2Ygcm93cyB0byBiZSBkaXNwbGF5ZWQuXG5cdCAqIEBwYXJhbSByb3dMZW5ndGggLSB0b3RhbCBudW1iZXIgb2Ygcm93cy5cblx0ICogQHBhcmFtIHJlc2V0IC0gc2hvdWxkIHBhZ2UgYmUgcmVzZXQgdG8gZmlyc3QgcGFnZS5cblx0ICovXG5cdHB1YmxpYyBjaGFuZ2VSb3dMZW5ndGggPSBmdW5jdGlvbihyb3dMZW5ndGg6IGFueSwgcmVzZXQ/OiBib29sZWFuKSB7XG5cdFx0bGV0IGxlbmd0aFZhbHVlID0gaXNOYU4ocGFyc2VJbnQocm93TGVuZ3RoLCAxMCkpXG5cdFx0XHQ/IDBcblx0XHRcdDogcGFyc2VJbnQocm93TGVuZ3RoLCAxMCk7XG5cdFx0bGV0IG5ld1Bvc2l0aW9uID0gMTtcblxuXHRcdGlmICghbGVuZ3RoVmFsdWUgJiYgdGhpcy5ndERhdGEpIHtcblx0XHRcdGxlbmd0aFZhbHVlID0gdGhpcy5ndERhdGEubGVuZ3RoO1xuXHRcdH1cblxuXHRcdC8vIGlmIHJlc2V0IGlzIG5vdCB0cnVlIGFuZCB3ZSdyZSBub3QgbGF6eSBsb2FkaW5nIGRhdGEuLi5cblx0XHRpZiAocmVzZXQgIT09IHRydWUgJiYgdGhpcy5fZ3RPcHRpb25zLmxhenlMb2FkICE9PSB0cnVlKSB7XG5cdFx0XHQvLyAuLi5nZXQgY3VycmVudCBwb3NpdGlvbiBpbiByZWNvcmQgc2V0XG5cdFx0XHRjb25zdCBjdXJyZW50UmVjb3JkID1cblx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoICogKHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMSk7XG5cdFx0XHRjb25zdCBjdXJyZW50UG9zaXRpb24gPVxuXHRcdFx0XHR0aGlzLl9ndERhdGEuaW5kZXhPZih0aGlzLl9ndERhdGFbY3VycmVudFJlY29yZF0pICsgMTtcblxuXHRcdFx0Ly8gLi4uZ2V0IG5ldyBwb3NpdGlvblxuXHRcdFx0bmV3UG9zaXRpb24gPSBNYXRoLmNlaWwoY3VycmVudFBvc2l0aW9uIC8gbGVuZ3RoVmFsdWUpO1xuXHRcdH1cblxuXHRcdC8vIGNoYW5nZSByb3cgbGVuZ3RoXG5cdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoID0gbGVuZ3RoVmFsdWU7XG5cblx0XHQvLyBnbyB0byBuZXcgcG9zaXRpb25cblx0XHR0aGlzLmd0SW5mby5wYWdlQ3VycmVudCA9IG5ld1Bvc2l0aW9uO1xuXG5cdFx0Ly8gaWYgbGF6eSBsb2FkaW5nIGRhdGEuLi5cblx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLmxhenlMb2FkKSB7XG5cdFx0XHQvLyAuLi5yZXBsYWNlIGRhdGEgd2l0aCBwbGFjZSBob2xkZXJzIGZvciBuZXcgZGF0YVxuXHRcdFx0dGhpcy5fZ3REYXRhWzBdID0gdGhpcy5sb2FkaW5nQ29udGVudChsZW5ndGhWYWx1ZSk7XG5cblx0XHRcdC8vIC4uLmVtcHR5IGN1cnJlbnQgc3RvcmVcblx0XHRcdHRoaXMuc3RvcmUgPSBbXTtcblx0XHR9XG5cblx0XHQvLyB0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtcm93LWxlbmd0aC1jaGFuZ2VkJyxcblx0XHRcdHZhbHVlOiBsZW5ndGhWYWx1ZVxuXHRcdH0pO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBGb3JjZSBhIHJlZHJhdyBvZiB0YWJsZSByb3dzLlxuXHQgKiBBcyB0aGUgdGFibGUgdXNlcyBwdXJlIHBpcGVzLCB3ZSBuZWVkIHRvIGZvcmNlIGEgcmVkcmF3IGlmIGFuIG9iamVjdCBpbiB0aGUgYXJyYXkgaXMgY2hhbmdlZCB0byBzZWUgdGhlIGNoYW5nZXMuXG5cdCAqL1xuXHRwdWJsaWMgcmVkcmF3ID0gZnVuY3Rpb24oJGV2ZW50PzogYW55KSB7XG5cdFx0dGhpcy5yZWZyZXNoU29ydGluZyA9ICF0aGlzLnJlZnJlc2hTb3J0aW5nO1xuXHRcdHRoaXMucmVmcmVzaFBhZ2VBcnJheSA9ICF0aGlzLnJlZnJlc2hQYWdlQXJyYXk7XG5cdFx0dGhpcy5yZWZyZXNoUGlwZSA9ICF0aGlzLnJlZnJlc2hQaXBlO1xuXHR9O1xuXG5cdC8qKiBVcGRhdGUgcmVjb3JkIHJhbmdlLiAqL1xuXHRwcml2YXRlIHVwZGF0ZVJlY29yZFJhbmdlKCkge1xuXHRcdHRoaXMuZ3RJbmZvLnJlY29yZEZyb20gPVxuXHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoID09PSAwXG5cdFx0XHRcdD8gMFxuXHRcdFx0XHQ6ICh0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDEpICogdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoICsgMTtcblx0XHR0aGlzLmd0SW5mby5yZWNvcmRUbyA9XG5cdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2ggPFxuXHRcdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgKiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdFx0PyB0aGlzLmd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2hcblx0XHRcdFx0OiB0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAqIHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aDtcblx0fVxuXG5cdC8qKiBVcGRhdGUgdG90YWxzLiAqL1xuXHRwcml2YXRlIHVwZGF0ZVRvdGFscygpIHtcblx0XHR0aGlzLnJlZnJlc2hUb3RhbHMgPSAhdGhpcy5yZWZyZXNoVG90YWxzO1xuXHR9XG5cblx0LyoqIEdvIHRvIG5leHQgcGFnZS4gKi9cblx0cHVibGljIG5leHRQYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgcGFnZSA9XG5cdFx0XHR0aGlzLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gdGhpcy5ndEluZm8ucGFnZVRvdGFsXG5cdFx0XHRcdD8gdGhpcy5ndEluZm8ucGFnZVRvdGFsXG5cdFx0XHRcdDogdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgKyAxO1xuXHRcdHRoaXMuZ29Ub1BhZ2UocGFnZSk7XG5cdH07XG5cblx0LyoqIEdvIHRvIHByZXZpb3VzIHBhZ2UuICovXG5cdHB1YmxpYyBwcmV2aW91c1BhZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBwYWdlID1cblx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ID09PSAxID8gMSA6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMTtcblx0XHR0aGlzLmdvVG9QYWdlKHBhZ2UpO1xuXHR9O1xuXG5cdC8qKiBSZXF1ZXN0IG1vcmUgZGF0YSAodXNlZCB3aGVuIGxhenkgbG9hZGluZykgKi9cblx0cHJpdmF0ZSBnZXREYXRhID0gZnVuY3Rpb24oKSB7XG5cdFx0Ly8gLi4uZW1pdCBldmVudCByZXF1ZXN0aW5nIGZvciBtb3JlIGRhdGFcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtcGFnZS1jaGFuZ2VkLWxhenknLFxuXHRcdFx0dmFsdWU6IHtcblx0XHRcdFx0cGFnZUN1cnJlbnQ6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50LFxuXHRcdFx0XHRyZWNvcmRMZW5ndGg6IHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBHbyB0byBzcGVjaWZpYyBwYWdlLlxuXHQgKiBAcGFyYW0gcGFnZSAtIHBhZ2UgbnVtYmVyLlxuXHQgKi9cblx0cHVibGljIGdvVG9QYWdlID0gZnVuY3Rpb24ocGFnZTogbnVtYmVyKSB7XG5cdFx0Y29uc3QgcHJldmlvdXNQYWdlID0gdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQ7XG5cdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgPSBwYWdlO1xuXHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbCgpOyAvLyBjYW5jZWwgaW5saW5lIGVkaXRcblxuXHRcdC8vIGlmIGxhenkgbG9hZGluZyBhbmQgaWYgcGFnZSBjb250YWlucyBubyByZWNvcmRzLi4uXG5cdFx0aWYgKHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCkge1xuXHRcdFx0Ly8gLi4uaWYgZGF0YSBmb3IgY3VycmVudCBwYWdlIGNvbnRhaW5zIG5vIGVudHJpZXMuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dGhpcy5fZ3RPcHRpb25zLmNhY2hlID09PSBmYWxzZSB8fFxuXHRcdFx0XHR0aGlzLl9ndERhdGFbdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxXS5sZW5ndGggPT09IDBcblx0XHRcdCkge1xuXHRcdFx0XHQvLyAuLi5jcmVhdGUgdGVtcG9yYXJ5IGNvbnRlbnQgd2hpbGUgd2FpdGluZyBmb3IgZGF0YVxuXHRcdFx0XHR0aGlzLl9ndERhdGFbdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxXSA9IHRoaXMubG9hZGluZ0NvbnRlbnQoXG5cdFx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRoaXMubG9hZGluZyA9IHRydWU7IC8vIGxvYWRpbmcgdHJ1ZVxuXHRcdFx0fVxuXHRcdFx0Ly8gLi4uaWYgZmlyc3QgZW50cnkgaW4gY3VycmVudCBwYWdlIGVxdWFscyBvdXIgbG9hZGluZyBwbGFjZWhvbGRlci4uLlxuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLl9ndERhdGFbdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxXVswXVt0aGlzLmxvYWRpbmdQcm9wZXJ0eV0gPT09XG5cdFx0XHRcdHRoaXMuZ3RUZXh0cy5sb2FkaW5nXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gLi4uZ2V0IGRhdGFcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRoaXMuZGVib3VuY2VUaW1lcik7XG5cdFx0XHRcdHRoaXMuZGVib3VuY2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMuZ2V0RGF0YSgpO1xuXHRcdFx0XHR9LCB0aGlzLl9ndE9wdGlvbnMuZGVib3VuY2VUaW1lKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyB0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cblx0XHQvLyAuLi5lbWl0IHBhZ2UgY2hhbmdlIGV2ZW50XG5cdFx0aWYgKHByZXZpb3VzUGFnZSAhPT0gcGFnZSkge1xuXHRcdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0XHRuYW1lOiAnZ3QtcGFnZS1jaGFuZ2VkJyxcblx0XHRcdFx0dmFsdWU6IHtcblx0XHRcdFx0XHRwYWdlQ3VycmVudDogdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQsXG5cdFx0XHRcdFx0cGFnZVByZXZpb3VzOiBwcmV2aW91c1BhZ2UsXG5cdFx0XHRcdFx0cmVjb3JkTGVuZ3RoOiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qKlxuXHQgKiBHZXQgbWV0YSBkYXRhIGZvciByb3cuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0Um93U3RhdGUocm93OiBSKTogR3RSb3dNZXRhIHtcblx0XHRyZXR1cm4gdHlwZW9mIHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gPT09ICd1bmRlZmluZWQnXG5cdFx0XHQ/IG51bGxcblx0XHRcdDogdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHBhbmQgYWxsIHJvd3MuXG5cdCAqIEBwYXJhbSBleHBhbmRlZFJvdyAtIGNvbXBvbmVudCB0byByZW5kZXIgd2hlbiByb3dzIGFyZSBleHBhbmRlZC5cblx0ICovXG5cdHB1YmxpYyBleHBhbmRBbGxSb3dzKGV4cGFuZGVkUm93OiB7IGNvbXBvbmVudDogVHlwZTxDPjsgZGF0YT86IGFueSB9KTogdm9pZCB7XG5cdFx0dGhpcy5leHBhbmRlZFJvdyA9IGV4cGFuZGVkUm93O1xuXHRcdHRoaXMuX3RvZ2dsZUFsbFJvd1Byb3BlcnR5KCdpc09wZW4nLCB0cnVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb2xsYXBzZSBhbGwgcm93cy5cblx0ICovXG5cdHB1YmxpYyBjb2xsYXBzZUFsbFJvd3MoKTogdm9pZCB7XG5cdFx0dGhpcy5fdG9nZ2xlQWxsUm93UHJvcGVydHkoJ2lzT3BlbicsIGZhbHNlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWxlY3QgYWxsIHJvd3MuXG5cdCAqL1xuXHRwdWJsaWMgc2VsZWN0QWxsUm93cygpOiB2b2lkIHtcblx0XHR0aGlzLl90b2dnbGVBbGxSb3dQcm9wZXJ0eSgnaXNTZWxlY3RlZCcsIHRydWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlc2VsZWN0IGFsbCByb3dzLlxuXHQgKi9cblx0cHVibGljIGRlc2VsZWN0QWxsUm93cygpOiB2b2lkIHtcblx0XHR0aGlzLl90b2dnbGVBbGxSb3dQcm9wZXJ0eSgnaXNTZWxlY3RlZCcsIGZhbHNlKTtcblx0fVxuXHQvKipcblx0ICogVG9nZ2xlIGFsbCByb3dzLlxuXHQgKi9cblx0cHVibGljIHRvZ2dsZUFsbFJvd3MoKTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCkge1xuXHRcdFx0aWYgKCF0aGlzLmxhenlBbGxTZWxlY3RlZCB8fCB0aGlzLnNlbGVjdGVkUm93cy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0dGhpcy5zZWxlY3RBbGxSb3dzKCk7XG5cdFx0XHRcdHRoaXMubGF6eUFsbFNlbGVjdGVkID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZGVzZWxlY3RBbGxSb3dzKCk7XG5cdFx0XHRcdHRoaXMubGF6eUFsbFNlbGVjdGVkID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICh0aGlzLnNlbGVjdGVkUm93cy5sZW5ndGggIT09IHRoaXMuZ3REYXRhLmxlbmd0aCkge1xuXHRcdFx0XHR0aGlzLnNlbGVjdEFsbFJvd3MoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZGVzZWxlY3RBbGxSb3dzKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSByb3cgY29sbGFwc2VkIHN0YXRlIGllLiBleHBhbmRlZC9vcGVuIG9yIGNvbGxhcHNlZC9jbG9zZWQuXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0IHRoYXQgc2hvdWxkIGJlIGV4cGFuZGVkL2NvbGxhcHNlZC5cblx0ICogQHBhcmFtIGV4cGFuZGVkUm93IC0gY29tcG9uZW50IHRvIHJlbmRlciB3aGVuIHJvdyBpcyBleHBhbmRlZC5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVDb2xsYXBzZShcblx0XHRyb3c6IEd0Um93LFxuXHRcdGV4cGFuZGVkUm93PzogeyBjb21wb25lbnQ6IFR5cGU8Qz47IGRhdGE/OiBhbnkgfVxuXHQpIHtcblx0XHRpZiAoZXhwYW5kZWRSb3cpIHtcblx0XHRcdHRoaXMuZXhwYW5kZWRSb3cgPSBleHBhbmRlZFJvdztcblx0XHR9XG5cdFx0dGhpcy5fdG9nZ2xlUm93UHJvcGVydHkocm93LCAnaXNPcGVuJyk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIHJvdyBzZWxlY3RlZCBzdGF0ZSBpZS4gc2VsZWN0ZWQgb3Igbm90LlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdCB0aGF0IHNob3VsZCBiZSBzZWxlY3RlZC9kZXNlbGVjdGVkLlxuXHQgKi9cblx0cHVibGljIHRvZ2dsZVNlbGVjdChyb3c6IEd0Um93KSB7XG5cdFx0dGhpcy5fdG9nZ2xlUm93UHJvcGVydHkocm93LCAnaXNTZWxlY3RlZCcpO1xuXHR9XG5cblx0cHVibGljIHJvd0NsaWNrKHJvdzogR3RSb3csICRldmVudDogTW91c2VFdmVudCkge1xuXHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdG5hbWU6ICdndC1yb3ctY2xpY2tlZCcsXG5cdFx0XHR2YWx1ZTogeyByb3c6IHJvdywgZXZlbnQ6ICRldmVudCB9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlIHJvdyBkYXRhLlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdCB0aGF0IGhhcyBiZWVuIGVkaXRlZC5cblx0ICogQHBhcmFtIG9sZFZhbHVlIC0gcm93IG9iamVjdCBiZWZvcmUgZWRpdC5cblx0ICovXG5cdHB1YmxpYyB1cGRhdGVSb3cocm93OiBHdFJvdywgb2xkVmFsdWU6IEd0Um93KSB7XG5cdFx0dGhpcy5fdG9nZ2xlUm93UHJvcGVydHkocm93LCAnaXNVcGRhdGVkJywgb2xkVmFsdWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIHJlbW92ZXMgYSByb3cgZnJvbSB0aGUgdGFibGVcblx0ICogQHBhcmFtIHJvdyAtIHRoZSByb3cgb2JqZWN0IHRvIHJlbW92ZVxuXHQgKi9cblx0cHVibGljIHJlbW92ZVJvdyhyb3c6IEd0Um93KSB7XG5cdFx0aWYgKHRoaXMuaXNSb3dTZWxlY3RlZChyb3cpKSB7XG5cdFx0XHR0aGlzLnRvZ2dsZVNlbGVjdChyb3cpO1xuXHRcdH1cblx0XHRjb25zdCBpbmRleCA9IHRoaXMuX2d0RGF0YS5pbmRleE9mKHJvdyk7XG5cdFx0dGhpcy5fZ3REYXRhLnNwbGljZShpbmRleCwgMSk7XG5cdH1cblxuXHQvKipcblx0ICogY2hlY2sgaWYgYSByb3cgaXMgc2VsZWN0ZWRcblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3Rcblx0ICovXG5cdHB1YmxpYyBpc1Jvd1NlbGVjdGVkKHJvdzogR3RSb3cpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSAmJiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdLmlzU2VsZWN0ZWRcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSBtZXRhIGluZm8gZm9yIGFsbCByb3dzLCBpZS4gaXNTZWxlY3RlZCwgaXNPcGVuLlxuXHQgKiBAcGFyYW0gYXJyYXkgLSBhcnJheSB0aGF0IGhvbGRzIHJvd3MgdGhhdCBuZWVkIHRvIGJlIHVwZGF0ZWQuXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eSAtIG5hbWUgb2YgcHJvcGVydHkgdGhhdCBzaG91bGQgYmUgY2hhbmdlZC90b2dnbGVkLlxuXHQgKiBAcGFyYW0gYWN0aXZlIC0gc2hvdWxkIHJvd3MgYmUgZXhwYW5kZWQvb3Blbiwgc2VsZWN0ZWQuXG5cdCAqIEBwYXJhbSBleGNlcHRpb24gLSB1cGRhdGUgYWxsIHJvd3MgZXhjZXB0IHRoaXMgb25lLlxuXHQgKi9cblx0cHJpdmF0ZSBfdXBkYXRlTWV0YUluZm8oXG5cdFx0YXJyYXk6IEFycmF5PEd0Um93Pixcblx0XHRwcm9wZXJ0eTogc3RyaW5nLFxuXHRcdGFjdGl2ZTogYm9vbGVhbixcblx0XHRleGNlcHRpb24/OiBHdFJvd1xuXHQpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoIXRoaXMubWV0YUluZm9bYXJyYXlbaV0uJCRndFJvd0lkXSkge1xuXHRcdFx0XHR0aGlzLm1ldGFJbmZvW2FycmF5W2ldLiQkZ3RSb3dJZF0gPSB7fTtcblx0XHRcdH1cblx0XHRcdGlmIChleGNlcHRpb24gJiYgYXJyYXlbaV0uJCRndFJvd0lkID09PSBleGNlcHRpb24uJCRndFJvd0lkKSB7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLm1ldGFJbmZvW2FycmF5W2ldLiQkZ3RSb3dJZF1bcHJvcGVydHldID0gYWN0aXZlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBQdXNoIHNlbGVjdGVkL2V4cGFuZGVkIGxhenkgbG9hZGVkIHJvd3MgdG8gYXJyYXkgd2l0aCBtZXRhIGRhdGEuXG5cdCAqIEBwYXJhbSB0YXJnZXQgLSBhcnJheSB0byB3aGljaCByb3dzIHNob3VsZCBiZSBhZGRlZC5cblx0ICogQHBhcmFtIHNvdXJjZSAtIGFycmF5IHRoYXQgaG9sZHMgcm93cyB0aGF0IHNob3VsZCBiZSBhZGRlZC5cblx0ICogQHJldHVybnMgYXJyYXkgd2l0aCBhZGRlZCByb3dzLlxuXHQgKi9cblx0cHJpdmF0ZSBfcHVzaExhenlSb3dzKFxuXHRcdHRhcmdldDogQXJyYXk8R3RSb3c+LFxuXHRcdHNvdXJjZTogQXJyYXk8R3RSb3c+XG5cdCk6IEFycmF5PEd0Um93PiB7XG5cdFx0Y29uc3QgVU5JUVVFX1JPV1MgPSB0YXJnZXQubWFwKHJvdyA9PiByb3cuJCRndFJvd0lkKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0Ly8gb25seSBhZGQgaWYgbm90IGFscmVhZHkgaW4gbGlzdFxuXHRcdFx0aWYgKFVOSVFVRV9ST1dTLmluZGV4T2Yoc291cmNlW2ldLiQkZ3RSb3dJZCkgPT09IC0xKSB7XG5cdFx0XHRcdHRhcmdldC5wdXNoKHNvdXJjZVtpXSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0YXJnZXQ7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIG1ldGEgaW5mbyBmb3IgYWxsIHJvd3MsIGllLiBpc1NlbGVjdGVkLCBpc09wZW4uXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eSAtIG5hbWUgb2YgcHJvcGVydHkgdGhhdCBzaG91bGQgYmUgY2hhbmdlZC90b2dnbGVkLlxuXHQgKiBAcGFyYW0gYWN0aXZlIC0gc2hvdWxkIHJvd3MgYmUgZXhwYW5kZWQvb3Blbiwgc2VsZWN0ZWQuXG5cdCAqL1xuXHRwcml2YXRlIF90b2dnbGVBbGxSb3dQcm9wZXJ0eShwcm9wZXJ0eTogc3RyaW5nLCBhY3RpdmU6IGJvb2xlYW4pIHtcblx0XHRsZXQgZXZlbnROYW1lOiBzdHJpbmc7XG5cdFx0bGV0IGV2ZW50VmFsdWU6IGFueTtcblx0XHRzd2l0Y2ggKHByb3BlcnR5KSB7XG5cdFx0XHRjYXNlICdpc09wZW4nOlxuXHRcdFx0XHQvLyBjaGVjayBpZiBtdWx0aXBsZSBleHBhbmRlZCByb3dzIGFyZSBhbGxvd2VkLi4uXG5cdFx0XHRcdGlmICh0aGlzLl9ndE9wdGlvbnMucm93RXhwYW5kQWxsb3dNdWx0aXBsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHQvLyAuLi5pZiBub3QsIGV4aXQgZnVuY3Rpb25cblx0XHRcdFx0XHRjb25zb2xlLmxvZyhcblx0XHRcdFx0XHRcdCdmZWF0dXJlIGRpc2FibGVkOiBlbmFibGUgYnkgc2V0dGluZyBcInJvd0V4cGFuZEFsbG93TXVsdGlwbGUgPSB0cnVlXCInXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGFjdGl2ZSkge1xuXHRcdFx0XHRcdGV2ZW50TmFtZSA9ICdleHBhbmQtYWxsJztcblx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzID0gdGhpcy5fZ3RPcHRpb25zLmxhenlMb2FkXG5cdFx0XHRcdFx0XHQ/IHRoaXMuX3B1c2hMYXp5Um93cyhcblx0XHRcdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzLFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2d0RGF0YVt0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDFdLnNsaWNlKClcblx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0OiB0aGlzLl9ndERhdGEuc2xpY2UoKTtcblx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLm9wZW5Sb3dzLCBwcm9wZXJ0eSwgYWN0aXZlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnY29sbGFwc2UtYWxsJztcblx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLm9wZW5Sb3dzLCBwcm9wZXJ0eSwgYWN0aXZlKTtcblx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0ZXZlbnRWYWx1ZSA9IHtcblx0XHRcdFx0XHRleHBhbmRlZFJvd3M6IHRoaXMub3BlblJvd3MsXG5cdFx0XHRcdFx0Y2hhbmdlZFJvdzogJ2FsbCdcblx0XHRcdFx0fTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdpc1NlbGVjdGVkJzpcblx0XHRcdFx0Ly8gY2hlY2sgaWYgbXVsdGkgcm93IHNlbGVjdGlvbiBpcyBhbGxvd2VkLi4uXG5cdFx0XHRcdGlmICh0aGlzLl9ndE9wdGlvbnMucm93U2VsZWN0aW9uQWxsb3dNdWx0aXBsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHQvLyAuLi5pZiBub3QsIGV4aXQgZnVuY3Rpb25cblx0XHRcdFx0XHRjb25zb2xlLmxvZyhcblx0XHRcdFx0XHRcdCdmZWF0dXJlIGRpc2FibGVkOiBlbmFibGUgYnkgc2V0dGluZyBcInJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGUgPSB0cnVlXCInXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGFjdGl2ZSkge1xuXHRcdFx0XHRcdGV2ZW50TmFtZSA9ICdzZWxlY3QtYWxsJztcblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkUm93cyA9IHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZFxuXHRcdFx0XHRcdFx0PyB0aGlzLl9wdXNoTGF6eVJvd3MoXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MsXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV0uc2xpY2UoKVxuXHRcdFx0XHRcdFx0ICApXG5cdFx0XHRcdFx0XHQ6IHRoaXMuX2d0RGF0YS5zbGljZSgpO1xuXHRcdFx0XHRcdHRoaXMuX3VwZGF0ZU1ldGFJbmZvKHRoaXMuc2VsZWN0ZWRSb3dzLCBwcm9wZXJ0eSwgYWN0aXZlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnZGVzZWxlY3QtYWxsJztcblx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MgPSBbXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRldmVudFZhbHVlID0ge1xuXHRcdFx0XHRcdHNlbGVjdGVkUm93czogdGhpcy5zZWxlY3RlZFJvd3MsXG5cdFx0XHRcdFx0Y2hhbmdlZFJvdzogJ2FsbCdcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXJvdy0nICsgZXZlbnROYW1lLFxuXHRcdFx0dmFsdWU6IGV2ZW50VmFsdWVcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUb2dnbGUgbWV0YSBpbmZvIGZvciByb3csIGllLiBpc1NlbGVjdGVkLCBpc09wZW4uXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0LlxuXHQgKiBAcGFyYW0gcHJvcGVydHkgLSBuYW1lIG9mIHByb3BlcnR5IHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQvdG9nZ2xlZC5cblx0ICogQHBhcmFtIHByb3BlcnR5VmFsdWVzIC0gb3B0aW9uYWwgcHJvcGVydHkgdmFsdWVzIHRoYXQgY2FuIGJlIHBhc3NlZC5cblx0ICovXG5cdHByaXZhdGUgX3RvZ2dsZVJvd1Byb3BlcnR5KFxuXHRcdHJvdzogR3RSb3csXG5cdFx0cHJvcGVydHk6IHN0cmluZyxcblx0XHRwcm9wZXJ0eVZhbHVlcz86IGFueVxuXHQpIHtcblx0XHRsZXQgZXZlbnROYW1lOiBzdHJpbmc7XG5cdFx0bGV0IGV2ZW50VmFsdWU6IGFueTtcblx0XHQvLyBtYWtlIHN1cmUgZ3RSb3dJZCBleGlzdHMgb24gcm93IG9iamVjdFxuXHRcdGlmICh0eXBlb2Ygcm93LiQkZ3RSb3dJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdC8vIGNoZWNrIGlmIG1ldGEgaW5mbyBleGlzdHMgZm9yIHJvd1xuXHRcdFx0aWYgKCF0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdKSB7XG5cdFx0XHRcdC8vIGlmIG5vdCwgYWRkIG9iamVjdCB0byBzdG9yZSBtZXRhIGluZm9cblx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSA9IHt9O1xuXHRcdFx0fVxuXG5cdFx0XHRzd2l0Y2ggKHByb3BlcnR5KSB7XG5cdFx0XHRcdGNhc2UgJ2lzT3Blbic6XG5cdFx0XHRcdFx0Y29uc3Qgb3BlbmVkID0gdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV07XG5cblx0XHRcdFx0XHQvLyBjaGVjayBpZiBtdWx0aXBsZSBleHBhbmRlZCByb3dzIGFyZSBhbGxvd2VkLi4uXG5cdFx0XHRcdFx0aWYgKHRoaXMuX2d0T3B0aW9ucy5yb3dFeHBhbmRBbGxvd011bHRpcGxlID09PSBmYWxzZSkge1xuXHRcdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCBjb2xsYXBzZSBhbGwgcm93cyBleGNlcHQgY3VycmVudCByb3dcblx0XHRcdFx0XHRcdHRoaXMuX3VwZGF0ZU1ldGFJbmZvKHRoaXMub3BlblJvd3MsIHByb3BlcnR5LCBmYWxzZSwgcm93KTtcblx0XHRcdFx0XHRcdHRoaXMub3BlblJvd3MgPSBbXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBjaGVjayBpZiByb3cgaXMgZXhwYW5kZWRcblx0XHRcdFx0XHRpZiAoIW9wZW5lZCkge1xuXHRcdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2V4cGFuZCc7XG5cdFx0XHRcdFx0XHQvLyBhZGQgcm93IHRvIGV4cGFuZGVkIHJvd3Ncblx0XHRcdFx0XHRcdHRoaXMub3BlblJvd3MucHVzaChyb3cpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRldmVudE5hbWUgPSAnY29sbGFwc2UnO1xuXHRcdFx0XHRcdFx0Ly8gbG9vcCB0aHJvdWdoIGV4cGFuZGVkIHJvd3MuLi5cblx0XHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5vcGVuUm93cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0XHQvLyBpZiBleHBhbmRlZCByb3cgZXF1YWxzIHBhc3NlZCByb3cuLi5cblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMub3BlblJvd3NbaV0uJCRndFJvd0lkID09PSByb3cuJCRndFJvd0lkKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gLi4ucmVtb3ZlIHJvdyBmcm9tIGV4cGFuZGVkIHJvd3MuLi5cblx0XHRcdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzLnNwbGljZShpLCAxKTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBleGl0IGxvb3Bcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRldmVudFZhbHVlID0ge1xuXHRcdFx0XHRcdFx0ZXhwYW5kZWRSb3dzOiB0aGlzLm9wZW5Sb3dzLFxuXHRcdFx0XHRcdFx0Y2hhbmdlZFJvdzogcm93XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnaXNTZWxlY3RlZCc6XG5cdFx0XHRcdFx0Y29uc3Qgc2VsZWN0ZWQgPSB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XTtcblxuXHRcdFx0XHRcdC8vIGNoZWNrIGlmIG11bHRpIHJvdyBzZWxlY3Rpb24gaXMgYWxsb3dlZC4uLlxuXHRcdFx0XHRcdGlmICh0aGlzLl9ndE9wdGlvbnMucm93U2VsZWN0aW9uQWxsb3dNdWx0aXBsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdC8vIC4uLmlmIG5vdCwgZGVzZWxlY3QgYWxsIHJvd3MgZXhjZXB0IGN1cnJlbnQgcm93XG5cdFx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgcHJvcGVydHksIGZhbHNlLCByb3cpO1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MgPSBbXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBjaGVjayBpZiByb3cgaXMgc2VsZWN0ZWRcblx0XHRcdFx0XHRpZiAoIXNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRldmVudE5hbWUgPSAnc2VsZWN0Jztcblx0XHRcdFx0XHRcdC8vIGFkZCByb3cgdG8gc2VsZWN0ZWQgcm93c1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MucHVzaChyb3cpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpZiAodGhpcy5ndE9wdGlvbnMubGF6eUxvYWQgJiYgdGhpcy5sYXp5QWxsU2VsZWN0ZWQpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5sYXp5QWxsU2VsZWN0ZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGV2ZW50TmFtZSA9ICdkZXNlbGVjdCc7XG5cdFx0XHRcdFx0XHQvLyBsb29wIHRocm91Z2ggc2VsZWN0ZWQgcm93cy4uLlxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNlbGVjdGVkUm93cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0XHQvLyBpZiBzZWxlY3RlZCByb3cgZXF1YWxzIHBhc3NlZCByb3cuLi5cblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMuc2VsZWN0ZWRSb3dzW2ldLiQkZ3RSb3dJZCA9PT0gcm93LiQkZ3RSb3dJZCkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLnJlbW92ZSByb3cgZnJvbSBzZWxlY3RlZCByb3dzLi4uXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3Muc3BsaWNlKGksIDEpO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIGV4aXQgbG9vcFxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGV2ZW50VmFsdWUgPSB7XG5cdFx0XHRcdFx0XHRzZWxlY3RlZFJvd3M6IHRoaXMuc2VsZWN0ZWRSb3dzLFxuXHRcdFx0XHRcdFx0Y2hhbmdlZFJvdzogcm93XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdpc1VwZGF0ZWQnOlxuXHRcdFx0XHRcdGV2ZW50TmFtZSA9ICd1cGRhdGVkJztcblx0XHRcdFx0XHRjb25zdCBvbGRWYWx1ZSA9IHByb3BlcnR5VmFsdWVzO1xuXHRcdFx0XHRcdC8vIGNoZWNrIGlmIGVkaXQgb2JqZWN0IGV4aXN0cyBmb3Igcm93XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldID0ge1xuXHRcdFx0XHRcdFx0XHRvcmlnaW5hbFZhbHVlOiBvbGRWYWx1ZSxcblx0XHRcdFx0XHRcdFx0b2xkVmFsdWU6IG9sZFZhbHVlLFxuXHRcdFx0XHRcdFx0XHRuZXdWYWx1ZTogcm93XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XS5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV0ubmV3VmFsdWUgPSByb3c7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGV2ZW50VmFsdWUgPSB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XTtcblx0XHRcdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdFx0XHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbChyb3cpO1xuXHRcdFx0XHRcdC8vIHRoaXMuZ3REYXRhID0gWy4uLnRoaXMuZ3REYXRhLm1hcCgocikgPT4geyByZXR1cm57Li4ucn07IH0pXTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdFx0bmFtZTogJ2d0LXJvdy0nICsgZXZlbnROYW1lLFxuXHRcdFx0XHR2YWx1ZTogZXZlbnRWYWx1ZVxuXHRcdFx0fSk7XG5cdFx0XHRpZiAocHJvcGVydHkgIT09ICdpc1VwZGF0ZWQnKSB7XG5cdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldID0gIXRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bXG5cdFx0XHRcdFx0cHJvcGVydHlcblx0XHRcdFx0XTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlIGNvbHVtbi5cblx0ICogQHBhcmFtICRldmVudCAtIGtleSB1cCBldmVudC5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QuXG5cdCAqIEBwYXJhbSBjb2x1bW4gLSBjb2x1bW4gb2JqZWN0LlxuXHQgKi9cblx0cHVibGljIGd0VXBkYXRlQ29sdW1uKFxuXHRcdCRldmVudDogS2V5Ym9hcmRFdmVudCxcblx0XHRyb3c6IEd0Um93LFxuXHRcdGNvbHVtbjogR3RSZW5kZXJGaWVsZDxhbnksIGFueT5cblx0KSB7XG5cdFx0dGhpcy5fZWRpdFJvdyhyb3csIGNvbHVtbik7XG5cdH1cblxuXHQvKipcblx0ICogRHJvcGRvd24gc2VsZWN0LlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdC5cblx0ICogQHBhcmFtIGNvbHVtbiAtIGNvbHVtbiBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgZ3REcm9wZG93blNlbGVjdChyb3c6IEd0Um93LCBjb2x1bW46IEd0UmVuZGVyRmllbGQ8YW55LCBhbnk+KSB7XG5cdFx0Y29uc3Qgb2xkVmFsdWUgPSB7IC4uLnJvdyB9O1xuXHRcdHJvd1tjb2x1bW4ub2JqZWN0S2V5XSA9IGNvbHVtbi5yZW5kZXJWYWx1ZTtcblx0XHR0aGlzLnVwZGF0ZVJvdyhyb3csIG9sZFZhbHVlKTtcblx0fVxuXG5cdHByaXZhdGUgX2VkaXRSb3cocm93OiBHdFJvdywgY29sdW1uOiBHdFJlbmRlckZpZWxkPGFueSwgYW55Pikge1xuXHRcdGNvbnN0IE9CSkVDVF9LRVkgPSBjb2x1bW4ub2JqZWN0S2V5OyAvLyBkZWNsYXJlIG9iamVjdCBrZXkgd2hpY2ggY29udGFpbnMgY2hhbmdlc1xuXG5cdFx0Ly8gY2hlY2sgaWYgY2VsbCBoYXMgY2hhbmdlZCB2YWx1ZVxuXHRcdGNvbHVtbi5lZGl0ZWQgPSByb3dbY29sdW1uLm9iamVjdEtleV0gIT09IGNvbHVtbi5yZW5kZXJWYWx1ZTtcblx0XHQvLyBjaGVjayBpZiByb3cgY29udGFpbnMgY2hhbmdlcy4uLlxuXHRcdGlmICghdGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdKSB7XG5cdFx0XHQvLyBpZiBub3QsIGNyZWF0ZSBhbiBvYmplY3QgZm9yIHRoZSBjaGFuZ2VkIHJvd1xuXHRcdFx0dGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdID0ge1xuXHRcdFx0XHRjaGFuZ2VzOiB7fSwgLy8gY3JlYXRlIHBsYWNlaG9sZGVyIGZvciBjaGFuZ2VzXG5cdFx0XHRcdHJvdzogcm93IC8vIHN0b3JlIHJlZmVyZW5jZSB0byB0aGUgcm93IHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWRcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gc3RvcmUgY2hhbmdlZCBjb2x1bW4gdW5kZXIgY2hhbmdlcyBpZiBpdCBoYXMgYmVlbiBlZGl0ZWRcblx0XHRpZiAoY29sdW1uLmVkaXRlZCkge1xuXHRcdFx0dGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdLmNoYW5nZXNbT0JKRUNUX0tFWV0gPSBjb2x1bW47XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGRlbGV0ZSBjaGFuZ2Ugb2JqZWN0IGlmIGNvbHVtbiBpcyB1bmNoYW5nZWRcblx0XHRcdGRlbGV0ZSB0aGlzLmVkaXRlZFJvd3Nbcm93LiQkZ3RSb3dJZF0uY2hhbmdlc1tPQkpFQ1RfS0VZXTtcblx0XHRcdC8vIGNoZWNrIGhvdyBtYW55IGNvbHVtbnMgaGF2ZSBiZWVuIGNoYW5nZWRcblx0XHRcdGNvbnN0IENIQU5HRURfQ09MVU1OUyA9IE9iamVjdC5rZXlzKFxuXHRcdFx0XHR0aGlzLmVkaXRlZFJvd3Nbcm93LiQkZ3RSb3dJZF0uY2hhbmdlc1xuXHRcdFx0KS5sZW5ndGg7XG5cdFx0XHRpZiAoQ0hBTkdFRF9DT0xVTU5TID09PSAwKSB7XG5cdFx0XHRcdC8vIGRlbGV0ZSByb3cgZnJvbSBlZGl0ZWQgcm93cyBpZiBubyBjb2x1bW5zIGhhdmUgYmVlbiBlZGl0ZWRcblx0XHRcdFx0ZGVsZXRlIHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gaWYgbm8gbGlzdGVuZXIgaXMgcHJlc2VudC4uLlxuXHRcdGlmICghdGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIpIHtcblx0XHRcdC8vIC4uLmxpc3RlbiBmb3IgdXBkYXRlIGV2ZW50XG5cdFx0XHR0aGlzLl9saXN0ZW5Gb3JLZXlkb3duRXZlbnQoKTtcblx0XHR9XG5cdH1cblx0LyoqXG5cdCAqIExpc3RlbiBmb3Iga2V5IGRvd24gZXZlbnQgLSBsaXN0ZW4gZm9yIGtleSBkb3duIGV2ZW50IGR1cmluZyBpbmxpbmUgZWRpdC5cblx0ICovXG5cdHByaXZhdGUgX2xpc3RlbkZvcktleWRvd25FdmVudCgpIHtcblx0XHQvLyBhZGQgZ2xvYmFsIGxpc3RlbmVyIGZvciBrZXkgZG93biBldmVudHNcblx0XHR0aGlzLmdsb2JhbElubGluZUVkaXRMaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKFxuXHRcdFx0J2RvY3VtZW50Jyxcblx0XHRcdCdrZXlkb3duJyxcblx0XHRcdCRldmVudCA9PiB7XG5cdFx0XHRcdHN3aXRjaCAoJGV2ZW50LmtleSkge1xuXHRcdFx0XHRcdGNhc2UgJ0VudGVyJzogLy8gdXBkYXRlIGRhdGEgb2JqZWN0XG5cdFx0XHRcdFx0XHR0aGlzLmlubGluZUVkaXRVcGRhdGUoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ0VzY2FwZSc6IC8vIGNhbmNlbFxuXHRcdFx0XHRcdFx0dGhpcy5pbmxpbmVFZGl0Q2FuY2VsKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdCk7XG5cdH1cblx0LyoqXG5cdCAqIElubGluZSBlZGl0IHVwZGF0ZSAtIGFjY2VwdCBjaGFuZ2VzIGFuZCB1cGRhdGUgcm93IHZhbHVlcy5cblx0ICovXG5cdHB1YmxpYyBpbmxpbmVFZGl0VXBkYXRlKCkge1xuXHRcdC8vIGxvb3AgdGhyb3VnaCByb3dzIHRoYXQgaGF2ZSBiZWVuIGVkaXRlZFxuXHRcdE9iamVjdC5rZXlzKHRoaXMuZWRpdGVkUm93cykubWFwKGtleSA9PiB7XG5cdFx0XHRjb25zdCBST1cgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5yb3c7IC8vIHJvdyB0byB1cGRhdGVcblx0XHRcdGNvbnN0IENIQU5HRVMgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5jaGFuZ2VzOyAvLyBjaGFuZ2VzIHRvIHRoZSByb3dcblxuXHRcdFx0Ly8gbG9vcCB0aHJvdWdoIGNoYW5nZXMgaW4gcm93XG5cdFx0XHRPYmplY3Qua2V5cyhDSEFOR0VTKS5tYXAob2JqZWN0S2V5ID0+IHtcblx0XHRcdFx0Y29uc3Qgb2xkVmFsdWUgPSB7IC4uLlJPVyB9O1xuXHRcdFx0XHRST1dbb2JqZWN0S2V5XSA9IENIQU5HRVNbb2JqZWN0S2V5XS5yZW5kZXJWYWx1ZTsgLy8gdXBkYXRlIGRhdGEgdmFsdWVcblx0XHRcdFx0dGhpcy51cGRhdGVSb3coUk9XLCBvbGRWYWx1ZSk7IC8vIHVwZGF0ZSBtZXRhIGluZm8gZm9yIHJvdyBhbmQgc2VuZCBldmVudFxuXHRcdFx0XHRDSEFOR0VTW29iamVjdEtleV0uZWRpdGVkID0gZmFsc2U7IC8vIGRpc2FibGUgZWRpdCBtb2RlXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0XHQvLyBjbGVhciByb3dzIG1hcmtlZCBhcyBlZGl0ZWQgYXMgdGhlIHJvd3MgaGF2ZSBiZWVuIHVwZGF0ZWRcblx0XHR0aGlzLmVkaXRlZFJvd3MgPSB7fTtcblx0XHQvLyByZW1vdmUgbGlzdGVuZXJcblx0XHR0aGlzLl9zdG9wTGlzdGVuaW5nRm9yS2V5ZG93bkV2ZW50KCk7XG5cdH1cblx0LyoqXG5cdCAqIElubGluZSBlZGl0IGNhbmNlbCAtIGNhbmNlbCBhbmQgcmVzZXQgaW5saW5lIGVkaXRzLlxuXHQgKi9cblx0cHVibGljIGlubGluZUVkaXRDYW5jZWwocm93PzogR3RSb3cpIHtcblx0XHRpZiAocm93KSB7XG5cdFx0XHRkZWxldGUgdGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdO1xuXHRcdFx0Ly8gcmVtb3ZlIGxpc3RlbmVyXG5cdFx0XHR0aGlzLl9zdG9wTGlzdGVuaW5nRm9yS2V5ZG93bkV2ZW50KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gbG9vcCB0aHJvdWdoIHJvd3MgdGhhdCBoYXZlIGJlZW4gZWRpdGVkXG5cdFx0T2JqZWN0LmtleXModGhpcy5lZGl0ZWRSb3dzKS5tYXAoa2V5ID0+IHtcblx0XHRcdGNvbnN0IFJPVyA9IHRoaXMuZWRpdGVkUm93c1trZXldLnJvdzsgLy8gcm93IHRvIHVwZGF0ZVxuXHRcdFx0Y29uc3QgQ0hBTkdFUyA9IHRoaXMuZWRpdGVkUm93c1trZXldLmNoYW5nZXM7IC8vIGNoYW5nZXMgdG8gdGhlIHJvd1xuXG5cdFx0XHQvLyBsb29wIHRocm91Z2ggY2hhbmdlcyBpbiByb3dcblx0XHRcdE9iamVjdC5rZXlzKENIQU5HRVMpLm1hcChvYmplY3RLZXkgPT4ge1xuXHRcdFx0XHRDSEFOR0VTW29iamVjdEtleV0ucmVuZGVyVmFsdWUgPSBST1dbb2JqZWN0S2V5XTsgLy8gcmVzZXQgcmVuZGVyZWQgdmFsdWVcblx0XHRcdFx0Q0hBTkdFU1tvYmplY3RLZXldLmVkaXRlZCA9IGZhbHNlOyAvLyBkaXNhYmxlIGVkaXQgbW9kZVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0Ly8gY2xlYXIgcm93cyBtYXJrZWQgYXMgZWRpdGVkIGFzIHRoZSByb3dzIGhhdmUgYmVlbiB1cGRhdGVkXG5cdFx0dGhpcy5lZGl0ZWRSb3dzID0ge307XG5cdFx0Ly8gcmVtb3ZlIGxpc3RlbmVyXG5cdFx0dGhpcy5fc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpO1xuXHR9XG5cdC8qKlxuXHQgKiBTdG9wIGxpc3RlbmluZyBmb3Iga2V5IGRvd24gZXZlbnQgLSBzdG9wIGxpc3RlbmluZyBmb3Iga2V5IGRvd24gZXZlbnRzIHBhc3NlZCBkdXJpbmcgaW5saW5lIGVkaXQuXG5cdCAqL1xuXHRwcml2YXRlIF9zdG9wTGlzdGVuaW5nRm9yS2V5ZG93bkV2ZW50KCkge1xuXHRcdGlmICh0aGlzLmdsb2JhbElubGluZUVkaXRMaXN0ZW5lcikge1xuXHRcdFx0dGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIoKTtcblx0XHRcdHRoaXMuZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyID0gbnVsbDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQXBwbHkgZmlsdGVyKHMpLlxuXHQgKiBAcGFyYW0gZmlsdGVyIC0gb2JqZWN0IGNvbnRhaW5pbmcga2V5IHZhbHVlIHBhaXJzLCB3aGVyZSB2YWx1ZSBzaG91bGQgYmUgYXJyYXkgb2YgdmFsdWVzLlxuXHQgKi9cblx0cHVibGljIGd0QXBwbHlGaWx0ZXIoZmlsdGVyOiBPYmplY3QpIHtcblx0XHR0aGlzLmd0SW5mby5maWx0ZXIgPSBmaWx0ZXI7XG5cdFx0Ly8gZ28gdG8gZmlyc3QgcGFnZVxuXHRcdHRoaXMuZ29Ub1BhZ2UoMSk7XG5cdFx0dGhpcy51cGRhdGVUb3RhbHMoKTtcblx0fVxuXG5cdC8qKiBDbGVhci9yZW1vdmUgYXBwbGllZCBmaWx0ZXIocykuICovXG5cdHB1YmxpYyBndENsZWFyRmlsdGVyKCkge1xuXHRcdHRoaXMuZ3RJbmZvLmZpbHRlciA9IGZhbHNlO1xuXHRcdHRoaXMudXBkYXRlVG90YWxzKCk7XG5cdFx0Ly8gdGhpcy51cGRhdGVSZWNvcmRSYW5nZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNlYXJjaFxuXHQgKiBAcGFyYW0gdmFsdWUgLSBzdHJpbmcgY29udGFpbmluZyBvbmUgb3IgbW9yZSB3b3Jkc1xuXHQgKi9cblx0cHVibGljIGd0U2VhcmNoKHZhbHVlOiBzdHJpbmcpIHtcblx0XHR0aGlzLmd0SW5mby5zZWFyY2hUZXJtcyA9IHZhbHVlO1xuXHRcdC8vIGFsd2F5cyBnbyB0byBmaXJzdCBwYWdlIHdoZW4gc2VhcmNoaW5nXG5cdFx0dGhpcy5nb1RvUGFnZSgxKTtcblx0XHR0aGlzLnVwZGF0ZVRvdGFscygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCByb3dzXG5cdCAqIEBwYXJhbSByb3dzIC0gcm93cyB0byBhZGRcblx0ICogQHJldHVybnMgbmV3IGRhdGEgYXJyYXkuXG5cdCAqL1xuXHRwdWJsaWMgZ3RBZGQocm93czogQXJyYXk8Uj4pOiBSZWFkb25seUFycmF5PFI+IHtcblx0XHR0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YSwgLi4ucm93c107XG5cdFx0cmV0dXJuIFsuLi50aGlzLmd0RGF0YV07XG5cdH1cblxuXHQvKipcblx0ICogRGVsZXRlIHJvd1xuXHQgKiBAcGFyYW0gb2JqZWN0S2V5IC0gb2JqZWN0IGtleSB5b3Ugd2FudCB0byBmaW5kIG1hdGNoIHdpdGhcblx0ICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGRlbGV0ZWRcblx0ICogQHBhcmFtIG1hdGNoIC0gYWxsOiBkZWxldGUgYWxsIG1hdGNoZXMsIGZpcnN0OiBkZWxldGUgZmlyc3QgbWF0Y2ggKGRlZmF1bHQpXG5cdCAqIEByZXR1cm5zIG5ldyBkYXRhIGFycmF5LlxuXHQgKi9cblx0cHVibGljIGd0RGVsZXRlKFxuXHRcdG9iamVjdEtleTogc3RyaW5nLFxuXHRcdHZhbHVlOiBzdHJpbmcgfCBudW1iZXIsXG5cdFx0bWF0Y2g6ICdmaXJzdCcgfCAnYWxsJyA9ICdmaXJzdCdcblx0KTogUmVhZG9ubHlBcnJheTxSPiB7XG5cdFx0aWYgKG1hdGNoID09PSAnZmlyc3QnKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZ3REYXRhLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmICh0aGlzLmd0RGF0YVtpXVtvYmplY3RLZXldID09PSB2YWx1ZSkge1xuXHRcdFx0XHRcdGlmICh0aGlzLmlzUm93U2VsZWN0ZWQodGhpcy5ndERhdGFbaV0pKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRvZ2dsZVNlbGVjdCh0aGlzLmd0RGF0YVtpXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuZ3REYXRhLnNwbGljZShpLCAxKTtcblx0XHRcdFx0XHR0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YV07XG5cdFx0XHRcdFx0aWYgKG1hdGNoID09PSAnZmlyc3QnKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yIChsZXQgaSA9IHRoaXMuZ3REYXRhLmxlbmd0aDsgaSA+IDA7IGktLSkge1xuXHRcdFx0XHRpZiAodGhpcy5ndERhdGFbaSAtIDFdW29iamVjdEtleV0gPT09IHZhbHVlKSB7XG5cdFx0XHRcdFx0aWYgKHRoaXMuaXNSb3dTZWxlY3RlZCh0aGlzLmd0RGF0YVtpIC0gMV0pKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRvZ2dsZVNlbGVjdCh0aGlzLmd0RGF0YVtpIC0gMV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLmd0RGF0YS5zcGxpY2UoaSAtIDEsIDEpO1xuXHRcdFx0XHRcdHRoaXMuZ3REYXRhID0gWy4uLnRoaXMuZ3REYXRhXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gWy4uLnRoaXMuZ3REYXRhXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgc3RvcmUgdG8gaG9sZCBwcmV2aW91c2x5IGxvYWRlZCByZWNvcmRzLlxuXHQgKiBAcGFyYW0gcmVjb3JkcyAtIHRvdGFsIG51bWJlciBvZiByZWNvcmRzIGluIHN0b3JlLlxuXHQgKiBAcGFyYW0gcGVyUGFnZSAtIGhvdyBtYW55IHJlY29yZHMgdG8gc2hvdyBwZXIgcGFnZS5cblx0ICogQHJldHVybnMgYSBuZXN0ZWQgYXJyYXkgdG8gaG9sZCByZWNvcmRzIHBlciBwYWdlLlxuXHQgKi9cblx0cHJpdmF0ZSBjcmVhdGVTdG9yZShyZWNvcmRzOiBudW1iZXIsIHBlclBhZ2U6IG51bWJlcik6IEFycmF5PEFycmF5PGFueT4+IHtcblx0XHRjb25zdCBzdG9yZXMgPSBNYXRoLmNlaWwocmVjb3JkcyAvIHBlclBhZ2UpO1xuXHRcdGNvbnN0IHN0b3JlOiBBcnJheTxBcnJheTxhbnk+PiA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3RvcmVzOyBpKyspIHtcblx0XHRcdHN0b3JlW2ldID0gW107XG5cdFx0fVxuXHRcdHJldHVybiBzdG9yZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgcGxhY2Vob2xkZXJzIGZvciByb3dzIHdoaWxlIGxvYWRpbmcgZGF0YSBmcm9tIGJhY2stZW5kLlxuXHQgKiBAcGFyYW0gcGVyUGFnZSAtIGhvdyBtYW55IHJlY29yZHMgdG8gc2hvdyBwZXIgcGFnZS5cblx0ICogQHJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBlbXB0eSByZWNvcmRzIHRvIGJlIHByZXNlbnRlZCB3aGlsZSBmZXRjaGluZyByZWFsIGRhdGEuXG5cdCAqL1xuXHRwcml2YXRlIGxvYWRpbmdDb250ZW50KHBlclBhZ2U6IG51bWJlcikge1xuXHRcdC8vIGNyZWF0ZSByb3cgb2JqZWN0XG5cdFx0Y29uc3Qgcm93T2JqZWN0OiBPYmplY3QgPSB7XG5cdFx0XHQkJGxvYWRpbmc6IHRydWVcblx0XHR9O1xuXHRcdGxldCBvcmRlciA9IDA7XG5cblx0XHQvLyBzb3J0IHNldHRpbmdzIGJ5IGNvbHVtbiBvcmRlclxuXHRcdHRoaXMuX2d0U2V0dGluZ3Muc29ydCh0aGlzLmdldENvbHVtbk9yZGVyKTtcblxuXHRcdC8vIGxvb3AgdGhyb3VnaCBhbGwgc2V0dGluZ3Mgb2JqZWN0cy4uLlxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgc2V0dGluZyA9IHRoaXMuX2d0U2V0dGluZ3NbaV07XG5cblx0XHRcdC8vIC4uLmlmIGNvbHVtbiBpcyB2aXNpYmxlIGFuZCBlbmFibGVkLi4uXG5cdFx0XHRpZiAoc2V0dGluZy52aXNpYmxlICE9PSBmYWxzZSAmJiBzZXR0aW5nLmVuYWJsZWQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdC8vIC4uLmlmIGZpcnN0IGNvbHVtbiwgc2V0IHZhbHVlIHRvIGxvYWRpbmcgdGV4dCBvdGhlcndpc2UgbGVhdmUgaXQgZW1wdHlcblx0XHRcdFx0aWYgKG9yZGVyID09PSAwKSB7XG5cdFx0XHRcdFx0cm93T2JqZWN0W3NldHRpbmcub2JqZWN0S2V5XSA9IHRoaXMuZ3RUZXh0cy5sb2FkaW5nO1xuXHRcdFx0XHRcdHRoaXMubG9hZGluZ1Byb3BlcnR5ID0gc2V0dGluZy5vYmplY3RLZXk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cm93T2JqZWN0W3NldHRpbmcub2JqZWN0S2V5XSA9ICcnO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG9yZGVyKys7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyb3dPYmplY3Rbc2V0dGluZy5vYmplY3RLZXldID0gJyc7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY3JlYXRlIGNvbnRlbnQgcGxhY2Vob2xkZXJcblx0XHRjb25zdCBjb250ZW50UGxhY2Vob2xkZXI6IEFycmF5PGFueT4gPSBbXTtcblxuXHRcdC8vIGNyZWF0ZSBlcXVhbCBudW1iZXIgb2Ygcm93cyBhcyByb3dzIHBlciBwYWdlXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBwZXJQYWdlOyBpKyspIHtcblx0XHRcdC8vIC4uLmFkZCB0ZW1wb3Jhcnkgcm93IG9iamVjdFxuXHRcdFx0Y29udGVudFBsYWNlaG9sZGVyLnB1c2gocm93T2JqZWN0KTtcblx0XHR9XG5cdFx0cmV0dXJuIGNvbnRlbnRQbGFjZWhvbGRlcjtcblx0fVxuXG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBzb3J0IG9yZGVyICovXG5cdHByaXZhdGUgZ2V0U29ydE9yZGVyID0gZnVuY3Rpb24oYTogR3RDb25maWdTZXR0aW5nLCBiOiBHdENvbmZpZ1NldHRpbmcpIHtcblx0XHRpZiAoYS5zb3J0T3JkZXIgPCBiLnNvcnRPcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5zb3J0T3JkZXIgPiBiLnNvcnRPcmRlciB8fCB0eXBlb2YgYS5zb3J0T3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH07XG5cblx0Ly8gVE9ETzogbW92ZSB0byBoZWxwZXIgZnVuY3Rpb25zXG5cdC8qKiBTb3J0IGJ5IGNvbHVtbiBvcmRlciAqL1xuXHRwcml2YXRlIGdldENvbHVtbk9yZGVyID0gZnVuY3Rpb24oYTogR3RDb25maWdTZXR0aW5nLCBiOiBHdENvbmZpZ1NldHRpbmcpIHtcblx0XHRpZiAoYS5jb2x1bW5PcmRlciA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fVxuXHRcdGlmIChhLmNvbHVtbk9yZGVyIDwgYi5jb2x1bW5PcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA+IGIuY29sdW1uT3JkZXIpIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fTtcblxuXHQvLyBUT0RPOiBtb3ZlIHRvIGhlbHBlciBmdW5jdGlvbnNcblx0LyoqIENyZWF0ZSBhIGRlZXAgY29weSBvZiBkYXRhICovXG5cdHByaXZhdGUgY2xvbmVEZWVwID0gZnVuY3Rpb24obzogYW55KSB7XG5cdFx0cmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpO1xuXHR9O1xuXG5cdC8qKiBFeHBvcnQgZGF0YSBhcyBDU1Zcblx0ICogQHBhcmFtIGZpbGVOYW1lIC0gb3B0aW9uYWwgZmlsZSBuYW1lIChvdmVycmlkZXMgZGVmYXVsdCBmaWxlIG5hbWUpLlxuXHQgKiBAcGFyYW0gdXNlQk9NIC0gdXNlIEJPTSAoYnl0ZSBvcmRlciBtYXJrZXIpLlxuXHQgKi9cblx0cHVibGljIGV4cG9ydENTVihmaWxlTmFtZT86IHN0cmluZywgdXNlQk9NOiBib29sZWFuID0gZmFsc2UpIHtcblx0XHRjb25zdCBkYXRhID0gdGhpcy5kYXRhLmV4cG9ydERhdGE7XG5cdFx0bGV0IGNzdiA9ICcnO1xuXHRcdGNvbnN0IEJPTSA9ICdcXHVGRUZGJztcblxuXHRcdC8vIGNzdiBleHBvcnQgaGVhZGVyc1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHRoaXMuX2d0U2V0dGluZ3NbaV0uZXhwb3J0ICE9PSBmYWxzZSkge1xuXHRcdFx0XHRjc3YgKz0gdGhpcy5nZXRQcm9wZXJ0eSh0aGlzLl9ndEZpZWxkcywgdGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXkpXG5cdFx0XHRcdFx0Lm5hbWU7XG5cblx0XHRcdFx0aWYgKGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aCAtIDEpIHtcblx0XHRcdFx0XHRjc3YgKz0gdGhpcy5fZ3RPcHRpb25zLmNzdkRlbGltaXRlcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGNzdiBleHBvcnQgYm9keVxuXHRcdGRhdGEuZm9yRWFjaChyb3cgPT4ge1xuXHRcdFx0Y3N2ICs9ICdcXG4nO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLmV4cG9ydCAhPT0gZmFsc2UpIHtcblx0XHRcdFx0XHQvLyBnZXQgZmllbGQgc2V0dGluZ3Ncblx0XHRcdFx0XHRjb25zdCBmaWVsZFNldHRpbmcgPSB0aGlzLmdldFByb3BlcnR5KFxuXHRcdFx0XHRcdFx0dGhpcy5fZ3RGaWVsZHMsXG5cdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleVxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHQvLyBnZXQgZXhwb3J0IHZhbHVlLCBpZiBleHBvcnQgZnVuY3Rpb24gaXMgZGVmaW5lZCB1c2UgaXQgb3RoZXJ3aXNlIGNoZWNrIGZvciB2YWx1ZSBmdW5jdGlvbiBhbmQgYXMgYSBsYXN0IHJlc29ydCBleHBvcnQgcmF3IGRhdGFcblx0XHRcdFx0XHRsZXQgZXhwb3J0VmFsdWU6IHN0cmluZyA9XG5cdFx0XHRcdFx0XHRmaWVsZFNldHRpbmcuZXhwb3J0ICYmIHR5cGVvZiBmaWVsZFNldHRpbmcuZXhwb3J0ID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHRcdD8gZmllbGRTZXR0aW5nLmV4cG9ydChyb3cpXG5cdFx0XHRcdFx0XHRcdDogZmllbGRTZXR0aW5nLnZhbHVlICYmIHR5cGVvZiBmaWVsZFNldHRpbmcudmFsdWUgPT09ICdmdW5jdGlvbidcblx0XHRcdFx0XHRcdFx0XHQ/IGZpZWxkU2V0dGluZy52YWx1ZShyb3cpXG5cdFx0XHRcdFx0XHRcdFx0OiByb3dbdGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXldO1xuXG5cdFx0XHRcdFx0Ly8gZXNjYXBlIGV4cG9ydCB2YWx1ZSB1c2luZyBkb3VibGUgcXVvdGVzIChcIikgaWYgZXhwb3J0IHZhbHVlIGNvbnRhaW5zIGRlbGltaXRlclxuXHRcdFx0XHRcdGV4cG9ydFZhbHVlID1cblx0XHRcdFx0XHRcdHR5cGVvZiBleHBvcnRWYWx1ZSA9PT0gJ3N0cmluZycgJiZcblx0XHRcdFx0XHRcdGV4cG9ydFZhbHVlLmluZGV4T2YodGhpcy5fZ3RPcHRpb25zLmNzdkRlbGltaXRlcikgIT09IC0xXG5cdFx0XHRcdFx0XHRcdD8gJ1wiJyArIGV4cG9ydFZhbHVlICsgJ1wiJ1xuXHRcdFx0XHRcdFx0XHQ6IGV4cG9ydFZhbHVlO1xuXG5cdFx0XHRcdFx0Y3N2ICs9IGV4cG9ydFZhbHVlO1xuXHRcdFx0XHRcdGlmIChpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0XHRjc3YgKz0gdGhpcy5fZ3RPcHRpb25zLmNzdkRlbGltaXRlcjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbKHVzZUJPTSA/IEJPTSA6ICcnKSArIGNzdl0sIHtcblx0XHRcdHR5cGU6ICd0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04J1xuXHRcdH0pO1xuXG5cdFx0aWYgKHdpbmRvdy5uYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYikge1xuXHRcdFx0bmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoXG5cdFx0XHRcdGJsb2IsXG5cdFx0XHRcdGZpbGVOYW1lID8gZmlsZU5hbWUgKyAnLmNzdicgOiB0aGlzLmd0VGV4dHMuY3N2RG93bmxvYWQgKyAnLmNzdidcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG5cdFx0XHRsaW5rLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuXHRcdFx0aWYgKGxpbmsuZG93bmxvYWQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRsaW5rLnNldEF0dHJpYnV0ZShcblx0XHRcdFx0XHQnaHJlZicsXG5cdFx0XHRcdFx0J2RhdGE6dGV4dC9jc3Y7Y2hhcnNldD11dGYtOCwnICtcblx0XHRcdFx0XHRcdGVuY29kZVVSSUNvbXBvbmVudCgodXNlQk9NID8gQk9NIDogJycpICsgY3N2KVxuXHRcdFx0XHQpOyAvLyBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpKTtcblx0XHRcdFx0bGluay5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcdFx0J2Rvd25sb2FkJyxcblx0XHRcdFx0XHRmaWxlTmFtZSA/IGZpbGVOYW1lICsgJy5jc3YnIDogdGhpcy5ndFRleHRzLmNzdkRvd25sb2FkICsgJy5jc3YnXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG5cdFx0XHRcdGxpbmsuY2xpY2soKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNzdiA9ICdkYXRhOnRleHQvY3N2O2NoYXJzZXQ9dXRmLTgsJyArICh1c2VCT00gPyBCT00gOiAnJykgKyBjc3Y7XG5cdFx0XHRcdHdpbmRvdy5vcGVuKGVuY29kZVVSSUNvbXBvbmVudChjc3YpKTtcblx0XHRcdH1cblx0XHRcdGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG5cdFx0fVxuXG5cdFx0Ly8gZW1pdCBleHBvcnQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtZXhwb3J0ZWQtY3N2Jyxcblx0XHRcdHZhbHVlOiBmaWxlTmFtZSA/IGZpbGVOYW1lIDogdGhpcy5ndFRleHRzLmNzdkRvd25sb2FkICsgJy5jc3YnXG5cdFx0fSk7XG5cdH1cblxuXHQvKiogUmV0dXJuIHByb3BlcnR5ICovXG5cdHByaXZhdGUgZ2V0UHJvcGVydHkgPSBmdW5jdGlvbihhcnJheTogQXJyYXk8YW55Piwga2V5OiBzdHJpbmcpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXJyYXlbaV0ub2JqZWN0S2V5ID09PSBrZXkpIHtcblx0XHRcdFx0cmV0dXJuIGFycmF5W2ldO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblxuXHRwcml2YXRlIHJlc3RydWN0dXJlU29ydGluZyA9IGZ1bmN0aW9uKCkge1xuXHRcdC8qKiBDaGVjayBhbmQgc3RvcmUgc29ydCBvcmRlciB1cG9uIGluaXRpYWxpemF0aW9uLlxuXHRcdCAqICBUaGlzIGlzIGRvbmUgYnkgY2hlY2tpbmcgc29ydCBwcm9wZXJ0aWVzIGluIHRoZSBzZXR0aW5ncyBhcnJheSBvZiB0aGUgdGFibGUsIGlmIG5vIHNvcnRpbmcgaXMgZGVmaW5lZFxuXHRcdCAqICB3ZSdsbCBzb3J0IHRoZSBkYXRhIGJ5IHRoZSBmaXJzdCB2aXNpYmxlIGFuZCBlbmFibGVkIGNvbHVtbiBpbiB0aGUgdGFibGUoYXNjZW5kaW5nKS4gUGxlYXNlIG5vdGUgdGhhdCBhY3R1YWxseVxuXHRcdCAqICBzb3J0aW5nIGhhdmUgdG8gYmUgZG9uZSBzZXJ2ZXIgc2lkZSB3aGVuIGxhenkgbG9hZGluZyBkYXRhIGZvciBvYnZpb3VzIHJlYXNvbnMuICAqL1xuXHRcdC8vIGNyZWF0ZSBzb3J0aW5nIGFycmF5XG5cdFx0Y29uc3Qgc29ydGluZyA9IFtdO1xuXHRcdGlmICh0aGlzLl9ndFNldHRpbmdzKSB7XG5cdFx0XHQvLyAuLi5zb3J0IHNldHRpbmdzIGJ5IHNvcnQgb3JkZXJcblx0XHRcdHRoaXMuX2d0U2V0dGluZ3Muc29ydCh0aGlzLmdldFNvcnRPcmRlcik7XG5cblx0XHRcdC8vIC4uLmxvb3AgdGhyb3VnaCBzZXR0aW5nc1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGNvbnN0IHNldHRpbmcgPSB0aGlzLl9ndFNldHRpbmdzW2ldO1xuXG5cdFx0XHRcdC8vIC4uLmlmIHNvcnRlZCBhc2NlbmRpbmcuLi5cblx0XHRcdFx0aWYgKHNldHRpbmcuc29ydCA9PT0gJ2FzYycpIHtcblx0XHRcdFx0XHQvLyAuLi4gYWRkIHRvIHNvcnRpbmdcblx0XHRcdFx0XHRzb3J0aW5nLnB1c2goc2V0dGluZy5vYmplY3RLZXkpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHNldHRpbmcuc29ydCA9PT0gJ2Rlc2MnKSB7XG5cdFx0XHRcdFx0LyogLi4uZWxzZSBpZiBzb3J0ZWQgZGVzY2VuZGluZy4uLiAqLyAvLyAuLi4gYWRkIHRvIHNvcnRpbmdcblx0XHRcdFx0XHRzb3J0aW5nLnB1c2goJy0nICsgc2V0dGluZy5vYmplY3RLZXkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyAuLi5pZiBubyBzb3J0aW5nIGFwcGxpZWQuLi5cblx0XHRcdGlmIChzb3J0aW5nLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRzb3J0aW5nLnB1c2goJyQkZ3RSb3dJZCcpO1xuXHRcdFx0XHQvKi8vIC4uLnNvcnQgc2V0dGluZ3MgYnkgY29sdW1uIG9yZGVyXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3Muc29ydCh0aGlzLmdldENvbHVtbk9yZGVyKTtcblxuXHRcdFx0XHQvLyAuLi5sb29wIHRocm91Z2ggc2V0dGluZ3Ncblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0Y29uc3Qgc2V0dGluZyA9IHRoaXMuX2d0U2V0dGluZ3NbaV07XG5cblx0XHRcdFx0XHQvLyAuLi5pZiBjb2x1bW4gaXMgZW5hYmxlZCBhbmQgdmlzaWJsZS4uLlxuXHRcdFx0XHRcdGlmIChzZXR0aW5nLmVuYWJsZWQgIT09IGZhbHNlICYmIHNldHRpbmcudmlzaWJsZSAhPT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdC8vIC4uLmFkZCBmaXJzdCBtYXRjaCBhbmQgZXhpdCBmdW5jdGlvblxuXHRcdFx0XHRcdFx0dGhpcy5zb3J0T3JkZXIgPSBbdGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXldO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSovXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuc29ydE9yZGVyLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0dGhpcy5zb3J0T3JkZXIgPSBzb3J0aW5nO1xuXHRcdH1cblx0fTtcblxuXHRuZ09uSW5pdCgpIHtcblx0XHQvLyBpZiBudW1iZXIgb2Ygcm93IHRvIGRpc3BsYXkgZnJvbSBzdGFydCBpcyBzZXQgdG8gbnVsbCBvciAwLi4uXG5cdFx0aWYgKCF0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3MpIHtcblx0XHRcdC8vIC4uLmNoYW5nZSByb3cgbGVuZ3RoXG5cdFx0XHR0aGlzLmNoYW5nZVJvd0xlbmd0aCh0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3MpO1xuXHRcdH1cblx0XHR0aGlzLnJlc3RydWN0dXJlU29ydGluZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqICBFeHRlbmQgb2JqZWN0IGZ1bmN0aW9uLlxuXHQgKi9cblx0cHJpdmF0ZSBleHRlbmQgPSBmdW5jdGlvbihhOiBPYmplY3QsIGI6IE9iamVjdCkge1xuXHRcdGZvciAoY29uc3Qga2V5IGluIGIpIHtcblx0XHRcdGlmIChiLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0XHRcdFx0YVtrZXldID0gYltrZXldO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gYTtcblx0fTtcblxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG5cdFx0Ly8gaWYgZ3QgdGV4dHMgaGF2ZSBjaGFuZ2VkLi4uXG5cdFx0aWYgKGNoYW5nZXNbJ2d0VGV4dHMnXSkge1xuXHRcdFx0Ly8gLi4uZXh0ZW5kIGd0T3B0aW9ucyBkZWZhdWx0IHZhbHVlcyB3aXRoIHZhbHVlcyBwYXNzZWQgaW50byBjb21wb25lbnRcblx0XHRcdHRoaXMuZ3RUZXh0cyA9IDxHdFRleHRzPnRoaXMuZXh0ZW5kKHRoaXMuZ3REZWZhdWx0VGV4dHMsIHRoaXMuZ3RUZXh0cyk7XG5cdFx0fVxuXG5cdFx0Ly8gaWYgbGF6eSBsb2FkaW5nIGRhdGEgYW5kIHBhZ2luZyBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUuLi5cblx0XHRpZiAodGhpcy5ndE9wdGlvbnMubGF6eUxvYWQgJiYgdGhpcy5ndEluZm8pIHtcblx0XHRcdC8vIC4uLmNhbGN1bGF0ZSB0b3RhbCBudW1iZXIgb2YgcGFnZXNcblx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VUb3RhbCA9IE1hdGguY2VpbChcblx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoIC8gdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHQpO1xuXG5cdFx0XHQvLyAuLi5kZWNsYXJlIHN0b3JlIHBvc2l0aW9uXG5cdFx0XHRjb25zdCBzdG9yZVBvc2l0aW9uID0gdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxO1xuXG5cdFx0XHQvLyAuLi5hbmQgaWYgc3RvcmUgaXMgZW1wdHkgb3IgcGFnZSBsZW5ndGggaGFzIGNoYW5nZWQuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dGhpcy5zdG9yZS5sZW5ndGggPT09IDAgfHxcblx0XHRcdFx0dGhpcy5zdG9yZVswXS5sZW5ndGggIT09IHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0KSB7XG5cdFx0XHRcdC8vIC4uLmNyZWF0ZSBzdG9yZVxuXHRcdFx0XHR0aGlzLnN0b3JlID0gdGhpcy5jcmVhdGVTdG9yZShcblx0XHRcdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2gsXG5cdFx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIC4uLnN0b3JlIHJldHJpZXZlZCBkYXRhIGluIHN0b3JlIGF0IHN0b3JlIHBvc2l0aW9uXG5cdFx0XHR0aGlzLnN0b3JlW3N0b3JlUG9zaXRpb25dID0gdGhpcy5ndERhdGE7XG5cdFx0XHR0aGlzLmd0SW5mby52aXNpYmxlUmVjb3JkcyA9IFsuLi50aGlzLmd0RGF0YV07IC8vIGFkZCB2aXNpYmxlIHJvd3NcblxuXHRcdFx0Ly8gcmVwbGFjZSBkYXRhIHdpdGggc3RvcmVcblx0XHRcdHRoaXMuX2d0RGF0YSA9IHRoaXMuc3RvcmU7XG5cdFx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0XHRcdHRoaXMudXBkYXRlUmVjb3JkUmFuZ2UoKTtcblx0XHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdFx0bmFtZTogJ2d0LWluZm8nLFxuXHRcdFx0XHR2YWx1ZTogdGhpcy5ndEluZm9cblx0XHRcdH0pO1xuXHRcdH0gZWxzZSBpZiAoXG5cdFx0XHR0aGlzLl9ndERhdGEgJiZcblx0XHRcdHRoaXMuX2d0RGF0YS5sZW5ndGggPj0gMCAmJlxuXHRcdFx0Y2hhbmdlc1snZ3REYXRhJ10gJiZcblx0XHRcdGNoYW5nZXNbJ2d0RGF0YSddLnByZXZpb3VzVmFsdWVcblx0XHQpIHtcblx0XHRcdHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRjaGFuZ2VzWydndERhdGEnXSAmJlxuXHRcdFx0Y2hhbmdlc1snZ3REYXRhJ10uZmlyc3RDaGFuZ2UgJiZcblx0XHRcdHRoaXMuX2d0RGF0YSAmJlxuXHRcdFx0dGhpcy5fZ3REYXRhLmxlbmd0aCA+IDBcblx0XHQpIHtcblx0XHRcdHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHRyYWNrQnlGbihpbmRleDogbnVtYmVyLCBpdGVtOiBHdFJvdykge1xuXHRcdHJldHVybiBpdGVtLiQkZ3RSb3dJZDtcblx0fVxuXG5cdHRyYWNrQnlDb2x1bW5GbihpbmRleDogbnVtYmVyLCBpdGVtOiBHdENvbmZpZ0ZpZWxkPGFueSwgYW55Pikge1xuXHRcdHJldHVybiBpdGVtLm9iamVjdEtleTtcblx0fVxuXG5cdG5nT25EZXN0cm95KCkge1xuXHRcdC8vIHJlbW92ZSBsaXN0ZW5lclxuXHRcdHRoaXMuX3N0b3BMaXN0ZW5pbmdGb3JLZXlkb3duRXZlbnQoKTtcblx0fVxufVxuIiwiaW1wb3J0IHtcblx0QWZ0ZXJWaWV3Q2hlY2tlZCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbXBvbmVudCxcblx0SW5wdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LXRhYmxlLWluZm8nLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxzcGFuICpuZ0lmPVwiZ2VuZXJpY1RhYmxlLmd0SW5mb1wiPnt7KGN1c3RvbVRleHQ/IGN1c3RvbVRleHQ6Z2VuZXJpY1RhYmxlLmd0VGV4dHMpIHwgZ3RUYWJsZUluZm86XG5cdFx0XHRnZW5lcmljVGFibGUuZ3RJbmZvOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2g6XG5cdFx0XHRnZW5lcmljVGFibGUuZ3RJbmZvLnJlY29yZEZyb206XG5cdFx0XHRnZW5lcmljVGFibGUuZ3RJbmZvLnJlY29yZFRvOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0SW5mby5yZWNvcmRzQWxsOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0VGV4dHMubG9hZGluZzpcblx0XHRcdGdlbmVyaWNUYWJsZS5ndFRleHRzLnRhYmxlSW5mb0FmdGVyU2VhcmNofX08L3NwYW4+XG4gIGAsXG5cdHN0eWxlczogW11cbn0pXG5leHBvcnQgY2xhc3MgR3RUYWJsZUluZm9Db21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdDaGVja2VkIHtcblx0QElucHV0KCkgZ2VuZXJpY1RhYmxlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+O1xuXHRASW5wdXQoKSBjdXN0b21UZXh0OiBzdHJpbmc7XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBfY2hhbmdlRGV0ZWN0aW9uUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuXHRuZ0FmdGVyVmlld0NoZWNrZWQoKSB7XG5cdFx0dGhpcy5fY2hhbmdlRGV0ZWN0aW9uUmVmLmRldGVjdENoYW5nZXMoKTtcblx0fVxufVxuaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR2VuZXJpY1RhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vZ2VuZXJpYy10YWJsZS9nZW5lcmljLXRhYmxlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHdFRleHRzIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC10ZXh0cyc7XG5pbXBvcnQgeyBHdEluZm9ybWF0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1pbmZvcm1hdGlvbic7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0VGFibGVJbmZvJ1xufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUluZm9QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHR0ZXh0czogR3RUZXh0cyB8IHN0cmluZyxcblx0XHRrZXlzOiBHdEluZm9ybWF0aW9uLFxuXHRcdHJlY29yZHNBZnRlclNlYXJjaDogbnVtYmVyLFxuXHRcdHJlY29yZEZyb206IG51bWJlcixcblx0XHRyZWNvcmRUbzogbnVtYmVyLFxuXHRcdHJlY29yZHNBbGw6IG51bWJlcixcblx0XHRsb2FkaW5nOiBzdHJpbmcsXG5cdFx0dGFibGVJbmZvQWZ0ZXJTZWFyY2g6IHN0cmluZ1xuXHQpOiBzdHJpbmcge1xuXHRcdGxldCB0ZXh0ID0gdHlwZW9mIHRleHRzID09PSAnb2JqZWN0JyA/IHRleHRzLnRhYmxlSW5mbyA6ICcnO1xuXHRcdGlmIChrZXlzLnJlY29yZHNBZnRlclNlYXJjaCAhPT0ga2V5cy5yZWNvcmRzQWxsKSB7XG5cdFx0XHR0ZXh0ID0gdHlwZW9mIHRleHRzID09PSAnb2JqZWN0JyA/IHRleHRzLnRhYmxlSW5mb0FmdGVyU2VhcmNoIDogJyc7XG5cdFx0fVxuXHRcdGZvciAoY29uc3Qga2V5IGluIGtleXMpIHtcblx0XHRcdGlmIChrZXlzLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0XHRcdFx0Y29uc3Qgc2VhcmNoU3RyaW5nID0gbmV3IFJlZ0V4cCgnIycgKyBrZXksICdnJyk7XG5cdFx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2Uoc2VhcmNoU3RyaW5nLCBrZXlzW2tleV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGV4dDtcblx0fVxufVxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdndC1wYWdpbmF0aW9uJyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8bmF2IGNsYXNzPVwiZ3QtcGFnaW5hdGlvblwiIGFyaWEtbGFiZWw9XCJUYWJsZSBuYXZpZ2F0aW9uXCIgKm5nSWY9XCJnZW5lcmljVGFibGUgJiYgZ2VuZXJpY1RhYmxlLmd0SW5mbyAmJiByZWFkeSAmJiBnZW5lcmljVGFibGUuZ3REYXRhPy5sZW5ndGggPiAwXCIgW25nQ2xhc3NdPVwieyduby1kYXRhJzpnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VUb3RhbCA9PT0gMH1cIj5cblx0XHRcdDx1bCBjbGFzcz1cInBhZ2luYXRpb25cIiBbbmdDbGFzc109XCJndENsYXNzZXNcIj5cblx0XHRcdFx0PGxpIGNsYXNzPVwicGFnZS1pdGVtXCIgW25nQ2xhc3NdPVwieydkaXNhYmxlZCcgOiBnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VDdXJyZW50ID09PSAxIHx8IGdlbmVyaWNUYWJsZS5sb2FkaW5nIH1cIj48YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgKGNsaWNrKT1cImdlbmVyaWNUYWJsZS5ndEluZm8ucGFnZUN1cnJlbnQgPiAxICYmIGdlbmVyaWNUYWJsZS5wcmV2aW91c1BhZ2UoKVwiIFthdHRyLmFyaWEtbGFiZWxdPVwiZ2VuZXJpY1RhYmxlLmd0VGV4dHMucGFnaW5hdGVQcmV2aW91c1wiPjxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZsYXF1bzs8L3NwYW4+PHNwYW4gY2xhc3M9XCJzci1vbmx5XCI+e3tnZW5lcmljVGFibGUuZ3RUZXh0cy5wYWdpbmF0ZVByZXZpb3VzfX08L3NwYW4+PC9hPjwvbGk+XG5cdFx0XHRcdDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiIFtuZ0NsYXNzXT1cInsnZGlzYWJsZWQnIDogZ2VuZXJpY1RhYmxlLmxvYWRpbmcgJiYgZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudCAhPT0gcGFnZSwgJ2FjdGl2ZScgOiBnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VDdXJyZW50ID09PSBwYWdlIH1cIiAqbmdGb3I9XCJsZXQgcGFnZSBvZiBnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VUb3RhbCB8IGd0UGFnaW5hdGlvblBpcGU6Z2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudFwiPjxhIGNsYXNzPVwicGFnZS1saW5rXCIgW3RhYmluZGV4XT1cInBhZ2UgPT09IHRydWUgPyAtMTowXCIgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiAoY2xpY2spPVwicGFnZSA9PT0gdHJ1ZSA/ICcnOmdlbmVyaWNUYWJsZS5nb1RvUGFnZShwYWdlKVwiPnt7cGFnZSA9PT0gdHJ1ZSA/ICcmaGVsbGlwOyc6cGFnZX19PC9hPjwvbGk+XG5cdFx0XHRcdDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiIFtuZ0NsYXNzXT1cInsnZGlzYWJsZWQnIDogZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlVG90YWwgfHwgZ2VuZXJpY1RhYmxlLmxvYWRpbmcgfVwiPjxhIGNsYXNzPVwicGFnZS1saW5rIGd0LWxpbmtcIiBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApO1wiIChjbGljayk9XCJnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VDdXJyZW50ICE9PSBnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VUb3RhbCAmJiBnZW5lcmljVGFibGUubmV4dFBhZ2UoKVwiIFthdHRyLmFyaWEtbGFiZWxdPVwiZ2VuZXJpY1RhYmxlLmd0VGV4dHMucGFnaW5hdGVOZXh0XCI+PHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnJhcXVvOzwvc3Bhbj48c3BhbiBjbGFzcz1cInNyLW9ubHlcIj57e2dlbmVyaWNUYWJsZS5ndFRleHRzLnBhZ2luYXRlTmV4dH19PC9zcGFuPjwvYT48L2xpPlxuXHRcdFx0PC91bD5cblx0XHQ8L25hdj5cbiAgYCxcblx0c3R5bGVzOiBbYC5ndC1saW5rIHtjdXJzb3I6IHBvaW50ZXI7fWBdXG59KVxuZXhwb3J0IGNsYXNzIEd0UGFnaW5hdGlvbkNvbXBvbmVudCB7XG5cdGdldCBnZW5lcmljVGFibGUoKTogR2VuZXJpY1RhYmxlQ29tcG9uZW50PGFueSwgYW55PiB7XG5cdFx0cmV0dXJuIHRoaXMuX2dlbmVyaWNUYWJsZTtcblx0fVxuXG5cdEBJbnB1dCgpXG5cdHNldCBnZW5lcmljVGFibGUodmFsdWU6IEdlbmVyaWNUYWJsZUNvbXBvbmVudDxhbnksIGFueT4pIHtcblx0XHRpZiAodmFsdWUpIHtcblx0XHRcdHZhbHVlLmd0RXZlbnQuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuXHRcdFx0XHRpZiAocmVzLm5hbWUgPT09ICdndC1pbmZvJyAmJiByZXMudmFsdWUucGFnZVRvdGFsID4gMCkge1xuXHRcdFx0XHRcdHRoaXMucmVhZHkgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0dGhpcy5fZ2VuZXJpY1RhYmxlID0gdmFsdWU7XG5cdH1cblxuXHRwcml2YXRlIF9nZW5lcmljVGFibGU6IEdlbmVyaWNUYWJsZUNvbXBvbmVudDxhbnksIGFueT47XG5cdEBJbnB1dCgpIGd0Q2xhc3Nlczogc3RyaW5nO1xuXHRwdWJsaWMgcmVhZHkgPSBmYWxzZTtcbn1cbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEdlbmVyaWNUYWJsZUNvbXBvbmVudCB9IGZyb20gJy4uL2dlbmVyaWMtdGFibGUvZ2VuZXJpYy10YWJsZS5jb21wb25lbnQnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFBhZ2luYXRpb25QaXBlJ1xufSlcbmV4cG9ydCBjbGFzcyBQYWdpbmF0aW9uUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHR0cmFuc2Zvcm0odG90YWxQYWdlczogbnVtYmVyLCBjdXJyZW50UGFnZTogbnVtYmVyKTogQXJyYXk8YW55PiB7XG5cdFx0aWYgKHRvdGFsUGFnZXMgPT09IDApIHtcblx0XHRcdHJldHVybiBbMV07XG5cdFx0fVxuXHRcdGNvbnN0IHBhZ2luYXRpb246IEFycmF5PGFueT4gPSBbXTsgLy8gY3JlYXRlIG5ldyBlbXB0eSBhcnJheSBmb3IgcGFnaW5hdGlvblxuXHRcdGNvbnN0IHNpYmxpbmdzID0gMjsgLy8gc2libGluZyBlbGVtZW50cyBpZS4gbnVtYmVyIG9mIGVsZW1lbnRzIG9uIGVhY2ggc2lkZSBvZiBjdXJyZW50IHBhZ2Vcblx0XHRjb25zdCBwYWdpbmF0aW9uTGVuZ3RoID1cblx0XHRcdHRvdGFsUGFnZXMgPCBzaWJsaW5ncyAqIDIgKyAxID8gdG90YWxQYWdlcyA6IHNpYmxpbmdzICogMiArIDE7IC8vIG51bWJlciBvZiBlbGVtZW50cyBpbiBwYWdpbmF0aW9uIGFycmF5XG5cdFx0Y29uc3Qgc3RhcnQgPSBjdXJyZW50UGFnZSA8PSBzaWJsaW5ncyA/IDEgOiBjdXJyZW50UGFnZSAtIHNpYmxpbmdzOyAvLyBzdGFydGluZyBwb3NpdGlvbiBmb3IgYXJyYXlcblx0XHRjb25zdCBtb2RpZmllciA9XG5cdFx0XHR0b3RhbFBhZ2VzIC0gKGN1cnJlbnRQYWdlICsgc2libGluZ3MpIDw9IDBcblx0XHRcdFx0PyB0b3RhbFBhZ2VzIC0gKGN1cnJlbnRQYWdlICsgc2libGluZ3MpXG5cdFx0XHRcdDogMDsgLy8gbW9kaWZpZXIgZm9yIHBhZ2luYXRpb24gdmFsdWVzXG5cdFx0Y29uc3QgbW9kaWZpZWRQb3NpdGlvbiA9IHN0YXJ0ICsgbW9kaWZpZXIgPD0gMCA/IDEgOiBzdGFydCArIG1vZGlmaWVyO1xuXG5cdFx0Ly8gcHVzaCBwYWdlcyB0byBwYWdpbmF0aW9uIGFycmF5XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBwYWdpbmF0aW9uTGVuZ3RoOyBpKyspIHtcblx0XHRcdHBhZ2luYXRpb24ucHVzaChtb2RpZmllZFBvc2l0aW9uICsgaSk7XG5cdFx0fVxuXG5cdFx0Ly8gaWYgZmlyc3QgcGFnZSBpcyBub3QgaW5jbHVkZWQgaW4gcGFnaW5hdGlvbi4uLlxuXHRcdGlmIChwYWdpbmF0aW9uLmluZGV4T2YoMSkgPT09IC0xKSB7XG5cdFx0XHQvLyAuLi5jaGVjayBpZiBzZWNvbmQgcGFnZSBpcyBpbiBwYWdpbmF0aW9uLi4uXG5cdFx0XHRpZiAocGFnaW5hdGlvbi5pbmRleE9mKDIpID09PSAtMSkge1xuXHRcdFx0XHQvLyAuLi5pZiBub3QgY2hlY2sgaWYgdG90YWwgbnVtYmVyIG9mIHBhZ2VzIGVxdWFscyBzZXZlbiBhbmQgbnVtYmVyIG9mIHNpYmxpbmdzIGFyZSB0d28uLi5cblx0XHRcdFx0aWYgKHRvdGFsUGFnZXMgPT09IDcgJiYgc2libGluZ3MgPT09IDIpIHtcblx0XHRcdFx0XHQvLyAuLi5hZGQgc2Vjb25kIHBhZ2UgYW5kIGRvbid0IGNvbnZlcnQgcGFnZSBudW1iZXIgdG8gZWxsaXBzaXNcblx0XHRcdFx0XHRwYWdpbmF0aW9uLnVuc2hpZnQoMik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCB1c2UgdGhpcyBwbGFjZWhvbGRlciBmb3IgZWxsaXBzaXMgaW5zdGVhZCBvZiBhY3R1YWwgcGFnZSBudW1iZXJcblx0XHRcdFx0XHRwYWdpbmF0aW9uWzBdID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gLi4uYWRkIGZpcnN0IHBhZ2UgYXMgZmlyc3QgYXJyYXkgaXRlbVxuXHRcdFx0cGFnaW5hdGlvbi51bnNoaWZ0KDEpO1xuXHRcdH0gZWxzZSBpZiAodG90YWxQYWdlcyA+IHBhZ2luYXRpb25MZW5ndGgpIHtcblx0XHRcdC8vIGlmIGZpcnN0IHBhZ2UgaXMgaW5jbHVkZWQgYWRkIGV4dHJhIHBhZ2UgdG8ga2VlcCBudW1iZXIgb2YgaXRlbXMgY29uc2lzdGVudFxuXHRcdFx0cGFnaW5hdGlvbi5zcGxpY2UocGFnaW5hdGlvbkxlbmd0aCwgMCwgcGFnaW5hdGlvbkxlbmd0aCArIDEpO1xuXHRcdH1cblx0XHQvLyBjaGVjayBpZiBsYXN0IHBhZ2UgaXMgaW5jbHVkZWQgaW4gcGFnaW5hdGlvbi4uLlxuXHRcdGlmIChwYWdpbmF0aW9uLmluZGV4T2YodG90YWxQYWdlcykgPT09IC0xKSB7XG5cdFx0XHQvLyAuLi5pZiBub3QsIHBhZ2UgbmV4dCB0byBsYXN0IHNob3VsZCBlaXRoZXIgc2hvdyBlbGxpcHNpcyBvciBhY3R1YWwgcGFnZSBudW1iZXIgZm9yIHRoZSBwYWdlXG5cdFx0XHRwYWdpbmF0aW9uW3BhZ2luYXRpb24ubGVuZ3RoIC0gMV0gPVxuXHRcdFx0XHRwYWdpbmF0aW9uW3BhZ2luYXRpb24ubGVuZ3RoIC0gMV0gPT09IHRvdGFsUGFnZXMgLSAxXG5cdFx0XHRcdFx0PyB0b3RhbFBhZ2VzIC0gMVxuXHRcdFx0XHRcdDogdHJ1ZTtcblxuXHRcdFx0Ly8gLi4uYWRkIGxhc3QgcGFnZSB0byBwYWdpbmF0aW9uXG5cdFx0XHRwYWdpbmF0aW9uLnB1c2godG90YWxQYWdlcyk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBhZ2luYXRpb247XG5cdH1cbn1cbiIsImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcbmltcG9ydCB7IEd0Q29uZmlnU2V0dGluZyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLXNldHRpbmcnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IEd0RXZlbnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWV2ZW50JztcblxuZXhwb3J0IGNsYXNzIEd0RXhwYW5kZWRSb3c8UiBleHRlbmRzIEd0Um93PiB7XG5cdHJvdzogUjtcblx0Y29sdW1uV2lkdGg6IE9iamVjdDtcblx0Z3RTZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPjtcblx0Z3RGaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8UiwgYW55Pj47XG5cdGd0T3B0aW9uczogYW55O1xuXHRndEluZm86IGFueTtcblx0ZGF0YTogYW55O1xuXHRyZWRyYXdFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Uj4oKTtcblx0Z3RFdmVudDogRXZlbnRFbWl0dGVyPEd0RXZlbnQ+O1xuXHR0b2dnbGVSb3dFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Uj4oKTtcblxuXHRwdWJsaWMgJGhpZGUoKTogdm9pZCB7XG5cdFx0dGhpcy50b2dnbGVSb3dFdmVudC5lbWl0KHRoaXMucm93KTtcblx0fVxuXG5cdHB1YmxpYyAkcmVkcmF3KCRldmVudD86IGFueSk6IHZvaWQge1xuXHRcdHRoaXMucmVkcmF3RXZlbnQuZW1pdCh0aGlzLnJvdyk7XG5cdH1cblx0cHVibGljICRyb3dDbGljayhyb3c6IEd0Um93LCAkZXZlbnQ6IE1vdXNlRXZlbnQpIHtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtcm93LWNsaWNrZWQnLFxuXHRcdFx0dmFsdWU6IHsgcm93OiByb3csIGV2ZW50OiAkZXZlbnQgfVxuXHRcdH0pO1xuXHR9XG59XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWV4cGFuZGluZy1yb3cnLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxkaXYgZ3RDb21wb25lbnRBbmNob3Jcblx0XHRcdCBbY3Rvcl09XCJ0eXBlXCIgKGluc3RhbmNlKT1cIm5ld0luc3RhbmNlKCRldmVudClcIj48L2Rpdj5cbiAgYCxcblx0c3R5bGVzOiBbXVxufSlcbmV4cG9ydCBjbGFzcyBHdEV4cGFuZGluZ1Jvd0NvbXBvbmVudDxcblx0UiBleHRlbmRzIEd0Um93LFxuXHRDIGV4dGVuZHMgR3RFeHBhbmRlZFJvdzxSPlxuPiB7XG5cdEBJbnB1dCgpIHR5cGU6IFR5cGU8Qz47XG5cdEBJbnB1dCgpIHJvdzogUjtcblx0QElucHV0KCkgY29sdW1uV2lkdGg6IE9iamVjdDtcblx0QElucHV0KCkgZ3RTZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPjtcblx0QElucHV0KCkgZ3RGaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8UiwgYW55Pj47XG5cdEBJbnB1dCgpIGd0T3B0aW9uczogYW55O1xuXHRASW5wdXQoKSBndEluZm86IGFueTtcblx0QElucHV0KCkgZGF0YTogYW55O1xuXG5cdEBPdXRwdXQoKSByZWRyYXdFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Uj4oKTtcblx0QE91dHB1dCgpIHRvZ2dsZVJvd0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxSPigpO1xuXHRASW5wdXQoKSBndEV2ZW50OiBhbnk7XG5cblx0bmV3SW5zdGFuY2UoaW5zdGFuY2U6IEMpOiB2b2lkIHtcblx0XHRpbnN0YW5jZS5yb3cgPSB0aGlzLnJvdztcblx0XHRpbnN0YW5jZS5jb2x1bW5XaWR0aCA9IHRoaXMuY29sdW1uV2lkdGg7XG5cdFx0aW5zdGFuY2UuZ3RTZXR0aW5ncyA9IHRoaXMuZ3RTZXR0aW5ncztcblx0XHRpbnN0YW5jZS5ndEZpZWxkcyA9IHRoaXMuZ3RGaWVsZHM7XG5cdFx0aW5zdGFuY2UuZ3RPcHRpb25zID0gdGhpcy5ndE9wdGlvbnM7XG5cdFx0aW5zdGFuY2UuZ3RJbmZvID0gdGhpcy5ndEluZm87XG5cdFx0aW5zdGFuY2UuZGF0YSA9XG5cdFx0XHR0eXBlb2YgdGhpcy5kYXRhID09PSAnZnVuY3Rpb24nID8gdGhpcy5kYXRhKHRoaXMucm93KSA6IHRoaXMuZGF0YTtcblx0XHRpbnN0YW5jZS5yZWRyYXdFdmVudC5zdWJzY3JpYmUodGhpcy5yZWRyYXdFdmVudCk7XG5cdFx0aW5zdGFuY2UudG9nZ2xlUm93RXZlbnQuc3Vic2NyaWJlKHRoaXMudG9nZ2xlUm93RXZlbnQpO1xuXHRcdGluc3RhbmNlLmd0RXZlbnQgPSB0aGlzLmd0RXZlbnQ7XG5cdH1cbn1cbiIsImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0RXZlbnRFbWl0dGVyLFxuXHRJbnB1dCxcblx0T25EZXN0cm95LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0UmVuZGVyZXIyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0ICogYXMgVGV0aGVyIGZyb20gJ3RldGhlcic7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWRyb3Bkb3duJyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGNsYXNzPVwiZHJvcGRvd24gZ3QtZHJvcGRvd25cIiBbbmdDbGFzc109XCJ7J3Nob3cnOmFjdGl2ZX1cIiBbYXR0ci5pZF09XCJpZFwiPlxuXHRcdFx0PGRpdiBjbGFzcz1cImRyb3Bkb3duLXRvZ2dsZVwiIChjbGljayk9XCJ0b2dnbGVEcm9wZG93bigpXCIgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJhY3RpdmVcIj57e3NlbGVjdGVkfX08L2Rpdj5cblx0XHRcdDxkaXYgY2xhc3M9XCJndC1kcm9wZG93bi1tZW51IGRyb3Bkb3duLW1lbnVcIiAqbmdJZj1cImFjdGl2ZVwiIFtuZ0NsYXNzXT1cInsnc2hvdyc6YWN0aXZlfVwiIFthdHRyLmlkXT1cImlkKydfbWVudSdcIj5cblx0XHRcdFx0PGJ1dHRvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIG9wdGlvbnM7XCIgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgKGNsaWNrKT1cInNlbGVjdChvcHRpb24pXCIgW25nQ2xhc3NdPVwieydhY3RpdmUnOm9wdGlvbiA9PT0gc2VsZWN0ZWR9XCI+e3tvcHRpb259fTwvYnV0dG9uPlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+XG4gIGAsXG5cdHN0eWxlczogW1xuXHRcdGBcblx0XHQuZ3QtZHJvcGRvd24gLmRyb3Bkb3duLXRvZ2dsZSB7XG5cdFx0XHRjdXJzb3I6IHBvaW50ZXI7XG5cdFx0fVxuXHRcdC5ndC1kcm9wZG93biAuZHJvcGRvd24tdG9nZ2xlOjphZnRlciB7XG5cdFx0XHR0cmFuc2l0aW9uOiBvcGFjaXR5IDAuNHMgZWFzZS1pbi1vdXQ7XG5cdFx0XHRvcGFjaXR5OiAwO1xuXHRcdH1cblx0XHQuZ3QtZHJvcGRvd24gLmRyb3Bkb3duLXRvZ2dsZTpob3Zlcjo6YWZ0ZXIge1xuXHRcdFx0b3BhY2l0eTogMTtcblx0XHR9XG5cdGBcblx0XVxufSlcbmV4cG9ydCBjbGFzcyBHdERyb3Bkb3duQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXHRnZXQgc2VsZWN0ZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkO1xuXHR9XG5cblx0X3NlbGVjdGVkOiBhbnk7XG5cdEBJbnB1dCgpXG5cdHNldCBzZWxlY3RlZChzZWxlY3Rpb24pIHtcblx0XHR0aGlzLl9zZWxlY3RlZCA9IHNlbGVjdGlvbjtcblx0fVxuXHRASW5wdXQoKSBvcHRpb25zOiBBcnJheTxhbnk+O1xuXHRASW5wdXQoKSBpZDogc3RyaW5nO1xuXHRAT3V0cHV0KCkgc2VsZWN0ZWRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdGFjdGl2ZSA9IGZhbHNlOyAvLyBpcyBkcm9wZG93biBhY3RpdmUgb3Igbm90XG5cdHN0YXRlOiBTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IFN1YmplY3QoKTsgLy8gY3VycmVudCBzdGF0ZSBvZiBkcm9wZG93blxuXHR0ZXRoZXI6IGFueTtcblx0Y2xpY2tMaXN0ZW5lcjogRnVuY3Rpb247XG5cdGtleXVwTGlzdGVuZXI6IEZ1bmN0aW9uO1xuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cblxuXHRzZWxlY3Qob3B0aW9uOiBhbnkpIHtcblx0XHR0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuXHRcdHRoaXMuc3RhdGUubmV4dCh0aGlzLmFjdGl2ZSk7XG5cdFx0aWYgKHRoaXMuX3NlbGVjdGVkICE9PSBvcHRpb24pIHtcblx0XHRcdHRoaXMuc2VsZWN0ZWRDaGFuZ2UuZW1pdChvcHRpb24pO1xuXHRcdH1cblx0fVxuXG5cdHRvZ2dsZURyb3Bkb3duKCkge1xuXHRcdHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0dGhpcy5zdGF0ZS5uZXh0KHRoaXMuYWN0aXZlKTtcblx0XHR9LCAwKTtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuc3RhdGUuc3Vic2NyaWJlKHN0YXRlID0+IHtcblx0XHRcdGlmIChzdGF0ZSkge1xuXHRcdFx0XHR0aGlzLnRldGhlciA9IG5ldyBUZXRoZXIoe1xuXHRcdFx0XHRcdGVsZW1lbnQ6ICcjJyArIHRoaXMuaWQgKyAnX21lbnUnLFxuXHRcdFx0XHRcdHRhcmdldDogJyMnICsgdGhpcy5pZCxcblx0XHRcdFx0XHRhdHRhY2htZW50OiAndG9wIGxlZnQnLFxuXHRcdFx0XHRcdHRhcmdldEF0dGFjaG1lbnQ6ICdib3R0b20gbGVmdCcsXG5cdFx0XHRcdFx0Y29uc3RyYWludHM6IFtcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0dG86ICd3aW5kb3cnLFxuXHRcdFx0XHRcdFx0XHRhdHRhY2htZW50OiAndG9nZXRoZXInXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHR0aGlzLnRldGhlci5wb3NpdGlvbigpO1xuXG5cdFx0XHRcdC8vIHNldCB1cCBjbGljayBsaXN0ZW5lciBhbmQgbGlzdGVuIGZvciBjbGljayBvdXRzaWRlIGRyb3Bkb3duXG5cdFx0XHRcdHRoaXMuY2xpY2tMaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKFxuXHRcdFx0XHRcdCdkb2N1bWVudCcsXG5cdFx0XHRcdFx0J2NsaWNrJyxcblx0XHRcdFx0XHQoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdFx0XHRcdFx0XHR0aGlzLnN0YXRlLm5leHQodGhpcy5hY3RpdmUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0KTtcblxuXHRcdFx0XHQvLyBzZXQgdXAga2V5Ym9hcmQgbGlzdGVuZXIgYW5kIGxpc3RlbiBmb3IgZXNjYXBlIGtleSB1cFxuXHRcdFx0XHR0aGlzLmtleXVwTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihcblx0XHRcdFx0XHQnZG9jdW1lbnQnLFxuXHRcdFx0XHRcdCdrZXl1cCcsXG5cdFx0XHRcdFx0KGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0XHRzd2l0Y2ggKGV2ZW50LmtleSkge1xuXHRcdFx0XHRcdFx0XHRjYXNlICdFc2NhcGUnOlxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zdGF0ZS5uZXh0KHRoaXMuYWN0aXZlKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnRldGhlci5kZXN0cm95KCk7XG5cdFx0XHRcdHRoaXMucmVtb3ZlTGlzdGVuZXJzKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVycygpO1xuXHR9XG5cblx0cmVtb3ZlTGlzdGVuZXJzKCkge1xuXHRcdGlmICh0aGlzLmNsaWNrTGlzdGVuZXIpIHtcblx0XHRcdHRoaXMuY2xpY2tMaXN0ZW5lcigpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5rZXl1cExpc3RlbmVyKSB7XG5cdFx0XHR0aGlzLmtleXVwTGlzdGVuZXIoKTtcblx0XHR9XG5cdH1cbn1cbiIsImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdEV4cGFuZGVkUm93IH0gZnJvbSAnLi4vZ3QtZXhwYW5kaW5nLXJvdy9ndC1leHBhbmRpbmctcm93LmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWRyaWxsZG93bicsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PHRhYmxlIGNsYXNzPVwidGFibGVcIj5cblx0XHRcdDx0ciAqbmdGb3I9XCJsZXQgcm93IG9mIGRhdGFcIiAoY2xpY2spPVwiJHJvd0NsaWNrKHJvdywgJGV2ZW50KVwiPlxuXHRcdFx0XHQ8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiByb3cgfCBndFJlbmRlcjpndFNldHRpbmdzOmd0RmllbGRzOm51bGw6bnVsbDpndE9wdGlvbnMuaGlnaGxpZ2h0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtcztcIlxuXHRcdFx0XHRcdG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID8gJ2d0LWlubGluZS1lZGl0JzonJ319IHt7Y29sdW1uLmVkaXRlZCA/ICdndC1lZGl0ZWQnOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOnJvdzpjb2x1bW4gfX1cIiBbc3R5bGUud2lkdGhdPVwiY29sdW1uV2lkdGhbY29sdW1uLm9iamVjdEtleV1cIiBbc3R5bGUubWF4LXdpZHRoXT1cImNvbHVtbldpZHRoW2NvbHVtbi5vYmplY3RLZXldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImd0LXJvdy1sYWJlbFwiXG5cdFx0XHRcdFx0XHRcdCAgKm5nSWY9XCJndE9wdGlvbnMuc3RhY2tcIj57eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA6IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfX08L3NwYW4+XG5cdFx0XHRcdFx0PGd0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeSAqbmdJZj1cImNvbHVtbi5jb2x1bW5Db21wb25lbnRcIiBjbGFzcz1cImd0LXJvdy1jb250ZW50XCJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCBbdHlwZV09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGVcIlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IFtpbmplY3Rvcl09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LmluamVjdG9yXCIgW3Jvd109XCJyb3dcIlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IFtjb2x1bW5dPVwiY29sdW1uXCIgKHJlZHJhd0V2ZW50KT1cIiRyZWRyYXcoJGV2ZW50KVwiXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKGNsaWNrKT1cImNvbHVtbi5jbGljayA/IGNvbHVtbi5jbGljayhyb3csY29sdW1uLCRldmVudCk6Jyc7XCI+PC9ndC1jdXN0b20tY29tcG9uZW50LWZhY3Rvcnk+XG5cdFx0XHRcdFx0PHNwYW4gKm5nSWY9XCIhY29sdW1uLmNvbHVtbkNvbXBvbmVudFwiXG5cdFx0XHRcdFx0XHQgIGNsYXNzPVwiZ3Qtcm93LWNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiXG5cdFx0XHRcdFx0XHQgIChjbGljayk9XCJjb2x1bW4uY2xpY2sgPyBjb2x1bW4uY2xpY2socm93LGNvbHVtbiwkZXZlbnQpOicnXCI+PC9zcGFuPlxuXHRcdFx0XHQ8L3RkPlxuXG5cdFx0XHQ8L3RyPlxuXHRcdDwvdGFibGU+XG4gIGAsXG5cdHN0eWxlczogW11cbn0pXG5leHBvcnQgY2xhc3MgR3REcmlsbGRvd25Db21wb25lbnQgZXh0ZW5kcyBHdEV4cGFuZGVkUm93PGFueT4gaW1wbGVtZW50cyBPbkluaXQge1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0bmdPbkluaXQoKSB7fVxufVxuIiwiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRFdmVudEVtaXR0ZXIsXG5cdEluamVjdG9yLFxuXHRJbnB1dCxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFR5cGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBHdEN1c3RvbUNvbXBvbmVudDxSPiBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cdHJvdzogUjtcblx0Y29sdW1uOiBhbnk7XG5cdHJlZHJhd0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx7IHJvdzogUjsgY29sdW1uOiBhbnkgfT4oKTtcblx0c2VhcmNoVGVybXM6IHN0cmluZztcblx0JHNlYXJjaFRlcm1zOiBSZXBsYXlTdWJqZWN0PHN0cmluZz4gPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuXHRwcm90ZWN0ZWQgJHJlZHJhdygkZXZlbnQ/OiBhbnkpIHtcblx0XHR0aGlzLnJlZHJhd0V2ZW50LmVtaXQoeyByb3c6IHRoaXMucm93LCBjb2x1bW46IHRoaXMuY29sdW1uIH0pO1xuXHR9XG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuJHNlYXJjaFRlcm1zLnN1YnNjcmliZSh0ZXJtcyA9PiAodGhpcy5zZWFyY2hUZXJtcyA9IHRlcm1zKSk7XG5cdH1cbn1cblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5Jyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGd0Q29tcG9uZW50QW5jaG9yIFtjdG9yXT1cInR5cGVcIlxuXHRcdFx0IFtpbmplY3Rvcl09XCJpbmplY3RvclwiXG5cdFx0XHQgKGluc3RhbmNlKT1cImluc3RhbmNlKCRldmVudClcIj48L2Rpdj5cblx0YFxufSlcbmV4cG9ydCBjbGFzcyBHdEN1c3RvbUNvbXBvbmVudEZhY3Rvcnk8UiwgQyBleHRlbmRzIEd0Q3VzdG9tQ29tcG9uZW50PFI+PiB7XG5cdEBJbnB1dCgpXG5cdHNldCBzZWFyY2hUZXJtcyh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy4kc2VhcmNoVGVybXMubmV4dCh2YWx1ZSk7XG5cdH1cblx0QElucHV0KCkgdHlwZTogVHlwZTxDPjtcblx0QElucHV0KCkgaW5qZWN0b3I6IEluamVjdG9yO1xuXHRASW5wdXQoKSByb3c6IFI7XG5cdEBJbnB1dCgpIGNvbHVtbjogYW55O1xuXHQkc2VhcmNoVGVybXM6IFJlcGxheVN1YmplY3Q8c3RyaW5nPiA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXHRAT3V0cHV0KCkgcmVkcmF3RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcm93OiBSOyBjb2x1bW46IGFueSB9PigpO1xuXG5cdGluc3RhbmNlKGluc3RhbmNlOiBDKSB7XG5cdFx0aW5zdGFuY2Uucm93ID0gdGhpcy5yb3c7XG5cdFx0aW5zdGFuY2UuY29sdW1uID0gdGhpcy5jb2x1bW47XG5cdFx0aW5zdGFuY2UuJHNlYXJjaFRlcm1zID0gdGhpcy4kc2VhcmNoVGVybXM7XG5cdFx0aW5zdGFuY2UucmVkcmF3RXZlbnQuc3Vic2NyaWJlKHRoaXMucmVkcmF3RXZlbnQpO1xuXHR9XG59XG4iLCJpbXBvcnQge1xuXHRDb21wb25lbnQsXG5cdEV2ZW50RW1pdHRlcixcblx0SG9zdEJpbmRpbmcsXG5cdElucHV0LFxuXHRPbkluaXQsXG5cdE91dHB1dFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnZ3QtY2hlY2tib3gnLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxsYWJlbCBjbGFzcz1cImN1c3RvbS1jb250cm9sIGN1c3RvbS1jaGVja2JveCBwLTBcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG5cdFx0XHQ8aW5wdXQgI2NoZWNrYm94IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiY3VzdG9tLWNvbnRyb2wtaW5wdXRcIiBbKGNoZWNrZWQpXT1cImNoZWNrZWRcIiAoY2hhbmdlKT1cInRvZ2dsZSgkZXZlbnQpO1wiPlxuXHRcdFx0PHNwYW4gY2xhc3M9XCJjdXN0b20tY29udHJvbC1sYWJlbFwiPjwvc3Bhbj5cblx0XHQ8L2xhYmVsPlxuICBgLFxuXHRzdHlsZXM6IFtdXG59KVxuZXhwb3J0IGNsYXNzIEd0Q2hlY2tib3hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXHRnZXQgaW5pdGlhbFZhbHVlKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLl9pbml0aWFsVmFsdWU7XG5cdH1cblxuXHRASG9zdEJpbmRpbmcoJ2NsYXNzJykgY2xhc3MgPSAnZC1mbGV4IGp1c3RpZnktY29udGVudC1lbmQnO1xuXG5cdEBJbnB1dCgpXG5cdHNldCBpbml0aWFsVmFsdWUodmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl9pbml0aWFsVmFsdWUgPSB2YWx1ZTtcblx0fVxuXHRnZXQgY2hlY2tlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fY2hlY2tlZDtcblx0fVxuXG5cdEBJbnB1dCgpXG5cdHNldCBjaGVja2VkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fY2hlY2tlZCA9IHZhbHVlO1xuXHR9XG5cblx0cHJpdmF0ZSBfY2hlY2tlZDogYm9vbGVhbjtcblx0cHJpdmF0ZSBfaW5pdGlhbFZhbHVlOiBib29sZWFuO1xuXHRAT3V0cHV0KCkgY2hhbmdlZDogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdGNvbnN0cnVjdG9yKCkge31cblxuXHRuZ09uSW5pdCgpIHt9XG5cblx0dG9nZ2xlKGNoZWNrZWQ6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmNoYW5nZWQuZW1pdCh0aGlzLmNoZWNrZWQpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdENvbmZpZ0ZpZWxkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctZmllbGQnO1xuaW1wb3J0IHsgR3RDb25maWdTZXR0aW5nIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctc2V0dGluZyc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RWaXNpYmxlJ1xufSlcbmV4cG9ydCBjbGFzcyBHdFZpc2libGVQaXBlPFIgZXh0ZW5kcyBHdFJvdz4gaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0Ly8gVE9ETzogbW92ZSB0byBoZWxwZXIgZnVuY3Rpb25zXG5cdC8qKiBTb3J0IGJ5IGNvbHVtbiBvcmRlciAqL1xuXHRwcml2YXRlIGdldENvbHVtbk9yZGVyID0gZnVuY3Rpb24oYTogYW55LCBiOiBhbnkpIHtcblx0XHRpZiAoYS5jb2x1bW5PcmRlciA8IGIuY29sdW1uT3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPiBiLmNvbHVtbk9yZGVyIHx8IHR5cGVvZiBhLmNvbHVtbk9yZGVyID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdHRyYW5zZm9ybShcblx0XHRhcnJheTogQXJyYXk8YW55Pixcblx0XHRzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPixcblx0XHRyZWZyZXNoUGlwZT86IGJvb2xlYW5cblx0KTogQXJyYXk8R3RDb25maWdGaWVsZDxSLCBhbnk+PiB8IEFycmF5PEd0Q29uZmlnU2V0dGluZz4ge1xuXHRcdGNvbnN0IHZpc2libGVDb2x1bW5zID0gc2V0dGluZ3Ncblx0XHRcdC5zb3J0KHRoaXMuZ2V0Q29sdW1uT3JkZXIpXG5cdFx0XHQubWFwKChzZXR0aW5nOiBHdENvbmZpZ1NldHRpbmcpID0+IHtcblx0XHRcdFx0aWYgKHNldHRpbmcudmlzaWJsZSAhPT0gZmFsc2UgJiYgc2V0dGluZy5lbmFibGVkICE9PSBmYWxzZSkge1xuXHRcdFx0XHRcdHJldHVybiBzZXR0aW5nLm9iamVjdEtleTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRyZXR1cm4gYXJyYXlcblx0XHRcdC5maWx0ZXIoKGNvbHVtbjogYW55KSA9PiB7XG5cdFx0XHRcdHJldHVybiB2aXNpYmxlQ29sdW1ucy5pbmRleE9mKGNvbHVtbi5vYmplY3RLZXkpICE9PSAtMTtcblx0XHRcdH0pXG5cdFx0XHQuc29ydChmdW5jdGlvbihhLCBiKSB7XG5cdFx0XHRcdHJldHVybiB2aXNpYmxlQ29sdW1ucy5pbmRleE9mKGEub2JqZWN0S2V5KSA8XG5cdFx0XHRcdFx0dmlzaWJsZUNvbHVtbnMuaW5kZXhPZihiLm9iamVjdEtleSlcblx0XHRcdFx0XHQ/IC0xXG5cdFx0XHRcdFx0OiAxO1xuXHRcdFx0fSk7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcbmltcG9ydCB7IEd0Q29uZmlnU2V0dGluZyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLXNldHRpbmcnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFNlYXJjaCdcbn0pXG5leHBvcnQgY2xhc3MgR3RTZWFyY2hQaXBlPFIgZXh0ZW5kcyBHdFJvdz4gaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0LyoqIFJldHVybiBwcm9wZXJ0eSAqL1xuXHRwcml2YXRlIGdldFByb3BlcnR5ID0gZnVuY3Rpb24oYXJyYXk6IEFycmF5PGFueT4sIGtleTogc3RyaW5nKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycmF5W2ldLm9iamVjdEtleSA9PT0ga2V5KSB7XG5cdFx0XHRcdHJldHVybiBhcnJheVtpXTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0dHJhbnNmb3JtKFxuXHRcdGFsbFJvd3M6IGFueSxcblx0XHRzZWFyY2hUZXJtczogc3RyaW5nLFxuXHRcdGd0SW5mbzogR3RJbmZvcm1hdGlvbixcblx0XHRzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPixcblx0XHRmaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8UiwgYW55Pj4sXG5cdFx0cmVmcmVzaERhdGE6IG51bWJlclxuXHQpOiBhbnkge1xuXHRcdC8vICBpZiBubyBzZWFyY2ggdGVybXMgYXJlIGRlZmluZWQuLi5cblx0XHRpZiAoIXNlYXJjaFRlcm1zIHx8IHNlYXJjaFRlcm1zLnJlcGxhY2UoL1wiL2csICcnKS5sZW5ndGggPT09IDApIHtcblx0XHRcdC8vIC4uLnJldHVybiBhbGwgcm93c1xuXHRcdFx0Y29uc3QgbGVuZ3RoID0gYWxsUm93cyA9PT0gbnVsbCA/IDAgOiBhbGxSb3dzLmxlbmd0aDtcblx0XHRcdGd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2ggPSBsZW5ndGg7XG5cdFx0XHRyZXR1cm4gYWxsUm93cztcblx0XHR9XG5cblx0XHRjb25zdCBzZWFyY2hGdW5jdGlvbjogYW55ID0ge307XG5cdFx0Y29uc3QgZmllbGRzVGVtcDogQXJyYXk8YW55PiA9IFtdO1xuXG5cdFx0Zm9yIChsZXQgayA9IDA7IGsgPCBmaWVsZHMubGVuZ3RoOyBrKyspIHtcblx0XHRcdGNvbnN0IGZpZWxkID0gZmllbGRzW2tdO1xuXG5cdFx0XHQvLyBjaGVjayBpZiBmaWVsZCBzaG91bGQgYmUgaW5jbHVkZWQgaW4gZ2xvYmFsIHNlYXJjaFxuXHRcdFx0Y29uc3QgaW5jbHVkZSA9XG5cdFx0XHRcdHRoaXMuZ2V0UHJvcGVydHkoc2V0dGluZ3MsIGZpZWxkLm9iamVjdEtleSkuc2VhcmNoID09PSBmYWxzZVxuXHRcdFx0XHRcdD8gZmFsc2Vcblx0XHRcdFx0XHQ6IHRydWU7XG5cblx0XHRcdC8vIGlmIGluY2x1ZGUuLi5cblx0XHRcdGlmIChpbmNsdWRlKSB7XG5cdFx0XHRcdC8vIC4uLmFuZCBpZiBzZWFyY2ggZnVuY3Rpb24gaXMgZGVmaW5lZC4uLlxuXHRcdFx0XHRpZiAodHlwZW9mIGZpZWxkLnNlYXJjaCA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdC8vIC4uLmFkZCBpdCBhcyBzZWFyY2ggZnVuY3Rpb24gZm9yIGZpZWxkXG5cdFx0XHRcdFx0c2VhcmNoRnVuY3Rpb25bZmllbGQub2JqZWN0S2V5XSA9IGZpZWxkLnNlYXJjaDtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyAuLi5pZiBubyBzZWFyY2ggZnVuY3Rpb24gaXMgZGVmaW5lZCBidXQgdmFsdWUgZnVuY3Rpb24gaXMgZGVmaW5lZC4uLlxuXHRcdFx0XHRlbHNlIGlmICh0eXBlb2YgZmllbGQudmFsdWUgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHQvLyAuLi5hZGQgaXQgYXMgc2VhcmNoIGZ1bmN0aW9uIGZvciBmaWVsZFxuXHRcdFx0XHRcdHNlYXJjaEZ1bmN0aW9uW2ZpZWxkLm9iamVjdEtleV0gPSBmaWVsZC52YWx1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIC4uLnB1c2ggaXQgdG8gb3VyIGZpZWxkcyBhcnJheVxuXHRcdFx0XHRmaWVsZHNUZW1wLnB1c2goZmllbGQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IGZpbHRlcmVkUm93czogQXJyYXk8YW55PiA9IFtdO1xuXHRcdHNlYXJjaFRlcm1zID0gdHlwZW9mIHNlYXJjaFRlcm1zID09PSAndW5kZWZpbmVkJyA/ICcnIDogc2VhcmNoVGVybXM7XG5cdFx0Y29uc3Qgc2VhcmNoVGVybXNBcnJheSA9IHNlYXJjaFRlcm1zLnRvTG93ZXJDYXNlKCkubWF0Y2goLyhcIi4qXCJ8W15cXHNdKykvZyk7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFsbFJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHJvdyA9IGFsbFJvd3NbaV07XG5cdFx0XHRsZXQgc3RyaW5nID0gJyc7XG5cblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgZmllbGRzVGVtcC5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRjb25zdCBzZXBhcmF0b3IgPSBqID09PSAwID8gJycgOiAnICYgJztcblx0XHRcdFx0c3RyaW5nICs9IHNlYXJjaEZ1bmN0aW9uW2ZpZWxkc1RlbXBbal0ub2JqZWN0S2V5XVxuXHRcdFx0XHRcdD8gc2VwYXJhdG9yICsgc2VhcmNoRnVuY3Rpb25bZmllbGRzVGVtcFtqXS5vYmplY3RLZXldKHJvdywgailcblx0XHRcdFx0XHQ6IHNlcGFyYXRvciArIHJvd1tmaWVsZHNUZW1wW2pdLm9iamVjdEtleV07XG5cdFx0XHR9XG5cdFx0XHRzdHJpbmcgPSBzdHJpbmcudG9Mb3dlckNhc2UoKTtcblx0XHRcdGxldCBtYXRjaDogQm9vbGVhbiA9IHRydWU7XG5cblx0XHRcdGZvciAobGV0IGsgPSAwOyBrIDwgc2VhcmNoVGVybXNBcnJheS5sZW5ndGg7IGsrKykge1xuXHRcdFx0XHRjb25zdCB0ZXJtID0gc2VhcmNoVGVybXNBcnJheVtrXS5yZXBsYWNlKC9cIi9nLCAnJyk7XG5cdFx0XHRcdG1hdGNoID0gc3RyaW5nLmluZGV4T2YodGVybSkgIT09IC0xO1xuXG5cdFx0XHRcdGlmICghbWF0Y2gpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKG1hdGNoKSB7XG5cdFx0XHRcdGZpbHRlcmVkUm93cy5wdXNoKHJvdyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGd0SW5mby5yZWNvcmRzQWZ0ZXJTZWFyY2ggPSBmaWx0ZXJlZFJvd3MubGVuZ3RoO1xuXHRcdC8vIGd0SW5mby5yZWZyZXNoKGZpbHRlcmVkUm93cy5sZW5ndGgsZ3QpO1xuXHRcdHJldHVybiBmaWx0ZXJlZFJvd3M7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RJc0VkaXRhYmxlJ1xufSlcbmV4cG9ydCBjbGFzcyBHdElzRWRpdGFibGVQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShwcm9wZXJ0eTogYW55LCByb3c6IGFueSwgcmVmcmVzaFBpcGU6IGJvb2xlYW4pOiBib29sZWFuIHtcblx0XHRpZiAodHlwZW9mIHByb3BlcnR5ID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRyZXR1cm4gcHJvcGVydHkocm93KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndElzT2JzZXJ2YWJsZSdcbn0pXG5leHBvcnQgY2xhc3MgR3RJc09ic2VydmFibGVQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShpbnB1dDogYW55KTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIGlucHV0IGluc3RhbmNlb2YgT2JzZXJ2YWJsZTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlSHRtbCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndEhpZ2hsaWdodCdcbn0pXG5leHBvcnQgY2xhc3MgR3RIaWdobGlnaHRQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIpIHt9XG5cblx0dHJhbnNmb3JtKHRleHQ6IHN0cmluZywgc2VhcmNoVGVybTogc3RyaW5nKTogU2FmZUh0bWwge1xuXHRcdGNvbnN0IGhheXN0YWNrQWx3YXlzU3RyaW5nID0gdGV4dCArICcnO1xuXHRcdGxldCBoaWdobGlnaHRlZFRleHQgPSBoYXlzdGFja0Fsd2F5c1N0cmluZzsgLy8gZmFsbGJhY2tcblxuXHRcdGxldCBzZWFyY2hQYXR0ZXJuO1xuXHRcdHRyeSB7XG5cdFx0XHRzZWFyY2hQYXR0ZXJuID0gbmV3IFJlZ0V4cChcblx0XHRcdFx0JygnICtcblx0XHRcdFx0c2VhcmNoVGVybVxuXHRcdFx0XHRcdC50b0xvd2VyQ2FzZSgpXG5cdFx0XHRcdFx0Lm1hdGNoKC9cIi4qP1wifFteIF0rL2cpIC8vIGV4dHJhY3Qgd29yZHNcblx0XHRcdFx0XHQubWFwKFxuXHRcdFx0XHRcdFx0bmVlZGxlID0+IG5lZWRsZS5yZXBsYWNlKC9cIiguKj8pXCIvLCAnJDEnKSAvLyBzdHJpcCBhd2F5ICdcIidcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LmpvaW4oJ3wnKSArIC8vIGNvbWJpbmUgd29yZHNcblx0XHRcdFx0XHQnKScsXG5cdFx0XHRcdCdpZydcblx0XHRcdCk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChoaWdobGlnaHRlZFRleHQpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGNvbnRhaW5zVGFnUGF0dGVybiA9IC8oPC4qPz4pKC4qKSg8XFwvLio/PikvZ2k7XG5cdFx0Y29uc3QgY29udGFpbnNUYWdNYXRjaGVzID0gY29udGFpbnNUYWdQYXR0ZXJuLmV4ZWMoaGF5c3RhY2tBbHdheXNTdHJpbmcpO1xuXG5cdFx0aWYgKGNvbnRhaW5zVGFnTWF0Y2hlcykge1xuXHRcdFx0Ly8gdGFnIGV4aXN0cyBpbiBoYXlzdGFja1xuXHRcdFx0aGlnaGxpZ2h0ZWRUZXh0ID1cblx0XHRcdFx0Y29udGFpbnNUYWdNYXRjaGVzWzFdICtcblx0XHRcdFx0Y29udGFpbnNUYWdNYXRjaGVzWzJdLnJlcGxhY2UoXG5cdFx0XHRcdFx0c2VhcmNoUGF0dGVybixcblx0XHRcdFx0XHQnPHNwYW4gY2xhc3M9XCJndC1oaWdobGlnaHQtc2VhcmNoXCI+JDE8L3NwYW4+J1xuXHRcdFx0XHQpICtcblx0XHRcdFx0Y29udGFpbnNUYWdNYXRjaGVzWzNdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRoaWdobGlnaHRlZFRleHQgPSBoYXlzdGFja0Fsd2F5c1N0cmluZy5yZXBsYWNlKFxuXHRcdFx0XHRzZWFyY2hQYXR0ZXJuLFxuXHRcdFx0XHQnPHNwYW4gY2xhc3M9XCJndC1oaWdobGlnaHQtc2VhcmNoXCI+JDE8L3NwYW4+J1xuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoaGlnaGxpZ2h0ZWRUZXh0KTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndENvbHVtbkNsYXNzJ1xufSlcbmV4cG9ydCBjbGFzcyBHdENvbHVtbkNsYXNzUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHR0cmFuc2Zvcm0oXG5cdFx0Z3RGaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8YW55LCBhbnk+Pixcblx0XHRjb2x1bW46IEd0Q29uZmlnRmllbGQ8R3RSb3csIGFueT4sXG5cdFx0cm93PzogR3RSb3dcblx0KTogYW55IHtcblx0XHQvLyBmaW5kIGNvbHVtbnMgd2l0aCBjb2x1bW5DbGFzcyBwcm9wZXJ0eSBkZWZpbmVkXG5cdFx0Y29uc3QgQ09MVU1OX1dJVEhfQ0xBU1MgPSBndEZpZWxkc1xuXHRcdFx0Lm1hcChmaWVsZCA9PiBmaWVsZClcblx0XHRcdC5maWx0ZXIoXG5cdFx0XHRcdGZpZWxkID0+IGZpZWxkLmNvbHVtbkNsYXNzICYmIGZpZWxkLm9iamVjdEtleSA9PT0gY29sdW1uLm9iamVjdEtleVxuXHRcdFx0KVswXTtcblx0XHRpZiAoIUNPTFVNTl9XSVRIX0NMQVNTKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fSBlbHNlIGlmICh0eXBlb2YgQ09MVU1OX1dJVEhfQ0xBU1MuY29sdW1uQ2xhc3MgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdC8vIGlmIGNvbHVtbiBjbGFzcyBpcyBhIGZ1bmN0aW9uLCB0cnkgdXNpbmcgdGhlIGZ1bmN0aW9uLi4uXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRyZXR1cm4gQ09MVU1OX1dJVEhfQ0xBU1MuY29sdW1uQ2xhc3Mocm93LCBjb2x1bW4pO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0J0Vycm9yIHdoZW4gdHJ5aW5nIHRvIGdldCBjb2x1bW4gY2xhc3MgbmFtZSB1c2luZyBmb3JtdWxhLicsXG5cdFx0XHRcdFx0ZXJyb3Jcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gaWYgbm90IGEgZnVuY3Rpb24sIHJldHVybiBwbGFpbiBzdHJpbmcgdmFsdWVcblx0XHRcdHJldHVybiBDT0xVTU5fV0lUSF9DTEFTUy5jb2x1bW5DbGFzcztcblx0XHR9XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0Um93Q2xhc3MnXG59KVxuZXhwb3J0IGNsYXNzIEd0Um93Q2xhc3NQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShhcnJheTogQXJyYXk8YW55PiwgZ3RGaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8YW55LCBhbnk+Pik6IGFueSB7XG5cdFx0aWYgKGFycmF5KSB7XG5cdFx0XHQvLyBmaW5kIGNvbHVtbnMgd2l0aCByb3dDbGFzcyBwcm9wZXJ0eSBkZWZpbmVkXG5cdFx0XHRjb25zdCBDT0xVTU5TX1dJVEhfQ0xBU1MgPSBndEZpZWxkc1xuXHRcdFx0XHQubWFwKGNvbHVtbiA9PiBjb2x1bW4pXG5cdFx0XHRcdC5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi5yb3dDbGFzcyk7XG5cdFx0XHRDT0xVTU5TX1dJVEhfQ0xBU1MubWFwKGNvbHVtbiA9PiB7XG5cdFx0XHRcdC8vIGZvciBlYWNoIGNvbHVtbiB3aXRoIHJvd0NsYXNzIHByb3BlcnR5IGRlZmluZWQuLi5cblx0XHRcdFx0YXJyYXkubWFwKHJvdyA9PiB7XG5cdFx0XHRcdFx0Ly8gbG9vcCB0aHJvdWdoIHJvd3MgYW5kIHNldCByb3cgY2xhc3Ncblx0XHRcdFx0XHRpZiAodHlwZW9mIGNvbHVtbi5yb3dDbGFzcyA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdFx0Ly8gaWYgcm93IGNsYXNzIGlzIGEgZnVuY3Rpb24sIHRyeSB1c2luZyB0aGUgZnVuY3Rpb24uLi5cblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGlmIChyb3cuJCRndFJvd0NsYXNzKSB7XG5cdFx0XHRcdFx0XHRcdFx0cm93LiQkZ3RSb3dDbGFzcyA9IHJvdy4kJGd0Um93Q2xhc3MuY29uY2F0KFxuXHRcdFx0XHRcdFx0XHRcdFx0JyAnICsgY29sdW1uLnJvd0NsYXNzKHJvdywgY29sdW1uKVxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0cm93LiQkZ3RSb3dDbGFzcyA9IGNvbHVtbi5yb3dDbGFzcyhyb3csIGNvbHVtbik7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFxuXHRcdFx0XHRcdFx0XHRcdCdFcnJvciB3aGVuIHRyeWluZyB0byBnZXQgcm93IGNsYXNzIG5hbWUgdXNpbmcgZm9ybXVsYS4nLFxuXHRcdFx0XHRcdFx0XHRcdGVycm9yXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIGlmIG5vdCBhIGZ1bmN0aW9uLCByZXR1cm4gcGxhaW4gc3RyaW5nIHZhbHVlXG5cdFx0XHRcdFx0XHRpZiAocm93LiQkZ3RSb3dDbGFzcykge1xuXHRcdFx0XHRcdFx0XHRyb3cuJCRndFJvd0NsYXNzID0gcm93LiQkZ3RSb3dDbGFzcy5jb25jYXQoJyAnICsgY29sdW1uLnJvd0NsYXNzKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHJvdy4kJGd0Um93Q2xhc3MgPSBjb2x1bW4ucm93Q2xhc3M7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gYXJyYXk7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnVG90YWwgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy10b3RhbCc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0VG90YWxzUG9zaXRpb24nXG59KVxuZXhwb3J0IGNsYXNzIEd0VG90YWxzUG9zaXRpb25QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHRhcnJheTogQXJyYXk8R3RDb25maWdUb3RhbD4sXG5cdFx0cG9zaXRpb246ICdoZWFkZXInIHwgJ2Zvb3RlcicgPSAnaGVhZGVyJ1xuXHQpOiBBcnJheTxhbnk+IHtcblx0XHRyZXR1cm4gYXJyYXkuZmlsdGVyKHRvdGFsID0+IHtcblx0XHRcdC8vIGlmIG5vIHBvc2l0aW9uIGlzIGRlZmluZWQgYXNzdW1lIHBvc2l0aW9uIHRvIGJlIGhlYWRlclxuXHRcdFx0Y29uc3QgdG90YWxQb3NpdGlvbiA9IHRvdGFsLnBvc2l0aW9uID8gdG90YWwucG9zaXRpb24gOiAnaGVhZGVyJztcblx0XHRcdHJldHVybiB0b3RhbFBvc2l0aW9uID09PSBwb3NpdGlvbjtcblx0XHR9KTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFRvdGFscydcbn0pXG5leHBvcnQgY2xhc3MgR3RUb3RhbHNQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHR2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgRnVuY3Rpb24sXG5cdFx0ZGF0YTogQXJyYXk8YW55Pixcblx0XHRvYmplY3RLZXk6IHN0cmluZyxcblx0XHRyZWZyZXNoOiBib29sZWFuXG5cdCk6IGFueSB7XG5cdFx0bGV0IG91dHB1dDtcblxuXHRcdGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdG91dHB1dCA9IHZhbHVlKGRhdGEsIG9iamVjdEtleSk7XG5cdFx0fSBlbHNlIGlmICh2YWx1ZSkge1xuXHRcdFx0b3V0cHV0ID0gdmFsdWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG91dHB1dCA9ICcnO1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RPcmRlckJ5J1xufSlcbmV4cG9ydCBjbGFzcyBHdE9yZGVyQnlQaXBlPFIgZXh0ZW5kcyBHdFJvdz4gaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0c3RhdGljIF9vcmRlckJ5Q29tcGFyYXRvcihhOiBhbnksIGI6IGFueSk6IG51bWJlciB7XG5cdFx0Ly8gc29ydCBib29sZWFuIHZhbHVlcyBhcyBzdHJpbmdzXG5cdFx0aWYgKHR5cGVvZiBhID09PSAnYm9vbGVhbicpIHtcblx0XHRcdGEgPSBhLnRvU3RyaW5nKCk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgYiA9PT0gJ2Jvb2xlYW4nKSB7XG5cdFx0XHRiID0gYi50b1N0cmluZygpO1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdGlzTmFOKHBhcnNlRmxvYXQoYSkpIHx8XG5cdFx0XHQhaXNGaW5pdGUoYSkgfHxcblx0XHRcdChpc05hTihwYXJzZUZsb2F0KGIpKSB8fCAhaXNGaW5pdGUoYikpXG5cdFx0KSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGIgPT09IG51bGwgfHxcblx0XHRcdFx0KHR5cGVvZiBiID09PSAndW5kZWZpbmVkJyAmJiAoYSAhPT0gbnVsbCAmJiB0eXBlb2YgYSAhPT0gJ3VuZGVmaW5lZCcpKVxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXHRcdFx0aWYgKFxuXHRcdFx0XHRhID09PSBudWxsIHx8XG5cdFx0XHRcdCh0eXBlb2YgYSA9PT0gJ3VuZGVmaW5lZCcgJiYgKGIgIT09IG51bGwgJiYgdHlwZW9mIGIgIT09ICd1bmRlZmluZWQnKSlcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGlzbid0IGEgbnVtYmVyIHNvIGxvd2VyY2FzZSB0aGUgc3RyaW5nIHRvIHByb3Blcmx5IGNvbXBhcmVcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGlmIChhLnRvTG93ZXJDYXNlKCkgPCBiLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGEudG9Mb3dlckNhc2UoKSA+IGIudG9Mb3dlckNhc2UoKSkge1xuXHRcdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gcGFyc2Ugc3RyaW5ncyBhcyBudW1iZXJzIHRvIGNvbXBhcmUgcHJvcGVybHlcblx0XHRcdGlmIChwYXJzZUZsb2F0KGEpIDwgcGFyc2VGbG9hdChiKSkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0XHRpZiAocGFyc2VGbG9hdChhKSA+IHBhcnNlRmxvYXQoYikpIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIDA7IC8vIGVxdWFsIGVhY2ggb3RoZXJcblx0fVxuXG5cdC8qKiBSZXR1cm4gcHJvcGVydHkgKi9cblx0cHJpdmF0ZSBnZXRQcm9wZXJ0eSA9IGZ1bmN0aW9uKGFycmF5OiBBcnJheTxhbnk+LCBrZXk6IHN0cmluZykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChhcnJheVtpXS5vYmplY3RLZXkgPT09IGtleSkge1xuXHRcdFx0XHRyZXR1cm4gYXJyYXlbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cdC8qKiBSZXR1cm4gc29ydCBmdW5jdGlvbiAqL1xuXHRwcml2YXRlIGdldFNvcnRGdW5jdGlvbihmaWVsZDogYW55KSB7XG5cdFx0aWYgKCFmaWVsZCkge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coJ2Vycm9yIHRyeWluZyB0byBzb3J0IHVuZGVmaW5lZCBmaWVsZCcpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIGZpZWxkLnNvcnQgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHJldHVybiBmaWVsZC5zb3J0O1xuXHRcdH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkLnZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRyZXR1cm4gZmllbGQudmFsdWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHR0cmFuc2Zvcm0oXG5cdFx0aW5wdXQ6IGFueSxcblx0XHRzb3J0QnlQcm9wZXJ0aWVzOiBBcnJheTxzdHJpbmc+LFxuXHRcdGZpZWxkczogR3RDb25maWdGaWVsZDxSLCBhbnk+W10sXG5cdFx0cmVmcmVzaFNvcnRpbmc6IGJvb2xlYW4sXG5cdFx0cmVmcmVzaERhdGE6IG51bWJlclxuXHQpOiBhbnkge1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShpbnB1dCkgfHwgaW5wdXQgPT09IG51bGwpIHtcblx0XHRcdHJldHVybiBpbnB1dDtcblx0XHR9XG5cdFx0aWYgKFxuXHRcdFx0IUFycmF5LmlzQXJyYXkoc29ydEJ5UHJvcGVydGllcykgfHxcblx0XHRcdChBcnJheS5pc0FycmF5KHNvcnRCeVByb3BlcnRpZXMpICYmIHNvcnRCeVByb3BlcnRpZXMubGVuZ3RoID09PSAxKVxuXHRcdCkge1xuXHRcdFx0Y29uc3QgcHJvcGVydHlUb0NoZWNrOiBzdHJpbmcgPSBzb3J0QnlQcm9wZXJ0aWVzWzBdO1xuXHRcdFx0Y29uc3QgZGVzYyA9IHByb3BlcnR5VG9DaGVjay5zdWJzdHIoMCwgMSkgPT09ICctJztcblxuXHRcdFx0Ly8gYmFzaWMgYXJyYXlcblx0XHRcdGlmIChcblx0XHRcdFx0IXByb3BlcnR5VG9DaGVjayB8fFxuXHRcdFx0XHRwcm9wZXJ0eVRvQ2hlY2sgPT09ICctJyB8fFxuXHRcdFx0XHRwcm9wZXJ0eVRvQ2hlY2sgPT09ICcrJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAhZGVzYyA/IGlucHV0LnNvcnQoKSA6IGlucHV0LnNvcnQoKS5yZXZlcnNlKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBwcm9wZXJ0eTogc3RyaW5nID1cblx0XHRcdFx0XHRwcm9wZXJ0eVRvQ2hlY2suc3Vic3RyKDAsIDEpID09PSAnKycgfHxcblx0XHRcdFx0XHRwcm9wZXJ0eVRvQ2hlY2suc3Vic3RyKDAsIDEpID09PSAnLSdcblx0XHRcdFx0XHRcdD8gcHJvcGVydHlUb0NoZWNrLnN1YnN0cigxKVxuXHRcdFx0XHRcdFx0OiBwcm9wZXJ0eVRvQ2hlY2s7XG5cblx0XHRcdFx0Ly8gY2hlY2sgaWYgY3VzdG9tIHNvcnQgZnVuY3Rpb24gaXMgZGVmaW5lZFxuXHRcdFx0XHRjb25zdCBzb3J0RnVuY3Rpb246IGFueSA9IHRoaXMuZ2V0U29ydEZ1bmN0aW9uKFxuXHRcdFx0XHRcdHRoaXMuZ2V0UHJvcGVydHkoZmllbGRzLCBwcm9wZXJ0eSlcblx0XHRcdFx0KTtcblxuXHRcdFx0XHQvLyBjb25zb2xlLmxvZyhwcm9wZXJ0eSk7XG5cdFx0XHRcdHJldHVybiBpbnB1dC5zb3J0KGZ1bmN0aW9uKGE6IGFueSwgYjogYW55KSB7XG5cdFx0XHRcdFx0Ly8gdXNlIGN1c3RvbSBzb3J0IGZ1bmN0aW9uIGlmIG9uZSBpcyBkZWZpbmVkXG5cdFx0XHRcdFx0Y29uc3QgcHJvcGVydHlBID1cblx0XHRcdFx0XHRcdHNvcnRGdW5jdGlvbiA9PT0gZmFsc2Vcblx0XHRcdFx0XHRcdFx0PyBwcm9wZXJ0eSA9PT0gJyQkZ3RSb3dJZCdcblx0XHRcdFx0XHRcdFx0XHQ/ICthLiQkZ3RSb3dJZC5zcGxpdCgnXycpWzBdXG5cdFx0XHRcdFx0XHRcdFx0OiBhW3Byb3BlcnR5XVxuXHRcdFx0XHRcdFx0XHQ6IHNvcnRGdW5jdGlvbihhKTtcblx0XHRcdFx0XHRjb25zdCBwcm9wZXJ0eUIgPVxuXHRcdFx0XHRcdFx0c29ydEZ1bmN0aW9uID09PSBmYWxzZVxuXHRcdFx0XHRcdFx0XHQ/IHByb3BlcnR5ID09PSAnJCRndFJvd0lkJ1xuXHRcdFx0XHRcdFx0XHRcdD8gK2IuJCRndFJvd0lkLnNwbGl0KCdfJylbMF1cblx0XHRcdFx0XHRcdFx0XHQ6IGJbcHJvcGVydHldXG5cdFx0XHRcdFx0XHRcdDogc29ydEZ1bmN0aW9uKGIpO1xuXG5cdFx0XHRcdFx0Ly8gaWYgYm90aCB2YWx1ZXMgYXJlIHVuZGVmaW5lZC4uLlxuXHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdHR5cGVvZiBwcm9wZXJ0eUEgPT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRcdFx0XHR0eXBlb2YgcHJvcGVydHlCID09PSAndW5kZWZpbmVkJ1xuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0Ly8gLi4uc2tpcCBjb21wYXJpc29uXG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiAhZGVzY1xuXHRcdFx0XHRcdFx0PyBHdE9yZGVyQnlQaXBlLl9vcmRlckJ5Q29tcGFyYXRvcihwcm9wZXJ0eUEsIHByb3BlcnR5Qilcblx0XHRcdFx0XHRcdDogLUd0T3JkZXJCeVBpcGUuX29yZGVyQnlDb21wYXJhdG9yKHByb3BlcnR5QSwgcHJvcGVydHlCKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGxvb3Agb3ZlciBwcm9wZXJ0eSBvZiB0aGUgYXJyYXkgaW4gb3JkZXIgYW5kIHNvcnRcblx0XHRcdHJldHVybiBpbnB1dC5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xuXHRcdFx0XHQvLyBjb25zb2xlLmxvZygnbXVsdGlwbGUnKTtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzb3J0QnlQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0Y29uc3QgZGVzYyA9IHNvcnRCeVByb3BlcnRpZXNbaV0uc3Vic3RyKDAsIDEpID09PSAnLSc7XG5cdFx0XHRcdFx0Y29uc3QgcHJvcGVydHkgPVxuXHRcdFx0XHRcdFx0c29ydEJ5UHJvcGVydGllc1tpXS5zdWJzdHIoMCwgMSkgPT09ICcrJyB8fFxuXHRcdFx0XHRcdFx0c29ydEJ5UHJvcGVydGllc1tpXS5zdWJzdHIoMCwgMSkgPT09ICctJ1xuXHRcdFx0XHRcdFx0XHQ/IHNvcnRCeVByb3BlcnRpZXNbaV0uc3Vic3RyKDEpXG5cdFx0XHRcdFx0XHRcdDogc29ydEJ5UHJvcGVydGllc1tpXTtcblxuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKHByb3BlcnR5KTtcblx0XHRcdFx0XHQvLyBjaGVjayBpZiBjdXN0b20gc29ydCBmdW5jdGlvbiBpcyBkZWZpbmVkXG5cdFx0XHRcdFx0Y29uc3Qgc29ydEZ1bmN0aW9uOiBhbnkgPSB0aGlzLmdldFNvcnRGdW5jdGlvbihcblx0XHRcdFx0XHRcdHRoaXMuZ2V0UHJvcGVydHkoZmllbGRzLCBwcm9wZXJ0eSlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gdXNlIGN1c3RvbSBzb3J0IGZ1bmN0aW9uIGlmIG9uZSBpcyBkZWZpbmVkXG5cdFx0XHRcdFx0Y29uc3QgcHJvcGVydHlBID1cblx0XHRcdFx0XHRcdHNvcnRGdW5jdGlvbiA9PT0gZmFsc2Vcblx0XHRcdFx0XHRcdFx0PyBwcm9wZXJ0eSA9PT0gJyQkZ3RSb3dJZCdcblx0XHRcdFx0XHRcdFx0XHQ/ICthLiQkZ3RSb3dJZC5zcGxpdCgnXycpWzBdXG5cdFx0XHRcdFx0XHRcdFx0OiBhW3Byb3BlcnR5XVxuXHRcdFx0XHRcdFx0XHQ6IHNvcnRGdW5jdGlvbihhKTtcblx0XHRcdFx0XHRjb25zdCBwcm9wZXJ0eUIgPVxuXHRcdFx0XHRcdFx0c29ydEZ1bmN0aW9uID09PSBmYWxzZVxuXHRcdFx0XHRcdFx0XHQ/IHByb3BlcnR5ID09PSAnJCRndFJvd0lkJ1xuXHRcdFx0XHRcdFx0XHRcdD8gK2IuJCRndFJvd0lkLnNwbGl0KCdfJylbMF1cblx0XHRcdFx0XHRcdFx0XHQ6IGJbcHJvcGVydHldXG5cdFx0XHRcdFx0XHRcdDogc29ydEZ1bmN0aW9uKGIpO1xuXG5cdFx0XHRcdFx0Y29uc3QgY29tcGFyaXNvbiA9ICFkZXNjXG5cdFx0XHRcdFx0XHQ/IEd0T3JkZXJCeVBpcGUuX29yZGVyQnlDb21wYXJhdG9yKHByb3BlcnR5QSwgcHJvcGVydHlCKVxuXHRcdFx0XHRcdFx0OiAtR3RPcmRlckJ5UGlwZS5fb3JkZXJCeUNvbXBhcmF0b3IocHJvcGVydHlBLCBwcm9wZXJ0eUIpO1xuXG5cdFx0XHRcdFx0Ly8gZG9uJ3QgcmV0dXJuIDAgeWV0IGluIGNhc2Ugb2YgbmVlZGluZyB0byBzb3J0IGJ5IG5leHQgcHJvcGVydHlcblx0XHRcdFx0XHRpZiAoY29tcGFyaXNvbiAhPT0gMCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGNvbXBhcmlzb247XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIDA7IC8vIGVxdWFsIGVhY2ggb3RoZXJcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSwgRXZlbnRFbWl0dGVyLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0SW5mb3JtYXRpb24gfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWluZm9ybWF0aW9uJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RGaWx0ZXInXG59KVxuZXhwb3J0IGNsYXNzIEd0RmlsdGVyUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHQvLyBAT3V0cHV0KCkgZmlsdGVySW5mbyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHR0cmFuc2Zvcm0oXG5cdFx0YWxsUm93czogYW55W10sXG5cdFx0ZmlsdGVyQnk6IE9iamVjdCxcblx0XHRndEluZm86IEd0SW5mb3JtYXRpb24sXG5cdFx0cmVmcmVzaEZpbHRlcjogYm9vbGVhbixcblx0XHRyZWZyZXNoRGF0YTogbnVtYmVyXG5cdCk6IGFueVtdIHtcblx0XHQvLyBjb25zb2xlLmxvZyhhbGxSb3dzLGZpbHRlckJ5KTtcblx0XHRndEluZm8ucmVjb3Jkc0FsbCA9IGFsbFJvd3MubGVuZ3RoO1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShhbGxSb3dzKSB8fCAhZmlsdGVyQnkpIHtcblx0XHRcdC8vIGd0SW5mby5maWx0ZXJlZCA9IGZhbHNlO1xuXG5cdFx0XHRjb25zdCBsZW5ndGggPSBhbGxSb3dzID09PSBudWxsID8gMCA6IGFsbFJvd3MubGVuZ3RoO1xuXHRcdFx0Z3RJbmZvLnJlY29yZHNBZnRlckZpbHRlciA9IGxlbmd0aDtcblx0XHRcdHJldHVybiBhbGxSb3dzO1xuXHRcdH1cblxuXHRcdGNvbnN0IG91dHB1dCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYWxsUm93cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgcm93T2JqZWN0ID0gYWxsUm93c1tpXTtcblx0XHRcdGxldCBtYXRjaCA9IHRydWU7XG5cblx0XHRcdGZvciAoY29uc3QgcHJvcGVydHkgaW4gZmlsdGVyQnkpIHtcblx0XHRcdFx0aWYgKGZpbHRlckJ5Lmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKHByb3BlcnR5KTtcblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyhmaWx0ZXJbcHJvcGVydHldLmluZGV4T2Yob2JqW3Byb3BlcnR5XSkpO1xuXHRcdFx0XHRcdGlmIChmaWx0ZXJCeVtwcm9wZXJ0eV0uaW5kZXhPZihyb3dPYmplY3RbcHJvcGVydHldKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdG1hdGNoID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAobWF0Y2gpIHtcblx0XHRcdFx0b3V0cHV0LnB1c2gocm93T2JqZWN0KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Z3RJbmZvLnJlY29yZHNBZnRlckZpbHRlciA9IG91dHB1dC5sZW5ndGg7IC8vIC5lbWl0KG91dHB1dC5sZW5ndGgpO1xuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuaW1wb3J0IHsgR3RFdmVudCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtZXZlbnQnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndENodW5rJ1xufSlcbmV4cG9ydCBjbGFzcyBHdENodW5rUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHR0cmFuc2Zvcm0oXG5cdFx0YXJyYXk6IGFueVtdLFxuXHRcdGd0SW5mbzogR3RJbmZvcm1hdGlvbixcblx0XHRjaHVua1NpemU6IG51bWJlcixcblx0XHRwYWdlOiBudW1iZXIsXG5cdFx0cmVmcmVzaFBhZ2VBcnJheTogYm9vbGVhbixcblx0XHRyZWZyZXNoRGF0YTogbnVtYmVyLFxuXHRcdGd0RXZlbnQ6IEV2ZW50RW1pdHRlcjxHdEV2ZW50Pixcblx0XHRkYXRhOiB7IGV4cG9ydERhdGE6IEFycmF5PGFueT4gfVxuXHQpOiBhbnlbXSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KGFycmF5KSkge1xuXHRcdFx0cmV0dXJuIGFycmF5O1xuXHRcdH1cblx0XHRkYXRhLmV4cG9ydERhdGEgPSBhcnJheTsgLy8gc3RvcmUgZGF0YSBmb3IgZXhwb3J0XG5cblx0XHRjb25zdCBQQUdFUyA9IFtdO1xuXHRcdGNvbnN0IEVOVFJJRVMgPSBhcnJheS5sZW5ndGg7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IEVOVFJJRVM7IGkgKz0gY2h1bmtTaXplKSB7XG5cdFx0XHRQQUdFUy5wdXNoKGFycmF5LnNsaWNlKGksIGkgKyBjaHVua1NpemUpKTtcblx0XHR9XG5cdFx0Z3RJbmZvLnZpc2libGVSZWNvcmRzID0gIVBBR0VTW3BhZ2UgLSAxXSA/IFtdIDogWy4uLlBBR0VTW3BhZ2UgLSAxXV07IC8vIGFkZCB2aXNpYmxlIHJvd3Ncblx0XHRndEluZm8ucGFnZVRvdGFsID0gUEFHRVMubGVuZ3RoOyAvLyBhZGQgbnVtYmVyIG9mIHBhZ2VzXG5cblx0XHRzZXRUaW1lb3V0KFxuXHRcdFx0KCkgPT5cblx0XHRcdFx0Z3RFdmVudC5lbWl0KHtcblx0XHRcdFx0XHRuYW1lOiAnZ3QtaW5mbycsXG5cdFx0XHRcdFx0dmFsdWU6IGd0SW5mb1xuXHRcdFx0XHR9KSxcblx0XHRcdDBcblx0XHQpO1xuXHRcdHJldHVybiBQQUdFU1twYWdlIC0gMV07XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdENvbmZpZ1NldHRpbmcgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1zZXR0aW5nJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFByb3BlcnR5J1xufSlcbmV4cG9ydCBjbGFzcyBHdFByb3BlcnR5UGlwZTxSIGV4dGVuZHMgR3RSb3c+IGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHRjb25maWc6IEd0Q29uZmlnRmllbGQ8UiwgYW55PltdIHwgR3RDb25maWdTZXR0aW5nW10sXG5cdFx0b2JqZWN0S2V5OiBzdHJpbmcsXG5cdFx0cHJvcGVydHk6IHN0cmluZyxcblx0XHRyZWZyZXNoPzogYm9vbGVhblxuXHQpOiBhbnkge1xuXHRcdGxldCBvdXRwdXQgPSBudWxsO1xuXHRcdHRyeSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNvbmZpZy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAoY29uZmlnW2ldLm9iamVjdEtleSA9PT0gb2JqZWN0S2V5KSB7XG5cdFx0XHRcdFx0b3V0cHV0ID0gY29uZmlnW2ldW3Byb3BlcnR5XTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcblx0XHRcdFx0J2Nhbm5vdCByZWFkIHByb3BlcnR5OiBcIicgK1xuXHRcdFx0XHRcdHByb3BlcnR5ICtcblx0XHRcdFx0XHQnXCIgb24gbWlzc2luZyBrZXk6IFwiJyArXG5cdFx0XHRcdFx0b2JqZWN0S2V5ICtcblx0XHRcdFx0XHQnXCIgaW4gY29uZmlnLicsXG5cdFx0XHRcdGVycm9yXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2Rhc2hDYXNlJ1xufSlcbmV4cG9ydCBjbGFzcyBEYXNoQ2FzZVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKHN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gc3RyaW5nLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnU2V0dGluZyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLXNldHRpbmcnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgR3RSb3cgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LXJvdyc7XG5pbXBvcnQgeyBHdFJlbmRlckZpZWxkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yZW5kZXItZmllbGQnO1xuaW1wb3J0IHsgR3RIaWdobGlnaHRQaXBlIH0gZnJvbSAnLi9ndC1oaWdobGlnaHQucGlwZSc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0UmVuZGVyJ1xufSlcbmV4cG9ydCBjbGFzcyBHdFJlbmRlclBpcGU8UiBleHRlbmRzIEd0Um93PiBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuXHRcdHByaXZhdGUgZ3RIaWdobGlnaHRQaXBlOiBHdEhpZ2hsaWdodFBpcGVcblx0KSB7fVxuXG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlciA9IGZ1bmN0aW9uKGE6IEd0Q29uZmlnU2V0dGluZywgYjogR3RDb25maWdTZXR0aW5nKSB7XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPCBiLmNvbHVtbk9yZGVyKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fVxuXHRcdGlmIChhLmNvbHVtbk9yZGVyID4gYi5jb2x1bW5PcmRlciB8fCB0eXBlb2YgYS5jb2x1bW5PcmRlciA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fTtcblxuXHQvKiogU29ydCBieSBsZW5ndGggKi9cblx0cHJpdmF0ZSBnZXRPcmRlckJ5TGVuZ3RoID0gZnVuY3Rpb24oYTogYW55LCBiOiBhbnkpIHtcblx0XHRyZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcblx0fTtcblxuXHQvKiogUmV0dXJuIHByb3BlcnR5ICovXG5cdHByaXZhdGUgZ2V0UHJvcGVydHkgPSBmdW5jdGlvbihhcnJheTogQXJyYXk8YW55Piwga2V5OiBzdHJpbmcpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXJyYXlbaV0ub2JqZWN0S2V5ID09PSBrZXkpIHtcblx0XHRcdFx0cmV0dXJuIGFycmF5W2ldO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblxuXHR0cmFuc2Zvcm0oXG5cdFx0cm93OiBhbnksXG5cdFx0c2V0dGluZ3M6IEFycmF5PEd0Q29uZmlnU2V0dGluZz4sXG5cdFx0ZmllbGRzOiBBcnJheTxHdENvbmZpZ0ZpZWxkPFIsIGFueT4+LFxuXHRcdHVwZGF0ZWQ6IGJvb2xlYW4sXG5cdFx0bG9hZGluZzogYm9vbGVhbixcblx0XHRoaWdobGlnaHQ6IGJvb2xlYW4gPSBmYWxzZSxcblx0XHRzZWFyY2hTdHJpbmc/OiBzdHJpbmdcblx0KTogQXJyYXk8R3RSZW5kZXJGaWVsZDxSLCBhbnk+PiB7XG5cdFx0Ly8gbGV0IGFyciA9IFt7XCJ0ZW1wXCI6MTIzLFwibmFtZVwiOlwiaGFwcHlcIn0se1widGVtcFwiOjQ1NixcIm5hbWVcIjpcImRmZ2RmZ1wifSx7XCJ0ZW1wXCI6Nzg5LFwibmFtZVwiOlwiYXNkYXNkXCJ9XTtcblx0XHQvLyBjb25zb2xlLmxvZyhhcnIsYXJyLm1hcChmdW5jdGlvbihpdGVtKXtyZXR1cm4gaXRlbS50ZW1wfSkpO1xuXHRcdC8vIGNvbnNvbGUubG9nKHNldHRpbmdzLm1hcCgnb2JqZWN0S2V5JykpO1xuXG5cdFx0Ly8gY29uc29sZS5sb2coJ3JlbmRlcicpO1xuXHRcdGNvbnN0IGNvbHVtbnM6IEFycmF5PHN0cmluZz4gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoc2V0dGluZ3NbaV0udmlzaWJsZSAhPT0gZmFsc2UgJiYgc2V0dGluZ3NbaV0uZW5hYmxlZCAhPT0gZmFsc2UpIHtcblx0XHRcdFx0Y29sdW1ucy5wdXNoKHNldHRpbmdzW2ldLm9iamVjdEtleSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdC8vIGNvbnNvbGUubG9nKCFyb3dbZmllbGRzW2ldLm9iamVjdEtleV0pO1xuXHRcdFx0aWYgKFxuXHRcdFx0XHRmaWVsZHNbaV0udmFsdWUgJiZcblx0XHRcdFx0dHlwZW9mIGZpZWxkc1tpXS52YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdFx0XHQhcm93Lmhhc093blByb3BlcnR5KGZpZWxkc1tpXS5vYmplY3RLZXkpXG5cdFx0XHQpIHtcblx0XHRcdFx0cm93W2ZpZWxkc1tpXS5vYmplY3RLZXldID0gbG9hZGluZyA/ICcnIDogZmllbGRzW2ldLnZhbHVlKHJvdyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIGNvbnNvbGUubG9nKHJvdyk7XG5cdFx0Y29uc3Qga2V5czogQXJyYXk8YW55PiA9IFtdO1xuXHRcdGZvciAoY29uc3Qga2V5IGluIHJvdykge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coa2V5KTtcblx0XHRcdGlmIChjb2x1bW5zLmluZGV4T2Yoa2V5KSAhPT0gLTEpIHtcblx0XHRcdFx0bGV0IGZpZWxkU2V0dGluZztcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRpZiAoZmllbGRzW2ldLm9iamVjdEtleSA9PT0ga2V5KSB7XG5cdFx0XHRcdFx0XHRmaWVsZFNldHRpbmcgPSBmaWVsZHNbaV07XG5cdFx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyhmaWVsZFNldHRpbmcpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IGNvbHVtbk9iamVjdDogR3RSZW5kZXJGaWVsZDxSLCBhbnk+ID0ge1xuXHRcdFx0XHRcdG9iamVjdEtleToga2V5LFxuXHRcdFx0XHRcdHNvcnRWYWx1ZTogcm93W2tleV1cblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBhZGQgY29tcG9uZW50IGlmIGRlZmluZWRcblx0XHRcdFx0aWYgKGZpZWxkU2V0dGluZy5jb2x1bW5Db21wb25lbnQpIHtcblx0XHRcdFx0XHRjb2x1bW5PYmplY3QuY29sdW1uQ29tcG9uZW50ID0gZmllbGRTZXR0aW5nLmNvbHVtbkNvbXBvbmVudDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChsb2FkaW5nKSB7XG5cdFx0XHRcdFx0Y29sdW1uT2JqZWN0LnJlbmRlclZhbHVlID0gcm93W2tleV0gIT09IG51bGwgPyByb3dba2V5XSA6ICcnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHRcdGhpZ2hsaWdodCAmJlxuXHRcdFx0XHRcdHNlYXJjaFN0cmluZyAmJlxuXHRcdFx0XHRcdHRoaXMuZ2V0UHJvcGVydHkoc2V0dGluZ3MsIGtleSkuc2VhcmNoICE9PSBmYWxzZVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRjb2x1bW5PYmplY3QucmVuZGVyVmFsdWUgPVxuXHRcdFx0XHRcdFx0ZmllbGRTZXR0aW5nLnJlbmRlciAmJiB0eXBlb2YgZmllbGRTZXR0aW5nLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJ1xuXHRcdFx0XHRcdFx0XHQ/IHRoaXMuZ3RIaWdobGlnaHRQaXBlLnRyYW5zZm9ybShcblx0XHRcdFx0XHRcdFx0XHRcdGZpZWxkU2V0dGluZy5yZW5kZXIocm93KSxcblx0XHRcdFx0XHRcdFx0XHRcdHNlYXJjaFN0cmluZ1xuXHRcdFx0XHRcdFx0XHQgIClcblx0XHRcdFx0XHRcdFx0OiB0aGlzLmd0SGlnaGxpZ2h0UGlwZS50cmFuc2Zvcm0oXG5cdFx0XHRcdFx0XHRcdFx0XHRyb3dba2V5XSAhPT0gbnVsbCA/IHJvd1trZXldIDogJycsXG5cdFx0XHRcdFx0XHRcdFx0XHRzZWFyY2hTdHJpbmdcblx0XHRcdFx0XHRcdFx0ICApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbHVtbk9iamVjdC5yZW5kZXJWYWx1ZSA9XG5cdFx0XHRcdFx0XHRmaWVsZFNldHRpbmcucmVuZGVyICYmIHR5cGVvZiBmaWVsZFNldHRpbmcucmVuZGVyID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHRcdD8gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoZmllbGRTZXR0aW5nLnJlbmRlcihyb3cpKVxuXHRcdFx0XHRcdFx0XHQ6IHJvd1trZXldICE9PSBudWxsXG5cdFx0XHRcdFx0XHRcdFx0PyByb3dba2V5XVxuXHRcdFx0XHRcdFx0XHRcdDogJyc7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoZmllbGRTZXR0aW5nLmNsaWNrICYmIHR5cGVvZiBmaWVsZFNldHRpbmcuY2xpY2sgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHRjb2x1bW5PYmplY3QuY2xpY2sgPSBmaWVsZFNldHRpbmcuY2xpY2s7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGZpZWxkU2V0dGluZy5leHBhbmQpIHtcblx0XHRcdFx0XHRjb2x1bW5PYmplY3QuZXhwYW5kID0gZmllbGRTZXR0aW5nLmV4cGFuZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGtleXMucHVzaChjb2x1bW5PYmplY3QpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGtleXMuc29ydChmdW5jdGlvbihhOiBhbnksIGI6IGFueSkge1xuXHRcdFx0cmV0dXJuIGNvbHVtbnMuaW5kZXhPZihhLm9iamVjdEtleSkgPCBjb2x1bW5zLmluZGV4T2YoYi5vYmplY3RLZXkpXG5cdFx0XHRcdD8gLTFcblx0XHRcdFx0OiAxO1xuXHRcdH0pO1xuXHRcdHJldHVybiBrZXlzO1xuXHR9XG59XG4iLCJpbXBvcnQge1xuXHRDb21wb25lbnRGYWN0b3J5LFxuXHRDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG5cdENvbXBvbmVudFJlZixcblx0RGlyZWN0aXZlLFxuXHRFdmVudEVtaXR0ZXIsXG5cdEluamVjdG9yLFxuXHRJbnB1dCxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFR5cGUsXG5cdFZpZXdDb250YWluZXJSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tndENvbXBvbmVudEFuY2hvcl0nXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudEFuY2hvckRpcmVjdGl2ZTxDPiBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cdEBJbnB1dCgpIGN0b3I6IFR5cGU8Qz47XG5cdEBJbnB1dCgpIGluamVjdG9yOiBJbmplY3Rvcjtcblx0QE91dHB1dCgpIGluc3RhbmNlOiBFdmVudEVtaXR0ZXI8Qz4gPSBuZXcgRXZlbnRFbWl0dGVyPEM+KCk7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcblx0XHRwcml2YXRlIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWZcblx0KSB7fVxuXG5cdG5nT25Jbml0KCk6IHZvaWQge1xuXHRcdGNvbnN0IGZhY3Rvcnk6IENvbXBvbmVudEZhY3Rvcnk8XG5cdFx0XHRDXG5cdFx0PiA9IHRoaXMuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KHRoaXMuY3Rvcik7XG5cdFx0Y29uc3QgY29tcG9uZW50OiBDb21wb25lbnRSZWY8Qz4gPSB0aGlzLnZpZXdDb250YWluZXIuY3JlYXRlQ29tcG9uZW50KFxuXHRcdFx0ZmFjdG9yeSxcblx0XHRcdDAsXG5cdFx0XHR0aGlzLmluamVjdG9yXG5cdFx0KTtcblx0XHR0aGlzLmluc3RhbmNlLmVtaXQoY29tcG9uZW50Lmluc3RhbmNlKTtcblx0fVxufVxuIiwiaW1wb3J0IHtcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdERpcmVjdGl2ZSxcblx0RWxlbWVudFJlZixcblx0SG9zdExpc3RlbmVyLFxuXHRJbnB1dFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW2d0Q29sdW1uV2lkdGhdJ1xufSlcbmV4cG9ydCBjbGFzcyBHdENvbHVtbldpZHRoRGlyZWN0aXZlIHtcblx0QElucHV0KCkgb2JqZWN0S2V5OiBzdHJpbmc7XG5cdEBJbnB1dCgpIHdpZHRoczogT2JqZWN0O1xuXHRASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcblx0cHVibGljIG9uUmVzaXplKCRldmVudDogYW55KSB7XG5cdFx0dGhpcy5jaGVja1NpemUoKTtcblx0fVxuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIGhvc3RFbGVtZW50OiBFbGVtZW50UmVmLFxuXHRcdHByaXZhdGUgY2RSZWY6IENoYW5nZURldGVjdG9yUmVmXG5cdCkge31cblx0bmdPbkluaXQoKSB7XG5cdFx0dGhpcy5jaGVja1NpemUoKTtcblx0fVxuXG5cdGNoZWNrU2l6ZSgpIHtcblx0XHR0aGlzLndpZHRoc1t0aGlzLm9iamVjdEtleV0gPSB3aW5kb3dcblx0XHRcdC5nZXRDb21wdXRlZFN0eWxlKHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudCwgbnVsbClcblx0XHRcdC5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpO1xuXHRcdHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDaGVja2JveENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9ndC1jaGVja2JveC9ndC1jaGVja2JveC5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3REcmlsbGRvd25Db21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZ3QtZHJpbGxkb3duL2d0LWRyaWxsZG93bi5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3REcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9ndC1kcm9wZG93bi9ndC1kcm9wZG93bi5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3RFeHBhbmRpbmdSb3dDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZ3QtZXhwYW5kaW5nLXJvdy9ndC1leHBhbmRpbmctcm93LmNvbXBvbmVudCc7XG5pbXBvcnQge1xuXHRHdFBhZ2luYXRpb25Db21wb25lbnQsXG5cdFBhZ2luYXRpb25QaXBlXG59IGZyb20gJy4vY29tcG9uZW50cy9ndC1wYWdpbmF0aW9uL2d0LXBhZ2luYXRpb24uY29tcG9uZW50JztcbmltcG9ydCB7XG5cdEd0VGFibGVJbmZvQ29tcG9uZW50LFxuXHRUYWJsZUluZm9QaXBlXG59IGZyb20gJy4vY29tcG9uZW50cy9ndC10YWJsZS1pbmZvL2d0LXRhYmxlLWluZm8uY29tcG9uZW50JztcbmltcG9ydCB7IEdlbmVyaWNUYWJsZUNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9nZW5lcmljLXRhYmxlL2dlbmVyaWMtdGFibGUuY29tcG9uZW50JztcbmltcG9ydCB7IEd0VmlzaWJsZVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXZpc2libGUucGlwZSc7XG5pbXBvcnQgeyBHdFNlYXJjaFBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXNlYXJjaC5waXBlJztcbmltcG9ydCB7IEd0SXNFZGl0YWJsZVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LWlzLWVkaXRhYmxlLnBpcGUnO1xuaW1wb3J0IHsgR3RJc09ic2VydmFibGVQaXBlIH0gZnJvbSAnLi9waXBlcy9ndC1pcy1vYnNlcnZhYmxlLnBpcGUnO1xuaW1wb3J0IHsgR3RIaWdobGlnaHRQaXBlIH0gZnJvbSAnLi9waXBlcy9ndC1oaWdobGlnaHQucGlwZSc7XG5pbXBvcnQgeyBHdENvbHVtbkNsYXNzUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtY29sdW1uLWNsYXNzLnBpcGUnO1xuaW1wb3J0IHsgR3RSb3dDbGFzc1BpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXJvdy1jbGFzcy5waXBlJztcbmltcG9ydCB7IEd0VG90YWxzUG9zaXRpb25QaXBlIH0gZnJvbSAnLi9waXBlcy9ndC10b3RhbHMtcG9zaXRpb24ucGlwZSc7XG5pbXBvcnQgeyBHdFRvdGFsc1BpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXRvdGFscy5waXBlJztcbmltcG9ydCB7IEd0TWV0YVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LW1ldGEucGlwZSc7XG5pbXBvcnQgeyBHdE9yZGVyQnlQaXBlIH0gZnJvbSAnLi9waXBlcy9ndC1vcmRlci1ieS5waXBlJztcbmltcG9ydCB7IEd0RmlsdGVyUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtZmlsdGVyLnBpcGUnO1xuaW1wb3J0IHsgR3RDaHVua1BpcGUgfSBmcm9tICcuL3BpcGVzL2d0LWNodW5rLnBpcGUnO1xuaW1wb3J0IHsgR3RQcm9wZXJ0eVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXByb3BlcnR5LnBpcGUnO1xuaW1wb3J0IHsgRGFzaENhc2VQaXBlIH0gZnJvbSAnLi9waXBlcy9kYXNoLWNhc2UucGlwZSc7XG5pbXBvcnQgeyBHdFJlbmRlclBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXJlbmRlci5waXBlJztcbmltcG9ydCB7IEd0Q3VzdG9tQ29tcG9uZW50RmFjdG9yeSB9IGZyb20gJy4vY29tcG9uZW50cy9ndC1jdXN0b20tY29tcG9uZW50LWZhY3RvcnkvZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21wb25lbnRBbmNob3JEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvY29tcG9uZW50LWFuY2hvci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgR3RDb2x1bW5XaWR0aERpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9ndC1jb2x1bW4td2lkdGguZGlyZWN0aXZlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuQE5nTW9kdWxlKHtcblx0ZGVjbGFyYXRpb25zOiBbXG5cdFx0Q29tcG9uZW50QW5jaG9yRGlyZWN0aXZlLFxuXHRcdEdlbmVyaWNUYWJsZUNvbXBvbmVudCxcblx0XHRHdFBhZ2luYXRpb25Db21wb25lbnQsXG5cdFx0R3RWaXNpYmxlUGlwZSxcblx0XHRHdFJlbmRlclBpcGUsXG5cdFx0RGFzaENhc2VQaXBlLFxuXHRcdEd0UHJvcGVydHlQaXBlLFxuXHRcdEd0Q2h1bmtQaXBlLFxuXHRcdEd0RmlsdGVyUGlwZSxcblx0XHRHdE9yZGVyQnlQaXBlLFxuXHRcdEd0RXhwYW5kaW5nUm93Q29tcG9uZW50LFxuXHRcdEd0Q3VzdG9tQ29tcG9uZW50RmFjdG9yeSxcblx0XHRHdFNlYXJjaFBpcGUsXG5cdFx0UGFnaW5hdGlvblBpcGUsXG5cdFx0R3RUYWJsZUluZm9Db21wb25lbnQsXG5cdFx0VGFibGVJbmZvUGlwZSxcblx0XHRHdE1ldGFQaXBlLFxuXHRcdEd0VG90YWxzUGlwZSxcblx0XHRHdFRvdGFsc1Bvc2l0aW9uUGlwZSxcblx0XHRHdFJvd0NsYXNzUGlwZSxcblx0XHRHdENvbHVtbkNsYXNzUGlwZSxcblx0XHRHdEhpZ2hsaWdodFBpcGUsXG5cdFx0R3RJc09ic2VydmFibGVQaXBlLFxuXHRcdEd0SXNFZGl0YWJsZVBpcGUsXG5cdFx0R3REcm9wZG93bkNvbXBvbmVudCxcblx0XHRHdENvbHVtbldpZHRoRGlyZWN0aXZlLFxuXHRcdEd0RHJpbGxkb3duQ29tcG9uZW50LFxuXHRcdEd0Q2hlY2tib3hDb21wb25lbnRcblx0XSxcblx0aW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGVdLFxuXHRleHBvcnRzOiBbXG5cdFx0R2VuZXJpY1RhYmxlQ29tcG9uZW50LFxuXHRcdEd0UGFnaW5hdGlvbkNvbXBvbmVudCxcblx0XHRHdFRhYmxlSW5mb0NvbXBvbmVudCxcblx0XHRHdFJlbmRlclBpcGUsXG5cdFx0R3RDb2x1bW5DbGFzc1BpcGUsXG5cdFx0R3RQcm9wZXJ0eVBpcGUsXG5cdFx0R3RIaWdobGlnaHRQaXBlLFxuXHRcdEd0RXhwYW5kaW5nUm93Q29tcG9uZW50LFxuXHRcdEd0RHJvcGRvd25Db21wb25lbnQsXG5cdFx0R3REcmlsbGRvd25Db21wb25lbnQsXG5cdFx0R3RDaGVja2JveENvbXBvbmVudFxuXHRdLFxuXHRlbnRyeUNvbXBvbmVudHM6IFtHdERyaWxsZG93bkNvbXBvbmVudCwgR3RDaGVja2JveENvbXBvbmVudF0sXG5cdHByb3ZpZGVyczogW0d0TWV0YVBpcGUsIEd0SGlnaGxpZ2h0UGlwZV1cbn0pXG5leHBvcnQgY2xhc3MgR2VuZXJpY1RhYmxlTW9kdWxlIHt9XG4iXSwibmFtZXMiOlsidHNsaWJfMS5fX2V4dGVuZHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOzs7Ozs7Ozs7O0lBT0MsOEJBQVM7Ozs7Ozs7SUFBVCxVQUNDLE9BQXFCLEVBQ3JCLFFBQWlCLEVBQ2pCLElBQWEsRUFDYixZQUFxQjtRQUVyQixLQUFLLHFCQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUU7Z0JBQzFCLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsUUFBUTtzQkFDNUIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztzQkFDcEIsSUFBSTswQkFDSCxJQUFJLEdBQUcsWUFBWTs0QkFDbkIsQ0FBQzs0QkFDRCxHQUFHOzRCQUNILElBQUksQ0FBQyxNQUFNLEVBQUU7aUNBQ1osUUFBUSxDQUFDLEVBQUUsQ0FBQztpQ0FDWixNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQzswQkFDZCxDQUFDOzRCQUNELEdBQUc7NEJBQ0gsSUFBSSxDQUFDLE1BQU0sRUFBRTtpQ0FDWixRQUFRLENBQUMsRUFBRSxDQUFDO2lDQUNaLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDbkI7WUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixFQUFFO2dCQUNwQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO2FBQ25DO1NBQ0Q7UUFDRCxP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