@seniorsistemas/platform-components 5.3.2 → 5.3.3-develop-73308358

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 (245) hide show
  1. package/esm2022/modules/advanced-filter/advanced-filter.module.mjs +75 -0
  2. package/esm2022/modules/advanced-filter/components/advanced-filter/advanced-filter.component.mjs +128 -0
  3. package/esm2022/modules/advanced-filter/components/form-filter/form-filter.component.mjs +651 -0
  4. package/esm2022/modules/advanced-filter/index.mjs +6 -0
  5. package/esm2022/modules/advanced-filter/locale/fallback.mjs +73 -0
  6. package/esm2022/modules/advanced-filter/models/context.mjs +2 -0
  7. package/esm2022/modules/advanced-filter/models/depends-on.mjs +2 -0
  8. package/esm2022/modules/advanced-filter/models/enum-item.mjs +2 -0
  9. package/esm2022/modules/advanced-filter/models/filter-type.mjs +14 -0
  10. package/esm2022/modules/advanced-filter/models/filter-value.mjs +2 -0
  11. package/esm2022/modules/advanced-filter/models/filter.mjs +41 -0
  12. package/esm2022/modules/advanced-filter/models/form-filter.mjs +28 -0
  13. package/esm2022/modules/advanced-filter/models/index.mjs +11 -0
  14. package/esm2022/modules/advanced-filter/models/scope.mjs +6 -0
  15. package/esm2022/modules/advanced-filter/models/search.mjs +2 -0
  16. package/esm2022/modules/advanced-filter/models/tab-view.mjs +18 -0
  17. package/esm2022/modules/advanced-filter/models/ticked-filter.mjs +2 -0
  18. package/esm2022/modules/advanced-filter/pipes/map-values.pipe.mjs +14 -0
  19. package/esm2022/modules/advanced-filter/pipes/translate.pipe.mjs +19 -0
  20. package/esm2022/modules/advanced-filter/services/advanced-filter.service.mjs +146 -0
  21. package/esm2022/modules/advanced-filter/services/calendar-options.service.mjs +77 -0
  22. package/esm2022/modules/advanced-filter/services/constants.mjs +6 -0
  23. package/esm2022/modules/advanced-filter/shared/constants.mjs +3 -0
  24. package/esm2022/modules/advanced-filter/utils/comparator.mjs +53 -0
  25. package/esm2022/modules/advanced-filter/utils/filter-id/index.mjs +8 -0
  26. package/esm2022/modules/advanced-filter/utils/filter-value/index.mjs +26 -0
  27. package/esm2022/modules/advanced-filter/utils/filterOperators.mjs +9 -0
  28. package/esm2022/modules/advanced-filter/utils/form-field/index.mjs +52 -0
  29. package/esm2022/modules/advanced-filter/utils/index.mjs +57 -0
  30. package/esm2022/modules/advanced-filter/utils/json-path.mjs +13 -0
  31. package/esm2022/modules/cyclic-json-interceptor/cyclic-json-interceptor.module.mjs +14 -0
  32. package/esm2022/modules/cyclic-json-interceptor/cyclic-json-interceptor.service.mjs +29 -0
  33. package/esm2022/modules/cyclic-json-interceptor/index.mjs +2 -0
  34. package/esm2022/modules/feature-toggle/constants/endpoint.constant.mjs +26 -0
  35. package/esm2022/modules/feature-toggle/feature-toggle.module.mjs +15 -0
  36. package/esm2022/modules/feature-toggle/feature-toggle.service.mjs +42 -0
  37. package/esm2022/modules/feature-toggle/index.mjs +4 -0
  38. package/esm2022/modules/feature-toggle/models/feature.mjs +2 -0
  39. package/esm2022/modules/http-interceptor/http-interceptor.module.mjs +16 -0
  40. package/esm2022/modules/http-interceptor/http-interceptor.service.mjs +42 -0
  41. package/esm2022/modules/http-interceptor/index.mjs +4 -0
  42. package/esm2022/modules/http-interceptor/rest-url.service.mjs +15 -0
  43. package/esm2022/modules/http-interceptor/x-services-url.service.mjs +18 -0
  44. package/esm2022/modules/permissions/permissions.config.mjs +17 -0
  45. package/esm2022/modules/permissions/permissions.module.mjs +43 -0
  46. package/esm2022/modules/permissions/permissions.service.mjs +169 -0
  47. package/esm2022/modules/spotlight/component/spotlight.component.mjs +274 -0
  48. package/esm2022/modules/spotlight/index.mjs +3 -0
  49. package/esm2022/modules/spotlight/locale/fallback.mjs +5 -0
  50. package/esm2022/modules/spotlight/models/display-type.enum.mjs +6 -0
  51. package/esm2022/modules/spotlight/models/index.mjs +10 -0
  52. package/esm2022/modules/spotlight/models/spotlight-control-list.interface.mjs +2 -0
  53. package/esm2022/modules/spotlight/models/spotlight-control.interface.mjs +11 -0
  54. package/esm2022/modules/spotlight/models/spotlight-notification.interface.mjs +2 -0
  55. package/esm2022/modules/spotlight/models/spotlight-screen-list.interface.mjs +2 -0
  56. package/esm2022/modules/spotlight/models/spotlight-screen.interface.mjs +2 -0
  57. package/esm2022/modules/spotlight/models/spotlight-status.enum.mjs +8 -0
  58. package/esm2022/modules/spotlight/models/spotlight-user.interface.mjs +2 -0
  59. package/esm2022/modules/spotlight/models/spotlight-users-list.interface.mjs +2 -0
  60. package/esm2022/modules/spotlight/models/spotlight.interface.mjs +2 -0
  61. package/esm2022/modules/spotlight/models/user-action.enum.mjs +7 -0
  62. package/esm2022/modules/spotlight/pipes/translate.pipe.mjs +19 -0
  63. package/esm2022/modules/spotlight/service/spotlight.service.mjs +34 -0
  64. package/esm2022/modules/spotlight/spotlight.module.mjs +53 -0
  65. package/esm2022/modules/translations/translations.module.mjs +192 -0
  66. package/esm2022/public-api.mjs +10 -0
  67. package/esm2022/seniorsistemas-platform-components.mjs +5 -0
  68. package/fesm2022/seniorsistemas-platform-components.mjs +2432 -0
  69. package/fesm2022/seniorsistemas-platform-components.mjs.map +1 -0
  70. package/index.d.ts +5 -0
  71. package/modules/advanced-filter/advanced-filter.module.d.ts +19 -0
  72. package/modules/advanced-filter/components/advanced-filter/advanced-filter.component.d.ts +4 -3
  73. package/modules/advanced-filter/components/form-filter/form-filter.component.d.ts +15 -12
  74. package/modules/advanced-filter/index.d.ts +1 -0
  75. package/modules/advanced-filter/models/tab-view.d.ts +1 -1
  76. package/modules/advanced-filter/pipes/map-values.pipe.d.ts +3 -0
  77. package/modules/advanced-filter/pipes/translate.pipe.d.ts +4 -3
  78. package/modules/advanced-filter/services/advanced-filter.service.d.ts +7 -3
  79. package/modules/advanced-filter/services/calendar-options.service.d.ts +4 -3
  80. package/modules/advanced-filter/services/constants.d.ts +4 -4
  81. package/modules/advanced-filter/utils/comparator.d.ts +1 -1
  82. package/modules/advanced-filter/utils/form-field/index.d.ts +1 -1
  83. package/modules/advanced-filter/utils/json-path.d.ts +1 -1
  84. package/modules/cyclic-json-interceptor/cyclic-json-interceptor.module.d.ts +4 -0
  85. package/modules/cyclic-json-interceptor/cyclic-json-interceptor.service.d.ts +3 -0
  86. package/modules/feature-toggle/feature-toggle.module.d.ts +5 -0
  87. package/modules/feature-toggle/feature-toggle.service.d.ts +4 -3
  88. package/modules/http-interceptor/http-interceptor.module.d.ts +4 -0
  89. package/modules/http-interceptor/http-interceptor.service.d.ts +3 -3
  90. package/modules/http-interceptor/rest-url.service.d.ts +3 -0
  91. package/modules/http-interceptor/x-services-url.service.d.ts +3 -0
  92. package/modules/permissions/permissions.config.d.ts +7 -1
  93. package/modules/permissions/permissions.module.d.ts +4 -0
  94. package/modules/permissions/permissions.service.d.ts +6 -12
  95. package/modules/spotlight/component/spotlight.component.d.ts +6 -7
  96. package/modules/spotlight/pipes/translate.pipe.d.ts +4 -3
  97. package/modules/spotlight/service/spotlight.service.d.ts +4 -3
  98. package/modules/spotlight/spotlight.module.d.ts +11 -0
  99. package/modules/translations/translations.module.d.ts +9 -5
  100. package/package.json +20 -54
  101. package/public-api.d.ts +1 -0
  102. package/bundles/seniorsistemas-platform-components.umd.js +0 -2745
  103. package/bundles/seniorsistemas-platform-components.umd.js.map +0 -1
  104. package/bundles/seniorsistemas-platform-components.umd.min.js +0 -17
  105. package/bundles/seniorsistemas-platform-components.umd.min.js.map +0 -1
  106. package/esm2015/modules/advanced-filter/advanced-filter.module.js +0 -47
  107. package/esm2015/modules/advanced-filter/components/advanced-filter/advanced-filter.component.js +0 -136
  108. package/esm2015/modules/advanced-filter/components/form-filter/form-filter.component.js +0 -578
  109. package/esm2015/modules/advanced-filter/index.js +0 -5
  110. package/esm2015/modules/advanced-filter/locale/fallback.js +0 -73
  111. package/esm2015/modules/advanced-filter/models/context.js +0 -1
  112. package/esm2015/modules/advanced-filter/models/depends-on.js +0 -1
  113. package/esm2015/modules/advanced-filter/models/enum-item.js +0 -1
  114. package/esm2015/modules/advanced-filter/models/filter-type.js +0 -14
  115. package/esm2015/modules/advanced-filter/models/filter-value.js +0 -1
  116. package/esm2015/modules/advanced-filter/models/filter.js +0 -23
  117. package/esm2015/modules/advanced-filter/models/form-filter.js +0 -19
  118. package/esm2015/modules/advanced-filter/models/index.js +0 -5
  119. package/esm2015/modules/advanced-filter/models/scope.js +0 -6
  120. package/esm2015/modules/advanced-filter/models/search.js +0 -1
  121. package/esm2015/modules/advanced-filter/models/tab-view.js +0 -18
  122. package/esm2015/modules/advanced-filter/models/ticked-filter.js +0 -1
  123. package/esm2015/modules/advanced-filter/pipes/map-values.pipe.js +0 -12
  124. package/esm2015/modules/advanced-filter/pipes/translate.pipe.js +0 -22
  125. package/esm2015/modules/advanced-filter/services/advanced-filter.service.js +0 -141
  126. package/esm2015/modules/advanced-filter/services/calendar-options.service.js +0 -81
  127. package/esm2015/modules/advanced-filter/services/constants.js +0 -6
  128. package/esm2015/modules/advanced-filter/shared/constants.js +0 -3
  129. package/esm2015/modules/advanced-filter/utils/comparator.js +0 -55
  130. package/esm2015/modules/advanced-filter/utils/filter-id/index.js +0 -8
  131. package/esm2015/modules/advanced-filter/utils/filter-value/index.js +0 -24
  132. package/esm2015/modules/advanced-filter/utils/filterOperators.js +0 -11
  133. package/esm2015/modules/advanced-filter/utils/form-field/index.js +0 -50
  134. package/esm2015/modules/advanced-filter/utils/index.js +0 -57
  135. package/esm2015/modules/advanced-filter/utils/json-path.js +0 -12
  136. package/esm2015/modules/cyclic-json-interceptor/cyclic-json-interceptor.module.js +0 -14
  137. package/esm2015/modules/cyclic-json-interceptor/cyclic-json-interceptor.service.js +0 -27
  138. package/esm2015/modules/cyclic-json-interceptor/index.js +0 -2
  139. package/esm2015/modules/feature-toggle/constants/endpoint.constant.js +0 -26
  140. package/esm2015/modules/feature-toggle/feature-toggle.module.js +0 -15
  141. package/esm2015/modules/feature-toggle/feature-toggle.service.js +0 -48
  142. package/esm2015/modules/feature-toggle/index.js +0 -3
  143. package/esm2015/modules/feature-toggle/models/feature.js +0 -1
  144. package/esm2015/modules/http-interceptor/http-interceptor.module.js +0 -16
  145. package/esm2015/modules/http-interceptor/http-interceptor.service.js +0 -47
  146. package/esm2015/modules/http-interceptor/index.js +0 -4
  147. package/esm2015/modules/http-interceptor/rest-url.service.js +0 -14
  148. package/esm2015/modules/http-interceptor/x-services-url.service.js +0 -17
  149. package/esm2015/modules/permissions/permissions.config.js +0 -11
  150. package/esm2015/modules/permissions/permissions.module.js +0 -42
  151. package/esm2015/modules/permissions/permissions.service.js +0 -196
  152. package/esm2015/modules/spotlight/component/spotlight.component.js +0 -274
  153. package/esm2015/modules/spotlight/index.js +0 -3
  154. package/esm2015/modules/spotlight/locale/fallback.js +0 -5
  155. package/esm2015/modules/spotlight/models/display-type.enum.js +0 -6
  156. package/esm2015/modules/spotlight/models/index.js +0 -4
  157. package/esm2015/modules/spotlight/models/spotlight-control-list.interface.js +0 -1
  158. package/esm2015/modules/spotlight/models/spotlight-control.interface.js +0 -3
  159. package/esm2015/modules/spotlight/models/spotlight-notification.interface.js +0 -1
  160. package/esm2015/modules/spotlight/models/spotlight-screen-list.interface.js +0 -1
  161. package/esm2015/modules/spotlight/models/spotlight-screen.interface.js +0 -1
  162. package/esm2015/modules/spotlight/models/spotlight-status.enum.js +0 -8
  163. package/esm2015/modules/spotlight/models/spotlight-user.interface.js +0 -1
  164. package/esm2015/modules/spotlight/models/spotlight-users-list.interface.js +0 -1
  165. package/esm2015/modules/spotlight/models/spotlight.interface.js +0 -1
  166. package/esm2015/modules/spotlight/models/user-action.enum.js +0 -7
  167. package/esm2015/modules/spotlight/pipes/translate.pipe.js +0 -22
  168. package/esm2015/modules/spotlight/service/spotlight.service.js +0 -38
  169. package/esm2015/modules/spotlight/spotlight.module.js +0 -37
  170. package/esm2015/modules/translations/translations.module.js +0 -182
  171. package/esm2015/public-api.js +0 -9
  172. package/esm2015/seniorsistemas-platform-components.js +0 -16
  173. package/esm5/modules/advanced-filter/advanced-filter.module.js +0 -54
  174. package/esm5/modules/advanced-filter/components/advanced-filter/advanced-filter.component.js +0 -144
  175. package/esm5/modules/advanced-filter/components/form-filter/form-filter.component.js +0 -626
  176. package/esm5/modules/advanced-filter/index.js +0 -5
  177. package/esm5/modules/advanced-filter/locale/fallback.js +0 -73
  178. package/esm5/modules/advanced-filter/models/context.js +0 -1
  179. package/esm5/modules/advanced-filter/models/depends-on.js +0 -1
  180. package/esm5/modules/advanced-filter/models/enum-item.js +0 -1
  181. package/esm5/modules/advanced-filter/models/filter-type.js +0 -14
  182. package/esm5/modules/advanced-filter/models/filter-value.js +0 -1
  183. package/esm5/modules/advanced-filter/models/filter.js +0 -25
  184. package/esm5/modules/advanced-filter/models/form-filter.js +0 -25
  185. package/esm5/modules/advanced-filter/models/index.js +0 -5
  186. package/esm5/modules/advanced-filter/models/scope.js +0 -6
  187. package/esm5/modules/advanced-filter/models/search.js +0 -1
  188. package/esm5/modules/advanced-filter/models/tab-view.js +0 -29
  189. package/esm5/modules/advanced-filter/models/ticked-filter.js +0 -1
  190. package/esm5/modules/advanced-filter/pipes/map-values.pipe.js +0 -16
  191. package/esm5/modules/advanced-filter/pipes/translate.pipe.js +0 -23
  192. package/esm5/modules/advanced-filter/services/advanced-filter.service.js +0 -152
  193. package/esm5/modules/advanced-filter/services/calendar-options.service.js +0 -82
  194. package/esm5/modules/advanced-filter/services/constants.js +0 -6
  195. package/esm5/modules/advanced-filter/shared/constants.js +0 -3
  196. package/esm5/modules/advanced-filter/utils/comparator.js +0 -55
  197. package/esm5/modules/advanced-filter/utils/filter-id/index.js +0 -8
  198. package/esm5/modules/advanced-filter/utils/filter-value/index.js +0 -25
  199. package/esm5/modules/advanced-filter/utils/filterOperators.js +0 -11
  200. package/esm5/modules/advanced-filter/utils/form-field/index.js +0 -52
  201. package/esm5/modules/advanced-filter/utils/index.js +0 -57
  202. package/esm5/modules/advanced-filter/utils/json-path.js +0 -12
  203. package/esm5/modules/cyclic-json-interceptor/cyclic-json-interceptor.module.js +0 -17
  204. package/esm5/modules/cyclic-json-interceptor/cyclic-json-interceptor.service.js +0 -30
  205. package/esm5/modules/cyclic-json-interceptor/index.js +0 -2
  206. package/esm5/modules/feature-toggle/constants/endpoint.constant.js +0 -27
  207. package/esm5/modules/feature-toggle/feature-toggle.module.js +0 -18
  208. package/esm5/modules/feature-toggle/feature-toggle.service.js +0 -51
  209. package/esm5/modules/feature-toggle/index.js +0 -3
  210. package/esm5/modules/feature-toggle/models/feature.js +0 -1
  211. package/esm5/modules/http-interceptor/http-interceptor.module.js +0 -19
  212. package/esm5/modules/http-interceptor/http-interceptor.service.js +0 -49
  213. package/esm5/modules/http-interceptor/index.js +0 -4
  214. package/esm5/modules/http-interceptor/rest-url.service.js +0 -17
  215. package/esm5/modules/http-interceptor/x-services-url.service.js +0 -20
  216. package/esm5/modules/permissions/permissions.config.js +0 -17
  217. package/esm5/modules/permissions/permissions.module.js +0 -46
  218. package/esm5/modules/permissions/permissions.service.js +0 -212
  219. package/esm5/modules/spotlight/component/spotlight.component.js +0 -300
  220. package/esm5/modules/spotlight/index.js +0 -3
  221. package/esm5/modules/spotlight/locale/fallback.js +0 -5
  222. package/esm5/modules/spotlight/models/display-type.enum.js +0 -6
  223. package/esm5/modules/spotlight/models/index.js +0 -4
  224. package/esm5/modules/spotlight/models/spotlight-control-list.interface.js +0 -1
  225. package/esm5/modules/spotlight/models/spotlight-control.interface.js +0 -7
  226. package/esm5/modules/spotlight/models/spotlight-notification.interface.js +0 -1
  227. package/esm5/modules/spotlight/models/spotlight-screen-list.interface.js +0 -1
  228. package/esm5/modules/spotlight/models/spotlight-screen.interface.js +0 -1
  229. package/esm5/modules/spotlight/models/spotlight-status.enum.js +0 -8
  230. package/esm5/modules/spotlight/models/spotlight-user.interface.js +0 -1
  231. package/esm5/modules/spotlight/models/spotlight-users-list.interface.js +0 -1
  232. package/esm5/modules/spotlight/models/spotlight.interface.js +0 -1
  233. package/esm5/modules/spotlight/models/user-action.enum.js +0 -7
  234. package/esm5/modules/spotlight/pipes/translate.pipe.js +0 -23
  235. package/esm5/modules/spotlight/service/spotlight.service.js +0 -39
  236. package/esm5/modules/spotlight/spotlight.module.js +0 -40
  237. package/esm5/modules/translations/translations.module.js +0 -226
  238. package/esm5/public-api.js +0 -9
  239. package/esm5/seniorsistemas-platform-components.js +0 -16
  240. package/fesm2015/seniorsistemas-platform-components.js +0 -2284
  241. package/fesm2015/seniorsistemas-platform-components.js.map +0 -1
  242. package/fesm5/seniorsistemas-platform-components.js +0 -2507
  243. package/fesm5/seniorsistemas-platform-components.js.map +0 -1
  244. package/seniorsistemas-platform-components.d.ts +0 -15
  245. package/seniorsistemas-platform-components.metadata.json +0 -1
