@snabcentr/client-ui 4.21.0 → 4.23.0

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 (104) hide show
  1. package/alerts/confirm-alert/sc-confirm-alert.component.d.ts +22 -0
  2. package/alerts/index.d.ts +1 -0
  3. package/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.d.ts +1 -1
  4. package/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.d.ts +3 -3
  5. package/catalog/input-quantity/sc-input-quantity.component.d.ts +17 -1
  6. package/esm2022/alerts/confirm-alert/sc-confirm-alert.component.mjs +29 -0
  7. package/esm2022/alerts/index.mjs +2 -0
  8. package/esm2022/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.mjs +4 -3
  9. package/esm2022/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.mjs +5 -16
  10. package/esm2022/catalog/input-quantity/sc-input-quantity.component.mjs +24 -4
  11. package/esm2022/feedback/feedback-form/sc-feedback-form.component.mjs +21 -11
  12. package/esm2022/helpers/sc-api-error-helper.mjs +25 -0
  13. package/esm2022/helpers/sc-file-helper.mjs +29 -0
  14. package/esm2022/order/draft/helpers/sc-draft-list-helper.mjs +83 -0
  15. package/esm2022/order/draft/models/sc-i-draft-list-item.mjs +2 -0
  16. package/esm2022/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.mjs +73 -0
  17. package/esm2022/order/draft/profstroy/badge/sc-profstroy-badge.component.mjs +21 -0
  18. package/esm2022/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.mjs +31 -0
  19. package/esm2022/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.mjs +139 -0
  20. package/esm2022/order/draft/profstroy/enums/sc-profstroy-draft-state.mjs +32 -0
  21. package/esm2022/order/draft/profstroy/helpers/sc-profstroy-draft-helper.mjs +94 -0
  22. package/esm2022/order/draft/profstroy/index.mjs +8 -0
  23. package/esm2022/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.mjs +2 -0
  24. package/esm2022/order/draft/sc-draft.component.mjs +148 -14
  25. package/esm2022/order/draft/services/sc-draft-expiration-clock.service.mjs +42 -0
  26. package/esm2022/order/draft/services/sc-draft-list-updates.service.mjs +288 -0
  27. package/esm2022/order/index.mjs +6 -1
  28. package/esm2022/order/new-order-items/sc-new-order-items.component.mjs +11 -3
  29. package/esm2022/order/order-form/sc-order-form.component.mjs +4 -2
  30. package/esm2022/order/order-item/sc-order-item.component.mjs +37 -5
  31. package/esm2022/order/order-items-list/sc-order-items-list.component.mjs +254 -47
  32. package/esm2022/order/order-items-list-by-stock/sc-order-items-list-by-stock.component.mjs +1 -1
  33. package/esm2022/order/order-items-list-with-actions/sc-order-items-list-with-actions.component.mjs +15 -3
  34. package/esm2022/pipes/sc-format-date.mjs +1 -1
  35. package/esm2022/providers/cleanup-recaptcha-artifacts.mjs +30 -0
  36. package/esm2022/providers/index.mjs +2 -1
  37. package/esm2022/providers/sc-date-formatter.mjs +1 -1
  38. package/esm2022/public-api.mjs +2 -2
  39. package/esm2022/samples/sc-sample.module.mjs +10 -3
  40. package/esm2022/services/index.mjs +1 -2
  41. package/feedback/feedback-form/sc-feedback-form.component.d.ts +1 -1
  42. package/fesm2022/snabcentr-client-ui.mjs +1399 -477
  43. package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
  44. package/helpers/sc-api-error-helper.d.ts +18 -0
  45. package/helpers/sc-file-helper.d.ts +13 -0
  46. package/order/draft/helpers/sc-draft-list-helper.d.ts +51 -0
  47. package/order/draft/models/sc-i-draft-list-item.d.ts +14 -0
  48. package/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.d.ts +58 -0
  49. package/order/draft/profstroy/badge/sc-profstroy-badge.component.d.ts +12 -0
  50. package/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.d.ts +21 -0
  51. package/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.d.ts +65 -0
  52. package/order/draft/profstroy/enums/sc-profstroy-draft-state.d.ts +29 -0
  53. package/order/draft/profstroy/helpers/sc-profstroy-draft-helper.d.ts +33 -0
  54. package/order/draft/profstroy/index.d.ts +7 -0
  55. package/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.d.ts +17 -0
  56. package/order/draft/sc-draft.component.d.ts +73 -1
  57. package/order/draft/services/sc-draft-expiration-clock.service.d.ts +29 -0
  58. package/order/draft/services/sc-draft-list-updates.service.d.ts +158 -0
  59. package/order/index.d.ts +5 -0
  60. package/order/new-order-items/sc-new-order-items.component.d.ts +9 -1
  61. package/order/order-form/sc-order-form.component.d.ts +1 -0
  62. package/order/order-item/sc-order-item.component.d.ts +25 -1
  63. package/order/order-items-list/sc-order-items-list.component.d.ts +132 -9
  64. package/order/order-items-list-with-actions/sc-order-items-list-with-actions.component.d.ts +13 -1
  65. package/package.json +3 -2
  66. package/pipes/sc-format-date.d.ts +1 -1
  67. package/providers/cleanup-recaptcha-artifacts.d.ts +7 -0
  68. package/providers/index.d.ts +1 -0
  69. package/providers/sc-date-formatter.d.ts +1 -1
  70. package/public-api.d.ts +1 -1
  71. package/release_notes.tmp +6 -7
  72. package/samples/sc-sample.module.d.ts +2 -1
  73. package/services/index.d.ts +0 -1
  74. package/styles/tailwind/tailwind.scss +43 -40
  75. package/esm2022/services/sc-scripts.service.mjs +0 -106
  76. package/esm2022/smart-captcha/index.mjs +0 -5
  77. package/esm2022/smart-captcha/interfaces/index.mjs +0 -6
  78. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-api.mjs +0 -2
  79. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-event.mjs +0 -2
  80. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-language.mjs +0 -2
  81. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-render-params.mjs +0 -2
  82. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-settings.mjs +0 -2
  83. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-window.mjs +0 -2
  84. package/esm2022/smart-captcha/sc-smart-captcha.component.mjs +0 -167
  85. package/esm2022/smart-captcha/services/index.mjs +0 -2
  86. package/esm2022/smart-captcha/services/sc-smart-captcha-loader.service.mjs +0 -87
  87. package/esm2022/smart-captcha/tokens/index.mjs +0 -3
  88. package/esm2022/smart-captcha/tokens/sc-smart-captcha-load-timeout.token.mjs +0 -8
  89. package/esm2022/smart-captcha/tokens/sc-smart-captcha-settings.token.mjs +0 -6
  90. package/services/sc-scripts.service.d.ts +0 -51
  91. package/smart-captcha/index.d.ts +0 -4
  92. package/smart-captcha/interfaces/index.d.ts +0 -5
  93. package/smart-captcha/interfaces/sc-smart-captcha-api.d.ts +0 -36
  94. package/smart-captcha/interfaces/sc-smart-captcha-event.d.ts +0 -4
  95. package/smart-captcha/interfaces/sc-smart-captcha-language.d.ts +0 -4
  96. package/smart-captcha/interfaces/sc-smart-captcha-render-params.d.ts +0 -16
  97. package/smart-captcha/interfaces/sc-smart-captcha-settings.d.ts +0 -16
  98. package/smart-captcha/interfaces/sc-smart-captcha-window.d.ts +0 -14
  99. package/smart-captcha/sc-smart-captcha.component.d.ts +0 -92
  100. package/smart-captcha/services/index.d.ts +0 -1
  101. package/smart-captcha/services/sc-smart-captcha-loader.service.d.ts +0 -50
  102. package/smart-captcha/tokens/index.d.ts +0 -2
  103. package/smart-captcha/tokens/sc-smart-captcha-load-timeout.token.d.ts +0 -5
  104. package/smart-captcha/tokens/sc-smart-captcha-settings.token.d.ts +0 -6
@@ -1,13 +1,13 @@
1
1
  /* eslint-disable no-param-reassign */
2
2
  import { AsyncPipe } from '@angular/common';
