@hmcts/rpx-xui-common-lib 2.0.0-rc.4 → 2.1.1-angular-upgrade-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 (180) hide show
  1. package/bundles/hmcts-rpx-xui-common-lib.umd.js +8004 -3340
  2. package/bundles/hmcts-rpx-xui-common-lib.umd.js.map +1 -1
  3. package/bundles/hmcts-rpx-xui-common-lib.umd.min.js +15 -1
  4. package/bundles/hmcts-rpx-xui-common-lib.umd.min.js.map +1 -1
  5. package/esm2015/hmcts-rpx-xui-common-lib.js +60 -45
  6. package/esm2015/lib/components/accessibility/accessibility.component.js +2 -2
  7. package/esm2015/lib/components/cookie-banner/cookie-banner.component.js +129 -0
  8. package/esm2015/lib/components/due-date/due-date.component.js +6 -7
  9. package/esm2015/lib/components/find-location/find-location.component.js +229 -0
  10. package/esm2015/lib/components/find-person/find-person.component.js +259 -0
  11. package/esm2015/lib/components/generic-filter/generic-filter-utils.js +65 -0
  12. package/esm2015/lib/components/generic-filter/generic-filter.component.js +630 -0
  13. package/esm2015/lib/components/index.js +2 -2
  14. package/esm2015/lib/components/loading-spinner/loading-spinner.component.js +6 -35
  15. package/esm2015/lib/components/pagination/pagination.component.js +50 -0
  16. package/esm2015/lib/components/public_api.js +9 -6
  17. package/esm2015/lib/components/search-judicials/search-judicials.component.js +249 -0
  18. package/esm2015/lib/components/search-location/search-location.component.js +265 -0
  19. package/esm2015/lib/components/search-venue/search-venue.component.js +246 -0
  20. package/esm2015/lib/components/selected-case-confirm/selected-case-confirm.component.js +4 -11
  21. package/esm2015/lib/components/service-messages/service-messages.component.js +2 -2
  22. package/esm2015/lib/components/share-case/share-case.component.js +2 -2
  23. package/esm2015/lib/components/user-list/user-list.component.js +29 -3
  24. package/esm2015/lib/exui-common-lib.module.js +48 -26
  25. package/esm2015/lib/gov-ui/components/gov-uk-date/gov-uk-date.component.js +81 -9
  26. package/esm2015/lib/gov-ui/components/gov-uk-input/gov-uk-input.component.js +2 -2
  27. package/esm2015/lib/gov-ui/components/hmcts-pagination/hmcts-pagination.component.js +49 -0
  28. package/esm2015/lib/gov-ui/components/hmcts-sub-navigation/hmcts-sub-navigation.component.js +7 -2
  29. package/esm2015/lib/gov-ui/components/index.js +2 -2
  30. package/esm2015/lib/gov-ui/components/public_api.js +1 -20
  31. package/esm2015/lib/gov-ui/gov-ui.service.js +1 -1
  32. package/esm2015/lib/gov-ui/index.js +2 -2
  33. package/esm2015/lib/gov-ui/models/isession-storage.interface.js +24 -0
  34. package/esm2015/lib/gov-ui/public_api.js +2 -4
  35. package/esm2015/lib/gov-ui/util/session-storage/session-storage-utils.js +58 -0
  36. package/esm2015/lib/models/contact-details.model.js +8 -1
  37. package/esm2015/lib/models/due-date.model.js +8 -1
  38. package/esm2015/lib/models/filter.model.js +118 -0
  39. package/esm2015/lib/models/index.js +14 -2
  40. package/esm2015/lib/models/location.model.js +108 -0
  41. package/esm2015/lib/models/pagination.model.js +18 -0
  42. package/esm2015/lib/models/person.model.js +92 -0
  43. package/esm2015/lib/models/public_api.js +4 -9
  44. package/esm2015/lib/models/search-options.model.js +22 -0
  45. package/esm2015/lib/services/case-sharing-state/case-sharing-state.service.js +1 -1
  46. package/esm2015/lib/services/cookie/cookie.service.js +110 -0
  47. package/esm2015/lib/services/feature-toggle/feature-toggle.guard.js +8 -2
  48. package/esm2015/lib/services/feature-toggle/feature-toggle.service.js +4 -3
  49. package/esm2015/lib/services/feature-toggle/launch-darkly.service.js +28 -21
  50. package/esm2015/lib/services/filter/filter.service.js +118 -0
  51. package/esm2015/lib/services/find-person/find-person.service.js +214 -0
  52. package/esm2015/lib/services/google-analytics/google-analytics.service.js +1 -1
  53. package/esm2015/lib/services/google-tag-manager/google-tag-manager.service.js +1 -1
  54. package/esm2015/lib/services/index.js +2 -2
  55. package/esm2015/lib/services/loading/loading.service.js +10 -11
  56. package/esm2015/lib/services/locations/location.service.js +55 -0
  57. package/esm2015/lib/services/manage-session/manage-session.services.js +3 -3
  58. package/esm2015/lib/services/public-api.js +9 -4
  59. package/esm2015/lib/services/role-guard/role.guard.js +1 -1
  60. package/esm2015/lib/services/role-guard/role.service.js +1 -1
  61. package/esm2015/lib/services/session-storage/session-storage.service.js +55 -0
  62. package/esm2015/lib/services/timeout-notifications/timeout-notifications.service.js +3 -3
  63. package/esm2015/public-api.js +6 -6
  64. package/esm5/hmcts-rpx-xui-common-lib.js +60 -45
  65. package/esm5/lib/components/accessibility/accessibility.component.js +2 -2
  66. package/esm5/lib/components/cookie-banner/cookie-banner.component.js +154 -0
  67. package/esm5/lib/components/due-date/due-date.component.js +6 -7
  68. package/esm5/lib/components/find-location/find-location.component.js +279 -0
  69. package/esm5/lib/components/find-person/find-person.component.js +286 -0
  70. package/esm5/lib/components/generic-filter/generic-filter-utils.js +66 -0
  71. package/esm5/lib/components/generic-filter/generic-filter.component.js +822 -0
  72. package/esm5/lib/components/index.js +2 -2
  73. package/esm5/lib/components/loading-spinner/loading-spinner.component.js +6 -38
  74. package/esm5/lib/components/pagination/pagination.component.js +58 -0
  75. package/esm5/lib/components/public_api.js +9 -6
  76. package/esm5/lib/components/search-judicials/search-judicials.component.js +291 -0
  77. package/esm5/lib/components/search-location/search-location.component.js +302 -0
  78. package/esm5/lib/components/search-venue/search-venue.component.js +290 -0
  79. package/esm5/lib/components/selected-case-confirm/selected-case-confirm.component.js +4 -11
  80. package/esm5/lib/components/service-messages/service-messages.component.js +2 -2
  81. package/esm5/lib/components/share-case/share-case.component.js +2 -2
  82. package/esm5/lib/components/user-list/user-list.component.js +36 -3
  83. package/esm5/lib/exui-common-lib.module.js +51 -29
  84. package/esm5/lib/gov-ui/components/gov-uk-date/gov-uk-date.component.js +95 -8
  85. package/esm5/lib/gov-ui/components/gov-uk-input/gov-uk-input.component.js +2 -2
  86. package/esm5/lib/gov-ui/components/hmcts-pagination/hmcts-pagination.component.js +51 -0
  87. package/esm5/lib/gov-ui/components/hmcts-sub-navigation/hmcts-sub-navigation.component.js +7 -2
  88. package/esm5/lib/gov-ui/components/index.js +2 -2
  89. package/esm5/lib/gov-ui/components/public_api.js +1 -20
  90. package/esm5/lib/gov-ui/gov-ui.service.js +1 -1
  91. package/esm5/lib/gov-ui/index.js +2 -2
  92. package/esm5/lib/gov-ui/models/isession-storage.interface.js +24 -0
  93. package/esm5/lib/gov-ui/public_api.js +2 -4
  94. package/esm5/lib/gov-ui/util/session-storage/session-storage-utils.js +58 -0
  95. package/esm5/lib/models/contact-details.model.js +8 -1
  96. package/esm5/lib/models/due-date.model.js +8 -1
  97. package/esm5/lib/models/filter.model.js +122 -0
  98. package/esm5/lib/models/index.js +14 -2
  99. package/esm5/lib/models/location.model.js +108 -0
  100. package/esm5/lib/models/pagination.model.js +18 -0
  101. package/esm5/lib/models/person.model.js +92 -0
  102. package/esm5/lib/models/public_api.js +4 -9
  103. package/esm5/lib/models/search-options.model.js +22 -0
  104. package/esm5/lib/services/case-sharing-state/case-sharing-state.service.js +1 -1
  105. package/esm5/lib/services/cookie/cookie.service.js +136 -0
  106. package/esm5/lib/services/feature-toggle/feature-toggle.guard.js +8 -2
  107. package/esm5/lib/services/feature-toggle/feature-toggle.service.js +5 -3
  108. package/esm5/lib/services/feature-toggle/launch-darkly.service.js +29 -19
  109. package/esm5/lib/services/filter/filter.service.js +153 -0
  110. package/esm5/lib/services/find-person/find-person.service.js +238 -0
  111. package/esm5/lib/services/google-analytics/google-analytics.service.js +1 -1
  112. package/esm5/lib/services/google-tag-manager/google-tag-manager.service.js +1 -1
  113. package/esm5/lib/services/index.js +2 -2
  114. package/esm5/lib/services/loading/loading.service.js +24 -15
  115. package/esm5/lib/services/locations/location.service.js +82 -0
  116. package/esm5/lib/services/manage-session/manage-session.services.js +3 -3
  117. package/esm5/lib/services/public-api.js +9 -4
  118. package/esm5/lib/services/role-guard/role.guard.js +1 -1
  119. package/esm5/lib/services/role-guard/role.service.js +1 -1
  120. package/esm5/lib/services/session-storage/session-storage.service.js +96 -0
  121. package/esm5/lib/services/timeout-notifications/timeout-notifications.service.js +3 -3
  122. package/esm5/public-api.js +6 -6
  123. package/fesm2015/hmcts-rpx-xui-common-lib.js +6320 -2429
  124. package/fesm2015/hmcts-rpx-xui-common-lib.js.map +1 -1
  125. package/fesm5/hmcts-rpx-xui-common-lib.js +7208 -2719
  126. package/fesm5/hmcts-rpx-xui-common-lib.js.map +1 -1
  127. package/hmcts-rpx-xui-common-lib.d.ts +58 -43
  128. package/hmcts-rpx-xui-common-lib.metadata.json +1 -1
  129. package/lib/components/cookie-banner/cookie-banner.component.d.ts +20 -0
  130. package/lib/components/find-location/find-location.component.d.ts +31 -0
  131. package/lib/components/find-person/find-person.component.d.ts +40 -0
  132. package/lib/components/generic-filter/generic-filter-utils.d.ts +8 -0
  133. package/lib/components/generic-filter/generic-filter.component.d.ts +40 -0
  134. package/lib/components/hmcts-session-dialog/hmcts-session-dialog.component.d.ts +1 -1
  135. package/lib/components/invite-user-form/invite-user-form.component.d.ts +1 -1
  136. package/lib/components/loading-spinner/loading-spinner.component.d.ts +1 -7
  137. package/lib/components/pagination/pagination.component.d.ts +10 -0
  138. package/lib/components/public_api.d.ts +8 -5
  139. package/lib/components/search-judicials/search-judicials.component.d.ts +37 -0
  140. package/lib/components/search-location/search-location.component.d.ts +38 -0
  141. package/lib/components/search-venue/search-venue.component.d.ts +37 -0
  142. package/lib/components/user-list/user-list.component.d.ts +9 -2
  143. package/lib/exui-common-lib.module.d.ts +13 -11
  144. package/lib/gov-ui/components/gov-uk-date/gov-uk-date.component.d.ts +8 -0
  145. package/lib/gov-ui/components/hmcts-pagination/hmcts-pagination.component.d.ts +10 -0
  146. package/lib/gov-ui/components/hmcts-sub-navigation/hmcts-sub-navigation.component.d.ts +2 -0
  147. package/lib/gov-ui/components/public_api.d.ts +0 -19
  148. package/lib/gov-ui/models/isession-storage.interface.d.ts +4 -0
  149. package/lib/gov-ui/public_api.d.ts +0 -2
  150. package/lib/gov-ui/util/session-storage/session-storage-utils.d.ts +6 -0
  151. package/lib/models/contact-details.model.d.ts +5 -1
  152. package/lib/models/due-date.model.d.ts +5 -0
  153. package/lib/models/filter.model.d.ts +65 -0
  154. package/lib/models/index.d.ts +12 -0
  155. package/lib/models/location.model.d.ts +49 -0
  156. package/lib/models/pagination.model.d.ts +5 -0
  157. package/lib/models/person.model.d.ts +43 -0
  158. package/lib/models/public_api.d.ts +2 -7
  159. package/lib/models/search-options.model.d.ts +8 -0
  160. package/lib/services/cookie/cookie.service.d.ts +9 -0
  161. package/lib/services/feature-toggle/feature-toggle.service.d.ts +1 -1
  162. package/lib/services/feature-toggle/launch-darkly.service.d.ts +4 -5
  163. package/lib/services/filter/filter.service.d.ts +15 -0
  164. package/lib/services/find-person/find-person.service.d.ts +17 -0
  165. package/lib/services/loading/loading.service.d.ts +1 -1
  166. package/lib/services/locations/location.service.d.ts +23 -0
  167. package/lib/services/public-api.d.ts +7 -2
  168. package/lib/services/session-storage/session-storage.service.d.ts +20 -0
  169. package/lib/window.d.ts +1 -1
  170. package/package.json +5 -3
  171. package/public-api.d.ts +2 -2
  172. package/esm2015/lib/gov-ui/directives/index.js +0 -7
  173. package/esm2015/lib/gov-ui/directives/public_api.js +0 -7
  174. package/esm2015/lib/models/badge-colour.enum.js +0 -14
  175. package/esm5/lib/gov-ui/directives/index.js +0 -7
  176. package/esm5/lib/gov-ui/directives/public_api.js +0 -7
  177. package/esm5/lib/models/badge-colour.enum.js +0 -14
  178. package/lib/gov-ui/directives/index.d.ts +0 -1
  179. package/lib/gov-ui/directives/public_api.d.ts +0 -1
  180. package/lib/models/badge-colour.enum.d.ts +0 -6