@@ -1,578 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { MessageService } from "primeng/api";
3
- import { ChangeDetectorRef, Component, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output } from '@angular/core';
4
- import { BehaviorSubject, from, Subject } from 'rxjs';
5
- import { filter as rxFilter, map, mergeMap, takeUntil, tap } from 'rxjs/operators';
6
- import { FilterType, Scope } from '../../models';
7
- import { ContextTab, TabView } from '../../models/tab-view';
8
- import { AdvancedFilterService } from '../../services/advanced-filter.service';
9
- import { FormFilter } from '../../models/form-filter';
10
- import { filterOperators, fromJson, getFilterId, getSearchType, getTabId, jsonPath, parseFilterValue, toFilterFormat, toUserFormat } from '../../utils/index';
11
- import { createFormControl } from '../../utils/form-field';
12
- import { clone, equals } from 'ramda';
13
- import { compare, isSupportedType, isValidOperator } from '../../utils/comparator';
14
- import { AutocompleteField, CalendarField, RadioButtonField, CurrencyField, FieldType, NumberField, SelectField, TextField } from '@seniorsistemas/angular-components';
15
- import { searchDisplayName, searchKeyName } from '../../shared/constants';
16
- import { TranslateService } from '@ngx-translate/core';
17
- import { CalendarOptionsService } from '../../services/calendar-options.service';
18
- const TRANSLATE_PREFIX = 'platform.filter_service';
19
- const TOAST_LIFE = 5000;
20
- let FormFilterComponent = class FormFilterComponent {
21
- constructor(filterService, translate, messageService, calendarOptionsService, changeDetectorRef) {
22
- this.filterService = filterService;
23
- this.translate = translate;
24
- this.messageService = messageService;
25
- this.calendarOptionsService = calendarOptionsService;
26
- this.changeDetectorRef = changeDetectorRef;
27
- this.destroy$ = new Subject();
28
- this.contexts = [];
29
- this.formFilters = [];
30
- this.oldFormFilters = [];
31
- this.actualFormFilters = [];
32
- this.general = new TabView({ name: 'Geral' });
33
- this.totalFiltersActive = 0;
34
- this.isMobile = false;
35
- this.tabViewOrientation = 'left';
36
- this.error = false;
37
- this.errorMessages = {
38
- min: this.translate.instant(`${TRANSLATE_PREFIX}.error_min_value`),
39
- max: this.translate.instant(`${TRANSLATE_PREFIX}.error_max_value`),
40
- pattern: this.translate.instant(`${TRANSLATE_PREFIX}.invalid_pattern`)
41
- };
42
- this.showMessages = true;
43
- this.isModal = false;
44
- this.contextId = '';
45
- this.totalFiltersActiveOutput = new EventEmitter();
46
- this.errorOutput = new EventEmitter();
47
- this.showDialogOutput = new EventEmitter();
48
- this.closeModalOutput = new EventEmitter();
49
- }
50
- onResizeWindow(event) {
51
- const { innerWidth } = event.target;
52
- this.isMobile = innerWidth <= 640;
53
- this.tabViewOrientation = this.isMobile ? 'top' : 'left';
54
- }
55
- ngOnInit() {
56
- this.isMobile = innerWidth <= 640;
57
- this.tabViewOrientation = this.isMobile ? 'top' : 'left';
58
- this.subscribeContextsObservable();
59
- this.subscribeFiltersObservable();
60
- window.addEventListener('message', event => {
61
- const data = event.data;
62
- const message = data.message && data.message.split(':')[1];
63
- if (message === 'addContext') {
64
- this.filterService.addContexts(...data.payload);
65
- }
66
- });
67
- }
68
- ngOnDestroy() {
69
- this.destroy$.next(true);
70
- }
71
- hasChanges() {
72
- const keys = Object.keys(this.formFilters);
73
- const oldKeys = Object.keys(this.oldFormFilters);
74
- if (!oldKeys.length) {
75
- return true;
76
- }
77
- const filtered = keys.filter(key => {
78
- const currentValue = this.formFilters[key].value;
79
- const oldValue = this.oldFormFilters[key] && this.oldFormFilters[key].value;
80
- return !equals(currentValue, oldValue);
81
- });
82
- return filtered.length > 0;
83
- }
84
- onApplyFilters() {
85
- this.hasChanges() && this.closeModalOutput.emit();
86
- }
87
- getFilters() {
88
- this.hasChanges() && this.filterService.tryAgain(this.contexts);
89
- }
90
- applyFilters(showToast = false) {
91
- if (this.hasChanges()) {
92
- this.showDialogOutput.emit(false);
93
- this.counterUpdate();
94
- const filters = this.getFiltersValues(this.formFilters);
95
- this.filterService.saveTickedFilters(filters);
96
- }
97
- else if (showToast) {
98
- const message = {
99
- key: 'filterServiceToastKey',
100
- severity: 'info',
101
- life: TOAST_LIFE,
102
- detail: this.translate.instant(`${TRANSLATE_PREFIX}.applied_filter_nochange`, { activeFilters: this.totalFiltersActive })
103
- };
104
- this.sendMessage(message);
105
- }
106
- this.oldFormFilters = clone(this.formFilters);
107
- }
108
- getDefaultValue(defaultValue, isMultiple) {
109
- if (defaultValue === undefined || (isMultiple && defaultValue[0] === '')) {
110
- return [];
111
- }
112
- return defaultValue;
113
- }
114
- clearFilters() {
115
- const keys = Object.keys(this.formFilters);
116
- keys.forEach(key => this.cleanFieldAndSetDefaultValue(key));
117
- }
118
- sendCloseMessage() {
119
- window.parent.postMessage({
120
- message: 'dashboard:close-modal',
121
- payload: {
122
- modalName: 'advanced-filter-1'
123
- }
124
- }, '*');
125
- }
126
- sendMessage(message) {
127
- if (this.showMessages) {
128
- this.messageService.add(message);
129
- }
130
- else {
131
- window.parent.postMessage({
132
- message: 'dashboard:toastr',
133
- payload: {
134
- type: 'success',
135
- message: message.detail
136
- }
137
- }, '*');
138
- }
139
- }
140
- saveFilters(forceSave = false) {
141
- const filters = this.parseToUserFilters(this.formFilters);
142
- const savedFilterSuccess = () => {
143
- if (!forceSave) {
144
- const message = {
145
- key: 'filterServiceToastKey',
146
- severity: 'info',
147
- life: TOAST_LIFE,
148
- detail: this.translate.instant(`${TRANSLATE_PREFIX}.saved_filters_success`, { activeFilters: this.totalFiltersActive })
149
- };
150
- this.sendMessage(message);
151
- }
152
- this.counterUpdate();
153
- };
154
- const savedFiltersError = () => {
155
- const message = {
156
- key: 'filterServiceToastKey',
157
- severity: 'error',
158
- life: TOAST_LIFE,
159
- detail: this.translate.instant(`${TRANSLATE_PREFIX}.saved_filters_error`, { activeFilters: this.totalFiltersActive })
160
- };
161
- this.sendMessage(message);
162
- };
163
- this.filterService
164
- .saveFilters(filters)
165
- .subscribe(savedFilterSuccess, savedFiltersError);
166
- }
167
- saveFiltersWithCallbackFunction(callbackFunction) {
168
- const filters = this.parseToUserFilters(this.formFilters);
169
- this.filterService
170
- .saveFilters(filters)
171
- .subscribe(callbackFunction);
172
- }
173
- counterUpdate() {
174
- this.totalFiltersActive = this.countActiveFilters(this.tabs);
175
- this.totalFiltersActiveOutput.emit(this.totalFiltersActive);
176
- }
177
- countActiveFilters(tabs) {
178
- let totalFiltersActive = 0;
179
- tabs.forEach(tabView => {
180
- const { value } = tabView.form;
181
- tabView.activeFilters = Object.keys(value).reduce((appliedFilters, key) => {
182
- const filterValue = value[key];
183
- const isArray = Array.isArray(filterValue);
184
- const isValidArray = isArray && filterValue.length > 0;
185
- if (isValidArray || (!isArray && filterValue)) {
186
- appliedFilters++;
187
- }
188
- return appliedFilters;
189
- }, 0);
190
- totalFiltersActive += tabView.activeFilters;
191
- });
192
- return totalFiltersActive;
193
- }
194
- parseToUserFilters(filters) {
195
- const ids = Object.keys(filters);
196
- return ids.reduce((all, filterId) => {
197
- const { type, services, name, value, domain, contexts } = filters[filterId];
198
- const filterValue = toUserFormat(value, type);
199
- const values = services.map(service => ({ name, service, value: filterValue, domain, contexts }));
200
- return [...all, ...values];
201
- }, []);
202
- }
203
- getFiltersValues(filters) {
204
- const ids = Object.keys(filters);
205
- return ids.reduce((all, filterId) => {
206
- const { type, services, name, value, domain } = filters[filterId];
207
- const filterValue = toFilterFormat(value, type);
208
- const values = services.map(service => ({ name, service, value: filterValue, domain }));
209
- return [...all, ...values];
210
- }, []);
211
- }
212
- subscribeContextsObservable() {
213
- const { contextsObserver } = this.filterService;
214
- contextsObserver.pipe(takeUntil(this.destroy$)).subscribe((contexts) => (this.contexts = contexts));
215
- }
216
- errorStateAction() {
217
- this.filterService.tryAgain(this.contexts);
218
- }
219
- subscribeFiltersObservable() {
220
- const { filtersObserver } = this.filterService;
221
- filtersObserver
222
- .pipe(takeUntil(this.destroy$))
223
- .subscribe(({ filters, applyFilter, error, message }) => {
224
- this.errorOutput.emit(error);
225
- this.error = error;
226
- this.errorState = message;
227
- if (!error) {
228
- this.createForm(filters, applyFilter);
229
- }
230
- });
231
- }
232
- createForm(filters, applyFilter) {
233
- this.tabs = this.createTabs(filters);
234
- this.counterUpdate();
235
- this.setDependencies(this.formFilters);
236
- this.createChildArray();
237
- if (filters.length > 0 && applyFilter) {
238
- this.applyFilters();
239
- }
240
- }
241
- setDependencies(filters) {
242
- const names = Object.keys(filters);
243
- const dependencies = from(names).pipe(map(key => filters[key]), rxFilter(({ dependsOn }) => dependsOn && dependsOn.length > 0), tap(({ dependsOn, domain, filterControl }) => {
244
- const invalidFilters = dependsOn
245
- .filter(dep => dep.required)
246
- .filter(dep => {
247
- const id = getFilterId(domain, dep.filterName);
248
- const formFilter = filters[id];
249
- const { value, type } = formFilter;
250
- const { comparator } = dep;
251
- if (comparator && isValidOperator(comparator.operator) && isSupportedType(type)) {
252
- const fieldValue = parseFilterValue(value, type);
253
- return !compare(comparator.operator, comparator.value, fieldValue);
254
- }
255
- return dep.required ? !formFilter.value : formFilter.value;
256
- });
257
- if (invalidFilters.length > 0) {
258
- filterControl.disable();
259
- }
260
- }), map(({ domain, dependsOn, filterControl }) => ({ domain, dependsOn, filterControl })));
261
- dependencies.subscribe(({ dependsOn, domain, filterControl }) => from(dependsOn)
262
- .pipe(rxFilter(dep => dep.required), map(({ filterName }) => getFilterId(domain, filterName)), map(filterId => filters[filterId]), mergeMap(formFilter => from(formFilter.valueChanges)), map(val => {
263
- const comparation = dependsOn.every(dep => {
264
- const filterId = getFilterId(domain, dep.filterName);
265
- if (this.formFilters[filterId]) {
266
- const type = this.formFilters[filterId].type;
267
- const { comparator } = dep;
268
- if (comparator && isValidOperator(comparator.operator) && isSupportedType(type)) {
269
- const value = parseFilterValue(val, type);
270
- return compare(comparator.operator, comparator.value, value);
271
- }
272
- return true;
273
- }
274
- });
275
- return !this.IsEmpty(val) && comparation ? 'enable' : 'disable';
276
- }))
277
- .subscribe(status => filterControl[status]()));
278
- }
279
- addGeneralField(filter) {
280
- const { name, domain, type } = filter;
281
- const controlName = getFilterId(domain, name);
282
- const fieldControl = createFormControl(filter);
283
- fieldControl.valueChanges
284
- .pipe(takeUntil(this.destroy$), map(v => parseFilterValue(v, type)), tap(value => (this.formFilters[controlName].value = value)))
285
- .subscribe(val => this.tabs.forEach(tab => {
286
- const control = tab.form.controls[name];
287
- if (control && tab.domain === domain) {
288
- control.setValue(val, { emitEvent: false });
289
- }
290
- }));
291
- const newFilter = Object.assign(Object.assign({}, filter), { name: controlName });
292
- const newField = this.createField(newFilter);
293
- this.general.form.addControl(controlName, fieldControl);
294
- this.general.fields.push(newField);
295
- }
296
- /*
297
- * Verifica os contextos de cada filtro, caso todos os contextos foram informados:
298
- * @return true
299
- * Caso não tenha nenhum contexto, considera-se por padrão que é todos:
300
- * @return true
301
- */
302
- containsAllContexts(myContexts) {
303
- if (!myContexts.length) {
304
- return true;
305
- }
306
- const allContexts = this.contexts.map(data => data.contextId);
307
- return equals(myContexts.sort(), allContexts.sort());
308
- }
309
- /**
310
- *
311
- * @todo Refatorar. O método possui muitas responsabilidades
312
- *
313
- */
314
- createTabs(filters) {
315
- return filters.reduce((tabs, filter) => {
316
- const { domain, services, name, type, scope, contexts, dependsOn, value, search, defaultValue } = filter;
317
- const isNotMultiple = search && getSearchType(search).output.maxSelectedItems === 1;
318
- const field = this.createField(filter);
319
- const filterId = getFilterId(domain, name);
320
- const filterConfig = {
321
- domain,
322
- contexts,
323
- services,
324
- name,
325
- dependsOn,
326
- value: fromJson(value, type, isNotMultiple),
327
- type,
328
- isMultiple: !isNotMultiple,
329
- defaultValue: fromJson(defaultValue, type, isNotMultiple)
330
- };
331
- this.formFilters[filterId] = new FormFilter(filterConfig);
332
- const formFilter = this.formFilters[filterId];
333
- if (scope === Scope.DOMAIN && this.containsAllContexts(contexts)) {
334
- this.addGeneralField(filter);
335
- }
336
- contexts.forEach(contextId => {
337
- if ((contextId === this.contextId) || (this.contextId === '')) {
338
- const tabId = getTabId(domain, contextId);
339
- const fieldControl = createFormControl(filter);
340
- if (!tabs.has(tabId)) {
341
- const { contextLabel } = this.contexts.find(context => context.contextId === contextId);
342
- const tab = new ContextTab({ domain, name: contextLabel });
343
- tabs.set(tabId, tab);
344
- }
345
- fieldControl.valueChanges
346
- .pipe(takeUntil(this.destroy$))
347
- .subscribe((val) => this.updateFilterValue(tabId, name, val, domain, type));
348
- const contextTab = tabs.get(tabId);
349
- contextTab.fields.push(field);
350
- contextTab.form.addControl(filter.name, fieldControl);
351
- if (!formFilter.filterControl) {
352
- formFilter.filterControl = fieldControl;
353
- }
354
- }
355
- });
356
- return tabs;
357
- }, new Map());
358
- }
359
- updateFilterValue(tabId, filterName, value, domain, type) {
360
- const controlOpts = { emitEvent: false };
361
- const fieldValue = parseFilterValue(value, type);
362
- const filterId = getFilterId(domain, filterName);
363
- const generalFieldControl = this.general.form.controls[filterId];
364
- this.tabs.forEach(({ form }, key) => {
365
- const control = form.controls[filterName];
366
- if (tabId !== key && control) {
367
- control.setValue(value, controlOpts);
368
- }
369
- });
370
- const { childs } = this.formFilters[filterId];
371
- childs && childs.forEach((child) => this.cleanFieldAndSetDefaultValue(child.filter.key));
372
- generalFieldControl && generalFieldControl.setValue(value, controlOpts);
373
- this.formFilters[filterId].value = fieldValue;
374
- }
375
- cleanFieldAndSetDefaultValue(key) {
376
- const { isMultiple, defaultValue, filterControl, type } = this.formFilters[key];
377
- const finalValue = this.getDefaultValue(defaultValue, isMultiple);
378
- if (filterControl) {
379
- if (type === 'DATE' || (type === 'SEARCH' && isMultiple)) {
380
- filterControl.setValue(finalValue);
381
- }
382
- if (type === 'INTEGER' || type === 'DOUBLE' || type === 'MONEY') {
383
- finalValue === '' ? filterControl.setValue(null) : filterControl.setValue(finalValue);
384
- }
385
- else {
386
- filterControl.setValue(finalValue, { onlySelf: true });
387
- }
388
- }
389
- }
390
- createChildArray() {
391
- const keys = Object.keys(this.formFilters);
392
- keys.forEach(key => {
393
- const { dependsOn, domain } = this.formFilters[key];
394
- dependsOn.forEach((field) => {
395
- const filterId = getFilterId(domain, field.filterName);
396
- if (this.formFilters[filterId]) {
397
- if (!this.formFilters[filterId].childs) {
398
- this.formFilters[filterId].childs = [];
399
- }
400
- this.formFilters[filterId].childs.push({ filter: { key, required: field.required } });
401
- }
402
- });
403
- });
404
- }
405
- createField(filter) {
406
- const { name, label, enumItems, type, mask } = filter;
407
- const translatedEnumItems = enumItems && enumItems.map((item) => ({ label: this.translate.instant(item.label), value: item.value }));
408
- const field = { name, label: this.translate.instant(label), placeholder: '' };
409
- const creators = {
410
- [FilterType.STRING]: () => new TextField(Object.assign(Object.assign({}, field), { mask: mask ? () => mask : null, type: FieldType.String })),
411
- [FilterType.MONEY]: () => new CurrencyField(Object.assign(Object.assign({}, field), { type: FieldType.Money })),
412
- [FilterType.BOOLEAN]: () => this.createRadioButton(Object.assign({}, field)),
413
- [FilterType.DATE]: () => this.createCalendar(Object.assign(Object.assign({}, field), { type: FieldType.Date })),
414
- [FilterType.DATETIME]: () => this.createCalendar(Object.assign(Object.assign({}, field), { type: FieldType.DateTime })),
415
- [FilterType.TIME]: () => this.createCalendar(Object.assign(Object.assign({}, field), { type: FieldType.Time })),
416
- [FilterType.ENUMERATION]: () => new SelectField(Object.assign(Object.assign({}, field), { placeholder: this.translate.instant('platform.filter_service.select'), options: [...translatedEnumItems], type: FieldType.Enum })),
417
- [FilterType.INTEGER]: () => new NumberField(Object.assign(Object.assign({}, field), { numberLocaleOptions: this.optionsInteger(), mask: mask ? () => mask : null, type: FieldType.Integer })),
418
- [FilterType.DOUBLE]: () => new CurrencyField(Object.assign(Object.assign({}, field), { type: FieldType.Double })),
419
- [FilterType.SEARCH]: () => this.createAutocompleteField(field, filter)
420
- };
421
- return creators[type]();
422
- }
423
- createRadioButton(field) {
424
- const options = [
425
- { label: this.translate.instant(`${TRANSLATE_PREFIX}.yes`), value: true },
426
- { label: this.translate.instant(`${TRANSLATE_PREFIX}.no`), value: false }
427
- ];
428
- return new RadioButtonField(Object.assign(Object.assign({}, field), { type: FieldType.Radio, options }));
429
- }
430
- createCalendar(config) {
431
- const calendar = new CalendarField(config);
432
- calendar.calendarLocaleOptions = this.calendarOptionsService.getOptions();
433
- if (!this.isModal)
434
- calendar.appendTo = 'body';
435
- return calendar;
436
- }
437
- createAutocompleteField(field, { dependsOn, search, domain, name }) {
438
- const suggestionsObservable = new BehaviorSubject([]);
439
- const { queryParam } = getSearchType(search).input;
440
- const { displayFields, keyFields, resultDataJsonPath, displayFieldConcatToken, maxSelectedItems } = getSearchType(search).output;
441
- const filterId = getFilterId(domain, name);
442
- const suggestionsError = (messageError) => {
443
- const messageDetail = messageError ? messageError : this.translate.instant(`${TRANSLATE_PREFIX}.find_suggestions_error`, { activeFilters: this.totalFiltersActive });
444
- const message = {
445
- key: 'filterServiceToastKey',
446
- severity: 'error',
447
- life: TOAST_LIFE,
448
- detail: messageDetail
449
- };
450
- this.sendMessage(message);
451
- };
452
- const onSearch = (val) => {
453
- const params = { [queryParam]: val };
454
- dependsOn && Object.assign(params, this.getDependenciesValues(dependsOn, domain));
455
- const searchUrl = search && search.type === 'ENTITY'
456
- ? this.getEntitySearchUrl(search.entitySearch.input, val, dependsOn)
457
- : getSearchType(search).input.url;
458
- this.filterService
459
- .searchFieldSuggestions(searchUrl, params, search.type)
460
- .pipe(map(response => jsonPath(response, resultDataJsonPath)), map((suggestions) => this.addSuggestionFields(suggestions, displayFields, keyFields, displayFieldConcatToken, filterId)))
461
- .subscribe(result => {
462
- suggestionsObservable.next(result);
463
- this.changeDetectorRef.detectChanges();
464
- }, (error) => {
465
- let messageError = undefined;
466
- if (error && error.error.message)
467
- messageError = error.error.message;
468
- suggestionsError(messageError);
469
- });
470
- };
471
- return new AutocompleteField(Object.assign(Object.assign({}, field), { onSearch, appendTo: 'body', suggestionsObservable, displayField: searchDisplayName, dataKey: searchKeyName, multiple: maxSelectedItems > 1, size: { lg: 12, md: 12, xl: 12 }, emptyMessage: this.translate.instant(`${TRANSLATE_PREFIX}.search_empty_message`) }));
472
- }
473
- getEntitySearchUrl(search, value, dependsOn) {
474
- const { attributes, domainName, entityName, serviceName } = search;
475
- const url = `${domainName}/${serviceName}/entities/${entityName}/?filter=`;
476
- const filters = attributes.map(attr => filterOperators[attr.comparator](attr.name, value));
477
- dependsOn &&
478
- dependsOn.forEach(obj => {
479
- const filterId = getFilterId(domainName, obj.filterName);
480
- const fieldValue = this.formFilters[filterId].value[searchKeyName];
481
- filters.push(`${obj.entityAttribute} eq '${fieldValue}'`);
482
- });
483
- // O regex apenas seleciona as virgulas ignorando as que estiverem dentro do ()
484
- return url.concat(filters).replace(/[,]+(?![^(]*[)])/g, ` ${search.operator} `);
485
- }
486
- addSuggestionFields(suggestions, displayFields, keyFields, separator, filterId) {
487
- const addValue = (acc, value, token) => (acc ? `${acc}${token}${value}` : value);
488
- const result = suggestions.map(suggestion => (Object.assign(Object.assign({}, suggestion), { [searchDisplayName]: displayFields.reduce((value, display) => {
489
- return addValue(value, this.translate.instant(suggestion[display]), separator);
490
- }, ''), [searchKeyName]: keyFields.reduce((value, key) => addValue(value, suggestion[key], ', '), '') })));
491
- this.formFilters[filterId].invalidValue = result.length === 0;
492
- return result.filter(item => {
493
- const { value } = this.formFilters[filterId];
494
- if (Array.isArray(value)) {
495
- const index = value.findIndex((i) => i.$$__keyValue__ === item.$$__keyValue__);
496
- if (index === -1) {
497
- return item;
498
- }
499
- }
500
- else {
501
- return item;
502
- }
503
- });
504
- }
505
- getDependenciesValues(dependencies, domain) {
506
- return dependencies.reduce((params, { filterName }) => {
507
- const filterId = getFilterId(domain, filterName);
508
- if (this.formFilters[filterId]) {
509
- const { value, type } = this.formFilters[filterId];
510
- if (type === 'ENUMERATION') {
511
- params[filterName] = value;
512
- }
513
- else {
514
- if (Array.isArray(value)) {
515
- params[filterName] = value.map(arr => arr[searchKeyName]);
516
- }
517
- else {
518
- params[filterName] = value ? value[searchKeyName] : [''];
519
- }
520
- }
521
- this.IsEmpty(params[filterName]) && delete params[filterName];
522
- return params;
523
- }
524
- }, {});
525
- }
526
- /*
527
- * Verifica se o valor informado é falso, em arrays, é verificado cada item
528
- */
529
- IsEmpty(value) {
530
- return Array.isArray(value) ? value.every(data => !data) : !value;
531
- }
532
- /**
533
- * Return format to specify for integer type field
534
- */
535
- optionsInteger() {
536
- return { currencySymbol: '', decimalSeparator: '', thousandsSeparator: '' };
537
- }
538
- };
539
- FormFilterComponent.ctorParameters = () => [
540
- { type: AdvancedFilterService },
541
- { type: TranslateService },
542
- { type: MessageService },
543
- { type: CalendarOptionsService },
544
- { type: ChangeDetectorRef }
545
- ];
546
- __decorate([
547
- Input()
548
- ], FormFilterComponent.prototype, "showMessages", void 0);
549
- __decorate([
550
- Input()
551
- ], FormFilterComponent.prototype, "isModal", void 0);
552
- __decorate([
553
- Input()
554
- ], FormFilterComponent.prototype, "contextId", void 0);
555
- __decorate([
556
- Output()
557
- ], FormFilterComponent.prototype, "totalFiltersActiveOutput", void 0);
558
- __decorate([
559
- Output()
560
- ], FormFilterComponent.prototype, "errorOutput", void 0);
561
- __decorate([
562
- Output()
563
- ], FormFilterComponent.prototype, "showDialogOutput", void 0);
564
- __decorate([
565
- Output()
566
- ], FormFilterComponent.prototype, "closeModalOutput", void 0);
567
- __decorate([
568
- HostListener('window:resize', ['$event'])
569
- ], FormFilterComponent.prototype, "onResizeWindow", null);
570
- FormFilterComponent = __decorate([
571
- Component({
572
- selector: 's-app-form-filter',
573
- template: "<s-empty-state\n *ngIf=\"error\"\n iconClass=\"fa fa-exclamation-triangle\"\n title=\"{{ errorState?.status }} - {{ errorState?.statusText }}\"\n (primaryAction)=\"errorStateAction()\"\n [primaryActionLabel]=\"translate.instant('platform.filter_service.try')\"\n [description]=\"translate.instant('platform.filter_service.error_state')\"\n></s-empty-state>\n\n<div *ngIf=\"!error\">\n <p-tabView *ngIf=\"tabs && tabs.size > 1\" [orientation]=\"tabViewOrientation\" selected=\"false\">\n <p-tabPanel *ngIf=\"general.fields.length\" [selected]=\"false\" [header]=\"general.name\">\n <s-dynamic-form [errorMessages]=\"errorMessages\" [fields]=\"general.fields\" [form]=\"general.form\"></s-dynamic-form>\n </p-tabPanel>\n\n <p-tabPanel *ngFor=\"let tab of (tabs | mapValues); let i = index\" [selected]=\"i === 0\" [header]=\"tab.label\">\n <s-dynamic-form [errorMessages]=\"errorMessages\" [fields]=\"tab.fields\" [form]=\"tab.form\"></s-dynamic-form>\n </p-tabPanel>\n </p-tabView>\n\n <div *ngIf=\"tabs && tabs.size === 1\">\n <s-dynamic-form\n *ngFor=\"let tab of (tabs | mapValues)\"\n [errorMessages]=\"errorMessages\"\n [fields]=\"tab.fields\"\n [form]=\"tab.form\"\n ></s-dynamic-form>\n </div>\n</div>\n",
574
- styles: [".filter-dialog{width:800px;top:100px}.filter-dialog>.ui-dialog-content{height:300px;padding:10px!important}@media (min-width:641px) and (max-width:1024px){.filter-dialog{width:75%}.filter-dialog>.ui-dialog-content{height:300px}}@media only screen and (min-device-width:481px) and (max-device-width:1024px) and (orientation:portrait){.filter-dialog{width:75%}.filter-dialog>.ui-dialog-content{height:90%}}@media (min-width:320px) and (max-width:640px){.filter-dialog{width:95%;left:0;top:0;opacity:1;margin:auto;height:93%}.filter-dialog>.ui-dialog-content{height:85%}}@media (min-width:320px) and (max-width:640px) and (max-width:360px){.filter-dialog button{padding:0!important}.filter-dialog>.ui-dialog-content{height:81%}}"]
575
- })
576
- ], FormFilterComponent);
577
- export { FormFilterComponent };
578
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1maWx0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHNlbmlvcnNpc3RlbWFzL3BsYXRmb3JtLWNvbXBvbmVudHMvIiwic291cmNlcyI6WyJtb2R1bGVzL2FkdmFuY2VkLWZpbHRlci9jb21wb25lbnRzL2Zvcm0tZmlsdGVyL2Zvcm0tZmlsdGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNILE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsTUFBTSxJQUFJLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuRixPQUFPLEVBQTJELFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxFQUNMLGVBQWUsRUFDZixRQUFRLEVBQ1IsV0FBVyxFQUNYLGFBQWEsRUFDYixRQUFRLEVBQ1IsUUFBUSxFQUNSLGdCQUFnQixFQUNoQixjQUFjLEVBQ2QsWUFBWSxFQUNiLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDM0QsT0FBTyxFQUFF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b25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSBcInByaW1lbmcvYXBpXCI7XG5pbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZnJvbSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyIGFzIHJ4RmlsdGVyLCBtYXAsIG1lcmdlTWFwLCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQ29udGV4dCwgRGVwZW5kc09uLCBFbnRpdHlTZWFyY2hJbnB1dCwgRW51bUl0ZW0sIEZpbHRlciwgRmlsdGVyVHlwZSwgU2NvcGUgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xuaW1wb3J0IHsgQ29udGV4dFRhYiwgVGFiVmlldyB9IGZyb20gJy4uLy4uL21vZGVscy90YWItdmlldyc7XG5pbXBvcnQgeyBBZHZhbmNlZEZpbHRlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hZHZhbmNlZC1maWx0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBGb3JtRmlsdGVyIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Zvcm0tZmlsdGVyJztcbmltcG9ydCB7XG4gIGZpbHRlck9wZXJhdG9ycyxcbiAgZnJvbUpzb24sXG4gIGdldEZpbHRlcklkLFxuICBnZXRTZWFyY2hUeXBlLFxuICBnZXRUYWJJZCxcbiAganNvblBhdGgsXG4gIHBhcnNlRmlsdGVyVmFsdWUsXG4gIHRvRmlsdGVyRm9ybWF0LFxuICB0b1VzZXJGb3JtYXRcbn0gZnJvbSAnLi4vLi4vdXRpbHMvaW5kZXgnO1xuaW1wb3J0IHsgY3JlYXRlRm9ybUNvbnRyb2wgfSBmcm9tICcuLi8uLi91dGlscy9mb3JtLWZpZWxkJztcbmltcG9ydCB7IGNsb25lLCBlcXVhbHMgfSBmcm9tICdyYW1kYSc7XG5pbXBvcnQgeyBjb21wYXJlLCBpc1N1cHBvcnRlZFR5cGUsIGlzVmFsaWRPcGVyYXRvciB9IGZyb20gJy4uLy4uL3V0aWxzL2NvbXBhcmF0b3InO1xuXG5pbXBvcnQge1xuICBBdXRvY29tcGxldGVGaWVsZCxcbiAgQ2FsZW5kYXJGaWVsZCxcbiAgUmFkaW9CdXR0b25GaWVsZCxcbiAgQ3VycmVuY3lGaWVsZCxcbiAgRmllbGQsXG4gIEZpZWxkQ29uZmlnLFxuICBGaWVsZFR5cGUsXG4gIE51bWJlckZpZWxkLFxuICBTZWxlY3RGaWVsZCxcbiAgVGV4dEZpZWxkLFxuICBSYXRpb25CdXR0b25PcHRpb24sXG4gIENhbGVuZGFyRmllbGRDb25maWdcbn0gZnJvbSAnQHNlbmlvcnNpc3RlbWFzL2FuZ3VsYXItY29tcG9uZW50cyc7XG5cbmltcG9ydCB7IHNlYXJjaERpc3BsYXlOYW1lLCBzZWFyY2hLZXlOYW1lIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBNZXNzYWdlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgQ2FsZW5kYXJPcHRpb25zU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2NhbGVuZGFyLW9wdGlvbnMuc2VydmljZSc7XG5cbmNvbnN0IFRSQU5TTEFURV9QUkVGSVggPSAncGxhdGZvcm0uZmlsdGVyX3NlcnZpY2UnO1xuY29uc3QgVE9BU1RfTElGRSA9IDUwMDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3MtYXBwLWZvcm0tZmlsdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Zvcm0tZmlsdGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZm9ybS1maWx0ZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBGb3JtRmlsdGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBkZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG4gIGVycm9yU3RhdGU6IEh0dHBFcnJvclJlc3BvbnNlO1xuICB0YWJzOiBNYXA8c3RyaW5nLCBDb250ZXh0VGFiPjtcbiAgY29udGV4dHM6IENvbnRleHRbXSA9IFtdO1xuICBmb3JtRmlsdGVyczogRm9ybUZpbHRlcltdID0gW107XG4gIG9sZEZvcm1GaWx0ZXJzOiBhbnlbXSA9IFtdO1xuICBhY3R1YWxGb3JtRmlsdGVyczogYW55W10gPSBbXTtcbiAgZ2VuZXJhbCA9IG5ldyBUYWJWaWV3KHsgbmFtZTogJ0dlcmFsJyB9KTtcbiAgdG90YWxGaWx0ZXJzQWN0aXZlID0gMDtcbiAgaXNNb2JpbGUgPSBmYWxzZTtcbiAgdGFiVmlld09yaWVudGF0aW9uID0gJ2xlZnQnO1xuICBlcnJvciA9IGZhbHNlO1xuXG4gIGVycm9yTWVzc2FnZXMgPSB7XG4gICAgbWluOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KGAke1RSQU5TTEFURV9QUkVGSVh9LmVycm9yX21pbl92YWx1ZWApLFxuICAgIG1heDogdGhpcy50cmFuc2xhdGUuaW5zdGFudChgJHtUUkFOU0xBVEVfUFJFRklYfS5lcnJvcl9tYXhfdmFsdWVgKSxcbiAgICBwYXR0ZXJuOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KGAke1RSQU5TTEFURV9QUkVGSVh9LmludmFsaWRfcGF0dGVybmApXG4gIH07XG5cbiAgQElucHV0KCkgc2hvd01lc3NhZ2VzID0gdHJ1ZTtcbiAgQElucHV0KCkgaXNNb2RhbCA9IGZhbHNlO1xuICBASW5wdXQoKSBjb250ZXh0SWQgPSAnJztcblxuXG4gIEBPdXRwdXQoKSB0b3RhbEZpbHRlcnNBY3RpdmVPdXRwdXQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIGVycm9yT3V0cHV0ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICBAT3V0cHV0KCkgc2hvd0RpYWxvZ091dHB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIGNsb3NlTW9kYWxPdXRwdXQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBmaWx0ZXJTZXJ2aWNlOiBBZHZhbmNlZEZpbHRlclNlcnZpY2UsXG4gICAgcHVibGljIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIGNhbGVuZGFyT3B0aW9uc1NlcnZpY2U6IENhbGVuZGFyT3B0aW9uc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7IH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgb25SZXNpemVXaW5kb3coZXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IHsgaW5uZXJXaWR0aCB9ID0gZXZlbnQudGFyZ2V0O1xuICAgIHRoaXMuaXNNb2JpbGUgPSBpbm5lcldpZHRoIDw9IDY0MDtcbiAgICB0aGlzLnRhYlZpZXdPcmllbnRhdGlvbiA9IHRoaXMuaXNNb2JpbGUgPyAndG9wJyA6ICdsZWZ0JztcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaXNNb2JpbGUgPSBpbm5lcldpZHRoIDw9IDY0MDtcbiAgICB0aGlzLnRhYlZpZXdPcmllbnRhdGlvbiA9IHRoaXMuaXNNb2JpbGUgPyAndG9wJyA6ICdsZWZ0JztcbiAgICB0aGlzLnN1YnNjcmliZUNvbnRleHRzT2JzZXJ2YWJsZSgpO1xuICAgIHRoaXMuc3Vic2NyaWJlRmlsdGVyc09ic2VydmFibGUoKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGF0YSA9IGV2ZW50LmRhdGE7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZGF0YS5tZXNzYWdlICYmIGRhdGEubWVzc2FnZS5zcGxpdCgnOicpWzFdO1xuICAgICAgaWYgKG1lc3NhZ2UgPT09ICdhZGRDb250ZXh0Jykge1xuICAgICAgICB0aGlzLmZpbHRlclNlcnZpY2UuYWRkQ29udGV4dHMoLi4uZGF0YS5wYXlsb2FkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgfVxuXG4gIGhhc0NoYW5nZXMoKSB7XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZm9ybUZpbHRlcnMpO1xuICAgIGNvbnN0IG9sZEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLm9sZEZvcm1GaWx0ZXJzKTtcbiAgICBpZiAoIW9sZEtleXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZmlsdGVyZWQgPSBrZXlzLmZpbHRlcihrZXkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5mb3JtRmlsdGVyc1trZXldLnZhbHVlO1xuICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLm9sZEZvcm1GaWx0ZXJzW2tleV0gJiYgdGhpcy5vbGRGb3JtRmlsdGVyc1trZXldLnZhbHVlO1xuICAgICAgcmV0dXJuICFlcXVhbHMoY3VycmVudFZhbHVlLCBvbGRWYWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbHRlcmVkLmxlbmd0aCA+IDA7XG4gIH1cblxuICBvbkFwcGx5RmlsdGVycygpIHtcbiAgICB0aGlzLmhhc0NoYW5nZXMoKSAmJiB0aGlzLmNsb3NlTW9kYWxPdXRwdXQuZW1pdCgpO1xuICB9XG5cbiAgcHVibGljIGdldEZpbHRlcnMoKSB7XG4gICAgdGhpcy5oYXNDaGFuZ2VzKCkgJiYgdGhpcy5maWx0ZXJTZXJ2aWNlLnRyeUFnYWluKHRoaXMuY29udGV4dHMpO1xuICB9XG5cbiAgYXBwbHlGaWx0ZXJzKHNob3dUb2FzdCA9IGZhbHNlKSB7XG4gICAgaWYgKHRoaXMuaGFzQ2hhbmdlcygpKSB7XG4gICAgICB0aGlzLnNob3dEaWFsb2dPdXRwdXQuZW1pdChmYWxzZSk7XG4gICAgICB0aGlzLmNvdW50ZXJVcGRhdGUoKTtcbiAgICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLmdldEZpbHRlcnNWYWx1ZXModGhpcy5mb3JtRmlsdGVycyk7XG4gICAgICB0aGlzLmZpbHRlclNlcnZpY2Uuc2F2ZVRpY2tlZEZpbHRlcnMoZmlsdGVycyk7XG4gICAgfSBlbHNlIGlmIChzaG93VG9hc3QpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgIGtleTogJ2ZpbHRlclNlcnZpY2VUb2FzdEtleScsXG4gICAgICAgIHNldmVyaXR5OiAnaW5mbycsXG4gICAgICAgIGxpZmU6IFRPQVNUX0xJRkUsXG4gICAgICAgIGRldGFpbDogdGhpcy50cmFuc2xhdGUuaW5zdGFudChgJHtUUkFOU0xBVEVfUFJFRklYfS5hcHBsaWVkX2ZpbHRlcl9ub2NoYW5nZWAsIHsgYWN0aXZlRmlsdGVyczogdGhpcy50b3RhbEZpbHRlcnNBY3RpdmUgfSlcbiAgICAgIH07XG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIH1cbiAgICB0aGlzLm9sZEZvcm1GaWx0ZXJzID0gY2xvbmUodGhpcy5mb3JtRmlsdGVycyk7XG4gIH1cblxuICBnZXREZWZhdWx0VmFsdWUoZGVmYXVsdFZhbHVlOiBhbnksIGlzTXVsdGlwbGU6IGJvb2xlYW4pIHtcbiAgICBpZiAoZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWQgfHwgKGlzTXVsdGlwbGUgJiYgZGVmYXVsdFZhbHVlWzBdID09PSAnJykpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgY2xlYXJGaWx0ZXJzKCkge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLmZvcm1GaWx0ZXJzKTtcbiAgICBrZXlzLmZvckVhY2goa2V5ID0+IHRoaXMuY2xlYW5GaWVsZEFuZFNldERlZmF1bHRWYWx1ZShrZXkpKTtcbiAgfVxuXG4gIHNlbmRDbG9zZU1lc3NhZ2UoKSB7XG4gICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZShcbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogJ2Rhc2hib2FyZDpjbG9zZS1tb2RhbCcsXG4gICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICBtb2RhbE5hbWU6ICdhZHZhbmNlZC1maWx0ZXItMSdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICcqJ1xuICAgICk7XG4gIH1cblxuICBzZW5kTWVzc2FnZShtZXNzYWdlOiBNZXNzYWdlKSB7XG4gICAgaWYgKHRoaXMuc2hvd01lc3NhZ2VzKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZChtZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZShcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6ICdkYXNoYm9hcmQ6dG9hc3RyJyxcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3VjY2VzcycsXG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLmRldGFpbFxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgJyonXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHNhdmVGaWx0ZXJzKGZvcmNlU2F2ZSA9IGZhbHNlKSB7XG4gICAgY29uc3QgZmlsdGVycyA9IHRoaXMucGFyc2VUb1VzZXJGaWx0ZXJzKHRoaXMuZm9ybUZpbHRlcnMpO1xuICAgIGNvbnN0IHNhdmVkRmlsdGVyU3VjY2VzcyA9ICgpID0+IHtcbiAgICAgIGlmICghZm9yY2VTYXZlKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgICAga2V5OiAnZmlsdGVyU2VydmljZVRvYXN0S2V5JyxcbiAgICAgICAgICBzZXZlcml0eTogJ2luZm8nLFxuICAgICAgICAgIGxpZmU6IFRPQVNUX0xJRkUsXG4gICAgICAgICAgZGV0YWlsOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KGAke1RSQU5TTEFURV9QUkVGSVh9LnNhdmVkX2ZpbHRlcnNfc3VjY2Vzc2AsIHsgYWN0aXZlRmlsdGVyczogdGhpcy50b3RhbEZpbHRlcnNBY3RpdmUgfSlcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jb3VudGVyVXBkYXRlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IHNhdmVkRmlsdGVyc0Vycm9yID0gKCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgICAga2V5OiAnZmlsdGVyU2VydmljZVRvYXN0S2V5JyxcbiAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgIGxpZmU6IFRPQVNUX0xJRkUsXG4gICAgICAgIGRldGFpbDogdGhpcy50cmFuc2xhdGUuaW5zdGFudChgJHtUUkFOU0xBVEVfUFJFRklYfS5zYXZlZF9maWx0ZXJzX2Vycm9yYCwgeyBhY3RpdmVGaWx0ZXJzOiB0aGlzLnRvdGFsRmlsdGVyc0FjdGl2ZSB9KVxuICAgICAgfTtcblxuICAgICAgdGhpcy5zZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5maWx0ZXJTZXJ2aWNlXG4gICAgICAuc2F2ZUZpbHRlcnMoZmlsdGVycylcbiAgICAgIC5zdWJzY3JpYmUoc2F2ZWRGaWx0ZXJTdWNjZXNzLCBzYXZlZEZpbHRlcnNFcnJvcik7XG4gIH1cblxuICBzYXZlRmlsdGVyc1dpdGhDYWxsYmFja0Z1bmN0aW9uKGNhbGxiYWNrRnVuY3Rpb246IGFueSkge1xuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLnBhcnNlVG9Vc2VyRmlsdGVycyh0aGlzLmZvcm1GaWx0ZXJzKTtcblxuICAgIHRoaXMuZmlsdGVyU2VydmljZVxuICAgICAgLnNhdmVGaWx0ZXJzKGZpbHRlcnMpXG4gICAgICAuc3Vic2NyaWJlKGNhbGxiYWNrRnVuY3Rpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb3VudGVyVXBkYXRlKCkge1xuICAgIHRoaXMudG90YWxGaWx0ZXJzQWN0aXZlID0gdGhpcy5jb3VudEFjdGl2ZUZpbHRlcnModGhpcy50YWJzKTtcbiAgICB0aGlzLnRvdGFsRmlsdGVyc0FjdGl2ZU91dHB1dC5lbWl0KHRoaXMudG90YWxGaWx0ZXJzQWN0aXZlKTtcbiAgfVxuXG4gIHByaXZhdGUgY291bnRBY3RpdmVGaWx0ZXJzKHRhYnM6IE1hcDxzdHJpbmcsIENvbnRleHRUYWI+KSB7XG4gICAgbGV0IHRvdGFsRmlsdGVyc0FjdGl2ZSA9IDA7XG5cbiAgICB0YWJzLmZvckVhY2godGFiVmlldyA9PiB7XG4gICAgICBjb25zdCB7IHZhbHVlIH0gPSB0YWJWaWV3LmZvcm07XG4gICAgICB0YWJWaWV3LmFjdGl2ZUZpbHRlcnMgPSBPYmplY3Qua2V5cyh2YWx1ZSkucmVkdWNlKChhcHBsaWVkRmlsdGVycywga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbHRlclZhbHVlID0gdmFsdWVba2V5XTtcbiAgICAgICAgY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoZmlsdGVyVmFsdWUpO1xuICAgICAgICBjb25zdCBpc1ZhbGlkQXJyYXkgPSBpc0FycmF5ICYmIGZpbHRlclZhbHVlLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgaWYgKGlzVmFsaWRBcnJheSB8fCAoIWlzQXJyYXkgJiYgZmlsdGVyVmFsdWUpKSB7XG4gICAgICAgICAgYXBwbGllZEZpbHRlcnMrKztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcHBsaWVkRmlsdGVycztcbiAgICAgIH0sIDApO1xuICAgICAgdG90YWxGaWx0ZXJzQWN0aXZlICs9IHRhYlZpZXcuYWN0aXZlRmlsdGVycztcbiAgICB9KTtcblxuICAgIHJldHVybiB0b3RhbEZpbHRlcnNBY3RpdmU7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlVG9Vc2VyRmlsdGVycyhmaWx0ZXJzOiBGb3JtRmlsdGVyW10pIHtcbiAgICBjb25zdCBpZHMgPSBPYmplY3Qua2V5cyhmaWx0ZXJzKTtcblxuICAgIHJldHVybiBpZHMucmVkdWNlKChhbGwsIGZpbHRlcklkKSA9PiB7XG4gICAgICBjb25zdCB7IHR5cGUsIHNlcnZpY2VzLCBuYW1lLCB2YWx1ZSwgZG9tYWluLCBjb250ZXh0cyB9ID0gZmlsdGVyc1tmaWx0ZXJJZF0gYXMgRmlsdGVyO1xuICAgICAgY29uc3QgZmlsdGVyVmFsdWUgPSB0b1VzZXJGb3JtYXQodmFsdWUsIHR5cGUpO1xuXG4gICAgICBjb25zdCB2YWx1ZXMgPSBzZXJ2aWNlcy5tYXAoc2VydmljZSA9PiAoeyBuYW1lLCBzZXJ2aWNlLCB2YWx1ZTogZmlsdGVyVmFsdWUsIGRvbWFpbiwgY29udGV4dHMgfSkpO1xuXG4gICAgICByZXR1cm4gWy4uLmFsbCwgLi4udmFsdWVzXTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZpbHRlcnNWYWx1ZXMoZmlsdGVyczogRm9ybUZpbHRlcltdKSB7XG4gICAgY29uc3QgaWRzID0gT2JqZWN0LmtleXMoZmlsdGVycyk7XG5cbiAgICByZXR1cm4gaWRzLnJlZHVjZSgoYWxsLCBmaWx0ZXJJZCkgPT4ge1xuICAgICAgY29uc3QgeyB0eXBlLCBzZXJ2aWNlcywgbmFtZSwgdmFsdWUsIGRvbWFpbiB9ID0gZmlsdGVyc1tmaWx0ZXJJZF0gYXMgRmlsdGVyO1xuICAgICAgY29uc3QgZmlsdGVyVmFsdWUgPSB0b0ZpbHRlckZvcm1hdCh2YWx1ZSwgdHlwZSk7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBzZXJ2aWNlcy5tYXAoc2VydmljZSA9PiAoeyBuYW1lLCBzZXJ2aWNlLCB2YWx1ZTogZmlsdGVyVmFsdWUsIGRvbWFpbiB9KSk7XG5cbiAgICAgIHJldHVybiBbLi4uYWxsLCAuLi52YWx1ZXNdO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlQ29udGV4dHNPYnNlcnZhYmxlKCkge1xuICAgIGNvbnN0IHsgY29udGV4dHNPYnNlcnZlciB9ID0gdGhpcy5maWx0ZXJTZXJ2aWNlO1xuICAgIGNvbnRleHRzT2JzZXJ2ZXIucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY29udGV4dHM6IENvbnRleHRbXSkgPT4gKHRoaXMuY29udGV4dHMgPSBjb250ZXh0cykpO1xuICB9XG5cbiAgZXJyb3JTdGF0ZUFjdGlvbigpIHtcbiAgICB0aGlzLmZpbHRlclNlcnZpY2UudHJ5QWdhaW4odGhpcy5jb250ZXh0cyk7XG4gIH1cblxuICBwcml2YXRlIHN1YnNjcmliZUZpbHRlcnNPYnNlcnZhYmxlKCkge1xuICAgIGNvbnN0IHsgZmlsdGVyc09ic2VydmVyIH0gPSB0aGlzLmZpbHRlclNlcnZpY2U7XG5cbiAgICBmaWx0ZXJzT2JzZXJ2ZXJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKHsgZmlsdGVycywgYXBwbHlGaWx0ZXIsIGVycm9yLCBtZXNzYWdlIH0pID0+IHtcbiAgICAgICAgdGhpcy5lcnJvck91dHB1dC5lbWl0KGVycm9yKTtcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xuICAgICAgICB0aGlzLmVycm9yU3RhdGUgPSBtZXNzYWdlO1xuICAgICAgICBpZiAoIWVycm9yKSB7XG4gICAgICAgICAgdGhpcy5jcmVhdGVGb3JtKGZpbHRlcnMsIGFwcGx5RmlsdGVyKVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRm9ybShmaWx0ZXJzOiBhbnksIGFwcGx5RmlsdGVyOiBhbnkpIHtcbiAgICB0aGlzLnRhYnMgPSB0aGlzLmNyZWF0ZVRhYnMoZmlsdGVycyk7XG4gICAgdGhpcy5jb3VudGVyVXBkYXRlKCk7XG4gICAgdGhpcy5zZXREZXBlbmRlbmNpZXModGhpcy5mb3JtRmlsdGVycyk7XG4gICAgdGhpcy5jcmVhdGVDaGlsZEFycmF5KCk7XG4gICAgaWYgKGZpbHRlcnMubGVuZ3RoID4gMCAmJiBhcHBseUZpbHRlcikge1xuICAgICAgdGhpcy5hcHBseUZpbHRlcnMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldERlcGVuZGVuY2llcyhmaWx0ZXJzOiBGb3JtRmlsdGVyW10pIHtcbiAgICBjb25zdCBuYW1lcyA9IE9iamVjdC5rZXlzKGZpbHRlcnMpO1xuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGZyb20obmFtZXMpLnBpcGUoXG4gICAgICBtYXAoa2V5ID0+IGZpbHRlcnNba2V5XSBhcyBGb3JtRmlsdGVyKSxcbiAgICAgIHJ4RmlsdGVyKCh7IGRlcGVuZHNPbiB9KSA9PiBkZXBlbmRzT24gJiYgZGVwZW5kc09uLmxlbmd0aCA+IDApLFxuICAgICAgdGFwKCh7IGRlcGVuZHNPbiwgZG9tYWluLCBmaWx0ZXJDb250cm9sIH0pID0+IHtcbiAgICAgICAgY29uc3QgaW52YWxpZEZpbHRlcnMgPSBkZXBlbmRzT25cbiAgICAgICAgICAuZmlsdGVyKGRlcCA9PiBkZXAucmVxdWlyZWQpXG4gICAgICAgICAgLmZpbHRlcihkZXAgPT4ge1xuICAgICAgICAgICAgY29uc3QgaWQgPSBnZXRGaWx0ZXJJZChkb21haW4sIGRlcC5maWx0ZXJOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1GaWx0ZXIgPSBmaWx0ZXJzW2lkXTtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIHR5cGUgfSA9IGZvcm1GaWx0ZXI7XG4gICAgICAgICAgICBjb25zdCB7IGNvbXBhcmF0b3IgfSA9IGRlcDtcbiAgICAgICAgICAgIGlmIChjb21wYXJhdG9yICYmIGlzVmFsaWRPcGVyYXRvcihjb21wYXJhdG9yLm9wZXJhdG9yKSAmJiBpc1N1cHBvcnRlZFR5cGUodHlwZSkpIHtcbiAgICAgICAgICAgICAgY29uc3QgZmllbGRWYWx1ZSA9IHBhcnNlRmlsdGVyVmFsdWUodmFsdWUsIHR5cGUpO1xuICAgICAgICAgICAgICByZXR1cm4gIWNvbXBhcmUoY29tcGFyYXRvci5vcGVyYXRvciwgY29tcGFyYXRvci52YWx1ZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGVwLnJlcXVpcmVkID8gIWZvcm1GaWx0ZXIudmFsdWUgOiBmb3JtRmlsdGVyLnZhbHVlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChpbnZhbGlkRmlsdGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZmlsdGVyQ29udHJvbC5kaXNhYmxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgbWFwKCh7IGRvbWFpbiwgZGVwZW5kc09uLCBmaWx0ZXJDb250cm9sIH0pID0+ICh7IGRvbWFpbiwgZGVwZW5kc09uLCBmaWx0ZXJDb250cm9sIH0pKVxuICAgICk7XG5cbiAgICBkZXBlbmRlbmNpZXMuc3Vic2NyaWJlKCh7IGRlcGVuZHNPbiwgZG9tYWluLCBmaWx0ZXJDb250cm9sIH0pID0+XG4gICAgICBmcm9tKGRlcGVuZHNPbilcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgcnhGaWx0ZXIoZGVwID0+IGRlcC5yZXF1aXJlZCksXG4gICAgICAgICAgbWFwKCh7IGZpbHRlck5hbWUgfSkgPT4gZ2V0RmlsdGVySWQoZG9tYWluLCBmaWx0ZXJOYW1lKSksXG4gICAgICAgICAgbWFwKGZpbHRlcklkID0+IGZpbHRlcnNbZmlsdGVySWRdIGFzIEZvcm1GaWx0ZXIpLFxuICAgICAgICAgIG1lcmdlTWFwKGZvcm1GaWx0ZXIgPT4gZnJvbShmb3JtRmlsdGVyLnZhbHVlQ2hhbmdlcykpLFxuICAgICAgICAgIG1hcCh2YWwgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29tcGFyYXRpb24gPSBkZXBlbmRzT24uZXZlcnkoZGVwID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZmlsdGVySWQgPSBnZXRGaWx0ZXJJZChkb21haW4sIGRlcC5maWx0ZXJOYW1lKTtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdLnR5cGU7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBjb21wYXJhdG9yIH0gPSBkZXA7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmF0b3IgJiYgaXNWYWxpZE9wZXJhdG9yKGNvbXBhcmF0b3Iub3BlcmF0b3IpICYmIGlzU3VwcG9ydGVkVHlwZSh0eXBlKSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJzZUZpbHRlclZhbHVlKHZhbCwgdHlwZSk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gY29tcGFyZShjb21wYXJhdG9yLm9wZXJhdG9yLCBjb21wYXJhdG9yLnZhbHVlLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5Jc0VtcHR5KHZhbCkgJiYgY29tcGFyYXRpb24gPyAnZW5hYmxlJyA6ICdkaXNhYmxlJztcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoc3RhdHVzID0+IGZpbHRlckNvbnRyb2xbc3RhdHVzXSgpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZEdlbmVyYWxGaWVsZChmaWx0ZXI6IEZpbHRlcikge1xuICAgIGNvbnN0IHsgbmFtZSwgZG9tYWluLCB0eXBlIH0gPSBmaWx0ZXI7XG4gICAgY29uc3QgY29udHJvbE5hbWUgPSBnZXRGaWx0ZXJJZChkb21haW4sIG5hbWUpO1xuICAgIGNvbnN0IGZpZWxkQ29udHJvbCA9IGNyZWF0ZUZvcm1Db250cm9sKGZpbHRlcik7XG5cbiAgICBmaWVsZENvbnRyb2wudmFsdWVDaGFuZ2VzXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLFxuICAgICAgICBtYXAodiA9PiBwYXJzZUZpbHRlclZhbHVlKHYsIHR5cGUpKSxcbiAgICAgICAgdGFwKHZhbHVlID0+ICh0aGlzLmZvcm1GaWx0ZXJzW2NvbnRyb2xOYW1lXS52YWx1ZSA9IHZhbHVlKSlcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUodmFsID0+XG4gICAgICAgIHRoaXMudGFicy5mb3JFYWNoKHRhYiA9PiB7XG4gICAgICAgICAgY29uc3QgY29udHJvbCA9IHRhYi5mb3JtLmNvbnRyb2xzW25hbWVdO1xuICAgICAgICAgIGlmIChjb250cm9sICYmIHRhYi5kb21haW4gPT09IGRvbWFpbikge1xuICAgICAgICAgICAgY29udHJvbC5zZXRWYWx1ZSh2YWwsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgY29uc3QgbmV3RmlsdGVyID0geyAuLi5maWx0ZXIsIC4uLnsgbmFtZTogY29udHJvbE5hbWUgfSB9O1xuICAgIGNvbnN0IG5ld0ZpZWxkID0gdGhpcy5jcmVhdGVGaWVsZChuZXdGaWx0ZXIpO1xuICAgIHRoaXMuZ2VuZXJhbC5mb3JtLmFkZENvbnRyb2woY29udHJvbE5hbWUsIGZpZWxkQ29udHJvbCk7XG4gICAgdGhpcy5nZW5lcmFsLmZpZWxkcy5wdXNoKG5ld0ZpZWxkKTtcbiAgfVxuXG4gIC8qXG4gICAqIFZlcmlmaWNhIG9zIGNvbnRleHRvcyBkZSBjYWRhIGZpbHRybywgY2FzbyB0b2RvcyBvcyBjb250ZXh0b3MgZm9yYW0gaW5mb3JtYWRvczpcbiAgICogQHJldHVybiB0cnVlXG4gICAqIENhc28gbsOjbyB0ZW5oYSBuZW5odW0gY29udGV4dG8sIGNvbnNpZGVyYS1zZSBwb3IgcGFkcsOjbyBxdWUgw6kgdG9kb3M6XG4gICAqIEByZXR1cm4gdHJ1ZVxuICAgKi9cbiAgcHJpdmF0ZSBjb250YWluc0FsbENvbnRleHRzKG15Q29udGV4dHM6IHN0cmluZ1tdKSB7XG4gICAgaWYgKCFteUNvbnRleHRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGFsbENvbnRleHRzID0gdGhpcy5jb250ZXh0cy5tYXAoZGF0YSA9PiBkYXRhLmNvbnRleHRJZCk7XG4gICAgcmV0dXJuIGVxdWFscyhteUNvbnRleHRzLnNvcnQoKSwgYWxsQ29udGV4dHMuc29ydCgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAdG9kbyBSZWZhdG9yYXIuIE8gbcOpdG9kbyBwb3NzdWkgbXVpdGFzIHJlc3BvbnNhYmlsaWRhZGVzXG4gICAqIFxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVUYWJzKGZpbHRlcnM6IEZpbHRlcltdKSB7XG4gICAgcmV0dXJuIGZpbHRlcnMucmVkdWNlKCh0YWJzLCBmaWx0ZXIpID0+IHtcbiAgICAgIGNvbnN0IHsgZG9tYWluLCBzZXJ2aWNlcywgbmFtZSwgdHlwZSwgc2NvcGUsIGNvbnRleHRzLCBkZXBlbmRzT24sIHZhbHVlLCBzZWFyY2gsIGRlZmF1bHRWYWx1ZSB9ID0gZmlsdGVyO1xuICAgICAgY29uc3QgaXNOb3RNdWx0aXBsZSA9IHNlYXJjaCAmJiBnZXRTZWFyY2hUeXBlKHNlYXJjaCkub3V0cHV0Lm1heFNlbGVjdGVkSXRlbXMgPT09IDE7XG4gICAgICBjb25zdCBmaWVsZCA9IHRoaXMuY3JlYXRlRmllbGQoZmlsdGVyKTtcbiAgICAgIGNvbnN0IGZpbHRlcklkID0gZ2V0RmlsdGVySWQoZG9tYWluLCBuYW1lKTtcbiAgICAgIGNvbnN0IGZpbHRlckNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluLFxuICAgICAgICBjb250ZXh0cyxcbiAgICAgICAgc2VydmljZXMsXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGRlcGVuZHNPbixcbiAgICAgICAgdmFsdWU6IGZyb21Kc29uKHZhbHVlLCB0eXBlLCBpc05vdE11bHRpcGxlKSxcbiAgICAgICAgdHlwZSxcbiAgICAgICAgaXNNdWx0aXBsZTogIWlzTm90TXVsdGlwbGUsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogZnJvbUpzb24oZGVmYXVsdFZhbHVlLCB0eXBlLCBpc05vdE11bHRpcGxlKVxuICAgICAgfTtcbiAgICAgIHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdID0gbmV3IEZvcm1GaWx0ZXIoZmlsdGVyQ29uZmlnKTtcbiAgICAgIGNvbnN0IGZvcm1GaWx0ZXIgPSB0aGlzLmZvcm1GaWx0ZXJzW2ZpbHRlcklkXTtcbiAgICAgIGlmIChzY29wZSA9PT0gU2NvcGUuRE9NQUlOICYmIHRoaXMuY29udGFpbnNBbGxDb250ZXh0cyhjb250ZXh0cykpIHtcbiAgICAgICAgdGhpcy5hZGRHZW5lcmFsRmllbGQoZmlsdGVyKTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dHMuZm9yRWFjaChjb250ZXh0SWQgPT4ge1xuICAgICAgICBpZiAoKGNvbnRleHRJZCA9PT0gdGhpcy5jb250ZXh0SWQpIHx8ICh0aGlzLmNvbnRleHRJZCA9PT0gJycpKSB7XG4gICAgICAgICAgY29uc3QgdGFiSWQgPSBnZXRUYWJJZChkb21haW4sIGNvbnRleHRJZCk7XG4gICAgICAgICAgY29uc3QgZmllbGRDb250cm9sID0gY3JlYXRlRm9ybUNvbnRyb2woZmlsdGVyKTtcblxuICAgICAgICAgIGlmICghdGFicy5oYXModGFiSWQpKSB7XG4gICAgICAgICAgICBjb25zdCB7IGNvbnRleHRMYWJlbCB9ID0gdGhpcy5jb250ZXh0cy5maW5kKGNvbnRleHQgPT4gY29udGV4dC5jb250ZXh0SWQgPT09IGNvbnRleHRJZCk7XG4gICAgICAgICAgICBjb25zdCB0YWIgPSBuZXcgQ29udGV4dFRhYih7IGRvbWFpbiwgbmFtZTogY29udGV4dExhYmVsIH0pO1xuICAgICAgICAgICAgdGFicy5zZXQodGFiSWQsIHRhYik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmllbGRDb250cm9sLnZhbHVlQ2hhbmdlc1xuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsOiBhbnkpID0+IHRoaXMudXBkYXRlRmlsdGVyVmFsdWUodGFiSWQsIG5hbWUsIHZhbCwgZG9tYWluLCB0eXBlKSk7XG5cbiAgICAgICAgICBjb25zdCBjb250ZXh0VGFiID0gdGFicy5nZXQodGFiSWQpO1xuXG4gICAgICAgICAgY29udGV4dFRhYi5maWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgICAgY29udGV4dFRhYi5mb3JtLmFkZENvbnRyb2woZmlsdGVyLm5hbWUsIGZpZWxkQ29udHJvbCk7XG5cbiAgICAgICAgICBpZiAoIWZvcm1GaWx0ZXIuZmlsdGVyQ29udHJvbCkge1xuICAgICAgICAgICAgZm9ybUZpbHRlci5maWx0ZXJDb250cm9sID0gZmllbGRDb250cm9sO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgcmV0dXJuIHRhYnM7XG4gICAgfSwgbmV3IE1hcDxzdHJpbmcsIENvbnRleHRUYWI+KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGaWx0ZXJWYWx1ZSh0YWJJZDogc3RyaW5nLCBmaWx0ZXJOYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnksIGRvbWFpbjogc3RyaW5nLCB0eXBlOiBGaWx0ZXJUeXBlKSB7XG4gICAgY29uc3QgY29udHJvbE9wdHMgPSB7IGVtaXRFdmVudDogZmFsc2UgfTtcbiAgICBjb25zdCBmaWVsZFZhbHVlID0gcGFyc2VGaWx0ZXJWYWx1ZSh2YWx1ZSwgdHlwZSk7XG4gICAgY29uc3QgZmlsdGVySWQgPSBnZXRGaWx0ZXJJZChkb21haW4sIGZpbHRlck5hbWUpO1xuICAgIGNvbnN0IGdlbmVyYWxGaWVsZENvbnRyb2wgPSB0aGlzLmdlbmVyYWwuZm9ybS5jb250cm9sc1tmaWx0ZXJJZF07XG5cbiAgICB0aGlzLnRhYnMuZm9yRWFjaCgoeyBmb3JtIH0sIGtleSkgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGZvcm0uY29udHJvbHNbZmlsdGVyTmFtZV07XG5cbiAgICAgIGlmICh0YWJJZCAhPT0ga2V5ICYmIGNvbnRyb2wpIHtcbiAgICAgICAgY29udHJvbC5zZXRWYWx1ZSh2YWx1ZSwgY29udHJvbE9wdHMpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHsgY2hpbGRzIH0gPSB0aGlzLmZvcm1GaWx0ZXJzW2ZpbHRlcklkXTtcbiAgICBjaGlsZHMgJiYgY2hpbGRzLmZvckVhY2goKGNoaWxkOiBhbnkpID0+IHRoaXMuY2xlYW5GaWVsZEFuZFNldERlZmF1bHRWYWx1ZShjaGlsZC5maWx0ZXIua2V5KSk7XG4gICAgZ2VuZXJhbEZpZWxkQ29udHJvbCAmJiBnZW5lcmFsRmllbGRDb250cm9sLnNldFZhbHVlKHZhbHVlLCBjb250cm9sT3B0cyk7XG4gICAgdGhpcy5mb3JtRmlsdGVyc1tmaWx0ZXJJZF0udmFsdWUgPSBmaWVsZFZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhbkZpZWxkQW5kU2V0RGVmYXVsdFZhbHVlKGtleTogc3RyaW5nKSB7XG4gICAgY29uc3QgeyBpc011bHRpcGxlLCBkZWZhdWx0VmFsdWUsIGZpbHRlckNvbnRyb2wsIHR5cGUgfSA9IHRoaXMuZm9ybUZpbHRlcnNba2V5XSBhcyBGb3JtRmlsdGVyO1xuICAgIGNvbnN0IGZpbmFsVmFsdWUgPSB0aGlzLmdldERlZmF1bHRWYWx1ZShkZWZhdWx0VmFsdWUsIGlzTXVsdGlwbGUpO1xuXG4gICAgaWYgKGZpbHRlckNvbnRyb2wpIHtcbiAgICAgIGlmICh0eXBlID09PSAnREFURScgfHwgKHR5cGUgPT09ICdTRUFSQ0gnICYmIGlzTXVsdGlwbGUpKSB7XG4gICAgICAgIGZpbHRlckNvbnRyb2wuc2V0VmFsdWUoZmluYWxWYWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gJ0lOVEVHRVInIHx8IHR5cGUgPT09ICdET1VCTEUnIHx8IHR5cGUgPT09ICdNT05FWScpIHtcbiAgICAgICAgZmluYWxWYWx1ZSA9PT0gJycgPyBmaWx0ZXJDb250cm9sLnNldFZhbHVlKG51bGwpIDogZmlsdGVyQ29udHJvbC5zZXRWYWx1ZShmaW5hbFZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbHRlckNvbnRyb2wuc2V0VmFsdWUoZmluYWxWYWx1ZSwgeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNoaWxkQXJyYXkoKSB7XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZm9ybUZpbHRlcnMpO1xuICAgIGtleXMuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgeyBkZXBlbmRzT24sIGRvbWFpbiB9ID0gdGhpcy5mb3JtRmlsdGVyc1trZXldO1xuICAgICAgZGVwZW5kc09uLmZvckVhY2goKGZpZWxkOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVySWQgPSBnZXRGaWx0ZXJJZChkb21haW4sIGZpZWxkLmZpbHRlck5hbWUpO1xuICAgICAgICBpZiAodGhpcy5mb3JtRmlsdGVyc1tmaWx0ZXJJZF0pIHtcbiAgICAgICAgICBpZiAoIXRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdLmNoaWxkcykge1xuICAgICAgICAgICAgdGhpcy5mb3JtRmlsdGVyc1tmaWx0ZXJJZF0uY2hpbGRzID0gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdLmNoaWxkcy5wdXNoKHsgZmlsdGVyOiB7IGtleSwgcmVxdWlyZWQ6IGZpZWxkLnJlcXVpcmVkIH0gfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVGaWVsZChmaWx0ZXI6IEZpbHRlcik6IEZpZWxkIHtcbiAgICBjb25zdCB7IG5hbWUsIGxhYmVsLCBlbnVtSXRlbXMsIHR5cGUsIG1hc2sgfSA9IGZpbHRlcjtcbiAgICBjb25zdCB0cmFuc2xhdGVkRW51bUl0ZW1zID1cbiAgICAgIGVudW1JdGVtcyAmJiBlbnVtSXRlbXMubWFwKChpdGVtOiBFbnVtSXRlbSkgPT4gKHsgbGFiZWw6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoaXRlbS5sYWJlbCksIHZhbHVlOiBpdGVtLnZhbHVlIH0pKTtcbiAgICBjb25zdCBmaWVsZCA9IHsgbmFtZSwgbGFiZWw6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQobGFiZWwpLCBwbGFjZWhvbGRlcjogJycgfTtcblxuICAgIGNvbnN0IGNyZWF0b3JzID0ge1xuICAgICAgW0ZpbHRlclR5cGUuU1RSSU5HXTogKCkgPT4gbmV3IFRleHRGaWVsZCh7IC4uLmZpZWxkLCBtYXNrOiBtYXNrID8gKCkgPT4gbWFzayA6IG51bGwsIHR5cGU6IEZpZWxkVHlwZS5TdHJpbmcgfSksXG4gICAgICBbRmlsdGVyVHlwZS5NT05FWV06ICgpID0+IG5ldyBDdXJyZW5jeUZpZWxkKHsgLi4uZmllbGQsIHR5cGU6IEZpZWxkVHlwZS5Nb25leSB9KSxcbiAgICAgIFtGaWx0ZXJUeXBlLkJPT0xFQU5dOiAoKSA9PiB0aGlzLmNyZWF0ZVJhZGlvQnV0dG9uKHsgLi4uZmllbGQgfSksXG4gICAgICBbRmlsdGVyVHlwZS5EQVRFXTogKCkgPT4gdGhpcy5jcmVhdGVDYWxlbmRhcih7IC4uLmZpZWxkLCB0eXBlOiBGaWVsZFR5cGUuRGF0ZSB9KSxcbiAgICAgIFtGaWx0ZXJUeXBlLkRBVEVUSU1FXTogKCkgPT4gdGhpcy5jcmVhdGVDYWxlbmRhcih7IC4uLmZpZWxkLCB0eXBlOiBGaWVsZFR5cGUuRGF0ZVRpbWUgfSksXG4gICAgICBbRmlsdGVyVHlwZS5USU1FXTogKCkgPT4gdGhpcy5jcmVhdGVDYWxlbmRhcih7IC4uLmZpZWxkLCB0eXBlOiBGaWVsZFR5cGUuVGltZSB9KSxcbiAgICAgIFtGaWx0ZXJUeXBlLkVOVU1FUkFUSU9OXTogKCkgPT5cbiAgICAgICAgbmV3IFNlbGVjdEZpZWxkKHtcbiAgICAgICAgICAuLi5maWVsZCxcbiAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgncGxhdGZvcm0uZmlsdGVyX3NlcnZpY2Uuc2VsZWN0JyksXG4gICAgICAgICAgb3B0aW9uczogWy4uLnRyYW5zbGF0ZWRFbnVtSXRlbXNdIGFzIGFueSxcbiAgICAgICAgICB0eXBlOiBGaWVsZFR5cGUuRW51bVxuICAgICAgICB9KSxcbiAgICAgIFtGaWx0ZXJUeXBlLklOVEVHRVJdOiAoKSA9PlxuICAgICAgICBuZXcgTnVtYmVyRmllbGQoe1xuICAgICAgICAgIC4uLmZpZWxkLFxuICAgICAgICAgIG51bWJlckxvY2FsZU9wdGlvbnM6IHRoaXMub3B0aW9uc0ludGVnZXIoKSxcbiAgICAgICAgICBtYXNrOiBtYXNrID8gKCkgPT4gbWFzayA6IG51bGwsXG4gICAgICAgICAgdHlwZTogRmllbGRUeXBlLkludGVnZXJcbiAgICAgICAgfSksXG4gICAgICBbRmlsdGVyVHlwZS5ET1VCTEVdOiAoKSA9PiBuZXcgQ3VycmVuY3lGaWVsZCh7IC4uLmZpZWxkLCB0eXBlOiBGaWVsZFR5cGUuRG91YmxlIH0pLFxuICAgICAgW0ZpbHRlclR5cGUuU0VBUkNIXTogKCkgPT4gdGhpcy5jcmVhdGVBdXRvY29tcGxldGVGaWVsZChmaWVsZCwgZmlsdGVyKVxuICAgIH07XG5cbiAgICByZXR1cm4gY3JlYXRvcnNbdHlwZV0oKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlUmFkaW9CdXR0b24oZmllbGQ6IEZpZWxkQ29uZmlnKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IFtcbiAgICAgIHsgbGFiZWw6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoYCR7VFJBTlNMQVRFX1BSRUZJWH0ueWVzYCksIHZhbHVlOiB0cnVlIH0sXG4gICAgICB7IGxhYmVsOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KGAke1RSQU5TTEFURV9QUkVGSVh9Lm5vYCksIHZhbHVlOiBmYWxzZSB9XG4gICAgXSBhcyBSYXRpb25CdXR0b25PcHRpb25bXTtcblxuICAgIHJldHVybiBuZXcgUmFkaW9CdXR0b25GaWVsZCh7IC4uLmZpZWxkLCB0eXBlOiBGaWVsZFR5cGUuUmFkaW8sIG9wdGlvbnMgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNhbGVuZGFyKGNvbmZpZzogQ2FsZW5kYXJGaWVsZENvbmZpZykge1xuICAgIGNvbnN0IGNhbGVuZGFyID0gbmV3IENhbGVuZGFyRmllbGQoY29uZmlnKTtcbiAgICBjYWxlbmRhci5jYWxlbmRhckxvY2FsZU9wdGlvbnMgPSB0aGlzLmNhbGVuZGFyT3B0aW9uc1NlcnZpY2UuZ2V0T3B0aW9ucygpO1xuICAgIGlmICghdGhpcy5pc01vZGFsKSBjYWxlbmRhci5hcHBlbmRUbyA9ICdib2R5JztcbiAgICByZXR1cm4gY2FsZW5kYXI7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUF1dG9jb21wbGV0ZUZpZWxkKGZpZWxkOiBGaWVsZENvbmZpZywgeyBkZXBlbmRzT24sIHNlYXJjaCwgZG9tYWluLCBuYW1lIH06IEZpbHRlcikge1xuICAgIGNvbnN0IHN1Z2dlc3Rpb25zT2JzZXJ2YWJsZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcbiAgICBjb25zdCB7IHF1ZXJ5UGFyYW0gfSA9IGdldFNlYXJjaFR5cGUoc2VhcmNoKS5pbnB1dDtcbiAgICBjb25zdCB7IGRpc3BsYXlGaWVsZHMsIGtleUZpZWxkcywgcmVzdWx0RGF0YUpzb25QYXRoLCBkaXNwbGF5RmllbGRDb25jYXRUb2tlbiwgbWF4U2VsZWN0ZWRJdGVtcyB9ID0gZ2V0U2VhcmNoVHlwZShzZWFyY2gpLm91dHB1dDtcbiAgICBjb25zdCBmaWx0ZXJJZCA9IGdldEZpbHRlcklkKGRvbWFpbiwgbmFtZSk7XG4gICAgY29uc3Qgc3VnZ2VzdGlvbnNFcnJvciA9IChtZXNzYWdlRXJyb3I/OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2VEZXRhaWwgPSBtZXNzYWdlRXJyb3IgPyBtZXNzYWdlRXJyb3IgOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KGAke1RSQU5TTEFURV9QUkVGSVh9LmZpbmRfc3VnZ2VzdGlvbnNfZXJyb3JgLCB7IGFjdGl2ZUZpbHRlcnM6IHRoaXMudG90YWxGaWx0ZXJzQWN0aXZlIH0pXG4gICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICBrZXk6ICdmaWx0ZXJTZXJ2aWNlVG9hc3RLZXknLFxuICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgbGlmZTogVE9BU1RfTElGRSxcbiAgICAgICAgZGV0YWlsOiBtZXNzYWdlRGV0YWlsXG4gICAgICB9O1xuICAgICAgdGhpcy5zZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uU2VhcmNoID0gKHZhbDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IFtxdWVyeVBhcmFtXTogdmFsIH07XG4gICAgICBkZXBlbmRzT24gJiYgT2JqZWN0LmFzc2lnbihwYXJhbXMsIHRoaXMuZ2V0RGVwZW5kZW5jaWVzVmFsdWVzKGRlcGVuZHNPbiwgZG9tYWluKSk7XG5cbiAgICAgIGNvbnN0IHNlYXJjaFVybCA9XG4gICAgICAgIHNlYXJjaCAmJiBzZWFyY2gudHlwZSA9PT0gJ0VOVElUWSdcbiAgICAgICAgICA/IHRoaXMuZ2V0RW50aXR5U2VhcmNoVXJsKHNlYXJjaC5lbnRpdHlTZWFyY2guaW5wdXQsIHZhbCwgZGVwZW5kc09uKVxuICAgICAgICAgIDogZ2V0U2VhcmNoVHlwZShzZWFyY2gpLmlucHV0LnVybDtcblxuICAgICAgdGhpcy5maWx0ZXJTZXJ2aWNlXG4gICAgICAgIC5zZWFyY2hGaWVsZFN1Z2dlc3Rpb25zKHNlYXJjaFVybCwgcGFyYW1zLCBzZWFyY2gudHlwZSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgbWFwKHJlc3BvbnNlID0+IGpzb25QYXRoKHJlc3BvbnNlLCByZXN1bHREYXRhSnNvblBhdGgpKSxcbiAgICAgICAgICBtYXAoKHN1Z2dlc3Rpb25zOiBhbnlbXSkgPT4gdGhpcy5hZGRTdWdnZXN0aW9uRmllbGRzKHN1Z2dlc3Rpb25zLCBkaXNwbGF5RmllbGRzLCBrZXlGaWVsZHMsIGRpc3BsYXlGaWVsZENvbmNhdFRva2VuLCBmaWx0ZXJJZCkpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgICAgIHN1Z2dlc3Rpb25zT2JzZXJ2YWJsZS5uZXh0KHJlc3VsdCk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgIGxldCBtZXNzYWdlRXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IuZXJyb3IubWVzc2FnZSkgbWVzc2FnZUVycm9yID0gZXJyb3IuZXJyb3IubWVzc2FnZVxuICAgICAgICAgIHN1Z2dlc3Rpb25zRXJyb3IobWVzc2FnZUVycm9yKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIG5ldyBBdXRvY29tcGxldGVGaWVsZCh7XG4gICAgICAuLi5maWVsZCxcbiAgICAgIG9uU2VhcmNoLFxuICAgICAgYXBwZW5kVG86ICdib2R5JyxcbiAgICAgIHN1Z2dlc3Rpb25zT2JzZXJ2YWJsZSxcbiAgICAgIGRpc3BsYXlGaWVsZDogc2VhcmNoRGlzcGxheU5hbWUsXG4gICAgICBkYXRhS2V5OiBzZWFyY2hLZXlOYW1lLFxuICAgICAgbXVsdGlwbGU6IG1heFNlbGVjdGVkSXRlbXMgPiAxLFxuICAgICAgc2l6ZTogeyBsZzogMTIsIG1kOiAxMiwgeGw6IDEyIH0sXG4gICAgICBlbXB0eU1lc3NhZ2U6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoYCR7VFJBTlNMQVRFX1BSRUZJWH0uc2VhcmNoX2VtcHR5X21lc3NhZ2VgKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbnRpdHlTZWFyY2hVcmwoc2VhcmNoOiBFbnRpdHlTZWFyY2hJbnB1dCwgdmFsdWU6IHN0cmluZywgZGVwZW5kc09uOiBEZXBlbmRzT25bXSkge1xuICAgIGNvbnN0IHsgYXR0cmlidXRlcywgZG9tYWluTmFtZSwgZW50aXR5TmFtZSwgc2VydmljZU5hbWUgfSA9IHNlYXJjaDtcbiAgICBjb25zdCB1cmwgPSBgJHtkb21haW5OYW1lfS8ke3NlcnZpY2VOYW1lfS9lbnRpdGllcy8ke2VudGl0eU5hbWV9Lz9maWx0ZXI9YDtcbiAgICBjb25zdCBmaWx0ZXJzOiBhbnkgPSBhdHRyaWJ1dGVzLm1hcChhdHRyID0+IGZpbHRlck9wZXJhdG9yc1thdHRyLmNvbXBhcmF0b3JdKGF0dHIubmFtZSwgdmFsdWUpKTtcblxuICAgIGRlcGVuZHNPbiAmJlxuICAgICAgZGVwZW5kc09uLmZvckVhY2gob2JqID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVySWQgPSBnZXRGaWx0ZXJJZChkb21haW5OYW1lLCBvYmouZmlsdGVyTmFtZSk7XG4gICAgICAgIGNvbnN0IGZpZWxkVmFsdWUgPSB0aGlzLmZvcm1GaWx0ZXJzW2ZpbHRlcklkXS52YWx1ZVtzZWFyY2hLZXlOYW1lXTtcbiAgICAgICAgZmlsdGVycy5wdXNoKGAke29iai5lbnRpdHlBdHRyaWJ1dGV9IGVxICcke2ZpZWxkVmFsdWV9J2ApO1xuICAgICAgfSk7XG5cbiAgICAvLyBPIHJlZ2V4IGFwZW5hcyBzZWxlY2lvbmEgYXMgdmlyZ3VsYXMgaWdub3JhbmRvIGFzIHF1ZSBlc3RpdmVyZW0gZGVudHJvIGRvICgpXG4gICAgcmV0dXJuIHVybC5jb25jYXQoZmlsdGVycykucmVwbGFjZSgvWyxdKyg/IVteKF0qWyldKS9nLCBgICR7c2VhcmNoLm9wZXJhdG9yfSBgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkU3VnZ2VzdGlvbkZpZWxkcyhzdWdnZXN0aW9uczogYW55W10sIGRpc3BsYXlGaWVsZHM6IHN0cmluZ1tdLCBrZXlGaWVsZHM6IHN0cmluZ1tdLCBzZXBhcmF0b3I6IHN0cmluZywgZmlsdGVySWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGFkZFZhbHVlID0gKGFjYzogc3RyaW5nLCB2YWx1ZTogYW55LCB0b2tlbjogc3RyaW5nKSA9PiAoYWNjID8gYCR7YWNjfSR7dG9rZW59JHt2YWx1ZX1gIDogdmFsdWUpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gc3VnZ2VzdGlvbnMubWFwKHN1Z2dlc3Rpb24gPT4gKHtcbiAgICAgIC4uLnN1Z2dlc3Rpb24sXG4gICAgICBbc2VhcmNoRGlzcGxheU5hbWVdOiBkaXNwbGF5RmllbGRzLnJlZHVjZSgodmFsdWUsIGRpc3BsYXkpID0+IHtcbiAgICAgICAgcmV0dXJuIGFkZFZhbHVlKHZhbHVlLCB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KHN1Z2dlc3Rpb25bZGlzcGxheV0pLCBzZXBhcmF0b3IpO1xuICAgICAgfSwgJycpLFxuICAgICAgW3NlYXJjaEtleU5hbWVdOiBrZXlGaWVsZHMucmVkdWNlKCh2YWx1ZSwga2V5KSA9PiBhZGRWYWx1ZSh2YWx1ZSwgc3VnZ2VzdGlvbltrZXldLCAnLCAnKSwgJycpXG4gICAgfSkpO1xuICAgIHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdLmludmFsaWRWYWx1ZSA9IHJlc3VsdC5sZW5ndGggPT09IDA7XG5cbiAgICByZXR1cm4gcmVzdWx0LmZpbHRlcihpdGVtID0+IHtcbiAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdmFsdWUuZmluZEluZGV4KChpOiBhbnkpID0+IGkuJCRfX2tleVZhbHVlX18gPT09IGl0ZW0uJCRfX2tleVZhbHVlX18pO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZXBlbmRlbmNpZXNWYWx1ZXMoZGVwZW5kZW5jaWVzOiBEZXBlbmRzT25bXSwgZG9tYWluOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZGVwZW5kZW5jaWVzLnJlZHVjZSgocGFyYW1zLCB7IGZpbHRlck5hbWUgfSkgPT4ge1xuICAgICAgY29uc3QgZmlsdGVySWQgPSBnZXRGaWx0ZXJJZChkb21haW4sIGZpbHRlck5hbWUpO1xuICAgICAgaWYgKHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdKSB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUsIHR5cGUgfSA9IHRoaXMuZm9ybUZpbHRlcnNbZmlsdGVySWRdO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ0VOVU1FUkFUSU9OJykge1xuICAgICAgICAgIHBhcmFtc1tmaWx0ZXJOYW1lXSA9IHZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgcGFyYW1zW2ZpbHRlck5hbWVdID0gdmFsdWUubWFwKGFyciA9PiBhcnJbc2VhcmNoS2V5TmFtZV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJhbXNbZmlsdGVyTmFtZV0gPSB2YWx1ZSA/IHZhbHVlW3NlYXJjaEtleU5hbWVdIDogWycnXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5Jc0VtcHR5KHBhcmFtc1tmaWx0ZXJOYW1lXSkgJiYgZGVsZXRlIHBhcmFtc1tmaWx0ZXJOYW1lXTtcbiAgICAgICAgcmV0dXJuIHBhcmFtcztcbiAgICAgIH1cbiAgICB9LCB7fSk7XG4gIH1cblxuICAvKlxuICAgKiBWZXJpZmljYSBzZSBvIHZhbG9yIGluZm9ybWFkbyDDqSBmYWxzbywgZW0gYXJyYXlzLCDDqSB2ZXJpZmljYWRvIGNhZGEgaXRlbVxuICAgKi9cbiAgcHJpdmF0ZSBJc0VtcHR5KHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5ldmVyeShkYXRhID0+ICFkYXRhKSA6ICF2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gZm9ybWF0IHRvIHNwZWNpZnkgZm9yIGludGVnZXIgdHlwZSBmaWVsZFxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpb25zSW50ZWdlcigpIHtcbiAgICByZXR1cm4geyBjdXJyZW5jeVN5bWJvbDogJycsIGRlY2ltYWxTZXBhcmF0b3I6ICcnLCB0aG91c2FuZHNTZXBhcmF0b3I6ICcnIH07XG4gIH1cbn1cbiJdfQ==