@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,1813 +0,0 @@
1
- /**
2
- * @fileoverview added by tsickle
3
- * @suppress {checkTypes} checked by tsc
4
- */
5
- import * as tslib_1 from "tslib";
6
- import { Component, EventEmitter, Input, Output, Renderer2, Type } from '@angular/core';
7
- import { GtMetaPipe } from '../../pipes/gt-meta.pipe';
8
- // unsupported: template constraints.
9
- // unsupported: template constraints.
10
- /**
11
- * @template R, C
12
- */
13
- var GenericTableComponent = /** @class */ (function () {
14
- function GenericTableComponent(renderer, gtMetaPipe) {
15
- var _this = this;
16
- this.renderer = renderer;
17
- this.gtMetaPipe = gtMetaPipe;
18
- this.columnWidth = {};
19
- this.sortOrder = [];
20
- this.metaInfo = {};
21
- this.selectedRows = [];
22
- this.openRows = [];
23
- this._gtSettings = [];
24
- this._gtFields = [];
25
- this.gtDefaultTexts = {
26
- loading: 'Loading...',
27
- noData: 'No data',
28
- noMatchingData: 'No data matching results found',
29
- noVisibleColumnsHeading: 'No visible columns',
30
- noVisibleColumns: 'Please select at least one column to be visible.',
31
- tableInfo: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries.',
32
- tableInfoAfterSearch: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries (filtered from a total of #recordsAll entries).',
33
- csvDownload: 'download',
34
- sortLabel: 'Sort:',
35
- paginateNext: 'Next page',
36
- paginatePrevious: 'Previous page',
37
- inlineEditEdited: 'Press enter to save'
38
- };
39
- this.gtTexts = this.gtDefaultTexts;
40
- this.gtEvent = new EventEmitter();
41
- this.gtDefaultOptions = {
42
- csvDelimiter: ';',
43
- stack: false,
44
- lazyLoad: false,
45
- cache: false,
46
- debounceTime: 200,
47
- highlightSearch: false,
48
- rowSelection: false,
49
- rowSelectionAllowMultiple: true,
50
- rowExpandAllowMultiple: true,
51
- numberOfRows: 10,
52
- reportColumnWidth: false,
53
- allowUnsorted: true,
54
- mutateData: true
55
- };
56
- this._gtOptions = this.gtDefaultOptions;
57
- this.store = [];
58
- this.loading = true;
59
- this.debounceTimer = null;
60
- this.lazyAllSelected = false;
61
- this.gtInfo = {
62
- pageCurrent: 1,
63
- pageTotal: 0,
64
- recordFrom: 0,
65
- recordTo: 0,
66
- recordLength: this.gtOptions.numberOfRows,
67
- recordsAll: 0,
68
- recordsAfterFilter: 0,
69
- recordsAfterSearch: 0
70
- };
71
- this.refreshPipe = false;
72
- this.refreshTotals = false;
73
- this.refreshSorting = false;
74
- this.refreshFilter = false;
75
- this.refreshPageArray = false;
76
- this.editedRows = {};
77
- this.data = { exportData: [] };
78
- /**
79
- * Sort table by object key.
80
- * @param objectKey - name of key to sort on.
81
- * @param event - such as key press during sorting.
82
- */
83
- this.gtSort = function (objectKey, event) {
84
- this.inlineEditCancel(); // cancel inline editing
85
- // loop through current settings
86
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
87
- if (this._gtSettings[i].objectKey === objectKey) {
88
- // check if sorting is disabled...
89
- if (this._gtSettings[i].sort &&
90
- this._gtSettings[i].sort.indexOf('disable') !== -1) {
91
- // ...if so, exit function without applying any sorting
92
- return;
93
- }
94
- else if (/* check if sorting is undefined... */ typeof this._gtSettings[i]
95
- .sort === 'undefined') {
96
- // ...is so, set sorting property to enable
97
- this._gtSettings[i].sort = 'enable';
98
- }
99
- }
100
- }
101
- // check length
102
- var /** @type {?} */ ctrlKey = event.metaKey || event.ctrlKey;
103
- var /** @type {?} */ sort = this.sortOrder.slice(0);
104
- var /** @type {?} */ match = -1;
105
- var /** @type {?} */ matchDesc = -1;
106
- var /** @type {?} */ pos = -1;
107
- // check if property already exits
108
- for (var /** @type {?} */ i = 0; i < sort.length; i++) {
109
- var /** @type {?} */ hit = sort[i].indexOf(objectKey);
110
- if (hit !== -1) {
111
- match = this.sortOrder.indexOf(objectKey);
112
- matchDesc =
113
- match === -1 ? this.sortOrder.indexOf('-' + objectKey) : match;
114
- pos = Math.max(match, matchDesc);
115
- }
116
- }
117
- // if ctrl key or meta key is press together with sort...
118
- if (ctrlKey) {
119
- if (this.sortOrder[this.sortOrder.length - 1] === '$$gtInitialRowIndex') {
120
- this.sortOrder.pop();
121
- }
122
- switch (pos) {
123
- // ...and property is not sorted before...
124
- case -1:
125
- // ...add property to sorting
126
- this.sortOrder.push(objectKey);
127
- break;
128
- default:
129
- // ...and property is sorted before...
130
- if (match !== -1) {
131
- // ...change from asc to desc if sorted asc
132
- this.sortOrder[pos] = '-' + objectKey;
133
- }
134
- else if (this.sortOrder.length > 1) {
135
- // ...remove sorting if sorted desc
136
- if (ctrlKey) {
137
- this.sortOrder[pos] = objectKey;
138
- }
139
- else {
140
- this.sortOrder.splice(pos, 1);
141
- }
142
- }
143
- else if (this.sortOrder.length === 1) {
144
- // ...set sorting to asc if only sorted property
145
- this.sortOrder[pos] = objectKey;
146
- }
147
- break;
148
- }
149
- }
150
- else {
151
- /* if ctrl key or meta key is not press together with sort... */
152
- switch (pos) {
153
- // ...and property is not sorted before...
154
- case -1:
155
- // ...sort by property
156
- this.sortOrder = [objectKey];
157
- break;
158
- default:
159
- // ...change from desc to asc and vise versa
160
- this.sortOrder =
161
- match !== -1
162
- ? ['-' + objectKey]
163
- : ctrlKey || !this.gtOptions.allowUnsorted
164
- ? [objectKey]
165
- : [];
166
- break;
167
- }
168
- }
169
- // update settings object with new sorting information
170
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
171
- if (this._gtSettings[i].objectKey === objectKey) {
172
- switch (this._gtSettings[i].sort) {
173
- // if sorted asc...
174
- case 'asc':
175
- // ...change to desc
176
- this._gtSettings[i].sort = 'desc';
177
- break;
178
- // if sorted desc...
179
- case 'desc':
180
- // ...change to asc if it's the only sorted property otherwise remove sorting
181
- this._gtSettings[i].sort =
182
- (this.sortOrder.length === 1 && sort.length < 2) ||
183
- ctrlKey ||
184
- !this.gtOptions.allowUnsorted
185
- ? 'asc'
186
- : 'enable';
187
- break;
188
- // if sorting enabled...
189
- case 'enable':
190
- // ...change to asc
191
- this._gtSettings[i].sort = 'asc';
192
- break;
193
- }
194
- this._gtSettings[i].sortOrder =
195
- this._gtSettings[i].sort === 'enable'
196
- ? this._gtSettings.length - 1
197
- : this.sortOrder.indexOf(objectKey) === -1
198
- ? this.sortOrder.indexOf('-' + objectKey)
199
- : this.sortOrder.indexOf(objectKey);
200
- }
201
- else if (this._gtSettings[i].sort &&
202
- this._gtSettings[i].sort.indexOf('disable') === -1 &&
203
- this.sortOrder.indexOf(this._gtSettings[i].objectKey) === -1 &&
204
- this.sortOrder.indexOf('-' + this._gtSettings[i].objectKey) === -1) {
205
- this._gtSettings[i].sort = 'enable';
206
- this._gtSettings[i].sortOrder = this._gtSettings.length - 1;
207
- }
208
- }
209
- // refresh sorting pipe
210
- this.refreshSorting = !this.refreshSorting;
211
- this.refreshPageArray = !this.refreshPageArray;
212
- // sort by initial sort order as last resort
213
- this.sortOrder.push('$$gtInitialRowIndex');
214
- // emit sort event
215
- this.gtEvent.emit({
216
- name: 'gt-sorting-applied',
217
- value: this.sortOrder
218
- });
219
- };
220
- /**
221
- * Change number of rows to be displayed.
222
- * @param rowLength - total number of rows.
223
- * @param reset - should page be reset to first page.
224
- */
225
- this.changeRowLength = function (rowLength, reset) {
226
- var /** @type {?} */ lengthValue = isNaN(parseInt(rowLength, 10))
227
- ? 0
228
- : parseInt(rowLength, 10);
229
- var /** @type {?} */ newPosition = 1;
230
- if (!lengthValue && this.gtData) {
231
- lengthValue = this.gtData.length;
232
- }
233
- // if reset is not true and we're not lazy loading data...
234
- if (reset !== true && this._gtOptions.lazyLoad !== true) {
235
- // ...get current position in record set
236
- var /** @type {?} */ currentRecord = this.gtInfo.recordLength * (this.gtInfo.pageCurrent - 1);
237
- var /** @type {?} */ currentPosition = this._gtData.indexOf(this._gtData[currentRecord]) + 1;
238
- // ...get new position
239
- newPosition = Math.ceil(currentPosition / lengthValue);
240
- }
241
- // change row length
242
- this.gtInfo.recordLength = lengthValue;
243
- // go to new position
244
- this.gtInfo.pageCurrent = newPosition;
245
- // if lazy loading data...
246
- if (this._gtOptions.lazyLoad) {
247
- // ...replace data with place holders for new data
248
- this._gtData[0] = this.loadingContent(lengthValue);
249
- // ...empty current store
250
- this.store = [];
251
- }
252
- // this.updateRecordRange();
253
- this.gtEvent.emit({
254
- name: 'gt-row-length-changed',
255
- value: lengthValue
256
- });
257
- };
258
- /**
259
- * Force a redraw of table rows.
260
- * As the table uses pure pipes, we need to force a redraw if an object in the array is changed to see the changes.
261
- */
262
- this.redraw = function ($event) {
263
- this.refreshSorting = !this.refreshSorting;
264
- this.refreshPageArray = !this.refreshPageArray;
265
- this.refreshPipe = !this.refreshPipe;
266
- };
267
- /**
268
- * Go to next page.
269
- */
270
- this.nextPage = function () {
271
- var /** @type {?} */ page = this.gtInfo.pageCurrent === this.gtInfo.pageTotal
272
- ? this.gtInfo.pageTotal
273
- : this.gtInfo.pageCurrent + 1;
274
- this.goToPage(page);
275
- };
276
- /**
277
- * Go to previous page.
278
- */
279
- this.previousPage = function () {
280
- var /** @type {?} */ page = this.gtInfo.pageCurrent === 1 ? 1 : this.gtInfo.pageCurrent - 1;
281
- this.goToPage(page);
282
- };
283
- /**
284
- * Request more data (used when lazy loading)
285
- */
286
- this.getData = function () {
287
- // ...emit event requesting for more data
288
- this.gtEvent.emit({
289
- name: 'gt-page-changed-lazy',
290
- value: {
291
- pageCurrent: this.gtInfo.pageCurrent,
292
- recordLength: this.gtInfo.recordLength
293
- }
294
- });
295
- };
296
- /**
297
- * Go to specific page.
298
- * @param page - page number.
299
- */
300
- this.goToPage = function (page) {
301
- var _this = this;
302
- var /** @type {?} */ previousPage = this.gtInfo.pageCurrent;
303
- this.gtInfo.pageCurrent = page;
304
- this.inlineEditCancel(); // cancel inline edit
305
- // if lazy loading and if page contains no records...
306
- if (this._gtOptions.lazyLoad) {
307
- // ...if data for current page contains no entries...
308
- if (this._gtOptions.cache === false ||
309
- this._gtData[this.gtInfo.pageCurrent - 1].length === 0) {
310
- // ...create temporary content while waiting for data
311
- this._gtData[this.gtInfo.pageCurrent - 1] = this.loadingContent(this.gtInfo.recordLength);
312
- this.loading = true; // loading true
313
- }
314
- // ...if first entry in current page equals our loading placeholder...
315
- if (this._gtData[this.gtInfo.pageCurrent - 1][0][this.loadingProperty] ===
316
- this.gtTexts.loading) {
317
- // ...get data
318
- clearTimeout(this.debounceTimer);
319
- this.debounceTimer = setTimeout(function () {
320
- _this.getData();
321
- }, this._gtOptions.debounceTime);
322
- }
323
- }
324
- // this.updateRecordRange();
325
- // ...emit page change event
326
- if (previousPage !== page) {
327
- this.gtEvent.emit({
328
- name: 'gt-page-changed',
329
- value: {
330
- pageCurrent: this.gtInfo.pageCurrent,
331
- pagePrevious: previousPage,
332
- recordLength: this.gtInfo.recordLength
333
- }
334
- });
335
- }
336
- };
337
- /**
338
- * Sort by sort order
339
- */
340
- this.getSortOrder = function (a, b) {
341
- if (a.sortOrder < b.sortOrder) {
342
- return -1;
343
- }
344
- if (a.sortOrder > b.sortOrder || typeof a.sortOrder === 'undefined') {
345
- return 1;
346
- }
347
- return 0;
348
- };
349
- /**
350
- * Sort by column order
351
- */
352
- this.getColumnOrder = function (a, b) {
353
- if (a.columnOrder === undefined) {
354
- return -1;
355
- }
356
- if (a.columnOrder < b.columnOrder) {
357
- return -1;
358
- }
359
- if (a.columnOrder > b.columnOrder) {
360
- return 1;
361
- }
362
- return 0;
363
- };
364
- /**
365
- * Create a deep copy of data
366
- */
367
- this.cloneDeep = function (o) {
368
- return JSON.parse(JSON.stringify(o));
369
- };
370
- /**
371
- * Return property
372
- */
373
- this.getProperty = function (array, key) {
374
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
375
- if (array[i].objectKey === key) {
376
- return array[i];
377
- }
378
- }
379
- };
380
- this.restructureSorting = function () {
381
- /**
382
- * Check and store sort order upon initialization.
383
- * This is done by checking sort properties in the settings array of the table, if no sorting is defined
384
- * we'll sort the data by the first visible and enabled column in the table(ascending). Please note that actually
385
- * sorting have to be done server side when lazy loading data for obvious reasons.
386
- */
387
- var /** @type {?} */ sorting = [];
388
- if (this._gtSettings) {
389
- // ...sort settings by sort order
390
- this._gtSettings.sort(this.getSortOrder);
391
- // ...loop through settings
392
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
393
- var /** @type {?} */ setting = this._gtSettings[i];
394
- // ...if sorted ascending...
395
- if (setting.sort === 'asc') {
396
- // ... add to sorting
397
- sorting.push(setting.objectKey);
398
- }
399
- else if (setting.sort === 'desc') {
400
- /* ...else if sorted descending... */
401
- // ... add to sorting
402
- sorting.push('-' + setting.objectKey);
403
- }
404
- }
405
- // ...if no sorting applied...
406
- if (sorting.length === 0) {
407
- sorting.push('$$gtRowId');
408
- /*// ...sort settings by column order
409
- this._gtSettings.sort(this.getColumnOrder);
410
-
411
- // ...loop through settings
412
- for (let i = 0; i < this._gtSettings.length; i++) {
413
- const setting = this._gtSettings[i];
414
-
415
- // ...if column is enabled and visible...
416
- if (setting.enabled !== false && setting.visible !== false) {
417
- // ...add first match and exit function
418
- this.sortOrder = [this._gtSettings[i].objectKey];
419
- return;
420
- }
421
- }*/
422
- }
423
- }
424
- if (this.sortOrder.length === 0) {
425
- this.sortOrder = sorting;
426
- }
427
- };
428
- /**
429
- * Extend object function.
430
- */
431
- this.extend = function (a, b) {
432
- for (var /** @type {?} */ key in b) {
433
- if (b.hasOwnProperty(key)) {
434
- a[key] = b[key];
435
- }
436
- }
437
- return a;
438
- };
439
- this.gtEvent.subscribe(function ($event) {
440
- if ($event.name === 'gt-info') {
441
- _this.updateRecordRange();
442
- }
443
- if ($event.name === 'gt-row-updated') {
444
- _this.updateTotals();
445
- }
446
- });
447
- }
448
- Object.defineProperty(GenericTableComponent.prototype, "gtRowComponent", {
449
- get: /**
450
- * @return {?}
451
- */
452
- function () {
453
- return this._gtRowComponent;
454
- },
455
- set: /**
456
- * @param {?} value
457
- * @return {?}
458
- */
459
- function (value) {
460
- 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');
461
- this._gtRowComponent = value;
462
- },
463
- enumerable: true,
464
- configurable: true
465
- });
466
- Object.defineProperty(GenericTableComponent.prototype, "hasEdits", {
467
- get: /**
468
- * @return {?}
469
- */
470
- function () {
471
- return Object.keys(this.editedRows).length > 0;
472
- },
473
- enumerable: true,
474
- configurable: true
475
- });
476
- Object.defineProperty(GenericTableComponent.prototype, "gtOptions", {
477
- get: /**
478
- * @return {?}
479
- */
480
- function () {
481
- return this._gtOptions;
482
- },
483
- set: /**
484
- * @param {?} value
485
- * @return {?}
486
- */
487
- function (value) {
488
- this._gtOptions = value;
489
- // if number of rows is passed and if number of rows differs from current record length...
490
- if (this.gtOptions.numberOfRows &&
491
- this.gtInfo.recordLength !== this.gtOptions.numberOfRows) {
492
- // ...update record length and redraw table
493
- this.gtInfo.recordLength = this.gtOptions.numberOfRows;
494
- this.redraw();
495
- }
496
- // ...extend gtOptions default values with values passed into component
497
- this._gtOptions = /** @type {?} */ (this.extend(this.gtDefaultOptions, this._gtOptions));
498
- },
499
- enumerable: true,
500
- configurable: true
501
- });
502
- Object.defineProperty(GenericTableComponent.prototype, "gtTotals", {
503
- get: /**
504
- * @return {?}
505
- */
506
- function () {
507
- return this._gtTotals;
508
- },
509
- set: /**
510
- * @param {?} value
511
- * @return {?}
512
- */
513
- function (value) {
514
- this._gtTotals = value;
515
- },
516
- enumerable: true,
517
- configurable: true
518
- });
519
- Object.defineProperty(GenericTableComponent.prototype, "gtFields", {
520
- get: /**
521
- * @return {?}
522
- */
523
- function () {
524
- return this._gtFields;
525
- },
526
- set: /**
527
- * @param {?} value
528
- * @return {?}
529
- */
530
- function (value) {
531
- this._gtFields = value;
532
- var /** @type {?} */ COLUMNS_WITH_CLASS_NAMES = this._gtFields
533
- .map(function (column) { return column; })
534
- .filter(function (column) { return column.classNames; });
535
- // TODO: remove deprecated warning when setting has been removed
536
- if (COLUMNS_WITH_CLASS_NAMES.length > 0) {
537
- 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: ' +
538
- COLUMNS_WITH_CLASS_NAMES[0].objectKey);
539
- }
540
- },
541
- enumerable: true,
542
- configurable: true
543
- });
544
- Object.defineProperty(GenericTableComponent.prototype, "gtSettings", {
545
- get: /**
546
- * @return {?}
547
- */
548
- function () {
549
- return this._gtSettings;
550
- },
551
- set: /**
552
- * @param {?} value
553
- * @return {?}
554
- */
555
- function (value) {
556
- this._gtSettings = value;
557
- // loop through current settings
558
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
559
- // set sort enabled/disabled setting
560
- this._gtSettings[i].sortEnabled =
561
- this._gtSettings[i].sortEnabled !== false
562
- ? (this._gtSettings[i].sortEnabled = !(this._gtSettings[i].sort &&
563
- this._gtSettings[i].sort.indexOf('disable') !== -1))
564
- : false;
565
- // check if sorting is undefined...
566
- if (typeof this._gtSettings[i].sort === 'undefined') {
567
- // ...is so, set sorting property to enable
568
- this._gtSettings[i].sort = 'enable';
569
- }
570
- // check if column order is undefined...
571
- if (typeof this._gtSettings[i].columnOrder === 'undefined' &&
572
- this._gtSettings[i].enabled !== false) {
573
- // ...is so, set sorting property to enable
574
- this._gtSettings[i].columnOrder = this._gtSettings[i - 1]
575
- ? this._gtSettings[i - 1].columnOrder + 1
576
- : 0;
577
- }
578
- // check if column lock settings are undefined...
579
- if (typeof this._gtSettings[i].lockSettings === 'undefined') {
580
- // ...if so, set lock settings to false unless field is disabled (enable === false)
581
- this._gtSettings[i].lockSettings =
582
- this._gtSettings[i].enabled === false || false;
583
- }
584
- }
585
- this.restructureSorting();
586
- },
587
- enumerable: true,
588
- configurable: true
589
- });
590
- Object.defineProperty(GenericTableComponent.prototype, "gtData", {
591
- get: /**
592
- * @return {?}
593
- */
594
- function () {
595
- return this._gtData;
596
- },
597
- set: /**
598
- * @param {?} initialData
599
- * @return {?}
600
- */
601
- function (initialData) {
602
- var _this = this;
603
- var /** @type {?} */ data = this._gtOptions.mutateData
604
- ? tslib_1.__spread(initialData) : this.cloneDeep(initialData);
605
- if (this.gtOptions.lazyLoad && this.gtInfo) {
606
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex, this.gtInfo.pageCurrent - 1, this.gtInfo.recordLength);
607
- if (this.lazyAllSelected) {
608
- var /** @type {?} */ UNIQUE_ROWS_1 = this.selectedRows.map(function (row) { return row.$$gtRowId; });
609
- data.map(function (row) {
610
- if (UNIQUE_ROWS_1.indexOf(row.$$gtRowId) === -1) {
611
- _this.selectedRows.push(row);
612
- }
613
- });
614
- this._updateMetaInfo(this.selectedRows, 'isSelected', true);
615
- }
616
- }
617
- else {
618
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex);
619
- }
620
- if (this.gtOptions.rowSelectionInitialState) {
621
- data.map(function (row) {
622
- var /** @type {?} */ selected = typeof _this.gtOptions.rowSelectionInitialState === 'function'
623
- ? _this.gtOptions.rowSelectionInitialState(row)
624
- : _this.gtOptions.rowSelectionInitialState;
625
- if (selected) {
626
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
627
- _this.metaInfo[row.$$gtRowId] = { isSelected: true };
628
- }
629
- else {
630
- _this.metaInfo[row.$$gtRowId].isSelected = true;
631
- }
632
- _this.selectedRows.push(row);
633
- }
634
- });
635
- }
636
- if (this.gtOptions.rowExpandInitialState &&
637
- this.gtOptions.rowExpandInitialComponent) {
638
- data.map(function (row) {
639
- var /** @type {?} */ expanded = typeof _this.gtOptions.rowExpandInitialState === 'function'
640
- ? _this.gtOptions.rowExpandInitialState(row)
641
- : _this.gtOptions.rowExpandInitialState;
642
- _this.expandedRow = _this.gtOptions.rowExpandInitialComponent;
643
- if (expanded) {
644
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
645
- _this.metaInfo[row.$$gtRowId] = { isOpen: true };
646
- }
647
- else {
648
- _this.metaInfo[row.$$gtRowId].isOpen = true;
649
- }
650
- }
651
- });
652
- }
653
- this._gtData = data;
654
- },
655
- enumerable: true,
656
- configurable: true
657
- });
658
- /**
659
- * Update record range.
660
- * @return {?}
661
- */
662
- GenericTableComponent.prototype.updateRecordRange = /**
663
- * Update record range.
664
- * @return {?}
665
- */
666
- function () {
667
- this.gtInfo.recordFrom =
668
- this.gtInfo.recordsAfterSearch === 0
669
- ? 0
670
- : (this.gtInfo.pageCurrent - 1) * this.gtInfo.recordLength + 1;
671
- this.gtInfo.recordTo =
672
- this.gtInfo.recordsAfterSearch <
673
- this.gtInfo.pageCurrent * this.gtInfo.recordLength
674
- ? this.gtInfo.recordsAfterSearch
675
- : this.gtInfo.pageCurrent * this.gtInfo.recordLength;
676
- };
677
- /**
678
- * Update totals.
679
- * @return {?}
680
- */
681
- GenericTableComponent.prototype.updateTotals = /**
682
- * Update totals.
683
- * @return {?}
684
- */
685
- function () {
686
- this.refreshTotals = !this.refreshTotals;
687
- };
688
- /**
689
- * Get meta data for row.
690
- * @param {?} row
691
- * @return {?}
692
- */
693
- GenericTableComponent.prototype.getRowState = /**
694
- * Get meta data for row.
695
- * @param {?} row
696
- * @return {?}
697
- */
698
- function (row) {
699
- return typeof this.metaInfo[row.$$gtRowId] === 'undefined'
700
- ? null
701
- : this.metaInfo[row.$$gtRowId];
702
- };
703
- /**
704
- * Expand all rows.
705
- * @param {?} expandedRow - component to render when rows are expanded.
706
- * @return {?}
707
- */
708
- GenericTableComponent.prototype.expandAllRows = /**
709
- * Expand all rows.
710
- * @param {?} expandedRow - component to render when rows are expanded.
711
- * @return {?}
712
- */
713
- function (expandedRow) {
714
- this.expandedRow = expandedRow;
715
- this._toggleAllRowProperty('isOpen', true);
716
- };
717
- /**
718
- * Collapse all rows.
719
- * @return {?}
720
- */
721
- GenericTableComponent.prototype.collapseAllRows = /**
722
- * Collapse all rows.
723
- * @return {?}
724
- */
725
- function () {
726
- this._toggleAllRowProperty('isOpen', false);
727
- };
728
- /**
729
- * Select all rows.
730
- * @return {?}
731
- */
732
- GenericTableComponent.prototype.selectAllRows = /**
733
- * Select all rows.
734
- * @return {?}
735
- */
736
- function () {
737
- this._toggleAllRowProperty('isSelected', true);
738
- };
739
- /**
740
- * Deselect all rows.
741
- * @return {?}
742
- */
743
- GenericTableComponent.prototype.deselectAllRows = /**
744
- * Deselect all rows.
745
- * @return {?}
746
- */
747
- function () {
748
- this._toggleAllRowProperty('isSelected', false);
749
- };
750
- /**
751
- * Toggle all rows.
752
- * @return {?}
753
- */
754
- GenericTableComponent.prototype.toggleAllRows = /**
755
- * Toggle all rows.
756
- * @return {?}
757
- */
758
- function () {
759
- if (this._gtOptions.lazyLoad) {
760
- if (!this.lazyAllSelected || this.selectedRows.length === 0) {
761
- this.selectAllRows();
762
- this.lazyAllSelected = true;
763
- }
764
- else {
765
- this.deselectAllRows();
766
- this.lazyAllSelected = false;
767
- }
768
- }
769
- else {
770
- if (this.selectedRows.length !== this.gtData.length) {
771
- this.selectAllRows();
772
- }
773
- else {
774
- this.deselectAllRows();
775
- }
776
- }
777
- };
778
- /**
779
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
780
- * @param {?} row - row object that should be expanded/collapsed.
781
- * @param {?=} expandedRow - component to render when row is expanded.
782
- * @return {?}
783
- */
784
- GenericTableComponent.prototype.toggleCollapse = /**
785
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
786
- * @param {?} row - row object that should be expanded/collapsed.
787
- * @param {?=} expandedRow - component to render when row is expanded.
788
- * @return {?}
789
- */
790
- function (row, expandedRow) {
791
- if (expandedRow) {
792
- this.expandedRow = expandedRow;
793
- }
794
- this._toggleRowProperty(row, 'isOpen');
795
- };
796
- /**
797
- * Toggle row selected state ie. selected or not.
798
- * @param {?} row - row object that should be selected/deselected.
799
- * @return {?}
800
- */
801
- GenericTableComponent.prototype.toggleSelect = /**
802
- * Toggle row selected state ie. selected or not.
803
- * @param {?} row - row object that should be selected/deselected.
804
- * @return {?}
805
- */
806
- function (row) {
807
- this._toggleRowProperty(row, 'isSelected');
808
- };
809
- /**
810
- * @param {?} row
811
- * @param {?} $event
812
- * @return {?}
813
- */
814
- GenericTableComponent.prototype.rowClick = /**
815
- * @param {?} row
816
- * @param {?} $event
817
- * @return {?}
818
- */
819
- function (row, $event) {
820
- this.gtEvent.emit({
821
- name: 'gt-row-clicked',
822
- value: { row: row, event: $event }
823
- });
824
- };
825
- /**
826
- * Update row data.
827
- * @param {?} row - row object that has been edited.
828
- * @param {?} oldValue - row object before edit.
829
- * @return {?}
830
- */
831
- GenericTableComponent.prototype.updateRow = /**
832
- * Update row data.
833
- * @param {?} row - row object that has been edited.
834
- * @param {?} oldValue - row object before edit.
835
- * @return {?}
836
- */
837
- function (row, oldValue) {
838
- this._toggleRowProperty(row, 'isUpdated', oldValue);
839
- };
840
- /**
841
- * removes a row from the table
842
- * @param {?} row - the row object to remove
843
- * @return {?}
844
- */
845
- GenericTableComponent.prototype.removeRow = /**
846
- * removes a row from the table
847
- * @param {?} row - the row object to remove
848
- * @return {?}
849
- */
850
- function (row) {
851
- if (this.isRowSelected(row)) {
852
- this.toggleSelect(row);
853
- }
854
- var /** @type {?} */ index = this._gtData.indexOf(row);
855
- this._gtData.splice(index, 1);
856
- };
857
- /**
858
- * check if a row is selected
859
- * @param {?} row - row object
860
- * @return {?}
861
- */
862
- GenericTableComponent.prototype.isRowSelected = /**
863
- * check if a row is selected
864
- * @param {?} row - row object
865
- * @return {?}
866
- */
867
- function (row) {
868
- return (this.metaInfo[row.$$gtRowId] && this.metaInfo[row.$$gtRowId].isSelected);
869
- };
870
- /**
871
- * Update meta info for all rows, ie. isSelected, isOpen.
872
- * @param {?} array - array that holds rows that need to be updated.
873
- * @param {?} property - name of property that should be changed/toggled.
874
- * @param {?} active - should rows be expanded/open, selected.
875
- * @param {?=} exception - update all rows except this one.
876
- * @return {?}
877
- */
878
- GenericTableComponent.prototype._updateMetaInfo = /**
879
- * Update meta info for all rows, ie. isSelected, isOpen.
880
- * @param {?} array - array that holds rows that need to be updated.
881
- * @param {?} property - name of property that should be changed/toggled.
882
- * @param {?} active - should rows be expanded/open, selected.
883
- * @param {?=} exception - update all rows except this one.
884
- * @return {?}
885
- */
886
- function (array, property, active, exception) {
887
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
888
- if (!this.metaInfo[array[i].$$gtRowId]) {
889
- this.metaInfo[array[i].$$gtRowId] = {};
890
- }
891
- if (exception && array[i].$$gtRowId === exception.$$gtRowId) {
892
- }
893
- else {
894
- this.metaInfo[array[i].$$gtRowId][property] = active;
895
- }
896
- }
897
- };
898
- /**
899
- * Push selected/expanded lazy loaded rows to array with meta data.
900
- * @param {?} target - array to which rows should be added.
901
- * @param {?} source - array that holds rows that should be added.
902
- * @return {?} array with added rows.
903
- */
904
- GenericTableComponent.prototype._pushLazyRows = /**
905
- * Push selected/expanded lazy loaded rows to array with meta data.
906
- * @param {?} target - array to which rows should be added.
907
- * @param {?} source - array that holds rows that should be added.
908
- * @return {?} array with added rows.
909
- */
910
- function (target, source) {
911
- var /** @type {?} */ UNIQUE_ROWS = target.map(function (row) { return row.$$gtRowId; });
912
- for (var /** @type {?} */ i = 0; i < source.length; i++) {
913
- // only add if not already in list
914
- if (UNIQUE_ROWS.indexOf(source[i].$$gtRowId) === -1) {
915
- target.push(source[i]);
916
- }
917
- }
918
- return target;
919
- };
920
- /**
921
- * Toggle meta info for all rows, ie. isSelected, isOpen.
922
- * @param {?} property - name of property that should be changed/toggled.
923
- * @param {?} active - should rows be expanded/open, selected.
924
- * @return {?}
925
- */
926
- GenericTableComponent.prototype._toggleAllRowProperty = /**
927
- * Toggle meta info for all rows, ie. isSelected, isOpen.
928
- * @param {?} property - name of property that should be changed/toggled.
929
- * @param {?} active - should rows be expanded/open, selected.
930
- * @return {?}
931
- */
932
- function (property, active) {
933
- var /** @type {?} */ eventName;
934
- var /** @type {?} */ eventValue;
935
- switch (property) {
936
- case 'isOpen':
937
- // check if multiple expanded rows are allowed...
938
- if (this._gtOptions.rowExpandAllowMultiple === false) {
939
- // ...if not, exit function
940
- console.log('feature disabled: enable by setting "rowExpandAllowMultiple = true"');
941
- return;
942
- }
943
- if (active) {
944
- eventName = 'expand-all';
945
- this.openRows = this._gtOptions.lazyLoad
946
- ? this._pushLazyRows(this.openRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
947
- : this._gtData.slice();
948
- this._updateMetaInfo(this.openRows, property, active);
949
- }
950
- else {
951
- eventName = 'collapse-all';
952
- this._updateMetaInfo(this.openRows, property, active);
953
- this.openRows = [];
954
- }
955
- eventValue = {
956
- expandedRows: this.openRows,
957
- changedRow: 'all'
958
- };
959
- break;
960
- case 'isSelected':
961
- // check if multi row selection is allowed...
962
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
963
- // ...if not, exit function
964
- console.log('feature disabled: enable by setting "rowSelectionAllowMultiple = true"');
965
- return;
966
- }
967
- if (active) {
968
- eventName = 'select-all';
969
- this.selectedRows = this._gtOptions.lazyLoad
970
- ? this._pushLazyRows(this.selectedRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
971
- : this._gtData.slice();
972
- this._updateMetaInfo(this.selectedRows, property, active);
973
- }
974
- else {
975
- eventName = 'deselect-all';
976
- this._updateMetaInfo(this.selectedRows, property, active);
977
- this.selectedRows = [];
978
- }
979
- eventValue = {
980
- selectedRows: this.selectedRows,
981
- changedRow: 'all'
982
- };
983
- break;
984
- }
985
- this.gtEvent.emit({
986
- name: 'gt-row-' + eventName,
987
- value: eventValue
988
- });
989
- };
990
- /**
991
- * Toggle meta info for row, ie. isSelected, isOpen.
992
- * @param {?} row - row object.
993
- * @param {?} property - name of property that should be changed/toggled.
994
- * @param {?=} propertyValues - optional property values that can be passed.
995
- * @return {?}
996
- */
997
- GenericTableComponent.prototype._toggleRowProperty = /**
998
- * Toggle meta info for row, ie. isSelected, isOpen.
999
- * @param {?} row - row object.
1000
- * @param {?} property - name of property that should be changed/toggled.
1001
- * @param {?=} propertyValues - optional property values that can be passed.
1002
- * @return {?}
1003
- */
1004
- function (row, property, propertyValues) {
1005
- var /** @type {?} */ eventName;
1006
- var /** @type {?} */ eventValue;
1007
- // make sure gtRowId exists on row object
1008
- if (typeof row.$$gtRowId !== 'undefined') {
1009
- // check if meta info exists for row
1010
- if (!this.metaInfo[row.$$gtRowId]) {
1011
- // if not, add object to store meta info
1012
- this.metaInfo[row.$$gtRowId] = {};
1013
- }
1014
- switch (property) {
1015
- case 'isOpen':
1016
- var /** @type {?} */ opened = this.metaInfo[row.$$gtRowId][property];
1017
- // check if multiple expanded rows are allowed...
1018
- if (this._gtOptions.rowExpandAllowMultiple === false) {
1019
- // ...if not, collapse all rows except current row
1020
- this._updateMetaInfo(this.openRows, property, false, row);
1021
- this.openRows = [];
1022
- }
1023
- // check if row is expanded
1024
- if (!opened) {
1025
- eventName = 'expand';
1026
- // add row to expanded rows
1027
- this.openRows.push(row);
1028
- }
1029
- else {
1030
- eventName = 'collapse';
1031
- // loop through expanded rows...
1032
- for (var /** @type {?} */ i = 0; i < this.openRows.length; i++) {
1033
- // if expanded row equals passed row...
1034
- if (this.openRows[i].$$gtRowId === row.$$gtRowId) {
1035
- // ...remove row from expanded rows...
1036
- this.openRows.splice(i, 1);
1037
- // ...and exit loop
1038
- break;
1039
- }
1040
- }
1041
- }
1042
- eventValue = {
1043
- expandedRows: this.openRows,
1044
- changedRow: row
1045
- };
1046
- break;
1047
- case 'isSelected':
1048
- var /** @type {?} */ selected = this.metaInfo[row.$$gtRowId][property];
1049
- // check if multi row selection is allowed...
1050
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
1051
- // ...if not, deselect all rows except current row
1052
- this._updateMetaInfo(this.selectedRows, property, false, row);
1053
- this.selectedRows = [];
1054
- }
1055
- // check if row is selected
1056
- if (!selected) {
1057
- eventName = 'select';
1058
- // add row to selected rows
1059
- this.selectedRows.push(row);
1060
- }
1061
- else {
1062
- if (this.gtOptions.lazyLoad && this.lazyAllSelected) {
1063
- this.lazyAllSelected = false;
1064
- }
1065
- eventName = 'deselect';
1066
- // loop through selected rows...
1067
- for (var /** @type {?} */ i = 0; i < this.selectedRows.length; i++) {
1068
- // if selected row equals passed row...
1069
- if (this.selectedRows[i].$$gtRowId === row.$$gtRowId) {
1070
- // ...remove row from selected rows...
1071
- this.selectedRows.splice(i, 1);
1072
- // ...and exit loop
1073
- break;
1074
- }
1075
- }
1076
- }
1077
- eventValue = {
1078
- selectedRows: this.selectedRows,
1079
- changedRow: row
1080
- };
1081
- break;
1082
- case 'isUpdated':
1083
- eventName = 'updated';
1084
- var /** @type {?} */ oldValue = propertyValues;
1085
- // check if edit object exists for row
1086
- if (typeof this.metaInfo[row.$$gtRowId][property] === 'undefined') {
1087
- this.metaInfo[row.$$gtRowId][property] = {
1088
- originalValue: oldValue,
1089
- oldValue: oldValue,
1090
- newValue: row
1091
- };
1092
- }
1093
- else {
1094
- this.metaInfo[row.$$gtRowId][property].oldValue = oldValue;
1095
- this.metaInfo[row.$$gtRowId][property].newValue = row;
1096
- }
1097
- eventValue = this.metaInfo[row.$$gtRowId][property];
1098
- this.redraw();
1099
- this.inlineEditCancel(row);
1100
- // this.gtData = [...this.gtData.map((r) => { return{...r}; })];
1101
- break;
1102
- }
1103
- this.gtEvent.emit({
1104
- name: 'gt-row-' + eventName,
1105
- value: eventValue
1106
- });
1107
- if (property !== 'isUpdated') {
1108
- this.metaInfo[row.$$gtRowId][property] = !this.metaInfo[row.$$gtRowId][property];
1109
- }
1110
- }
1111
- };
1112
- /**
1113
- * Update column.
1114
- * @param {?} $event - key up event.
1115
- * @param {?} row - row object.
1116
- * @param {?} column - column object.
1117
- * @return {?}
1118
- */
1119
- GenericTableComponent.prototype.gtUpdateColumn = /**
1120
- * Update column.
1121
- * @param {?} $event - key up event.
1122
- * @param {?} row - row object.
1123
- * @param {?} column - column object.
1124
- * @return {?}
1125
- */
1126
- function ($event, row, column) {
1127
- this._editRow(row, column);
1128
- };
1129
- /**
1130
- * Dropdown select.
1131
- * @param {?} row - row object.
1132
- * @param {?} column - column object.
1133
- * @return {?}
1134
- */
1135
- GenericTableComponent.prototype.gtDropdownSelect = /**
1136
- * Dropdown select.
1137
- * @param {?} row - row object.
1138
- * @param {?} column - column object.
1139
- * @return {?}
1140
- */
1141
- function (row, column) {
1142
- var /** @type {?} */ oldValue = tslib_1.__assign({}, row);
1143
- row[column.objectKey] = column.renderValue;
1144
- this.updateRow(row, oldValue);
1145
- };
1146
- /**
1147
- * @param {?} row
1148
- * @param {?} column
1149
- * @return {?}
1150
- */
1151
- GenericTableComponent.prototype._editRow = /**
1152
- * @param {?} row
1153
- * @param {?} column
1154
- * @return {?}
1155
- */
1156
- function (row, column) {
1157
- var /** @type {?} */ OBJECT_KEY = column.objectKey; // declare object key which contains changes
1158
- // check if cell has changed value
1159
- column.edited = row[column.objectKey] !== column.renderValue;
1160
- // check if row contains changes...
1161
- if (!this.editedRows[row.$$gtRowId]) {
1162
- // if not, create an object for the changed row
1163
- this.editedRows[row.$$gtRowId] = {
1164
- changes: {},
1165
- // create placeholder for changes
1166
- row: row // store reference to the row that should be updated
1167
- };
1168
- }
1169
- // store changed column under changes if it has been edited
1170
- if (column.edited) {
1171
- this.editedRows[row.$$gtRowId].changes[OBJECT_KEY] = column;
1172
- }
1173
- else {
1174
- // delete change object if column is unchanged
1175
- delete this.editedRows[row.$$gtRowId].changes[OBJECT_KEY];
1176
- // check how many columns have been changed
1177
- var /** @type {?} */ CHANGED_COLUMNS = Object.keys(this.editedRows[row.$$gtRowId].changes).length;
1178
- if (CHANGED_COLUMNS === 0) {
1179
- // delete row from edited rows if no columns have been edited
1180
- delete this.editedRows[row.$$gtRowId];
1181
- }
1182
- }
1183
- // if no listener is present...
1184
- if (!this.globalInlineEditListener) {
1185
- // ...listen for update event
1186
- this._listenForKeydownEvent();
1187
- }
1188
- };
1189
- /**
1190
- * Listen for key down event - listen for key down event during inline edit.
1191
- * @return {?}
1192
- */
1193
- GenericTableComponent.prototype._listenForKeydownEvent = /**
1194
- * Listen for key down event - listen for key down event during inline edit.
1195
- * @return {?}
1196
- */
1197
- function () {
1198
- var _this = this;
1199
- // add global listener for key down events
1200
- this.globalInlineEditListener = this.renderer.listen('document', 'keydown', function ($event) {
1201
- switch ($event.key) {
1202
- case 'Enter': // update data object
1203
- // update data object
1204
- _this.inlineEditUpdate();
1205
- break;
1206
- case 'Escape': // cancel
1207
- // cancel
1208
- _this.inlineEditCancel();
1209
- break;
1210
- }
1211
- });
1212
- };
1213
- /**
1214
- * Inline edit update - accept changes and update row values.
1215
- * @return {?}
1216
- */
1217
- GenericTableComponent.prototype.inlineEditUpdate = /**
1218
- * Inline edit update - accept changes and update row values.
1219
- * @return {?}
1220
- */
1221
- function () {
1222
- var _this = this;
1223
- // loop through rows that have been edited
1224
- Object.keys(this.editedRows).map(function (key) {
1225
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
1226
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
1227
- // loop through changes in row
1228
- Object.keys(CHANGES).map(function (objectKey) {
1229
- var /** @type {?} */ oldValue = tslib_1.__assign({}, ROW);
1230
- ROW[objectKey] = CHANGES[objectKey].renderValue; // update data value
1231
- _this.updateRow(ROW, oldValue); // update meta info for row and send event
1232
- CHANGES[objectKey].edited = false; // disable edit mode
1233
- });
1234
- });
1235
- // clear rows marked as edited as the rows have been updated
1236
- this.editedRows = {};
1237
- // remove listener
1238
- this._stopListeningForKeydownEvent();
1239
- };
1240
- /**
1241
- * Inline edit cancel - cancel and reset inline edits.
1242
- * @param {?=} row
1243
- * @return {?}
1244
- */
1245
- GenericTableComponent.prototype.inlineEditCancel = /**
1246
- * Inline edit cancel - cancel and reset inline edits.
1247
- * @param {?=} row
1248
- * @return {?}
1249
- */
1250
- function (row) {
1251
- var _this = this;
1252
- if (row) {
1253
- delete this.editedRows[row.$$gtRowId];
1254
- // remove listener
1255
- this._stopListeningForKeydownEvent();
1256
- return;
1257
- }
1258
- // loop through rows that have been edited
1259
- Object.keys(this.editedRows).map(function (key) {
1260
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
1261
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
1262
- // loop through changes in row
1263
- Object.keys(CHANGES).map(function (objectKey) {
1264
- CHANGES[objectKey].renderValue = ROW[objectKey]; // reset rendered value
1265
- CHANGES[objectKey].edited = false; // disable edit mode
1266
- });
1267
- });
1268
- // clear rows marked as edited as the rows have been updated
1269
- this.editedRows = {};
1270
- // remove listener
1271
- this._stopListeningForKeydownEvent();
1272
- };
1273
- /**
1274
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
1275
- * @return {?}
1276
- */
1277
- GenericTableComponent.prototype._stopListeningForKeydownEvent = /**
1278
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
1279
- * @return {?}
1280
- */
1281
- function () {
1282
- if (this.globalInlineEditListener) {
1283
- this.globalInlineEditListener();
1284
- this.globalInlineEditListener = null;
1285
- }
1286
- };
1287
- /**
1288
- * Apply filter(s).
1289
- * @param {?} filter - object containing key value pairs, where value should be array of values.
1290
- * @return {?}
1291
- */
1292
- GenericTableComponent.prototype.gtApplyFilter = /**
1293
- * Apply filter(s).
1294
- * @param {?} filter - object containing key value pairs, where value should be array of values.
1295
- * @return {?}
1296
- */
1297
- function (filter) {
1298
- this.gtInfo.filter = filter;
1299
- // go to first page
1300
- this.goToPage(1);
1301
- this.updateTotals();
1302
- };
1303
- /**
1304
- * Clear/remove applied filter(s).
1305
- * @return {?}
1306
- */
1307
- GenericTableComponent.prototype.gtClearFilter = /**
1308
- * Clear/remove applied filter(s).
1309
- * @return {?}
1310
- */
1311
- function () {
1312
- this.gtInfo.filter = false;
1313
- this.updateTotals();
1314
- // this.updateRecordRange();
1315
- };
1316
- /**
1317
- * Search
1318
- * @param {?} value - string containing one or more words
1319
- * @return {?}
1320
- */
1321
- GenericTableComponent.prototype.gtSearch = /**
1322
- * Search
1323
- * @param {?} value - string containing one or more words
1324
- * @return {?}
1325
- */
1326
- function (value) {
1327
- this.gtInfo.searchTerms = value;
1328
- // always go to first page when searching
1329
- this.goToPage(1);
1330
- this.updateTotals();
1331
- };
1332
- /**
1333
- * Add rows
1334
- * @param {?} rows - rows to add
1335
- * @return {?} new data array.
1336
- */
1337
- GenericTableComponent.prototype.gtAdd = /**
1338
- * Add rows
1339
- * @param {?} rows - rows to add
1340
- * @return {?} new data array.
1341
- */
1342
- function (rows) {
1343
- this.gtData = tslib_1.__spread(this.gtData, rows);
1344
- return tslib_1.__spread(this.gtData);
1345
- };
1346
- /**
1347
- * Delete row
1348
- * @param {?} objectKey - object key you want to find match with
1349
- * @param {?} value - the value that should be deleted
1350
- * @param {?=} match - all: delete all matches, first: delete first match (default)
1351
- * @return {?} new data array.
1352
- */
1353
- GenericTableComponent.prototype.gtDelete = /**
1354
- * Delete row
1355
- * @param {?} objectKey - object key you want to find match with
1356
- * @param {?} value - the value that should be deleted
1357
- * @param {?=} match - all: delete all matches, first: delete first match (default)
1358
- * @return {?} new data array.
1359
- */
1360
- function (objectKey, value, match) {
1361
- if (match === void 0) { match = 'first'; }
1362
- if (match === 'first') {
1363
- for (var /** @type {?} */ i = 0; i < this.gtData.length; i++) {
1364
- if (this.gtData[i][objectKey] === value) {
1365
- if (this.isRowSelected(this.gtData[i])) {
1366
- this.toggleSelect(this.gtData[i]);
1367
- }
1368
- this.gtData.splice(i, 1);
1369
- this.gtData = tslib_1.__spread(this.gtData);
1370
- if (match === 'first') {
1371
- break;
1372
- }
1373
- }
1374
- }
1375
- }
1376
- else {
1377
- for (var /** @type {?} */ i = this.gtData.length; i > 0; i--) {
1378
- if (this.gtData[i - 1][objectKey] === value) {
1379
- if (this.isRowSelected(this.gtData[i - 1])) {
1380
- this.toggleSelect(this.gtData[i - 1]);
1381
- }
1382
- this.gtData.splice(i - 1, 1);
1383
- this.gtData = tslib_1.__spread(this.gtData);
1384
- }
1385
- }
1386
- }
1387
- return tslib_1.__spread(this.gtData);
1388
- };
1389
- /**
1390
- * Create store to hold previously loaded records.
1391
- * @param {?} records - total number of records in store.
1392
- * @param {?} perPage - how many records to show per page.
1393
- * @return {?} a nested array to hold records per page.
1394
- */
1395
- GenericTableComponent.prototype.createStore = /**
1396
- * Create store to hold previously loaded records.
1397
- * @param {?} records - total number of records in store.
1398
- * @param {?} perPage - how many records to show per page.
1399
- * @return {?} a nested array to hold records per page.
1400
- */
1401
- function (records, perPage) {
1402
- var /** @type {?} */ stores = Math.ceil(records / perPage);
1403
- var /** @type {?} */ store = [];
1404
- for (var /** @type {?} */ i = 0; i < stores; i++) {
1405
- store[i] = [];
1406
- }
1407
- return store;
1408
- };
1409
- /**
1410
- * Create placeholders for rows while loading data from back-end.
1411
- * @param {?} perPage - how many records to show per page.
1412
- * @return {?} an array containing empty records to be presented while fetching real data.
1413
- */
1414
- GenericTableComponent.prototype.loadingContent = /**
1415
- * Create placeholders for rows while loading data from back-end.
1416
- * @param {?} perPage - how many records to show per page.
1417
- * @return {?} an array containing empty records to be presented while fetching real data.
1418
- */
1419
- function (perPage) {
1420
- // create row object
1421
- var /** @type {?} */ rowObject = {
1422
- $$loading: true
1423
- };
1424
- var /** @type {?} */ order = 0;
1425
- // sort settings by column order
1426
- this._gtSettings.sort(this.getColumnOrder);
1427
- // loop through all settings objects...
1428
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1429
- var /** @type {?} */ setting = this._gtSettings[i];
1430
- // ...if column is visible and enabled...
1431
- if (setting.visible !== false && setting.enabled !== false) {
1432
- // ...if first column, set value to loading text otherwise leave it empty
1433
- if (order === 0) {
1434
- rowObject[setting.objectKey] = this.gtTexts.loading;
1435
- this.loadingProperty = setting.objectKey;
1436
- }
1437
- else {
1438
- rowObject[setting.objectKey] = '';
1439
- }
1440
- order++;
1441
- }
1442
- else {
1443
- rowObject[setting.objectKey] = '';
1444
- }
1445
- }
1446
- // create content placeholder
1447
- var /** @type {?} */ contentPlaceholder = [];
1448
- // create equal number of rows as rows per page
1449
- for (var /** @type {?} */ i = 0; i < perPage; i++) {
1450
- // ...add temporary row object
1451
- contentPlaceholder.push(rowObject);
1452
- }
1453
- return contentPlaceholder;
1454
- };
1455
- /**
1456
- * Export data as CSV
1457
- * @param {?=} fileName - optional file name (overrides default file name).
1458
- * @param {?=} useBOM - use BOM (byte order marker).
1459
- * @return {?}
1460
- */
1461
- GenericTableComponent.prototype.exportCSV = /**
1462
- * Export data as CSV
1463
- * @param {?=} fileName - optional file name (overrides default file name).
1464
- * @param {?=} useBOM - use BOM (byte order marker).
1465
- * @return {?}
1466
- */
1467
- function (fileName, useBOM) {
1468
- var _this = this;
1469
- if (useBOM === void 0) { useBOM = false; }
1470
- var /** @type {?} */ data = this.data.exportData;
1471
- var /** @type {?} */ csv = '';
1472
- var /** @type {?} */ BOM = '\uFEFF';
1473
- // csv export headers
1474
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1475
- if (this._gtSettings[i].export !== false) {
1476
- csv += this.getProperty(this._gtFields, this._gtSettings[i].objectKey)
1477
- .name;
1478
- if (i < this._gtSettings.length - 1) {
1479
- csv += this._gtOptions.csvDelimiter;
1480
- }
1481
- }
1482
- }
1483
- // csv export body
1484
- data.forEach(function (row) {
1485
- csv += '\n';
1486
- for (var /** @type {?} */ i = 0; i < _this._gtSettings.length; i++) {
1487
- if (_this._gtSettings[i].export !== false) {
1488
- // get field settings
1489
- var /** @type {?} */ fieldSetting = _this.getProperty(_this._gtFields, _this._gtSettings[i].objectKey);
1490
- // get export value, if export function is defined use it otherwise check for value function and as a last resort export raw data
1491
- var /** @type {?} */ exportValue = fieldSetting.export && typeof fieldSetting.export === 'function'
1492
- ? fieldSetting.export(row)
1493
- : fieldSetting.value && typeof fieldSetting.value === 'function'
1494
- ? fieldSetting.value(row)
1495
- : row[_this._gtSettings[i].objectKey];
1496
- // escape export value using double quotes (") if export value contains delimiter
1497
- exportValue =
1498
- typeof exportValue === 'string' &&
1499
- exportValue.indexOf(_this._gtOptions.csvDelimiter) !== -1
1500
- ? '"' + exportValue + '"'
1501
- : exportValue;
1502
- csv += exportValue;
1503
- if (i < _this._gtSettings.length - 1) {
1504
- csv += _this._gtOptions.csvDelimiter;
1505
- }
1506
- }
1507
- }
1508
- });
1509
- var /** @type {?} */ blob = new Blob([(useBOM ? BOM : '') + csv], {
1510
- type: 'text/csv;charset=utf-8'
1511
- });
1512
- if (window.navigator.msSaveOrOpenBlob) {
1513
- navigator.msSaveOrOpenBlob(blob, fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
1514
- }
1515
- else {
1516
- var /** @type {?} */ link = document.createElement('a');
1517
- link.style.display = 'none';
1518
- document.body.appendChild(link);
1519
- if (link.download !== undefined) {
1520
- link.setAttribute('href', 'data:text/csv;charset=utf-8,' +
1521
- encodeURIComponent((useBOM ? BOM : '') + csv)); // URL.createObjectURL(blob));
1522
- link.setAttribute('download', fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
1523
- document.body.appendChild(link);
1524
- link.click();
1525
- }
1526
- else {
1527
- csv = 'data:text/csv;charset=utf-8,' + (useBOM ? BOM : '') + csv;
1528
- window.open(encodeURIComponent(csv));
1529
- }
1530
- document.body.removeChild(link);
1531
- }
1532
- // emit export event
1533
- this.gtEvent.emit({
1534
- name: 'gt-exported-csv',
1535
- value: fileName ? fileName : this.gtTexts.csvDownload + '.csv'
1536
- });
1537
- };
1538
- /**
1539
- * @return {?}
1540
- */
1541
- GenericTableComponent.prototype.ngOnInit = /**
1542
- * @return {?}
1543
- */
1544
- function () {
1545
- // if number of row to display from start is set to null or 0...
1546
- if (!this.gtOptions.numberOfRows) {
1547
- // ...change row length
1548
- this.changeRowLength(this.gtOptions.numberOfRows);
1549
- }
1550
- this.restructureSorting();
1551
- };
1552
- /**
1553
- * @param {?} changes
1554
- * @return {?}
1555
- */
1556
- GenericTableComponent.prototype.ngOnChanges = /**
1557
- * @param {?} changes
1558
- * @return {?}
1559
- */
1560
- function (changes) {
1561
- // if gt texts have changed...
1562
- if (changes['gtTexts']) {
1563
- // ...extend gtOptions default values with values passed into component
1564
- this.gtTexts = /** @type {?} */ (this.extend(this.gtDefaultTexts, this.gtTexts));
1565
- }
1566
- // if lazy loading data and paging information is available...
1567
- if (this.gtOptions.lazyLoad && this.gtInfo) {
1568
- // ...calculate total number of pages
1569
- this.gtInfo.pageTotal = Math.ceil(this.gtInfo.recordsAfterSearch / this.gtInfo.recordLength);
1570
- // ...declare store position
1571
- var /** @type {?} */ storePosition = this.gtInfo.pageCurrent - 1;
1572
- // ...and if store is empty or page length has changed...
1573
- if (this.store.length === 0 ||
1574
- this.store[0].length !== this.gtInfo.recordLength) {
1575
- // ...create store
1576
- this.store = this.createStore(this.gtInfo.recordsAfterSearch, this.gtInfo.recordLength);
1577
- }
1578
- // ...store retrieved data in store at store position
1579
- this.store[storePosition] = this.gtData;
1580
- this.gtInfo.visibleRecords = tslib_1.__spread(this.gtData); // add visible rows
1581
- // replace data with store
1582
- this._gtData = this.store;
1583
- this.loading = false;
1584
- this.updateRecordRange();
1585
- this.gtEvent.emit({
1586
- name: 'gt-info',
1587
- value: this.gtInfo
1588
- });
1589
- }
1590
- else if (this._gtData &&
1591
- this._gtData.length >= 0 &&
1592
- changes['gtData'] &&
1593
- changes['gtData'].previousValue) {
1594
- this.loading = false;
1595
- }
1596
- else if (changes['gtData'] &&
1597
- changes['gtData'].firstChange &&
1598
- this._gtData &&
1599
- this._gtData.length > 0) {
1600
- this.loading = false;
1601
- }
1602
- };
1603
- /**
1604
- * @param {?} index
1605
- * @param {?} item
1606
- * @return {?}
1607
- */
1608
- GenericTableComponent.prototype.trackByFn = /**
1609
- * @param {?} index
1610
- * @param {?} item
1611
- * @return {?}
1612
- */
1613
- function (index, item) {
1614
- return item.$$gtRowId;
1615
- };
1616
- /**
1617
- * @param {?} index
1618
- * @param {?} item
1619
- * @return {?}
1620
- */
1621
- GenericTableComponent.prototype.trackByColumnFn = /**
1622
- * @param {?} index
1623
- * @param {?} item
1624
- * @return {?}
1625
- */
1626
- function (index, item) {
1627
- return item.objectKey;
1628
- };
1629
- /**
1630
- * @return {?}
1631
- */
1632
- GenericTableComponent.prototype.ngOnDestroy = /**
1633
- * @return {?}
1634
- */
1635
- function () {
1636
- // remove listener
1637
- this._stopListeningForKeydownEvent();
1638
- };
1639
- GenericTableComponent.decorators = [
1640
- { type: Component, args: [{
1641
- selector: 'generic-table',
1642
- template: "<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length > 0\">\n <thead>\n <tr>\n <th class=\"gt-sort-label\" *ngIf=\"gtOptions.stack\">{{gtTexts.sortLabel}}</th>\n <th *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{column.sortEnabled ? 'sort-'+column.sort:''}} {{column.sortEnabled && column.sortOrder >= 0 ? 'sort-order-'+column.sortOrder:''}} {{ gtFields | gtColumnClass:column }}\"\n (click)=\"column.sortEnabled ? gtSort(column.objectKey,$event):'';\">\n <span *ngIf=\"!(gtFields | gtProperty:column.objectKey:'header')\">{{gtFields | gtProperty:column.objectKey:'name'}}</span>\n <gt-custom-component-factory *ngIf=\"(gtFields | gtProperty:column.objectKey:'header')\"\n [type]=\"(gtFields | gtProperty:column.objectKey:'header')?.type\"\n [injector]=\"(gtFields | gtProperty:column.objectKey:'header')?.injector\"\n [column]=\"gtFields | gtProperty:column.objectKey:'name'\"></gt-custom-component-factory>\n <gt-checkbox *ngIf=\"(gtFields | gtProperty:column.objectKey:'columnComponent')?.type === 'checkbox'\" [checked]=\"(gtOptions.lazyLoad ? lazyAllSelected:selectedRows.length === gtData.length)\" (changed)=\"toggleAllRows()\"></gt-checkbox>\n </th>\n </tr>\n </thead>\n <ng-template\n [ngIf]=\"gtTotals && (gtOptions.lazyLoad === false ? (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length).length > 0 : gtData.length > 0)\">\n <thead class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </thead>\n <tfoot class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition:'footer'\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </tfoot>\n </ng-template>\n <tbody *ngIf=\"gtData && gtInfo\">\n <ng-template class=\"table-rows\" ngFor let-row let-last=\"last\" [ngForTrackBy]=\"trackByFn\"\n [ngForOf]=\"gtOptions.lazyLoad && gtInfo ? (gtData[gtInfo.pageCurrent-1]) : (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length | gtOrderBy:sortOrder:gtFields:refreshSorting:gtData.length | gtChunk:gtInfo:gtInfo.recordLength:gtInfo.pageCurrent:refreshPageArray:gtData.length:gtEvent:data | gtRowClass:gtFields)\">\n <tr [ngClass]=\"{'row-selected':metaInfo[row.$$gtRowId]?.isSelected, 'row-open':metaInfo[row.$$gtRowId]?.isOpen, 'row-loading':loading, 'row-expandable':gtRowComponent}\"\n class=\"{{row.$$gtRowClass}}\"\n (click)=\"gtOptions.rowSelection ? toggleSelect(row):rowClick(row, $event)\">\n <td *ngFor=\"let column of row | gtRender:gtSettings:gtFields:refreshPipe:loading:gtOptions.highlightSearch:gtInfo.searchTerms;trackBy:trackByColumnFn\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{(gtFields | gtProperty:column.objectKey:'inlineEdit') ? 'gt-inline-edit':''}} {{column.edited ? 'gt-edited':''}} {{ gtFields | gtColumnClass:column:row }}\">\n <span class=\"gt-row-label\"\n *ngIf=\"gtOptions.stack\">{{(gtFields | gtProperty:column.objectKey:'stackedHeading') ? (gtFields | gtProperty:column.objectKey:'stackedHeading') : (gtFields | gtProperty:column.objectKey:'name')}}</span>\n <gt-custom-component-factory *ngIf=\"column.columnComponent && column.columnComponent.type !== 'checkbox'\" class=\"gt-row-content\"\n [type]=\"column.columnComponent.type\"\n [injector]=\"column.columnComponent.injector\" [row]=\"row\"\n [column]=\"column\" (redrawEvent)=\"redraw($event)\"\n [searchTerms]=\"gtInfo.searchTerms\" (searchEvent)=\"redraw($event)\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></gt-custom-component-factory>\n <span *ngIf=\"!column.columnComponent && (!(gtFields | gtProperty:column.objectKey:'inlineEdit') || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || (!((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe)))\"\n class=\"gt-row-content\" [innerHTML]=\"column.renderValue\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></span>\n <ng-template\n [ngIf]=\"!column.columnComponent && (((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe))\">\n <ng-template [ngIf]=\"([true,'email','number','password', 'text'].indexOf((gtFields | gtProperty:column.objectKey:'inlineEdit').type) !== -1) || !(gtFields | gtProperty:column.objectKey:'inlineEdit').type\">\n <input class=\"inline-edit\" [attr.type]=\"!(gtFields | gtProperty:column.objectKey:'inlineEdit').type ? 'text' : !((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type:(gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(((gtFields | gtProperty:column.objectKey:'inlineEdit').type) && ((gtFields | gtProperty:column.objectKey:'inlineEdit').type).length > 0) || ((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable)\"\n [options]=\"!((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type : (gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <ng-template [ngIf]=\"!column.columnComponent && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active) \">\n <ng-template\n [ngIf]=\"[true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') !== -1\">\n <input class=\"inline-edit\" [attr.type]=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') === true ? 'text':(gtFields | gtProperty:column.objectKey:'inlineEdit')\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') && [true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') === -1\"\n [options]=\"gtFields | gtProperty:column.objectKey:'inlineEdit'\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <gt-checkbox *ngIf=\"column.columnComponent && column.columnComponent.type === 'checkbox'\" [checked]=\"metaInfo[row.$$gtRowId]?.isSelected\" (changed)=\"toggleSelect(row)\"></gt-checkbox>\n </td>\n </tr>\n <tr class=\"row-expanded\" *ngIf=\"metaInfo[row.$$gtRowId]?.isOpen\">\n <td [attr.colspan]=\"(gtFields | gtVisible:gtSettings:refreshPipe).length\">\n <gt-expanding-row [row]=\"row\"\n [type]=\"expandedRow.component ? expandedRow.component:gtRowComponent\"\n [columnWidth]=\"columnWidth\"\n [gtFields]=\"gtFields\"\n [gtOptions]=\"gtOptions\"\n [gtEvent]=\"gtEvent\"\n [gtInfo]=\"gtInfo\"\n [gtSettings]=\"gtSettings\"\n [data]=\"expandedRow.data ? expandedRow.data:row\"\n (redrawEvent)=\"redraw($event)\"\n (toggleRowEvent)=\"toggleCollapse($event)\"></gt-expanding-row>\n </td>\n </tr>\n <tr *ngIf=\"gtOptions.reportColumnWidth && last\">\n <td style=\"padding: 0; border:none;\"\n *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\" gtColumnWidth\n [objectKey]=\"column.objectKey\" [widths]=\"columnWidth\"></td>\n </tr>\n </ng-template>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && (gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-matching-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">\n {{gtTexts.noMatchingData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && !(gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.noData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && loading\">\n <td class=\"gt-loading-data\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.loading}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length === 0\">\n <thead>\n <tr>\n <th class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumnsHeading}}</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumns}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"!gtFields || !gtSettings\">\n <thead>\n <tr>\n <th class=\"gt-loading-config\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-loading-config\">&nbsp;</td>\n </tr>\n </tbody>\n</table>\n"
1643
- }] }
1644
- ];
1645
- /** @nocollapse */
1646
- GenericTableComponent.ctorParameters = function () { return [
1647
- { type: Renderer2, },
1648
- { type: GtMetaPipe, },
1649
- ]; };
1650
- GenericTableComponent.propDecorators = {
1651
- "gtOptions": [{ type: Input },],
1652
- "gtTotals": [{ type: Input },],
1653
- "gtFields": [{ type: Input },],
1654
- "gtSettings": [{ type: Input },],
1655
- "gtData": [{ type: Input },],
1656
- "gtRowComponent": [{ type: Input },],
1657
- "gtTexts": [{ type: Input },],
1658
- "gtClasses": [{ type: Input },],
1659
- "gtEvent": [{ type: Output },],
1660
- "gtInfo": [{ type: Input },],
1661
- };
1662
- return GenericTableComponent;
1663
- }());
1664
- export { GenericTableComponent };
1665
- function GenericTableComponent_tsickle_Closure_declarations() {
1666
- /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
1667
- GenericTableComponent.decorators;
1668
- /**
1669
- * @nocollapse
1670
- * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
1671
- */
1672
- GenericTableComponent.ctorParameters;
1673
- /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
1674
- GenericTableComponent.propDecorators;
1675
- /** @type {?} */
1676
- GenericTableComponent.prototype.columnWidth;
1677
- /** @type {?} */
1678
- GenericTableComponent.prototype.configObject;
1679
- /** @type {?} */
1680
- GenericTableComponent.prototype.sortOrder;
1681
- /** @type {?} */
1682
- GenericTableComponent.prototype.metaInfo;
1683
- /** @type {?} */
1684
- GenericTableComponent.prototype.selectedRows;
1685
- /** @type {?} */
1686
- GenericTableComponent.prototype.openRows;
1687
- /** @type {?} */
1688
- GenericTableComponent.prototype._gtSettings;
1689
- /** @type {?} */
1690
- GenericTableComponent.prototype._gtFields;
1691
- /** @type {?} */
1692
- GenericTableComponent.prototype._gtData;
1693
- /** @type {?} */
1694
- GenericTableComponent.prototype._gtTotals;
1695
- /** @type {?} */
1696
- GenericTableComponent.prototype._gtRowComponent;
1697
- /** @type {?} */
1698
- GenericTableComponent.prototype.expandedRow;
1699
- /** @type {?} */
1700
- GenericTableComponent.prototype.gtDefaultTexts;
1701
- /** @type {?} */
1702
- GenericTableComponent.prototype.gtTexts;
1703
- /** @type {?} */
1704
- GenericTableComponent.prototype.gtClasses;
1705
- /** @type {?} */
1706
- GenericTableComponent.prototype.gtEvent;
1707
- /** @type {?} */
1708
- GenericTableComponent.prototype.gtDefaultOptions;
1709
- /** @type {?} */
1710
- GenericTableComponent.prototype._gtOptions;
1711
- /** @type {?} */
1712
- GenericTableComponent.prototype.store;
1713
- /** @type {?} */
1714
- GenericTableComponent.prototype.loading;
1715
- /** @type {?} */
1716
- GenericTableComponent.prototype.debounceTimer;
1717
- /** @type {?} */
1718
- GenericTableComponent.prototype.loadingProperty;
1719
- /** @type {?} */
1720
- GenericTableComponent.prototype.lazyAllSelected;
1721
- /** @type {?} */
1722
- GenericTableComponent.prototype.gtInfo;
1723
- /** @type {?} */
1724
- GenericTableComponent.prototype.refreshPipe;
1725
- /** @type {?} */
1726
- GenericTableComponent.prototype.refreshTotals;
1727
- /** @type {?} */
1728
- GenericTableComponent.prototype.refreshSorting;
1729
- /** @type {?} */
1730
- GenericTableComponent.prototype.refreshFilter;
1731
- /** @type {?} */
1732
- GenericTableComponent.prototype.refreshPageArray;
1733
- /** @type {?} */
1734
- GenericTableComponent.prototype.globalInlineEditListener;
1735
- /** @type {?} */
1736
- GenericTableComponent.prototype.editedRows;
1737
- /** @type {?} */
1738
- GenericTableComponent.prototype.data;
1739
- /**
1740
- * Sort table by object key.
1741
- * \@param objectKey - name of key to sort on.
1742
- * \@param event - such as key press during sorting.
1743
- * @type {?}
1744
- */
1745
- GenericTableComponent.prototype.gtSort;
1746
- /**
1747
- * Change number of rows to be displayed.
1748
- * \@param rowLength - total number of rows.
1749
- * \@param reset - should page be reset to first page.
1750
- * @type {?}
1751
- */
1752
- GenericTableComponent.prototype.changeRowLength;
1753
- /**
1754
- * Force a redraw of table rows.
1755
- * As the table uses pure pipes, we need to force a redraw if an object in the array is changed to see the changes.
1756
- * @type {?}
1757
- */
1758
- GenericTableComponent.prototype.redraw;
1759
- /**
1760
- * Go to next page.
1761
- * @type {?}
1762
- */
1763
- GenericTableComponent.prototype.nextPage;
1764
- /**
1765
- * Go to previous page.
1766
- * @type {?}
1767
- */
1768
- GenericTableComponent.prototype.previousPage;
1769
- /**
1770
- * Request more data (used when lazy loading)
1771
- * @type {?}
1772
- */
1773
- GenericTableComponent.prototype.getData;
1774
- /**
1775
- * Go to specific page.
1776
- * \@param page - page number.
1777
- * @type {?}
1778
- */
1779
- GenericTableComponent.prototype.goToPage;
1780
- /**
1781
- * Sort by sort order
1782
- * @type {?}
1783
- */
1784
- GenericTableComponent.prototype.getSortOrder;
1785
- /**
1786
- * Sort by column order
1787
- * @type {?}
1788
- */
1789
- GenericTableComponent.prototype.getColumnOrder;
1790
- /**
1791
- * Create a deep copy of data
1792
- * @type {?}
1793
- */
1794
- GenericTableComponent.prototype.cloneDeep;
1795
- /**
1796
- * Return property
1797
- * @type {?}
1798
- */
1799
- GenericTableComponent.prototype.getProperty;
1800
- /** @type {?} */
1801
- GenericTableComponent.prototype.restructureSorting;
1802
- /**
1803
- * Extend object function.
1804
- * @type {?}
1805
- */
1806
- GenericTableComponent.prototype.extend;
1807
- /** @type {?} */
1808
- GenericTableComponent.prototype.renderer;
1809
- /** @type {?} */
1810
- GenericTableComponent.prototype.gtMetaPipe;
1811
- }
1812
-
1813
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9nZW5lcmljLXRhYmxlL2dlbmVyaWMtdGFibGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNOLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFDTixTQUFTLEVBRVQsSUFBSSxFQUNKLE1BQU0sZUFBZSxDQUFDO0FBWXZCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7OztJQXFhckQsK0JBQW9CLFFBQW1CLEVBQVUsVUFBc0I7UUFBdkUsaUJBU0M7UUFUbUIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUFVLGVBQVUsR0FBVixVQUFVLENBQVk7MkJBbkYxQyxFQUFFO3lCQUVBLEVBQUU7d0JBQ21CLEVBQUU7NEJBQ2xCLEVBQUU7d0JBQ04sRUFBRTsyQkFDTyxFQUFFO3lCQUNFLEVBQUU7OEJBUWQ7WUFDaEMsT0FBTyxFQUFFLFlBQVk7WUFDckIsTUFBTSxFQUFFLFNBQVM7WUFDakIsY0FBYyxFQUFFLGdDQUFnQztZQUNoRCx1QkFBdUIsRUFBRSxvQkFBb0I7WUFDN0MsZ0JBQWdCLEVBQUUsa0RBQWtEO1lBQ3BFLFNBQVMsRUFDUixrRUFBa0U7WUFDbkUsb0JBQW9CLEVBQ25CLGtIQUFrSDtZQUNuSCxXQUFXLEVBQUUsVUFBVTtZQUN2QixTQUFTLEVBQUUsT0FBTztZQUNsQixZQUFZLEVBQUUsV0FBVztZQUN6QixnQkFBZ0IsRUFBRSxlQUFlO1lBQ2pDLGdCQUFnQixFQUFFLHFCQUFxQjtTQUN2Qzt1QkFDMkIsSUFBSSxDQUFDLGNBQWM7dUJBRUosSUFBSSxZQUFZLEVBQUU7Z0NBQ3hCO1lBQ3BDLFlBQVksRUFBRSxHQUFHO1lBQ2pCLEtBQUssRUFBRSxLQUFLO1lBQ1osUUFBUSxF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LElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1NBQ3JCO0tBQ0Q7Ozs7OztJQUVELHlDQUFTOzs7OztJQUFULFVBQVUsS0FBYSxFQUFFLElBQVc7UUFDbkMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0tBQ3RCOzs7Ozs7SUFFRCwrQ0FBZTs7Ozs7SUFBZixVQUFnQixLQUFhLEVBQUUsSUFBNkI7UUFDM0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0tBQ3RCOzs7O0lBRUQsMkNBQVc7OztJQUFYOztRQUVDLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO0tBQ3JDOztnQkFybkRELFNBQVMsU0FBQztvQkFDVixRQUFRLEVBQUUsZUFBZTtvQkFDekIsUUFBUSxFQUFFLGlpWUF1SlY7aUJBQ0E7Ozs7Z0JBM0tBLFNBQVM7Z0JBZUQsVUFBVTs7OzhCQTJMakIsS0FBSzs2QkFxQkwsS0FBSzs2QkFJTCxLQUFLOytCQWNMLEtBQUs7MkJBeUNMLEtBQUs7bUNBK0RMLEtBQUs7NEJBdUNMLEtBQUs7OEJBQ0wsS0FBSzs0QkFDTCxNQUFNOzJCQXVCTixLQUFLOztnQ0FqYVA7O1NBb0xhLHFCQUFxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0RXZlbnRFbWl0dGVyLFxuXHRJbnB1dCxcblx0T25DaGFuZ2VzLFxuXHRPbkRlc3Ryb3ksXG5cdE9uSW5pdCxcblx0T3V0cHV0LFxuXHRSZW5kZXJlcjIsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdFR5cGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcbmltcG9ydCB7IEd0RXhwYW5kZWRSb3cgfSBmcm9tICcuLi9ndC1leHBhbmRpbmctcm93L2d0LWV4cGFuZGluZy1yb3cuY29tcG9uZW50JztcbmltcG9ydCB7IEd0T3B0aW9ucyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtb3B0aW9ucyc7XG5pbXBvcnQgeyBHdENvbmZpZ0ZpZWxkIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWctZmllbGQnO1xuaW1wb3J0IHsgR3RDb25maWdTZXR0aW5nIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWctc2V0dGluZyc7XG5pbXBvcnQgeyBHdFJvd01ldGEgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LXJvdy1tZXRhJztcbmltcG9ydCB7IEd0VGV4dHMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LXRleHRzJztcbmltcG9ydCB7IEd0Q29uZmlnIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWcnO1xuaW1wb3J0IHsgR3RFdmVudCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtZXZlbnQnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuaW1wb3J0IHsgR3RSZW5kZXJGaWVsZCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtcmVuZGVyLWZpZWxkJztcbmltcG9ydCB7IEd0TWV0YVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9ndC1tZXRhLnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdnZW5lcmljLXRhYmxlJyxcblx0dGVtcGxhdGU6IGA8dGFibGUgY2xhc3M9XCJ0YWJsZVwiIG5nQ2xhc3M9XCJ7e2d0Q2xhc3Nlc319IHt7Z3RPcHRpb25zLnN0YWNrID8gJ3RhYmxlLXN0YWNrZWQnOicnfX1cIlxuICAgICAgICpuZ0lmPVwiZ3RGaWVsZHMgJiYgZ3RTZXR0aW5ncyAmJiAoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZSkubGVuZ3RoID4gMFwiPlxuICA8dGhlYWQ+XG4gIDx0cj5cbiAgICA8dGggY2xhc3M9XCJndC1zb3J0LWxhYmVsXCIgKm5nSWY9XCJndE9wdGlvbnMuc3RhY2tcIj57e2d0VGV4dHMuc29ydExhYmVsfX08L3RoPlxuICAgIDx0aCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZVwiXG4gICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7e2NvbHVtbi5zb3J0RW5hYmxlZCA/ICdzb3J0LScrY29sdW1uLnNvcnQ6Jyd9fSB7e2NvbHVtbi5zb3J0RW5hYmxlZCAmJiBjb2x1bW4uc29ydE9yZGVyID49IDAgID8gJ3NvcnQtb3JkZXItJytjb2x1bW4uc29ydE9yZGVyOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbiB9fVwiXG4gICAgICAgIChjbGljayk9XCJjb2x1bW4uc29ydEVuYWJsZWQgPyBndFNvcnQoY29sdW1uLm9iamVjdEtleSwkZXZlbnQpOicnO1wiPlxuICAgICAgPHNwYW4gKm5nSWY9XCIhKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKVwiPnt7Z3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J25hbWUnfX08L3NwYW4+XG4gICAgICA8Z3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5ICpuZ0lmPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cIihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaGVhZGVyJyk/LnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5qZWN0b3JdPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKT8uaW5qZWN0b3JcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uXT1cImd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OiduYW1lJ1wiPjwvZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5PlxuICAgICAgPGd0LWNoZWNrYm94ICpuZ0lmPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5Oidjb2x1bW5Db21wb25lbnQnKT8udHlwZSA9PT0gJ2NoZWNrYm94J1wiIFtjaGVja2VkXT1cIihndE9wdGlvbnMubGF6eUxvYWQgPyBsYXp5QWxsU2VsZWN0ZWQ6c2VsZWN0ZWRSb3dzLmxlbmd0aCA9PT0gZ3REYXRhLmxlbmd0aClcIiAoY2hhbmdlZCk9XCJ0b2dnbGVBbGxSb3dzKClcIj48L2d0LWNoZWNrYm94PlxuICAgIDwvdGg+XG4gIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDxuZy10ZW1wbGF0ZVxuICAgIFtuZ0lmXT1cImd0VG90YWxzICYmIChndE9wdGlvbnMubGF6eUxvYWQgPT09IGZhbHNlID8gKGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoKS5sZW5ndGggPiAwIDogZ3REYXRhLmxlbmd0aCA+IDApXCI+XG4gICAgPHRoZWFkIGNsYXNzPVwiZ3QtdG90YWxzXCI+XG4gICAgPHRyICpuZ0Zvcj1cImxldCB0b3RhbCBvZiBndFRvdGFscyB8IGd0VG90YWxzUG9zaXRpb25cIj5cbiAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZTtsZXQgaSA9IGluZGV4O1wiXG4gICAgICAgICAgbmdDbGFzcz1cInt7Y29sdW1uLm9iamVjdEtleSArJy10b3RhbHMtY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyBndEZpZWxkcyB8IGd0Q29sdW1uQ2xhc3M6Y29sdW1uIH19XCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaSA9PT0gMFwiIGNsYXNzPVwiZmxvYXQtbGVmdFwiPnt7dG90YWwubmFtZX19PC9zcGFuPjxzcGFuXG4gICAgICAgIFtpbm5lckhUTUxdPVwidG90YWwuZmllbGRzW2NvbHVtbi5vYmplY3RLZXldIHwgZ3RUb3RhbHM6KHRvdGFsLnVwZGF0ZSA9PT0gZmFsc2UgfHwgZ3RPcHRpb25zLmxhenlMb2FkID09PSB0cnVlKSA/IGd0RGF0YTooZ3REYXRhIHwgZ3RGaWx0ZXI6Z3RJbmZvLmZpbHRlcjpndEluZm86cmVmcmVzaEZpbHRlcjpndERhdGEubGVuZ3RoIHwgZ3RTZWFyY2g6Z3RJbmZvLnNlYXJjaFRlcm1zOmd0SW5mbzpndFNldHRpbmdzOmd0RmllbGRzOmd0RGF0YS5sZW5ndGgpOmNvbHVtbi5vYmplY3RLZXk6cmVmcmVzaFRvdGFsc1wiPjwvc3Bhbj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8L3RoZWFkPlxuICAgIDx0Zm9vdCBjbGFzcz1cImd0LXRvdGFsc1wiPlxuICAgIDx0ciAqbmdGb3I9XCJsZXQgdG90YWwgb2YgZ3RUb3RhbHMgfCBndFRvdGFsc1Bvc2l0aW9uOidmb290ZXInXCI+XG4gICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBndFNldHRpbmdzIHwgZ3RWaXNpYmxlOmd0U2V0dGluZ3M6cmVmcmVzaFBpcGU7bGV0IGkgPSBpbmRleDtcIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctdG90YWxzLWNvbHVtbicgfCBkYXNoQ2FzZX19IHt7Z3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2NsYXNzTmFtZXMnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbiB9fVwiPlxuICAgICAgICA8c3BhbiAqbmdJZj1cImkgPT09IDBcIiBjbGFzcz1cImZsb2F0LWxlZnRcIj57e3RvdGFsLm5hbWV9fTwvc3Bhbj48c3BhblxuICAgICAgICBbaW5uZXJIVE1MXT1cInRvdGFsLmZpZWxkc1tjb2x1bW4ub2JqZWN0S2V5XSB8IGd0VG90YWxzOih0b3RhbC51cGRhdGUgPT09IGZhbHNlIHx8IGd0T3B0aW9ucy5sYXp5TG9hZCA9PT0gdHJ1ZSkgPyBndERhdGE6KGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoKTpjb2x1bW4ub2JqZWN0S2V5OnJlZnJlc2hUb3RhbHNcIj48L3NwYW4+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gICAgPC90Zm9vdD5cbiAgPC9uZy10ZW1wbGF0ZT5cbiAgPHRib2R5ICpuZ0lmPVwiZ3REYXRhICYmIGd0SW5mb1wiPlxuICA8bmctdGVtcGxhdGUgY2xhc3M9XCJ0YWJsZS1yb3dzXCIgbmdGb3IgbGV0LXJvdyBsZXQtbGFzdD1cImxhc3RcIiBbbmdGb3JUcmFja0J5XT1cInRyYWNrQnlGblwiXG4gICAgICAgICAgICAgICBbbmdGb3JPZl09XCJndE9wdGlvbnMubGF6eUxvYWQgJiYgZ3RJbmZvID8gKGd0RGF0YVtndEluZm8ucGFnZUN1cnJlbnQtMV0pIDogKGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoIHwgZ3RPcmRlckJ5OnNvcnRPcmRlcjpndEZpZWxkczpyZWZyZXNoU29ydGluZzpndERhdGEubGVuZ3RoIHwgZ3RDaHVuazpndEluZm86Z3RJbmZvLnJlY29yZExlbmd0aDpndEluZm8ucGFnZUN1cnJlbnQ6cmVmcmVzaFBhZ2VBcnJheTpndERhdGEubGVuZ3RoOmd0RXZlbnQ6ZGF0YSB8IGd0Um93Q2xhc3M6Z3RGaWVsZHMpXCI+XG4gICAgPHRyIFtuZ0NsYXNzXT1cInsncm93LXNlbGVjdGVkJzptZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNTZWxlY3RlZCwgJ3Jvdy1vcGVuJzptZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNPcGVuLCAncm93LWxvYWRpbmcnOmxvYWRpbmcsICdyb3ctZXhwYW5kYWJsZSc6Z3RSb3dDb21wb25lbnR9XCJcbiAgICAgICAgY2xhc3M9XCJ7e3Jvdy4kJGd0Um93Q2xhc3N9fVwiXG4gICAgICAgIChjbGljayk9XCJndE9wdGlvbnMucm93U2VsZWN0aW9uID8gdG9nZ2xlU2VsZWN0KHJvdyk6cm93Q2xpY2socm93LCAkZXZlbnQpXCI+XG4gICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiByb3cgfCBndFJlbmRlcjpndFNldHRpbmdzOmd0RmllbGRzOnJlZnJlc2hQaXBlOmxvYWRpbmc6Z3RPcHRpb25zLmhpZ2hsaWdodFNlYXJjaDpndEluZm8uc2VhcmNoVGVybXM7dHJhY2tCeTp0cmFja0J5Q29sdW1uRm5cIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID8gJ2d0LWlubGluZS1lZGl0JzonJ319IHt7Y29sdW1uLmVkaXRlZCA/ICdndC1lZGl0ZWQnOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbjpyb3cgfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3Qtcm93LWxhYmVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ3RPcHRpb25zLnN0YWNrXCI+e3soZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J3N0YWNrZWRIZWFkaW5nJykgPyAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J3N0YWNrZWRIZWFkaW5nJykgOiAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J25hbWUnKX19PC9zcGFuPlxuICAgICAgICA8Z3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5ICpuZ0lmPVwiY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiBjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGUgIT09ICdjaGVja2JveCdcIiBjbGFzcz1cImd0LXJvdy1jb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbmplY3Rvcl09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LmluamVjdG9yXCIgW3Jvd109XCJyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb2x1bW5dPVwiY29sdW1uXCIgKHJlZHJhd0V2ZW50KT1cInJlZHJhdygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VhcmNoVGVybXNdPVwiZ3RJbmZvLnNlYXJjaFRlcm1zXCIgIChzZWFyY2hFdmVudCk9XCJyZWRyYXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbHVtbi5jbGljayA/IGNvbHVtbi5jbGljayhyb3csY29sdW1uLCRldmVudCk6Jyc7Y29sdW1uLmV4cGFuZCA/IHRvZ2dsZUNvbGxhcHNlKHJvdywgY29sdW1uLmV4cGFuZCk6JydcIj48L2d0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeT5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCIhY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiAoIShndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSB8IGFzeW5jKSB8fCAoISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSB8IGd0SXNFZGl0YWJsZTpyb3c6cmVmcmVzaFBpcGUpKSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cImd0LXJvdy1jb250ZW50XCIgW2lubmVySFRNTF09XCJjb2x1bW4ucmVuZGVyVmFsdWVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiY29sdW1uLmNsaWNrID8gY29sdW1uLmNsaWNrKHJvdyxjb2x1bW4sJGV2ZW50KTonJztjb2x1bW4uZXhwYW5kID8gdG9nZ2xlQ29sbGFwc2Uocm93LCBjb2x1bW4uZXhwYW5kKTonJ1wiPjwvc3Bhbj5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgW25nSWZdPVwiIWNvbHVtbi5jb2x1bW5Db21wb25lbnQgJiYgKCgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgYXN5bmMpIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc0VkaXRhYmxlOnJvdzpyZWZyZXNoUGlwZSkpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIihbdHJ1ZSwnZW1haWwnLCdudW1iZXInLCdwYXNzd29yZCcsICd0ZXh0J10uaW5kZXhPZigoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlKSAhPT0gLTEpIHx8ICEoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlXCI+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbmxpbmUtZWRpdFwiIFthdHRyLnR5cGVdPVwiIShndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgPyAndGV4dCcgOiAhKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBndElzT2JzZXJ2YWJsZSkgPyAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlOihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBhc3luY1wiIFsobmdNb2RlbCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwiZ3RVcGRhdGVDb2x1bW4oJGV2ZW50LHJvdywgY29sdW1uKVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndC1pbmxpbmUtZWRpdC1ub3RpY2VcIj57e2d0VGV4dHMuaW5saW5lRWRpdEVkaXRlZH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPGd0LWRyb3Bkb3duXG4gICAgICAgICAgICAqbmdJZj1cIigoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSkgJiYgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUpLmxlbmd0aCA+IDApIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlIHwgZ3RJc09ic2VydmFibGUpXCJcbiAgICAgICAgICAgIFtvcHRpb25zXT1cIiEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSB8IGd0SXNPYnNlcnZhYmxlKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgOiAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlIHwgYXN5bmNcIlxuICAgICAgICAgICAgW2lkXT1cIidfJyArIHJvdy4kJGd0Um93SWQgKyAnXycgKyBjb2x1bW4ub2JqZWN0S2V5XCJcbiAgICAgICAgICAgIFsoc2VsZWN0ZWQpXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiIChzZWxlY3RlZENoYW5nZSk9XCJndERyb3Bkb3duU2VsZWN0KHJvdywgY29sdW1uKVwiPkFkZFxuICAgICAgICAgICAgaW5saW5lIGVkaXRpbmcgbW9kdWxlXG4gICAgICAgICAgPC9ndC1kcm9wZG93bj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFjb2x1bW4uY29sdW1uQ29tcG9uZW50ICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSkgXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBbbmdJZl09XCJbdHJ1ZSwnZW1haWwnLCdudW1iZXInLCdwYXNzd29yZCddLmluZGV4T2YoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKSAhPT0gLTFcIj5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlubGluZS1lZGl0XCIgW2F0dHIudHlwZV09XCIoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKSA9PT0gdHJ1ZSA/ICd0ZXh0JzooZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKVwiIFsobmdNb2RlbCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwiZ3RVcGRhdGVDb2x1bW4oJGV2ZW50LHJvdywgY29sdW1uKVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndC1pbmxpbmUtZWRpdC1ub3RpY2VcIj57e2d0VGV4dHMuaW5saW5lRWRpdEVkaXRlZH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPGd0LWRyb3Bkb3duXG4gICAgICAgICAgICAqbmdJZj1cIihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpICYmIFt0cnVlLCdlbWFpbCcsJ251bWJlcicsJ3Bhc3N3b3JkJ10uaW5kZXhPZihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID09PSAtMVwiXG4gICAgICAgICAgICBbb3B0aW9uc109XCJndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCdcIlxuICAgICAgICAgICAgW2lkXT1cIidfJyArIHJvdy4kJGd0Um93SWQgKyAnXycgKyBjb2x1bW4ub2JqZWN0S2V5XCJcbiAgICAgICAgICAgIFsoc2VsZWN0ZWQpXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiIChzZWxlY3RlZENoYW5nZSk9XCJndERyb3Bkb3duU2VsZWN0KHJvdywgY29sdW1uKVwiPkFkZFxuICAgICAgICAgICAgaW5saW5lIGVkaXRpbmcgbW9kdWxlXG4gICAgICAgICAgPC9ndC1kcm9wZG93bj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGd0LWNoZWNrYm94ICpuZ0lmPVwiY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiBjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGUgPT09ICdjaGVja2JveCdcIiBbY2hlY2tlZF09XCJtZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNTZWxlY3RlZFwiIChjaGFuZ2VkKT1cInRvZ2dsZVNlbGVjdChyb3cpXCI+PC9ndC1jaGVja2JveD5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHIgY2xhc3M9XCJyb3ctZXhwYW5kZWRcIiAqbmdJZj1cIm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdPy5pc09wZW5cIj5cbiAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIihndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlKS5sZW5ndGhcIj5cbiAgICAgICAgPGd0LWV4cGFuZGluZy1yb3cgW3Jvd109XCJyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJleHBhbmRlZFJvdy5jb21wb25lbnQgPyBleHBhbmRlZFJvdy5jb21wb25lbnQ6Z3RSb3dDb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uV2lkdGhdPVwiY29sdW1uV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RGaWVsZHNdPVwiZ3RGaWVsZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RPcHRpb25zXT1cImd0T3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndEV2ZW50XT1cImd0RXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RJbmZvXT1cImd0SW5mb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndFNldHRpbmdzXT1cImd0U2V0dGluZ3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJleHBhbmRlZFJvdy5kYXRhID8gZXhwYW5kZWRSb3cuZGF0YTpyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVkcmF3RXZlbnQpPVwicmVkcmF3KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAodG9nZ2xlUm93RXZlbnQpPVwidG9nZ2xlQ29sbGFwc2UoJGV2ZW50KVwiPjwvZ3QtZXhwYW5kaW5nLXJvdz5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHIgKm5nSWY9XCJndE9wdGlvbnMucmVwb3J0Q29sdW1uV2lkdGggJiYgbGFzdFwiPlxuICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogMDsgYm9yZGVyOm5vbmU7XCJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZVwiIGd0Q29sdW1uV2lkdGhcbiAgICAgICAgICBbb2JqZWN0S2V5XT1cImNvbHVtbi5vYmplY3RLZXlcIiBbd2lkdGhzXT1cImNvbHVtbldpZHRoXCI+PC90ZD5cbiAgICA8L3RyPlxuICA8L25nLXRlbXBsYXRlPlxuICA8dHIgKm5nSWY9XCJndEluZm8ucGFnZVRvdGFsID09PSAwICYmIChndEluZm8uc2VhcmNoVGVybXMgfHwgZ3RJbmZvLmZpbHRlcikgJiYgIWxvYWRpbmdcIj5cbiAgICA8dGQgY2xhc3M9XCJndC1uby1tYXRjaGluZy1yZXN1bHRzXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+XG4gICAgICB7e2d0VGV4dHMubm9NYXRjaGluZ0RhdGF9fVxuICAgIDwvdGQ+XG4gIDwvdHI+XG4gIDx0ciAqbmdJZj1cImd0SW5mby5wYWdlVG90YWwgPT09IDAgJiYgIShndEluZm8uc2VhcmNoVGVybXMgfHwgZ3RJbmZvLmZpbHRlcikgJiYgIWxvYWRpbmdcIj5cbiAgICA8dGQgY2xhc3M9XCJndC1uby1yZXN1bHRzXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+e3tndFRleHRzLm5vRGF0YX19XG4gICAgPC90ZD5cbiAgPC90cj5cbiAgPHRyICpuZ0lmPVwiZ3RJbmZvLnBhZ2VUb3RhbCA9PT0gMCAmJiBsb2FkaW5nXCI+XG4gICAgPHRkIGNsYXNzPVwiZ3QtbG9hZGluZy1kYXRhXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+e3tndFRleHRzLmxvYWRpbmd9fTwvdGQ+XG4gIDwvdHI+XG4gIDwvdGJvZHk+XG48L3RhYmxlPlxuPHRhYmxlIGNsYXNzPVwidGFibGVcIiBuZ0NsYXNzPVwie3tndENsYXNzZXN9fSB7e2d0T3B0aW9ucy5zdGFjayA/ICd0YWJsZS1zdGFja2VkJzonJ319XCJcbiAgICAgICAqbmdJZj1cImd0RmllbGRzICYmIGd0U2V0dGluZ3MgJiYgKGd0RmllbGRzIHwgZ3RWaXNpYmxlOmd0U2V0dGluZ3M6cmVmcmVzaFBpcGUpLmxlbmd0aCA9PT0gMFwiPlxuICA8dGhlYWQ+XG4gIDx0cj5cbiAgICA8dGggY2xhc3M9XCJndC1uby12aXNpYmxlLWNvbHVtbnNcIj57e2d0VGV4dHMubm9WaXNpYmxlQ29sdW1uc0hlYWRpbmd9fTwvdGg+XG4gIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDx0Ym9keT5cbiAgPHRyPlxuICAgIDx0ZCBjbGFzcz1cImd0LW5vLXZpc2libGUtY29sdW1uc1wiPnt7Z3RUZXh0cy5ub1Zpc2libGVDb2x1bW5zfX08L3RkPlxuICA8L3RyPlxuICA8L3Rib2R5PlxuPC90YWJsZT5cbjx0YWJsZSBjbGFzcz1cInRhYmxlXCIgbmdDbGFzcz1cInt7Z3RDbGFzc2VzfX0ge3tndE9wdGlvbnMuc3RhY2sgPyAndGFibGUtc3RhY2tlZCc6Jyd9fVwiXG4gICAgICAgKm5nSWY9XCIhZ3RGaWVsZHMgfHwgIWd0U2V0dGluZ3NcIj5cbiAgPHRoZWFkPlxuICA8dHI+XG4gICAgPHRoIGNsYXNzPVwiZ3QtbG9hZGluZy1jb25maWdcIj4mbmJzcDs8L3RoPlxuICA8L3RyPlxuICA8L3RoZWFkPlxuICA8dGJvZHk+XG4gIDx0cj5cbiAgICA8dGQgY2xhc3M9XCJndC1sb2FkaW5nLWNvbmZpZ1wiPiZuYnNwOzwvdGQ+XG4gIDwvdHI+XG4gIDwvdGJvZHk+XG48L3RhYmxlPlxuYFxufSlcbmV4cG9ydCBjbGFzcyBHZW5lcmljVGFibGVDb21wb25lbnQ8UiBleHRlbmRzIEd0Um93LCBDIGV4dGVuZHMgR3RFeHBhbmRlZFJvdzxSPj5cblx0aW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblx0Z2V0IGd0Um93Q29tcG9uZW50KCk6IFR5cGU8Qz4ge1xuXHRcdHJldHVybiB0aGlzLl9ndFJvd0NvbXBvbmVudDtcblx0fVxuXG5cdGdldCBoYXNFZGl0cygpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gT2JqZWN0LmtleXModGhpcy5lZGl0ZWRSb3dzKS5sZW5ndGggPiAwO1xuXHR9XG5cblx0Z2V0IGd0T3B0aW9ucygpOiBHdE9wdGlvbnMge1xuXHRcdHJldHVybiB0aGlzLl9ndE9wdGlvbnM7XG5cdH1cblxuXHRnZXQgZ3RUb3RhbHMoKTogYW55IHtcblx0XHRyZXR1cm4gdGhpcy5fZ3RUb3RhbHM7XG5cdH1cblxuXHRnZXQgZ3RGaWVsZHMoKTogR3RDb25maWdGaWVsZDxSLCBhbnk+W10ge1xuXHRcdHJldHVybiB0aGlzLl9ndEZpZWxkcztcblx0fVxuXG5cdGdldCBndFNldHRpbmdzKCk6IEd0Q29uZmlnU2V0dGluZ1tdIHtcblx0XHRyZXR1cm4gdGhpcy5fZ3RTZXR0aW5ncztcblx0fVxuXG5cdGdldCBndERhdGEoKTogQXJyYXk8YW55PiB7XG5cdFx0cmV0dXJuIHRoaXMuX2d0RGF0YTtcblx0fVxuXG5cdEBJbnB1dCgpXG5cdHNldCBndE9wdGlvbnModmFsdWU6IEd0T3B0aW9ucykge1xuXHRcdHRoaXMuX2d0T3B0aW9ucyA9IHZhbHVlO1xuXG5cdFx0Ly8gaWYgbnVtYmVyIG9mIHJvd3MgaXMgcGFzc2VkIGFuZCBpZiBudW1iZXIgb2Ygcm93cyBkaWZmZXJzIGZyb20gY3VycmVudCByZWNvcmQgbGVuZ3RoLi4uXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzICYmXG5cdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGggIT09IHRoaXMuZ3RPcHRpb25zLm51bWJlck9mUm93c1xuXHRcdCkge1xuXHRcdFx0Ly8gLi4udXBkYXRlIHJlY29yZCBsZW5ndGggYW5kIHJlZHJhdyB0YWJsZVxuXHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoID0gdGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzO1xuXHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHR9XG5cblx0XHQvLyAuLi5leHRlbmQgZ3RPcHRpb25zIGRlZmF1bHQgdmFsdWVzIHdpdGggdmFsdWVzIHBhc3NlZCBpbnRvIGNvbXBvbmVudFxuXHRcdHRoaXMuX2d0T3B0aW9ucyA9IDxHdE9wdGlvbnM+dGhpcy5leHRlbmQoXG5cdFx0XHR0aGlzLmd0RGVmYXVsdE9wdGlvbnMsXG5cdFx0XHR0aGlzLl9ndE9wdGlvbnNcblx0XHQpO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGd0VG90YWxzKHZhbHVlOiBhbnkpIHtcblx0XHR0aGlzLl9ndFRvdGFscyA9IHZhbHVlO1xuXHR9XG5cdEBJbnB1dCgpXG5cdHNldCBndEZpZWxkcyh2YWx1ZTogR3RDb25maWdGaWVsZDxSLCBhbnk+W10pIHtcblx0XHR0aGlzLl9ndEZpZWxkcyA9IHZhbHVlO1xuXHRcdGNvbnN0IENPTFVNTlNfV0lUSF9DTEFTU19OQU1FUyA9IHRoaXMuX2d0RmllbGRzXG5cdFx0XHQubWFwKGNvbHVtbiA9PiBjb2x1bW4pXG5cdFx0XHQuZmlsdGVyKGNvbHVtbiA9PiBjb2x1bW4uY2xhc3NOYW1lcyk7XG5cdFx0Ly8gVE9ETzogcmVtb3ZlIGRlcHJlY2F0ZWQgd2FybmluZyB3aGVuIHNldHRpbmcgaGFzIGJlZW4gcmVtb3ZlZFxuXHRcdGlmIChDT0xVTU5TX1dJVEhfQ0xBU1NfTkFNRVMubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc29sZS53YXJuKFxuXHRcdFx0XHQnRmllbGQgc2V0dGluZyBcImNsYXNzTmFtZXNcIiBoYXZlIGJlZW4gZGVwcmVjYXRlZCBpbiBmYXZvciBmb3IgXCJjb2x1bW5DbGFzc1wiIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZSwgcGxlYXNlIHVwZGF0ZSBmaWVsZCBzZXR0aW5ncyBmb3IgY29sdW1uIHdpdGggb2JqZWN0IGtleTogJyArXG5cdFx0XHRcdFx0Q09MVU1OU19XSVRIX0NMQVNTX05BTUVTWzBdLm9iamVjdEtleVxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0QElucHV0KClcblx0c2V0IGd0U2V0dGluZ3ModmFsdWU6IEd0Q29uZmlnU2V0dGluZ1tdKSB7XG5cdFx0dGhpcy5fZ3RTZXR0aW5ncyA9IHZhbHVlO1xuXG5cdFx0Ly8gbG9vcCB0aHJvdWdoIGN1cnJlbnQgc2V0dGluZ3Ncblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdC8vIHNldCBzb3J0IGVuYWJsZWQvZGlzYWJsZWQgc2V0dGluZ1xuXHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0RW5hYmxlZCA9XG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydEVuYWJsZWQgIT09IGZhbHNlXG5cdFx0XHRcdFx0PyAodGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0RW5hYmxlZCA9ICEoXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCAmJlxuXHRcdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQuaW5kZXhPZignZGlzYWJsZScpICE9PSAtMVxuXHRcdFx0XHRcdCAgKSlcblx0XHRcdFx0XHQ6IGZhbHNlO1xuXG5cdFx0XHQvLyBjaGVjayBpZiBzb3J0aW5nIGlzIHVuZGVmaW5lZC4uLlxuXHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdC8vIC4uLmlzIHNvLCBzZXQgc29ydGluZyBwcm9wZXJ0eSB0byBlbmFibGVcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2VuYWJsZSc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGNoZWNrIGlmIGNvbHVtbiBvcmRlciBpcyB1bmRlZmluZWQuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV0uY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uZW5hYmxlZCAhPT0gZmFsc2Vcblx0XHRcdCkge1xuXHRcdFx0XHQvLyAuLi5pcyBzbywgc2V0IHNvcnRpbmcgcHJvcGVydHkgdG8gZW5hYmxlXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uY29sdW1uT3JkZXIgPSB0aGlzLl9ndFNldHRpbmdzW2kgLSAxXVxuXHRcdFx0XHRcdD8gdGhpcy5fZ3RTZXR0aW5nc1tpIC0gMV0uY29sdW1uT3JkZXIgKyAxXG5cdFx0XHRcdFx0OiAwO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBjaGVjayBpZiBjb2x1bW4gbG9jayBzZXR0aW5ncyBhcmUgdW5kZWZpbmVkLi4uXG5cdFx0XHRpZiAodHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV0ubG9ja1NldHRpbmdzID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHQvLyAuLi5pZiBzbywgc2V0IGxvY2sgc2V0dGluZ3MgdG8gZmFsc2UgdW5sZXNzIGZpZWxkIGlzIGRpc2FibGVkIChlbmFibGUgPT09IGZhbHNlKVxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLmxvY2tTZXR0aW5ncyA9XG5cdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5lbmFibGVkID09PSBmYWxzZSB8fCBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dGhpcy5yZXN0cnVjdHVyZVNvcnRpbmcoKTtcblx0fVxuXHRASW5wdXQoKVxuXHRzZXQgZ3REYXRhKGluaXRpYWxEYXRhOiBBcnJheTxhbnk+KSB7XG5cdFx0Y29uc3QgZGF0YSA9IHRoaXMuX2d0T3B0aW9ucy5tdXRhdGVEYXRhXG5cdFx0XHQ/IFsuLi5pbml0aWFsRGF0YV1cblx0XHRcdDogdGhpcy5jbG9uZURlZXAoaW5pdGlhbERhdGEpO1xuXHRcdGlmICh0aGlzLmd0T3B0aW9ucy5sYXp5TG9hZCAmJiB0aGlzLmd0SW5mbykge1xuXHRcdFx0dGhpcy5ndE1ldGFQaXBlLnRyYW5zZm9ybShcblx0XHRcdFx0ZGF0YSxcblx0XHRcdFx0dGhpcy5ndE9wdGlvbnMucm93SW5kZXgsXG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMSxcblx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHQpO1xuXHRcdFx0aWYgKHRoaXMubGF6eUFsbFNlbGVjdGVkKSB7XG5cdFx0XHRcdGNvbnN0IFVOSVFVRV9ST1dTID0gdGhpcy5zZWxlY3RlZFJvd3MubWFwKHJvdyA9PiByb3cuJCRndFJvd0lkKTtcblx0XHRcdFx0ZGF0YS5tYXAocm93ID0+IHtcblx0XHRcdFx0XHRpZiAoVU5JUVVFX1JPV1MuaW5kZXhPZihyb3cuJCRndFJvd0lkKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgJ2lzU2VsZWN0ZWQnLCB0cnVlKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5ndE1ldGFQaXBlLnRyYW5zZm9ybShkYXRhLCB0aGlzLmd0T3B0aW9ucy5yb3dJbmRleCk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLmd0T3B0aW9ucy5yb3dTZWxlY3Rpb25Jbml0aWFsU3RhdGUpIHtcblx0XHRcdGRhdGEubWFwKHJvdyA9PiB7XG5cdFx0XHRcdGNvbnN0IHNlbGVjdGVkID1cblx0XHRcdFx0XHR0eXBlb2YgdGhpcy5ndE9wdGlvbnMucm93U2VsZWN0aW9uSW5pdGlhbFN0YXRlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHQ/IHRoaXMuZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkluaXRpYWxTdGF0ZShyb3cpXG5cdFx0XHRcdFx0XHQ6IHRoaXMuZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkluaXRpYWxTdGF0ZTtcblx0XHRcdFx0aWYgKHNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSA9IHsgaXNTZWxlY3RlZDogdHJ1ZSB9O1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdLmlzU2VsZWN0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkUm93cy5wdXNoKHJvdyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHR0aGlzLmd0T3B0aW9ucy5yb3dFeHBhbmRJbml0aWFsU3RhdGUgJiZcblx0XHRcdHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxDb21wb25lbnRcblx0XHQpIHtcblx0XHRcdGRhdGEubWFwKHJvdyA9PiB7XG5cdFx0XHRcdGNvbnN0IGV4cGFuZGVkID1cblx0XHRcdFx0XHR0eXBlb2YgdGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbFN0YXRlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHQ/IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxTdGF0ZShyb3cpXG5cdFx0XHRcdFx0XHQ6IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxTdGF0ZTtcblx0XHRcdFx0dGhpcy5leHBhbmRlZFJvdyA9IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxDb21wb25lbnQ7XG5cblx0XHRcdFx0aWYgKGV4cGFuZGVkKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSA9IHsgaXNPcGVuOiB0cnVlIH07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0uaXNPcGVuID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHR0aGlzLl9ndERhdGEgPSBkYXRhO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGd0Um93Q29tcG9uZW50KHZhbHVlOiBUeXBlPEM+KSB7XG5cdFx0Y29uc29sZS53YXJuKFxuXHRcdFx0J0d0Um93Q29tcG9uZW50IGhhcyBiZWVuIGRlcHJlY2F0ZWQgYW5kIHN1cHBvcnQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vaGphbG1lcnMvYW5ndWxhci1nZW5lcmljLXRhYmxlL2lzc3Vlcy8zNCdcblx0XHQpO1xuXHRcdHRoaXMuX2d0Um93Q29tcG9uZW50ID0gdmFsdWU7XG5cdH1cblxuXHRwdWJsaWMgY29sdW1uV2lkdGg6IE9iamVjdCA9IHt9O1xuXHRwdWJsaWMgY29uZmlnT2JqZWN0OiBHdENvbmZpZzxSPjtcblx0cHVibGljIHNvcnRPcmRlcjogQXJyYXk8YW55PiA9IFtdO1xuXHRwdWJsaWMgbWV0YUluZm86IHsgW2d0Um93SWQ6IHN0cmluZ106IEd0Um93TWV0YSB9ID0ge307XG5cdHB1YmxpYyBzZWxlY3RlZFJvd3M6IEFycmF5PEd0Um93PiA9IFtdO1xuXHRwdWJsaWMgb3BlblJvd3M6IEFycmF5PEd0Um93PiA9IFtdO1xuXHRwcml2YXRlIF9ndFNldHRpbmdzOiBHdENvbmZpZ1NldHRpbmdbXSA9IFtdO1xuXHRwcml2YXRlIF9ndEZpZWxkczogR3RDb25maWdGaWVsZDxSLCBhbnk+W10gPSBbXTtcblx0cHJpdmF0ZSBfZ3REYXRhOiBBcnJheTxhbnk+O1xuXHRwcml2YXRlIF9ndFRvdGFsczogYW55O1xuXHRwcml2YXRlIF9ndFJvd0NvbXBvbmVudDogVHlwZTxDPjtcblx0cHVibGljIGV4cGFuZGVkUm93OiB7XG5cdFx0Y29tcG9uZW50OiBUeXBlPEM+O1xuXHRcdGRhdGE/OiBBcnJheTxhbnk+O1xuXHR9O1xuXHRwdWJsaWMgZ3REZWZhdWx0VGV4dHM6IEd0VGV4dHMgPSB7XG5cdFx0bG9hZGluZzogJ0xvYWRpbmcuLi4nLFxuXHRcdG5vRGF0YTogJ05vIGRhdGEnLFxuXHRcdG5vTWF0Y2hpbmdEYXRhOiAnTm8gZGF0YSBtYXRjaGluZyByZXN1bHRzIGZvdW5kJyxcblx0XHRub1Zpc2libGVDb2x1bW5zSGVhZGluZzogJ05vIHZpc2libGUgY29sdW1ucycsXG5cdFx0bm9WaXNpYmxlQ29sdW1uczogJ1BsZWFzZSBzZWxlY3QgYXQgbGVhc3Qgb25lIGNvbHVtbiB0byBiZSB2aXNpYmxlLicsXG5cdFx0dGFibGVJbmZvOlxuXHRcdFx0J1Nob3dpbmcgI3JlY29yZEZyb20gdG8gI3JlY29yZFRvIG9mICNyZWNvcmRzQWZ0ZXJTZWFyY2ggZW50cmllcy4nLFxuXHRcdHRhYmxlSW5mb0FmdGVyU2VhcmNoOlxuXHRcdFx0J1Nob3dpbmcgICNyZWNvcmRGcm9tIHRvICNyZWNvcmRUbyBvZiAjcmVjb3Jkc0FmdGVyU2VhcmNoIGVudHJpZXMgKGZpbHRlcmVkIGZyb20gYSB0b3RhbCBvZiAjcmVjb3Jkc0FsbCBlbnRyaWVzKS4nLFxuXHRcdGNzdkRvd25sb2FkOiAnZG93bmxvYWQnLFxuXHRcdHNvcnRMYWJlbDogJ1NvcnQ6Jyxcblx0XHRwYWdpbmF0ZU5leHQ6ICdOZXh0IHBhZ2UnLFxuXHRcdHBhZ2luYXRlUHJldmlvdXM6ICdQcmV2aW91cyBwYWdlJyxcblx0XHRpbmxpbmVFZGl0RWRpdGVkOiAnUHJlc3MgZW50ZXIgdG8gc2F2ZSdcblx0fTtcblx0QElucHV0KCkgZ3RUZXh0czogR3RUZXh0cyA9IHRoaXMuZ3REZWZhdWx0VGV4dHM7XG5cdEBJbnB1dCgpIGd0Q2xhc3Nlczogc3RyaW5nO1xuXHRAT3V0cHV0KCkgZ3RFdmVudDogRXZlbnRFbWl0dGVyPEd0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRwdWJsaWMgZ3REZWZhdWx0T3B0aW9uczogR3RPcHRpb25zID0ge1xuXHRcdGNzdkRlbGltaXRlcjogJzsnLFxuXHRcdHN0YWNrOiBmYWxzZSxcblx0XHRsYXp5TG9hZDogZmFsc2UsXG5cdFx0Y2FjaGU6IGZhbHNlLFxuXHRcdGRlYm91bmNlVGltZTogMjAwLFxuXHRcdGhpZ2hsaWdodFNlYXJjaDogZmFsc2UsXG5cdFx0cm93U2VsZWN0aW9uOiBmYWxzZSxcblx0XHRyb3dTZWxlY3Rpb25BbGxvd011bHRpcGxlOiB0cnVlLFxuXHRcdHJvd0V4cGFuZEFsbG93TXVsdGlwbGU6IHRydWUsXG5cdFx0bnVtYmVyT2ZSb3dzOiAxMCxcblx0XHRyZXBvcnRDb2x1bW5XaWR0aDogZmFsc2UsXG5cdFx0YWxsb3dVbnNvcnRlZDogdHJ1ZSxcblx0XHRtdXRhdGVEYXRhOiB0cnVlXG5cdH07XG5cdHByaXZhdGUgX2d0T3B0aW9uczogR3RPcHRpb25zID0gdGhpcy5ndERlZmF1bHRPcHRpb25zO1xuXHRwdWJsaWMgc3RvcmU6IEFycmF5PGFueT4gPSBbXTtcblx0cHVibGljIGxvYWRpbmcgPSB0cnVlO1xuXHRwcml2YXRlIGRlYm91bmNlVGltZXI6IHZvaWQgPSBudWxsO1xuXHRwdWJsaWMgbG9hZGluZ1Byb3BlcnR5OiBzdHJpbmc7XG5cdHB1YmxpYyBsYXp5QWxsU2VsZWN0ZWQgPSBmYWxzZTtcblxuXHRASW5wdXQoKVxuXHRndEluZm86IEd0SW5mb3JtYXRpb24gPSB7XG5cdFx0cGFnZUN1cnJlbnQ6IDEsXG5cdFx0cGFnZVRvdGFsOiAwLFxuXHRcdHJlY29yZEZyb206IDAsXG5cdFx0cmVjb3JkVG86IDAsXG5cdFx0cmVjb3JkTGVuZ3RoOiB0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3MsXG5cdFx0cmVjb3Jkc0FsbDogMCxcblx0XHRyZWNvcmRzQWZ0ZXJGaWx0ZXI6IDAsXG5cdFx0cmVjb3Jkc0FmdGVyU2VhcmNoOiAwXG5cdH07XG5cblx0cHVibGljIHJlZnJlc2hQaXBlID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoVG90YWxzID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoU29ydGluZyA9IGZhbHNlO1xuXHRwdWJsaWMgcmVmcmVzaEZpbHRlciA9IGZhbHNlO1xuXHRwdWJsaWMgcmVmcmVzaFBhZ2VBcnJheSA9IGZhbHNlO1xuXHRwcml2YXRlIGdsb2JhbElubGluZUVkaXRMaXN0ZW5lcjogRnVuY3Rpb247XG5cdHB1YmxpYyBlZGl0ZWRSb3dzOiB7XG5cdFx0W2tleTogc3RyaW5nXToge1xuXHRcdFx0Y2hhbmdlczogeyBba2V5OiBzdHJpbmddOiBHdFJlbmRlckZpZWxkPEd0Um93LCBhbnk+IH07XG5cdFx0XHRyb3c6IEd0Um93O1xuXHRcdH07XG5cdH0gPSB7fTtcblxuXHRwdWJsaWMgZGF0YTogeyBleHBvcnREYXRhOiBBcnJheTxhbnk+IH0gPSB7IGV4cG9ydERhdGE6IFtdIH07IC8vIFN0b3JlIGZpbHRlcmVkIGRhdGEgZm9yIGV4cG9ydFxuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBndE1ldGFQaXBlOiBHdE1ldGFQaXBlKSB7XG5cdFx0dGhpcy5ndEV2ZW50LnN1YnNjcmliZSgoJGV2ZW50OiBHdEV2ZW50KSA9PiB7XG5cdFx0XHRpZiAoJGV2ZW50Lm5hbWUgPT09ICdndC1pbmZvJykge1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoJGV2ZW50Lm5hbWUgPT09ICdndC1yb3ctdXBkYXRlZCcpIHtcblx0XHRcdFx0dGhpcy51cGRhdGVUb3RhbHMoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTb3J0IHRhYmxlIGJ5IG9iamVjdCBrZXkuXG5cdCAqIEBwYXJhbSBvYmplY3RLZXkgLSBuYW1lIG9mIGtleSB0byBzb3J0IG9uLlxuXHQgKiBAcGFyYW0gZXZlbnQgLSBzdWNoIGFzIGtleSBwcmVzcyBkdXJpbmcgc29ydGluZy5cblx0ICovXG5cdHB1YmxpYyBndFNvcnQgPSBmdW5jdGlvbihvYmplY3RLZXk6IHN0cmluZywgZXZlbnQ6IGFueSkge1xuXHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbCgpOyAvLyBjYW5jZWwgaW5saW5lIGVkaXRpbmdcblxuXHRcdC8vIGxvb3AgdGhyb3VnaCBjdXJyZW50IHNldHRpbmdzXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAodGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXkgPT09IG9iamVjdEtleSkge1xuXHRcdFx0XHQvLyBjaGVjayBpZiBzb3J0aW5nIGlzIGRpc2FibGVkLi4uXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgJiZcblx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQuaW5kZXhPZignZGlzYWJsZScpICE9PSAtMVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHQvLyAuLi5pZiBzbywgZXhpdCBmdW5jdGlvbiB3aXRob3V0IGFwcGx5aW5nIGFueSBzb3J0aW5nXG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHRcdC8qIGNoZWNrIGlmIHNvcnRpbmcgaXMgdW5kZWZpbmVkLi4uICovIHR5cGVvZiB0aGlzLl9ndFNldHRpbmdzW2ldXG5cdFx0XHRcdFx0XHQuc29ydCA9PT0gJ3VuZGVmaW5lZCdcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0Ly8gLi4uaXMgc28sIHNldCBzb3J0aW5nIHByb3BlcnR5IHRvIGVuYWJsZVxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdlbmFibGUnO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY2hlY2sgbGVuZ3RoXG5cdFx0Y29uc3QgY3RybEtleSA9IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleTtcblx0XHRjb25zdCBzb3J0ID0gdGhpcy5zb3J0T3JkZXIuc2xpY2UoMCk7XG5cblx0XHRsZXQgbWF0Y2ggPSAtMTtcblx0XHRsZXQgbWF0Y2hEZXNjID0gLTE7XG5cdFx0bGV0IHBvcyA9IC0xO1xuXG5cdFx0Ly8gY2hlY2sgaWYgcHJvcGVydHkgYWxyZWFkeSBleGl0c1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc29ydC5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgaGl0ID0gc29ydFtpXS5pbmRleE9mKG9iamVjdEtleSk7XG5cdFx0XHRpZiAoaGl0ICE9PSAtMSkge1xuXHRcdFx0XHRtYXRjaCA9IHRoaXMuc29ydE9yZGVyLmluZGV4T2Yob2JqZWN0S2V5KTtcblx0XHRcdFx0bWF0Y2hEZXNjID1cblx0XHRcdFx0XHRtYXRjaCA9PT0gLTEgPyB0aGlzLnNvcnRPcmRlci5pbmRleE9mKCctJyArIG9iamVjdEtleSkgOiBtYXRjaDtcblx0XHRcdFx0cG9zID0gTWF0aC5tYXgobWF0Y2gsIG1hdGNoRGVzYyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaWYgY3RybCBrZXkgb3IgbWV0YSBrZXkgaXMgcHJlc3MgdG9nZXRoZXIgd2l0aCBzb3J0Li4uXG5cdFx0aWYgKGN0cmxLZXkpIHtcblx0XHRcdGlmICh0aGlzLnNvcnRPcmRlclt0aGlzLnNvcnRPcmRlci5sZW5ndGggLSAxXSA9PT0gJyQkZ3RJbml0aWFsUm93SW5kZXgnKSB7XG5cdFx0XHRcdHRoaXMuc29ydE9yZGVyLnBvcCgpO1xuXHRcdFx0fVxuXHRcdFx0c3dpdGNoIChwb3MpIHtcblx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIG5vdCBzb3J0ZWQgYmVmb3JlLi4uXG5cdFx0XHRcdGNhc2UgLTE6XG5cdFx0XHRcdFx0Ly8gLi4uYWRkIHByb3BlcnR5IHRvIHNvcnRpbmdcblx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlci5wdXNoKG9iamVjdEtleSk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIHNvcnRlZCBiZWZvcmUuLi5cblx0XHRcdFx0XHRpZiAobWF0Y2ggIT09IC0xKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5jaGFuZ2UgZnJvbSBhc2MgdG8gZGVzYyBpZiBzb3J0ZWQgYXNjXG5cdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlcltwb3NdID0gJy0nICsgb2JqZWN0S2V5O1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5zb3J0T3JkZXIubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdFx0Ly8gLi4ucmVtb3ZlIHNvcnRpbmcgaWYgc29ydGVkIGRlc2Ncblx0XHRcdFx0XHRcdGlmIChjdHJsS2V5KSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyW3Bvc10gPSBvYmplY3RLZXk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlci5zcGxpY2UocG9zLCAxKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuc29ydE9yZGVyLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0Ly8gLi4uc2V0IHNvcnRpbmcgdG8gYXNjIGlmIG9ubHkgc29ydGVkIHByb3BlcnR5XG5cdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlcltwb3NdID0gb2JqZWN0S2V5O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0LyogaWYgY3RybCBrZXkgb3IgbWV0YSBrZXkgaXMgbm90IHByZXNzIHRvZ2V0aGVyIHdpdGggc29ydC4uLiAqL1xuXHRcdFx0c3dpdGNoIChwb3MpIHtcblx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIG5vdCBzb3J0ZWQgYmVmb3JlLi4uXG5cdFx0XHRcdGNhc2UgLTE6XG5cdFx0XHRcdFx0Ly8gLi4uc29ydCBieSBwcm9wZXJ0eVxuXHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyID0gW29iamVjdEtleV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0Ly8gLi4uY2hhbmdlIGZyb20gZGVzYyB0byBhc2MgYW5kIHZpc2UgdmVyc2Fcblx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlciA9XG5cdFx0XHRcdFx0XHRtYXRjaCAhPT0gLTFcblx0XHRcdFx0XHRcdFx0PyBbJy0nICsgb2JqZWN0S2V5XVxuXHRcdFx0XHRcdFx0XHQ6IGN0cmxLZXkgfHwgIXRoaXMuZ3RPcHRpb25zLmFsbG93VW5zb3J0ZWRcblx0XHRcdFx0XHRcdFx0XHQ/IFtvYmplY3RLZXldXG5cdFx0XHRcdFx0XHRcdFx0OiBbXTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgc2V0dGluZ3Mgb2JqZWN0IHdpdGggbmV3IHNvcnRpbmcgaW5mb3JtYXRpb25cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSA9PT0gb2JqZWN0S2V5KSB7XG5cdFx0XHRcdHN3aXRjaCAodGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0KSB7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGVkIGFzYy4uLlxuXHRcdFx0XHRcdGNhc2UgJ2FzYyc6XG5cdFx0XHRcdFx0XHQvLyAuLi5jaGFuZ2UgdG8gZGVzY1xuXHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2Rlc2MnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGVkIGRlc2MuLi5cblx0XHRcdFx0XHRjYXNlICdkZXNjJzpcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSB0byBhc2MgaWYgaXQncyB0aGUgb25seSBzb3J0ZWQgcHJvcGVydHkgb3RoZXJ3aXNlIHJlbW92ZSBzb3J0aW5nXG5cdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPVxuXHRcdFx0XHRcdFx0XHQodGhpcy5zb3J0T3JkZXIubGVuZ3RoID09PSAxICYmIHNvcnQubGVuZ3RoIDwgMikgfHxcblx0XHRcdFx0XHRcdFx0Y3RybEtleSB8fFxuXHRcdFx0XHRcdFx0XHQhdGhpcy5ndE9wdGlvbnMuYWxsb3dVbnNvcnRlZFxuXHRcdFx0XHRcdFx0XHRcdD8gJ2FzYydcblx0XHRcdFx0XHRcdFx0XHQ6ICdlbmFibGUnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGluZyBlbmFibGVkLi4uXG5cdFx0XHRcdFx0Y2FzZSAnZW5hYmxlJzpcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSB0byBhc2Ncblx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdhc2MnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0T3JkZXIgPVxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9PT0gJ2VuYWJsZSdcblx0XHRcdFx0XHRcdD8gdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxXG5cdFx0XHRcdFx0XHQ6IHRoaXMuc29ydE9yZGVyLmluZGV4T2Yob2JqZWN0S2V5KSA9PT0gLTFcblx0XHRcdFx0XHRcdFx0PyB0aGlzLnNvcnRPcmRlci5pbmRleE9mKCctJyArIG9iamVjdEtleSlcblx0XHRcdFx0XHRcdFx0OiB0aGlzLnNvcnRPcmRlci5pbmRleE9mKG9iamVjdEtleSk7XG5cdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgJiZcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0LmluZGV4T2YoJ2Rpc2FibGUnKSA9PT0gLTEgJiZcblx0XHRcdFx0dGhpcy5zb3J0T3JkZXIuaW5kZXhPZih0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSkgPT09IC0xICYmXG5cdFx0XHRcdHRoaXMuc29ydE9yZGVyLmluZGV4T2YoJy0nICsgdGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXkpID09PSAtMVxuXHRcdFx0KSB7XG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdlbmFibGUnO1xuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnRPcmRlciA9IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoIC0gMTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyByZWZyZXNoIHNvcnRpbmcgcGlwZVxuXHRcdHRoaXMucmVmcmVzaFNvcnRpbmcgPSAhdGhpcy5yZWZyZXNoU29ydGluZztcblx0XHR0aGlzLnJlZnJlc2hQYWdlQXJyYXkgPSAhdGhpcy5yZWZyZXNoUGFnZUFycmF5O1xuXG5cdFx0Ly8gc29ydCBieSBpbml0aWFsIHNvcnQgb3JkZXIgYXMgbGFzdCByZXNvcnRcblx0XHR0aGlzLnNvcnRPcmRlci5wdXNoKCckJGd0SW5pdGlhbFJvd0luZGV4Jyk7XG5cblx0XHQvLyBlbWl0IHNvcnQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtc29ydGluZy1hcHBsaWVkJyxcblx0XHRcdHZhbHVlOiB0aGlzLnNvcnRPcmRlclxuXHRcdH0pO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBDaGFuZ2UgbnVtYmVyIG9mIHJvd3MgdG8gYmUgZGlzcGxheWVkLlxuXHQgKiBAcGFyYW0gcm93TGVuZ3RoIC0gdG90YWwgbnVtYmVyIG9mIHJvd3MuXG5cdCAqIEBwYXJhbSByZXNldCAtIHNob3VsZCBwYWdlIGJlIHJlc2V0IHRvIGZpcnN0IHBhZ2UuXG5cdCAqL1xuXHRwdWJsaWMgY2hhbmdlUm93TGVuZ3RoID0gZnVuY3Rpb24ocm93TGVuZ3RoOiBhbnksIHJlc2V0PzogYm9vbGVhbikge1xuXHRcdGxldCBsZW5ndGhWYWx1ZSA9IGlzTmFOKHBhcnNlSW50KHJvd0xlbmd0aCwgMTApKVxuXHRcdFx0PyAwXG5cdFx0XHQ6IHBhcnNlSW50KHJvd0xlbmd0aCwgMTApO1xuXHRcdGxldCBuZXdQb3NpdGlvbiA9IDE7XG5cblx0XHRpZiAoIWxlbmd0aFZhbHVlICYmIHRoaXMuZ3REYXRhKSB7XG5cdFx0XHRsZW5ndGhWYWx1ZSA9IHRoaXMuZ3REYXRhLmxlbmd0aDtcblx0XHR9XG5cblx0XHQvLyBpZiByZXNldCBpcyBub3QgdHJ1ZSBhbmQgd2UncmUgbm90IGxhenkgbG9hZGluZyBkYXRhLi4uXG5cdFx0aWYgKHJlc2V0ICE9PSB0cnVlICYmIHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCAhPT0gdHJ1ZSkge1xuXHRcdFx0Ly8gLi4uZ2V0IGN1cnJlbnQgcG9zaXRpb24gaW4gcmVjb3JkIHNldFxuXHRcdFx0Y29uc3QgY3VycmVudFJlY29yZCA9XG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCAqICh0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDEpO1xuXHRcdFx0Y29uc3QgY3VycmVudFBvc2l0aW9uID1cblx0XHRcdFx0dGhpcy5fZ3REYXRhLmluZGV4T2YodGhpcy5fZ3REYXRhW2N1cnJlbnRSZWNvcmRdKSArIDE7XG5cblx0XHRcdC8vIC4uLmdldCBuZXcgcG9zaXRpb25cblx0XHRcdG5ld1Bvc2l0aW9uID0gTWF0aC5jZWlsKGN1cnJlbnRQb3NpdGlvbiAvIGxlbmd0aFZhbHVlKTtcblx0XHR9XG5cblx0XHQvLyBjaGFuZ2Ugcm93IGxlbmd0aFxuXHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCA9IGxlbmd0aFZhbHVlO1xuXG5cdFx0Ly8gZ28gdG8gbmV3IHBvc2l0aW9uXG5cdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgPSBuZXdQb3NpdGlvbjtcblxuXHRcdC8vIGlmIGxhenkgbG9hZGluZyBkYXRhLi4uXG5cdFx0aWYgKHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCkge1xuXHRcdFx0Ly8gLi4ucmVwbGFjZSBkYXRhIHdpdGggcGxhY2UgaG9sZGVycyBmb3IgbmV3IGRhdGFcblx0XHRcdHRoaXMuX2d0RGF0YVswXSA9IHRoaXMubG9hZGluZ0NvbnRlbnQobGVuZ3RoVmFsdWUpO1xuXG5cdFx0XHQvLyAuLi5lbXB0eSBjdXJyZW50IHN0b3JlXG5cdFx0XHR0aGlzLnN0b3JlID0gW107XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcy51cGRhdGVSZWNvcmRSYW5nZSgpO1xuXG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXJvdy1sZW5ndGgtY2hhbmdlZCcsXG5cdFx0XHR2YWx1ZTogbGVuZ3RoVmFsdWVcblx0XHR9KTtcblx0fTtcblxuXHQvKipcblx0ICogRm9yY2UgYSByZWRyYXcgb2YgdGFibGUgcm93cy5cblx0ICogQXMgdGhlIHRhYmxlIHVzZXMgcHVyZSBwaXBlcywgd2UgbmVlZCB0byBmb3JjZSBhIHJlZHJhdyBpZiBhbiBvYmplY3QgaW4gdGhlIGFycmF5IGlzIGNoYW5nZWQgdG8gc2VlIHRoZSBjaGFuZ2VzLlxuXHQgKi9cblx0cHVibGljIHJlZHJhdyA9IGZ1bmN0aW9uKCRldmVudD86IGFueSkge1xuXHRcdHRoaXMucmVmcmVzaFNvcnRpbmcgPSAhdGhpcy5yZWZyZXNoU29ydGluZztcblx0XHR0aGlzLnJlZnJlc2hQYWdlQXJyYXkgPSAhdGhpcy5yZWZyZXNoUGFnZUFycmF5O1xuXHRcdHRoaXMucmVmcmVzaFBpcGUgPSAhdGhpcy5yZWZyZXNoUGlwZTtcblx0fTtcblxuXHQvKiogVXBkYXRlIHJlY29yZCByYW5nZS4gKi9cblx0cHJpdmF0ZSB1cGRhdGVSZWNvcmRSYW5nZSgpIHtcblx0XHR0aGlzLmd0SW5mby5yZWNvcmRGcm9tID1cblx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCA9PT0gMFxuXHRcdFx0XHQ/IDBcblx0XHRcdFx0OiAodGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxKSAqIHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCArIDE7XG5cdFx0dGhpcy5ndEluZm8ucmVjb3JkVG8gPVxuXHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoIDxcblx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ICogdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdD8gdGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoXG5cdFx0XHRcdDogdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgKiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGg7XG5cdH1cblxuXHQvKiogVXBkYXRlIHRvdGFscy4gKi9cblx0cHJpdmF0ZSB1cGRhdGVUb3RhbHMoKSB7XG5cdFx0dGhpcy5yZWZyZXNoVG90YWxzID0gIXRoaXMucmVmcmVzaFRvdGFscztcblx0fVxuXG5cdC8qKiBHbyB0byBuZXh0IHBhZ2UuICovXG5cdHB1YmxpYyBuZXh0UGFnZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IHBhZ2UgPVxuXHRcdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgPT09IHRoaXMuZ3RJbmZvLnBhZ2VUb3RhbFxuXHRcdFx0XHQ/IHRoaXMuZ3RJbmZvLnBhZ2VUb3RhbFxuXHRcdFx0XHQ6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ICsgMTtcblx0XHR0aGlzLmdvVG9QYWdlKHBhZ2UpO1xuXHR9O1xuXG5cdC8qKiBHbyB0byBwcmV2aW91cyBwYWdlLiAqL1xuXHRwdWJsaWMgcHJldmlvdXNQYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgcGFnZSA9XG5cdFx0XHR0aGlzLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gMSA/IDEgOiB0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDE7XG5cdFx0dGhpcy5nb1RvUGFnZShwYWdlKTtcblx0fTtcblxuXHQvKiogUmVxdWVzdCBtb3JlIGRhdGEgKHVzZWQgd2hlbiBsYXp5IGxvYWRpbmcpICovXG5cdHByaXZhdGUgZ2V0RGF0YSA9IGZ1bmN0aW9uKCkge1xuXHRcdC8vIC4uLmVtaXQgZXZlbnQgcmVxdWVzdGluZyBmb3IgbW9yZSBkYXRhXG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXBhZ2UtY2hhbmdlZC1sYXp5Jyxcblx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdHBhZ2VDdXJyZW50OiB0aGlzLmd0SW5mby5wYWdlQ3VycmVudCxcblx0XHRcdFx0cmVjb3JkTGVuZ3RoOiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdH1cblx0XHR9KTtcblx0fTtcblxuXHQvKipcblx0ICogR28gdG8gc3BlY2lmaWMgcGFnZS5cblx0ICogQHBhcmFtIHBhZ2UgLSBwYWdlIG51bWJlci5cblx0ICovXG5cdHB1YmxpYyBnb1RvUGFnZSA9IGZ1bmN0aW9uKHBhZ2U6IG51bWJlcikge1xuXHRcdGNvbnN0IHByZXZpb3VzUGFnZSA9IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50O1xuXHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ID0gcGFnZTtcblx0XHR0aGlzLmlubGluZUVkaXRDYW5jZWwoKTsgLy8gY2FuY2VsIGlubGluZSBlZGl0XG5cblx0XHQvLyBpZiBsYXp5IGxvYWRpbmcgYW5kIGlmIHBhZ2UgY29udGFpbnMgbm8gcmVjb3Jkcy4uLlxuXHRcdGlmICh0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWQpIHtcblx0XHRcdC8vIC4uLmlmIGRhdGEgZm9yIGN1cnJlbnQgcGFnZSBjb250YWlucyBubyBlbnRyaWVzLi4uXG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuX2d0T3B0aW9ucy5jYWNoZSA9PT0gZmFsc2UgfHxcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV0ubGVuZ3RoID09PSAwXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gLi4uY3JlYXRlIHRlbXBvcmFyeSBjb250ZW50IHdoaWxlIHdhaXRpbmcgZm9yIGRhdGFcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV0gPSB0aGlzLmxvYWRpbmdDb250ZW50KFxuXHRcdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0XHQpO1xuXHRcdFx0XHR0aGlzLmxvYWRpbmcgPSB0cnVlOyAvLyBsb2FkaW5nIHRydWVcblx0XHRcdH1cblx0XHRcdC8vIC4uLmlmIGZpcnN0IGVudHJ5IGluIGN1cnJlbnQgcGFnZSBlcXVhbHMgb3VyIGxvYWRpbmcgcGxhY2Vob2xkZXIuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV1bMF1bdGhpcy5sb2FkaW5nUHJvcGVydHldID09PVxuXHRcdFx0XHR0aGlzLmd0VGV4dHMubG9hZGluZ1xuXHRcdFx0KSB7XG5cdFx0XHRcdC8vIC4uLmdldCBkYXRhXG5cdFx0XHRcdGNsZWFyVGltZW91dCh0aGlzLmRlYm91bmNlVGltZXIpO1xuXHRcdFx0XHR0aGlzLmRlYm91bmNlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmdldERhdGEoKTtcblx0XHRcdFx0fSwgdGhpcy5fZ3RPcHRpb25zLmRlYm91bmNlVGltZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcy51cGRhdGVSZWNvcmRSYW5nZSgpO1xuXG5cdFx0Ly8gLi4uZW1pdCBwYWdlIGNoYW5nZSBldmVudFxuXHRcdGlmIChwcmV2aW91c1BhZ2UgIT09IHBhZ2UpIHtcblx0XHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdFx0bmFtZTogJ2d0LXBhZ2UtY2hhbmdlZCcsXG5cdFx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdFx0cGFnZUN1cnJlbnQ6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50LFxuXHRcdFx0XHRcdHBhZ2VQcmV2aW91czogcHJldmlvdXNQYWdlLFxuXHRcdFx0XHRcdHJlY29yZExlbmd0aDogdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fTtcblxuXHQvKipcblx0ICogR2V0IG1ldGEgZGF0YSBmb3Igcm93LlxuXHQgKi9cblx0cHVibGljIGdldFJvd1N0YXRlKHJvdzogUik6IEd0Um93TWV0YSB7XG5cdFx0cmV0dXJuIHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJ1xuXHRcdFx0PyBudWxsXG5cdFx0XHQ6IHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF07XG5cdH1cblxuXHQvKipcblx0ICogRXhwYW5kIGFsbCByb3dzLlxuXHQgKiBAcGFyYW0gZXhwYW5kZWRSb3cgLSBjb21wb25lbnQgdG8gcmVuZGVyIHdoZW4gcm93cyBhcmUgZXhwYW5kZWQuXG5cdCAqL1xuXHRwdWJsaWMgZXhwYW5kQWxsUm93cyhleHBhbmRlZFJvdzogeyBjb21wb25lbnQ6IFR5cGU8Qz47IGRhdGE/OiBhbnkgfSk6IHZvaWQge1xuXHRcdHRoaXMuZXhwYW5kZWRSb3cgPSBleHBhbmRlZFJvdztcblx0XHR0aGlzLl90b2dnbGVBbGxSb3dQcm9wZXJ0eSgnaXNPcGVuJywgdHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29sbGFwc2UgYWxsIHJvd3MuXG5cdCAqL1xuXHRwdWJsaWMgY29sbGFwc2VBbGxSb3dzKCk6IHZvaWQge1xuXHRcdHRoaXMuX3RvZ2dsZUFsbFJvd1Byb3BlcnR5KCdpc09wZW4nLCBmYWxzZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2VsZWN0IGFsbCByb3dzLlxuXHQgKi9cblx0cHVibGljIHNlbGVjdEFsbFJvd3MoKTogdm9pZCB7XG5cdFx0dGhpcy5fdG9nZ2xlQWxsUm93UHJvcGVydHkoJ2lzU2VsZWN0ZWQnLCB0cnVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZXNlbGVjdCBhbGwgcm93cy5cblx0ICovXG5cdHB1YmxpYyBkZXNlbGVjdEFsbFJvd3MoKTogdm9pZCB7XG5cdFx0dGhpcy5fdG9nZ2xlQWxsUm93UHJvcGVydHkoJ2lzU2VsZWN0ZWQnLCBmYWxzZSk7XG5cdH1cblx0LyoqXG5cdCAqIFRvZ2dsZSBhbGwgcm93cy5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVBbGxSb3dzKCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWQpIHtcblx0XHRcdGlmICghdGhpcy5sYXp5QWxsU2VsZWN0ZWQgfHwgdGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdHRoaXMuc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0XHR0aGlzLmxhenlBbGxTZWxlY3RlZCA9IHRydWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRlc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0XHR0aGlzLmxhenlBbGxTZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoICE9PSB0aGlzLmd0RGF0YS5sZW5ndGgpIHtcblx0XHRcdFx0dGhpcy5zZWxlY3RBbGxSb3dzKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRlc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUb2dnbGUgcm93IGNvbGxhcHNlZCBzdGF0ZSBpZS4gZXhwYW5kZWQvb3BlbiBvciBjb2xsYXBzZWQvY2xvc2VkLlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdCB0aGF0IHNob3VsZCBiZSBleHBhbmRlZC9jb2xsYXBzZWQuXG5cdCAqIEBwYXJhbSBleHBhbmRlZFJvdyAtIGNvbXBvbmVudCB0byByZW5kZXIgd2hlbiByb3cgaXMgZXhwYW5kZWQuXG5cdCAqL1xuXHRwdWJsaWMgdG9nZ2xlQ29sbGFwc2UoXG5cdFx0cm93OiBHdFJvdyxcblx0XHRleHBhbmRlZFJvdz86IHsgY29tcG9uZW50OiBUeXBlPEM+OyBkYXRhPzogYW55IH1cblx0KSB7XG5cdFx0aWYgKGV4cGFuZGVkUm93KSB7XG5cdFx0XHR0aGlzLmV4cGFuZGVkUm93ID0gZXhwYW5kZWRSb3c7XG5cdFx0fVxuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzT3BlbicpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSByb3cgc2VsZWN0ZWQgc3RhdGUgaWUuIHNlbGVjdGVkIG9yIG5vdC5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QgdGhhdCBzaG91bGQgYmUgc2VsZWN0ZWQvZGVzZWxlY3RlZC5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVTZWxlY3Qocm93OiBHdFJvdykge1xuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzU2VsZWN0ZWQnKTtcblx0fVxuXG5cdHB1YmxpYyByb3dDbGljayhyb3c6IEd0Um93LCAkZXZlbnQ6IE1vdXNlRXZlbnQpIHtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtcm93LWNsaWNrZWQnLFxuXHRcdFx0dmFsdWU6IHsgcm93OiByb3csIGV2ZW50OiAkZXZlbnQgfVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSByb3cgZGF0YS5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QgdGhhdCBoYXMgYmVlbiBlZGl0ZWQuXG5cdCAqIEBwYXJhbSBvbGRWYWx1ZSAtIHJvdyBvYmplY3QgYmVmb3JlIGVkaXQuXG5cdCAqL1xuXHRwdWJsaWMgdXBkYXRlUm93KHJvdzogR3RSb3csIG9sZFZhbHVlOiBHdFJvdykge1xuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzVXBkYXRlZCcsIG9sZFZhbHVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiByZW1vdmVzIGEgcm93IGZyb20gdGhlIHRhYmxlXG5cdCAqIEBwYXJhbSByb3cgLSB0aGUgcm93IG9iamVjdCB0byByZW1vdmVcblx0ICovXG5cdHB1YmxpYyByZW1vdmVSb3cocm93OiBHdFJvdykge1xuXHRcdGlmICh0aGlzLmlzUm93U2VsZWN0ZWQocm93KSkge1xuXHRcdFx0dGhpcy50b2dnbGVTZWxlY3Qocm93KTtcblx0XHR9XG5cdFx0Y29uc3QgaW5kZXggPSB0aGlzLl9ndERhdGEuaW5kZXhPZihyb3cpO1xuXHRcdHRoaXMuX2d0RGF0YS5zcGxpY2UoaW5kZXgsIDEpO1xuXHR9XG5cblx0LyoqXG5cdCAqIGNoZWNrIGlmIGEgcm93IGlzIHNlbGVjdGVkXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0XG5cdCAqL1xuXHRwdWJsaWMgaXNSb3dTZWxlY3RlZChyb3c6IEd0Um93KTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gJiYgdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXS5pc1NlbGVjdGVkXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgbWV0YSBpbmZvIGZvciBhbGwgcm93cywgaWUuIGlzU2VsZWN0ZWQsIGlzT3Blbi5cblx0ICogQHBhcmFtIGFycmF5IC0gYXJyYXkgdGhhdCBob2xkcyByb3dzIHRoYXQgbmVlZCB0byBiZSB1cGRhdGVkLlxuXHQgKiBAcGFyYW0gcHJvcGVydHkgLSBuYW1lIG9mIHByb3BlcnR5IHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQvdG9nZ2xlZC5cblx0ICogQHBhcmFtIGFjdGl2ZSAtIHNob3VsZCByb3dzIGJlIGV4cGFuZGVkL29wZW4sIHNlbGVjdGVkLlxuXHQgKiBAcGFyYW0gZXhjZXB0aW9uIC0gdXBkYXRlIGFsbCByb3dzIGV4Y2VwdCB0aGlzIG9uZS5cblx0ICovXG5cdHByaXZhdGUgX3VwZGF0ZU1ldGFJbmZvKFxuXHRcdGFycmF5OiBBcnJheTxHdFJvdz4sXG5cdFx0cHJvcGVydHk6IHN0cmluZyxcblx0XHRhY3RpdmU6IGJvb2xlYW4sXG5cdFx0ZXhjZXB0aW9uPzogR3RSb3dcblx0KSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1ldGFJbmZvW2FycmF5W2ldLiQkZ3RSb3dJZF0pIHtcblx0XHRcdFx0dGhpcy5tZXRhSW5mb1thcnJheVtpXS4kJGd0Um93SWRdID0ge307XG5cdFx0XHR9XG5cdFx0XHRpZiAoZXhjZXB0aW9uICYmIGFycmF5W2ldLiQkZ3RSb3dJZCA9PT0gZXhjZXB0aW9uLiQkZ3RSb3dJZCkge1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5tZXRhSW5mb1thcnJheVtpXS4kJGd0Um93SWRdW3Byb3BlcnR5XSA9IGFjdGl2ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUHVzaCBzZWxlY3RlZC9leHBhbmRlZCBsYXp5IGxvYWRlZCByb3dzIHRvIGFycmF5IHdpdGggbWV0YSBkYXRhLlxuXHQgKiBAcGFyYW0gdGFyZ2V0IC0gYXJyYXkgdG8gd2hpY2ggcm93cyBzaG91bGQgYmUgYWRkZWQuXG5cdCAqIEBwYXJhbSBzb3VyY2UgLSBhcnJheSB0aGF0IGhvbGRzIHJvd3MgdGhhdCBzaG91bGQgYmUgYWRkZWQuXG5cdCAqIEByZXR1cm5zIGFycmF5IHdpdGggYWRkZWQgcm93cy5cblx0ICovXG5cdHByaXZhdGUgX3B1c2hMYXp5Um93cyhcblx0XHR0YXJnZXQ6IEFycmF5PEd0Um93Pixcblx0XHRzb3VyY2U6IEFycmF5PEd0Um93PlxuXHQpOiBBcnJheTxHdFJvdz4ge1xuXHRcdGNvbnN0IFVOSVFVRV9ST1dTID0gdGFyZ2V0Lm1hcChyb3cgPT4gcm93LiQkZ3RSb3dJZCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcblx0XHRcdC8vIG9ubHkgYWRkIGlmIG5vdCBhbHJlYWR5IGluIGxpc3Rcblx0XHRcdGlmIChVTklRVUVfUk9XUy5pbmRleE9mKHNvdXJjZVtpXS4kJGd0Um93SWQpID09PSAtMSkge1xuXHRcdFx0XHR0YXJnZXQucHVzaChzb3VyY2VbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGFyZ2V0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBtZXRhIGluZm8gZm9yIGFsbCByb3dzLCBpZS4gaXNTZWxlY3RlZCwgaXNPcGVuLlxuXHQgKiBAcGFyYW0gcHJvcGVydHkgLSBuYW1lIG9mIHByb3BlcnR5IHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQvdG9nZ2xlZC5cblx0ICogQHBhcmFtIGFjdGl2ZSAtIHNob3VsZCByb3dzIGJlIGV4cGFuZGVkL29wZW4sIHNlbGVjdGVkLlxuXHQgKi9cblx0cHJpdmF0ZSBfdG9nZ2xlQWxsUm93UHJvcGVydHkocHJvcGVydHk6IHN0cmluZywgYWN0aXZlOiBib29sZWFuKSB7XG5cdFx0bGV0IGV2ZW50TmFtZTogc3RyaW5nO1xuXHRcdGxldCBldmVudFZhbHVlOiBhbnk7XG5cdFx0c3dpdGNoIChwcm9wZXJ0eSkge1xuXHRcdFx0Y2FzZSAnaXNPcGVuJzpcblx0XHRcdFx0Ly8gY2hlY2sgaWYgbXVsdGlwbGUgZXhwYW5kZWQgcm93cyBhcmUgYWxsb3dlZC4uLlxuXHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd0V4cGFuZEFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCBleGl0IGZ1bmN0aW9uXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0XHQnZmVhdHVyZSBkaXNhYmxlZDogZW5hYmxlIGJ5IHNldHRpbmcgXCJyb3dFeHBhbmRBbGxvd011bHRpcGxlID0gdHJ1ZVwiJ1xuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChhY3RpdmUpIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnZXhwYW5kLWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5vcGVuUm93cyA9IHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZFxuXHRcdFx0XHRcdFx0PyB0aGlzLl9wdXNoTGF6eVJvd3MoXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5vcGVuUm93cyxcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9ndERhdGFbdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxXS5zbGljZSgpXG5cdFx0XHRcdFx0XHQgIClcblx0XHRcdFx0XHRcdDogdGhpcy5fZ3REYXRhLnNsaWNlKCk7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5vcGVuUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2NvbGxhcHNlLWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5vcGVuUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdFx0dGhpcy5vcGVuUm93cyA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGV2ZW50VmFsdWUgPSB7XG5cdFx0XHRcdFx0ZXhwYW5kZWRSb3dzOiB0aGlzLm9wZW5Sb3dzLFxuXHRcdFx0XHRcdGNoYW5nZWRSb3c6ICdhbGwnXG5cdFx0XHRcdH07XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnaXNTZWxlY3RlZCc6XG5cdFx0XHRcdC8vIGNoZWNrIGlmIG11bHRpIHJvdyBzZWxlY3Rpb24gaXMgYWxsb3dlZC4uLlxuXHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCBleGl0IGZ1bmN0aW9uXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0XHQnZmVhdHVyZSBkaXNhYmxlZDogZW5hYmxlIGJ5IHNldHRpbmcgXCJyb3dTZWxlY3Rpb25BbGxvd011bHRpcGxlID0gdHJ1ZVwiJ1xuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChhY3RpdmUpIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnc2VsZWN0LWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MgPSB0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWRcblx0XHRcdFx0XHRcdD8gdGhpcy5fcHVzaExhenlSb3dzKFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2d0RGF0YVt0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDFdLnNsaWNlKClcblx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0OiB0aGlzLl9ndERhdGEuc2xpY2UoKTtcblx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2Rlc2VsZWN0LWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5zZWxlY3RlZFJvd3MsIHByb3BlcnR5LCBhY3RpdmUpO1xuXHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0ZXZlbnRWYWx1ZSA9IHtcblx0XHRcdFx0XHRzZWxlY3RlZFJvd3M6IHRoaXMuc2VsZWN0ZWRSb3dzLFxuXHRcdFx0XHRcdGNoYW5nZWRSb3c6ICdhbGwnXG5cdFx0XHRcdH07XG5cblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdG5hbWU6ICdndC1yb3ctJyArIGV2ZW50TmFtZSxcblx0XHRcdHZhbHVlOiBldmVudFZhbHVlXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIG1ldGEgaW5mbyBmb3Igcm93LCBpZS4gaXNTZWxlY3RlZCwgaXNPcGVuLlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdC5cblx0ICogQHBhcmFtIHByb3BlcnR5IC0gbmFtZSBvZiBwcm9wZXJ0eSB0aGF0IHNob3VsZCBiZSBjaGFuZ2VkL3RvZ2dsZWQuXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eVZhbHVlcyAtIG9wdGlvbmFsIHByb3BlcnR5IHZhbHVlcyB0aGF0IGNhbiBiZSBwYXNzZWQuXG5cdCAqL1xuXHRwcml2YXRlIF90b2dnbGVSb3dQcm9wZXJ0eShcblx0XHRyb3c6IEd0Um93LFxuXHRcdHByb3BlcnR5OiBzdHJpbmcsXG5cdFx0cHJvcGVydHlWYWx1ZXM/OiBhbnlcblx0KSB7XG5cdFx0bGV0IGV2ZW50TmFtZTogc3RyaW5nO1xuXHRcdGxldCBldmVudFZhbHVlOiBhbnk7XG5cdFx0Ly8gbWFrZSBzdXJlIGd0Um93SWQgZXhpc3RzIG9uIHJvdyBvYmplY3Rcblx0XHRpZiAodHlwZW9mIHJvdy4kJGd0Um93SWQgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHQvLyBjaGVjayBpZiBtZXRhIGluZm8gZXhpc3RzIGZvciByb3dcblx0XHRcdGlmICghdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSkge1xuXHRcdFx0XHQvLyBpZiBub3QsIGFkZCBvYmplY3QgdG8gc3RvcmUgbWV0YSBpbmZvXG5cdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gPSB7fTtcblx0XHRcdH1cblxuXHRcdFx0c3dpdGNoIChwcm9wZXJ0eSkge1xuXHRcdFx0XHRjYXNlICdpc09wZW4nOlxuXHRcdFx0XHRcdGNvbnN0IG9wZW5lZCA9IHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldO1xuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgbXVsdGlwbGUgZXhwYW5kZWQgcm93cyBhcmUgYWxsb3dlZC4uLlxuXHRcdFx0XHRcdGlmICh0aGlzLl9ndE9wdGlvbnMucm93RXhwYW5kQWxsb3dNdWx0aXBsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdC8vIC4uLmlmIG5vdCwgY29sbGFwc2UgYWxsIHJvd3MgZXhjZXB0IGN1cnJlbnQgcm93XG5cdFx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLm9wZW5Sb3dzLCBwcm9wZXJ0eSwgZmFsc2UsIHJvdyk7XG5cdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzID0gW107XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgcm93IGlzIGV4cGFuZGVkXG5cdFx0XHRcdFx0aWYgKCFvcGVuZWQpIHtcblx0XHRcdFx0XHRcdGV2ZW50TmFtZSA9ICdleHBhbmQnO1xuXHRcdFx0XHRcdFx0Ly8gYWRkIHJvdyB0byBleHBhbmRlZCByb3dzXG5cdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2NvbGxhcHNlJztcblx0XHRcdFx0XHRcdC8vIGxvb3AgdGhyb3VnaCBleHBhbmRlZCByb3dzLi4uXG5cdFx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub3BlblJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0Ly8gaWYgZXhwYW5kZWQgcm93IGVxdWFscyBwYXNzZWQgcm93Li4uXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLm9wZW5Sb3dzW2ldLiQkZ3RSb3dJZCA9PT0gcm93LiQkZ3RSb3dJZCkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLnJlbW92ZSByb3cgZnJvbSBleHBhbmRlZCByb3dzLi4uXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5vcGVuUm93cy5zcGxpY2UoaSwgMSk7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgZXhpdCBsb29wXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZXZlbnRWYWx1ZSA9IHtcblx0XHRcdFx0XHRcdGV4cGFuZGVkUm93czogdGhpcy5vcGVuUm93cyxcblx0XHRcdFx0XHRcdGNoYW5nZWRSb3c6IHJvd1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ2lzU2VsZWN0ZWQnOlxuXHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkID0gdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV07XG5cblx0XHRcdFx0XHQvLyBjaGVjayBpZiBtdWx0aSByb3cgc2VsZWN0aW9uIGlzIGFsbG93ZWQuLi5cblx0XHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5pZiBub3QsIGRlc2VsZWN0IGFsbCByb3dzIGV4Y2VwdCBjdXJyZW50IHJvd1xuXHRcdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5zZWxlY3RlZFJvd3MsIHByb3BlcnR5LCBmYWxzZSwgcm93KTtcblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzID0gW107XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgcm93IGlzIHNlbGVjdGVkXG5cdFx0XHRcdFx0aWYgKCFzZWxlY3RlZCkge1xuXHRcdFx0XHRcdFx0ZXZlbnROYW1lID0gJ3NlbGVjdCc7XG5cdFx0XHRcdFx0XHQvLyBhZGQgcm93IHRvIHNlbGVjdGVkIHJvd3Ncblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKHRoaXMuZ3RPcHRpb25zLmxhenlMb2FkICYmIHRoaXMubGF6eUFsbFNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubGF6eUFsbFNlbGVjdGVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRldmVudE5hbWUgPSAnZGVzZWxlY3QnO1xuXHRcdFx0XHRcdFx0Ly8gbG9vcCB0aHJvdWdoIHNlbGVjdGVkIHJvd3MuLi5cblx0XHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0Ly8gaWYgc2VsZWN0ZWQgcm93IGVxdWFscyBwYXNzZWQgcm93Li4uXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnNlbGVjdGVkUm93c1tpXS4kJGd0Um93SWQgPT09IHJvdy4kJGd0Um93SWQpIHtcblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5yZW1vdmUgcm93IGZyb20gc2VsZWN0ZWQgcm93cy4uLlxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnNwbGljZShpLCAxKTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBleGl0IGxvb3Bcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRldmVudFZhbHVlID0ge1xuXHRcdFx0XHRcdFx0c2VsZWN0ZWRSb3dzOiB0aGlzLnNlbGVjdGVkUm93cyxcblx0XHRcdFx0XHRcdGNoYW5nZWRSb3c6IHJvd1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnaXNVcGRhdGVkJzpcblx0XHRcdFx0XHRldmVudE5hbWUgPSAndXBkYXRlZCc7XG5cdFx0XHRcdFx0Y29uc3Qgb2xkVmFsdWUgPSBwcm9wZXJ0eVZhbHVlcztcblx0XHRcdFx0XHQvLyBjaGVjayBpZiBlZGl0IG9iamVjdCBleGlzdHMgZm9yIHJvd1xuXHRcdFx0XHRcdGlmICh0eXBlb2YgdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV0gPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XSA9IHtcblx0XHRcdFx0XHRcdFx0b3JpZ2luYWxWYWx1ZTogb2xkVmFsdWUsXG5cdFx0XHRcdFx0XHRcdG9sZFZhbHVlOiBvbGRWYWx1ZSxcblx0XHRcdFx0XHRcdFx0bmV3VmFsdWU6IHJvd1xuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV0ub2xkVmFsdWUgPSBvbGRWYWx1ZTtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldLm5ld1ZhbHVlID0gcm93O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRldmVudFZhbHVlID0gdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV07XG5cdFx0XHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHRcdFx0XHR0aGlzLmlubGluZUVkaXRDYW5jZWwocm93KTtcblx0XHRcdFx0XHQvLyB0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YS5tYXAoKHIpID0+IHsgcmV0dXJuey4uLnJ9OyB9KV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRcdG5hbWU6ICdndC1yb3ctJyArIGV2ZW50TmFtZSxcblx0XHRcdFx0dmFsdWU6IGV2ZW50VmFsdWVcblx0XHRcdH0pO1xuXHRcdFx0aWYgKHByb3BlcnR5ICE9PSAnaXNVcGRhdGVkJykge1xuXHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XSA9ICF0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW1xuXHRcdFx0XHRcdHByb3BlcnR5XG5cdFx0XHRcdF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSBjb2x1bW4uXG5cdCAqIEBwYXJhbSAkZXZlbnQgLSBrZXkgdXAgZXZlbnQuXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0LlxuXHQgKiBAcGFyYW0gY29sdW1uIC0gY29sdW1uIG9iamVjdC5cblx0ICovXG5cdHB1YmxpYyBndFVwZGF0ZUNvbHVtbihcblx0XHQkZXZlbnQ6IEtleWJvYXJkRXZlbnQsXG5cdFx0cm93OiBHdFJvdyxcblx0XHRjb2x1bW46IEd0UmVuZGVyRmllbGQ8YW55LCBhbnk+XG5cdCkge1xuXHRcdHRoaXMuX2VkaXRSb3cocm93LCBjb2x1bW4pO1xuXHR9XG5cblx0LyoqXG5cdCAqIERyb3Bkb3duIHNlbGVjdC5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QuXG5cdCAqIEBwYXJhbSBjb2x1bW4gLSBjb2x1bW4gb2JqZWN0LlxuXHQgKi9cblx0cHVibGljIGd0RHJvcGRvd25TZWxlY3Qocm93OiBHdFJvdywgY29sdW1uOiBHdFJlbmRlckZpZWxkPGFueSwgYW55Pikge1xuXHRcdGNvbnN0IG9sZFZhbHVlID0geyAuLi5yb3cgfTtcblx0XHRyb3dbY29sdW1uLm9iamVjdEtleV0gPSBjb2x1bW4ucmVuZGVyVmFsdWU7XG5cdFx0dGhpcy51cGRhdGVSb3cocm93LCBvbGRWYWx1ZSk7XG5cdH1cblxuXHRwcml2YXRlIF9lZGl0Um93KHJvdzogR3RSb3csIGNvbHVtbjogR3RSZW5kZXJGaWVsZDxhbnksIGFueT4pIHtcblx0XHRjb25zdCBPQkpFQ1RfS0VZID0gY29sdW1uLm9iamVjdEtleTsgLy8gZGVjbGFyZSBvYmplY3Qga2V5IHdoaWNoIGNvbnRhaW5zIGNoYW5nZXNcblxuXHRcdC8vIGNoZWNrIGlmIGNlbGwgaGFzIGNoYW5nZWQgdmFsdWVcblx0XHRjb2x1bW4uZWRpdGVkID0gcm93W2NvbHVtbi5vYmplY3RLZXldICE9PSBjb2x1bW4ucmVuZGVyVmFsdWU7XG5cdFx0Ly8gY2hlY2sgaWYgcm93IGNvbnRhaW5zIGNoYW5nZXMuLi5cblx0XHRpZiAoIXRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXSkge1xuXHRcdFx0Ly8gaWYgbm90LCBjcmVhdGUgYW4gb2JqZWN0IGZvciB0aGUgY2hhbmdlZCByb3dcblx0XHRcdHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXSA9IHtcblx0XHRcdFx0Y2hhbmdlczoge30sIC8vIGNyZWF0ZSBwbGFjZWhvbGRlciBmb3IgY2hhbmdlc1xuXHRcdFx0XHRyb3c6IHJvdyAvLyBzdG9yZSByZWZlcmVuY2UgdG8gdGhlIHJvdyB0aGF0IHNob3VsZCBiZSB1cGRhdGVkXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIHN0b3JlIGNoYW5nZWQgY29sdW1uIHVuZGVyIGNoYW5nZXMgaWYgaXQgaGFzIGJlZW4gZWRpdGVkXG5cdFx0aWYgKGNvbHVtbi5lZGl0ZWQpIHtcblx0XHRcdHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXS5jaGFuZ2VzW09CSkVDVF9LRVldID0gY29sdW1uO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBkZWxldGUgY2hhbmdlIG9iamVjdCBpZiBjb2x1bW4gaXMgdW5jaGFuZ2VkXG5cdFx0XHRkZWxldGUgdGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdLmNoYW5nZXNbT0JKRUNUX0tFWV07XG5cdFx0XHQvLyBjaGVjayBob3cgbWFueSBjb2x1bW5zIGhhdmUgYmVlbiBjaGFuZ2VkXG5cdFx0XHRjb25zdCBDSEFOR0VEX0NPTFVNTlMgPSBPYmplY3Qua2V5cyhcblx0XHRcdFx0dGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdLmNoYW5nZXNcblx0XHRcdCkubGVuZ3RoO1xuXHRcdFx0aWYgKENIQU5HRURfQ09MVU1OUyA9PT0gMCkge1xuXHRcdFx0XHQvLyBkZWxldGUgcm93IGZyb20gZWRpdGVkIHJvd3MgaWYgbm8gY29sdW1ucyBoYXZlIGJlZW4gZWRpdGVkXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmVkaXRlZFJvd3Nbcm93LiQkZ3RSb3dJZF07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIGlmIG5vIGxpc3RlbmVyIGlzIHByZXNlbnQuLi5cblx0XHRpZiAoIXRoaXMuZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyKSB7XG5cdFx0XHQvLyAuLi5saXN0ZW4gZm9yIHVwZGF0ZSBldmVudFxuXHRcdFx0dGhpcy5fbGlzdGVuRm9yS2V5ZG93bkV2ZW50KCk7XG5cdFx0fVxuXHR9XG5cdC8qKlxuXHQgKiBMaXN0ZW4gZm9yIGtleSBkb3duIGV2ZW50IC0gbGlzdGVuIGZvciBrZXkgZG93biBldmVudCBkdXJpbmcgaW5saW5lIGVkaXQuXG5cdCAqL1xuXHRwcml2YXRlIF9saXN0ZW5Gb3JLZXlkb3duRXZlbnQoKSB7XG5cdFx0Ly8gYWRkIGdsb2JhbCBsaXN0ZW5lciBmb3Iga2V5IGRvd24gZXZlbnRzXG5cdFx0dGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihcblx0XHRcdCdkb2N1bWVudCcsXG5cdFx0XHQna2V5ZG93bicsXG5cdFx0XHQkZXZlbnQgPT4ge1xuXHRcdFx0XHRzd2l0Y2ggKCRldmVudC5rZXkpIHtcblx0XHRcdFx0XHRjYXNlICdFbnRlcic6IC8vIHVwZGF0ZSBkYXRhIG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpcy5pbmxpbmVFZGl0VXBkYXRlKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdFc2NhcGUnOiAvLyBjYW5jZWxcblx0XHRcdFx0XHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbCgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHQpO1xuXHR9XG5cdC8qKlxuXHQgKiBJbmxpbmUgZWRpdCB1cGRhdGUgLSBhY2NlcHQgY2hhbmdlcyBhbmQgdXBkYXRlIHJvdyB2YWx1ZXMuXG5cdCAqL1xuXHRwdWJsaWMgaW5saW5lRWRpdFVwZGF0ZSgpIHtcblx0XHQvLyBsb29wIHRocm91Z2ggcm93cyB0aGF0IGhhdmUgYmVlbiBlZGl0ZWRcblx0XHRPYmplY3Qua2V5cyh0aGlzLmVkaXRlZFJvd3MpLm1hcChrZXkgPT4ge1xuXHRcdFx0Y29uc3QgUk9XID0gdGhpcy5lZGl0ZWRSb3dzW2tleV0ucm93OyAvLyByb3cgdG8gdXBkYXRlXG5cdFx0XHRjb25zdCBDSEFOR0VTID0gdGhpcy5lZGl0ZWRSb3dzW2tleV0uY2hhbmdlczsgLy8gY2hhbmdlcyB0byB0aGUgcm93XG5cblx0XHRcdC8vIGxvb3AgdGhyb3VnaCBjaGFuZ2VzIGluIHJvd1xuXHRcdFx0T2JqZWN0LmtleXMoQ0hBTkdFUykubWFwKG9iamVjdEtleSA9PiB7XG5cdFx0XHRcdGNvbnN0IG9sZFZhbHVlID0geyAuLi5ST1cgfTtcblx0XHRcdFx0Uk9XW29iamVjdEtleV0gPSBDSEFOR0VTW29iamVjdEtleV0ucmVuZGVyVmFsdWU7IC8vIHVwZGF0ZSBkYXRhIHZhbHVlXG5cdFx0XHRcdHRoaXMudXBkYXRlUm93KFJPVywgb2xkVmFsdWUpOyAvLyB1cGRhdGUgbWV0YSBpbmZvIGZvciByb3cgYW5kIHNlbmQgZXZlbnRcblx0XHRcdFx0Q0hBTkdFU1tvYmplY3RLZXldLmVkaXRlZCA9IGZhbHNlOyAvLyBkaXNhYmxlIGVkaXQgbW9kZVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0Ly8gY2xlYXIgcm93cyBtYXJrZWQgYXMgZWRpdGVkIGFzIHRoZSByb3dzIGhhdmUgYmVlbiB1cGRhdGVkXG5cdFx0dGhpcy5lZGl0ZWRSb3dzID0ge307XG5cdFx0Ly8gcmVtb3ZlIGxpc3RlbmVyXG5cdFx0dGhpcy5fc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpO1xuXHR9XG5cdC8qKlxuXHQgKiBJbmxpbmUgZWRpdCBjYW5jZWwgLSBjYW5jZWwgYW5kIHJlc2V0IGlubGluZSBlZGl0cy5cblx0ICovXG5cdHB1YmxpYyBpbmxpbmVFZGl0Q2FuY2VsKHJvdz86IEd0Um93KSB7XG5cdFx0aWYgKHJvdykge1xuXHRcdFx0ZGVsZXRlIHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXTtcblx0XHRcdC8vIHJlbW92ZSBsaXN0ZW5lclxuXHRcdFx0dGhpcy5fc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGxvb3AgdGhyb3VnaCByb3dzIHRoYXQgaGF2ZSBiZWVuIGVkaXRlZFxuXHRcdE9iamVjdC5rZXlzKHRoaXMuZWRpdGVkUm93cykubWFwKGtleSA9PiB7XG5cdFx0XHRjb25zdCBST1cgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5yb3c7IC8vIHJvdyB0byB1cGRhdGVcblx0XHRcdGNvbnN0IENIQU5HRVMgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5jaGFuZ2VzOyAvLyBjaGFuZ2VzIHRvIHRoZSByb3dcblxuXHRcdFx0Ly8gbG9vcCB0aHJvdWdoIGNoYW5nZXMgaW4gcm93XG5cdFx0XHRPYmplY3Qua2V5cyhDSEFOR0VTKS5tYXAob2JqZWN0S2V5ID0+IHtcblx0XHRcdFx0Q0hBTkdFU1tvYmplY3RLZXldLnJlbmRlclZhbHVlID0gUk9XW29iamVjdEtleV07IC8vIHJlc2V0IHJlbmRlcmVkIHZhbHVlXG5cdFx0XHRcdENIQU5HRVNbb2JqZWN0S2V5XS5lZGl0ZWQgPSBmYWxzZTsgLy8gZGlzYWJsZSBlZGl0IG1vZGVcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdC8vIGNsZWFyIHJvd3MgbWFya2VkIGFzIGVkaXRlZCBhcyB0aGUgcm93cyBoYXZlIGJlZW4gdXBkYXRlZFxuXHRcdHRoaXMuZWRpdGVkUm93cyA9IHt9O1xuXHRcdC8vIHJlbW92ZSBsaXN0ZW5lclxuXHRcdHRoaXMuX3N0b3BMaXN0ZW5pbmdGb3JLZXlkb3duRXZlbnQoKTtcblx0fVxuXHQvKipcblx0ICogU3RvcCBsaXN0ZW5pbmcgZm9yIGtleSBkb3duIGV2ZW50IC0gc3RvcCBsaXN0ZW5pbmcgZm9yIGtleSBkb3duIGV2ZW50cyBwYXNzZWQgZHVyaW5nIGlubGluZSBlZGl0LlxuXHQgKi9cblx0cHJpdmF0ZSBfc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpIHtcblx0XHRpZiAodGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIpIHtcblx0XHRcdHRoaXMuZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyKCk7XG5cdFx0XHR0aGlzLmdsb2JhbElubGluZUVkaXRMaXN0ZW5lciA9IG51bGw7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGx5IGZpbHRlcihzKS5cblx0ICogQHBhcmFtIGZpbHRlciAtIG9iamVjdCBjb250YWluaW5nIGtleSB2YWx1ZSBwYWlycywgd2hlcmUgdmFsdWUgc2hvdWxkIGJlIGFycmF5IG9mIHZhbHVlcy5cblx0ICovXG5cdHB1YmxpYyBndEFwcGx5RmlsdGVyKGZpbHRlcjogT2JqZWN0KSB7XG5cdFx0dGhpcy5ndEluZm8uZmlsdGVyID0gZmlsdGVyO1xuXHRcdC8vIGdvIHRvIGZpcnN0IHBhZ2Vcblx0XHR0aGlzLmdvVG9QYWdlKDEpO1xuXHRcdHRoaXMudXBkYXRlVG90YWxzKCk7XG5cdH1cblxuXHQvKiogQ2xlYXIvcmVtb3ZlIGFwcGxpZWQgZmlsdGVyKHMpLiAqL1xuXHRwdWJsaWMgZ3RDbGVhckZpbHRlcigpIHtcblx0XHR0aGlzLmd0SW5mby5maWx0ZXIgPSBmYWxzZTtcblx0XHR0aGlzLnVwZGF0ZVRvdGFscygpO1xuXHRcdC8vIHRoaXMudXBkYXRlUmVjb3JkUmFuZ2UoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWFyY2hcblx0ICogQHBhcmFtIHZhbHVlIC0gc3RyaW5nIGNvbnRhaW5pbmcgb25lIG9yIG1vcmUgd29yZHNcblx0ICovXG5cdHB1YmxpYyBndFNlYXJjaCh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5ndEluZm8uc2VhcmNoVGVybXMgPSB2YWx1ZTtcblx0XHQvLyBhbHdheXMgZ28gdG8gZmlyc3QgcGFnZSB3aGVuIHNlYXJjaGluZ1xuXHRcdHRoaXMuZ29Ub1BhZ2UoMSk7XG5cdFx0dGhpcy51cGRhdGVUb3RhbHMoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgcm93c1xuXHQgKiBAcGFyYW0gcm93cyAtIHJvd3MgdG8gYWRkXG5cdCAqIEByZXR1cm5zIG5ldyBkYXRhIGFycmF5LlxuXHQgKi9cblx0cHVibGljIGd0QWRkKHJvd3M6IEFycmF5PFI+KTogUmVhZG9ubHlBcnJheTxSPiB7XG5cdFx0dGhpcy5ndERhdGEgPSBbLi4udGhpcy5ndERhdGEsIC4uLnJvd3NdO1xuXHRcdHJldHVybiBbLi4udGhpcy5ndERhdGFdO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlbGV0ZSByb3dcblx0ICogQHBhcmFtIG9iamVjdEtleSAtIG9iamVjdCBrZXkgeW91IHdhbnQgdG8gZmluZCBtYXRjaCB3aXRoXG5cdCAqIEBwYXJhbSB2YWx1ZSAtIHRoZSB2YWx1ZSB0aGF0IHNob3VsZCBiZSBkZWxldGVkXG5cdCAqIEBwYXJhbSBtYXRjaCAtIGFsbDogZGVsZXRlIGFsbCBtYXRjaGVzLCBmaXJzdDogZGVsZXRlIGZpcnN0IG1hdGNoIChkZWZhdWx0KVxuXHQgKiBAcmV0dXJucyBuZXcgZGF0YSBhcnJheS5cblx0ICovXG5cdHB1YmxpYyBndERlbGV0ZShcblx0XHRvYmplY3RLZXk6IHN0cmluZyxcblx0XHR2YWx1ZTogc3RyaW5nIHwgbnVtYmVyLFxuXHRcdG1hdGNoOiAnZmlyc3QnIHwgJ2FsbCcgPSAnZmlyc3QnXG5cdCk6IFJlYWRvbmx5QXJyYXk8Uj4ge1xuXHRcdGlmIChtYXRjaCA9PT0gJ2ZpcnN0Jykge1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmd0RGF0YS5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAodGhpcy5ndERhdGFbaV1bb2JqZWN0S2V5XSA9PT0gdmFsdWUpIHtcblx0XHRcdFx0XHRpZiAodGhpcy5pc1Jvd1NlbGVjdGVkKHRoaXMuZ3REYXRhW2ldKSkge1xuXHRcdFx0XHRcdFx0dGhpcy50b2dnbGVTZWxlY3QodGhpcy5ndERhdGFbaV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLmd0RGF0YS5zcGxpY2UoaSwgMSk7XG5cdFx0XHRcdFx0dGhpcy5ndERhdGEgPSBbLi4udGhpcy5ndERhdGFdO1xuXHRcdFx0XHRcdGlmIChtYXRjaCA9PT0gJ2ZpcnN0Jykge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAobGV0IGkgPSB0aGlzLmd0RGF0YS5sZW5ndGg7IGkgPiAwOyBpLS0pIHtcblx0XHRcdFx0aWYgKHRoaXMuZ3REYXRhW2kgLSAxXVtvYmplY3RLZXldID09PSB2YWx1ZSkge1xuXHRcdFx0XHRcdGlmICh0aGlzLmlzUm93U2VsZWN0ZWQodGhpcy5ndERhdGFbaSAtIDFdKSkge1xuXHRcdFx0XHRcdFx0dGhpcy50b2dnbGVTZWxlY3QodGhpcy5ndERhdGFbaSAtIDFdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5ndERhdGEuc3BsaWNlKGkgLSAxLCAxKTtcblx0XHRcdFx0XHR0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIFsuLi50aGlzLmd0RGF0YV07XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlIHN0b3JlIHRvIGhvbGQgcHJldmlvdXNseSBsb2FkZWQgcmVjb3Jkcy5cblx0ICogQHBhcmFtIHJlY29yZHMgLSB0b3RhbCBudW1iZXIgb2YgcmVjb3JkcyBpbiBzdG9yZS5cblx0ICogQHBhcmFtIHBlclBhZ2UgLSBob3cgbWFueSByZWNvcmRzIHRvIHNob3cgcGVyIHBhZ2UuXG5cdCAqIEByZXR1cm5zIGEgbmVzdGVkIGFycmF5IHRvIGhvbGQgcmVjb3JkcyBwZXIgcGFnZS5cblx0ICovXG5cdHByaXZhdGUgY3JlYXRlU3RvcmUocmVjb3JkczogbnVtYmVyLCBwZXJQYWdlOiBudW1iZXIpOiBBcnJheTxBcnJheTxhbnk+PiB7XG5cdFx0Y29uc3Qgc3RvcmVzID0gTWF0aC5jZWlsKHJlY29yZHMgLyBwZXJQYWdlKTtcblx0XHRjb25zdCBzdG9yZTogQXJyYXk8QXJyYXk8YW55Pj4gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHN0b3JlczsgaSsrKSB7XG5cdFx0XHRzdG9yZVtpXSA9IFtdO1xuXHRcdH1cblx0XHRyZXR1cm4gc3RvcmU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlIHBsYWNlaG9sZGVycyBmb3Igcm93cyB3aGlsZSBsb2FkaW5nIGRhdGEgZnJvbSBiYWNrLWVuZC5cblx0ICogQHBhcmFtIHBlclBhZ2UgLSBob3cgbWFueSByZWNvcmRzIHRvIHNob3cgcGVyIHBhZ2UuXG5cdCAqIEByZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgZW1wdHkgcmVjb3JkcyB0byBiZSBwcmVzZW50ZWQgd2hpbGUgZmV0Y2hpbmcgcmVhbCBkYXRhLlxuXHQgKi9cblx0cHJpdmF0ZSBsb2FkaW5nQ29udGVudChwZXJQYWdlOiBudW1iZXIpIHtcblx0XHQvLyBjcmVhdGUgcm93IG9iamVjdFxuXHRcdGNvbnN0IHJvd09iamVjdDogT2JqZWN0ID0ge1xuXHRcdFx0JCRsb2FkaW5nOiB0cnVlXG5cdFx0fTtcblx0XHRsZXQgb3JkZXIgPSAwO1xuXG5cdFx0Ly8gc29ydCBzZXR0aW5ncyBieSBjb2x1bW4gb3JkZXJcblx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRDb2x1bW5PcmRlcik7XG5cblx0XHQvLyBsb29wIHRocm91Z2ggYWxsIHNldHRpbmdzIG9iamVjdHMuLi5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHNldHRpbmcgPSB0aGlzLl9ndFNldHRpbmdzW2ldO1xuXG5cdFx0XHQvLyAuLi5pZiBjb2x1bW4gaXMgdmlzaWJsZSBhbmQgZW5hYmxlZC4uLlxuXHRcdFx0aWYgKHNldHRpbmcudmlzaWJsZSAhPT0gZmFsc2UgJiYgc2V0dGluZy5lbmFibGVkICE9PSBmYWxzZSkge1xuXHRcdFx0XHQvLyAuLi5pZiBmaXJzdCBjb2x1bW4sIHNldCB2YWx1ZSB0byBsb2FkaW5nIHRleHQgb3RoZXJ3aXNlIGxlYXZlIGl0IGVtcHR5XG5cdFx0XHRcdGlmIChvcmRlciA9PT0gMCkge1xuXHRcdFx0XHRcdHJvd09iamVjdFtzZXR0aW5nLm9iamVjdEtleV0gPSB0aGlzLmd0VGV4dHMubG9hZGluZztcblx0XHRcdFx0XHR0aGlzLmxvYWRpbmdQcm9wZXJ0eSA9IHNldHRpbmcub2JqZWN0S2V5O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJvd09iamVjdFtzZXR0aW5nLm9iamVjdEtleV0gPSAnJztcblx0XHRcdFx0fVxuXHRcdFx0XHRvcmRlcisrO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cm93T2JqZWN0W3NldHRpbmcub2JqZWN0S2V5XSA9ICcnO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGNyZWF0ZSBjb250ZW50IHBsYWNlaG9sZGVyXG5cdFx0Y29uc3QgY29udGVudFBsYWNlaG9sZGVyOiBBcnJheTxhbnk+ID0gW107XG5cblx0XHQvLyBjcmVhdGUgZXF1YWwgbnVtYmVyIG9mIHJvd3MgYXMgcm93cyBwZXIgcGFnZVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgcGVyUGFnZTsgaSsrKSB7XG5cdFx0XHQvLyAuLi5hZGQgdGVtcG9yYXJ5IHJvdyBvYmplY3Rcblx0XHRcdGNvbnRlbnRQbGFjZWhvbGRlci5wdXNoKHJvd09iamVjdCk7XG5cdFx0fVxuXHRcdHJldHVybiBjb250ZW50UGxhY2Vob2xkZXI7XG5cdH1cblxuXHQvLyBUT0RPOiBtb3ZlIHRvIGhlbHBlciBmdW5jdGlvbnNcblx0LyoqIFNvcnQgYnkgc29ydCBvcmRlciAqL1xuXHRwcml2YXRlIGdldFNvcnRPcmRlciA9IGZ1bmN0aW9uKGE6IEd0Q29uZmlnU2V0dGluZywgYjogR3RDb25maWdTZXR0aW5nKSB7XG5cdFx0aWYgKGEuc29ydE9yZGVyIDwgYi5zb3J0T3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuc29ydE9yZGVyID4gYi5zb3J0T3JkZXIgfHwgdHlwZW9mIGEuc29ydE9yZGVyID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlciA9IGZ1bmN0aW9uKGE6IEd0Q29uZmlnU2V0dGluZywgYjogR3RDb25maWdTZXR0aW5nKSB7XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA8IGIuY29sdW1uT3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPiBiLmNvbHVtbk9yZGVyKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH07XG5cblx0Ly8gVE9ETzogbW92ZSB0byBoZWxwZXIgZnVuY3Rpb25zXG5cdC8qKiBDcmVhdGUgYSBkZWVwIGNvcHkgb2YgZGF0YSAqL1xuXHRwcml2YXRlIGNsb25lRGVlcCA9IGZ1bmN0aW9uKG86IGFueSkge1xuXHRcdHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKTtcblx0fTtcblxuXHQvKiogRXhwb3J0IGRhdGEgYXMgQ1NWXG5cdCAqIEBwYXJhbSBmaWxlTmFtZSAtIG9wdGlvbmFsIGZpbGUgbmFtZSAob3ZlcnJpZGVzIGRlZmF1bHQgZmlsZSBuYW1lKS5cblx0ICogQHBhcmFtIHVzZUJPTSAtIHVzZSBCT00gKGJ5dGUgb3JkZXIgbWFya2VyKS5cblx0ICovXG5cdHB1YmxpYyBleHBvcnRDU1YoZmlsZU5hbWU/OiBzdHJpbmcsIHVzZUJPTTogYm9vbGVhbiA9IGZhbHNlKSB7XG5cdFx0Y29uc3QgZGF0YSA9IHRoaXMuZGF0YS5leHBvcnREYXRhO1xuXHRcdGxldCBjc3YgPSAnJztcblx0XHRjb25zdCBCT00gPSAnXFx1RkVGRic7XG5cblx0XHQvLyBjc3YgZXhwb3J0IGhlYWRlcnNcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLmV4cG9ydCAhPT0gZmFsc2UpIHtcblx0XHRcdFx0Y3N2ICs9IHRoaXMuZ2V0UHJvcGVydHkodGhpcy5fZ3RGaWVsZHMsIHRoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5KVxuXHRcdFx0XHRcdC5uYW1lO1xuXG5cdFx0XHRcdGlmIChpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0Y3N2ICs9IHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBjc3YgZXhwb3J0IGJvZHlcblx0XHRkYXRhLmZvckVhY2gocm93ID0+IHtcblx0XHRcdGNzdiArPSAnXFxuJztcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAodGhpcy5fZ3RTZXR0aW5nc1tpXS5leHBvcnQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gZ2V0IGZpZWxkIHNldHRpbmdzXG5cdFx0XHRcdFx0Y29uc3QgZmllbGRTZXR0aW5nID0gdGhpcy5nZXRQcm9wZXJ0eShcblx0XHRcdFx0XHRcdHRoaXMuX2d0RmllbGRzLFxuXHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gZ2V0IGV4cG9ydCB2YWx1ZSwgaWYgZXhwb3J0IGZ1bmN0aW9uIGlzIGRlZmluZWQgdXNlIGl0IG90aGVyd2lzZSBjaGVjayBmb3IgdmFsdWUgZnVuY3Rpb24gYW5kIGFzIGEgbGFzdCByZXNvcnQgZXhwb3J0IHJhdyBkYXRhXG5cdFx0XHRcdFx0bGV0IGV4cG9ydFZhbHVlOiBzdHJpbmcgPVxuXHRcdFx0XHRcdFx0ZmllbGRTZXR0aW5nLmV4cG9ydCAmJiB0eXBlb2YgZmllbGRTZXR0aW5nLmV4cG9ydCA9PT0gJ2Z1bmN0aW9uJ1xuXHRcdFx0XHRcdFx0XHQ/IGZpZWxkU2V0dGluZy5leHBvcnQocm93KVxuXHRcdFx0XHRcdFx0XHQ6IGZpZWxkU2V0dGluZy52YWx1ZSAmJiB0eXBlb2YgZmllbGRTZXR0aW5nLnZhbHVlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHRcdFx0PyBmaWVsZFNldHRpbmcudmFsdWUocm93KVxuXHRcdFx0XHRcdFx0XHRcdDogcm93W3RoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblxuXHRcdFx0XHRcdC8vIGVzY2FwZSBleHBvcnQgdmFsdWUgdXNpbmcgZG91YmxlIHF1b3RlcyAoXCIpIGlmIGV4cG9ydCB2YWx1ZSBjb250YWlucyBkZWxpbWl0ZXJcblx0XHRcdFx0XHRleHBvcnRWYWx1ZSA9XG5cdFx0XHRcdFx0XHR0eXBlb2YgZXhwb3J0VmFsdWUgPT09ICdzdHJpbmcnICYmXG5cdFx0XHRcdFx0XHRleHBvcnRWYWx1ZS5pbmRleE9mKHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXIpICE9PSAtMVxuXHRcdFx0XHRcdFx0XHQ/ICdcIicgKyBleHBvcnRWYWx1ZSArICdcIidcblx0XHRcdFx0XHRcdFx0OiBleHBvcnRWYWx1ZTtcblxuXHRcdFx0XHRcdGNzdiArPSBleHBvcnRWYWx1ZTtcblx0XHRcdFx0XHRpZiAoaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0Y3N2ICs9IHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRjb25zdCBibG9iID0gbmV3IEJsb2IoWyh1c2VCT00gPyBCT00gOiAnJykgKyBjc3ZdLCB7XG5cdFx0XHR0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtOCdcblx0XHR9KTtcblxuXHRcdGlmICh3aW5kb3cubmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHtcblx0XHRcdG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKFxuXHRcdFx0XHRibG9iLFxuXHRcdFx0XHRmaWxlTmFtZSA/IGZpbGVOYW1lICsgJy5jc3YnIDogdGhpcy5ndFRleHRzLmNzdkRvd25sb2FkICsgJy5jc3YnXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXHRcdFx0bGluay5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcblx0XHRcdGlmIChsaW5rLmRvd25sb2FkICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0bGluay5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcdFx0J2hyZWYnLFxuXHRcdFx0XHRcdCdkYXRhOnRleHQvY3N2O2NoYXJzZXQ9dXRmLTgsJyArXG5cdFx0XHRcdFx0XHRlbmNvZGVVUklDb21wb25lbnQoKHVzZUJPTSA/IEJPTSA6ICcnKSArIGNzdilcblx0XHRcdFx0KTsgLy8gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKSk7XG5cdFx0XHRcdGxpbmsuc2V0QXR0cmlidXRlKFxuXHRcdFx0XHRcdCdkb3dubG9hZCcsXG5cdFx0XHRcdFx0ZmlsZU5hbWUgPyBmaWxlTmFtZSArICcuY3N2JyA6IHRoaXMuZ3RUZXh0cy5jc3ZEb3dubG9hZCArICcuY3N2J1xuXHRcdFx0XHQpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuXHRcdFx0XHRsaW5rLmNsaWNrKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjc3YgPSAnZGF0YTp0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04LCcgKyAodXNlQk9NID8gQk9NIDogJycpICsgY3N2O1xuXHRcdFx0XHR3aW5kb3cub3BlbihlbmNvZGVVUklDb21wb25lbnQoY3N2KSk7XG5cdFx0XHR9XG5cdFx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxpbmspO1xuXHRcdH1cblxuXHRcdC8vIGVtaXQgZXhwb3J0IGV2ZW50XG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LWV4cG9ydGVkLWNzdicsXG5cdFx0XHR2YWx1ZTogZmlsZU5hbWUgPyBmaWxlTmFtZSA6IHRoaXMuZ3RUZXh0cy5jc3ZEb3dubG9hZCArICcuY3N2J1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqIFJldHVybiBwcm9wZXJ0eSAqL1xuXHRwcml2YXRlIGdldFByb3BlcnR5ID0gZnVuY3Rpb24oYXJyYXk6IEFycmF5PGFueT4sIGtleTogc3RyaW5nKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycmF5W2ldLm9iamVjdEtleSA9PT0ga2V5KSB7XG5cdFx0XHRcdHJldHVybiBhcnJheVtpXTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0cHJpdmF0ZSByZXN0cnVjdHVyZVNvcnRpbmcgPSBmdW5jdGlvbigpIHtcblx0XHQvKiogQ2hlY2sgYW5kIHN0b3JlIHNvcnQgb3JkZXIgdXBvbiBpbml0aWFsaXphdGlvbi5cblx0XHQgKiAgVGhpcyBpcyBkb25lIGJ5IGNoZWNraW5nIHNvcnQgcHJvcGVydGllcyBpbiB0aGUgc2V0dGluZ3MgYXJyYXkgb2YgdGhlIHRhYmxlLCBpZiBubyBzb3J0aW5nIGlzIGRlZmluZWRcblx0XHQgKiAgd2UnbGwgc29ydCB0aGUgZGF0YSBieSB0aGUgZmlyc3QgdmlzaWJsZSBhbmQgZW5hYmxlZCBjb2x1bW4gaW4gdGhlIHRhYmxlKGFzY2VuZGluZykuIFBsZWFzZSBub3RlIHRoYXQgYWN0dWFsbHlcblx0XHQgKiAgc29ydGluZyBoYXZlIHRvIGJlIGRvbmUgc2VydmVyIHNpZGUgd2hlbiBsYXp5IGxvYWRpbmcgZGF0YSBmb3Igb2J2aW91cyByZWFzb25zLiAgKi9cblx0XHQvLyBjcmVhdGUgc29ydGluZyBhcnJheVxuXHRcdGNvbnN0IHNvcnRpbmcgPSBbXTtcblx0XHRpZiAodGhpcy5fZ3RTZXR0aW5ncykge1xuXHRcdFx0Ly8gLi4uc29ydCBzZXR0aW5ncyBieSBzb3J0IG9yZGVyXG5cdFx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRTb3J0T3JkZXIpO1xuXG5cdFx0XHQvLyAuLi5sb29wIHRocm91Z2ggc2V0dGluZ3Ncblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRjb25zdCBzZXR0aW5nID0gdGhpcy5fZ3RTZXR0aW5nc1tpXTtcblxuXHRcdFx0XHQvLyAuLi5pZiBzb3J0ZWQgYXNjZW5kaW5nLi4uXG5cdFx0XHRcdGlmIChzZXR0aW5nLnNvcnQgPT09ICdhc2MnKSB7XG5cdFx0XHRcdFx0Ly8gLi4uIGFkZCB0byBzb3J0aW5nXG5cdFx0XHRcdFx0c29ydGluZy5wdXNoKHNldHRpbmcub2JqZWN0S2V5KTtcblx0XHRcdFx0fSBlbHNlIGlmIChzZXR0aW5nLnNvcnQgPT09ICdkZXNjJykge1xuXHRcdFx0XHRcdC8qIC4uLmVsc2UgaWYgc29ydGVkIGRlc2NlbmRpbmcuLi4gKi8gLy8gLi4uIGFkZCB0byBzb3J0aW5nXG5cdFx0XHRcdFx0c29ydGluZy5wdXNoKCctJyArIHNldHRpbmcub2JqZWN0S2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gLi4uaWYgbm8gc29ydGluZyBhcHBsaWVkLi4uXG5cdFx0XHRpZiAoc29ydGluZy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0c29ydGluZy5wdXNoKCckJGd0Um93SWQnKTtcblx0XHRcdFx0LyovLyAuLi5zb3J0IHNldHRpbmdzIGJ5IGNvbHVtbiBvcmRlclxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRDb2x1bW5PcmRlcik7XG5cblx0XHRcdFx0Ly8gLi4ubG9vcCB0aHJvdWdoIHNldHRpbmdzXG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdGNvbnN0IHNldHRpbmcgPSB0aGlzLl9ndFNldHRpbmdzW2ldO1xuXG5cdFx0XHRcdFx0Ly8gLi4uaWYgY29sdW1uIGlzIGVuYWJsZWQgYW5kIHZpc2libGUuLi5cblx0XHRcdFx0XHRpZiAoc2V0dGluZy5lbmFibGVkICE9PSBmYWxzZSAmJiBzZXR0aW5nLnZpc2libGUgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5hZGQgZmlyc3QgbWF0Y2ggYW5kIGV4aXQgZnVuY3Rpb25cblx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyID0gW3RoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0qL1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICh0aGlzLnNvcnRPcmRlci5sZW5ndGggPT09IDApIHtcblx0XHRcdHRoaXMuc29ydE9yZGVyID0gc29ydGluZztcblx0XHR9XG5cdH07XG5cblx0bmdPbkluaXQoKSB7XG5cdFx0Ly8gaWYgbnVtYmVyIG9mIHJvdyB0byBkaXNwbGF5IGZyb20gc3RhcnQgaXMgc2V0IHRvIG51bGwgb3IgMC4uLlxuXHRcdGlmICghdGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzKSB7XG5cdFx0XHQvLyAuLi5jaGFuZ2Ugcm93IGxlbmd0aFxuXHRcdFx0dGhpcy5jaGFuZ2VSb3dMZW5ndGgodGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzKTtcblx0XHR9XG5cdFx0dGhpcy5yZXN0cnVjdHVyZVNvcnRpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiAgRXh0ZW5kIG9iamVjdCBmdW5jdGlvbi5cblx0ICovXG5cdHByaXZhdGUgZXh0ZW5kID0gZnVuY3Rpb24oYTogT2JqZWN0LCBiOiBPYmplY3QpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiBiKSB7XG5cdFx0XHRpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGFba2V5XSA9IGJba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGE7XG5cdH07XG5cblx0bmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuXHRcdC8vIGlmIGd0IHRleHRzIGhhdmUgY2hhbmdlZC4uLlxuXHRcdGlmIChjaGFuZ2VzWydndFRleHRzJ10pIHtcblx0XHRcdC8vIC4uLmV4dGVuZCBndE9wdGlvbnMgZGVmYXVsdCB2YWx1ZXMgd2l0aCB2YWx1ZXMgcGFzc2VkIGludG8gY29tcG9uZW50XG5cdFx0XHR0aGlzLmd0VGV4dHMgPSA8R3RUZXh0cz50aGlzLmV4dGVuZCh0aGlzLmd0RGVmYXVsdFRleHRzLCB0aGlzLmd0VGV4dHMpO1xuXHRcdH1cblxuXHRcdC8vIGlmIGxhenkgbG9hZGluZyBkYXRhIGFuZCBwYWdpbmcgaW5mb3JtYXRpb24gaXMgYXZhaWxhYmxlLi4uXG5cdFx0aWYgKHRoaXMuZ3RPcHRpb25zLmxhenlMb2FkICYmIHRoaXMuZ3RJbmZvKSB7XG5cdFx0XHQvLyAuLi5jYWxjdWxhdGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzXG5cdFx0XHR0aGlzLmd0SW5mby5wYWdlVG90YWwgPSBNYXRoLmNlaWwoXG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCAvIHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0KTtcblxuXHRcdFx0Ly8gLi4uZGVjbGFyZSBzdG9yZSBwb3NpdGlvblxuXHRcdFx0Y29uc3Qgc3RvcmVQb3NpdGlvbiA9IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMTtcblxuXHRcdFx0Ly8gLi4uYW5kIGlmIHN0b3JlIGlzIGVtcHR5IG9yIHBhZ2UgbGVuZ3RoIGhhcyBjaGFuZ2VkLi4uXG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuc3RvcmUubGVuZ3RoID09PSAwIHx8XG5cdFx0XHRcdHRoaXMuc3RvcmVbMF0ubGVuZ3RoICE9PSB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdCkge1xuXHRcdFx0XHQvLyAuLi5jcmVhdGUgc3RvcmVcblx0XHRcdFx0dGhpcy5zdG9yZSA9IHRoaXMuY3JlYXRlU3RvcmUoXG5cdFx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoLFxuXHRcdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyAuLi5zdG9yZSByZXRyaWV2ZWQgZGF0YSBpbiBzdG9yZSBhdCBzdG9yZSBwb3NpdGlvblxuXHRcdFx0dGhpcy5zdG9yZVtzdG9yZVBvc2l0aW9uXSA9IHRoaXMuZ3REYXRhO1xuXHRcdFx0dGhpcy5ndEluZm8udmlzaWJsZVJlY29yZHMgPSBbLi4udGhpcy5ndERhdGFdOyAvLyBhZGQgdmlzaWJsZSByb3dzXG5cblx0XHRcdC8vIHJlcGxhY2UgZGF0YSB3aXRoIHN0b3JlXG5cdFx0XHR0aGlzLl9ndERhdGEgPSB0aGlzLnN0b3JlO1xuXHRcdFx0dGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cdFx0XHR0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cdFx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRcdG5hbWU6ICdndC1pbmZvJyxcblx0XHRcdFx0dmFsdWU6IHRoaXMuZ3RJbmZvXG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0dGhpcy5fZ3REYXRhICYmXG5cdFx0XHR0aGlzLl9ndERhdGEubGVuZ3RoID49IDAgJiZcblx0XHRcdGNoYW5nZXNbJ2d0RGF0YSddICYmXG5cdFx0XHRjaGFuZ2VzWydndERhdGEnXS5wcmV2aW91c1ZhbHVlXG5cdFx0KSB7XG5cdFx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0Y2hhbmdlc1snZ3REYXRhJ10gJiZcblx0XHRcdGNoYW5nZXNbJ2d0RGF0YSddLmZpcnN0Q2hhbmdlICYmXG5cdFx0XHR0aGlzLl9ndERhdGEgJiZcblx0XHRcdHRoaXMuX2d0RGF0YS5sZW5ndGggPiAwXG5cdFx0KSB7XG5cdFx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHR0cmFja0J5Rm4oaW5kZXg6IG51bWJlciwgaXRlbTogR3RSb3cpIHtcblx0XHRyZXR1cm4gaXRlbS4kJGd0Um93SWQ7XG5cdH1cblxuXHR0cmFja0J5Q29sdW1uRm4oaW5kZXg6IG51bWJlciwgaXRlbTogR3RDb25maWdGaWVsZDxhbnksIGFueT4pIHtcblx0XHRyZXR1cm4gaXRlbS5vYmplY3RLZXk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHQvLyByZW1vdmUgbGlzdGVuZXJcblx0XHR0aGlzLl9zdG9wTGlzdGVuaW5nRm9yS2V5ZG93bkV2ZW50KCk7XG5cdH1cbn1cbiJdfQ==