@angular-generic-table/core 5.0.0-alpha.2 → 5.0.0-rc.11

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