@@ -0,0 +1,630 @@
1
+ /**
2
+ * @fileoverview added by tsickle
3
+ * Generated from: lib/components/generic-filter/generic-filter.component.ts
4
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
+ */
6
+ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core';
7
+ import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
8
+ import { FilterService } from './../../services/filter/filter.service';
9
+ import { getValues, maxSelectedValidator, minSelectedValidator } from './generic-filter-utils';
10
+ export class GenericFilterComponent {
11
+ /**
12
+ * @param {?} filterService
13
+ * @param {?} fb
14
+ */
15
+ constructor(filterService, fb) {
16
+ this.filterService = filterService;
17
+ this.fb = fb;
18
+ this.submitted = false;
19
+ }
20
+ /**
21
+ * @return {?}
22
+ */
23
+ get config() {
24
+ return this._config;
25
+ }
26
+ /**
27
+ * @param {?} value
28
+ * @return {?}
29
+ */
30
+ set config(value) {
31
+ this._config = Object.assign({}, value, { fields: value.fields.map((/**
32
+ * @param {?} field
33
+ * @return {?}
34
+ */
35
+ field => (Object.assign({}, field, { displayMinSelectedError: false, displayMaxSelectedError: false })))) });
36
+ this._config = value;
37
+ }
38
+ /**
39
+ * @return {?}
40
+ */
41
+ get settings() {
42
+ return this._settings;
43
+ }
44
+ /**
45
+ * @param {?} value
46
+ * @return {?}
47
+ */
48
+ set settings(value) {
49
+ if (!value) {
50
+ this.getSettings();
51
+ }
52
+ if (value && value.fields) {
53
+ this.mergeDefaultFields(value);
54
+ }
55
+ this._settings = value;
56
+ }
57
+ /**
58
+ * @private
59
+ * @param {?} field
60
+ * @return {?}
61
+ */
62
+ static addFormValidators(field) {
63
+ /** @type {?} */
64
+ const validators = [];
65
+ if (field && field.minSelected) {
66
+ validators.push(minSelectedValidator(field.minSelected));
67
+ }
68
+ if (field && field.maxSelected) {
69
+ validators.push(maxSelectedValidator(field.maxSelected));
70
+ }
71
+ return validators;
72
+ }
73
+ /**
74
+ * @return {?}
75
+ */
76
+ ngOnInit() {
77
+ if (!this.settings) {
78
+ this.getSettings();
79
+ }
80
+ this.mergeDefaultFields(this.settings);
81
+ this.buildForm(this.config, this.settings);
82
+ this.formSub = this.form.valueChanges.subscribe((/**
83
+ * @return {?}
84
+ */
85
+ () => this.submitted = false));
86
+ }
87
+ /**
88
+ * @return {?}
89
+ */
90
+ ngOnDestroy() {
91
+ if (this.formSub) {
92
+ this.formSub.unsubscribe();
93
+ }
94
+ }
95
+ /**
96
+ * @param {?} field
97
+ * @param {?} form
98
+ * @return {?}
99
+ */
100
+ hidden(field, form) {
101
+ if (!field.showCondition) {
102
+ return false;
103
+ }
104
+ if (typeof field.showCondition === 'string') {
105
+ /** @type {?} */
106
+ const control = (/** @type {?} */ (form.get(field.name)));
107
+ const [name, value] = field.showCondition.split('=');
108
+ if (form.value && form.value[name] === value) {
109
+ if (field.type === 'find-person') {
110
+ control.get('email').setValidators(Validators.required);
111
+ control.get('email').updateValueAndValidity();
112
+ }
113
+ else {
114
+ control.setValidators(Validators.required);
115
+ control.updateValueAndValidity();
116
+ }
117
+ return false;
118
+ }
119
+ else {
120
+ if (field.type === 'find-person') {
121
+ control.get('email').clearValidators();
122
+ control.get('email').updateValueAndValidity();
123
+ }
124
+ else {
125
+ control.clearValidators();
126
+ control.updateValueAndValidity();
127
+ }
128
+ }
129
+ }
130
+ return true;
131
+ }
132
+ /**
133
+ * @param {?} field
134
+ * @param {?} form
135
+ * @return {?}
136
+ */
137
+ disabled(field, form) {
138
+ if (!field.enableCondition) {
139
+ return null;
140
+ }
141
+ if (typeof field.enableCondition === 'string') {
142
+ /** @type {?} */
143
+ const control = (/** @type {?} */ (form.get(field.name)));
144
+ const [name, value] = field.enableCondition.split('=');
145
+ if (form.value && form.value[name] === value) {
146
+ if (field.type === 'find-person') {
147
+ control.get('email').setValidators(Validators.required);
148
+ control.get('email').updateValueAndValidity();
149
+ }
150
+ else {
151
+ control.setValidators(Validators.required);
152
+ control.updateValueAndValidity();
153
+ }
154
+ return null;
155
+ }
156
+ else {
157
+ if (field.type === 'find-person') {
158
+ control.get('email').clearValidators();
159
+ control.get('email').updateValueAndValidity();
160
+ }
161
+ else {
162
+ control.clearValidators();
163
+ control.updateValueAndValidity();
164
+ }
165
+ }
166
+ }
167
+ // find-location is special case where need to reset textbox (by existing disabling functionality)
168
+ // field.disable referred to component itself
169
+ if (field.type === 'find-location') {
170
+ return true;
171
+ }
172
+ // Note: field.disable decides whether to actually disable or not
173
+ return field.disable ? field.disable : null;
174
+ }
175
+ /**
176
+ * @param {?} form
177
+ * @return {?}
178
+ */
179
+ applyFilter(form) {
180
+ this.submitted = true;
181
+ form.markAsTouched();
182
+ if (form.valid) {
183
+ this._settings = {
184
+ id: this.config.id,
185
+ fields: this.getSelectedValues(form.value, this.config)
186
+ };
187
+ this.filterService.givenErrors.next(null);
188
+ /** @type {?} */
189
+ const settings = Object.assign({}, this.settings, { reset: false });
190
+ this.filterService.persist(settings, this.config.persistence);
191
+ }
192
+ else {
193
+ this.emitFormErrors(form);
194
+ }
195
+ }
196
+ // when domain changes ensure that person field is reset
197
+ /**
198
+ * @param {?} field
199
+ * @param {?} form
200
+ * @return {?}
201
+ */
202
+ fieldChanged(field, form) {
203
+ // TODO - Do similar with jurisdiction/service for caseworkers by services
204
+ if (field.changeResetFields && field.changeResetFields.length) {
205
+ for (const resetField of field.changeResetFields) {
206
+ this.resetField(resetField, form);
207
+ }
208
+ }
209
+ }
210
+ // when user enters input change radio button
211
+ /**
212
+ * @param {?} field
213
+ * @return {?}
214
+ */
215
+ inputChanged(field) {
216
+ if (field.radioSelectionChange && typeof field.radioSelectionChange === 'string') {
217
+ const [name, value] = field.enableCondition.split('=');
218
+ this.form.get(name).patchValue(value);
219
+ }
220
+ }
221
+ /**
222
+ * @return {?}
223
+ */
224
+ cancelFilter() {
225
+ this.buildForm(this.config, this.settings, true);
226
+ if (this.config && this.config.cancelSetting) {
227
+ this._settings.fields = JSON.parse(JSON.stringify(this.config.cancelSetting.fields));
228
+ }
229
+ /** @type {?} */
230
+ const settings = Object.assign({}, this.settings, { reset: true });
231
+ this.filterService.persist(settings, this.config.persistence);
232
+ this.filterService.givenErrors.next(null);
233
+ this.submitted = false;
234
+ }
235
+ /**
236
+ * @param {?} values
237
+ * @param {?} field
238
+ * @return {?}
239
+ */
240
+ updatePersonControls(values, field) {
241
+ /** @type {?} */
242
+ let keys;
243
+ if (!values) {
244
+ keys = Object.keys(this.form.get(field.name).value);
245
+ }
246
+ else {
247
+ keys = Object.keys(values);
248
+ }
249
+ for (const key of keys) {
250
+ if (this.form.get(field.name) && this.form.get(field.name).get(key)) {
251
+ /** @type {?} */
252
+ const value = values && values[key] ? values[key] : null;
253
+ this.form.get(field.name).get(key).patchValue(value);
254
+ }
255
+ }
256
+ }
257
+ /**
258
+ * @param {?} event
259
+ * @param {?} form
260
+ * @param {?} item
261
+ * @param {?} field
262
+ * @return {?}
263
+ */
264
+ toggleSelectAll(event, form, item, field) {
265
+ /** @type {?} */
266
+ const isChecked = event.target.checked;
267
+ /** @type {?} */
268
+ const formArray = (/** @type {?} */ (form.get(field.name)));
269
+ if (!item.selectAll) {
270
+ /** @type {?} */
271
+ const allChecked = formArray.controls.every((/**
272
+ * @param {?} control
273
+ * @return {?}
274
+ */
275
+ (control) => control.value));
276
+ /** @type {?} */
277
+ let index = null;
278
+ /** @type {?} */
279
+ const hasSelectAllOption = field.options.find((/**
280
+ * @param {?} option
281
+ * @param {?} i
282
+ * @return {?}
283
+ */
284
+ (option, i) => {
285
+ if (option.hasOwnProperty('selectAll')) {
286
+ index = i;
287
+ return true;
288
+ }
289
+ return false;
290
+ }));
291
+ // tslint:disable-next-line:variable-name
292
+ /** @type {?} */
293
+ const isAllCheckedExcludingTheSelectAllOption = formArray.controls.filter((/**
294
+ * @param {?} _control
295
+ * @param {?} i
296
+ * @return {?}
297
+ */
298
+ (_control, i) => i !== index))
299
+ .every((/**
300
+ * @param {?} control
301
+ * @return {?}
302
+ */
303
+ (control) => control.value));
304
+ if (!allChecked && hasSelectAllOption && !isChecked) {
305
+ formArray.controls.forEach((/**
306
+ * @param {?} control
307
+ * @param {?} i
308
+ * @return {?}
309
+ */
310
+ (control, i) => {
311
+ if (index === i) {
312
+ control.patchValue(false);
313
+ return;
314
+ }
315
+ }));
316
+ }
317
+ else if (hasSelectAllOption && !allChecked && isChecked && isAllCheckedExcludingTheSelectAllOption) {
318
+ formArray.controls[index].patchValue(true);
319
+ }
320
+ return;
321
+ }
322
+ formArray.controls.forEach((/**
323
+ * @param {?} control
324
+ * @return {?}
325
+ */
326
+ (control) => {
327
+ if (isChecked) {
328
+ control.patchValue(true);
329
+ }
330
+ else {
331
+ control.patchValue(false);
332
+ }
333
+ }));
334
+ }
335
+ /**
336
+ * @private
337
+ * @param {?} resetField
338
+ * @param {?} form
339
+ * @return {?}
340
+ */
341
+ resetField(resetField, form) {
342
+ /** @type {?} */
343
+ const control = form.get(resetField);
344
+ /** @type {?} */
345
+ const defaultValue = this.config.cancelSetting.fields.find((/**
346
+ * @param {?} f
347
+ * @return {?}
348
+ */
349
+ (f) => f.name === resetField));
350
+ if (control instanceof FormArray) {
351
+ for (let i = 0; i < control.length; i++) {
352
+ control.removeAt(i);
353
+ }
354
+ }
355
+ else if (control instanceof FormGroup) {
356
+ /** @type {?} */
357
+ const keys = Object.keys(control.value);
358
+ for (const key of keys) {
359
+ this.resetField(key, control);
360
+ }
361
+ }
362
+ else if (control instanceof FormControl) {
363
+ /** @type {?} */
364
+ const value = defaultValue && defaultValue.value && defaultValue.value.length ? defaultValue.value[0] : null;
365
+ control.setValue(value);
366
+ }
367
+ }
368
+ /**
369
+ * @private
370
+ * @param {?} filter
371
+ * @return {?}
372
+ */
373
+ mergeDefaultFields(filter) {
374
+ if (filter) {
375
+ filter.fields = this.filterService.get(this.config.id) ? this.filterService.get(this.config.id).fields : filter.fields;
376
+ }
377
+ else if (this.config && this.config.cancelSetting) {
378
+ this._settings = {
379
+ id: this.config.id,
380
+ fields: JSON.parse(JSON.stringify(this.config.cancelSetting.fields))
381
+ };
382
+ }
383
+ }
384
+ /**
385
+ * @private
386
+ * @return {?}
387
+ */
388
+ getSettings() {
389
+ this._settings = this.filterService.get(this.config.id);
390
+ }
391
+ /**
392
+ * @private
393
+ * @param {?} config
394
+ * @param {?} settings
395
+ * @param {?=} reset
396
+ * @return {?}
397
+ */
398
+ buildForm(config, settings, reset) {
399
+ /** @type {?} */
400
+ const findPersonControl = this.form ? this.form.get('findPersonControl') : null;
401
+ this.form = this.fb.group({});
402
+ if (findPersonControl) {
403
+ // in order to maintain find person component, control needs to be kept
404
+ this.form.addControl('findPersonControl', findPersonControl);
405
+ }
406
+ for (const field of config.fields) {
407
+ if (field.type === 'checkbox' || field.type === 'checkbox-large') {
408
+ /** @type {?} */
409
+ const formArray = this.buildCheckBoxFormArray(field, settings);
410
+ this.form.addControl(field.name, formArray);
411
+ }
412
+ else if (field.type === 'find-location') {
413
+ /** @type {?} */
414
+ const formArray = this.buildFindLocationFormArray(field, settings);
415
+ this.form.addControl(field.name, formArray);
416
+ }
417
+ else {
418
+ /** @type {?} */
419
+ const validators = [];
420
+ if (field.minSelected && field.minSelected > 0) {
421
+ validators.push(Validators.required);
422
+ }
423
+ /** @type {?} */
424
+ let defaultValue = null;
425
+ if (reset && config.cancelSetting) {
426
+ /** @type {?} */
427
+ const cancelField = config.cancelSetting.fields.find((/**
428
+ * @param {?} f
429
+ * @return {?}
430
+ */
431
+ (f) => f.name === field.name));
432
+ defaultValue = cancelField && cancelField.value ? cancelField.value[0] : '';
433
+ }
434
+ else if (settings && settings.fields) {
435
+ /** @type {?} */
436
+ const lastSavedValue = settings.fields.find((/**
437
+ * @param {?} f
438
+ * @return {?}
439
+ */
440
+ (f) => f.name === field.name));
441
+ defaultValue = lastSavedValue && lastSavedValue ? lastSavedValue.value[0] : '';
442
+ }
443
+ // if field is find-person build a form group;
444
+ if (field.type === 'find-person') {
445
+ /** @type {?} */
446
+ const formGroup = new FormGroup({
447
+ domain: new FormControl(''),
448
+ email: new FormControl(defaultValue && defaultValue.hasOwnProperty('email') ? defaultValue.email : '', validators),
449
+ id: new FormControl(''),
450
+ name: new FormControl(''),
451
+ knownAs: new FormControl(''),
452
+ });
453
+ this.form.addControl(field.name, formGroup);
454
+ }
455
+ else {
456
+ /** @type {?} */
457
+ const control = new FormControl(defaultValue, validators);
458
+ this.form.addControl(field.name, control);
459
+ }
460
+ // if field updates find person component set the initial domain
461
+ if (field.findPersonField) {
462
+ this.fieldChanged(field, this.form);
463
+ }
464
+ }
465
+ }
466
+ }
467
+ /**
468
+ * @private
469
+ * @param {?} field
470
+ * @param {?} settings
471
+ * @return {?}
472
+ */
473
+ buildCheckBoxFormArray(field, settings) {
474
+ /** @type {?} */
475
+ const validators = GenericFilterComponent.addFormValidators(field);
476
+ /** @type {?} */
477
+ const formArray = this.fb.array([], validators);
478
+ /** @type {?} */
479
+ let defaultValues;
480
+ if (settings && settings.fields) {
481
+ defaultValues = settings.fields.find((/**
482
+ * @param {?} f
483
+ * @return {?}
484
+ */
485
+ (f) => f.name === field.name));
486
+ }
487
+ for (const option of field.options) {
488
+ /** @type {?} */
489
+ let checked = false;
490
+ if (defaultValues && Array.isArray(defaultValues.value)) {
491
+ checked = !!defaultValues.value.find((/**
492
+ * @param {?} value
493
+ * @return {?}
494
+ */
495
+ (value) => value === option.key));
496
+ }
497
+ formArray.push(new FormControl(checked));
498
+ }
499
+ return formArray;
500
+ }
501
+ /**
502
+ * @private
503
+ * @param {?} field
504
+ * @param {?} settings
505
+ * @return {?}
506
+ */
507
+ buildFindLocationFormArray(field, settings) {
508
+ /** @type {?} */
509
+ const validators = GenericFilterComponent.addFormValidators(field);
510
+ /** @type {?} */
511
+ const formArray = this.fb.array([], validators);
512
+ /** @type {?} */
513
+ let defaultValues;
514
+ if (settings && settings.fields) {
515
+ defaultValues = settings.fields.find((/**
516
+ * @param {?} f
517
+ * @return {?}
518
+ */
519
+ (f) => f.name === field.name));
520
+ if (defaultValues && defaultValues.value && defaultValues.value.length > 0) {
521
+ for (const defaultValue of defaultValues.value) {
522
+ formArray.push(new FormControl(defaultValue));
523
+ }
524
+ }
525
+ }
526
+ return formArray;
527
+ }
528
+ /**
529
+ * @private
530
+ * @param {?} formValues
531
+ * @param {?} config
532
+ * @return {?}
533
+ */
534
+ getSelectedValues(formValues, config) {
535
+ return Object.keys(formValues).map((/**
536
+ * @param {?} name
537
+ * @return {?}
538
+ */
539
+ (name) => {
540
+ /** @type {?} */
541
+ const values = formValues[name];
542
+ if (Array.isArray(values)) {
543
+ /** @type {?} */
544
+ const field = config.fields.find((/**
545
+ * @param {?} f
546
+ * @return {?}
547
+ */
548
+ f => f.name === name));
549
+ if (field.type === 'find-location') {
550
+ return { value: values, name };
551
+ }
552
+ else {
553
+ return { value: getValues(field.options, values), name };
554
+ }
555
+ }
556
+ else {
557
+ return { value: [values], name };
558
+ }
559
+ }));
560
+ }
561
+ /**
562
+ * @private
563
+ * @param {?} form
564
+ * @return {?}
565
+ */
566
+ emitFormErrors(form) {
567
+ /** @type {?} */
568
+ const errors = [];
569
+ for (const field of this.config.fields) {
570
+ /** @type {?} */
571
+ const formGroup = form.get(field.name);
572
+ if (formGroup && formGroup.errors && formGroup.errors.minLength) {
573
+ errors.push({ name: field.name, error: field.minSelectedError });
574
+ }
575
+ if (formGroup && formGroup.errors && formGroup.errors.maxLength) {
576
+ errors.push({ name: field.name, error: field.minSelectedError });
577
+ }
578
+ }
579
+ if (errors.length) {
580
+ this.filterService.givenErrors.next(errors);
581
+ }
582
+ }
583
+ }
584
+ GenericFilterComponent.decorators = [
585
+ { type: Component, args: [{
586
+ selector: 'xuilib-generic-filter',
587
+ template: "<form [formGroup]=\"form\" (ngSubmit)=\"applyFilter(form)\">\n <div class=\"contain-classes\" *ngFor=\"let field of config.fields\">\n <hr *ngIf=\"field.lineBreakBefore\" class=\"govuk-section-break govuk-section-break--visible elevated-break\">\n <div class=\"govuk-form-group xui-generic-filter\"\n [hidden]=\"hidden(field, form)\"\n [id]=\"field.name\"\n [ngClass]=\"{'form-group-error': submitted && (form.get(field.name).errors?.minLength || form.get(field.name).errors?.maxLength)}\">\n <h3 *ngIf=\"field.title\" class=\"govuk-heading-s\">{{field.title}}</h3>\n <p class=\"govuk-body\" *ngIf=\"field.subTitle\">{{field.subTitle}}</p>\n <span [id]=\"field.name + '-error'\" class=\"govuk-error-message\" *ngIf=\"field.displayMinSelectedError && submitted && form.get(field.name).errors?.minLength\">\n <span class=\"govuk-visually-hidden\">Error:</span> {{field.minSelectedError}}\n </span>\n <span [id]=\"field.name + '-error'\" class=\"govuk-error-message\" *ngIf=\"field.displayMaxSelectedError && submitted && form.get(field.name).errors?.maxLength\">\n <span class=\"govuk-visually-hidden\">Error:</span> {{field.maxSelectedError}}\n </span>\n <div class=\"govuk-body\" [ngSwitch]=\"field.type\">\n <ng-container *ngSwitchCase=\"'select'\">\n <select class=\"govuk-select\" (change)=\"fieldChanged(field, form)\" [attr.disabled]=\"disabled(field, form)\" [name]=\"'select_' + field.name\" [id]=\"'select_' + field.name\" [formControlName]=\"field.name\">\n <option disabled selected hidden value=\"\">{{field.disabledText}}</option>\n <option class=\"govuk-radios__item\" *ngFor=\"let item of field.options\" [value]=\"item.key\">{{item.label}}</option>\n </select>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkbox'\">\n <div class=\"govuk-checkboxes govuk-checkboxes--small\" [formGroupName]=\"field.name\" [attr.field]=\"field.name\" [id]=\"'checkbox_' + field.name\">\n <div *ngFor=\"let item of field.options; let i = index\" class=\"govuk-checkboxes__item\">\n <input type=\"checkbox\" class=\"govuk-checkboxes__input\"\n [attr.disabled]=\"disabled(field, form)\"\n [formControlName]=\"i\"\n (change)=\"toggleSelectAll($event, form, item, field)\"\n [value]=\"item.key\" [id]=\"'checkbox_' + item.key\"\n [name]=\"'checkbox_' + item.key\"\n />\n <label\n [for]=\"'checkbox_' + item.key\"\n class=\"govuk-label govuk-checkboxes__label\"\n [ngClass]=\"{'govuk-!-font-weight-bold': item.selectAll}\"\n >{{item.label}}</label>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkbox-large'\">\n <div class=\"govuk-checkboxes\" [formGroupName]=\"field.name\" [attr.field]=\"field.name\" [id]=\"'checkbox_' + field.name\">\n <div *ngFor=\"let item of field.options; let i = index\" class=\"govuk-checkboxes__item\">\n <input type=\"checkbox\" class=\"govuk-checkboxes__input\"\n [attr.disabled]=\"disabled(field, form)\"\n [formControlName]=\"i\"\n (change)=\"toggleSelectAll($event, form, item, field)\"\n [value]=\"item.key\" [id]=\"'checkbox_' + item.key\"\n [name]=\"'checkbox_' + item.key\"\n />\n <label\n [for]=\"'checkbox_' + item.key\"\n class=\"govuk-label govuk-checkboxes__label\"\n [ngClass]=\"{'govuk-!-font-weight-bold': item.selectAll}\"\n >{{item.label}}</label>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'radio'\">\n <div class=\"govuk-radios\">\n <div *ngFor=\"let item of field.options\" class=\"govuk-radios__item\">\n <input type=\"radio\"\n [formControlName]=\"field.name\"\n [id]=\"'radio_' + item.key\"\n [attr.disabled]=\"disabled(field, form)\"\n [checked]=\"item.key === form.get(field.name).value\"\n class=\"govuk-radios__input\"\n [value]=\"item.key\"\n (change)=\"fieldChanged(field, form)\"\n />\n <label [for]=\"'radio_' + item.key\" class=\"govuk-label govuk-radios__label\">{{item.label}}</label>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'find-person'\">\n <xuilib-find-person subTitle=\"\" (personSelected)=\"updatePersonControls($event, field)\"\n (personFieldChanged)=\"inputChanged(field)\"\n [submitted]=\"submitted\"\n [disabled]=\"disabled(field, form)\"\n [domain]=\"form.get(field.domainField)?.value\"\n [findPersonGroup]=\"form\"\n [selectedPerson]=\"form.get(field.name)?.value?.email\"\n [userIncluded]=\"false\"\n ></xuilib-find-person>\n </ng-container>\n <ng-container *ngSwitchCase=\"'find-location'\">\n <xuilib-find-location (locationFieldChanged)=\"inputChanged(field)\"\n [form]=\"form\"\n [fields]=\"config.fields\"\n [locationTitle]=\"field.locationTitle\"\n [enableAddLocationButton]=\"field.enableAddLocationButton\"\n [disabled]=\"disabled(field, form)\"\n [disableInputField]=\"field.disable\"\n [selectedLocations]=\"form.get(field.name)?.value\"\n [submitted]=\"submitted\"\n [services]=\"form.get(field.findLocationField)?.value\"\n [field]=\"field\"\n ></xuilib-find-location>\n </ng-container>\n </div>\n </div>\n </div>\n <hr class=\"govuk-section-break govuk-section-break--m govuk-section-break--visible\"/>\n <div class=\"govuk-grid-row\">\n <div class=\"govuk-grid-column-full\">\n <button\n class=\"govuk-button govuk-!-margin-right-1 govuk-!-margin-bottom-0\"\n type=\"submit\"\n id=\"applyFilter\"\n [disabled]=\"config.enableDisabledButton && form.invalid\"\n >{{config.applyButtonText || 'Apply'}}</button>\n <button *ngIf=\"config.showCancelFilterButton\"\n class=\"govuk-button govuk-button--secondary govuk-!-margin-bottom-0\"\n type=\"button\"\n id=\"cancelFilter\"\n (click)=\"cancelFilter()\">{{ config.cancelButtonText || 'Cancel'}}</button>\n </div>\n </div>\n</form>\n",
588
+ changeDetection: ChangeDetectionStrategy.OnPush,
589
+ encapsulation: ViewEncapsulation.None,
590
+ styles: [".contain-classes .elevated-break{position:relative;top:-10px}.contain-classes .xui-generic-filter .select-all{margin-bottom:10px}.contain-classes .xui-generic-filter .govuk-checkboxes{display:flex;flex-wrap:wrap}.contain-classes .xui-generic-filter .govuk-checkboxes>div{flex-grow:1;flex-shrink:0}"]
591
+ }] }
592
+ ];
593
+ /** @nocollapse */
594
+ GenericFilterComponent.ctorParameters = () => [
595
+ { type: FilterService },
596
+ { type: FormBuilder }
597
+ ];
598
+ GenericFilterComponent.propDecorators = {
599
+ config: [{ type: Input }],
600
+ settings: [{ type: Input }]
601
+ };
602
+ if (false) {
603
+ /** @type {?} */
604
+ GenericFilterComponent.prototype.form;
605
+ /** @type {?} */
606
+ GenericFilterComponent.prototype.submitted;
607
+ /** @type {?} */
608
+ GenericFilterComponent.prototype.formSub;
609
+ /**
610
+ * @type {?}
611
+ * @private
612
+ */
613
+ GenericFilterComponent.prototype._config;
614
+ /**
615
+ * @type {?}
616
+ * @private
617
+ */
618
+ GenericFilterComponent.prototype._settings;
619
+ /**
620
+ * @type {?}
621
+ * @private
622
+ */
623
+ GenericFilterComponent.prototype.filterService;
624
+ /**
625
+ * @type {?}
626
+ * @private
627
+ */
628
+ GenericFilterComponent.prototype.fb;
629
+ }
630
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1maWx0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhtY3RzL3JweC14dWktY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL2dlbmVyaWMtZmlsdGVyL2dlbmVyaWMtZmlsdGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBQyx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixpQkFBaUIsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUM5RyxPQUFPLEVBQWtCLFNBQVMsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBZSxVQUFVLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUd4SCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sd0NBQXdDLENBQUM7QUFDckUsT0FBTyxFQUFDLFNBQVMsRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBUzdGLE1BQU0sT0FBTyxzQkFBc0I7Ozs7O0lBS2pDLFlBQTZCLGFBQTRCLEVBQW1CLEVBQWU7UUFBOUQsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFBbUIsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUhwRixjQUFTLEdBQUcsS0FBSyxDQUFDO0lBSXpCLENBQUM7Ozs7SUFLRCxJQUFXLE1BQU07UUFDZixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQzs7Ozs7SUFFRCxJQUNXLE1BQU0sQ0FBQyxLQUFtQjtRQUNuQyxJQUFJLENBQUMsT0FBTyxxQkFDUCxLQUFLLElBQ1IsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRzs7OztZQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsbUJBQzdCLEtBQUssSUFDUix1QkFBdUIsRUFBRSxLQUFLLEVBQzlCLHVCQUF1QixFQUFFLEtBQUssSUFDOUIsRUFBQyxHQUNKLENBQUM7UUFDRixJQUFJLENBQUMsT0FBTyxH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QUFDLENBQUM7YUFDaEU7WUFDRCxJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO2dCQUMvRCxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxnQkFBZ0IsRUFBQyxDQUFDLENBQUM7YUFDaEU7U0FDRjtRQUNELElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtZQUNqQixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDN0M7SUFDSCxDQUFDOzs7WUFuWUYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSx1QkFBdUI7Z0JBQ2pDLHk3TkFBNEM7Z0JBRTVDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2dCQUMvQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTs7YUFDdEM7Ozs7WUFUTyxhQUFhO1lBSGUsV0FBVzs7O3FCQTRCNUMsS0FBSzt1QkFvQkwsS0FBSzs7OztJQWxDTixzQ0FBdUI7O0lBQ3ZCLDJDQUF5Qjs7SUFDekIseUNBQTZCOzs7OztJQU03Qix5Q0FBOEI7Ozs7O0lBb0I5QiwyQ0FBa0M7Ozs7O0lBeEJ0QiwrQ0FBNkM7Ozs7O0lBQUUsb0NBQWdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QWJzdHJhY3RDb250cm9sLCBGb3JtQXJyYXksIEZvcm1CdWlsZGVyLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBWYWxpZGF0b3JGbiwgVmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtGaWx0ZXJDb25maWcsIEZpbHRlckVycm9yLCBGaWx0ZXJGaWVsZENvbmZpZywgRmlsdGVyU2V0dGluZ30gZnJvbSAnLi4vLi4vbW9kZWxzJztcbmltcG9ydCB7RmlsdGVyU2VydmljZX0gZnJvbSAnLi8uLi8uLi9zZXJ2aWNlcy9maWx0ZXIvZmlsdGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtnZXRWYWx1ZXMsIG1heFNlbGVjdGVkVmFsaWRhdG9yLCBtaW5TZWxlY3RlZFZhbGlkYXRvcn0gZnJvbSAnLi9nZW5lcmljLWZpbHRlci11dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3h1aWxpYi1nZW5lcmljLWZpbHRlcicsXG4gIHRlbXBsYXRlVXJsOiAnZ2VuZXJpYy1maWx0ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnZ2VuZXJpYy1maWx0ZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgR2VuZXJpY0ZpbHRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHVibGljIGZvcm06IEZvcm1Hcm91cDtcbiAgcHVibGljIHN1Ym1pdHRlZCA9IGZhbHNlO1xuICBwdWJsaWMgZm9ybVN1YjogU3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZmlsdGVyU2VydmljZTogRmlsdGVyU2VydmljZSwgcHJpdmF0ZSByZWFkb25seSBmYjogRm9ybUJ1aWxkZXIpIHtcbiAgfVxuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX2NvbmZpZzogRmlsdGVyQ29uZmlnO1xuXG4gIHB1YmxpYyBnZXQgY29uZmlnKCk6IEZpbHRlckNvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgY29uZmlnKHZhbHVlOiBGaWx0ZXJDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSB7XG4gICAgICAuLi52YWx1ZSxcbiAgICAgIGZpZWxkczogdmFsdWUuZmllbGRzLm1hcChmaWVsZCA9PiAoe1xuICAgICAgICAuLi5maWVsZCxcbiAgICAgICAgZGlzcGxheU1pblNlbGVjdGVkRXJyb3I6IGZhbHNlLFxuICAgICAgICBkaXNwbGF5TWF4U2VsZWN0ZWRFcnJvcjogZmFsc2UsXG4gICAgICB9KSlcbiAgICB9O1xuICAgIHRoaXMuX2NvbmZpZyA9IHZhbHVlO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfc2V0dGluZ3M/OiBGaWx0ZXJTZXR0aW5nO1xuXG4gIHB1YmxpYyBnZXQgc2V0dGluZ3MoKTogRmlsdGVyU2V0dGluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xuICB9XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNldCBzZXR0aW5ncyh2YWx1ZTogRmlsdGVyU2V0dGluZykge1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHRoaXMuZ2V0U2V0dGluZ3MoKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlICYmIHZhbHVlLmZpZWxkcykge1xuICAgICAgdGhpcy5tZXJnZURlZmF1bHRGaWVsZHModmFsdWUpO1xuICAgIH1cbiAgICB0aGlzLl9zZXR0aW5ncyA9IHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYWRkRm9ybVZhbGlkYXRvcnMoZmllbGQ6IEZpbHRlckZpZWxkQ29uZmlnKTogVmFsaWRhdG9ycyB7XG4gICAgY29uc3QgdmFsaWRhdG9ycyA9IFtdO1xuICAgIGlmIChmaWVsZCAmJiBmaWVsZC5taW5TZWxlY3RlZCkge1xuICAgICAgdmFsaWRhdG9ycy5wdXNoKG1pblNlbGVjdGVkVmFsaWRhdG9yKGZpZWxkLm1pblNlbGVjdGVkKSk7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkICYmIGZpZWxkLm1heFNlbGVjdGVkKSB7XG4gICAgICB2YWxpZGF0b3JzLnB1c2gobWF4U2VsZWN0ZWRWYWxpZGF0b3IoZmllbGQubWF4U2VsZWN0ZWQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRvcnM7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNldHRpbmdzKSB7XG4gICAgICB0aGlzLmdldFNldHRpbmdzKCk7XG4gICAgfVxuICAgIHRoaXMubWVyZ2VEZWZhdWx0RmllbGRzKHRoaXMuc2V0dGluZ3MpO1xuICAgIHRoaXMuYnVpbGRGb3JtKHRoaXMuY29uZmlnLCB0aGlzLnNldHRpbmdzKTtcbiAgICB0aGlzLmZvcm1TdWIgPSB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLnN1Ym1pdHRlZCA9IGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtU3ViKSB7XG4gICAgICB0aGlzLmZvcm1TdWIudW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgaGlkZGVuKGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZywgZm9ybTogRm9ybUdyb3VwKTogYm9vbGVhbiB7XG4gICAgaWYgKCFmaWVsZC5zaG93Q29uZGl0aW9uKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZmllbGQuc2hvd0NvbmRpdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtLmdldChmaWVsZC5uYW1lKSBhcyBGb3JtQ29udHJvbDtcbiAgICAgIGNvbnN0IFtuYW1lLCB2YWx1ZV0gPSBmaWVsZC5zaG93Q29uZGl0aW9uLnNwbGl0KCc9Jyk7XG4gICAgICBpZiAoZm9ybS52YWx1ZSAmJiBmb3JtLnZhbHVlW25hbWVdID09PSB2YWx1ZSkge1xuICAgICAgICBpZiAoZmllbGQudHlwZSA9PT0gJ2ZpbmQtcGVyc29uJykge1xuICAgICAgICAgIGNvbnRyb2wuZ2V0KCdlbWFpbCcpLnNldFZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAgICAgICAgY29udHJvbC5nZXQoJ2VtYWlsJykudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnRyb2wuc2V0VmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcbiAgICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmllbGQudHlwZSA9PT0gJ2ZpbmQtcGVyc29uJykge1xuICAgICAgICAgIGNvbnRyb2wuZ2V0KCdlbWFpbCcpLmNsZWFyVmFsaWRhdG9ycygpO1xuICAgICAgICAgIGNvbnRyb2wuZ2V0KCdlbWFpbCcpLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb250cm9sLmNsZWFyVmFsaWRhdG9ycygpO1xuICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGVkKGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZywgZm9ybTogRm9ybUdyb3VwKTogYm9vbGVhbiB7XG4gICAgaWYgKCFmaWVsZC5lbmFibGVDb25kaXRpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZpZWxkLmVuYWJsZUNvbmRpdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtLmdldChmaWVsZC5uYW1lKSBhcyBGb3JtQ29udHJvbDtcbiAgICAgIGNvbnN0IFtuYW1lLCB2YWx1ZV0gPSBmaWVsZC5lbmFibGVDb25kaXRpb24uc3BsaXQoJz0nKTtcbiAgICAgIGlmIChmb3JtLnZhbHVlICYmIGZvcm0udmFsdWVbbmFtZV0gPT09IHZhbHVlKSB7XG4gICAgICAgIGlmIChmaWVsZC50eXBlID09PSAnZmluZC1wZXJzb24nKSB7XG4gICAgICAgICAgY29udHJvbC5nZXQoJ2VtYWlsJykuc2V0VmFsaWRhdG9ycyhWYWxpZGF0b3JzLnJlcXVpcmVkKTtcbiAgICAgICAgICBjb250cm9sLmdldCgnZW1haWwnKS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgICAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT09ICdmaW5kLXBlcnNvbicpIHtcbiAgICAgICAgICBjb250cm9sLmdldCgnZW1haWwnKS5jbGVhclZhbGlkYXRvcnMoKTtcbiAgICAgICAgICBjb250cm9sLmdldCgnZW1haWwnKS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udHJvbC5jbGVhclZhbGlkYXRvcnMoKTtcbiAgICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBmaW5kLWxvY2F0aW9uIGlzIHNwZWNpYWwgY2FzZSB3aGVyZSBuZWVkIHRvIHJlc2V0IHRleHRib3ggKGJ5IGV4aXN0aW5nIGRpc2FibGluZyBmdW5jdGlvbmFsaXR5KVxuICAgIC8vIGZpZWxkLmRpc2FibGUgcmVmZXJyZWQgdG8gY29tcG9uZW50IGl0c2VsZlxuICAgIGlmIChmaWVsZC50eXBlID09PSAnZmluZC1sb2NhdGlvbicpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBOb3RlOiBmaWVsZC5kaXNhYmxlIGRlY2lkZXMgd2hldGhlciB0byBhY3R1YWxseSBkaXNhYmxlIG9yIG5vdFxuICAgIHJldHVybiBmaWVsZC5kaXNhYmxlID8gZmllbGQuZGlzYWJsZSA6IG51bGw7XG4gIH1cblxuICBwdWJsaWMgYXBwbHlGaWx0ZXIoZm9ybTogRm9ybUdyb3VwKTogdm9pZCB7XG4gICAgdGhpcy5zdWJtaXR0ZWQgPSB0cnVlO1xuICAgIGZvcm0ubWFya0FzVG91Y2hlZCgpO1xuICAgIGlmIChmb3JtLnZhbGlkKSB7XG4gICAgICB0aGlzLl9zZXR0aW5ncyA9IHtcbiAgICAgICAgaWQ6IHRoaXMuY29uZmlnLmlkLFxuICAgICAgICBmaWVsZHM6IHRoaXMuZ2V0U2VsZWN0ZWRWYWx1ZXMoZm9ybS52YWx1ZSwgdGhpcy5jb25maWcpXG4gICAgICB9O1xuICAgICAgdGhpcy5maWx0ZXJTZXJ2aWNlLmdpdmVuRXJyb3JzLm5leHQobnVsbCk7XG4gICAgICBjb25zdCBzZXR0aW5ncyA9IHsuLi50aGlzLnNldHRpbmdzLCByZXNldDogZmFsc2V9O1xuICAgICAgdGhpcy5maWx0ZXJTZXJ2aWNlLnBlcnNpc3Qoc2V0dGluZ3MsIHRoaXMuY29uZmlnLnBlcnNpc3RlbmNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0Rm9ybUVycm9ycyhmb3JtKTtcbiAgICB9XG4gIH1cblxuICAvLyB3aGVuIGRvbWFpbiBjaGFuZ2VzIGVuc3VyZSB0aGF0IHBlcnNvbiBmaWVsZCBpcyByZXNldFxuICBwdWJsaWMgZmllbGRDaGFuZ2VkKGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZywgZm9ybTogRm9ybUdyb3VwKTogdm9pZCB7XG4gICAgLy8gVE9ETyAtIERvIHNpbWlsYXIgd2l0aCBqdXJpc2RpY3Rpb24vc2VydmljZSBmb3IgY2FzZXdvcmtlcnMgYnkgc2VydmljZXNcbiAgICBpZiAoZmllbGQuY2hhbmdlUmVzZXRGaWVsZHMgJiYgZmllbGQuY2hhbmdlUmVzZXRGaWVsZHMubGVuZ3RoKSB7XG4gICAgICBmb3IgKGNvbnN0IHJlc2V0RmllbGQgb2YgZmllbGQuY2hhbmdlUmVzZXRGaWVsZHMpIHtcbiAgICAgICAgdGhpcy5yZXNldEZpZWxkKHJlc2V0RmllbGQsIGZvcm0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHdoZW4gdXNlciBlbnRlcnMgaW5wdXQgY2hhbmdlIHJhZGlvIGJ1dHRvblxuICBwdWJsaWMgaW5wdXRDaGFuZ2VkKGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZyk6IHZvaWQge1xuICAgIGlmIChmaWVsZC5yYWRpb1NlbGVjdGlvbkNoYW5nZSAmJiB0eXBlb2YgZmllbGQucmFkaW9TZWxlY3Rpb25DaGFuZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBbbmFtZSwgdmFsdWVdID0gZmllbGQuZW5hYmxlQ29uZGl0aW9uLnNwbGl0KCc9Jyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KG5hbWUpLnBhdGNoVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjYW5jZWxGaWx0ZXIoKTogdm9pZCB7XG4gICAgdGhpcy5idWlsZEZvcm0odGhpcy5jb25maWcsIHRoaXMuc2V0dGluZ3MsIHRydWUpO1xuICAgIGlmICh0aGlzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZy5jYW5jZWxTZXR0aW5nKSB7XG4gICAgICB0aGlzLl9zZXR0aW5ncy5maWVsZHMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuY29uZmlnLmNhbmNlbFNldHRpbmcuZmllbGRzKSk7XG4gICAgfVxuICAgIGNvbnN0IHNldHRpbmdzID0gey4uLnRoaXMuc2V0dGluZ3MsIHJlc2V0OiB0cnVlfTtcbiAgICB0aGlzLmZpbHRlclNlcnZpY2UucGVyc2lzdChzZXR0aW5ncywgdGhpcy5jb25maWcucGVyc2lzdGVuY2UpO1xuICAgIHRoaXMuZmlsdGVyU2VydmljZS5naXZlbkVycm9ycy5uZXh0KG51bGwpO1xuICAgIHRoaXMuc3VibWl0dGVkID0gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlUGVyc29uQ29udHJvbHModmFsdWVzOiBhbnksIGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZyk6IHZvaWQge1xuICAgIGxldCBrZXlzO1xuICAgIGlmICghdmFsdWVzKSB7XG4gICAgICBrZXlzID0gT2JqZWN0LmtleXModGhpcy5mb3JtLmdldChmaWVsZC5uYW1lKS52YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZXMpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBpZiAodGhpcy5mb3JtLmdldChmaWVsZC5uYW1lKSAmJiB0aGlzLmZvcm0uZ2V0KGZpZWxkLm5hbWUpLmdldChrZXkpKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzICYmIHZhbHVlc1trZXldID8gdmFsdWVzW2tleV0gOiBudWxsO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KGZpZWxkLm5hbWUpLmdldChrZXkpLnBhdGNoVmFsdWUodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVTZWxlY3RBbGwoZXZlbnQ6IGFueSwgZm9ybTogRm9ybUdyb3VwLCBpdGVtOiB7IGtleTogc3RyaW5nOyBsYWJlbDogc3RyaW5nOyBzZWxlY3RBbGw/OiB0cnVlIH0sIGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZyk6IHZvaWQge1xuICAgIGNvbnN0IGlzQ2hlY2tlZCA9IGV2ZW50LnRhcmdldC5jaGVja2VkO1xuICAgIGNvbnN0IGZvcm1BcnJheTogRm9ybUFycmF5ID0gZm9ybS5nZXQoZmllbGQubmFtZSkgYXMgRm9ybUFycmF5O1xuICAgIGlmICghaXRlbS5zZWxlY3RBbGwpIHtcbiAgICAgIGNvbnN0IGFsbENoZWNrZWQgPSBmb3JtQXJyYXkuY29udHJvbHMuZXZlcnkoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gY29udHJvbC52YWx1ZSk7XG4gICAgICBsZXQgaW5kZXg6IG51bWJlciA9IG51bGw7XG4gICAgICBjb25zdCBoYXNTZWxlY3RBbGxPcHRpb24gPSBmaWVsZC5vcHRpb25zLmZpbmQoKG9wdGlvbiwgaSkgPT4ge1xuICAgICAgICBpZiAob3B0aW9uLmhhc093blByb3BlcnR5KCdzZWxlY3RBbGwnKSkge1xuICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gICAgICBjb25zdCBpc0FsbENoZWNrZWRFeGNsdWRpbmdUaGVTZWxlY3RBbGxPcHRpb24gPSBmb3JtQXJyYXkuY29udHJvbHMuZmlsdGVyKChfY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpOiBudW1iZXIpID0+IGkgIT09IGluZGV4KVxuICAgICAgICAuZXZlcnkoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gY29udHJvbC52YWx1ZSk7XG5cbiAgICAgIGlmICghYWxsQ2hlY2tlZCAmJiBoYXNTZWxlY3RBbGxPcHRpb24gJiYgIWlzQ2hlY2tlZCkge1xuICAgICAgICBmb3JtQXJyYXkuY29udHJvbHMuZm9yRWFjaCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgICBpZiAoaW5kZXggPT09IGkpIHtcbiAgICAgICAgICAgIGNvbnRyb2wucGF0Y2hWYWx1ZShmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaGFzU2VsZWN0QWxsT3B0aW9uICYmICFhbGxDaGVja2VkICYmIGlzQ2hlY2tlZCAmJiBpc0FsbENoZWNrZWRFeGNsdWRpbmdUaGVTZWxlY3RBbGxPcHRpb24pIHtcbiAgICAgICAgZm9ybUFycmF5LmNvbnRyb2xzW2luZGV4XS5wYXRjaFZhbHVlKHRydWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3JtQXJyYXkuY29udHJvbHMuZm9yRWFjaCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICBpZiAoaXNDaGVja2VkKSB7XG4gICAgICAgIGNvbnRyb2wucGF0Y2hWYWx1ZSh0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRyb2wucGF0Y2hWYWx1ZShmYWxzZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0RmllbGQocmVzZXRGaWVsZDogc3RyaW5nLCBmb3JtOiBGb3JtR3JvdXApOiB2b2lkIHtcbiAgICBjb25zdCBjb250cm9sID0gZm9ybS5nZXQocmVzZXRGaWVsZCk7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlOiB7IG5hbWU6IHN0cmluZywgdmFsdWU6IGFueVtdIH0gPSB0aGlzLmNvbmZpZy5jYW5jZWxTZXR0aW5nLmZpZWxkcy5maW5kKChmKSA9PiBmLm5hbWUgPT09IHJlc2V0RmllbGQpO1xuICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRyb2wubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29udHJvbC5yZW1vdmVBdChpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtR3JvdXApIHtcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhjb250cm9sLnZhbHVlKTtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgICAgdGhpcy5yZXNldEZpZWxkKGtleSwgY29udHJvbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZGVmYXVsdFZhbHVlICYmIGRlZmF1bHRWYWx1ZS52YWx1ZSAmJiBkZWZhdWx0VmFsdWUudmFsdWUubGVuZ3RoID8gZGVmYXVsdFZhbHVlLnZhbHVlWzBdIDogbnVsbDtcbiAgICAgIGNvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VEZWZhdWx0RmllbGRzKGZpbHRlcjogRmlsdGVyU2V0dGluZyk6IHZvaWQge1xuICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5maWVsZHMgPSB0aGlzLmZpbHRlclNlcnZpY2UuZ2V0KHRoaXMuY29uZmlnLmlkKSA/IHRoaXMuZmlsdGVyU2VydmljZS5nZXQodGhpcy5jb25maWcuaWQpLmZpZWxkcyA6IGZpbHRlci5maWVsZHM7XG4gICAgfSBlbHNlIGlmICh0aGlzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZy5jYW5jZWxTZXR0aW5nKSB7XG4gICAgICB0aGlzLl9zZXR0aW5ncyA9IHtcbiAgICAgICAgaWQ6IHRoaXMuY29uZmlnLmlkLFxuICAgICAgICBmaWVsZHM6IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWcuY2FuY2VsU2V0dGluZy5maWVsZHMpKVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFNldHRpbmdzKCk6IHZvaWQge1xuICAgIHRoaXMuX3NldHRpbmdzID0gdGhpcy5maWx0ZXJTZXJ2aWNlLmdldCh0aGlzLmNvbmZpZy5pZCk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRm9ybShjb25maWc6IEZpbHRlckNvbmZpZywgc2V0dGluZ3M6IEZpbHRlclNldHRpbmcsIHJlc2V0PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IGZpbmRQZXJzb25Db250cm9sID0gdGhpcy5mb3JtID8gdGhpcy5mb3JtLmdldCgnZmluZFBlcnNvbkNvbnRyb2wnKSA6IG51bGw7XG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7fSk7XG4gICAgaWYgKGZpbmRQZXJzb25Db250cm9sKSB7XG4gICAgICAvLyBpbiBvcmRlciB0byBtYWludGFpbiBmaW5kIHBlcnNvbiBjb21wb25lbnQsIGNvbnRyb2wgbmVlZHMgdG8gYmUga2VwdFxuICAgICAgdGhpcy5mb3JtLmFkZENvbnRyb2woJ2ZpbmRQZXJzb25Db250cm9sJywgZmluZFBlcnNvbkNvbnRyb2wpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGNvbmZpZy5maWVsZHMpIHtcbiAgICAgIGlmIChmaWVsZC50eXBlID09PSAnY2hlY2tib3gnIHx8IGZpZWxkLnR5cGUgPT09ICdjaGVja2JveC1sYXJnZScpIHtcbiAgICAgICAgY29uc3QgZm9ybUFycmF5ID0gdGhpcy5idWlsZENoZWNrQm94Rm9ybUFycmF5KGZpZWxkLCBzZXR0aW5ncyk7XG4gICAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKGZpZWxkLm5hbWUsIGZvcm1BcnJheSk7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkLnR5cGUgPT09ICdmaW5kLWxvY2F0aW9uJykge1xuICAgICAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmJ1aWxkRmluZExvY2F0aW9uRm9ybUFycmF5KGZpZWxkLCBzZXR0aW5ncyk7XG4gICAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKGZpZWxkLm5hbWUsIGZvcm1BcnJheSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gW107XG4gICAgICAgIGlmIChmaWVsZC5taW5TZWxlY3RlZCAmJiBmaWVsZC5taW5TZWxlY3RlZCA+IDApIHtcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGRlZmF1bHRWYWx1ZTogYW55ID0gbnVsbDtcbiAgICAgICAgaWYgKHJlc2V0ICYmIGNvbmZpZy5jYW5jZWxTZXR0aW5nKSB7XG4gICAgICAgICAgY29uc3QgY2FuY2VsRmllbGQgPSBjb25maWcuY2FuY2VsU2V0dGluZy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZC5uYW1lKTtcbiAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBjYW5jZWxGaWVsZCAmJiBjYW5jZWxGaWVsZC52YWx1ZSA/IGNhbmNlbEZpZWxkLnZhbHVlWzBdIDogJyc7XG4gICAgICAgIH0gZWxzZSBpZiAoc2V0dGluZ3MgJiYgc2V0dGluZ3MuZmllbGRzKSB7XG4gICAgICAgICAgY29uc3QgbGFzdFNhdmVkVmFsdWUgPSBzZXR0aW5ncy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZC5uYW1lKTtcbiAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBsYXN0U2F2ZWRWYWx1ZSAmJiBsYXN0U2F2ZWRWYWx1ZSA/IGxhc3RTYXZlZFZhbHVlLnZhbHVlWzBdIDogJyc7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgZmllbGQgaXMgZmluZC1wZXJzb24gYnVpbGQgYSBmb3JtIGdyb3VwO1xuICAgICAgICBpZiAoZmllbGQudHlwZSA9PT0gJ2ZpbmQtcGVyc29uJykge1xuICAgICAgICAgIGNvbnN0IGZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe1xuICAgICAgICAgICAgZG9tYWluOiBuZXcgRm9ybUNvbnRyb2woJycpLFxuICAgICAgICAgICAgZW1haWw6IG5ldyBGb3JtQ29udHJvbChkZWZhdWx0VmFsdWUgJiYgZGVmYXVsdFZhbHVlLmhhc093blByb3BlcnR5KCdlbWFpbCcpID8gZGVmYXVsdFZhbHVlLmVtYWlsIDogJycsIHZhbGlkYXRvcnMpLFxuICAgICAgICAgICAgaWQ6IG5ldyBGb3JtQ29udHJvbCgnJyksXG4gICAgICAgICAgICBuYW1lOiBuZXcgRm9ybUNvbnRyb2woJycpLFxuICAgICAgICAgICAga25vd25BczogbmV3IEZvcm1Db250cm9sKCcnKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbChmaWVsZC5uYW1lLCBmb3JtR3JvdXApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woZGVmYXVsdFZhbHVlLCB2YWxpZGF0b3JzKTtcbiAgICAgICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbChmaWVsZC5uYW1lLCBjb250cm9sKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIGZpZWxkIHVwZGF0ZXMgZmluZCBwZXJzb24gY29tcG9uZW50IHNldCB0aGUgaW5pdGlhbCBkb21haW5cbiAgICAgICAgaWYgKGZpZWxkLmZpbmRQZXJzb25GaWVsZCkge1xuICAgICAgICAgIHRoaXMuZmllbGRDaGFuZ2VkKGZpZWxkLCB0aGlzLmZvcm0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZENoZWNrQm94Rm9ybUFycmF5KGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZywgc2V0dGluZ3M6IEZpbHRlclNldHRpbmcpOiBGb3JtQXJyYXkge1xuICAgIGNvbnN0IHZhbGlkYXRvcnMgPSBHZW5lcmljRmlsdGVyQ29tcG9uZW50LmFkZEZvcm1WYWxpZGF0b3JzKGZpZWxkKTtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmZiLmFycmF5KFtdLCB2YWxpZGF0b3JzKTtcbiAgICBsZXQgZGVmYXVsdFZhbHVlcztcbiAgICBpZiAoc2V0dGluZ3MgJiYgc2V0dGluZ3MuZmllbGRzKSB7XG4gICAgICBkZWZhdWx0VmFsdWVzID0gc2V0dGluZ3MuZmllbGRzLmZpbmQoKGYpID0+IGYubmFtZSA9PT0gZmllbGQubmFtZSk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnMpIHtcbiAgICAgIGxldCBjaGVja2VkID0gZmFsc2U7XG4gICAgICBpZiAoZGVmYXVsdFZhbHVlcyAmJiBBcnJheS5pc0FycmF5KGRlZmF1bHRWYWx1ZXMudmFsdWUpKSB7XG4gICAgICAgIGNoZWNrZWQgPSAhIWRlZmF1bHRWYWx1ZXMudmFsdWUuZmluZCgodmFsdWUpID0+IHZhbHVlID09PSBvcHRpb24ua2V5KTtcbiAgICAgIH1cbiAgICAgIGZvcm1BcnJheS5wdXNoKG5ldyBGb3JtQ29udHJvbChjaGVja2VkKSk7XG4gICAgfVxuICAgIHJldHVybiBmb3JtQXJyYXk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRmluZExvY2F0aW9uRm9ybUFycmF5KGZpZWxkOiBGaWx0ZXJGaWVsZENvbmZpZywgc2V0dGluZ3M6IEZpbHRlclNldHRpbmcpOiBGb3JtQXJyYXkge1xuICAgIGNvbnN0IHZhbGlkYXRvcnMgPSBHZW5lcmljRmlsdGVyQ29tcG9uZW50LmFkZEZvcm1WYWxpZGF0b3JzKGZpZWxkKTtcbiAgICBjb25zdCBmb3JtQXJyYXkgPSB0aGlzLmZiLmFycmF5KFtdLCB2YWxpZGF0b3JzKTtcbiAgICBsZXQgZGVmYXVsdFZhbHVlczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBhbnlbXSB9O1xuICAgIGlmIChzZXR0aW5ncyAmJiBzZXR0aW5ncy5maWVsZHMpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZXMgPSBzZXR0aW5ncy5maWVsZHMuZmluZCgoZikgPT4gZi5uYW1lID09PSBmaWVsZC5uYW1lKTtcbiAgICAgIGlmIChkZWZhdWx0VmFsdWVzICYmIGRlZmF1bHRWYWx1ZXMudmFsdWUgJiYgZGVmYXVsdFZhbHVlcy52YWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGVmYXVsdFZhbHVlIG9mIGRlZmF1bHRWYWx1ZXMudmFsdWUpIHtcbiAgICAgICAgICBmb3JtQXJyYXkucHVzaChuZXcgRm9ybUNvbnRyb2woZGVmYXVsdFZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvcm1BcnJheTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2VsZWN0ZWRWYWx1ZXMoZm9ybVZhbHVlczogYW55LCBjb25maWc6IEZpbHRlckNvbmZpZyk6IGFueSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGZvcm1WYWx1ZXMpLm1hcCgobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBmb3JtVmFsdWVzW25hbWVdO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xuICAgICAgICBjb25zdCBmaWVsZCA9IGNvbmZpZy5maWVsZHMuZmluZChmID0+IGYubmFtZSA9PT0gbmFtZSk7XG4gICAgICAgIGlmIChmaWVsZC50eXBlID09PSAnZmluZC1sb2NhdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4ge3ZhbHVlOiB2YWx1ZXMsIG5hbWV9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7dmFsdWU6IGdldFZhbHVlcyhmaWVsZC5vcHRpb25zLCB2YWx1ZXMpLCBuYW1lfTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHt2YWx1ZTogW3ZhbHVlc10sIG5hbWV9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Rm9ybUVycm9ycyhmb3JtOiBGb3JtR3JvdXApOiB2b2lkIHtcbiAgICBjb25zdCBlcnJvcnM6IEZpbHRlckVycm9yW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRoaXMuY29uZmlnLmZpZWxkcykge1xuICAgICAgY29uc3QgZm9ybUdyb3VwID0gZm9ybS5nZXQoZmllbGQubmFtZSk7XG4gICAgICBpZiAoZm9ybUdyb3VwICYmIGZvcm1Hcm91cC5lcnJvcnMgJiYgZm9ybUdyb3VwLmVycm9ycy5taW5MZW5ndGgpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goe25hbWU6IGZpZWxkLm5hbWUsIGVycm9yOiBmaWVsZC5taW5TZWxlY3RlZEVycm9yfSk7XG4gICAgICB9XG4gICAgICBpZiAoZm9ybUdyb3VwICYmIGZvcm1Hcm91cC5lcnJvcnMgJiYgZm9ybUdyb3VwLmVycm9ycy5tYXhMZW5ndGgpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goe25hbWU6IGZpZWxkLm5hbWUsIGVycm9yOiBmaWVsZC5taW5TZWxlY3RlZEVycm9yfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcnMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmZpbHRlclNlcnZpY2UuZ2l2ZW5FcnJvcnMubmV4dChlcnJvcnMpO1xuICAgIH1cbiAgfVxufVxuIl19