3
- import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, Input, input, signal } from '@angular/core';
3
+ import { ChangeDetectionStrategy, Component, computed, DestroyRef, effect, inject, Input, input, signal, untracked } from '@angular/core';
4
4
  import { outputFromObservable, takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
5
5
  import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
6
- import { SC_ORDER_LOADER, ScNumberHelper, ScUnitsHelper } from '@snabcentr/client-core';
6
+ import { SC_ORDER_LOADER, ScNumberHelper, ScOrderItem, ScOrderItemsGroup, ScUnitsHelper } from '@snabcentr/client-core';
7
7
  import { TuiCurrencyPipe } from '@taiga-ui/addon-commerce';
8
- import { TuiButton, TuiFormatNumberPipe, TuiLabel } from '@taiga-ui/core';
9
- import { TuiButtonLoading, TuiCheckbox } from '@taiga-ui/kit';
10
- import { catchError, finalize, map, of } from 'rxjs';
8
+ import { TuiAlertService, TuiButton, TuiDialogService, TuiFormatNumberPipe, TuiLabel } from '@taiga-ui/core';
9
+ import { TUI_CONFIRM, TuiButtonLoading, TuiCheckbox } from '@taiga-ui/kit';
10
+ import { EMPTY, filter, finalize, map, noop, of, switchMap } from 'rxjs';
11
11
  import { ScPrintDirective } from '../../directives';
12
12
  import { SC_DIALOG_SERVICE_TOKEN } from '../../providers';
13
13
  import { SC_ORDER_OPTIONS } from '../directives/sc-order-options';
@@ -18,6 +18,29 @@ import * as i1 from "@angular/forms";
18
18
  * Компонент списка товаров корзины, заказа или черновика.
19
19
  */
20
20
  export class ScOrderItemsListComponent {
21
+ /**
22
+ * Возвращает копию набора с добавленными или убранными ключами.
23
+ *
24
+ * @param keys Набор.
25
+ * @param changed Ключи.
26
+ * @param isIncluded Признак добавления.
27
+ */
28
+ static withKeys(keys, changed, isIncluded) {
29
+ const next = new Set(keys);
30
+ changed.forEach((key) => {
31
+ if (isIncluded) {
32
+ next.add(key);
33
+ }
34
+ else {
35
+ next.delete(key);
36
+ }
37
+ });
38
+ return next;
39
+ }
40
+ /**
41
+ * Инициализирует экземпляр класса {@link ScOrderItemsListComponent}.
42
+ * Входы выбора и пометки недоступных позиций могут прийти после списка позиций, поэтому при их изменении выбор синхронизируется заново.
43
+ */
21
44
  constructor() {
22
45
  /**
23
46
  * Внутренний сигнал списка элементов корзины (товаров).
@@ -31,6 +54,56 @@ export class ScOrderItemsListComponent {
31
54
  * Включить редактирование позиций.
32
55
  */
33
56
  this.editable = input(false);
57
+ /**
58
+ * Признак вывода позиций по группам (группа позиции или «Без группы») с заголовками и итогами. Без признака позиции выводятся одним списком без заголовков.
59
+ */
60
+ this.grouped = input(false);
61
+ /**
62
+ * Признак, что позиции, которые не попадут в заказ, помечаются примечанием и не выбираются. Неактивные позиции приглушаются и зачёркиваются.
63
+ */
64
+ this.markUnavailable = input(false);
65
+ /**
66
+ * Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
67
+ */
68
+ this.useLinePrice = input(false);
69
+ /**
70
+ * Признак, что параметры позиции меняются в диалоге товара: диалог доступен у любой активной позиции, а количество и метраж измеряемых товаров
71
+ * меняются только в нём, даже если метраж ещё не задан.
72
+ */
73
+ this.measuredInDialog = input(false);
74
+ /**
75
+ * Откуда удаляется позиция для текста подтверждения, например «из черновика». Если не задано, позиция удаляется без подтверждения.
76
+ * Тот же текст используется в предупреждении о нулевом количестве.
77
+ */
78
+ this.deleteConfirmationTarget = input(null);
79
+ /**
80
+ * Подпись итоговой суммы.
81
+ */
82
+ this.totalLabel = input('Итого');
83
+ /**
84
+ * Позиции, разбитые на группы. Без группировки все позиции идут одной группой без заголовка.
85
+ */
86
+ this.groups = computed(() => {
87
+ const items = this.itemsSignal();
88
+ return this.grouped() ? ScOrderItemsGroup.fromItems(items) : [new ScOrderItemsGroup('', items)];
89
+ });
90
+ /**
91
+ * Идентификаторы позиций, изменение или удаление которых ждёт очереди или выполняется.
92
+ */
93
+ this.pendingItemsIds = signal(new Set());
94
+ /**
95
+ * Названия удаляемых групп.
96
+ */
97
+ this.deletingGroupsNames = signal(new Set());
98
+ /**
99
+ * Названия групп с позициями, ждущими ответа: такие группы удалить нельзя.
100
+ */
101
+ this.pendingGroupsNames = computed(() => {
102
+ const pendingIds = this.pendingItemsIds();
103
+ return new Set(this.groups()
104
+ .filter((group) => group.items.some((item) => pendingIds.has(item.id)))
105
+ .map((group) => group.name));
106
+ });
34
107
  /**
35
108
  * Внутренняя группа формы для выбора позиций.
36
109
  */
@@ -46,11 +119,12 @@ export class ScOrderItemsListComponent {
46
119
  initialValue: [],
47
120
  });
48
121
  /**
49
- * Состояние флага «Выбрать все»: `true`, если выбраны все позиции, `false`, если ни одной, и `null`, если только часть.
122
+ * Состояние флага «Выбрать все»: `true`, если выбраны все доступные для выбора позиции, `false`, если ни одной или выбирать нечего,
123
+ * и `null`, если только часть.
50
124
  */
51
125
  this.allItemsSelected = computed(() => {
52
126
  const checkedList = this.itemsIds().map(([, checked]) => checked);
53
- if (checkedList.every(Boolean)) {
127
+ if (checkedList.length > 0 && checkedList.every(Boolean)) {
54
128
  return true;
55
129
  }
56
130
  return checkedList.some(Boolean) ? null : false;
@@ -75,7 +149,7 @@ export class ScOrderItemsListComponent {
75
149
  const items = this.itemsSignal();
76
150
  const selectedItemsIds = this.selectedItemsIds();
77
151
  const selectable = this.selectable();
78
- return ScNumberHelper.roundMoney(items.filter((item) => !selectable || selectedItemsIds.includes(item.id)).reduce((sum, item) => sum + item.costRub, 0));
152
+ return ScOrderItem.getCostSum(items.filter((item) => !selectable || selectedItemsIds.includes(item.id)));
79
153
  });
80
154
  /**
81
155
  * Сервис получения и редактирования списка товаров заказа (корзина / заказ / черновик = заказ).
@@ -86,6 +160,10 @@ export class ScOrderItemsListComponent {
86
160
  * Признак, что можно редактировать позиции.
87
161
  */
88
162
  this.canEdit = computed(() => this.editable() && 'updateProduct$' in this.orderItemsListLoader);
163
+ /**
164
+ * Признак, что группу можно удалить целиком.
165
+ */
166
+ this.canDeleteGroups = computed(() => this.canEdit() && 'deleteProducts$' in this.orderItemsListLoader);
89
167
  /**
90
168
  * Настройки вывода сумм в рублях.
91
169
  */
@@ -99,6 +177,21 @@ export class ScOrderItemsListComponent {
99
177
  * Предоставляется родителем через токен {@link SC_DIALOG_SERVICE_TOKEN}.
100
178
  */
101
179
  this.scDialogService = inject(SC_DIALOG_SERVICE_TOKEN);
180
+ /**
181
+ * Сервис диалоговых окон Taiga для подтверждений.
182
+ */
183
+ this.dialogService = inject(TuiDialogService);
184
+ /**
185
+ * Сервис уведомлений.
186
+ */
187
+ this.alerts = inject(TuiAlertService);
188
+ effect(() => {
189
+ this.markUnavailable();
190
+ this.selectable();
191
+ untracked(() => {
192
+ this.syncSelectionControls();
193
+ });
194
+ });
102
195
  }
103
196
  /**
104
197
  * Список элементов корзины (товаров). При установке синхронно обновляет контролы выбора в форме.
@@ -109,6 +202,7 @@ export class ScOrderItemsListComponent {
109
202
  }
110
203
  /**
111
204
  * Синхронизирует контролы формы выбора с текущим списком товаров: удаляет контролы для отсутствующих id, добавляет для новых.
205
+ * Контролы меняются без событий, а значение группы пересчитывается один раз в конце: на заявках в сотни позиций это заметно.
112
206
  */
113
207
  syncSelectionControls() {
114
208
  if (!this.selectable()) {
@@ -118,70 +212,125 @@ export class ScOrderItemsListComponent {
118
212
  const currentIds = new Set(currentItems.map((item) => item.id));
119
213
  Object.keys(this.selectionFormGroup.controls).forEach((name) => {
120
214
  if (!currentIds.has(name)) {
121
- this.selectionFormGroup.removeControl(name);
215
+ this.selectionFormGroup.removeControl(name, { emitEvent: false });
122
216
  }
123
217
  });
124
218
  currentItems.forEach((item) => {
125
- if (!this.selectionFormGroup.contains(item.id)) {
126
- this.selectionFormGroup.addControl(item.id, new FormControl(true, { nonNullable: true }));
219
+ const control = this.selectionFormGroup.get(item.id);
220
+ const isSelectable = !this.markUnavailable() || item.isOrderable;
221
+ if (!control) {
222
+ this.selectionFormGroup.addControl(item.id, new FormControl({ value: isSelectable, disabled: !isSelectable }, { nonNullable: true }), { emitEvent: false });
223
+ }
224
+ else if (!isSelectable && control.enabled) {
225
+ control.setValue(false, { emitEvent: false });
226
+ control.disable({ emitEvent: false });
227
+ }
228
+ else if (isSelectable && control.disabled) {
229
+ control.enable({ emitEvent: false });
230
+ control.setValue(true, { emitEvent: false });
127
231
  }
128
232
  });
233
+ this.selectionFormGroup.updateValueAndValidity();
129
234
  }
130
235
  /**
131
- * Выбирает все позиции или снимает выбор со всех.
236
+ * Выбирает все доступные для выбора позиции или снимает выбор со всех.
132
237
  *
133
238
  * @param event Событие изменения флага выбора всех позиций.
134
239
  */
135
240
  selectAllChangeHandler(event) {
136
241
  const { checked } = event.target;
137
- this.selectionFormGroup.setValue(Object.fromEntries(Object.keys(this.selectionFormGroup.controls).map((id) => [id, checked])));
242
+ const enabledIds = Object.entries(this.selectionFormGroup.controls)
243
+ .filter(([, control]) => control.enabled)
244
+ .map(([id]) => id);
245
+ this.selectionFormGroup.patchValue(Object.fromEntries(enabledIds.map((id) => [id, checked])));
246
+ }
247
+ /**
248
+ * Возвращает признак, что позиция приглушена: она неактивна или не выбрана для заказа.
249
+ *
250
+ * @param item Позиция.
251
+ */
252
+ isItemDimmed(item) {
253
+ const isUnselected = this.selectable() && !this.selectionFormGroup.get(item.id)?.value;
254
+ return this.markUnavailable() ? item.isInactive || (item.isOrderable && isUnselected) : isUnselected;
255
+ }
256
+ /**
257
+ * Возвращает признак, что количество и метраж товара позиции меняются в диалоге товара.
258
+ *
259
+ * @param item Позиция.
260
+ */
261
+ isEditedInDialog(item) {
262
+ return this.measuredInDialog() && ScUnitsHelper.productIsMeasurable(item.product);
138
263
  }
139
264
  /**
140
- * Удаляет позицию.
265
+ * Удаляет позицию, при необходимости после подтверждения. Сообщение об ошибке показывает перехватчик приложения.
141
266
  *
142
267
  * @param item Позиция товара для удаления.
143
- * @param priceCard Компонент карточки товара.
144
268
  */
145
- deleteItem(item, priceCard) {
146
- if (!this.canEdit()) {
269
+ deleteItem(item) {
270
+ if (!this.canEdit() || this.pendingItemsIds().has(item.id)) {
147
271
  return;
148
272
  }
149
- priceCard.showLoader.set(true);
150
- this.orderItemsListLoader
151
- .deleteProduct$(item, this.orderOptions?.orderId())
152
- .pipe(catchError(() => {
153
- priceCard.quantityControl.patchValue(item.quantity, {
154
- emitEvent: false,
155
- });
156
- return of();
157
- }), finalize(() => {
158
- priceCard.showLoader.set(false);
273
+ this.confirmDelete$(item)
274
+ .pipe(switchMap(() => {
275
+ this.setItemPending(item.id, true);
276
+ return this.orderItemsListLoader.deleteProduct$(item, this.orderOptions?.orderId()).pipe(finalize(() => {
277
+ this.setItemPending(item.id, false);
278
+ }));
159
279
  }), takeUntilDestroyed(this.destroyRef))
160
- .subscribe();
280
+ .subscribe({ error: noop });
161
281
  }
162
282
  /**
163
- * Обновляет количество товара.
283
+ * Удаляет все позиции группы после подтверждения. Состав берётся на момент подтверждения.
284
+ *
285
+ * @param group Группа позиций.
286
+ */
287
+ deleteGroup(group) {
288
+ if (!this.canDeleteGroups() || this.pendingGroupsNames().has(group.name)) {
289
+ return;
290
+ }
291
+ this.confirmGroupDelete$(group)
292
+ .pipe(switchMap(() => {
293
+ const items = this.groups().find(({ name }) => name === group.name)?.items ?? [];
294
+ const ids = items.map((item) => item.id);
295
+ if (ids.length === 0) {
296
+ return EMPTY;
297
+ }
298
+ this.setItemsPending(ids, true);
299
+ this.deletingGroupsNames.update((names) => ScOrderItemsListComponent.withKeys(names, [group.name], true));
300
+ return this.orderItemsListLoader.deleteProducts$(items, this.orderOptions?.orderId()).pipe(finalize(() => {
301
+ this.setItemsPending(ids, false);
302
+ this.deletingGroupsNames.update((names) => ScOrderItemsListComponent.withKeys(names, [group.name], false));
303
+ }));
304
+ }), takeUntilDestroyed(this.destroyRef))
305
+ .subscribe({ error: noop });
306
+ }
307
+ /**
308
+ * Обновляет количество товара. Количество неактивной позиции не меняется. Пустое или нулевое значение возвращается к сохранённому количеству.
164
309
  *
165
310
  * @param newQuantity Новое значение количества товара.
166
311
  * @param priceCard Компонент карточки товара.
167
312
  */
168
313
  patchItem(newQuantity, priceCard) {
169
- if (!this.canEdit() || !priceCard.orderItem || !priceCard.product || !newQuantity) {
314
+ const { orderItem } = priceCard;
315
+ if (!this.canEdit() || !orderItem || !priceCard.product || orderItem.isInactive) {
316
+ return;
317
+ }
318
+ if (!newQuantity) {
319
+ priceCard.quantityControl.patchValue(orderItem.quantity, { emitEvent: false });
320
+ this.warnEmptyQuantity();
170
321
  return;
171
322
  }
172
- priceCard.showLoader.set(true);
323
+ this.setItemPending(orderItem.id, true);
173
324
  this.orderItemsListLoader
174
- .updateProduct$(priceCard.orderItem.id, { quantity: newQuantity }, this.orderOptions?.orderId())
175
- .pipe(catchError(() => {
176
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
177
- priceCard.quantityControl.patchValue(priceCard.orderItem.quantity, {
178
- emitEvent: false,
179
- });
180
- return of();
181
- }), finalize(() => {
182
- priceCard.showLoader.set(false);
325
+ .updateProduct$(orderItem.id, { quantity: newQuantity }, this.orderOptions?.orderId())
326
+ .pipe(finalize(() => {
327
+ this.setItemPending(orderItem.id, false);
183
328
  }), takeUntilDestroyed(this.destroyRef))
184
- .subscribe();
329
+ .subscribe({
330
+ error: () => {
331
+ priceCard.quantityControl.patchValue((priceCard.orderItem ?? orderItem).quantity, { emitEvent: false });
332
+ },
333
+ });
185
334
  }
186
335
  /**
187
336
  * Открывает модальное окно описания товара.
@@ -196,7 +345,7 @@ export class ScOrderItemsListComponent {
196
345
  }
197
346
  }
198
347
  /**
199
- * Открывает модальное окно изменения товара или его конфигуратора.
348
+ * Открывает модальное окно изменения товара или его конфигуратора. Если параметры позиции меняются в диалоге, окно товара открывается и у штучного товара.
200
349
  *
201
350
  * @param item Позиция товара.
202
351
  */
@@ -205,7 +354,7 @@ export class ScOrderItemsListComponent {
205
354
  if (isConfigurator) {
206
355
  this.scDialogService.openConfiguratorDialog(item.product, item, this.orderOptions?.orderId());
207
356
  }
208
- else if (ScUnitsHelper.productIsMeasurable(item.product)) {
357
+ else if (this.measuredInDialog() || ScUnitsHelper.productIsMeasurable(item.product)) {
209
358
  this.scDialogService.openAddOrEditingCartItemDialog(item.product, item, this.orderOptions?.orderId(), true);
210
359
  }
211
360
  }
@@ -217,8 +366,66 @@ export class ScOrderItemsListComponent {
217
366
  openPriceHistoryChartDialog(product) {
218
367
  this.scDialogService.openPriceHistoryChartDialog(product);
219
368
  }
369
+ /**
370
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление позиции подтверждено или подтверждение не требуется.
371
+ *
372
+ * @param item Удаляемая позиция.
373
+ */
374
+ confirmDelete$(item) {
375
+ const target = this.deleteConfirmationTarget();
376
+ if (!target) {
377
+ return of(true);
378
+ }
379
+ return this.confirmRemoval$(`Удалить позицию «${item.product.name}» ${target}?`);
380
+ }
381
+ /**
382
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление группы подтверждено.
383
+ *
384
+ * @param group Группа позиций.
385
+ */
386
+ confirmGroupDelete$(group) {
387
+ const target = this.deleteConfirmationTarget();
388
+ const source = target ? ` ${target}` : '';
389
+ return this.confirmRemoval$(`Удалить все позиции группы «${group.name}»${source}?`);
390
+ }
391
+ /**
392
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление подтверждено.
393
+ *
394
+ * @param label Вопрос.
395
+ */
396
+ confirmRemoval$(label) {
397
+ return this.dialogService.open(TUI_CONFIRM, { label, data: { yes: 'Да, удалить', no: 'Нет, оставить' } }).pipe(filter(Boolean));
398
+ }
399
+ /**
400
+ * Отмечает позицию как ожидающую ответа или снимает отметку.
401
+ *
402
+ * @param id Идентификатор позиции.
403
+ * @param isPending Признак ожидания.
404
+ */
405
+ setItemPending(id, isPending) {
406
+ this.setItemsPending([id], isPending);
407
+ }
408
+ /**
409
+ * Ставит или снимает отметку ожидания у позиций.
410
+ *
411
+ * @param itemsIds Идентификаторы позиций.
412
+ * @param isPending Признак ожидания.
413
+ */
414
+ setItemsPending(itemsIds, isPending) {
415
+ this.pendingItemsIds.update((ids) => ScOrderItemsListComponent.withKeys(ids, itemsIds, isPending));
416
+ }
417
+ /**
418
+ * Предупреждает, что количество не может быть пустым или нулевым, а убрать позицию можно удалением. Поле возвращается к сохранённому количеству
419
+ * в любом списке, предупреждение показывается только в списках с подтверждением удаления.
420
+ */
421
+ warnEmptyQuantity() {
422
+ const target = this.deleteConfirmationTarget();
423
+ if (target) {
424
+ this.alerts.open(`Количество должно быть больше нуля. Чтобы убрать позицию ${target}, удалите её.`, { appearance: 'warning' }).subscribe();
425
+ }
426
+ }
220
427
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
221
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListComponent, isStandalone: true, selector: "sc-order-items-list", inputs: { selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0424\u043B\u0430\u0433 \u0432\u044B\u0431\u043E\u0440\u0430 \u0432\u0441\u0435\u0445 \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (selectable() && itemsSignal().length) {\n <label\n tuiLabel\n scPrint=\"defaultNoPrint\"\n class=\"self-start\"\n >\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [ngModel]=\"allItemsSelected()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (change)=\"selectAllChangeHandler($event)\"\n />\n \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435\n </label>\n }\n\n @for (item of itemsSignal(); track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value;\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n [disabled]=\"itemComponent.showLoader()\"\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator\"\n [isShowEditControls]=\"canEdit()\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"selectable() && !selectionFormGroup.get(item.id)?.value\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item, itemComponent)\"\n [loading]=\"itemComponent.showLoader()\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0441\u043F\u0438\u0441\u043A\u0430. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">\u0418\u0442\u043E\u0433\u043E: {{ totalSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TuiFormatNumberPipe, name: "tuiFormatNumber" }, { kind: "component", type: ScOrderItemComponent, selector: "sc-order-item", inputs: ["isShowEditControls"], outputs: ["clickSettings"] }, { kind: "directive", type: ScPrintDirective, selector: "[scPrint]", inputs: ["scPrint"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "pipe", type: TuiCurrencyPipe, name: "tuiCurrency" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListComponent, isStandalone: true, selector: "sc-order-items-list", inputs: { selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, grouped: { classPropertyName: "grouped", publicName: "grouped", isSignal: true, isRequired: false, transformFunction: null }, markUnavailable: { classPropertyName: "markUnavailable", publicName: "markUnavailable", isSignal: true, isRequired: false, transformFunction: null }, useLinePrice: { classPropertyName: "useLinePrice", publicName: "useLinePrice", isSignal: true, isRequired: false, transformFunction: null }, measuredInDialog: { classPropertyName: "measuredInDialog", publicName: "measuredInDialog", isSignal: true, isRequired: false, transformFunction: null }, deleteConfirmationTarget: { classPropertyName: "deleteConfirmationTarget", publicName: "deleteConfirmationTarget", isSignal: true, isRequired: false, transformFunction: null }, totalLabel: { classPropertyName: "totalLabel", publicName: "totalLabel", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0424\u043B\u0430\u0433 \u0432\u044B\u0431\u043E\u0440\u0430 \u0432\u0441\u0435\u0445 \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (selectable() && itemsSignal().length) {\n <label\n tuiLabel\n scPrint=\"defaultNoPrint\"\n class=\"self-start\"\n >\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [ngModel]=\"allItemsSelected()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"selectionFormGroup.disabled\"\n (change)=\"selectAllChangeHandler($event)\"\n />\n \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435\n </label>\n }\n\n @for (group of groups(); track group.name) {\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (group.name) {\n <div class=\"flex flex-wrap items-end justify-between gap-x-4 gap-y-1 border-b border-tui-base-03 pb-2\">\n <div class=\"flex min-w-0 flex-col\">\n <span class=\"break-words text-body-l-bold\">{{ group.name }}</span>\n <span class=\"text-body-s text-tui-text-02\">\u043F\u043E\u0437\u0438\u0446\u0438\u0439: {{ group.items.length }}, \u0432 \u0437\u0430\u043A\u0430\u0437: {{ group.orderableCount }}</span>\n </div>\n <div class=\"flex flex-col items-end gap-1\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0433\u0440\u0443\u043F\u043F\u044B. -->\n @if (canDeleteGroups()) {\n <button\n tuiButton\n type=\"button\"\n appearance=\"flat\"\n size=\"xs\"\n scPrint=\"defaultNoPrint\"\n [loading]=\"deletingGroupsNames().has(group.name)\"\n [disabled]=\"pendingGroupsNames().has(group.name)\"\n (click)=\"deleteGroup(group)\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C\n </button>\n }\n <span class=\"whitespace-nowrap text-body-m-bold\">{{ group.orderableSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</span>\n </div>\n </div>\n }\n\n @for (item of group.items; track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value || (markUnavailable() && !item.isOrderable);\n @let isPending = pendingItemsIds().has(item.id);\n @let editedInDialog = isEditedInDialog(item);\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator && !editedInDialog\"\n [isShowEditControls]=\"canEdit()\"\n [useLinePrice]=\"useLinePrice()\"\n [markUnavailable]=\"markUnavailable()\"\n [isPending]=\"isPending\"\n [settingsAvailable]=\"canEdit() && measuredInDialog() && !item.configurator && !item.isInactive\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"isItemDimmed(item)\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item)\"\n [loading]=\"isPending\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0441\u043F\u0438\u0441\u043A\u0430. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">{{ totalLabel() }}: {{ totalSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TuiFormatNumberPipe, name: "tuiFormatNumber" }, { kind: "component", type: ScOrderItemComponent, selector: "sc-order-item", inputs: ["isShowEditControls", "useLinePrice", "markUnavailable", "isPending", "settingsAvailable"], outputs: ["clickSettings"] }, { kind: "directive", type: ScPrintDirective, selector: "[scPrint]", inputs: ["scPrint"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "pipe", type: TuiCurrencyPipe, name: "tuiCurrency" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
222
429
  }
223
430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListComponent, decorators: [{
224
431
  type: Component,
@@ -234,9 +441,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
234
441
  TuiButton,
235
442
  TuiButtonLoading,
236
443
  TuiCurrencyPipe,
237
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0424\u043B\u0430\u0433 \u0432\u044B\u0431\u043E\u0440\u0430 \u0432\u0441\u0435\u0445 \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (selectable() && itemsSignal().length) {\n <label\n tuiLabel\n scPrint=\"defaultNoPrint\"\n class=\"self-start\"\n >\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [ngModel]=\"allItemsSelected()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (change)=\"selectAllChangeHandler($event)\"\n />\n \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435\n </label>\n }\n\n @for (item of itemsSignal(); track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value;\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n [disabled]=\"itemComponent.showLoader()\"\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator\"\n [isShowEditControls]=\"canEdit()\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"selectable() && !selectionFormGroup.get(item.id)?.value\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item, itemComponent)\"\n [loading]=\"itemComponent.showLoader()\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0441\u043F\u0438\u0441\u043A\u0430. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">\u0418\u0442\u043E\u0433\u043E: {{ totalSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n" }]
238
- }], propDecorators: { items: [{
444
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0424\u043B\u0430\u0433 \u0432\u044B\u0431\u043E\u0440\u0430 \u0432\u0441\u0435\u0445 \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (selectable() && itemsSignal().length) {\n <label\n tuiLabel\n scPrint=\"defaultNoPrint\"\n class=\"self-start\"\n >\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [ngModel]=\"allItemsSelected()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"selectionFormGroup.disabled\"\n (change)=\"selectAllChangeHandler($event)\"\n />\n \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435\n </label>\n }\n\n @for (group of groups(); track group.name) {\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (group.name) {\n <div class=\"flex flex-wrap items-end justify-between gap-x-4 gap-y-1 border-b border-tui-base-03 pb-2\">\n <div class=\"flex min-w-0 flex-col\">\n <span class=\"break-words text-body-l-bold\">{{ group.name }}</span>\n <span class=\"text-body-s text-tui-text-02\">\u043F\u043E\u0437\u0438\u0446\u0438\u0439: {{ group.items.length }}, \u0432 \u0437\u0430\u043A\u0430\u0437: {{ group.orderableCount }}</span>\n </div>\n <div class=\"flex flex-col items-end gap-1\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0433\u0440\u0443\u043F\u043F\u044B. -->\n @if (canDeleteGroups()) {\n <button\n tuiButton\n type=\"button\"\n appearance=\"flat\"\n size=\"xs\"\n scPrint=\"defaultNoPrint\"\n [loading]=\"deletingGroupsNames().has(group.name)\"\n [disabled]=\"pendingGroupsNames().has(group.name)\"\n (click)=\"deleteGroup(group)\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C\n </button>\n }\n <span class=\"whitespace-nowrap text-body-m-bold\">{{ group.orderableSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</span>\n </div>\n </div>\n }\n\n @for (item of group.items; track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value || (markUnavailable() && !item.isOrderable);\n @let isPending = pendingItemsIds().has(item.id);\n @let editedInDialog = isEditedInDialog(item);\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator && !editedInDialog\"\n [isShowEditControls]=\"canEdit()\"\n [useLinePrice]=\"useLinePrice()\"\n [markUnavailable]=\"markUnavailable()\"\n [isPending]=\"isPending\"\n [settingsAvailable]=\"canEdit() && measuredInDialog() && !item.configurator && !item.isInactive\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"isItemDimmed(item)\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item)\"\n [loading]=\"isPending\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0441\u043F\u0438\u0441\u043A\u0430. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">{{ totalLabel() }}: {{ totalSum | tuiFormatNumber: moneyFormat | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n" }]
445
+ }], ctorParameters: () => [], propDecorators: { items: [{
239
446
  type: Input,
240
447
  args: [{ required: true }]
241
448
  }] } });
242
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Mtb3JkZXItaXRlbXMtbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbGllbnQtdWkvb3JkZXIvb3JkZXItaXRlbXMtbGlzdC9zYy1vcmRlci1pdGVtcy1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NsaWVudC11aS9vcmRlci9vcmRlci1pdGVtcy1saXN0L3NjLW9yZGVyLWl0ZW1zLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZILE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUcsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUYsT0FBTyxFQUFFLGVBQWUsRUFBd0MsY0FBYyxFQUFlLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNJLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1B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RUQ7Ozs7T0FJRztJQUNPLDJCQUEyQixDQUFDLE9BQStCO1FBQ2pFLElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUQsQ0FBQzsrR0FwUFEseUJBQXlCO21HQUF6Qix5QkFBeUIsMGhCQ3ZDdEMsbWtIQW1GQSx1Q0QxRFEsU0FBUyx5Q0FDVCxtQkFBbUIsd0RBQ25CLG9CQUFvQixzSEFDcEIsZ0JBQWdCLDBFQUNoQixXQUFXLDJxQkFDWCxtQkFBbUIsZ1ZBQ25CLFdBQVcsb0dBQ1gsUUFBUSw0REFDUixTQUFTLG9JQUNULGdCQUFnQixrSEFDaEIsZUFBZTs7NEZBSVYseUJBQXlCO2tCQW5CckMsU0FBUztpQ0FDTSxJQUFJLFlBQ04scUJBQXFCLFdBRXRCO3dCQUNMLFNBQVM7d0JBQ1QsbUJBQW1CO3dCQUNuQixvQkFBb0I7d0JBQ3BCLGdCQUFnQjt3QkFDaEIsV0FBVzt3QkFDWCxtQkFBbUI7d0JBQ25CLFdBQVc7d0JBQ1gsUUFBUTt3QkFDUixTQUFTO3dCQUNULGdCQUFnQjt3QkFDaEIsZUFBZTtxQkFDbEIsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07OEJBNEczQyxLQUFLO3NCQURSLEtBQUs7dUJBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cblxuaW1wb3J0IHsgQXN5bmNQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGNvbXB1dGVkLCBEZXN0cm95UmVmLCBpbmplY3QsIElucHV0LCBpbnB1dCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBvdXRwdXRGcm9tT2JzZXJ2YWJsZSwgdGFrZVVudGlsRGVzdHJveWVkLCB0b09ic2VydmFibGUsIHRvU2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTQ19PUkRFUl9MT0FERVIsIFNjSU9yZGVyRWRpdG9yTG9hZGVyLCBTY0lPcmRlckxvYWRlciwgU2NOdW1iZXJIZWxwZXIsIFNjT3JkZXJJdGVtLCBTY1VuaXRzSGVscGVyIH0gZnJvbSAnQHNuYWJjZW50ci9jbGllbnQtY29yZSc7XG5pbXBvcnQgeyBUdWlDdXJyZW5jeVBpcGUgfSBmcm9tICdAdGFpZ2EtdWkvYWRkb24tY29tbWVyY2UnO1xuaW1wb3J0IHsgVHVpQnV0dG9uLCBUdWlGb3JtYXROdW1iZXJQaXBlLCBUdWlMYWJlbCB9IGZyb20gJ0B0YWlnYS11aS9jb3JlJztcbmltcG9ydCB7IFR1aUJ1dHRvbkxvYWRpbmcsIFR1aUNoZWNrYm94IH0gZnJvbSAnQHRhaWdhLXVpL2tpdCc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaW5hbGl6ZSwgbWFwLCBvZiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBBYnN0cmFjdFNjUHJpY2VDYXJkLCBTY1ByaW50RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcyc7XG5pbXBvcnQgeyBJU2NEaWFsb2dTZXJ2aWNlLCBTQ19ESUFMT0dfU0VSVklDRV9UT0tFTiB9IGZyb20gJy4uLy4uL3Byb3ZpZGVycyc7XG5pbXBvcnQgeyBTQ19PUkRFUl9PUFRJT05TLCBTY09yZGVyT3B0aW9ucyB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvc2Mtb3JkZXItb3B0aW9ucyc7XG5pbXBvcnQgeyBTY09yZGVySXRlbUNvbXBvbmVudCB9IGZyb20gJy4uL29yZGVyLWl0ZW0vc2Mtb3JkZXItaXRlbS5jb21wb25lbnQnO1xuXG4vKipcbiAqINCa0L7QvNC/0L7QvdC10L3RgiDRgdC/0LjRgdC60LAg0YLQvtCy0LDRgNC+0LIg0LrQvtGA0LfQuNC90YssINC30LDQutCw0LfQsCDQuNC70Lgg0YfQtdGA0L3QvtCy0LjQutCwLlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAnc2Mtb3JkZXItaXRlbXMtbGlzdCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3NjLW9yZGVyLWl0ZW1zLWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQXN5bmNQaXBlLFxuICAgICAgICBUdWlGb3JtYXROdW1iZXJQaXBlLFxuICAgICAgICBTY09yZGVySXRlbUNvbXBvbmVudCxcbiAgICAgICAgU2NQcmludERpcmVjdGl2ZSxcbiAgICAgICAgRm9ybXNNb2R1bGUsXG4gICAgICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgICAgIFR1aUNoZWNrYm94LFxuICAgICAgICBUdWlMYWJlbCxcbiAgICAgICAgVHVpQnV0dG9uLFxuICAgICAgICBUdWlCdXR0b25Mb2FkaW5nLFxuICAgICAgICBUdWlDdXJyZW5jeVBpcGUsXG4gICAgXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2NPcmRlckl0ZW1zTGlzdENvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICog0JLQvdGD0YLRgNC10L3QvdC40Lkg0YHQuNCz0L3QsNC7INGB0L/QuNGB0LrQsCDRjdC70LXQvNC10L3RgtC+0LIg0LrQvtGA0LfQuNC90YsgKNGC0L7QstCw0YDQvtCyKS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXRlbXNTaWduYWwgPSBzaWduYWw8U2NPcmRlckl0ZW1bXT4oW10pO1xuXG4gICAgLyoqXG4gICAgICog0JLQutC70Y7Rh9C40YLRjCDQstGL0LHQvtGAINC/0L7Qt9C40YbQuNC5INGH0LXQutCx0L7QutGB0LDQvNC4LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBzZWxlY3RhYmxlID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiDQktC60LvRjtGH0LjRgtGMINGA0LXQtNCw0LrRgtC40YDQvtCy0LDQvdC40LUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGVkaXRhYmxlID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICog0JLQvdGD0YLRgNC10L3QvdGP0Y8g0LPRgNGD0L/Qv9CwINGE0L7RgNC80Ysg0LTQu9GPINCy0YvQsdC+0YDQsCDQv9C+0LfQuNGG0LjQuS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2VsZWN0aW9uRm9ybUdyb3VwID0gbmV3IEZvcm1Hcm91cDxSZWNvcmQ8c3RyaW5nLCBGb3JtQ29udHJvbDxib29sZWFuPj4+KHt9KTtcblxuICAgIC8qKlxuICAgICAqINCe0L/RhtC40Lgg0LfQsNC60LDQt9CwICjRh9C10YDQvdC+0LLQuNC60LApLiDQn9GA0LXQtNC+0YHRgtCw0LLQu9GP0LXRgtGB0Y8g0LTQuNGA0LXQutGC0LjQstC+0Lkge0BsaW5rIFNjT3JkZXJBY2Nlc3NvckRpcmVjdGl2ZX0g0LIg0LrQvtC90YLQtdC60YHRgtC1INGH0LXRgNC90L7QstC40LrQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3JkZXJPcHRpb25zID0gaW5qZWN0PFNjT3JkZXJPcHRpb25zPihTQ19PUkRFUl9PUFRJT05TLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDRiyDQstGL0LHRgNCw0L3QvdGL0YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGl0ZW1zSWRzID0gdG9TaWduYWwodGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAudmFsdWVDaGFuZ2VzLnBpcGUobWFwKCh2YWx1ZSkgPT4gT2JqZWN0LmVudHJpZXM8Ym9vbGVhbj4odmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4pKSksIHtcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBbXSxcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0L7RgdGC0L7Rj9C90LjQtSDRhNC70LDQs9CwIMKr0JLRi9Cx0YDQsNGC0Ywg0LLRgdC1wrs6IGB0cnVlYCwg0LXRgdC70Lgg0LLRi9Cx0YDQsNC90Ysg0LLRgdC1INC/0L7Qt9C40YbQuNC4LCBgZmFsc2VgLCDQtdGB0LvQuCDQvdC4INC+0LTQvdC+0LksINC4IGBudWxsYCwg0LXRgdC70Lgg0YLQvtC70YzQutC+INGH0LDRgdGC0YwuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGFsbEl0ZW1zU2VsZWN0ZWQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoZWNrZWRMaXN0ID0gdGhpcy5pdGVtc0lkcygpLm1hcCgoWywgY2hlY2tlZF0pID0+IGNoZWNrZWQpO1xuXG4gICAgICAgIGlmIChjaGVja2VkTGlzdC5ldmVyeShCb29sZWFuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hlY2tlZExpc3Quc29tZShCb29sZWFuKSA/IG51bGwgOiBmYWxzZTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0LjQs9C90LDQuyDQuNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgNC+0LIg0LLRi9Cx0YDQsNC90L3Ri9GFINC/0L7Qt9C40YbQuNC5LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZEl0ZW1zSWRzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3RhYmxlID0gdGhpcy5zZWxlY3RhYmxlKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXNJZHMoKVxuICAgICAgICAgICAgLmZpbHRlcigoWywgY2hlY2tlZF0pID0+ICFzZWxlY3RhYmxlIHx8IGNoZWNrZWQpXG4gICAgICAgICAgICAubWFwKChba2V5XSkgPT4ga2V5KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCS0YvRhdC+0LTQvdGL0LUg0LTQsNC90L3Ri9C1INC/0YDQuCDQuNC30LzQtdC90LXQvdC40Lgg0LLRi9Cx0L7RgNCwINC/0L7Qt9C40YbQuNC5LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZEl0ZW1zSWRzQ2hhbmdlID0gb3V0cHV0RnJvbU9ic2VydmFibGUodG9PYnNlcnZhYmxlKHRoaXMuc2VsZWN0ZWRJdGVtc0lkcykpO1xuXG4gICAgLyoqXG4gICAgICog0KHRg9C80LzQsCDRgdGC0L7QuNC80L7RgdGC0Lgg0LLRi9Cx0YDQsNC90L3Ri9GFINC/0L7Qt9C40YbQuNC5LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBzdW1TZWxlY3RlZEl0ZW1zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXNTaWduYWwoKTtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtc0lkcyA9IHRoaXMuc2VsZWN0ZWRJdGVtc0lkcygpO1xuICAgICAgICBjb25zdCBzZWxlY3RhYmxlID0gdGhpcy5zZWxlY3RhYmxlKCk7XG5cbiAgICAgICAgcmV0dXJuIFNjTnVtYmVySGVscGVyLnJvdW5kTW9uZXkoXG4gICAgICAgICAgICBpdGVtcy5maWx0ZXIoKGl0ZW0pID0+ICFzZWxlY3RhYmxlIHx8IHNlbGVjdGVkSXRlbXNJZHMuaW5jbHVkZXMoaXRlbS5pZCkpLnJlZHVjZSgoc3VtOiBudW1iZXIsIGl0ZW06IFNjT3JkZXJJdGVtKSA9PiBzdW0gKyBpdGVtLmNvc3RSdWIsIDApXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiDQodC10YDQstC40YEg0L/QvtC70YPRh9C10L3QuNGPINC4INGA0LXQtNCw0LrRgtC40YDQvtCy0LDQvdC40Y8g0YHQv9C40YHQutCwINGC0L7QstCw0YDQvtCyINC30LDQutCw0LfQsCAo0LrQvtGA0LfQuNC90LAgLyDQt9Cw0LrQsNC3IC8g0YfQtdGA0L3QvtCy0LjQuiA9INC30LDQutCw0LcpLlxuICAgICAqINCf0YDQtdC00L7RgdGC0LDQstC70Y/QtdGC0YHRjyDRgNC+0LTQuNGC0LXQu9C10Lwg0YfQtdGA0LXQtyDRgtC+0LrQtdC9IHtAbGluayBTQ19PUkRFUl9MT0FERVJ9ICjRgNC10LDQu9C40LfQsNGG0LjRjyB7QGxpbmsgU2NJT3JkZXJMb2FkZXJ9KS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3JkZXJJdGVtc0xpc3RMb2FkZXIgPSBpbmplY3Q8U2NJT3JkZXJMb2FkZXIgfCBTY0lPcmRlckVkaXRvckxvYWRlcj4oU0NfT1JERVJfTE9BREVSKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6LCDRh9GC0L4g0LzQvtC20L3QviDRgNC10LTQsNC60YLQuNGA0L7QstCw0YLRjCDQv9C+0LfQuNGG0LjQuC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FuRWRpdCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZWRpdGFibGUoKSAmJiAndXBkYXRlUHJvZHVjdCQnIGluIHRoaXMub3JkZXJJdGVtc0xpc3RMb2FkZXIpO1xuXG4gICAgLyoqXG4gICAgICog0J3QsNGB0YLRgNC+0LnQutC4INCy0YvQstC+0LTQsCDRgdGD0LzQvCDQsiDRgNGD0LHQu9GP0YUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG1vbmV5Rm9ybWF0ID0gU2NOdW1iZXJIZWxwZXIuZ2V0TW9uZXlGb3JtYXQoKTtcblxuICAgIC8qKlxuICAgICAqINCh0YHRi9C70LrQsCDQtNC70Y8g0LDQstGC0L7QvNCw0YLQuNGH0LXRgdC60L7Qs9C+INGD0L/RgNCw0LLQu9C10L3QuNGPINGD0L3QuNGH0YLQvtC20LXQvdC40LXQvCDQt9Cw0LLQuNGB0LjQvNC+0YHRgtC10LkuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LvRjyDRgNCw0LHQvtGC0Ysg0YEg0LTQuNCw0LvQvtCz0L7QstGL0LzQuCDQvtC60L3QsNC80LguXG4gICAgICog0J/RgNC10LTQvtGB0YLQsNCy0LvRj9C10YLRgdGPINGA0L7QtNC40YLQtdC70LXQvCDRh9C10YDQtdC3INGC0L7QutC10L0ge0BsaW5rIFNDX0RJQUxPR19TRVJWSUNFX1RPS0VOfS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjRGlhbG9nU2VydmljZSA9IGluamVjdDxJU2NEaWFsb2dTZXJ2aWNlPihTQ19ESUFMT0dfU0VSVklDRV9UT0tFTik7XG5cbiAgICAvKipcbiAgICAgKiDQodC/0LjRgdC+0Log0Y3Qu9C10LzQtdC90YLQvtCyINC60L7RgNC30LjQvdGLICjRgtC+0LLQsNGA0L7QsikuINCf0YDQuCDRg9GB0YLQsNC90L7QstC60LUg0YHQuNC90YXRgNC+0L3QvdC+INC+0LHQvdC+0LLQu9GP0LXRgiDQutC+0L3RgtGA0L7Qu9GLINCy0YvQsdC+0YDQsCDQsiDRhNC+0YDQvNC1LlxuICAgICAqL1xuICAgIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pXG4gICAgc2V0IGl0ZW1zKHZhbHVlOiBTY09yZGVySXRlbVtdKSB7XG4gICAgICAgIHRoaXMuaXRlbXNTaWduYWwuc2V0KHZhbHVlKTtcbiAgICAgICAgdGhpcy5zeW5jU2VsZWN0aW9uQ29udHJvbHMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodC40L3RhdGA0L7QvdC40LfQuNGA0YPQtdGCINC60L7QvdGC0YDQvtC70Ysg0YTQvtGA0LzRiyDQstGL0LHQvtGA0LAg0YEg0YLQtdC60YPRidC40Lwg0YHQv9C40YHQutC+0Lwg0YLQvtCy0LDRgNC+0LI6INGD0LTQsNC70Y/QtdGCINC60L7QvdGC0YDQvtC70Ysg0LTQu9GPINC+0YLRgdGD0YLRgdGC0LLRg9GO0YnQuNGFIGlkLCDQtNC+0LHQsNCy0LvRj9C10YIg0LTQu9GPINC90L7QstGL0YUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzeW5jU2VsZWN0aW9uQ29udHJvbHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RhYmxlKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHRoaXMuaXRlbXNTaWduYWwoKTtcbiAgICAgICAgY29uc3QgY3VycmVudElkcyA9IG5ldyBTZXQoY3VycmVudEl0ZW1zLm1hcCgoaXRlbSkgPT4gaXRlbS5pZCkpO1xuXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0aW9uRm9ybUdyb3VwLmNvbnRyb2xzKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRJZHMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAucmVtb3ZlQ29udHJvbChuYW1lIGFzIG5ldmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY3VycmVudEl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAuY29udGFpbnMoaXRlbS5pZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbkZvcm1Hcm91cC5hZGRDb250cm9sKGl0ZW0uaWQsIG5ldyBGb3JtQ29udHJvbCh0cnVlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JLRi9Cx0LjRgNCw0LXRgiDQstGB0LUg0L/QvtC30LjRhtC40Lgg0LjQu9C4INGB0L3QuNC80LDQtdGCINCy0YvQsdC+0YAg0YHQviDQstGB0LXRhS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBldmVudCDQodC+0LHRi9GC0LjQtSDQuNC30LzQtdC90LXQvdC40Y8g0YTQu9Cw0LPQsCDQstGL0LHQvtGA0LAg0LLRgdC10YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNlbGVjdEFsbENoYW5nZUhhbmRsZXIoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHsgY2hlY2tlZCB9ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG5cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAuc2V0VmFsdWUoT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0aW9uRm9ybUdyb3VwLmNvbnRyb2xzKS5tYXAoKGlkKSA9PiBbaWQsIGNoZWNrZWRdKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCj0LTQsNC70Y/QtdGCINC/0L7Qt9C40YbQuNGOLlxuICAgICAqXG4gICAgICogQHBhcmFtIGl0ZW0g0J/QvtC30LjRhtC40Y8g0YLQvtCy0LDRgNCwINC00LvRjyDRg9C00LDQu9C10L3QuNGPLlxuICAgICAqIEBwYXJhbSBwcmljZUNhcmQg0JrQvtC80L/QvtC90LXQvdGCINC60LDRgNGC0L7Rh9C60Lgg0YLQvtCy0LDRgNCwLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBkZWxldGVJdGVtKGl0ZW06IFNjT3JkZXJJdGVtLCBwcmljZUNhcmQ6IEFic3RyYWN0U2NQcmljZUNhcmQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhbkVkaXQoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJpY2VDYXJkLnNob3dMb2FkZXIuc2V0KHRydWUpO1xuXG4gICAgICAgICh0aGlzLm9yZGVySXRlbXNMaXN0TG9hZGVyIGFzIFNjSU9yZGVyRWRpdG9yTG9hZGVyKVxuICAgICAgICAgICAgLmRlbGV0ZVByb2R1Y3QkKGl0ZW0sIHRoaXMub3JkZXJPcHRpb25zPy5vcmRlcklkKCkpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VDYXJkLnF1YW50aXR5Q29udHJvbC5wYXRjaFZhbHVlKGl0ZW0ucXVhbnRpdHksIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRFdmVudDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZigpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VDYXJkLnNob3dMb2FkZXIuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0LHQvdC+0LLQu9GP0LXRgiDQutC+0LvQuNGH0LXRgdGC0LLQviDRgtC+0LLQsNGA0LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmV3UXVhbnRpdHkg0J3QvtCy0L7QtSDQt9C90LDRh9C10L3QuNC1INC60L7Qu9C40YfQtdGB0YLQstCwINGC0L7QstCw0YDQsC5cbiAgICAgKiBAcGFyYW0gcHJpY2VDYXJkINCa0L7QvNC/0L7QvdC10L3RgiDQutCw0YDRgtC+0YfQutC4INGC0L7QstCw0YDQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcGF0Y2hJdGVtKG5ld1F1YW50aXR5OiBudW1iZXIgfCBudWxsLCBwcmljZUNhcmQ6IEFic3RyYWN0U2NQcmljZUNhcmQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhbkVkaXQoKSB8fCAhcHJpY2VDYXJkLm9yZGVySXRlbSB8fCAhcHJpY2VDYXJkLnByb2R1Y3QgfHwgIW5ld1F1YW50aXR5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBwcmljZUNhcmQuc2hvd0xvYWRlci5zZXQodHJ1ZSk7XG5cbiAgICAgICAgKHRoaXMub3JkZXJJdGVtc0xpc3RMb2FkZXIgYXMgU2NJT3JkZXJFZGl0b3JMb2FkZXIpXG4gICAgICAgICAgICAudXBkYXRlUHJvZHVjdCQocHJpY2VDYXJkLm9yZGVySXRlbS5pZCwgeyBxdWFudGl0eTogbmV3UXVhbnRpdHkgfSwgdGhpcy5vcmRlck9wdGlvbnM/Lm9yZGVySWQoKSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICBwcmljZUNhcmQucXVhbnRpdHlDb250cm9sLnBhdGNoVmFsdWUocHJpY2VDYXJkLm9yZGVySXRlbSEucXVhbnRpdHksIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRFdmVudDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZigpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VDYXJkLnNob3dMb2FkZXIuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0YLQutGA0YvQstCw0LXRgiDQvNC+0LTQsNC70YzQvdC+0LUg0L7QutC90L4g0L7Qv9C40YHQsNC90LjRjyDRgtC+0LLQsNGA0LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJvZHVjdCDQotC+0LLQsNGAL9GD0YHQu9GD0LPQsCwg0L7Qv9C40YHQsNC90LjQtSDQutC+0YLQvtGA0L7QuSDQvdC10L7QsdGF0L7QtNC40LzQviDQvtGC0L7QsdGA0LDQt9C40YLRjC5cbiAgICAgKiBAcGFyYW0gb3JkZXJJdGVtINCV0LTQuNC90LjRh9C90LDRjyDQv9C+0LfQuNGG0LjRjyDRgtC+0LLQsNGA0LAv0YPRgdC70YPQs9C4INCyINC30LDQutCw0LfQtSwg0LTQu9GPINC60L7RgtC+0YDQvtC5INC90LXQvtCx0YXQvtC00LjQvNC+INC+0YLQutGA0YvRgtGMINC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgC5cbiAgICAgKiBAcGFyYW0gb3JkZXJJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQt9Cw0LrQsNC30LAsINCyINC60L7RgtC+0YDQvtC8INC90LXQvtCx0YXQvtC00LjQvNC+INC+0YLQutGA0YvRgtGMINC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgb3BlblByb2R1Y3RJbmZvRGlhbG9nKHByb2R1Y3Q6IFNjT3JkZXJJdGVtWydwcm9kdWN0J10sIG9yZGVySXRlbT86IFNjT3JkZXJJdGVtLCBvcmRlcklkPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNjRGlhbG9nU2VydmljZS5vcGVuUHJvZHVjdEluZm9EaWFsb2cpIHtcbiAgICAgICAgICAgIHRoaXMuc2NEaWFsb2dTZXJ2aWNlLm9wZW5Qcm9kdWN0SW5mb0RpYWxvZyhwcm9kdWN0LCBvcmRlckl0ZW0sIG9yZGVySWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7RgtC60YDRi9Cy0LDQtdGCINC80L7QtNCw0LvRjNC90L7QtSDQvtC60L3QviDQuNC30LzQtdC90LXQvdC40Y8g0YLQvtCy0LDRgNCwINC40LvQuCDQtdCz0L4g0LrQvtC90YTQuNCz0YPRgNCw0YLQvtGA0LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbSDQn9C+0LfQuNGG0LjRjyDRgtC+0LLQsNGA0LAuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIG9wZW5TZXR0aW5nc0RpYWxvZyhpdGVtOiBTY09yZGVySXRlbSk6IHZvaWQge1xuICAgICAgICBjb25zdCBpc0NvbmZpZ3VyYXRvciA9IEJvb2xlYW4oaXRlbS5jb25maWd1cmF0b3IpO1xuXG4gICAgICAgIGlmIChpc0NvbmZpZ3VyYXRvcikge1xuICAgICAgICAgICAgdGhpcy5zY0RpYWxvZ1NlcnZpY2Uub3BlbkNvbmZpZ3VyYXRvckRpYWxvZyhpdGVtLnByb2R1Y3QsIGl0ZW0sIHRoaXMub3JkZXJPcHRpb25zPy5vcmRlcklkKCkpO1xuICAgICAgICB9IGVsc2UgaWYgKFNjVW5pdHNIZWxwZXIucHJvZHVjdElzTWVhc3VyYWJsZShpdGVtLnByb2R1Y3QpKSB7XG4gICAgICAgICAgICB0aGlzLnNjRGlhbG9nU2VydmljZS5vcGVuQWRkT3JFZGl0aW5nQ2FydEl0ZW1EaWFsb2coaXRlbS5wcm9kdWN0LCBpdGVtLCB0aGlzLm9yZGVyT3B0aW9ucz8ub3JkZXJJZCgpLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0YLQutGA0YvQstCw0LXRgiDQtNC40LDQu9C+0LPQvtCy0L7QtSDQvtC60L3QviBcItCT0YDQsNGE0LjQuiDQuNC30LzQtdC90LXQvdC40Y8g0YHRgtC+0LjQvNC+0YHRgtC4XCIg0LTQu9GPINGC0L7QstCw0YDQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9kdWN0INCi0L7QstCw0YAv0YPRgdC70YPQs9CwLCDQtNC70Y8g0LrQvtGC0L7RgNC+0LPQviDQvdC10L7QsdGF0L7QtNC40LzQviDQvtGC0L7QsdGA0LDQt9C40YLRjCDQs9GA0LDRhNC40Log0LjQt9C80LXQvdC10L3QuNGPINGB0YLQvtC40LzQvtGB0YLQuC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgb3BlblByaWNlSGlzdG9yeUNoYXJ0RGlhbG9nKHByb2R1Y3Q6IFNjT3JkZXJJdGVtWydwcm9kdWN0J10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zY0RpYWxvZ1NlcnZpY2Uub3BlblByaWNlSGlzdG9yeUNoYXJ0RGlhbG9nKHByb2R1Y3QpO1xuICAgIH1cbn1cbiIsIjxkaXZcbiAgICBbZm9ybUdyb3VwXT1cInNlbGVjdGlvbkZvcm1Hcm91cFwiXG4gICAgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC01XCJcbj5cbiAgICA8IS0tINCk0LvQsNCzINCy0YvQsdC+0YDQsCDQstGB0LXRhSDQv9C+0LfQuNGG0LjQuS4gLS0+XG4gICAgQGlmIChzZWxlY3RhYmxlKCkgJiYgaXRlbXNTaWduYWwoKS5sZW5ndGgpIHtcbiAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICB0dWlMYWJlbFxuICAgICAgICAgICAgc2NQcmludD1cImRlZmF1bHROb1ByaW50XCJcbiAgICAgICAgICAgIGNsYXNzPVwic2VsZi1zdGFydFwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR1aUNoZWNrYm94XG4gICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICBzaXplPVwibVwiXG4gICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiYWxsSXRlbXNTZWxlY3RlZCgpXCJcbiAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0QWxsQ2hhbmdlSGFuZGxlcigkZXZlbnQpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICDQktGL0LHRgNCw0YLRjCDQstGB0LVcbiAgICAgICAgPC9sYWJlbD5cbiAgICB9XG5cbiAgICBAZm9yIChpdGVtIG9mIGl0ZW1zU2lnbmFsKCk7IHRyYWNrIGl0ZW0uaWQpIHtcbiAgICAgICAgQGlmICgkaW5kZXggIT09IDApIHtcbiAgICAgICAgICAgIDxociBjbGFzcz1cIm10LWF1dG8gaC1weCB3LWZ1bGwgYmctdHVpLWNsZWFyXCIgLz5cbiAgICAgICAgfVxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtNCByZWxhdGl2ZVwiPlxuICAgICAgICAgICAgQGxldCBpc0FjdGl2ZSA9ICFzZWxlY3RhYmxlKCkgfHwgc2VsZWN0aW9uRm9ybUdyb3VwLmdldChpdGVtLmlkKT8udmFsdWU7XG5cbiAgICAgICAgICAgIDwhLS0g0KfQtdC60LHQvtC60YEg0LLRi9Cx0L7RgNCwINGC0L7QstCw0YDQsC4gLS0+XG4gICAgICAgICAgICBAaWYgKHNlbGVjdGFibGUoKSkge1xuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICB0dWlDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXRlbUNvbXBvbmVudC5zaG93TG9hZGVyKClcIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICBzaXplPVwibVwiXG4gICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5pZFwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPCEtLSDQmtCw0YDRgtC+0YfQutCwINGC0L7QstCw0YDQsC4gLS0+XG4gICAgICAgICAgICA8c2Mtb3JkZXItaXRlbVxuICAgICAgICAgICAgICAgICNpdGVtQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgW3Byb2R1Y3RdPVwiaXRlbS5wcm9kdWN0XCJcbiAgICAgICAgICAgICAgICBbb3JkZXJJdGVtXT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgIFtzaG93UXVhbnRpdHlDb250cm9sXT1cImNhbkVkaXQoKSAmJiAhaXRlbS5jb25maWd1cmF0b3JcIlxuICAgICAgICAgICAgICAgIFtpc1Nob3dFZGl0Q29udHJvbHNdPVwiY2FuRWRpdCgpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBkdXJhdGlvbi0yMDBcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vcGFjaXR5LTYwXT1cInNlbGVjdGFibGUoKSAmJiAhc2VsZWN0aW9uRm9ybUdyb3VwLmdldChpdGVtLmlkKT8udmFsdWVcIlxuICAgICAgICAgICAgICAgIChjbGlja0NhcmRFdmVudCk9XCJvcGVuUHJvZHVjdEluZm9EaWFsb2coaXRlbS5wcm9kdWN0LCBpdGVtLCBvcmRlck9wdGlvbnM/Lm9yZGVySWQoKSlcIlxuICAgICAgICAgICAgICAgIChxdWFudGl0eVZhbHVlQ2hhbmdlcyk9XCJwYXRjaEl0ZW0oJGV2ZW50LCBpdGVtQ29tcG9uZW50KVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrUHJpY2VIaXN0b3J5RXZlbnQpPVwib3BlblByaWNlSGlzdG9yeUNoYXJ0RGlhbG9nKGl0ZW0ucHJvZHVjdClcIlxuICAgICAgICAgICAgICAgIChjbGlja1NldHRpbmdzKT1cIm9wZW5TZXR0aW5nc0RpYWxvZyhpdGVtKVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwiIWlzQWN0aXZlXCJcbiAgICAgICAgICAgIC8+XG5cbiAgICAgICAgICAgIDwhLS0g0JrQvdC+0L/QutCwINGD0LTQsNC70LXQvdC40Y8g0YLQvtCy0LDRgNCwLiAtLT5cbiAgICAgICAgICAgIEBpZiAoY2FuRWRpdCgpKSB7XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0dWlJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGljb25TdGFydD1cIkB0dWkudHJhc2hcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlSXRlbShpdGVtLCBpdGVtQ29tcG9uZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIFtsb2FkaW5nXT1cIml0ZW1Db21wb25lbnQuc2hvd0xvYWRlcigpXCJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInNcIlxuICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCIhYWJzb2x1dGUgbGVmdC0xIHRvcC0xIGxnOiFyZWxhdGl2ZSBsZzpsZWZ0LTAgbGc6dG9wLTAgbGc6IXNlbGYtY2VudGVyXCJcbiAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0g0KTRg9GC0LXRgCDRgdC/0LjRgdC60LAuIC0tPlxuICAgIDxkaXZcbiAgICAgICAgc2NQcmludD1cImNvc3RcIlxuICAgICAgICBjbGFzcz1cImZsZXggZmxleC1jb2wgaXRlbXMtZW5kIGdhcC0yLjVcIlxuICAgID5cbiAgICAgICAgQGxldCB0b3RhbFN1bSA9IHN1bVNlbGVjdGVkSXRlbXMoKTtcbiAgICAgICAgPCEtLSDQmNGC0L7Qs9C+0LLQsNGPINGB0YPQvNC80LAuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1iYXNlIGZvbnQtYm9sZFwiPtCY0YLQvtCz0L46IHt7IHRvdGFsU3VtIHwgdHVpRm9ybWF0TnVtYmVyOiBtb25leUZvcm1hdCB8IGFzeW5jIH19IHt7ICdSVUInIHwgdHVpQ3VycmVuY3kgfX08L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19
449
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Mtb3JkZXItaXRlbXMtbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbGllbnQtdWkvb3JkZXIvb3JkZXItaXRlbXMtbGlzdC9zYy1vcmRlci1pdGVtcy1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NsaWVudC11aS9vcmRlci9vcmRlci1pdGVtcy1saXN0L3NjLW9yZGVyLWl0ZW1zLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUksT0FBTyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM5RyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRixPQUFPLEVBQUUsZUFBZSxFQUE0RCxjQUFjLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xMLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RyxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFN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QUNuQixXQUFXO3dCQUNYLFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxnQkFBZ0I7d0JBQ2hCLGVBQWU7cUJBQ2xCLG1CQUNnQix1QkFBdUIsQ0FBQyxNQUFNO3dEQTZOM0MsS0FBSztzQkFEUixLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXBhcmFtLXJlYXNzaWduICovXG5cbmltcG9ydCB7IEFzeW5jUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBjb21wdXRlZCwgRGVzdHJveVJlZiwgZWZmZWN0LCBpbmplY3QsIElucHV0LCBpbnB1dCwgc2lnbmFsLCB1bnRyYWNrZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG91dHB1dEZyb21PYnNlcnZhYmxlLCB0YWtlVW50aWxEZXN0cm95ZWQsIHRvT2JzZXJ2YWJsZSwgdG9TaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNDX09SREVSX0xPQURFUiwgU2NJT3JkZXJFZGl0b3JMb2FkZXIsIFNjSU9yZGVySXRlbXNHcm91cCwgU2NJT3JkZXJMb2FkZXIsIFNjTnVtYmVySGVscGVyLCBTY09yZGVySXRlbSwgU2NPcmRlckl0ZW1zR3JvdXAsIFNjVW5pdHNIZWxwZXIgfSBmcm9tICdAc25hYmNlbnRyL2NsaWVudC1jb3JlJztcbmltcG9ydCB7IFR1aUN1cnJlbmN5UGlwZSB9IGZyb20gJ0B0YWlnYS11aS9hZGRvbi1jb21tZXJjZSc7XG5pbXBvcnQgeyBUdWlBbGVydFNlcnZpY2UsIFR1aUJ1dHRvbiwgVHVpRGlhbG9nU2VydmljZSwgVHVpRm9ybWF0TnVtYmVyUGlwZSwgVHVpTGFiZWwgfSBmcm9tICdAdGFpZ2EtdWkvY29yZSc7XG5pbXBvcnQgeyBUVUlfQ09ORklSTSwgVHVpQnV0dG9uTG9hZGluZywgVHVpQ2hlY2tib3ggfSBmcm9tICdAdGFpZ2EtdWkva2l0JztcbmltcG9ydCB7IEVNUFRZLCBmaWx0ZXIsIGZpbmFsaXplLCBtYXAsIG5vb3AsIE9ic2VydmFibGUsIG9mLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQWJzdHJhY3RTY1ByaWNlQ2FyZCwgU2NQcmludERpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgSVNjRGlhbG9nU2VydmljZSwgU0NfRElBTE9HX1NFUlZJQ0VfVE9LRU4gfSBmcm9tICcuLi8uLi9wcm92aWRlcnMnO1xuaW1wb3J0IHsgU0NfT1JERVJfT1BUSU9OUywgU2NPcmRlck9wdGlvbnMgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3NjLW9yZGVyLW9wdGlvbnMnO1xuaW1wb3J0IHsgU2NPcmRlckl0ZW1Db21wb25lbnQgfSBmcm9tICcuLi9vcmRlci1pdGVtL3NjLW9yZGVyLWl0ZW0uY29tcG9uZW50JztcblxuLyoqXG4gKiDQmtC+0LzQv9C+0L3QtdC90YIg0YHQv9C40YHQutCwINGC0L7QstCw0YDQvtCyINC60L7RgNC30LjQvdGLLCDQt9Cw0LrQsNC30LAg0LjQu9C4INGH0LXRgNC90L7QstC40LrQsC5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzZWxlY3RvcjogJ3NjLW9yZGVyLWl0ZW1zLWxpc3QnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zYy1vcmRlci1pdGVtcy1saXN0LmNvbXBvbmVudC5odG1sJyxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIEFzeW5jUGlwZSxcbiAgICAgICAgVHVpRm9ybWF0TnVtYmVyUGlwZSxcbiAgICAgICAgU2NPcmRlckl0ZW1Db21wb25lbnQsXG4gICAgICAgIFNjUHJpbnREaXJlY3RpdmUsXG4gICAgICAgIEZvcm1zTW9kdWxlLFxuICAgICAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgICAgICBUdWlDaGVja2JveCxcbiAgICAgICAgVHVpTGFiZWwsXG4gICAgICAgIFR1aUJ1dHRvbixcbiAgICAgICAgVHVpQnV0dG9uTG9hZGluZyxcbiAgICAgICAgVHVpQ3VycmVuY3lQaXBlLFxuICAgIF0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNjT3JkZXJJdGVtc0xpc3RDb21wb25lbnQge1xuICAgIC8qKlxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC60L7Qv9C40Y4g0L3QsNCx0L7RgNCwINGBINC00L7QsdCw0LLQu9C10L3QvdGL0LzQuCDQuNC70Lgg0YPQsdGA0LDQvdC90YvQvNC4INC60LvRjtGH0LDQvNC4LlxuICAgICAqXG4gICAgICogQHBhcmFtIGtleXMg0J3QsNCx0L7RgC5cbiAgICAgKiBAcGFyYW0gY2hhbmdlZCDQmtC70Y7Rh9C4LlxuICAgICAqIEBwYXJhbSBpc0luY2x1ZGVkINCf0YDQuNC30L3QsNC6INC00L7QsdCw0LLQu9C10L3QuNGPLlxuICAgICAqL1xuICAgIHByaXZhdGUgc3RhdGljIHdpdGhLZXlzKGtleXM6IFJlYWRvbmx5U2V0PHN0cmluZz4sIGNoYW5nZWQ6IHN0cmluZ1tdLCBpc0luY2x1ZGVkOiBib29sZWFuKTogUmVhZG9ubHlTZXQ8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0KGtleXMpO1xuXG4gICAgICAgIGNoYW5nZWQuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNJbmNsdWRlZCkge1xuICAgICAgICAgICAgICAgIG5leHQuYWRkKGtleSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5leHQuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBuZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCS0L3Rg9GC0YDQtdC90L3QuNC5INGB0LjQs9C90LDQuyDRgdC/0LjRgdC60LAg0Y3Qu9C10LzQtdC90YLQvtCyINC60L7RgNC30LjQvdGLICjRgtC+0LLQsNGA0L7QsikuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGl0ZW1zU2lnbmFsID0gc2lnbmFsPFNjT3JkZXJJdGVtW10+KFtdKTtcblxuICAgIC8qKlxuICAgICAqINCS0LrQu9GO0YfQuNGC0Ywg0LLRi9Cx0L7RgCDQv9C+0LfQuNGG0LjQuSDRh9C10LrQsdC+0LrRgdCw0LzQuC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgc2VsZWN0YWJsZSA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xuXG4gICAgLyoqXG4gICAgICog0JLQutC70Y7Rh9C40YLRjCDRgNC10LTQsNC60YLQuNGA0L7QstCw0L3QuNC1INC/0L7Qt9C40YbQuNC5LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBlZGl0YWJsZSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INCy0YvQstC+0LTQsCDQv9C+0LfQuNGG0LjQuSDQv9C+INCz0YDRg9C/0L/QsNC8ICjQs9GA0YPQv9C/0LAg0L/QvtC30LjRhtC40Lgg0LjQu9C4IMKr0JHQtdC3INCz0YDRg9C/0L/Ri8K7KSDRgSDQt9Cw0LPQvtC70L7QstC60LDQvNC4INC4INC40YLQvtCz0LDQvNC4LiDQkdC10Lcg0L/RgNC40LfQvdCw0LrQsCDQv9C+0LfQuNGG0LjQuCDQstGL0LLQvtC00Y/RgtGB0Y8g0L7QtNC90LjQvCDRgdC/0LjRgdC60L7QvCDQsdC10Lcg0LfQsNCz0L7Qu9C+0LLQutC+0LIuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGdyb3VwZWQgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiwg0YfRgtC+INC/0L7Qt9C40YbQuNC4LCDQutC+0YLQvtGA0YvQtSDQvdC1INC/0L7Qv9Cw0LTRg9GCINCyINC30LDQutCw0LcsINC/0L7QvNC10YfQsNGO0YLRgdGPINC/0YDQuNC80LXRh9Cw0L3QuNC10Lwg0Lgg0L3QtSDQstGL0LHQuNGA0LDRjtGC0YHRjy4g0J3QtdCw0LrRgtC40LLQvdGL0LUg0L/QvtC30LjRhtC40Lgg0L/RgNC40LPQu9GD0YjQsNGO0YLRgdGPINC4INC30LDRh9GR0YDQutC40LLQsNGO0YLRgdGPLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBtYXJrVW5hdmFpbGFibGUgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiwg0YfRgtC+INGG0LXQvdCwINC30LAg0LXQtNC40L3QuNGG0YMg0LHQtdGA0ZHRgtGB0Y8g0LjQtyDQv9C+0LfQuNGG0LjQuCwg0LAg0L3QtSDQuNC3INGC0LXQutGD0YnQtdC5INGG0LXQvdGLINGC0L7QstCw0YDQsC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdXNlTGluZVByaWNlID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0LosINGH0YLQviDQv9Cw0YDQsNC80LXRgtGA0Ysg0L/QvtC30LjRhtC40Lgg0LzQtdC90Y/RjtGC0YHRjyDQsiDQtNC40LDQu9C+0LPQtSDRgtC+0LLQsNGA0LA6INC00LjQsNC70L7QsyDQtNC+0YHRgtGD0L/QtdC9INGDINC70Y7QsdC+0Lkg0LDQutGC0LjQstC90L7QuSDQv9C+0LfQuNGG0LjQuCwg0LAg0LrQvtC70LjRh9C10YHRgtCy0L4g0Lgg0LzQtdGC0YDQsNC2INC40LfQvNC10YDRj9C10LzRi9GFINGC0L7QstCw0YDQvtCyXG4gICAgICog0LzQtdC90Y/RjtGC0YHRjyDRgtC+0LvRjNC60L4g0LIg0L3RkdC8LCDQtNCw0LbQtSDQtdGB0LvQuCDQvNC10YLRgNCw0LYg0LXRidGRINC90LUg0LfQsNC00LDQvS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbWVhc3VyZWRJbkRpYWxvZyA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcblxuICAgIC8qKlxuICAgICAqINCe0YLQutGD0LTQsCDRg9C00LDQu9GP0LXRgtGB0Y8g0L/QvtC30LjRhtC40Y8g0LTQu9GPINGC0LXQutGB0YLQsCDQv9C+0LTRgtCy0LXRgNC20LTQtdC90LjRjywg0L3QsNC/0YDQuNC80LXRgCDCq9C40Lcg0YfQtdGA0L3QvtCy0LjQutCwwrsuINCV0YHQu9C4INC90LUg0LfQsNC00LDQvdC+LCDQv9C+0LfQuNGG0LjRjyDRg9C00LDQu9GP0LXRgtGB0Y8g0LHQtdC3INC/0L7QtNGC0LLQtdGA0LbQtNC10L3QuNGPLlxuICAgICAqINCi0L7RgiDQttC1INGC0LXQutGB0YIg0LjRgdC/0L7Qu9GM0LfRg9C10YLRgdGPINCyINC/0YDQtdC00YPQv9GA0LXQttC00LXQvdC40Lgg0L4g0L3Rg9C70LXQstC+0Lwg0LrQvtC70LjRh9C10YHRgtCy0LUuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRlbGV0ZUNvbmZpcm1hdGlvblRhcmdldCA9IGlucHV0PHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gICAgLyoqXG4gICAgICog0J/QvtC00L/QuNGB0Ywg0LjRgtC+0LPQvtCy0L7QuSDRgdGD0LzQvNGLLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0b3RhbExhYmVsID0gaW5wdXQ8c3RyaW5nPign0JjRgtC+0LPQvicpO1xuXG4gICAgLyoqXG4gICAgICog0J/QvtC30LjRhtC40LgsINGA0LDQt9Cx0LjRgtGL0LUg0L3QsCDQs9GA0YPQv9C/0YsuINCR0LXQtyDQs9GA0YPQv9C/0LjRgNC+0LLQutC4INCy0YHQtSDQv9C+0LfQuNGG0LjQuCDQuNC00YPRgiDQvtC00L3QvtC5INCz0YDRg9C/0L/QvtC5INCx0LXQtyDQt9Cw0LPQvtC70L7QstC60LAuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGdyb3VwcyA9IGNvbXB1dGVkPFNjSU9yZGVySXRlbXNHcm91cFtdPigoKSA9PiB7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtc1NpZ25hbCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmdyb3VwZWQoKSA/IFNjT3JkZXJJdGVtc0dyb3VwLmZyb21JdGVtcyhpdGVtcykgOiBbbmV3IFNjT3JkZXJJdGVtc0dyb3VwKCcnLCBpdGVtcyldO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDRiyDQv9C+0LfQuNGG0LjQuSwg0LjQt9C80LXQvdC10L3QuNC1INC40LvQuCDRg9C00LDQu9C10L3QuNC1INC60L7RgtC+0YDRi9GFINC20LTRkdGCINC+0YfQtdGA0LXQtNC4INC40LvQuCDQstGL0L/QvtC70L3Rj9C10YLRgdGPLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBwZW5kaW5nSXRlbXNJZHMgPSBzaWduYWw8UmVhZG9ubHlTZXQ8c3RyaW5nPj4obmV3IFNldDxzdHJpbmc+KCkpO1xuXG4gICAgLyoqXG4gICAgICog0J3QsNC30LLQsNC90LjRjyDRg9C00LDQu9GP0LXQvNGL0YUg0LPRgNGD0L/Qvy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGVsZXRpbmdHcm91cHNOYW1lcyA9IHNpZ25hbDxSZWFkb25seVNldDxzdHJpbmc+PihuZXcgU2V0PHN0cmluZz4oKSk7XG5cbiAgICAvKipcbiAgICAgKiDQndCw0LfQstCw0L3QuNGPINCz0YDRg9C/0L8g0YEg0L/QvtC30LjRhtC40Y/QvNC4LCDQttC00YPRidC40LzQuCDQvtGC0LLQtdGC0LA6INGC0LDQutC40LUg0LPRgNGD0L/Qv9GLINGD0LTQsNC70LjRgtGMINC90LXQu9GM0LfRjy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcGVuZGluZ0dyb3Vwc05hbWVzID0gY29tcHV0ZWQ8UmVhZG9ubHlTZXQ8c3RyaW5nPj4oKCkgPT4ge1xuICAgICAgICBjb25zdCBwZW5kaW5nSWRzID0gdGhpcy5wZW5kaW5nSXRlbXNJZHMoKTtcblxuICAgICAgICByZXR1cm4gbmV3IFNldChcbiAgICAgICAgICAgIHRoaXMuZ3JvdXBzKClcbiAgICAgICAgICAgICAgICAuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAuaXRlbXMuc29tZSgoaXRlbSkgPT4gcGVuZGluZ0lkcy5oYXMoaXRlbS5pZCkpKVxuICAgICAgICAgICAgICAgIC5tYXAoKGdyb3VwKSA9PiBncm91cC5uYW1lKVxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JLQvdGD0YLRgNC10L3QvdGP0Y8g0LPRgNGD0L/Qv9CwINGE0L7RgNC80Ysg0LTQu9GPINCy0YvQsdC+0YDQsCDQv9C+0LfQuNGG0LjQuS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2VsZWN0aW9uRm9ybUdyb3VwID0gbmV3IEZvcm1Hcm91cDxSZWNvcmQ8c3RyaW5nLCBGb3JtQ29udHJvbDxib29sZWFuPj4+KHt9KTtcblxuICAgIC8qKlxuICAgICAqINCe0L/RhtC40Lgg0LfQsNC60LDQt9CwICjRh9C10YDQvdC+0LLQuNC60LApLiDQn9GA0LXQtNC+0YHRgtCw0LLQu9GP0LXRgtGB0Y8g0LTQuNGA0LXQutGC0LjQstC+0Lkge0BsaW5rIFNjT3JkZXJBY2Nlc3NvckRpcmVjdGl2ZX0g0LIg0LrQvtC90YLQtdC60YHRgtC1INGH0LXRgNC90L7QstC40LrQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3JkZXJPcHRpb25zID0gaW5qZWN0PFNjT3JkZXJPcHRpb25zPihTQ19PUkRFUl9PUFRJT05TLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDRiyDQstGL0LHRgNCw0L3QvdGL0YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGl0ZW1zSWRzID0gdG9TaWduYWwodGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAudmFsdWVDaGFuZ2VzLnBpcGUobWFwKCh2YWx1ZSkgPT4gT2JqZWN0LmVudHJpZXM8Ym9vbGVhbj4odmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4pKSksIHtcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBbXSxcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0L7RgdGC0L7Rj9C90LjQtSDRhNC70LDQs9CwIMKr0JLRi9Cx0YDQsNGC0Ywg0LLRgdC1wrs6IGB0cnVlYCwg0LXRgdC70Lgg0LLRi9Cx0YDQsNC90Ysg0LLRgdC1INC00L7RgdGC0YPQv9C90YvQtSDQtNC70Y8g0LLRi9Cx0L7RgNCwINC/0L7Qt9C40YbQuNC4LCBgZmFsc2VgLCDQtdGB0LvQuCDQvdC4INC+0LTQvdC+0Lkg0LjQu9C4INCy0YvQsdC40YDQsNGC0Ywg0L3QtdGH0LXQs9C+LFxuICAgICAqINC4IGBudWxsYCwg0LXRgdC70Lgg0YLQvtC70YzQutC+INGH0LDRgdGC0YwuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGFsbEl0ZW1zU2VsZWN0ZWQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoZWNrZWRMaXN0ID0gdGhpcy5pdGVtc0lkcygpLm1hcCgoWywgY2hlY2tlZF0pID0+IGNoZWNrZWQpO1xuXG4gICAgICAgIGlmIChjaGVja2VkTGlzdC5sZW5ndGggPiAwICYmIGNoZWNrZWRMaXN0LmV2ZXJ5KEJvb2xlYW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaGVja2VkTGlzdC5zb21lKEJvb2xlYW4pID8gbnVsbCA6IGZhbHNlO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog0KHQuNCz0L3QsNC7INC40LTQtdC90YLQuNGE0LjQutCw0YLQvtGA0L7QsiDQstGL0LHRgNCw0L3QvdGL0YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGVkSXRlbXNJZHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGFibGUgPSB0aGlzLnNlbGVjdGFibGUoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5pdGVtc0lkcygpXG4gICAgICAgICAgICAuZmlsdGVyKChbLCBjaGVja2VkXSkgPT4gIXNlbGVjdGFibGUgfHwgY2hlY2tlZClcbiAgICAgICAgICAgIC5tYXAoKFtrZXldKSA9PiBrZXkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JLRi9GF0L7QtNC90YvQtSDQtNCw0L3QvdGL0LUg0L/RgNC4INC40LfQvNC10L3QtdC90LjQuCDQstGL0LHQvtGA0LAg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGVkSXRlbXNJZHNDaGFuZ2UgPSBvdXRwdXRGcm9tT2JzZXJ2YWJsZSh0b09ic2VydmFibGUodGhpcy5zZWxlY3RlZEl0ZW1zSWRzKSk7XG5cbiAgICAvKipcbiAgICAgKiDQodGD0LzQvNCwINGB0YLQvtC40LzQvtGB0YLQuCDQstGL0LHRgNCw0L3QvdGL0YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHN1bVNlbGVjdGVkSXRlbXMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtc1NpZ25hbCgpO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW1zSWRzID0gdGhpcy5zZWxlY3RlZEl0ZW1zSWRzKCk7XG4gICAgICAgIGNvbnN0IHNlbGVjdGFibGUgPSB0aGlzLnNlbGVjdGFibGUoKTtcblxuICAgICAgICByZXR1cm4gU2NPcmRlckl0ZW0uZ2V0Q29zdFN1bShpdGVtcy5maWx0ZXIoKGl0ZW0pID0+ICFzZWxlY3RhYmxlIHx8IHNlbGVjdGVkSXRlbXNJZHMuaW5jbHVkZXMoaXRlbS5pZCkpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQv9C+0LvRg9GH0LXQvdC40Y8g0Lgg0YDQtdC00LDQutGC0LjRgNC+0LLQsNC90LjRjyDRgdC/0LjRgdC60LAg0YLQvtCy0LDRgNC+0LIg0LfQsNC60LDQt9CwICjQutC+0YDQt9C40L3QsCAvINC30LDQutCw0LcgLyDRh9C10YDQvdC+0LLQuNC6ID0g0LfQsNC60LDQtykuXG4gICAgICog0J/RgNC10LTQvtGB0YLQsNCy0LvRj9C10YLRgdGPINGA0L7QtNC40YLQtdC70LXQvCDRh9C10YDQtdC3INGC0L7QutC10L0ge0BsaW5rIFNDX09SREVSX0xPQURFUn0gKNGA0LXQsNC70LjQt9Cw0YbQuNGPIHtAbGluayBTY0lPcmRlckxvYWRlcn0pLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBvcmRlckl0ZW1zTGlzdExvYWRlciA9IGluamVjdDxTY0lPcmRlckxvYWRlciB8IFNjSU9yZGVyRWRpdG9yTG9hZGVyPihTQ19PUkRFUl9MT0FERVIpO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0LosINGH0YLQviDQvNC+0LbQvdC+INGA0LXQtNCw0LrRgtC40YDQvtCy0LDRgtGMINC/0L7Qt9C40YbQuNC4LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBjYW5FZGl0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5lZGl0YWJsZSgpICYmICd1cGRhdGVQcm9kdWN0JCcgaW4gdGhpcy5vcmRlckl0ZW1zTGlzdExvYWRlcik7XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiwg0YfRgtC+INCz0YDRg9C/0L/RgyDQvNC+0LbQvdC+INGD0LTQsNC70LjRgtGMINGG0LXQu9C40LrQvtC8LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBjYW5EZWxldGVHcm91cHMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNhbkVkaXQoKSAmJiAnZGVsZXRlUHJvZHVjdHMkJyBpbiB0aGlzLm9yZGVySXRlbXNMaXN0TG9hZGVyKTtcblxuICAgIC8qKlxuICAgICAqINCd0LDRgdGC0YDQvtC50LrQuCDQstGL0LLQvtC00LAg0YHRg9C80Lwg0LIg0YDRg9Cx0LvRj9GFLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBtb25leUZvcm1hdCA9IFNjTnVtYmVySGVscGVyLmdldE1vbmV5Rm9ybWF0KCk7XG5cbiAgICAvKipcbiAgICAgKiDQodGB0YvQu9C60LAg0LTQu9GPINCw0LLRgtC+0LzQsNGC0LjRh9C10YHQutC+0LPQviDRg9C/0YDQsNCy0LvQtdC90LjRjyDRg9C90LjRh9GC0L7QttC10L3QuNC10Lwg0LfQsNCy0LjRgdC40LzQvtGB0YLQtdC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQtNC70Y8g0YDQsNCx0L7RgtGLINGBINC00LjQsNC70L7Qs9C+0LLRi9C80Lgg0L7QutC90LDQvNC4LlxuICAgICAqINCf0YDQtdC00L7RgdGC0LDQstC70Y/QtdGC0YHRjyDRgNC+0LTQuNGC0LXQu9C10Lwg0YfQtdGA0LXQtyDRgtC+0LrQtdC9IHtAbGluayBTQ19ESUFMT0dfU0VSVklDRV9UT0tFTn0uXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY0RpYWxvZ1NlcnZpY2UgPSBpbmplY3Q8SVNjRGlhbG9nU2VydmljZT4oU0NfRElBTE9HX1NFUlZJQ0VfVE9LRU4pO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LjQsNC70L7Qs9C+0LLRi9GFINC+0LrQvtC9IFRhaWdhINC00LvRjyDQv9C+0LTRgtCy0LXRgNC20LTQtdC90LjQuS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRpYWxvZ1NlcnZpY2UgPSBpbmplY3QoVHVpRGlhbG9nU2VydmljZSk7XG5cbiAgICAvKipcbiAgICAgKiDQodC10YDQstC40YEg0YPQstC10LTQvtC80LvQtdC90LjQuS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGFsZXJ0cyA9IGluamVjdChUdWlBbGVydFNlcnZpY2UpO1xuXG4gICAgLyoqXG4gICAgICog0JjQvdC40YbQuNCw0LvQuNC30LjRgNGD0LXRgiDRjdC60LfQtdC80L/Qu9GP0YAg0LrQu9Cw0YHRgdCwIHtAbGluayBTY09yZGVySXRlbXNMaXN0Q29tcG9uZW50fS5cbiAgICAgKiDQktGF0L7QtNGLINCy0YvQsdC+0YDQsCDQuCDQv9C+0LzQtdGC0LrQuCDQvdC10LTQvtGB0YLRg9C/0L3Ri9GFINC/0L7Qt9C40YbQuNC5INC80L7Qs9GD0YIg0L/RgNC40LnRgtC4INC/0L7RgdC70LUg0YHQv9C40YHQutCwINC/0L7Qt9C40YbQuNC5LCDQv9C+0Y3RgtC+0LzRgyDQv9GA0Lgg0LjRhSDQuNC30LzQtdC90LXQvdC40Lgg0LLRi9Cx0L7RgCDRgdC40L3RhdGA0L7QvdC40LfQuNGA0YPQtdGC0YHRjyDQt9Cw0L3QvtCy0L4uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXJrVW5hdmFpbGFibGUoKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0YWJsZSgpO1xuICAgICAgICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNTZWxlY3Rpb25Db250cm9scygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCh0L/QuNGB0L7QuiDRjdC70LXQvNC10L3RgtC+0LIg0LrQvtGA0LfQuNC90YsgKNGC0L7QstCw0YDQvtCyKS4g0J/RgNC4INGD0YHRgtCw0L3QvtCy0LrQtSDRgdC40L3RhdGA0L7QvdC90L4g0L7QsdC90L7QstC70Y/QtdGCINC60L7QvdGC0YDQvtC70Ysg0LLRi9Cx0L7RgNCwINCyINGE0L7RgNC80LUuXG4gICAgICovXG4gICAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgICBzZXQgaXRlbXModmFsdWU6IFNjT3JkZXJJdGVtW10pIHtcbiAgICAgICAgdGhpcy5pdGVtc1NpZ25hbC5zZXQodmFsdWUpO1xuICAgICAgICB0aGlzLnN5bmNTZWxlY3Rpb25Db250cm9scygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCh0LjQvdGF0YDQvtC90LjQt9C40YDRg9C10YIg0LrQvtC90YLRgNC+0LvRiyDRhNC+0YDQvNGLINCy0YvQsdC+0YDQsCDRgSDRgtC10LrRg9GJ0LjQvCDRgdC/0LjRgdC60L7QvCDRgtC+0LLQsNGA0L7Qsjog0YPQtNCw0LvRj9C10YIg0LrQvtC90YLRgNC+0LvRiyDQtNC70Y8g0L7RgtGB0YPRgtGB0YLQstGD0Y7RidC40YUgaWQsINC00L7QsdCw0LLQu9GP0LXRgiDQtNC70Y8g0L3QvtCy0YvRhS5cbiAgICAgKiDQmtC+0L3RgtGA0L7Qu9GLINC80LXQvdGP0Y7RgtGB0Y8g0LHQtdC3INGB0L7QsdGL0YLQuNC5LCDQsCDQt9C90LDRh9C10L3QuNC1INCz0YDRg9C/0L/RiyDQv9C10YDQtdGB0YfQuNGC0YvQstCw0LXRgtGB0Y8g0L7QtNC40L0g0YDQsNC3INCyINC60L7QvdGG0LU6INC90LAg0LfQsNGP0LLQutCw0YUg0LIg0YHQvtGC0L3QuCDQv9C+0LfQuNGG0LjQuSDRjdGC0L4g0LfQsNC80LXRgtC90L4uXG4gICAgICovXG4gICAgcHJpdmF0ZSBzeW5jU2VsZWN0aW9uQ29udHJvbHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RhYmxlKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHRoaXMuaXRlbXNTaWduYWwoKTtcbiAgICAgICAgY29uc3QgY3VycmVudElkcyA9IG5ldyBTZXQoY3VycmVudEl0ZW1zLm1hcCgoaXRlbSkgPT4gaXRlbS5pZCkpO1xuXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0aW9uRm9ybUdyb3VwLmNvbnRyb2xzKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRJZHMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAucmVtb3ZlQ29udHJvbChuYW1lIGFzIG5ldmVyLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGN1cnJlbnRJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb250cm9sID0gdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAuZ2V0KGl0ZW0uaWQpO1xuICAgICAgICAgICAgY29uc3QgaXNTZWxlY3RhYmxlID0gIXRoaXMubWFya1VuYXZhaWxhYmxlKCkgfHwgaXRlbS5pc09yZGVyYWJsZTtcblxuICAgICAgICAgICAgaWYgKCFjb250cm9sKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAuYWRkQ29udHJvbChpdGVtLmlkLCBuZXcgRm9ybUNvbnRyb2woeyB2YWx1ZTogaXNTZWxlY3RhYmxlLCBkaXNhYmxlZDogIWlzU2VsZWN0YWJsZSB9LCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1NlbGVjdGFibGUgJiYgY29udHJvbC5lbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbC5zZXRWYWx1ZShmYWxzZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzU2VsZWN0YWJsZSAmJiBjb250cm9sLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbC5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuc2V0VmFsdWUodHJ1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnNlbGVjdGlvbkZvcm1Hcm91cC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JLRi9Cx0LjRgNCw0LXRgiDQstGB0LUg0LTQvtGB0YLRg9C/0L3Ri9C1INC00LvRjyDQstGL0LHQvtGA0LAg0L/QvtC30LjRhtC40Lgg0LjQu9C4INGB0L3QuNC80LDQtdGCINCy0YvQsdC+0YAg0YHQviDQstGB0LXRhS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBldmVudCDQodC+0LHRi9GC0LjQtSDQuNC30LzQtdC90LXQvdC40Y8g0YTQu9Cw0LPQsCDQstGL0LHQvtGA0LAg0LLRgdC10YUg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNlbGVjdEFsbENoYW5nZUhhbmRsZXIoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHsgY2hlY2tlZCB9ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGVuYWJsZWRJZHMgPSBPYmplY3QuZW50cmllcyh0aGlzLnNlbGVjdGlvbkZvcm1Hcm91cC5jb250cm9scylcbiAgICAgICAgICAgIC5maWx0ZXIoKFssIGNvbnRyb2xdKSA9PiBjb250cm9sLmVuYWJsZWQpXG4gICAgICAgICAgICAubWFwKChbaWRdKSA9PiBpZCk7XG5cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25Gb3JtR3JvdXAucGF0Y2hWYWx1ZShPYmplY3QuZnJvbUVudHJpZXMoZW5hYmxlZElkcy5tYXAoKGlkKSA9PiBbaWQsIGNoZWNrZWRdKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC/0YDQuNC30L3QsNC6LCDRh9GC0L4g0L/QvtC30LjRhtC40Y8g0L/RgNC40LPQu9GD0YjQtdC90LA6INC+0L3QsCDQvdC10LDQutGC0LjQstC90LAg0LjQu9C4INC90LUg0LLRi9Cx0YDQsNC90LAg0LTQu9GPINC30LDQutCw0LfQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpdGVtINCf0L7Qt9C40YbQuNGPLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBpc0l0ZW1EaW1tZWQoaXRlbTogU2NPcmRlckl0ZW0pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgaXNVbnNlbGVjdGVkID0gdGhpcy5zZWxlY3RhYmxlKCkgJiYgIXRoaXMuc2VsZWN0aW9uRm9ybUdyb3VwLmdldChpdGVtLmlkKT8udmFsdWU7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMubWFya1VuYXZhaWxhYmxlKCkgPyBpdGVtLmlzSW5hY3RpdmUgfHwgKGl0ZW0uaXNPcmRlcmFibGUgJiYgaXNVbnNlbGVjdGVkKSA6IGlzVW5zZWxlY3RlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktC+0LfQstGA0LDRidCw0LXRgiDQv9GA0LjQt9C90LDQuiwg0YfRgtC+INC60L7Qu9C40YfQtdGB0YLQstC+INC4INC80LXRgtGA0LDQtiDRgtC+0LLQsNGA0LAg0L/QvtC30LjRhtC40Lgg0LzQtdC90Y/RjtGC0YHRjyDQsiDQtNC40LDQu9C+0LPQtSDRgtC+0LLQsNGA0LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbSDQn9C+0LfQuNGG0LjRjy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgaXNFZGl0ZWRJbkRpYWxvZyhpdGVtOiBTY09yZGVySXRlbSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWFzdXJlZEluRGlhbG9nKCkgJiYgU2NVbml0c0hlbHBlci5wcm9kdWN0SXNNZWFzdXJhYmxlKGl0ZW0ucHJvZHVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KPQtNCw0LvRj9C10YIg0L/QvtC30LjRhtC40Y4sINC/0YDQuCDQvdC10L7QsdGF0L7QtNC40LzQvtGB0YLQuCDQv9C+0YHQu9C1INC/0L7QtNGC0LLQtdGA0LbQtNC10L3QuNGPLiDQodC+0L7QsdGJ0LXQvdC40LUg0L7QsSDQvtGI0LjQsdC60LUg0L/QvtC60LDQt9GL0LLQsNC10YIg0L/QtdGA0LXRhdCy0LDRgtGH0LjQuiDQv9GA0LjQu9C+0LbQtdC90LjRjy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpdGVtINCf0L7Qt9C40YbQuNGPINGC0L7QstCw0YDQsCDQtNC70Y8g0YPQtNCw0LvQtdC90LjRjy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZGVsZXRlSXRlbShpdGVtOiBTY09yZGVySXRlbSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuY2FuRWRpdCgpIHx8IHRoaXMucGVuZGluZ0l0ZW1zSWRzKCkuaGFzKGl0ZW0uaWQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpcm1EZWxldGUkKGl0ZW0pXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEl0ZW1QZW5kaW5nKGl0ZW0uaWQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5vcmRlckl0ZW1zTGlzdExvYWRlciBhcyBTY0lPcmRlckVkaXRvckxvYWRlcikuZGVsZXRlUHJvZHVjdCQoaXRlbSwgdGhpcy5vcmRlck9wdGlvbnM/Lm9yZGVySWQoKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEl0ZW1QZW5kaW5nKGl0ZW0uaWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZilcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoeyBlcnJvcjogbm9vcCB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQo9C00LDQu9GP0LXRgiDQstGB0LUg0L/QvtC30LjRhtC40Lgg0LPRgNGD0L/Qv9GLINC/0L7RgdC70LUg0L/QvtC00YLQstC10YDQttC00LXQvdC40Y8uINCh0L7RgdGC0LDQsiDQsdC10YDRkdGC0YHRjyDQvdCwINC80L7QvNC10L3RgiDQv9C+0LTRgtCy0LXRgNC20LTQtdC90LjRjy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBncm91cCDQk9GA0YPQv9C/0LAg0L/QvtC30LjRhtC40LkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGRlbGV0ZUdyb3VwKGdyb3VwOiBTY0lPcmRlckl0ZW1zR3JvdXApOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhbkRlbGV0ZUdyb3VwcygpIHx8IHRoaXMucGVuZGluZ0dyb3Vwc05hbWVzKCkuaGFzKGdyb3VwLm5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpcm1Hcm91cERlbGV0ZSQoZ3JvdXApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuZ3JvdXBzKCkuZmluZCgoeyBuYW1lIH0pID0+IG5hbWUgPT09IGdyb3VwLm5hbWUpPy5pdGVtcyA/PyBbXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWRzID0gaXRlbXMubWFwKChpdGVtKSA9PiBpdGVtLmlkKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRJdGVtc1BlbmRpbmcoaWRzLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGluZ0dyb3Vwc05hbWVzLnVwZGF0ZSgobmFtZXMpID0+IFNjT3JkZXJJdGVtc0xpc3RDb21wb25lbnQud2l0aEtleXMobmFtZXMsIFtncm91cC5uYW1lXSwgdHJ1ZSkpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5vcmRlckl0ZW1zTGlzdExvYWRlciBhcyBSZXF1aXJlZDxTY0lPcmRlckVkaXRvckxvYWRlcj4pLmRlbGV0ZVByb2R1Y3RzJChpdGVtcywgdGhpcy5vcmRlck9wdGlvbnM/Lm9yZGVySWQoKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEl0ZW1zUGVuZGluZyhpZHMsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlbGV0aW5nR3JvdXBzTmFtZXMudXBkYXRlKChuYW1lcykgPT4gU2NPcmRlckl0ZW1zTGlzdENvbXBvbmVudC53aXRoS2V5cyhuYW1lcywgW2dyb3VwLm5hbWVdLCBmYWxzZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh7IGVycm9yOiBub29wIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0LHQvdC+0LLQu9GP0LXRgiDQutC+0LvQuNGH0LXRgdGC0LLQviDRgtC+0LLQsNGA0LAuINCa0L7Qu9C40YfQtdGB0YLQstC+INC90LXQsNC60YLQuNCy0L3QvtC5INC/0L7Qt9C40YbQuNC4INC90LUg0LzQtdC90Y/QtdGC0YHRjy4g0J/Rg9GB0YLQvtC1INC40LvQuCDQvdGD0LvQtdCy0L7QtSDQt9C90LDRh9C10L3QuNC1INCy0L7Qt9Cy0YDQsNGJ0LDQtdGC0YHRjyDQuiDRgdC+0YXRgNCw0L3RkdC90L3QvtC80YMg0LrQvtC70LjRh9C10YHRgtCy0YMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmV3UXVhbnRpdHkg0J3QvtCy0L7QtSDQt9C90LDRh9C10L3QuNC1INC60L7Qu9C40YfQtdGB0YLQstCwINGC0L7QstCw0YDQsC5cbiAgICAgKiBAcGFyYW0gcHJpY2VDYXJkINCa0L7QvNC/0L7QvdC10L3RgiDQutCw0YDRgtC+0YfQutC4INGC0L7QstCw0YDQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcGF0Y2hJdGVtKG5ld1F1YW50aXR5OiBudW1iZXIgfCBudWxsLCBwcmljZUNhcmQ6IEFic3RyYWN0U2NQcmljZUNhcmQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgeyBvcmRlckl0ZW0gfSA9IHByaWNlQ2FyZDtcblxuICAgICAgICBpZiAoIXRoaXMuY2FuRWRpdCgpIHx8ICFvcmRlckl0ZW0gfHwgIXByaWNlQ2FyZC5wcm9kdWN0IHx8IG9yZGVySXRlbS5pc0luYWN0aXZlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5ld1F1YW50aXR5KSB7XG4gICAgICAgICAgICBwcmljZUNhcmQucXVhbnRpdHlDb250cm9sLnBhdGNoVmFsdWUob3JkZXJJdGVtLnF1YW50aXR5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICB0aGlzLndhcm5FbXB0eVF1YW50aXR5KCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0SXRlbVBlbmRpbmcob3JkZXJJdGVtLmlkLCB0cnVlKTtcblxuICAgICAgICAodGhpcy5vcmRlckl0ZW1zTGlzdExvYWRlciBhcyBTY0lPcmRlckVkaXRvckxvYWRlcilcbiAgICAgICAgICAgIC51cGRhdGVQcm9kdWN0JChvcmRlckl0ZW0uaWQsIHsgcXVhbnRpdHk6IG5ld1F1YW50aXR5IH0sIHRoaXMub3JkZXJPcHRpb25zPy5vcmRlcklkKCkpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0SXRlbVBlbmRpbmcob3JkZXJJdGVtLmlkLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZilcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHByaWNlQ2FyZC5xdWFudGl0eUNvbnRyb2wucGF0Y2hWYWx1ZSgocHJpY2VDYXJkLm9yZGVySXRlbSA/PyBvcmRlckl0ZW0pLnF1YW50aXR5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0YLQutGA0YvQstCw0LXRgiDQvNC+0LTQsNC70YzQvdC+0LUg0L7QutC90L4g0L7Qv9C40YHQsNC90LjRjyDRgtC+0LLQsNGA0LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJvZHVjdCDQotC+0LLQsNGAL9GD0YHQu9GD0LPQsCwg0L7Qv9C40YHQsNC90LjQtSDQutC+0YLQvtGA0L7QuSDQvdC10L7QsdGF0L7QtNC40LzQviDQvtGC0L7QsdGA0LDQt9C40YLRjC5cbiAgICAgKiBAcGFyYW0gb3JkZXJJdGVtINCV0LTQuNC90LjRh9C90LDRjyDQv9C+0LfQuNGG0LjRjyDRgtC+0LLQsNGA0LAv0YPRgdC70YPQs9C4INCyINC30LDQutCw0LfQtSwg0LTQu9GPINC60L7RgtC+0YDQvtC5INC90LXQvtCx0YXQvtC00LjQvNC+INC+0YLQutGA0YvRgtGMINC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgC5cbiAgICAgKiBAcGFyYW0gb3JkZXJJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQt9Cw0LrQsNC30LAsINCyINC60L7RgtC+0YDQvtC8INC90LXQvtCx0YXQvtC00LjQvNC+INC+0YLQutGA0YvRgtGMINC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgb3BlblByb2R1Y3RJbmZvRGlhbG9nKHByb2R1Y3Q6IFNjT3JkZXJJdGVtWydwcm9kdWN0J10sIG9yZGVySXRlbT86IFNjT3JkZXJJdGVtLCBvcmRlcklkPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNjRGlhbG9nU2VydmljZS5vcGVuUHJvZHVjdEluZm9EaWFsb2cpIHtcbiAgICAgICAgICAgIHRoaXMuc2NEaWFsb2dTZXJ2aWNlLm9wZW5Qcm9kdWN0SW5mb0RpYWxvZyhwcm9kdWN0LCBvcmRlckl0ZW0sIG9yZGVySWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7RgtC60YDRi9Cy0LDQtdGCINC80L7QtNCw0LvRjNC90L7QtSDQvtC60L3QviDQuNC30LzQtdC90LXQvdC40Y8g0YLQvtCy0LDRgNCwINC40LvQuCDQtdCz0L4g0LrQvtC90YTQuNCz0YPRgNCw0YLQvtGA0LAuINCV0YHQu9C4INC/0LDRgNCw0LzQtdGC0YDRiyDQv9C+0LfQuNGG0LjQuCDQvNC10L3Rj9GO0YLRgdGPINCyINC00LjQsNC70L7Qs9C1LCDQvtC60L3QviDRgtC+0LLQsNGA0LAg0L7RgtC60YDRi9Cy0LDQtdGC0YHRjyDQuCDRgyDRiNGC0YPRh9C90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpdGVtINCf0L7Qt9C40YbQuNGPINGC0L7QstCw0YDQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgb3BlblNldHRpbmdzRGlhbG9nKGl0ZW06IFNjT3JkZXJJdGVtKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGlzQ29uZmlndXJhdG9yID0gQm9vbGVhbihpdGVtLmNvbmZpZ3VyYXRvcik7XG5cbiAgICAgICAgaWYgKGlzQ29uZmlndXJhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLnNjRGlhbG9nU2VydmljZS5vcGVuQ29uZmlndXJhdG9yRGlhbG9nKGl0ZW0ucHJvZHVjdCwgaXRlbSwgdGhpcy5vcmRlck9wdGlvbnM/Lm9yZGVySWQoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5tZWFzdXJlZEluRGlhbG9nKCkgfHwgU2NVbml0c0hlbHBlci5wcm9kdWN0SXNNZWFzdXJhYmxlKGl0ZW0ucHJvZHVjdCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2NEaWFsb2dTZXJ2aWNlLm9wZW5BZGRPckVkaXRpbmdDYXJ0SXRlbURpYWxvZyhpdGVtLnByb2R1Y3QsIGl0ZW0sIHRoaXMub3JkZXJPcHRpb25zPy5vcmRlcklkKCksIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7RgtC60YDRi9Cy0LDQtdGCINC00LjQsNC70L7Qs9C+0LLQvtC1INC+0LrQvdC+IFwi0JPRgNCw0YTQuNC6INC40LfQvNC10L3QtdC90LjRjyDRgdGC0L7QuNC80L7RgdGC0LhcIiDQtNC70Y8g0YLQvtCy0LDRgNCwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHByb2R1Y3Qg0KLQvtCy0LDRgC/Rg9GB0LvRg9Cz0LAsINC00LvRjyDQutC+0YLQvtGA0L7Qs9C+INC90LXQvtCx0YXQvtC00LjQvNC+INC+0YLQvtCx0YDQsNC30LjRgtGMINCz0YDQsNGE0LjQuiDQuNC30LzQtdC90LXQvdC40Y8g0YHRgtC+0LjQvNC+0YHRgtC4LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBvcGVuUHJpY2VIaXN0b3J5Q2hhcnREaWFsb2cocHJvZHVjdDogU2NPcmRlckl0ZW1bJ3Byb2R1Y3QnXSk6IHZvaWQge1xuICAgICAgICB0aGlzLnNjRGlhbG9nU2VydmljZS5vcGVuUHJpY2VIaXN0b3J5Q2hhcnREaWFsb2cocHJvZHVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JLQvtC30LLRgNCw0YnQsNC10YIge0BsaW5rIE9ic2VydmFibGV9LCDQutC+0YLQvtGA0YvQuSDQstGL0LTQsNGR0YIg0LfQvdCw0YfQtdC90LjQtSwg0LrQvtCz0LTQsCDRg9C00LDQu9C10L3QuNC1INC/0L7Qt9C40YbQuNC4INC/0L7QtNGC0LLQtdGA0LbQtNC10L3QviDQuNC70Lgg0L/QvtC00YLQstC10YDQttC00LXQvdC40LUg0L3QtSDRgtGA0LXQsdGD0LXRgtGB0Y8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbSDQo9C00LDQu9GP0LXQvNCw0Y8g0L/QvtC30LjRhtC40Y8uXG4gICAgICovXG4gICAgcHJpdmF0ZSBjb25maXJtRGVsZXRlJChpdGVtOiBTY09yZGVySXRlbSk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmRlbGV0ZUNvbmZpcm1hdGlvblRhcmdldCgpO1xuXG4gICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gb2YodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5jb25maXJtUmVtb3ZhbCQoYNCj0LTQsNC70LjRgtGMINC/0L7Qt9C40YbQuNGOIMKrJHtpdGVtLnByb2R1Y3QubmFtZX3CuyAke3RhcmdldH0/YCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JLQvtC30LLRgNCw0YnQsNC10YIge0BsaW5rIE9ic2VydmFibGV9LCDQutC+0YLQvtGA0YvQuSDQstGL0LTQsNGR0YIg0LfQvdCw0YfQtdC90LjQtSwg0LrQvtCz0LTQsCDRg9C00LDQu9C10L3QuNC1INCz0YDRg9C/0L/RiyDQv9C+0LTRgtCy0LXRgNC20LTQtdC90L4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZ3JvdXAg0JPRgNGD0L/Qv9CwINC/0L7Qt9C40YbQuNC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgY29uZmlybUdyb3VwRGVsZXRlJChncm91cDogU2NJT3JkZXJJdGVtc0dyb3VwKTogT2JzZXJ2YWJsZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZGVsZXRlQ29uZmlybWF0aW9uVGFyZ2V0KCk7XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IHRhcmdldCA/IGAgJHt0YXJnZXR9YCA6ICcnO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpcm1SZW1vdmFsJChg0KPQtNCw0LvQuNGC0Ywg0LLRgdC1INC/0L7Qt9C40YbQuNC4INCz0YDRg9C/0L/RiyDCqyR7Z3JvdXAubmFtZX3CuyR7c291cmNlfT9gKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQktC+0LfQstGA0LDRidCw0LXRgiB7QGxpbmsgT2JzZXJ2YWJsZX0sINC60L7RgtC+0YDRi9C5INCy0YvQtNCw0ZHRgiDQt9C90LDRh9C10L3QuNC1LCDQutC+0LPQtNCwINGD0LTQsNC70LXQvdC40LUg0L/QvtC00YLQstC10YDQttC00LXQvdC+LlxuICAgICAqXG4gICAgICogQHBhcmFtIGxhYmVsINCS0L7Qv9GA0L7RgS5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNvbmZpcm1SZW1vdmFsJChsYWJlbDogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpYWxvZ1NlcnZpY2Uub3Blbjxib29sZWFuPihUVUlfQ09ORklSTSwgeyBsYWJlbCwgZGF0YTogeyB5ZXM6ICfQlNCwLCDRg9C00LDQu9C40YLRjCcsIG5vOiAn0J3QtdGCLCDQvtGB0YLQsNCy0LjRgtGMJyB9IH0pLnBpcGUoZmlsdGVyKEJvb2xlYW4pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntGC0LzQtdGH0LDQtdGCINC/0L7Qt9C40YbQuNGOINC60LDQuiDQvtC20LjQtNCw0Y7RidGD0Y4g0L7RgtCy0LXRgtCwINC40LvQuCDRgdC90LjQvNCw0LXRgiDQvtGC0LzQtdGC0LrRgy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQv9C+0LfQuNGG0LjQuC5cbiAgICAgKiBAcGFyYW0gaXNQZW5kaW5nINCf0YDQuNC30L3QsNC6INC+0LbQuNC00LDQvdC40Y8uXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZXRJdGVtUGVuZGluZyhpZDogc3RyaW5nLCBpc1BlbmRpbmc6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRJdGVtc1BlbmRpbmcoW2lkXSwgaXNQZW5kaW5nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodGC0LDQstC40YIg0LjQu9C4INGB0L3QuNC80LDQtdGCINC+0YLQvNC10YLQutGDINC+0LbQuNC00LDQvdC40Y8g0YMg0L/QvtC30LjRhtC40LkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaXRlbXNJZHMg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDRiyDQv9C+0LfQuNGG0LjQuS5cbiAgICAgKiBAcGFyYW0gaXNQZW5kaW5nINCf0YDQuNC30L3QsNC6INC+0LbQuNC00LDQvdC40Y8uXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZXRJdGVtc1BlbmRpbmcoaXRlbXNJZHM6IHN0cmluZ1tdLCBpc1BlbmRpbmc6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nSXRlbXNJZHMudXBkYXRlKChpZHMpID0+IFNjT3JkZXJJdGVtc0xpc3RDb21wb25lbnQud2l0aEtleXMoaWRzLCBpdGVtc0lkcywgaXNQZW5kaW5nKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J/RgNC10LTRg9C/0YDQtdC20LTQsNC10YIsINGH0YLQviDQutC+0LvQuNGH0LXRgdGC0LLQviDQvdC1INC80L7QttC10YIg0LHRi9GC0Ywg0L/Rg9GB0YLRi9C8INC40LvQuCDQvdGD0LvQtdCy0YvQvCwg0LAg0YPQsdGA0LDRgtGMINC/0L7Qt9C40YbQuNGOINC80L7QttC90L4g0YPQtNCw0LvQtdC90LjQtdC8LiDQn9C+0LvQtSDQstC+0LfQstGA0LDRidCw0LXRgtGB0Y8g0Log0YHQvtGF0YDQsNC90ZHQvdC90L7QvNGDINC60L7Qu9C40YfQtdGB0YLQstGDXG4gICAgICog0LIg0LvRjtCx0L7QvCDRgdC/0LjRgdC60LUsINC/0YDQtdC00YPQv9GA0LXQttC00LXQvdC40LUg0L/QvtC60LDQt9GL0LLQsNC10YLRgdGPINGC0L7Qu9GM0LrQviDQsiDRgdC/0LjRgdC60LDRhSDRgSDQv9C+0LTRgtCy0LXRgNC20LTQtdC90LjQtdC8INGD0LTQsNC70LXQvdC40Y8uXG4gICAgICovXG4gICAgcHJpdmF0ZSB3YXJuRW1wdHlRdWFudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5kZWxldGVDb25maXJtYXRpb25UYXJnZXQoKTtcblxuICAgICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgICAgICB0aGlzLmFsZXJ0cy5vcGVuKGDQmtC+0LvQuNGH0LXRgdGC0LLQviDQtNC+0LvQttC90L4g0LHRi9GC0Ywg0LHQvtC70YzRiNC1INC90YPQu9GPLiDQp9GC0L7QsdGLINGD0LHRgNCw0YLRjCDQv9C+0LfQuNGG0LjRjiAke3RhcmdldH0sINGD0LTQsNC70LjRgtC1INC10ZEuYCwgeyBhcHBlYXJhbmNlOiAnd2FybmluZycgfSkuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8ZGl2XG4gICAgW2Zvcm1Hcm91cF09XCJzZWxlY3Rpb25Gb3JtR3JvdXBcIlxuICAgIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtNVwiXG4+XG4gICAgPCEtLSDQpNC70LDQsyDQstGL0LHQvtGA0LAg0LLRgdC10YUg0L/QvtC30LjRhtC40LkuIC0tPlxuICAgIEBpZiAoc2VsZWN0YWJsZSgpICYmIGl0ZW1zU2lnbmFsKCkubGVuZ3RoKSB7XG4gICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgdHVpTGFiZWxcbiAgICAgICAgICAgIHNjUHJpbnQ9XCJkZWZhdWx0Tm9QcmludFwiXG4gICAgICAgICAgICBjbGFzcz1cInNlbGYtc3RhcnRcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICB0dWlDaGVja2JveFxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgc2l6ZT1cIm1cIlxuICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImFsbEl0ZW1zU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwic2VsZWN0aW9uRm9ybUdyb3VwLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdEFsbENoYW5nZUhhbmRsZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAg0JLRi9Cx0YDQsNGC0Ywg0LLRgdC1XG4gICAgICAgIDwvbGFiZWw+XG4gICAgfVxuXG4gICAgQGZvciAoZ3JvdXAgb2YgZ3JvdXBzKCk7IHRyYWNrIGdyb3VwLm5hbWUpIHtcbiAgICAgICAgPCEtLSDQl9Cw0LPQvtC70L7QstC+0Log0LPRgNGD0L/Qv9GLINC/0L7Qt9C40YbQuNC5LiAtLT5cbiAgICAgICAgQGlmIChncm91cC5uYW1lKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXAgaXRlbXMtZW5kIGp1c3RpZnktYmV0d2VlbiBnYXAteC00IGdhcC15LTEgYm9yZGVyLWIgYm9yZGVyLXR1aS1iYXNlLTAzIHBiLTJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBtaW4tdy0wIGZsZXgtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnJlYWstd29yZHMgdGV4dC1ib2R5LWwtYm9sZFwiPnt7IGdyb3VwLm5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1ib2R5LXMgdGV4dC10dWktdGV4dC0wMlwiPtC/0L7Qt9C40YbQuNC5OiB7eyBncm91cC5pdGVtcy5sZW5ndGggfX0sINCyINC30LDQutCw0Lc6IHt7IGdyb3VwLm9yZGVyYWJsZUNvdW50IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGl0ZW1zLWVuZCBnYXAtMVwiPlxuICAgICAgICAgICAgICAgICAgICA8IS0tINCa0L3QvtC/0LrQsCDRg9C00LDQu9C10L3QuNGPINCz0YDRg9C/0L/Riy4gLS0+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoY2FuRGVsZXRlR3JvdXBzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlPVwiZmxhdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY1ByaW50PVwiZGVmYXVsdE5vUHJpbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsb2FkaW5nXT1cImRlbGV0aW5nR3JvdXBzTmFtZXMoKS5oYXMoZ3JvdXAubmFtZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJwZW5kaW5nR3JvdXBzTmFtZXMoKS5oYXMoZ3JvdXAubmFtZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVHcm91cChncm91cClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgINCj0LTQsNC70LjRgtGMXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIndoaXRlc3BhY2Utbm93cmFwIHRleHQtYm9keS1tLWJvbGRcIj57eyBncm91cC5vcmRlcmFibGVTdW0gfCB0dWlGb3JtYXROdW1iZXI6IG1vbmV5Rm9ybWF0IHwgYXN5bmMgfX0ge3sgJ1JVQicgfCB0dWlDdXJyZW5jeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgQGZvciAoaXRlbSBvZiBncm91cC5pdGVtczsgdHJhY2sgaXRlbS5pZCkge1xuICAgICAgICAgICAgQGlmICgkaW5kZXggIT09IDApIHtcbiAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJtdC1hdXRvIGgtcHggdy1mdWxsIGJnLXR1aS1jbGVhclwiIC8+XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtNCByZWxhdGl2ZVwiPlxuICAgICAgICAgICAgICAgIEBsZXQgaXNBY3RpdmUgPSAhc2VsZWN0YWJsZSgpIHx8IHNlbGVjdGlvbkZvcm1Hcm91cC5nZXQoaXRlbS5pZCk/LnZhbHVlIHx8IChtYXJrVW5hdmFpbGFibGUoKSAmJiAhaXRlbS5pc09yZGVyYWJsZSk7XG4gICAgICAgICAgICAgICAgQGxldCBpc1BlbmRpbmcgPSBwZW5kaW5nSXRlbXNJZHMoKS5oYXMoaXRlbS5pZCk7XG4gICAgICAgICAgICAgICAgQGxldCBlZGl0ZWRJbkRpYWxvZyA9IGlzRWRpdGVkSW5EaWFsb2coaXRlbSk7XG5cbiAgICAgICAgICAgICAgICA8IS0tINCn0LXQutCx0L7QutGBINCy0YvQsdC+0YDQsCDRgtC+0LLQsNGA0LAuIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0YWJsZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgdHVpQ2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplPVwibVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0uaWRcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0g0JrQsNGA0YLQvtGH0LrQsCDRgtC+0LLQsNGA0LAuIC0tPlxuICAgICAgICAgICAgICAgIDxzYy1vcmRlci1pdGVtXG4gICAgICAgICAgICAgICAgICAgICNpdGVtQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgIFtwcm9kdWN0XT1cIml0ZW0ucHJvZHVjdFwiXG4gICAgICAgICAgICAgICAgICAgIFtvcmRlckl0ZW1dPVwiaXRlbVwiXG4gICAgICAgICAgICAgICAgICAgIFtzaG93UXVhbnRpdHlDb250cm9sXT1cImNhbkVkaXQoKSAmJiAhaXRlbS5jb25maWd1cmF0b3IgJiYgIWVkaXRlZEluRGlhbG9nXCJcbiAgICAgICAgICAgICAgICAgICAgW2lzU2hvd0VkaXRDb250cm9sc109XCJjYW5FZGl0KClcIlxuICAgICAgICAgICAgICAgICAgICBbdXNlTGluZVByaWNlXT1cInVzZUxpbmVQcmljZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgW21hcmtVbmF2YWlsYWJsZV09XCJtYXJrVW5hdmFpbGFibGUoKVwiXG4gICAgICAgICAgICAgICAgICAgIFtpc1BlbmRpbmddPVwiaXNQZW5kaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgW3NldHRpbmdzQXZhaWxhYmxlXT1cImNhbkVkaXQoKSAmJiBtZWFzdXJlZEluRGlhbG9nKCkgJiYgIWl0ZW0uY29uZmlndXJhdG9yICYmICFpdGVtLmlzSW5hY3RpdmVcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBkdXJhdGlvbi0yMDBcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub3BhY2l0eS02MF09XCJpc0l0ZW1EaW1tZWQoaXRlbSlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2tDYXJkRXZlbnQpPVwib3BlblByb2R1Y3RJbmZvRGlhbG9nKGl0ZW0ucHJvZHVjdCwgaXRlbSwgb3JkZXJPcHRpb25zPy5vcmRlcklkKCkpXCJcbiAgICAgICAgICAgICAgICAgICAgKHF1YW50aXR5VmFsdWVDaGFuZ2VzKT1cInBhdGNoSXRlbSgkZXZlbnQsIGl0ZW1Db21wb25lbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrUHJpY2VIaXN0b3J5RXZlbnQpPVwib3BlblByaWNlSGlzdG9yeUNoYXJ0RGlhbG9nKGl0ZW0ucHJvZHVjdClcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2tTZXR0aW5ncyk9XCJvcGVuU2V0dGluZ3NEaWFsb2coaXRlbSlcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MucG9pbnRlci1ldmVudHMtbm9uZV09XCIhaXNBY3RpdmVcIlxuICAgICAgICAgICAgICAgIC8+XG5cbiAgICAgICAgICAgICAgICA8IS0tINCa0L3QvtC/0LrQsCDRg9C00LDQu9C10L3QuNGPINGC0L7QstCw0YDQsC4gLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjYW5FZGl0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgdHVpSWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvblN0YXJ0PVwiQHR1aS50cmFzaFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlSXRlbShpdGVtKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbG9hZGluZ109XCJpc1BlbmRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cInNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiFhYnNvbHV0ZSBsZWZ0LTEgdG9wLTEgbGc6IXJlbGF0aXZlIGxnOmxlZnQtMCBsZzp0b3AtMCBsZzohc2VsZi1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICA8IS0tINCk0YPRgtC10YAg0YHQv9C40YHQutCwLiAtLT5cbiAgICA8ZGl2XG4gICAgICAgIHNjUHJpbnQ9XCJjb3N0XCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGl0ZW1zLWVuZCBnYXAtMi41XCJcbiAgICA+XG4gICAgICAgIEBsZXQgdG90YWxTdW0gPSBzdW1TZWxlY3RlZEl0ZW1zKCk7XG4gICAgICAgIDwhLS0g0JjRgtC+0LPQvtCy0LDRjyDRgdGD0LzQvNCwLiAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtYmFzZSBmb250LWJvbGRcIj57eyB0b3RhbExhYmVsKCkgfX06IHt7IHRvdGFsU3VtIHwgdHVpRm9ybWF0TnVtYmVyOiBtb25leUZvcm1hdCB8IGFzeW5jIH19IHt7ICdSVUInIHwgdHVpQ3VycmVuY3kgfX08L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19