@mediusinc/mng-commons 5.2.0 → 5.3.0-rc.1

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 (102) hide show
  1. package/core/components/pages/error/error.page.component.d.ts +3 -0
  2. package/core/components/pages/not-found/not-found.page.component.d.ts +3 -0
  3. package/core/descriptors/model.descriptor.d.ts +3 -0
  4. package/core/enum/enum-helpers.d.ts +5 -0
  5. package/core/helpers/route.d.ts +3 -4
  6. package/core/index.d.ts +1 -1
  7. package/core/models/menu.model.d.ts +14 -2
  8. package/core/services/{local-storage-config.service.d.ts → commons-storage.service.d.ts} +4 -3
  9. package/core/services/commons.service.d.ts +24 -0
  10. package/core/services/tokens/module-config.token.d.ts +23 -2
  11. package/esm2022/core/components/pages/error/error.page.component.mjs +4 -1
  12. package/esm2022/core/components/pages/not-found/not-found.page.component.mjs +4 -1
  13. package/esm2022/core/data-list/data-list-params-helpers.mjs +7 -4
  14. package/esm2022/core/descriptors/model.descriptor.mjs +1 -1
  15. package/esm2022/core/enum/enum-helpers.mjs +10 -1
  16. package/esm2022/core/helpers/route.mjs +1 -1
  17. package/esm2022/core/index.mjs +2 -2
  18. package/esm2022/core/models/menu.model.mjs +1 -1
  19. package/esm2022/core/pipes/enum.pipe.mjs +16 -5
  20. package/esm2022/core/provide.mjs +3 -3
  21. package/esm2022/core/router/route-builder.mjs +8 -1
  22. package/esm2022/core/security/permission.guard.mjs +2 -2
  23. package/esm2022/core/security/permission.service.mjs +2 -2
  24. package/esm2022/core/services/commons-storage.service.mjs +31 -0
  25. package/esm2022/core/services/commons.service.mjs +25 -1
  26. package/esm2022/core/services/tokens/module-config.token.mjs +1 -1
  27. package/esm2022/form/components/autocomplete/autocomplete.component.mjs +5 -15
  28. package/esm2022/model/descriptors/model.descriptor.mjs +10 -5
  29. package/esm2022/table/api/descriptors/column.descriptor.mjs +1 -1
  30. package/esm2022/table/api/models/table.model.mjs +2 -3
  31. package/esm2022/table/components/table/table.component.mjs +14 -42
  32. package/esm2022/tableview/action/components/editor/injector-context/action-editor-injector-context.component.mjs +18 -4
  33. package/esm2022/tableview/api/action/descriptors/action.descriptor.mjs +12 -13
  34. package/esm2022/tableview/api/action/helpers/data-provider-executors.mjs +2 -2
  35. package/esm2022/tableview/api/editor/descriptors/editor.descriptor.mjs +16 -24
  36. package/esm2022/tableview/api/editor/descriptors/field-action.descriptor.mjs +4 -8
  37. package/esm2022/tableview/api/editor/descriptors/field-base.descriptor.mjs +5 -12
  38. package/esm2022/tableview/api/editor/descriptors/field-group.descriptor.mjs +13 -19
  39. package/esm2022/tableview/api/editor/descriptors/field-lookup.descriptor.mjs +7 -7
  40. package/esm2022/tableview/api/editor/descriptors/field-many.descriptor.mjs +7 -7
  41. package/esm2022/tableview/api/editor/descriptors/field.descriptor.mjs +8 -4
  42. package/esm2022/tableview/api/editor/models/field.model.mjs +4 -3
  43. package/esm2022/tableview/api/editor/models/formly-field.model.mjs +1 -1
  44. package/esm2022/tableview/api/tableview/descriptors/tableview.descriptor.mjs +3 -3
  45. package/esm2022/tableview/api/tableview/helpers/tableview-default-actions.mjs +3 -3
  46. package/esm2022/tableview/editor/components/editor/form-editor.component.mjs +2 -2
  47. package/esm2022/tableview/editor/components/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +12 -5
  48. package/esm2022/tableview/editor/components/formly/fields/formly-field-input/formly-field-input.component.mjs +6 -4
  49. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +8 -7
  50. package/esm2022/tableview/editor/components/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +4 -3
  51. package/esm2022/tableview/editor/components/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +13 -4
  52. package/esm2022/tableview/editor/components/formly/fields/formly-field-type.abstract.component.mjs +7 -1
  53. package/esm2022/tableview/editor/components/formly/pipes/formly-field-label.pipe.mjs +19 -0
  54. package/esm2022/tableview/editor/components/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +33 -17
  55. package/esm2022/tableview/editor/helpers/editor-field.mjs +39 -0
  56. package/esm2022/tableview/editor/helpers/editor-formly.mjs +21 -15
  57. package/esm2022/tableview/editor/helpers/formly-config.mjs +13 -17
  58. package/esm2022/tableview/index.mjs +2 -1
  59. package/fesm2022/mediusinc-mng-commons-core.mjs +78 -17
  60. package/fesm2022/mediusinc-mng-commons-core.mjs.map +1 -1
  61. package/fesm2022/mediusinc-mng-commons-form.mjs +4 -14
  62. package/fesm2022/mediusinc-mng-commons-form.mjs.map +1 -1
  63. package/fesm2022/mediusinc-mng-commons-model.mjs +9 -4
  64. package/fesm2022/mediusinc-mng-commons-model.mjs.map +1 -1
  65. package/fesm2022/mediusinc-mng-commons-table-api.mjs +1 -2
  66. package/fesm2022/mediusinc-mng-commons-table-api.mjs.map +1 -1
  67. package/fesm2022/mediusinc-mng-commons-table.mjs +13 -41
  68. package/fesm2022/mediusinc-mng-commons-table.mjs.map +1 -1
  69. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs +72 -92
  70. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs.map +1 -1
  71. package/fesm2022/mediusinc-mng-commons-tableview.mjs +171 -69
  72. package/fesm2022/mediusinc-mng-commons-tableview.mjs.map +1 -1
  73. package/form/components/autocomplete/autocomplete.component.d.ts +1 -2
  74. package/i18n/en.json +21 -0
  75. package/i18n/sl.json +21 -0
  76. package/model/descriptors/model.descriptor.d.ts +4 -2
  77. package/package.json +1 -1
  78. package/table/api/descriptors/column.descriptor.d.ts +2 -5
  79. package/table/api/models/table.model.d.ts +1 -2
  80. package/table/components/table/table.component.d.ts +4 -12
  81. package/tableview/action/components/editor/injector-context/action-editor-injector-context.component.d.ts +2 -0
  82. package/tableview/api/action/descriptors/action.descriptor.d.ts +3 -4
  83. package/tableview/api/editor/descriptors/editor.descriptor.d.ts +8 -8
  84. package/tableview/api/editor/descriptors/field-action.descriptor.d.ts +3 -4
  85. package/tableview/api/editor/descriptors/field-base.descriptor.d.ts +11 -13
  86. package/tableview/api/editor/descriptors/field-group.descriptor.d.ts +14 -17
  87. package/tableview/api/editor/descriptors/field-lookup.descriptor.d.ts +5 -5
  88. package/tableview/api/editor/descriptors/field-many.descriptor.d.ts +4 -4
  89. package/tableview/api/editor/descriptors/field.descriptor.d.ts +4 -3
  90. package/tableview/api/editor/models/field.model.d.ts +3 -2
  91. package/tableview/api/editor/models/formly-field.model.d.ts +2 -0
  92. package/tableview/api/tableview/descriptors/tableview.descriptor.d.ts +8 -8
  93. package/tableview/editor/components/formly/fields/formly-field-fieldset/formly-field-fieldset.component.d.ts +5 -2
  94. package/tableview/editor/components/formly/fields/formly-field-tabs/formly-field-tabs.component.d.ts +5 -1
  95. package/tableview/editor/components/formly/fields/formly-field-type.abstract.component.d.ts +2 -1
  96. package/tableview/editor/components/formly/pipes/formly-field-label.pipe.d.ts +8 -0
  97. package/tableview/editor/components/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.d.ts +7 -3
  98. package/tableview/editor/helpers/editor-field.d.ts +2 -0
  99. package/tableview/editor/helpers/editor-formly.d.ts +4 -4
  100. package/tableview/index.d.ts +1 -0
  101. package/version-info.json +6 -6
  102. package/esm2022/core/services/local-storage-config.service.mjs +0 -29
@@ -11,7 +11,7 @@ import { Table, TableModule } from 'primeng/table';
11
11
  import { TooltipModule } from 'primeng/tooltip';
12
12
  import { NEVER, Subject, combineLatest, of, switchMap } from 'rxjs';
13
13
  import { filter } from 'rxjs/operators';
14
- import { ClassMapPipe, CommonsService, ComponentDirective, FilterMatchMode, I18nPropertyPipe, LocalStorageService, LoggerService, TemplateDirective, booleanOrUndefinedAttribute, toObservable as commonsToObservable, dataListParamsToUrlQuery, findTemplateByName, fromSubscribeError, fromTableLoadToDataListParams, fromUrlQueryToDataListParams, getErrorLogLevel, mergeDataListParamsWithDefaults } from '@mediusinc/mng-commons/core';
14
+ import { ClassMapPipe, CommonsService, CommonsStorageService, ComponentDirective, FilterMatchMode, I18nPropertyPipe, LoggerService, TemplateDirective, booleanOrUndefinedAttribute, toObservable as commonsToObservable, dataListParamsToUrlQuery, findTemplateByName, fromSubscribeError, fromTableLoadToDataListParams, fromUrlQueryToDataListParams, getErrorLogLevel, mergeDataListParamsWithDefaults } from '@mediusinc/mng-commons/core';
15
15
  import { FilterTypeEnum } from '@mediusinc/mng-commons/filter';
16
16
  import { TableDynamicDescriptorInst, TablePaginationModeEnum, TableSizeEnum, tableDescriptor } from '@mediusinc/mng-commons/table/api';
17
17
  import { tableNotificationError } from '../../helpers/notification';
@@ -39,7 +39,7 @@ export class TableComponent {
39
39
  this.translate = inject(TranslateService);
40
40
  this.messageService = inject(MessageService);
41
41
  this.commons = inject(CommonsService);
42
- this.localStorageService = inject(LocalStorageService);
42
+ this.storageService = inject(CommonsStorageService);
43
43
  this.dataListService = inject((DataListService));
44
44
  // metadata input
45
45
  this.descriptorInput = input.required({ alias: 'descriptor' });
@@ -49,7 +49,7 @@ export class TableComponent {
49
49
  this.loadingInput = input(undefined, { alias: 'loading', transform: booleanOrUndefinedAttribute });
50
50
  this.dataProvider = input();
51
51
  // extra features input
52
- this.useQueryParamsInput = input(false, { alias: 'useQueryParams' });
52
+ this.useQueryParams = input(false);
53
53
  this.cellClickEnabled = input(true);
54
54
  this.selectionMode = input('multiple');
55
55
  this.selectionEnabled = input(false);
@@ -83,14 +83,13 @@ export class TableComponent {
83
83
  this.footerTemplate = computed(() => findTemplateByName([...this.templates()], 'footer'));
84
84
  this.rowExpandTemplate = computed(() => findTemplateByName([...this.templates()], 'rowExpandContent'));
85
85
  // data provider and items
86
- this.useQueryParams = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? false : this.useQueryParamsInput()));
87
86
  this.isLazy = computed(() => this.dataProvider()?.isLazy === true);
88
87
  this.isPagination = computed(() => this.paginationMode() === TablePaginationModeEnum.Pagination);
89
88
  this.useQueryParamsInitialized = signal(false);
90
89
  // visual
91
90
  this.paginationMode = computed(() => {
92
91
  if (typeof this.descriptor().paginationMode !== 'undefined') {
93
- // descriptor choice is the most strong - if defined, use this value
92
+ // descriptor choice is the strongest - if defined, use this value
94
93
  return this.descriptor().paginationMode;
95
94
  }
96
95
  else if (typeof this.dataProvider() !== 'undefined') {
@@ -101,7 +100,6 @@ export class TableComponent {
101
100
  return TablePaginationModeEnum.None;
102
101
  }
103
102
  });
104
- this.infiniteScroll = computed(() => this.paginationMode() === TablePaginationModeEnum.InfiniteScroll);
105
103
  this.className = computed(() => {
106
104
  let className = this.descriptor().className ?? '';
107
105
  switch (this.descriptor().size) {
@@ -117,8 +115,6 @@ export class TableComponent {
117
115
  }
118
116
  return className;
119
117
  });
120
- this.tableFullHeightOffset = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? this.descriptor().tableFullHeightOffset ?? 315 : undefined));
121
- this.rowHeight = computed(() => (this.paginationMode() === TablePaginationModeEnum.InfiniteScroll ? this.descriptor().rowHeight ?? 45 : undefined));
122
118
  // data provider
123
119
  this.dataProviderService = computed(() => {
124
120
  const dataProvider = this.dataProvider();
@@ -130,26 +126,22 @@ export class TableComponent {
130
126
  this.descriptor = signal(tableDescriptor());
131
127
  this.localstorageKey = computed(() => {
132
128
  const descriptor = this.descriptor();
133
- return descriptor.model.typeName || descriptor.model.i18nBaseKey
134
- ? generateTableLayoutPrefsKey(descriptor.model.typeName ?? descriptor.model.i18nBaseKey, this.router.url, descriptor.identifier)
135
- : null;
129
+ return descriptor.model.i18nBaseKey ? generateTableLayoutPrefsKey(descriptor.model.i18nBaseKey, this.router.url, descriptor.identifier) : null;
136
130
  });
137
131
  this.layoutPrefsSaveCnt = signal(0);
138
132
  this.layoutPreferences = computed(() => {
139
133
  const lsKey = this.localstorageKey();
140
134
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
141
135
  const cnt = this.layoutPrefsSaveCnt(); // needed to force updates on user changes
142
- const layoutPrefs = lsKey ? this.localStorageService.getItem(this.cmpTypeName, lsKey) : undefined;
136
+ const layoutPrefs = lsKey ? this.storageService.getItem(this.cmpTypeName, lsKey) : undefined;
143
137
  return layoutPrefs ?? { columnWidths: {} };
144
138
  });
145
- this.columns = computed(() => this.computColumnsWithLayout());
139
+ this.columns = computed(() => this.computeColumnsWithLayout());
146
140
  this.visibleColumns = computed(() => this.columns().filter(col => col.isVisible));
147
141
  // filter, sort
148
142
  this.hasColumnFilters = computed(() => this.filterDescriptors().length > 0);
149
143
  this.filterDescriptors = computed(() => this.descriptor().filters);
150
144
  this.defaultParams = computed(() => this.computeDefaultDataListParams());
151
- this.isFilterChanged = false;
152
- this.isSortChanged = false;
153
145
  this.anyColumnVisible = computed(() => this.visibleColumns().length > 0);
154
146
  this.hasCustomLastColumn = computed(() => this.columnCustomLastComponent || this.columnCustomLastTemplate());
155
147
  this.hasLastColumn = computed(() => this.hasCustomLastColumn() || this.areColumnsToggleable() || this.areColumnsReorderable());
@@ -276,14 +268,6 @@ export class TableComponent {
276
268
  this.loadTableWithDataProvider(mergeDataListParamsWithDefaults(params, this.defaultParams()));
277
269
  }
278
270
  }
279
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
280
- onTableSort(event) {
281
- this.isSortChanged = true;
282
- }
283
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
284
- onTableFilter(event) {
285
- this.isFilterChanged = true;
286
- }
287
271
  onCellClick(event, col, item, idx) {
288
272
  if (!this.isCellClickEnabled()) {
289
273
  return;
@@ -333,19 +317,7 @@ export class TableComponent {
333
317
  if (descriptorInput instanceof TableDynamicDescriptorInst) {
334
318
  this.descriptor.set(descriptorInput.toTableDescriptorFromData(res));
335
319
  }
336
- if (this.infiniteScroll()) {
337
- let items = this.dataListService.data();
338
- if (this.isFilterChanged || this.isSortChanged) {
339
- items = [];
340
- }
341
- items.splice(paramsWithDefaults.offset ?? 0, paramsWithDefaults.limit ?? this.dataListService.rows(), ...(res?.data ?? []));
342
- this.dataListService.setData(items);
343
- }
344
- else {
345
- this.dataListService.setData(res?.data ?? [], res?.totalCount);
346
- }
347
- this.isFilterChanged = false;
348
- this.isSortChanged = false;
320
+ this.dataListService.setData(res?.data ?? [], res?.totalCount);
349
321
  this.dataListService.loading.set(false);
350
322
  },
351
323
  error: err => {
@@ -447,7 +419,7 @@ export class TableComponent {
447
419
  saveLayoutPreferences(layoutPrefs) {
448
420
  const key = this.localstorageKey();
449
421
  if (key) {
450
- this.localStorageService.setItem(this.cmpTypeName, key, layoutPrefs);
422
+ this.storageService.setItem(this.cmpTypeName, key, layoutPrefs);
451
423
  this.layoutPrefsSaveCnt.update(v => v + 1);
452
424
  }
453
425
  }
@@ -505,7 +477,7 @@ export class TableComponent {
505
477
  });
506
478
  return params;
507
479
  }
508
- computColumnsWithLayout() {
480
+ computeColumnsWithLayout() {
509
481
  const descriptor = this.descriptor();
510
482
  const layoutPrefs = this.layoutPreferences();
511
483
  // initialize columns with additional properties
@@ -536,12 +508,12 @@ export class TableComponent {
536
508
  resetDefaultLayout() {
537
509
  const key = this.localstorageKey();
538
510
  if (key) {
539
- this.localStorageService.removeItem(this.cmpTypeName, key);
511
+ this.storageService.removeItem(this.cmpTypeName, key);
540
512
  this.layoutPrefsSaveCnt.update(v => v + 1);
541
513
  }
542
514
  }
543
515
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
544
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TableComponent, isStandalone: true, selector: "mng-table", inputs: { descriptorInput: { classPropertyName: "descriptorInput", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, useQueryParamsInput: { classPropertyName: "useQueryParamsInput", publicName: "useQueryParams", isSignal: true, isRequired: false, transformFunction: null }, cellClickEnabled: { classPropertyName: "cellClickEnabled", publicName: "cellClickEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectionEnabled: { classPropertyName: "selectionEnabled", publicName: "selectionEnabled", isSignal: true, isRequired: false, transformFunction: null }, rowReorderEnabledInput: { classPropertyName: "rowReorderEnabledInput", publicName: "rowReorderEnabled", isSignal: true, isRequired: false, transformFunction: null }, columnLastMinWidth: { classPropertyName: "columnLastMinWidth", publicName: "columnLastMinWidth", isSignal: true, isRequired: false, transformFunction: null }, captionComponent: { classPropertyName: "captionComponent", publicName: "captionComponent", isSignal: true, isRequired: false, transformFunction: null }, columnCustomLastComponent: { classPropertyName: "columnCustomLastComponent", publicName: "columnCustomLastComponent", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFieldsInput: { classPropertyName: "globalFilterFieldsInput", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableLoad: "tableLoad", cellClick: "cellClick", selectionChange: "selectionChange", captionComponentInstance: "captionComponentInstance", columnCustomLastComponentInstance: "columnCustomLastComponentInstance", rowReorder: "rowReorder" }, providers: [DataListService], queries: [{ propertyName: "templates", predicate: TemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "components", predicate: (ComponentDirective), descendants: true, isSignal: true }, { propertyName: "primeTable", first: true, predicate: Table, descendants: true, isSignal: true }], ngImport: i0, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\"\n (onRowReorder)=\"onRowReorder($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight()\"\n [pReorderableRow]=\"idx\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"columnsColspan()\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "pipe", type: I18nPropertyPipe, name: "mngI18nProperty" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "pipe", type: ClassMapPipe, name: "mngClassMap" }, { kind: "pipe", type: LocaleDefaultRowClassPipe, name: "mngLocaleDefaultRowClass" }, { kind: "component", type: TableColumnFilterFullComponent, selector: "mng-table-column-filter-full", inputs: ["descriptor"] }, { kind: "pipe", type: TableColumnFilterClassPipe, name: "mngTableColumnFilterClass" }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i1.RowToggler, selector: "[pRowToggler]", inputs: ["pRowToggler", "pRowTogglerDisabled"] }, { kind: "directive", type: i1.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i1.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i1.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i1.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "directive", type: i1.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i1.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i3.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
516
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TableComponent, isStandalone: true, selector: "mng-table", inputs: { descriptorInput: { classPropertyName: "descriptorInput", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, useQueryParams: { classPropertyName: "useQueryParams", publicName: "useQueryParams", isSignal: true, isRequired: false, transformFunction: null }, cellClickEnabled: { classPropertyName: "cellClickEnabled", publicName: "cellClickEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectionEnabled: { classPropertyName: "selectionEnabled", publicName: "selectionEnabled", isSignal: true, isRequired: false, transformFunction: null }, rowReorderEnabledInput: { classPropertyName: "rowReorderEnabledInput", publicName: "rowReorderEnabled", isSignal: true, isRequired: false, transformFunction: null }, columnLastMinWidth: { classPropertyName: "columnLastMinWidth", publicName: "columnLastMinWidth", isSignal: true, isRequired: false, transformFunction: null }, captionComponent: { classPropertyName: "captionComponent", publicName: "captionComponent", isSignal: true, isRequired: false, transformFunction: null }, columnCustomLastComponent: { classPropertyName: "columnCustomLastComponent", publicName: "columnCustomLastComponent", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFieldsInput: { classPropertyName: "globalFilterFieldsInput", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableLoad: "tableLoad", cellClick: "cellClick", selectionChange: "selectionChange", captionComponentInstance: "captionComponentInstance", columnCustomLastComponentInstance: "columnCustomLastComponentInstance", rowReorder: "rowReorder" }, providers: [DataListService], queries: [{ propertyName: "templates", predicate: TemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "components", predicate: (ComponentDirective), descendants: true, isSignal: true }, { propertyName: "primeTable", first: true, predicate: Table, descendants: true, isSignal: true }], ngImport: i0, template: "<div>\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination()\"\n [rows]=\"dataListService.rows()\"\n [first]=\"dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onRowReorder)=\"onRowReorder($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [pReorderableRow]=\"idx\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "pipe", type: I18nPropertyPipe, name: "mngI18nProperty" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "pipe", type: ClassMapPipe, name: "mngClassMap" }, { kind: "pipe", type: LocaleDefaultRowClassPipe, name: "mngLocaleDefaultRowClass" }, { kind: "component", type: TableColumnFilterFullComponent, selector: "mng-table-column-filter-full", inputs: ["descriptor"] }, { kind: "pipe", type: TableColumnFilterClassPipe, name: "mngTableColumnFilterClass" }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i1.RowToggler, selector: "[pRowToggler]", inputs: ["pRowToggler", "pRowTogglerDisabled"] }, { kind: "directive", type: i1.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i1.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i1.TableRadioButton, selector: "p-tableRadioButton", inputs: ["disabled", "value", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1.TableCheckbox, selector: "p-tableCheckbox", inputs: ["disabled", "value", "index", "inputId", "name", "required", "ariaLabel"] }, { kind: "component", type: i1.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "directive", type: i1.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i1.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i3.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
545
517
  }
546
518
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TableComponent, decorators: [{
547
519
  type: Component,
@@ -563,6 +535,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
563
535
  TooltipModule,
564
536
  TranslateModule,
565
537
  FormsModule
566
- ], providers: [DataListService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.height]=\"tableFullHeightOffset() ? 'calc(100vh - ' + tableFullHeightOffset() + 'px)' : null\">\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination() && !infiniteScroll()\"\n [rows]=\"infiniteScroll() ? 20 : dataListService.rows()\"\n [first]=\"infiniteScroll() ? 0 : dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"infiniteScroll() ? undefined : dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"!infiniteScroll()\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n [virtualScroll]=\"infiniteScroll()\"\n [virtualScrollItemSize]=\"rowHeight()\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onSort)=\"onTableSort($event)\"\n (onFilter)=\"onTableFilter($event)\"\n (onRowReorder)=\"onRowReorder($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [style.height.px]=\"rowHeight()\"\n [pReorderableRow]=\"idx\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr [style.height.px]=\"rowHeight()\">\n <td [attr.colspan]=\"columnsColspan()\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n" }]
538
+ ], providers: [DataListService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (!useQueryParams() || useQueryParamsInitialized()) {\n <p-table\n [value]=\"dataListService.data()\"\n [dataKey]=\"descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"dataListService.loading()\"\n [paginator]=\"isPagination()\"\n [rows]=\"dataListService.rows()\"\n [first]=\"dataListService.offset()\"\n [totalRecords]=\"dataListService.count()\"\n [rowsPerPageOptions]=\"dataListService.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"dataListService.sortMeta()\"\n [filters]=\"dataListService.filterMeta()\"\n [globalFilterFields]=\"dataListService.globalFilterFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [rowHover]=\"descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"descriptor().hasResizableColumns\"\n [columnResizeMode]=\"descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n (onColResize)=\"onTableColumnResize($event)\"\n (onColReorder)=\"onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onRowReorder)=\"onRowReorder($event)\">\n @if (captionTemplate() || captionComponent() || descriptor().title) {\n <ng-template pTemplate=\"caption\">\n @if (captionTemplate()) {\n <ng-container *ngTemplateOutlet=\"captionTemplate()\"></ng-container>\n } @else if (captionComponent()) {\n <div [mngComponent]=\"captionComponent()\" (instanceCreated)=\"captionComponentInstance.emit($event)\"></div>\n } @else {\n <h5 class=\"p-0 m-0\">{{ descriptor().title }}</h5>\n }\n </ng-template>\n }\n <ng-template pTemplate=\"header\">\n @if (!descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"descriptor().headerClassName\">\n\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (descriptor().rowExpandable) {\n <th scope=\"col\" class=\"col-1\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n <div class=\"flex justify-content-between align-items-center\">\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n <p-sortIcon [field]=\"col.descriptor.property\"></p-sortIcon>\n </div>\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n {{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"column-custom-last text-right\">\n @if (descriptor().hasResizableColumns) {\n <p-multiSelect\n #columnToggleMultiselect\n styleClass=\"p-button-primary mng-table-columns-multiselect\"\n appendTo=\"body\"\n dataKey=\"id\"\n tooltipPosition=\"left\"\n placeholder=\"\"\n dropdownIcon=\"pi pi-sliders-h\"\n [filter]=\"false\"\n [options]=\"columns()\"\n [ngModel]=\"visibleColumns()\"\n [pTooltip]=\"'mngTable.adjustTable' | translate\"\n [displaySelectedLabel]=\"false\"\n (onChange)=\"onColumnToggle($event)\">\n <ng-template pTemplate=\"filter\">\n <div class=\"p-checkbox p-component ml-1\" [ngClass]=\"{'p-checkbox-disabled': !areColumnsToggleable}\">\n <div class=\"p-hidden-accessible\">\n <input\n type=\"checkbox\"\n readonly=\"readonly\"\n [checked]=\"columnToggleMultiselect.allSelected\"\n (focus)=\"columnToggleMultiselect.onHeaderCheckboxFocus()\"\n (blur)=\"columnToggleMultiselect.onHeaderCheckboxBlur()\"\n (keydown.space)=\"columnToggleMultiselect.onToggleAll($event)\"\n [disabled]=\"!areColumnsToggleable\" />\n </div>\n <div\n class=\"p-checkbox-box\"\n role=\"checkbox\"\n [attr.aria-checked]=\"columnToggleMultiselect.allSelected\"\n [ngClass]=\"{\n 'p-highlight': anyColumnVisible()\n }\"\n (click)=\"onColumnToggleAll()\">\n <span class=\"p-checkbox-icon\" [ngClass]=\"{'pi pi-check': anyColumnVisible()}\"></span>\n </div>\n </div>\n <p-button\n icon=\"pi pi-replay\"\n styleClass=\"p-button-secondary\"\n [pTooltip]=\"'mngTable.resetLayout' | translate\"\n tooltipPosition=\"left\"\n (click)=\"resetDefaultLayout()\"></p-button>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n {{ item.descriptor.title ?? (item.descriptor.property | mngI18nProperty: descriptor().model) | translate }}\n </ng-template>\n </p-multiSelect>\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"col.filter?.columnClassName | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : col.filter?.columnWidth ?? col.descriptor.width ?? null\"\n [style.min-width.px]=\"col.width ? null : col.filter?.columnMinWidth ?? col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter) {\n <mng-table-column-filter-full [descriptor]=\"col.filter\"></mng-table-column-filter-full>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th class=\"column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template pTemplate=\"body\" let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [pReorderableRow]=\"idx\"\n [ngClass]=\"descriptor().rowClassName | mngClassMap: descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: descriptor() : item\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (descriptor().rowExpandable) {\n <td class=\"col-1\">\n @if (!descriptor().rowExpandableProperty || item[descriptor().rowExpandableProperty!]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n class=\"p-button-text p-button-rounded p-button-plain\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableColumnFilterClass: col.filter : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <span class=\"p-column-title\">{{ col.descriptor.title ?? (col.descriptor.property | mngI18nProperty: descriptor().model) | translate }}</span>\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"column-custom-last justify-content-end text-right\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"descriptor().actionColumnFrozen ?? true\"\n alignFrozen=\"right\">\n @if (columnCustomLastTemplate()) {\n <ng-container *ngTemplateOutlet=\"columnCustomLastTemplate(); context: {rowItem: item, rowIndex: idx}\"></ng-container>\n } @else if (columnCustomLastComponent()) {\n <div [mngComponent]=\"columnCustomLastComponent()\" (instanceCreated)=\"columnCustomLastComponentInstance.emit($event)\"></div>\n }\n </td>\n }\n </tr>\n </ng-template>\n @if (descriptor().rowExpandable) {\n <ng-template pTemplate=\"rowexpansion\" let-item>\n <tr>\n <td class=\"col-1\"></td>\n <td [colSpan]=\"descriptor().rowExpandableColSpan\">\n <ng-container *ngTemplateOutlet=\"rowExpandTemplate(); context: {rowItem: item}\"></ng-container>\n </td>\n </tr>\n </ng-template>\n }\n <ng-template pTemplate=\"loadingicon\">\n <div class=\"flex flex-column align-items-center\">\n @if (descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + descriptor().loadingIcon\"></i>\n }\n @if (descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': descriptor().loadingIcon}\">\n {{ descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template pTemplate=\"loadingbody\">\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton [ngStyle]=\"{width: '100%'}\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n {{ 'mngTable.noItems' | translate }}\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template pTemplate=\"summary\">\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: dataListService.data(), totalCount: dataListService.count()}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n" }]
567
539
  }], ctorParameters: () => [] });
568
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUUsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUtSLGVBQWUsRUFDZixRQUFRLEVBQ1IsZUFBZSxFQUNmLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUNULFlBQVksRUFDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsb0JBQW9CLEVBQUUsWUFBWSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQVUsTUFBTSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFbEksT0FBTyxFQUFDLGVBQWUsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3RFLE9BQU8sRUFBaUIsY0FBYyxFQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1QyxPQUFPLEVBQXlCLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDOUUsT0FBTyxFQUFDLEtBQUssRUFBK0MsV0FBVyxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUNwSCxPQUFP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RkFDOUIsMEJBQTBCLGlFQUMxQixXQUFXLHk0R0FDWCxpQkFBaUIsbzFDQUNqQixZQUFZLDJrQkFDWixhQUFhLHFYQUNiLGVBQWUsMkZBQ2YsV0FBVzs7MkZBS04sY0FBYztrQkExQjFCLFNBQVM7aUNBQ00sSUFBSSxZQUNOLFdBQVcsV0FFWjt3QkFDTCxTQUFTO3dCQUNULGtCQUFrQjt3QkFDbEIsZ0JBQWdCO3dCQUNoQixPQUFPO3dCQUNQLE9BQU87d0JBQ1AsZ0JBQWdCO3dCQUNoQix5QkFBeUI7d0JBQ3pCLFlBQVk7d0JBQ1oseUJBQXlCO3dCQUN6Qiw4QkFBOEI7d0JBQzlCLDBCQUEwQjt3QkFDMUIsV0FBVzt3QkFDWCxpQkFBaUI7d0JBQ2pCLFlBQVk7d0JBQ1osYUFBYTt3QkFDYixlQUFlO3dCQUNmLFdBQVc7cUJBQ2QsYUFDVSxDQUFDLGVBQWUsQ0FBQyxtQkFDWCx1QkFBdUIsQ0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBc3luY1BpcGUsIE5nQ2xhc3MsIE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENvbXBvbmVudCxcbiAgICBJbmplY3RvcixcbiAgICBPbkRlc3Ryb3ksXG4gICAgU2lnbmFsLFxuICAgIFRlbXBsYXRlUmVmLFxuICAgIFR5cGUsXG4gICAgYWZ0ZXJOZXh0UmVuZGVyLFxuICAgIGNvbXB1dGVkLFxuICAgIGNvbnRlbnRDaGlsZHJlbixcbiAgICBlZmZlY3QsXG4gICAgaW5qZWN0LFxuICAgIGlucHV0LFxuICAgIG91dHB1dCxcbiAgICBzaWduYWwsXG4gICAgdmlld0NoaWxkLFxuICAgIHZpZXdDaGlsZHJlblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7b3V0cHV0RnJvbU9ic2VydmFibGUsIHRvT2JzZXJ2YWJsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHtGb3Jtc01vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgTmF2aWdhdGlvbkNhbmNlbCwgTmF2aWdhdGlvbkVuZCwgTmF2aWdhdGlvbkVycm9yLCBOYXZpZ2F0aW9uU3RhcnQsIFBhcmFtcywgUm91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQge1RyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge0ZpbHRlck1ldGFkYXRhLCBNZXNzYWdlU2VydmljZSwgU29ydE1ldGF9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7QnV0dG9uTW9kdWxlfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQge011bHRpU2VsZWN0Q2hhbmdlRXZlbnQsIE11bHRpU2VsZWN0TW9kdWxlfSBmcm9tICdwcmltZW5nL211bHRpc2VsZWN0JztcbmltcG9ydCB7VGFibGUsIFRhYmxlQ29sdW1uUmVvcmRlckV2ZW50LCBUYWJsZUxhenlMb2FkRXZlbnQsIFRhYmxlTW9kdWxlLCBUYWJsZVJvd1Jlb3JkZXJFdmVudH0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQge1Rvb2x0aXBNb2R1bGV9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5pbXBvcnQge05FVkVSLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGNvbWJpbmVMYXRlc3QsIG9mLCBzd2l0Y2hNYXB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtmaWx0ZXJ9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgICBDbGFzc01hcFBpcGUsXG4gICAgQ29tbW9uc1NlcnZpY2UsXG4gICAgQ29tcG9uZW50RGlyZWN0aXZlLFxuICAgIERhdGFMaXN0UGFyYW1zLFxuICAgIERhdGFMaXN0UmVzdWx0LFxuICAgIEZpbHRlck1hdGNoTW9kZSxcbiAgICBJMThuUHJvcGVydHlQaXBlLFxuICAgIExvY2FsU3RvcmFnZVNlcnZpY2UsXG4gICAgTG9nZ2VyU2VydmljZSxcbiAgICBUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgICBib29sZWFuT3JVbmRlZmluZWRBdHRyaWJ1dGUsXG4gICAgdG9PYnNlcnZhYmxlIGFzIGNvbW1vbnNUb09ic2VydmFibGUsXG4gICAgZGF0YUxpc3RQYXJhbXNUb1VybFF1ZXJ5LFxuICAgIGZpbmRUZW1wbGF0ZUJ5TmFtZSxcbiAgICBmcm9tU3Vic2NyaWJlRXJyb3IsXG4gICAgZnJvbVRhYmxlTG9hZFRvRGF0YUxpc3RQYXJhbXMsXG4gICAgZnJvbVVybFF1ZXJ5VG9EYXRhTGlzdFBhcmFtcyxcbiAgICBnZXRFcnJvckxvZ0xldmVsLFxuICAgIG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHNcbn0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9jb3JlJztcbmltcG9ydCB7RmlsdGVyTG9va3VwRGVzY3JpcHRvciwgRmlsdGVyVHlwZUVudW19IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvZmlsdGVyJztcbmltcG9ydCB7XG4gICAgQ29sdW1uRGVzY3JpcHRvcixcbiAgICBJVGFibGVEYXRhUHJvdmlkZXIsXG4gICAgVGFibGVDZWxsQ2xpY2tFdmVudCxcbiAgICBUYWJsZURlc2NyaXB0b3JJbnN0LFxuICAgIFRhYmxlRHluYW1pY0Rlc2NyaXB0b3JJbnN0LFxuICAgIFRhYmxlTGF5b3V0UHJlZmVyZW5jZXMsXG4gICAgVGFibGVMb2FkRXZlbnQsXG4gICAgVGFibGVQYWdpbmF0aW9uTW9kZUVudW0sXG4gICAgVGFibGVTaXplRW51bSxcbiAgICB0YWJsZURlc2NyaXB0b3Jcbn0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy90YWJsZS9hcGknO1xuXG5pbXBvcnQge3RhYmxlTm90aWZpY2F0aW9uRXJyb3J9IGZyb20gJy4uLy4uL2hlbHBlcnMvbm90aWZpY2F0aW9uJztcbmltcG9ydCB7Z2VuZXJhdGVUYWJsZUxheW91dFByZWZzS2V5fSBmcm9tICcuLi8uLi9oZWxwZXJzL3RhYmxlLWxheW91dC1wcmVmcyc7XG5pbXBvcnQge0NvbHVtbldpdGhQcmVmZXJlbmNlc30gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi1wcmVmZXJlbmNlcy5tb2RlbCc7XG5pbXBvcnQge0xvY2FsZURlZmF1bHRSb3dDbGFzc1BpcGV9IGZyb20gJy4uLy4uL3BpcGVzL2xvY2FsZS1kZWZhdWx0LXJvdy1jbGFzcy5waXBlJztcbmltcG9ydCB7VGFibGVDb2x1bW5GaWx0ZXJDbGFzc1BpcGV9IGZyb20gJy4uLy4uL3BpcGVzL3RhYmxlLWNvbHVtbi1maWx0ZXItY2xhc3MucGlwZSc7XG5pbXBvcnQge0RhdGFMaXN0U2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS1saXN0LnNlcnZpY2UnO1xuaW1wb3J0IHtUYWJsZUNvbHVtbkZpbHRlckZ1bGxDb21wb25lbnR9IGZyb20gJy4uL2NvbHVtbi1maWx0ZXItZnVsbC9jb2x1bW4tZmlsdGVyLWZ1bGwuY29tcG9uZW50JztcbmltcG9ydCB7VGFibGVDb2x1bW5WYWx1ZUNvbXBvbmVudH0gZnJvbSAnLi4vY29sdW1uLXZhbHVlL2NvbHVtbi12YWx1ZS5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAnbW5nLXRhYmxlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQXN5bmNQaXBlLFxuICAgICAgICBDb21wb25lbnREaXJlY3RpdmUsXG4gICAgICAgIEkxOG5Qcm9wZXJ0eVBpcGUsXG4gICAgICAgIE5nQ2xhc3MsXG4gICAgICAgIE5nU3R5bGUsXG4gICAgICAgIE5nVGVtcGxhdGVPdXRsZXQsXG4gICAgICAgIFRhYmxlQ29sdW1uVmFsdWVDb21wb25lbnQsXG4gICAgICAgIENsYXNzTWFwUGlwZSxcbiAgICAgICAgTG9jYWxlRGVmYXVsdFJvd0NsYXNzUGlwZSxcbiAgICAgICAgVGFibGVDb2x1bW5GaWx0ZXJGdWxsQ29tcG9uZW50LFxuICAgICAgICBUYWJsZUNvbHVtbkZpbHRlckNsYXNzUGlwZSxcbiAgICAgICAgVGFibGVNb2R1bGUsXG4gICAgICAgIE11bHRpU2VsZWN0TW9kdWxlLFxuICAgICAgICBCdXR0b25Nb2R1bGUsXG4gICAgICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgICAgICAgRm9ybXNNb2R1bGVcbiAgICBdLFxuICAgIHByb3ZpZGVyczogW0RhdGFMaXN0U2VydmljZV0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQ8SXRlbSA9IGFueSwgU2VydmljZSA9IHVuZGVmaW5lZCwgU29ydHMgPSBhbnksIEZpbHRlcnMgZXh0ZW5kcyBrZXlvZiBhbnkgPSBhbnk+IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgY21wVHlwZU5hbWUgPSAnVGFibGVDb21wb25lbnQnO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBpbmplY3QoTG9nZ2VyU2VydmljZSkuY3JlYXRlKHRoaXMuY21wVHlwZU5hbWUpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZSA9IGluamVjdChBY3RpdmF0ZWRSb3V0ZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xhdGUgPSBpbmplY3QoVHJhbnNsYXRlU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBtZXNzYWdlU2VydmljZSA9IGluamVjdChNZXNzYWdlU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb21tb25zID0gaW5qZWN0KENvbW1vbnNTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvY2FsU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoTG9jYWxTdG9yYWdlU2VydmljZSk7XG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGFMaXN0U2VydmljZSA9IGluamVjdChEYXRhTGlzdFNlcnZpY2U8SXRlbT4pO1xuXG4gICAgLy8gbWV0YWRhdGEgaW5wdXRcbiAgICBwdWJsaWMgZGVzY3JpcHRvcklucHV0ID0gaW5wdXQucmVxdWlyZWQ8VGFibGVEZXNjcmlwdG9ySW5zdDxJdGVtLCBTb3J0cywgRmlsdGVycz4+KHthbGlhczogJ2Rlc2NyaXB0b3InfSk7XG5cbiAgICAvLyBkYXRhIHNvdXJjZSBpbnB1dHNcbiAgICBwdWJsaWMgaXRlbXMgPSBpbnB1dDxJdGVtW10+KCk7XG4gICAgcHVibGljIHJlc3VsdCA9IGlucHV0PERhdGFMaXN0UmVzdWx0PEl0ZW0+PigpO1xuICAgIHB1YmxpYyBsb2FkaW5nSW5wdXQgPSBpbnB1dCh1bmRlZmluZWQsIHthbGlhczogJ2xvYWRpbmcnLCB0cmFuc2Zvcm06IGJvb2xlYW5PclVuZGVmaW5lZEF0dHJpYnV0ZX0pO1xuICAgIHB1YmxpYyBkYXRhUHJvdmlkZXIgPSBpbnB1dDxJVGFibGVEYXRhUHJvdmlkZXI8SXRlbSwgU2VydmljZSwgU29ydHMsIEZpbHRlcnM+PigpO1xuXG4gICAgLy8gZXh0cmEgZmVhdHVyZXMgaW5wdXRcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXNJbnB1dCA9IGlucHV0KGZhbHNlLCB7YWxpYXM6ICd1c2VRdWVyeVBhcmFtcyd9KTtcbiAgICBwdWJsaWMgY2VsbENsaWNrRW5hYmxlZCA9IGlucHV0KHRydWUpO1xuICAgIHB1YmxpYyBzZWxlY3Rpb25Nb2RlID0gaW5wdXQ8J3NpbmdsZScgfCAnbXVsdGlwbGUnPignbXVsdGlwbGUnKTtcbiAgICBwdWJsaWMgc2VsZWN0aW9uRW5hYmxlZCA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgcm93UmVvcmRlckVuYWJsZWRJbnB1dCA9IGlucHV0PGJvb2xlYW4+KHRydWUsIHthbGlhczogJ3Jvd1Jlb3JkZXJFbmFibGVkJ30pO1xuICAgIHB1YmxpYyByb3dSZW9yZGVyRW5hYmxlZCA9IGNvbXB1dGVkPGJvb2xlYW4+KCgpID0+IHRoaXMucm93UmVvcmRlckVuYWJsZWRJbnB1dCgpICYmIHRoaXMuZGVzY3JpcHRvcigpLnJvd1Jlb3JkZXJhYmxlKTtcblxuICAgIC8vIHN0eWxpbmdcbiAgICBwdWJsaWMgY29sdW1uTGFzdE1pbldpZHRoID0gaW5wdXQ8bnVtYmVyPigpO1xuICAgIHB1YmxpYyBjb2x1bW5zQ29sc3BhbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMudmlzaWJsZUNvbHVtbnMoKS5sZW5ndGggKyAodGhpcy5oYXNMYXN0Q29sdW1uKCkgPyAxIDogMCkgKyAodGhpcy5zZWxlY3Rpb25FbmFibGVkKCkgPyAxIDogMCkgKyAodGhpcy5yb3dSZW9yZGVyRW5hYmxlZCgpID8gMSA6IDApKTtcblxuICAgIC8vIGNvbXBvbmVudCBpbnB1dHNcbiAgICBwdWJsaWMgY2FwdGlvbkNvbXBvbmVudCA9IGlucHV0PFR5cGU8YW55Pj4oKTtcbiAgICBwdWJsaWMgY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCA9IGlucHV0PFR5cGU8YW55Pj4oKTtcbiAgICBwdWJsaWMgZ2xvYmFsRmlsdGVyRmllbGRzSW5wdXQgPSBpbnB1dDxzdHJpbmdbXSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkLCB7YWxpYXM6ICdnbG9iYWxGaWx0ZXJGaWVsZHMnfSk7XG5cbiAgICAvLyBjZWxsIGNsaWNrXG4gICAgcHJpdmF0ZSBjZWxsQ2xpY2tTdWJqZWN0ID0gbmV3IFN1YmplY3Q8VGFibGVDZWxsQ2xpY2tFdmVudDxJdGVtPj4oKTtcbiAgICBwdWJsaWMgaXNDZWxsQ2xpY2tPYnNlcnZlZCA9IHNpZ25hbCh0aGlzLmNlbGxDbGlja1N1YmplY3Qub2JzZXJ2ZWQpO1xuICAgIHB1YmxpYyBpc0NlbGxDbGlja0VuYWJsZWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNlbGxDbGlja0VuYWJsZWQoKSAmJiB0aGlzLmlzQ2VsbENsaWNrT2JzZXJ2ZWQoKSk7XG5cbiAgICAvLyBldmVudCBvdXRwdXRzXG4gICAgcHVibGljIHRhYmxlTG9hZCA9IG91dHB1dDxUYWJsZUxvYWRFdmVudD4oKTtcbiAgICBwdWJsaWMgY2VsbENsaWNrID0gb3V0cHV0RnJvbU9ic2VydmFibGUodGhpcy5jZWxsQ2xpY2tTdWJqZWN0KTtcbiAgICBwdWJsaWMgc2VsZWN0aW9uQ2hhbmdlID0gb3V0cHV0PEFycmF5PEl0ZW0+PigpO1xuICAgIHB1YmxpYyBjYXB0aW9uQ29tcG9uZW50SW5zdGFuY2UgPSBvdXRwdXQ8YW55PigpO1xuICAgIHB1YmxpYyBjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50SW5zdGFuY2UgPSBvdXRwdXQ8YW55PigpO1xuICAgIHB1YmxpYyByb3dSZW9yZGVyID0gb3V0cHV0PFRhYmxlUm93UmVvcmRlckV2ZW50PigpO1xuXG4gICAgLy8gY29udGVudCBhbmQgdmlldyBxdWVyaWVzXG4gICAgcHVibGljIHRlbXBsYXRlcyA9IGNvbnRlbnRDaGlsZHJlbihUZW1wbGF0ZURpcmVjdGl2ZSk7XG4gICAgcHVibGljIGNvbXBvbmVudHMgPSB2aWV3Q2hpbGRyZW4oQ29tcG9uZW50RGlyZWN0aXZlPGFueT4pO1xuICAgIHB1YmxpYyBwcmltZVRhYmxlID0gdmlld0NoaWxkLnJlcXVpcmVkKFRhYmxlKTtcblxuICAgIC8vIHRlbXBsYXRlc1xuICAgIHB1YmxpYyBjYXB0aW9uVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnY2FwdGlvbicpKTtcbiAgICBwdWJsaWMgY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlOiBTaWduYWw8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+ID0gY29tcHV0ZWQoKCkgPT4gZmluZFRlbXBsYXRlQnlOYW1lKFsuLi50aGlzLnRlbXBsYXRlcygpXSwgJ2NvbHVtbkN1c3RvbUxhc3QnKSk7XG4gICAgcHVibGljIGZvb3RlclRlbXBsYXRlOiBTaWduYWw8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+ID0gY29tcHV0ZWQoKCkgPT4gZmluZFRlbXBsYXRlQnlOYW1lKFsuLi50aGlzLnRlbXBsYXRlcygpXSwgJ2Zvb3RlcicpKTtcbiAgICBwdWJsaWMgcm93RXhwYW5kVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAncm93RXhwYW5kQ29udGVudCcpKTtcblxuICAgIC8vIGRhdGEgcHJvdmlkZXIgYW5kIGl0ZW1zXG4gICAgcHVibGljIHVzZVF1ZXJ5UGFyYW1zID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMucGFnaW5hdGlvbk1vZGUoKSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwgPyBmYWxzZSA6IHRoaXMudXNlUXVlcnlQYXJhbXNJbnB1dCgpKSk7XG4gICAgcHVibGljIGlzTGF6eSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGF0YVByb3ZpZGVyKCk/LmlzTGF6eSA9PT0gdHJ1ZSk7XG4gICAgcHVibGljIGlzUGFnaW5hdGlvbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMucGFnaW5hdGlvbk1vZGUoKSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uUGFnaW5hdGlvbik7XG4gICAgcHVibGljIHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQgPSBzaWduYWwoZmFsc2UpO1xuXG4gICAgLy8gdmlzdWFsXG4gICAgcHJpdmF0ZSBwYWdpbmF0aW9uTW9kZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmRlc2NyaXB0b3IoKS5wYWdpbmF0aW9uTW9kZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIC8vIGRlc2NyaXB0b3IgY2hvaWNlIGlzIHRoZSBtb3N0IHN0cm9uZyAtIGlmIGRlZmluZWQsIHVzZSB0aGlzIHZhbHVlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXNjcmlwdG9yKCkucGFnaW5hdGlvbk1vZGU7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuZGF0YVByb3ZpZGVyKCkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAvLyB3aGVuIGRhdGEgcHJvdmlkZXIgaXMgdXNlZCwgdXNlIHBhZ2luYXRpb25cbiAgICAgICAgICAgIHJldHVybiBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5QYWdpbmF0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLk5vbmU7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBwdWJsaWMgaW5maW5pdGVTY3JvbGwgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnBhZ2luYXRpb25Nb2RlKCkgPT09IFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLkluZmluaXRlU2Nyb2xsKTtcbiAgICBwdWJsaWMgY2xhc3NOYW1lID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBsZXQgY2xhc3NOYW1lID0gdGhpcy5kZXNjcmlwdG9yKCkuY2xhc3NOYW1lID8/ICcnO1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZGVzY3JpcHRvcigpLnNpemUpIHtcbiAgICAgICAgICAgIGNhc2UgVGFibGVTaXplRW51bS5TbWFsbDpcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gJyBwLWRhdGF0YWJsZS1zbSc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFRhYmxlU2l6ZUVudW0uTGFyZ2U6XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgcC1kYXRhdGFibGUtbGcnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IoKS5oYXNHcmlkbGluZXMpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLWdyaWRsaW5lcyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgICB9KTtcbiAgICBwdWJsaWMgdGFibGVGdWxsSGVpZ2h0T2Zmc2V0ID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMucGFnaW5hdGlvbk1vZGUoKSA9PT0gVGFibGVQYWdpbmF0aW9uTW9kZUVudW0uSW5maW5pdGVTY3JvbGwgPyB0aGlzLmRlc2NyaXB0b3IoKS50YWJsZUZ1bGxIZWlnaHRPZmZzZXQgPz8gMzE1IDogdW5kZWZpbmVkKSk7XG4gICAgcHVibGljIHJvd0hlaWdodCA9IGNvbXB1dGVkKCgpID0+ICh0aGlzLnBhZ2luYXRpb25Nb2RlKCkgPT09IFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLkluZmluaXRlU2Nyb2xsID8gdGhpcy5kZXNjcmlwdG9yKCkucm93SGVpZ2h0ID8/IDQ1IDogdW5kZWZpbmVkKSk7XG5cbiAgICAvLyBkYXRhIHByb3ZpZGVyXG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXJTZXJ2aWNlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhUHJvdmlkZXIgPSB0aGlzLmRhdGFQcm92aWRlcigpO1xuICAgICAgICByZXR1cm4gZGF0YVByb3ZpZGVyPy5zZXJ2aWNlVHlwZSA/IHRoaXMuaW5qZWN0b3IuZ2V0PGFueT4oZGF0YVByb3ZpZGVyLnNlcnZpY2VUeXBlKSA6IG51bGw7XG4gICAgfSk7XG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50PzogVGFibGVMYXp5TG9hZEV2ZW50O1xuICAgIHByaXZhdGUgbGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24gPSAwO1xuICAgIHByaXZhdGUgbGF0ZXN0UGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXM7XG4gICAgcHJpdmF0ZSBsYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHNWZXJzaW9uID0gMDtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlclN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICAgIC8vIGRlc2NyaXB0b3JzXG4gICAgcHVibGljIGRlc2NyaXB0b3IgPSBzaWduYWw8VGFibGVEZXNjcmlwdG9ySW5zdDxhbnksIGFueSwgYW55Pj4odGFibGVEZXNjcmlwdG9yPHN0cmluZywgc3RyaW5nLCBzdHJpbmc+KCkpO1xuICAgIHByaXZhdGUgbG9jYWxzdG9yYWdlS2V5ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gdGhpcy5kZXNjcmlwdG9yKCk7XG4gICAgICAgIHJldHVybiBkZXNjcmlwdG9yLm1vZGVsLnR5cGVOYW1lIHx8IGRlc2NyaXB0b3IubW9kZWwuaTE4bkJhc2VLZXlcbiAgICAgICAgICAgID8gZ2VuZXJhdGVUYWJsZUxheW91dFByZWZzS2V5KGRlc2NyaXB0b3IubW9kZWwudHlwZU5hbWUgPz8gZGVzY3JpcHRvci5tb2RlbC5pMThuQmFzZUtleSwgdGhpcy5yb3V0ZXIudXJsLCBkZXNjcmlwdG9yLmlkZW50aWZpZXIpXG4gICAgICAgICAgICA6IG51bGw7XG4gICAgfSk7XG4gICAgcHJpdmF0ZSBsYXlvdXRQcmVmc1NhdmVDbnQgPSBzaWduYWwoMCk7XG4gICAgcHJpdmF0ZSBsYXlvdXRQcmVmZXJlbmNlcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3QgbHNLZXkgPSB0aGlzLmxvY2Fsc3RvcmFnZUtleSgpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICAgIGNvbnN0IGNudCA9IHRoaXMubGF5b3V0UHJlZnNTYXZlQ250KCk7IC8vIG5lZWRlZCB0byBmb3JjZSB1cGRhdGVzIG9uIHVzZXIgY2hhbmdlc1xuICAgICAgICBjb25zdCBsYXlvdXRQcmVmcyA9IGxzS2V5ID8gdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW08VGFibGVMYXlvdXRQcmVmZXJlbmNlcz4odGhpcy5jbXBUeXBlTmFtZSwgbHNLZXkpIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbGF5b3V0UHJlZnMgPz8ge2NvbHVtbldpZHRoczoge319O1xuICAgIH0pO1xuICAgIHB1YmxpYyBjb2x1bW5zID0gY29tcHV0ZWQ8Q29sdW1uV2l0aFByZWZlcmVuY2VzW10+KCgpID0+IHRoaXMuY29tcHV0Q29sdW1uc1dpdGhMYXlvdXQoKSk7XG4gICAgcHVibGljIHZpc2libGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKGNvbCA9PiBjb2wuaXNWaXNpYmxlKSk7XG5cbiAgICAvLyBmaWx0ZXIsIHNvcnRcbiAgICBwdWJsaWMgaGFzQ29sdW1uRmlsdGVycyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMoKS5sZW5ndGggPiAwKTtcbiAgICBwcml2YXRlIGZpbHRlckRlc2NyaXB0b3JzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZXNjcmlwdG9yKCkuZmlsdGVycyk7XG4gICAgcHJpdmF0ZSBkZWZhdWx0UGFyYW1zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wdXRlRGVmYXVsdERhdGFMaXN0UGFyYW1zKCkpO1xuICAgIHByaXZhdGUgaXNGaWx0ZXJDaGFuZ2VkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBpc1NvcnRDaGFuZ2VkID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgYW55Q29sdW1uVmlzaWJsZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMudmlzaWJsZUNvbHVtbnMoKS5sZW5ndGggPiAwKTtcbiAgICBwdWJsaWMgaGFzQ3VzdG9tTGFzdENvbHVtbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCB8fCB0aGlzLmNvbHVtbkN1c3RvbUxhc3RUZW1wbGF0ZSgpKTtcbiAgICBwdWJsaWMgaGFzTGFzdENvbHVtbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuaGFzQ3VzdG9tTGFzdENvbHVtbigpIHx8IHRoaXMuYXJlQ29sdW1uc1RvZ2dsZWFibGUoKSB8fCB0aGlzLmFyZUNvbHVtbnNSZW9yZGVyYWJsZSgpKTtcblxuICAgIC8vIGxheW91dCBwcmVmc1xuICAgIHB1YmxpYyBhcmVDb2x1bW5zUmVvcmRlcmFibGUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlc2NyaXB0b3IoKS5jb2x1bW5zLnNvbWUodmFsdWUgPT4gdmFsdWUuaXNSZW9yZGVyYWJsZSkpO1xuICAgIHB1YmxpYyBhcmVDb2x1bW5zVG9nZ2xlYWJsZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVzY3JpcHRvcigpLmNvbHVtbnMuc29tZSh2YWx1ZSA9PiB2YWx1ZS5pc1RvZ2dsZWFibGUpKTtcblxuICAgIC8vIG90aGVyXG4gICAgcHJpdmF0ZSByb3V0ZXJJc05hdmlnYXRpb25PdXRzaWRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGVmZmVjdChcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gdGhpcy5kZXNjcmlwdG9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGVzY3JpcHRvci5yb3dzUGVyUGFnZU9wdGlvbnMpICYmIGRlc2NyaXB0b3Iucm93c1BlclBhZ2VPcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zLnNldChkZXNjcmlwdG9yLnJvd3NQZXJQYWdlT3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yLmRlZmF1bHROdW1Sb3dzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3Muc2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zKCkuaW5jbHVkZXMoZGVzY3JpcHRvci5kZWZhdWx0TnVtUm93cykgPyBkZXNjcmlwdG9yLmRlZmF1bHROdW1Sb3dzIDogdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zKClbMF1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge2FsbG93U2lnbmFsV3JpdGVzOiB0cnVlfVxuICAgICAgICApO1xuXG4gICAgICAgIGVmZmVjdChcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBsb2FkaW5nID0gdGhpcy5sb2FkaW5nSW5wdXQoKTtcbiAgICAgICAgICAgICAgICBpZiAobG9hZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGxvYWRpbmcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucmVzdWx0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNldERhdGEocmVzdWx0LmRhdGEsIHJlc3VsdC50b3RhbENvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9hZGluZyA9IHRoaXMubG9hZGluZ0lucHV0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkaW5nID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBzZXQgaWYgaW5wdXQgaXMgbm90IGRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucmVzdWx0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zKCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSB1bmRlZmluZWQgJiYgaXRlbXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5zZXREYXRhKGl0ZW1zKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9hZGluZyA9IHRoaXMubG9hZGluZ0lucHV0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkaW5nID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBzZXQgaWYgaW5wdXQgaXMgbm90IGRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmdsb2JhbEZpbHRlckZpZWxkcy5zZXQodGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHNJbnB1dCgpID8/IHRoaXMuY29sdW1ucygpLm1hcChjID0+IGMuZGVzY3JpcHRvci5wcm9wZXJ0eSkpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBhZnRlck5leHRSZW5kZXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0NlbGxDbGlja09ic2VydmVkLnNldCh0aGlzLmNlbGxDbGlja1N1YmplY3Qub2JzZXJ2ZWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0b09ic2VydmFibGUodGhpcy5kYXRhUHJvdmlkZXIpXG4gICAgICAgICAgICAucGlwZShzd2l0Y2hNYXAoZHAgPT4gZHA/LmdldEFsbFJlbG9hZCQgPz8gb2Yoe30pKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBjb21iaW5lTGF0ZXN0KFt0b09ic2VydmFibGUodGhpcy5kZXNjcmlwdG9ySW5wdXQpLCB0b09ic2VydmFibGUodGhpcy5kYXRhUHJvdmlkZXIpLCB0b09ic2VydmFibGUodGhpcy51c2VRdWVyeVBhcmFtcyldKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgLy8gZGF0YVByb3ZpZGVyIGlzIG5lZWRlZCB0byBlbnN1cmUgY29ycmVjdCBvcmRlciBvZiBleGVjdXRpb24gYW5kIHJlbG9hZFxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKFtkZXNjcmlwdG9ySW5wdXQsIGRhdGFQcm92aWRlciwgdXNlUXVlcnlQYXJhbXNdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9ySW5wdXQgIT09IHRoaXMuZGVzY3JpcHRvcigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3Iuc2V0KGRlc2NyaXB0b3JJbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHVzZVF1ZXJ5UGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIHRhYmxlIGxvYWRzIGZyb20gcm91dGUgdXBkYXRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucm91dGUucXVlcnlQYXJhbXM7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZShxcCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHFwID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvYWQgZGF0YSBpbW1lZGlhdGVseSBieSBjcmVhdGluZyBkZWZhdWx0IHNvcnRzIGFuZCBmaWx0ZXJzIChwcmltZW5nIHdpbGwgdHJpZ2dlciBvbkxhenlMb2FkIGV2ZW50IG9uIHNvcnQmZmlsdGVyIG1ldGFkYXRhIGNoYW5nZSlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFNvcnQgPSB0aGlzLmNyZWF0ZVNvcnRNZXRhKHRoaXMuZGVmYXVsdFBhcmFtcygpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZWZhdWx0U29ydCB8fCBkZWZhdWx0U29ydC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5zb3J0TWV0YS5zZXQoZGVmYXVsdFNvcnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdEZpbHRlciA9IHRoaXMuY3JlYXRlRmlsdGVyTWV0YSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZmlsdGVyTWV0YS5zZXQoZGVmYXVsdEZpbHRlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHt9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRUYWJsZUZyb21Sb3V0ZVVwZGF0ZShxcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdG9PYnNlcnZhYmxlKHRoaXMudXNlUXVlcnlQYXJhbXMpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAodXNlUXAgPT4gKHVzZVFwID8gdGhpcy5yb3V0ZXIuZXZlbnRzIDogTkVWRVIpKSxcbiAgICAgICAgICAgICAgICBmaWx0ZXIoXG4gICAgICAgICAgICAgICAgICAgIGUgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIChlIGluc3RhbmNlb2YgTmF2aWdhdGlvblN0YXJ0ICYmIGUudXJsLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXSAhPT0gdGhpcy5yb3V0ZXIudXJsLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkNhbmNlbCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FcnJvclxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXJJc05hdmlnYXRpb25PdXRzaWRlSW5Qcm9ncmVzcyA9IGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQ7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWxvYWQoZW1pdEV2ZW50ID0gZmFsc2UsIHJlc2V0UGFyYW1zID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aERlZmF1bHRzOiBEYXRhTGlzdFBhcmFtcyA9XG4gICAgICAgICAgICByZXNldFBhcmFtcyB8fCAhdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHMgPyB0aGlzLmRlZmF1bHRQYXJhbXMoKSA6IG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHModGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHMsIHRoaXMuZGVmYXVsdFBhcmFtcygpKTtcbiAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKHBhcmFtc1dpdGhEZWZhdWx0cywgZW1pdEV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25UYWJsZUxhenlMb2FkKGV2ZW50OiBUYWJsZUxhenlMb2FkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJMYXRlc3RMYXp5TG9hZEV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIHRoaXMubGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24rKztcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBmcm9tVGFibGVMb2FkVG9EYXRhTGlzdFBhcmFtcyhldmVudCk7XG5cbiAgICAgICAgaWYgKHRoaXMudXNlUXVlcnlQYXJhbXMoKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnJvdXRlcklzTmF2aWdhdGlvbk91dHNpZGVJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcyBjaGVjayBpcyBuZWNlc3Nhcnk6IGZyb20gc29tZSByZWFzb24sIHByaW1lTkcgY29tbWl0cyBvbmUgbGFzdCBsYXp5IGxvYWQgZXZlbnQgd2hlbmV2ZXIgYW55IGFuZ3VsYXIgcm91dGVyIG5hdmlnYXRpb24gb2NjdXJzXG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW10sIHtcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVUbzogdGhpcy5yb3V0ZSxcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZVVybDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcXVlcnlQYXJhbXM6IGRhdGFMaXN0UGFyYW1zVG9VcmxRdWVyeShwYXJhbXMsIHRoaXMuZGVmYXVsdFBhcmFtcygpKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2FkVGFibGVXaXRoRGF0YVByb3ZpZGVyKG1lcmdlRGF0YUxpc3RQYXJhbXNXaXRoRGVmYXVsdHMocGFyYW1zLCB0aGlzLmRlZmF1bHRQYXJhbXMoKSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHB1YmxpYyBvblRhYmxlU29ydChldmVudDogYW55KSB7XG4gICAgICAgIHRoaXMuaXNTb3J0Q2hhbmdlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHB1YmxpYyBvblRhYmxlRmlsdGVyKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgdGhpcy5pc0ZpbHRlckNoYW5nZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNlbGxDbGljayhldmVudDogRXZlbnQsIGNvbDogQ29sdW1uRGVzY3JpcHRvcjxhbnksIEl0ZW0+LCBpdGVtOiBJdGVtLCBpZHg6IG51bWJlcikge1xuICAgICAgICBpZiAoIXRoaXMuaXNDZWxsQ2xpY2tFbmFibGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YWJsZUV2ZW50OiBUYWJsZUNlbGxDbGlja0V2ZW50PEl0ZW0+ID0ge1xuICAgICAgICAgICAgY29sdW1uOiBjb2wsXG4gICAgICAgICAgICByb3dJdGVtOiBpdGVtLFxuICAgICAgICAgICAgcm93SW5kZXg6IGlkeCxcbiAgICAgICAgICAgIGV2ZW50OiBldmVudFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNlbGxDbGlja1N1YmplY3QubmV4dCh0YWJsZUV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWxlY3Rpb25DaGFuZ2UoZXZlbnQ6IEFycmF5PEl0ZW0+KSB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoZXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblJvd1Jlb3JkZXIoZXZlbnQ6IFRhYmxlUm93UmVvcmRlckV2ZW50KSB7XG4gICAgICAgIHRoaXMucm93UmVvcmRlci5lbWl0KGV2ZW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgaXMgY2FsbGVkIG9uIGNvbHVtbiByZXNpemVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBldmVudCdzIGVsZW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgb25UYWJsZUNvbHVtblJlc2l6ZSh7ZWxlbWVudH06IGFueSk6IHZvaWQge1xuICAgICAgICBjb25zdCBmaWVsZElkOiBzdHJpbmcgPSBlbGVtZW50LmlkO1xuICAgICAgICBjb25zdCB3aWR0aDogbnVtYmVyID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcblxuICAgICAgICBjb25zdCBsYXlvdXRQcmVmcyA9IHRoaXMubGF5b3V0UHJlZmVyZW5jZXMoKTtcbiAgICAgICAgY29uc3QgY29sID0gdGhpcy5jb2x1bW5zKCkuZmluZChlbCA9PiBlbC5kZXNjcmlwdG9yLnByb3BlcnR5ID09PSBmaWVsZElkKTtcbiAgICAgICAgaWYgKGNvbCkgY29sLndpZHRoID0gd2lkdGg7XG4gICAgICAgIGlmICghbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzKSBsYXlvdXRQcmVmcy5jb2x1bW5XaWR0aHMgPSB7fTtcblxuICAgICAgICBsYXlvdXRQcmVmcy5jb2x1bW5XaWR0aHNbZmllbGRJZF0gPSB3aWR0aDtcbiAgICAgICAgdGhpcy5zYXZlTGF5b3V0UHJlZmVyZW5jZXMobGF5b3V0UHJlZnMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZFRhYmxlV2l0aERhdGFQcm92aWRlcihwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zLCBlbWl0RXZlbnQgPSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IGRhdGFQcm92aWRlciA9IHRoaXMuZGF0YVByb3ZpZGVyKCk7XG4gICAgICAgIGlmICghZGF0YVByb3ZpZGVyIHx8IHBhcmFtc1dpdGhEZWZhdWx0cy5saW1pdCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KHRydWUpO1xuXG4gICAgICAgIHRoaXMubGF0ZXN0UGFyYW1zV2l0aERlZmF1bHRzID0gcGFyYW1zV2l0aERlZmF1bHRzO1xuICAgICAgICB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0c1ZlcnNpb24rKztcblxuICAgICAgICB0aGlzLmRhdGFQcm92aWRlclN1YnNjcmlwdGlvbiA9IGNvbW1vbnNUb09ic2VydmFibGUoXG4gICAgICAgICAgICBkYXRhUHJvdmlkZXIuZ2V0QWxsKFxuICAgICAgICAgICAgICAgIHBhcmFtc1dpdGhEZWZhdWx0cyBhcyBEYXRhTGlzdFBhcmFtczxTb3J0cywgRmlsdGVycz4sXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTZXJ2aWNlKCksXG4gICAgICAgICAgICAgICAgdGhpcy5kZXNjcmlwdG9yKCkuaXNMb2NhbGl6ZWQgPyB0aGlzLmNvbW1vbnMuYXBwRGF0YUxvY2FsZSgpID8/IHVuZGVmaW5lZCA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgKVxuICAgICAgICApLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiByZXMgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3JJbnB1dCA9IHRoaXMuZGVzY3JpcHRvcklucHV0KCk7XG4gICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3JJbnB1dCBpbnN0YW5jZW9mIFRhYmxlRHluYW1pY0Rlc2NyaXB0b3JJbnN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvci5zZXQoZGVzY3JpcHRvcklucHV0LnRvVGFibGVEZXNjcmlwdG9yRnJvbURhdGEocmVzKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5maW5pdGVTY3JvbGwoKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLmRhdGFMaXN0U2VydmljZS5kYXRhKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRmlsdGVyQ2hhbmdlZCB8fCB0aGlzLmlzU29ydENoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zID0gW107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaXRlbXMuc3BsaWNlKHBhcmFtc1dpdGhEZWZhdWx0cyEub2Zmc2V0ID8/IDAsIHBhcmFtc1dpdGhEZWZhdWx0cyEubGltaXQgPz8gdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cygpLCAuLi4ocmVzPy5kYXRhID8/IFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNldERhdGEoaXRlbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNldERhdGEocmVzPy5kYXRhID8/IFtdLCByZXM/LnRvdGFsQ291bnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuaXNGaWx0ZXJDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1NvcnRDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBlcnIgPT4ge1xuICAgICAgICAgICAgICAgIHRhYmxlTm90aWZpY2F0aW9uRXJyb3IodGhpcy50cmFuc2xhdGUsIHRoaXMuZGVzY3JpcHRvcigpLCBlcnIsIHRoaXMubWVzc2FnZVNlcnZpY2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNldERhdGEoW10pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcuc2V0KGZhbHNlKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gZnJvbVN1YnNjcmliZUVycm9yKGVyciwgJ1RhYmxlQ29tcG9uZW50RXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW06IHBhcmFtc1dpdGhEZWZhdWx0c1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmxvZyhlcnJvciwgZ2V0RXJyb3JMb2dMZXZlbChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoZW1pdEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCB0YWJsZUV2ZW50OiBUYWJsZUxvYWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiB0aGlzLmRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQsXG4gICAgICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXNXaXRoRGVmYXVsdHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnRhYmxlTG9hZC5lbWl0KHRhYmxlRXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkVGFibGVGcm9tUm91dGVVcGRhdGUodXJsUGFyYW1zOiBQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aERlZmF1bHRzID0gbWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyhmcm9tVXJsUXVlcnlUb0RhdGFMaXN0UGFyYW1zKHVybFBhcmFtcyksIHRoaXMuZGVmYXVsdFBhcmFtcygpKTtcbiAgICAgICAgaWYgKHRoaXMubGF0ZXN0TGF6eUxvYWRFdmVudFZlcnNpb24gPCB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0c1ZlcnNpb24gKyAxKSB7XG4gICAgICAgICAgICAvLyB1cGRhdGUgb25seSBpZiBuZXcgdmVyc2lvbiBmcm9tIHF1ZXJ5IHBhcmFtcyB3aWxsIGJlIGhpZ2hlclxuICAgICAgICAgICAgdGhpcy51cGRhdGVQcmltZVNvcnRBbmRGaWx0ZXIocGFyYW1zV2l0aERlZmF1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQuc2V0KHRydWUpO1xuICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVByaW1lU29ydEFuZEZpbHRlcihwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zKSB7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNvcnRNZXRhLnNldCh0aGlzLmNyZWF0ZVNvcnRNZXRhKHBhcmFtc1dpdGhEZWZhdWx0cykpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhLnNldCh0aGlzLmNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzKSk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnJvd3Muc2V0KHBhcmFtc1dpdGhEZWZhdWx0cz8ubGltaXQgPz8gdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cygpKTtcbiAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uub2Zmc2V0LnNldChwYXJhbXNXaXRoRGVmYXVsdHM/Lm9mZnNldCA/PyAwKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUZpbHRlck1ldGEocGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcHJpbWVGaWx0ZXJNZXRhOiB7W3M6IHN0cmluZ106IEZpbHRlck1ldGFkYXRhfSA9IHt9O1xuICAgICAgICAvLyBpZiBhbnkgZmlsdGVyIGlzIHByZXNlbnQsIG5vIGRlZmF1bHQgZmlsdGVycyBzaG91bGQgYmUgYXBwbGllZCFcbiAgICAgICAgaWYgKHBhcmFtc1dpdGhEZWZhdWx0cz8uZmlsdGVycykge1xuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXMocGFyYW1zV2l0aERlZmF1bHRzLmZpbHRlcnMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICAgIHByaW1lRmlsdGVyTWV0YVtrZXldID0ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZTogdmFsdWUubWF0Y2hNb2RlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByaW1lRmlsdGVyTWV0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVNvcnRNZXRhKHBhcmFtc1dpdGhEZWZhdWx0cz86IERhdGFMaXN0UGFyYW1zKTogU29ydE1ldGFbXSB8IG51bGwge1xuICAgICAgICBpZiAocGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0ICE9PSB1bmRlZmluZWQgJiYgQXJyYXkuaXNBcnJheShwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQpICYmIHBhcmFtc1dpdGhEZWZhdWx0cz8uc29ydC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0Lm1hcChcbiAgICAgICAgICAgICAgICBzID0+XG4gICAgICAgICAgICAgICAgICAgIDxTb3J0TWV0YT57XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZDogcy5wcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyOiBzLmFzY2VuZGluZyA/IDEgOiAtMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uVG9nZ2xlKGV2ZW50OiBNdWx0aVNlbGVjdENoYW5nZUV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gdGhpcy5sYXlvdXRQcmVmZXJlbmNlcygpO1xuICAgICAgICBjb25zdCBzZWxlY3RlZENvbHVtbnMgPSAoZXZlbnQudmFsdWUgYXMgQ29sdW1uV2l0aFByZWZlcmVuY2VzW10pLm1hcCh2ID0+IHYuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIGNvbnN0IGhpZGRlbkNvbHVtbnMgPSB0aGlzLmNvbHVtbnMoKVxuICAgICAgICAgICAgLmZpbHRlcihjID0+IHNlbGVjdGVkQ29sdW1ucy5pbmRleE9mKGMuZGVzY3JpcHRvci5wcm9wZXJ0eSkgPCAwKVxuICAgICAgICAgICAgLm1hcChjID0+IGMuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIGxheW91dFByZWZzLmNvbHVtbkhpZGRlbiA9IGhpZGRlbkNvbHVtbnM7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db2x1bW5Ub2dnbGVBbGwoKSB7XG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gdGhpcy5sYXlvdXRQcmVmZXJlbmNlcygpO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gWy4uLnRoaXMuY29sdW1ucygpXTtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gIXRoaXMuY29sdW1ucygpLnNvbWUoYyA9PiBjLmlzVmlzaWJsZSk7XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUgIT09IGNvbC5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICBjb2wuaXNWaXNpYmxlID0gaXNWaXNpYmxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxheW91dFByZWZzLmNvbHVtbkhpZGRlbiA9IGNvbHVtbnMuZmlsdGVyKGMgPT4gIWMuaXNWaXNpYmxlKS5tYXAoYyA9PiBjLmRlc2NyaXB0b3IucHJvcGVydHkpO1xuICAgICAgICB0aGlzLnNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmcyk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29sdW1uUmVvcmRlcihldmVudDogVGFibGVDb2x1bW5SZW9yZGVyRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmRyb3BJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyb3BJbmRleCA+PSAwICYmIGV2ZW50LmRyYWdJbmRleCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmRyYWdJbmRleCA+PSAwICYmIGV2ZW50LmRyb3BJbmRleCAhPT0gZXZlbnQuZHJhZ0luZGV4KSB7XG4gICAgICAgICAgICBjb25zdCBldmVudERyb3BJbmRleCA9IGV2ZW50LmRyb3BJbmRleDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RHJhZ0luZGV4ID0gZXZlbnQuZHJhZ0luZGV4O1xuICAgICAgICAgICAgY29uc3QgcHJldlZpc2libGVDb2x1bW5zID0gdGhpcy5jb2x1bW5zKCkuZmlsdGVyKGMgPT4gYy5pc1Zpc2libGUpO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcm9wID0gcHJldlZpc2libGVDb2x1bW5zW2V2ZW50RHJvcEluZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJhZyA9IHByZXZWaXNpYmxlQ29sdW1uc1tldmVudERyYWdJbmRleF07XG4gICAgICAgICAgICBjb25zdCBjb2xBdERyb3BJbmRleCA9IHRoaXMuY29sdW1ucygpLmZpbmRJbmRleChlbCA9PiBlbC5pZCA9PT0gY29sQXREcm9wLmlkKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJhZ0luZGV4ID0gdGhpcy5jb2x1bW5zKCkuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyYWcuaWQpO1xuXG4gICAgICAgICAgICBpZiAoY29sQXREcm9wSW5kZXggPiAtMSAmJiBjb2xBdERyYWdJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbnMgPSBbLi4udGhpcy5jb2x1bW5zKCldO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMuc3BsaWNlKGNvbEF0RHJhZ0luZGV4LCAxKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkcm9wSW5kZXggPSBjb2x1bW5zLmZpbmRJbmRleChlbCA9PiBlbC5pZCA9PT0gY29sQXREcm9wLmlkKSArIChldmVudERyb3BJbmRleCA+IGV2ZW50RHJhZ0luZGV4ID8gMSA6IDApO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMgPSBbLi4uY29sdW1ucy5zbGljZSgwLCBkcm9wSW5kZXgpLCBjb2xBdERyYWcsIC4uLmNvbHVtbnMuc2xpY2UoZHJvcEluZGV4KV07XG4gICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgICAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uT3JkZXIgPSBjb2x1bW5zLm1hcChlbCA9PiBlbC5kZXNjcmlwdG9yLnByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNhdmVMYXlvdXRQcmVmZXJlbmNlcyhsYXlvdXRQcmVmczogVGFibGVMYXlvdXRQcmVmZXJlbmNlcykge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmxvY2Fsc3RvcmFnZUtleSgpO1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICB0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2Uuc2V0SXRlbSh0aGlzLmNtcFR5cGVOYW1lLCBrZXksIGxheW91dFByZWZzKTtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0UHJlZnNTYXZlQ250LnVwZGF0ZSh2ID0+IHYgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZURlZmF1bHREYXRhTGlzdFBhcmFtcygpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zOiBEYXRhTGlzdFBhcmFtcyA9IHtcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIGxpbWl0OiB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKVswXSxcbiAgICAgICAgICAgIHNvcnQ6IHRoaXMuZGVzY3JpcHRvcigpXG4gICAgICAgICAgICAgICAgLnNvcnRzLmZpbHRlcihzID0+IHMuZGVmYXVsdElzRW5hYmxlZClcbiAgICAgICAgICAgICAgICAubWFwKHMgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6IHMucHJvcGVydHksXG4gICAgICAgICAgICAgICAgICAgIGFzY2VuZGluZzogcy5kZWZhdWx0SXNBc2NlbmRpbmdcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICBmaWx0ZXJzOiB7fVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMoKVxuICAgICAgICAgICAgLmZpbHRlcihkID0+IGQuaGFzRGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgLmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG1hdGNoTW9kZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gZi5kZWZhdWx0TWF0Y2hNb2RlO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZi5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLlN0cmluZzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuQ29udGFpbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkxvb2t1cDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uTG9va3VwRW51bToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvb2t1cEZpbHRlciA9IGYgYXMgRmlsdGVyTG9va3VwRGVzY3JpcHRvcjxhbnksIEl0ZW0+O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb29rdXBGaWx0ZXIubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkluO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaE1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVxdWFscztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZi5tYXRjaE1vZGVzICYmICFmLm1hdGNoTW9kZXM/LmluY2x1ZGVzKG1hdGNoTW9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gZi5tYXRjaE1vZGVzWzBdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZTogYW55IHwgYW55W10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gWy4uLnZhbHVlXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGYuZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gZi5wcm9wZXJ0eTtcbiAgICAgICAgICAgICAgICBwYXJhbXMuZmlsdGVycyFbcHJvcGVydHldID0ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZTogbWF0Y2hNb2RlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRDb2x1bW5zV2l0aExheW91dCgpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHRoaXMuZGVzY3JpcHRvcigpO1xuICAgICAgICBjb25zdCBsYXlvdXRQcmVmcyA9IHRoaXMubGF5b3V0UHJlZmVyZW5jZXMoKTtcblxuICAgICAgICAvLyBpbml0aWFsaXplIGNvbHVtbnMgd2l0aCBhZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IGNvbHVtbnM6IENvbHVtbldpdGhQcmVmZXJlbmNlc1tdID0gZGVzY3JpcHRvci5jb2x1bW5zLm1hcChjb2wgPT4gKHtcbiAgICAgICAgICAgIGlkOiBgJHtjb2wucHJvcGVydHl9LSR7dGltZXN0YW1wfWAsXG4gICAgICAgICAgICBkZXNjcmlwdG9yOiBjb2wsXG4gICAgICAgICAgICBmaWx0ZXI6IGRlc2NyaXB0b3IuZmlsdGVycy5maW5kKGYgPT4gZi5zaG93T25Db2x1bW4gPT09IGNvbC5wcm9wZXJ0eSksXG4gICAgICAgICAgICBzb3J0OiBkZXNjcmlwdG9yLnNvcnRzLmZpbmQoZiA9PiBmLnNob3dPbkNvbHVtbiA9PT0gY29sLnByb3BlcnR5KSxcbiAgICAgICAgICAgIGRpc2FibGVkOiAhY29sLmlzVG9nZ2xlYWJsZSxcbiAgICAgICAgICAgIGlzVmlzaWJsZTogbGF5b3V0UHJlZnMuY29sdW1uSGlkZGVuID8gIWxheW91dFByZWZzLmNvbHVtbkhpZGRlbi5pbmNsdWRlcyhjb2wucHJvcGVydHkpIDogY29sLmlzVmlzaWJsZSxcbiAgICAgICAgICAgIHdpZHRoOiBsYXlvdXRQcmVmcy5jb2x1bW5XaWR0aHM/Lltjb2wucHJvcGVydHldXG4gICAgICAgIH0pKTtcblxuICAgICAgICBpZiAobGF5b3V0UHJlZnMuY29sdW1uT3JkZXIpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGF5b3V0UHJlZnMuY29sdW1uT3JkZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xOYW1lID0gbGF5b3V0UHJlZnMuY29sdW1uT3JkZXJbaV07XG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2l0aFByZWZzID0gY29sdW1ucy5maW5kKGVsID0+IGVsLmRlc2NyaXB0b3IucHJvcGVydHkgPT09IGNvbE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChjb2xXaXRoUHJlZnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sV2l0aFByZWZzLm9yZGVySWR4ID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sdW1ucy5zb3J0KChhLCBiKSA9PiAoYS5vcmRlcklkeCAhPT0gdW5kZWZpbmVkICYmIGIub3JkZXJJZHggIT09IHVuZGVmaW5lZCA/IGEub3JkZXJJZHggLSBiLm9yZGVySWR4IDogMCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2V0IGNvbHVtbiBvcmRlciBhbmQgY29sdW1uIHZpc2liaWxpdHkgdG8gZGVmYXVsdCBzZXR0aW5nc1xuICAgICAqL1xuICAgIHB1YmxpYyByZXNldERlZmF1bHRMYXlvdXQoKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMubG9jYWxzdG9yYWdlS2V5KCk7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5yZW1vdmVJdGVtKHRoaXMuY21wVHlwZU5hbWUsIGtleSk7XG4gICAgICAgICAgICB0aGlzLmxheW91dFByZWZzU2F2ZUNudC51cGRhdGUodiA9PiB2ICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8ZGl2IFtzdHlsZS5oZWlnaHRdPVwidGFibGVGdWxsSGVpZ2h0T2Zmc2V0KCkgPyAnY2FsYygxMDB2aCAtICcgKyB0YWJsZUZ1bGxIZWlnaHRPZmZzZXQoKSArICdweCknIDogbnVsbFwiPlxuICAgIDwhLS0gTVVTVCBOT1QgdXNlIG9ic2VydmFibGUgZm9yIHZhbHVlIHdoZW4gdXNpbmcgdmlydHVhbCBzY3JvbGwgLSBkb2VzIG5vdCB3b3JrIGZvciBzb21lIHJlYXNvbiAtLT5cbiAgICBAaWYgKCF1c2VRdWVyeVBhcmFtcygpIHx8IHVzZVF1ZXJ5UGFyYW1zSW5pdGlhbGl6ZWQoKSkge1xuICAgICAgICA8cC10YWJsZVxuICAgICAgICAgICAgW3ZhbHVlXT1cImRhdGFMaXN0U2VydmljZS5kYXRhKClcIlxuICAgICAgICAgICAgW2RhdGFLZXldPVwiZGVzY3JpcHRvcigpLnRyYWNrUHJvcGVydHlcIlxuICAgICAgICAgICAgW2xhenldPVwiaXNMYXp5KClcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwiZGF0YUxpc3RTZXJ2aWNlLmxvYWRpbmcoKVwiXG4gICAgICAgICAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGlvbigpICYmICFpbmZpbml0ZVNjcm9sbCgpXCJcbiAgICAgICAgICAgIFtyb3dzXT1cImluZmluaXRlU2Nyb2xsKCkgPyAyMCA6IGRhdGFMaXN0U2VydmljZS5yb3dzKClcIlxuICAgICAgICAgICAgW2ZpcnN0XT1cImluZmluaXRlU2Nyb2xsKCkgPyAwIDogZGF0YUxpc3RTZXJ2aWNlLm9mZnNldCgpXCJcbiAgICAgICAgICAgIFt0b3RhbFJlY29yZHNdPVwiZGF0YUxpc3RTZXJ2aWNlLmNvdW50KClcIlxuICAgICAgICAgICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJpbmZpbml0ZVNjcm9sbCgpID8gdW5kZWZpbmVkIDogZGF0YUxpc3RTZXJ2aWNlLnJvd3NQZXJQYWdlT3B0aW9ucygpXCJcbiAgICAgICAgICAgIFtzaG93Q3VycmVudFBhZ2VSZXBvcnRdPVwiIWluZmluaXRlU2Nyb2xsKClcIlxuICAgICAgICAgICAgW2N1cnJlbnRQYWdlUmVwb3J0VGVtcGxhdGVdPVwiJ21uZ1RhYmxlLnBhZ2luYXRpb25Nc2cnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFttdWx0aVNvcnRNZXRhXT1cImRhdGFMaXN0U2VydmljZS5zb3J0TWV0YSgpXCJcbiAgICAgICAgICAgIFtmaWx0ZXJzXT1cImRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhKClcIlxuICAgICAgICAgICAgW2dsb2JhbEZpbHRlckZpZWxkc109XCJkYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzKClcIlxuICAgICAgICAgICAgc29ydE1vZGU9XCJtdWx0aXBsZVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uXT1cIltdXCJcbiAgICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25TZWxlY3Rpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICBbc2VsZWN0aW9uTW9kZV09XCJzZWxlY3Rpb25FbmFibGVkKCkgPyBzZWxlY3Rpb25Nb2RlKCkgOiBudWxsXCJcbiAgICAgICAgICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgICAgICAgICAgW3ZpcnR1YWxTY3JvbGxdPVwiaW5maW5pdGVTY3JvbGwoKVwiXG4gICAgICAgICAgICBbdmlydHVhbFNjcm9sbEl0ZW1TaXplXT1cInJvd0hlaWdodCgpXCJcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodD1cImZsZXhcIlxuICAgICAgICAgICAgW3Jvd0hvdmVyXT1cImRlc2NyaXB0b3IoKS5oYXNIb3ZlclwiXG4gICAgICAgICAgICBbc3R5bGVDbGFzc109XCJjbGFzc05hbWUoKVwiXG4gICAgICAgICAgICBbcmVzaXphYmxlQ29sdW1uc109XCJkZXNjcmlwdG9yKCkuaGFzUmVzaXphYmxlQ29sdW1uc1wiXG4gICAgICAgICAgICBbY29sdW1uUmVzaXplTW9kZV09XCJkZXNjcmlwdG9yKCkuY29sdW1uUmVzaXplTW9kZSA/PyAnZXhwYW5kJ1wiXG4gICAgICAgICAgICBbcmVvcmRlcmFibGVDb2x1bW5zXT1cImFyZUNvbHVtbnNSZW9yZGVyYWJsZSgpXCJcbiAgICAgICAgICAgIHBhZ2luYXRvckRyb3Bkb3duQXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgIFtjb2x1bW5zXT1cInZpc2libGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgKG9uQ29sUmVzaXplKT1cIm9uVGFibGVDb2x1bW5SZXNpemUoJGV2ZW50KVwiXG4gICAgICAgICAgICAob25Db2xSZW9yZGVyKT1cIm9uQ29sdW1uUmVvcmRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgIChvbkxhenlMb2FkKT1cIm9uVGFibGVMYXp5TG9hZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChvblNvcnQpPVwib25UYWJsZVNvcnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAob25GaWx0ZXIpPVwib25UYWJsZUZpbHRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgIChvblJvd1Jlb3JkZXIpPVwib25Sb3dSZW9yZGVyKCRldmVudClcIj5cbiAgICAgICAgICAgIEBpZiAoY2FwdGlvblRlbXBsYXRlKCkgfHwgY2FwdGlvbkNvbXBvbmVudCgpIHx8IGRlc2NyaXB0b3IoKS50aXRsZSkge1xuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoY2FwdGlvblRlbXBsYXRlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjYXB0aW9uVGVtcGxhdGUoKVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjYXB0aW9uQ29tcG9uZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW21uZ0NvbXBvbmVudF09XCJjYXB0aW9uQ29tcG9uZW50KClcIiAoaW5zdGFuY2VDcmVhdGVkKT1cImNhcHRpb25Db21wb25lbnRJbnN0YW5jZS5lbWl0KCRldmVudClcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDUgY2xhc3M9XCJwLTAgbS0wXCI+e3sgZGVzY3JpcHRvcigpLnRpdGxlIH19PC9oNT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgQGlmICghZGVzY3JpcHRvcigpLmhpZGVIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwibW5nLXRhYmxlLWhlYWRlclwiIFtjbGFzc109XCJkZXNjcmlwdG9yKCkuaGVhZGVyQ2xhc3NOYW1lXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25Nb2RlKCkgPT09ICdtdWx0aXBsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFibGVIZWFkZXJDaGVja2JveD48L3AtdGFibGVIZWFkZXJDaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBXZSBuZWVkIHRoZSBsaW5lIGJlbG93LCBiZWNhdXNlIG90aGVyd2lzZSBwLXRhYmxlUmFkaW9CdXR0b24gc2hpZnRzIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zIGluIHRhYmxlIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgY2xhc3M9XCJjb2wtMVwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJ0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocm93UmVvcmRlckVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzb3J0YWJsZUNvbHVtblRIVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sLmRlc2NyaXB0b3IudGl0bGUgPz8gKGNvbC5kZXNjcmlwdG9yLnByb3BlcnR5IHwgbW5nSTE4blByb3BlcnR5OiBkZXNjcmlwdG9yKCkubW9kZWwpIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1zb3J0SWNvbiBbZmllbGRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIj48L3Atc29ydEljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25Tb3J0YWJsZUNvbHVtblRIVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChjb2wuZGVzY3JpcHRvci5pc1Jlb3JkZXJhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJlc2l6YWJsZUNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJlb3JkZXJhYmxlQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbl09XCJjb2wuc29ydD8ucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbkRpc2FibGVkXT1cIiFjb2wuc29ydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoID8gY29sLndpZHRoICsgJ3B4JyA6IGNvbC5kZXNjcmlwdG9yLndpZHRoICsgJyUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZGVzY3JpcHRvci5oZWFkZXJDbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2wuc29ydCA/IHNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZSA6IG5vblNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZXNpemFibGVDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uXT1cImNvbC5zb3J0Py5wcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uRGlzYWJsZWRdPVwiIWNvbC5zb3J0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggPyBjb2wud2lkdGggKyAncHgnIDogY29sLmRlc2NyaXB0b3Iud2lkdGggKyAnJSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wud2lkdGggPyBudWxsIDogY29sLmRlc2NyaXB0b3IubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wud2lkdGggPz8gY29sLmRlc2NyaXB0b3IubWF4V2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cImNvbC5kZXNjcmlwdG9yLmhlYWRlckNsYXNzTmFtZSB8IG1uZ1RhYmxlQ29sdW1uRmlsdGVyQ2xhc3M6IGNvbC5maWx0ZXIgOiBoYXNDb2x1bW5GaWx0ZXJzKCkgJiYgIWNvbC53aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbC5zb3J0ID8gc29ydGFibGVDb2x1bW5USFRlbXBsYXRlIDogbm9uU29ydGFibGVDb2x1bW5USFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChoYXNMYXN0Q29sdW1uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2x1bW5MYXN0TWluV2lkdGgoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuYWN0aW9uQ29sdW1uRnJvemVuID8/IGFyZUNvbHVtbnNUb2dnbGVhYmxlKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbkZyb3plbj1cInJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2x1bW4tY3VzdG9tLWxhc3QgdGV4dC1yaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5oYXNSZXNpemFibGVDb2x1bW5zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3M9XCJwLWJ1dHRvbi1wcmltYXJ5IG1uZy10YWJsZS1jb2x1bW5zLW11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJpZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwibGVmdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyb3Bkb3duSWNvbj1cInBpIHBpLXNsaWRlcnMtaFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlcl09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2aXNpYmxlQ29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwiJ21uZ1RhYmxlLmFkanVzdFRhYmxlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc3BsYXlTZWxlY3RlZExhYmVsXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25Db2x1bW5Ub2dnbGUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmaWx0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY2hlY2tib3ggcC1jb21wb25lbnQgbWwtMVwiIFtuZ0NsYXNzXT1cInsncC1jaGVja2JveC1kaXNhYmxlZCc6ICFhcmVDb2x1bW5zVG9nZ2xlYWJsZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWhpZGRlbi1hY2Nlc3NpYmxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRvbmx5PVwicmVhZG9ubHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5hbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5vbkhlYWRlckNoZWNrYm94Rm9jdXMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChibHVyKT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0Lm9uSGVhZGVyQ2hlY2tib3hCbHVyKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5vblRvZ2dsZUFsbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFhcmVDb2x1bW5zVG9nZ2xlYWJsZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtY2hlY2tib3gtYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5hbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1oaWdobGlnaHQnOiBhbnlDb2x1bW5WaXNpYmxlKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25Db2x1bW5Ub2dnbGVBbGwoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicC1jaGVja2JveC1pY29uXCIgW25nQ2xhc3NdPVwieydwaSBwaS1jaGVjayc6IGFueUNvbHVtblZpc2libGUoKX1cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXJlcGxheVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNsYXNzPVwicC1idXR0b24tc2Vjb25kYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCInbW5nVGFibGUucmVzZXRMYXlvdXQnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImxlZnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlc2V0RGVmYXVsdExheW91dCgpXCI+PC9wLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0uZGVzY3JpcHRvci50aXRsZSA/PyAoaXRlbS5kZXNjcmlwdG9yLnByb3BlcnR5IHwgbW5nSTE4blByb3BlcnR5OiBkZXNjcmlwdG9yKCkubW9kZWwpIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBpZiAoaGFzQ29sdW1uRmlsdGVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cIm1uZy1jb2x1bW4tZmlsdGVyLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBXZSBuZWVkIHRoZSBsaW5lIGJlbG93LCBiZWNhdXNlIG90aGVyd2lzZSBwLXRhYmxlUmFkaW9CdXR0b24gc2hpZnRzIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zIGluIHRhYmxlIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25FbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocm93UmVvcmRlckVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZmlsdGVyPy5jb2x1bW5DbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5maWx0ZXI/LmNvbHVtbldpZHRoID8/IGNvbC5kZXNjcmlwdG9yLndpZHRoID8/IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZmlsdGVyPy5jb2x1bW5NaW5XaWR0aCA/PyBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1uZy10YWJsZS1jb2x1bW4tZmlsdGVyLWZ1bGwgW2Rlc2NyaXB0b3JdPVwiY29sLmZpbHRlclwiPjwvbW5nLXRhYmxlLWNvbHVtbi1maWx0ZXItZnVsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGhhc0xhc3RDb2x1bW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdFwiIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoKClcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1pdGVtIGxldC1pZHg9XCJyb3dJbmRleFwiIGxldC1leHBhbmRlZD1cImV4cGFuZGVkXCI+XG4gICAgICAgICAgICAgICAgPHRyXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwicm93SGVpZ2h0KClcIlxuICAgICAgICAgICAgICAgICAgICBbcFJlb3JkZXJhYmxlUm93XT1cImlkeFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImRlc2NyaXB0b3IoKS5yb3dDbGFzc05hbWUgfCBtbmdDbGFzc01hcDogZGVzY3JpcHRvcigpLnJvd0NsYXNzTmFtZU1hcEZuIDogaXRlbSB8IG1uZ0xvY2FsZURlZmF1bHRSb3dDbGFzczogZGVzY3JpcHRvcigpIDogaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKHNlbGVjdGlvbkVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25Nb2RlKCkgPT09ICdtdWx0aXBsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlQ2hlY2tib3ggW3ZhbHVlXT1cIml0ZW1cIj48L3AtdGFibGVDaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC10YWJsZVJhZGlvQnV0dG9uIFt2YWx1ZV09XCJpdGVtXCI+PC9wLXRhYmxlUmFkaW9CdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIWRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlUHJvcGVydHkgfHwgaXRlbVtkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZVByb3BlcnR5IV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFJvd1RvZ2dsZXJdPVwiaXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXRleHQgcC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi1wbGFpblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWNvbl09XCJleHBhbmRlZCA/ICdwaSBwaS1jaGV2cm9uLWRvd24nIDogJ3BpIHBpLWNoZXZyb24tcmlnaHQnXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAaWYgKHJvd1Jlb3JkZXJFbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBpIHBpLWJhcnNcIiBwUmVvcmRlcmFibGVSb3dIYW5kbGU+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25DZWxsQ2xpY2soJGV2ZW50LCBjb2wuZGVzY3JpcHRvciwgaXRlbSwgaWR4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuZGVzY3JpcHRvci5jbGFzc05hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgbW5nQ2xhc3NNYXA6IGNvbC5kZXNjcmlwdG9yLmNsYXNzTmFtZU1hcEZuIDogaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jbGlja2FibGVdPVwiaXNDZWxsQ2xpY2tFbmFibGVkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggPyBjb2wud2lkdGggKyAncHgnIDogY29sLmRlc2NyaXB0b3Iud2lkdGggKyAnJSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbC53aWR0aCA/PyBjb2wuZGVzY3JpcHRvci5tYXhXaWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicC1jb2x1bW4tdGl0bGVcIj57eyBjb2wuZGVzY3JpcHRvci50aXRsZSA/PyAoY29sLmRlc2NyaXB0b3IucHJvcGVydHkgfCBtbmdJMThuUHJvcGVydHk6IGRlc2NyaXB0b3IoKS5tb2RlbCkgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1uZy10YWJsZS1jb2x1bW4tdmFsdWUgW2Rlc2NyaXB0b3JdPVwiY29sLmRlc2NyaXB0b3JcIiBbaXRlbV09XCJpdGVtXCI+PC9tbmctdGFibGUtY29sdW1uLXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGhhc0xhc3RDb2x1bW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2x1bW4tY3VzdG9tLWxhc3QganVzdGlmeS1jb250ZW50LWVuZCB0ZXh0LXJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbHVtbkxhc3RNaW5XaWR0aCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRnJvemVuQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuYWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduRnJvemVuPVwicmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbHVtbkN1c3RvbUxhc3RUZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2x1bW5DdXN0b21MYXN0VGVtcGxhdGUoKTsgY29udGV4dDoge3Jvd0l0ZW06IGl0ZW0sIHJvd0luZGV4OiBpZHh9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW21uZ0NvbXBvbmVudF09XCJjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50KClcIiAoaW5zdGFuY2VDcmVhdGVkKT1cImNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnRJbnN0YW5jZS5lbWl0KCRldmVudClcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cInJvd2V4cGFuc2lvblwiIGxldC1pdGVtPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtMVwiPjwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgW2NvbFNwYW5dPVwiZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGVDb2xTcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInJvd0V4cGFuZFRlbXBsYXRlKCk7IGNvbnRleHQ6IHtyb3dJdGVtOiBpdGVtfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImxvYWRpbmdpY29uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLmxvYWRpbmdJY29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwiJ3RleHQtd2hpdGUgdGV4dC00eGwgcGktc3BpbiAnICsgZGVzY3JpcHRvcigpLmxvYWRpbmdJY29uXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLmxvYWRpbmdUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dCB0ZXh0LXdoaXRlIHRleHQtbGcgZm9udC1zZW1pYm9sZFwiIFtuZ0NsYXNzXT1cInsnbXQtMyc6IGRlc2NyaXB0b3IoKS5sb2FkaW5nSWNvbn1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBkZXNjcmlwdG9yKCkubG9hZGluZ1RleHQgPz8gJycgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImxvYWRpbmdib2R5XCI+XG4gICAgICAgICAgICAgICAgPHRyIFtzdHlsZS5oZWlnaHQucHhdPVwicm93SGVpZ2h0KClcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwiY29sdW1uc0NvbHNwYW4oKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmctdGV4dFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtc2tlbGV0b24gW25nU3R5bGVdPVwie3dpZHRoOiAnMTAwJSd9XCI+PC9wLXNrZWxldG9uPlxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgIDx0ciBbc3R5bGUuaGVpZ2h0LnB4XT1cInJvd0hlaWdodCgpXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnNDb2xzcGFuKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7ICdtbmdUYWJsZS5ub0l0ZW1zJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgQGlmIChmb290ZXJUZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cInN1bW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvb3RlclRlbXBsYXRlKCk7IGNvbnRleHQ6IHtkYXRhOiBkYXRhTGlzdFNlcnZpY2UuZGF0YSgpLCB0b3RhbENvdW50OiBkYXRhTGlzdFNlcnZpY2UuY291bnQoKX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgfVxuICAgICAgICA8L3AtdGFibGU+XG4gICAgfVxuPC9kaXY+XG4iXX0=
540
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUUsT0FBTyxFQUNILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUtSLGVBQWUsRUFDZixRQUFRLEVBQ1IsZUFBZSxFQUNmLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUNULFlBQVksRUFDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsb0JBQW9CLEVBQUUsWUFBWSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQVUsTUFBTSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFbEksT0FBTyxFQUFDLGVBQWUsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3RFLE9BQU8sRUFBaUIsY0FBYyxFQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1QyxPQUFPLEVBQXlCLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDOUUsT0FBTyxFQUFDLEtBQUssRUFBK0MsV0FBVyxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUNwSCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUMsT0FBTyxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQWdCLGFBQWEsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ2hGLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0QyxPQUFPLEVBQ0gsWUFBWSxFQUNaLGNBQWMsRUFDZCxxQkFBcUIsRUFDckIsa0JBQWtCLEVBR2xCLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsYUFBYSxFQUNiLGlCQUFpQixFQUNqQiwyQkFBMkIsRUFDM0IsWUFBWSxJQUFJLG1CQUFtQixFQUNuQyx3QkFBd0IsRUFDeEIsa0JBQWtCLEVBQ2xCLGtCQUFrQixFQUNsQiw2QkFBNkIsRUFDN0IsNEJBQTRCLEVBQzVCLGdCQUFnQixFQUNoQiwrQkFBK0IsRUFDbEMsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQXlCLGNBQWMsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBQ3JGLE9BQU8sRUFLSCwwQkFBMEIsRUFHMUIsdUJBQXVCLEVBQ3ZCLGFBQWEsRUFDYixlQUFlLEVBQ2xCLE1BQU0sa0NBQWtDLENBQUM7QUFFMUMsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDbEUsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFN0UsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sMkNBQTJDLENBQUM7QUFDcEYsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0sNENBQTRDLENBQUM7QUFDdEYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQ2pFLE9BQU8sRUFBQyw4QkFBOEIsRUFBQyxNQUFNLG9EQUFvRCxDQUFDO0FBQ2xHLE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLHdDQUF3QyxDQUFDOzs7Ozs7Ozs7QUE0QmpGLE1BQU0sT0FBTyxjQUFjO0lBNEl2QjtRQTNJZ0IsZ0JBQVcsR0FBRyxnQkFBZ0IsQ0FBQztRQUU5QixXQUFNLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEQsYUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1QixXQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hCLFVBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDL0IsY0FBUyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3JDLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3hDLFlBQU8sR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDakMsbUJBQWMsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNoRCxvQkFBZSxHQUFHLE1BQU0sQ0FBQyxDQUFBLGVBQXFCLENBQUEsQ0FBQyxDQUFDO1FBRWhFLGlCQUFpQjtRQUNWLG9CQUFlLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBNEMsRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFDLENBQUMsQ0FBQztRQUUxRyxxQkFBcUI7UUFDZCxVQUFLLEdBQUcsS0FBSyxFQUFVLENBQUM7UUFDeEIsV0FBTSxHQUFHLEtBQUssRUFBd0IsQ0FBQztRQUN2QyxpQkFBWSxHQUFHLEtBQUssQ0FBQyxTQUFTLEVBQUUsRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSwyQkFBMkIsRUFBQyxDQUFDLENBQUM7UUFDNUYsaUJBQVksR0FBRyxLQUFLLEVBQXFELENBQUM7UUFFakYsdUJBQXVCO1FBQ2hCLG1CQUFjLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLHFCQUFnQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixrQkFBYSxHQUFHLEtBQUssQ0FBd0IsVUFBVSxDQUFDLENBQUM7UUFDekQscUJBQWdCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLDJCQUFzQixHQUFHLEtBQUssQ0FBVSxJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUMsQ0FBQyxDQUFDO1FBQzVFLHNCQUFpQixHQUFHLFFBQVEsQ0FBVSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFdEgsVUFBVTtRQUNILHVCQUFrQixHQUFHLEtBQUssRUFBVSxDQUFDO1FBQ3JDLG1CQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFL0ssbUJBQW1CO1FBQ1oscUJBQWdCLEdBQUcsS0FBSyxFQUFhLENBQUM7UUFDdEMsOEJBQXlCLEdBQUcsS0FBSyxFQUFhLENBQUM7UUFDL0MsNEJBQXVCLEdBQUcsS0FBSyxDQUF1QixTQUFTLEVBQUUsRUFBQyxLQUFLLEVBQUUsb0JBQW9CLEVBQUMsQ0FBQyxDQUFDO1FBRXZHLGFBQWE7UUFDTCxxQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBNkIsQ0FBQztRQUM3RCx3QkFBbUIsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdELHVCQUFrQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1FBRWxHLGdCQUFnQjtRQUNULGNBQVMsR0FBRyxNQUFNLEVBQWtCLENBQUM7UUFDckMsY0FBUyxHQUFHLG9CQUFvQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3hELG9CQUFlLEdBQUcsTUFBTSxFQUFlLENBQUM7UUFDeEMsNkJBQXdCLEdBQUcsTUFBTSxFQUFPLENBQUM7UUFDekMsc0NBQWlDLEdBQUcsTUFBTSxFQUFPLENBQUM7UUFDbEQsZUFBVSxHQUFHLE1BQU0sRUFBd0IsQ0FBQztRQUVuRCwyQkFBMkI7UUFDcEIsY0FBUyxHQUFHLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9DLGVBQVUsR0FBRyxZQUFZLENBQUMsQ0FBQSxrQkFBdUIsQ0FBQSxDQUFDLENBQUM7UUFDbkQsZUFBVSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFOUMsWUFBWTtRQUNMLG9CQUFlLEdBQW9DLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN4SCw2QkFBd0IsR0FBb0MsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7UUFDMUksbUJBQWMsR0FBb0MsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3RILHNCQUFpQixHQUFvQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQztRQUUxSSwwQkFBMEI7UUFDbkIsV0FBTSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQzlELGlCQUFZLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyx1QkFBdUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM1Riw4QkFBeUIsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFakQsU0FBUztRQUNELG1CQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNuQyxJQUFJLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDMUQsa0VBQWtFO2dCQUNsRSxPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxjQUFjLENBQUM7WUFDNUMsQ0FBQztpQkFBTSxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLFdBQVcsRUFBRSxDQUFDO2dCQUNwRCw2Q0FBNkM7Z0JBQzdDLE9BQU8sdUJBQXVCLENBQUMsVUFBVSxDQUFDO1lBQzlDLENBQUM7aUJBQU0sQ0FBQztnQkFDSixPQUFPLHVCQUF1QixDQUFDLElBQUksQ0FBQztZQUN4QyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSSxjQUFTLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUM3QixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztZQUNsRCxRQUFRLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDN0IsS0FBSyxhQUFhLENBQUMsS0FBSztvQkFDcEIsU0FBUyxJQUFJLGlCQUFpQixDQUFDO29CQUMvQixNQUFNO2dCQUNWLEtBQUssYUFBYSxDQUFDLEtBQUs7b0JBQ3BCLFNBQVMsSUFBSSxpQkFBaUIsQ0FBQztvQkFDL0IsTUFBTTtZQUNkLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDakMsU0FBUyxJQUFJLHdCQUF3QixDQUFDO1lBQzFDLENBQUM7WUFDRCxPQUFPLFNBQVMsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUVILGdCQUFnQjtRQUNSLHdCQUFtQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDeEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3pDLE9BQU8sWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQU0sWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDL0YsQ0FBQyxDQUFDLENBQUM7UUFFSywrQkFBMEIsR0FBRyxDQUFDLENBQUM7UUFFL0Isb0NBQStCLEdBQUcsQ0FBQyxDQUFDO1FBRzVDLGNBQWM7UUFDUCxlQUFVLEdBQUcsTUFBTSxDQUFxQyxlQUFlLEVBQTBCLENBQUMsQ0FBQztRQUNsRyxvQkFBZSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ25KLENBQUMsQ0FBQyxDQUFDO1FBQ0ssdUJBQWtCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9CLHNCQUFpQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDdEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JDLDZEQUE2RDtZQUM3RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLDBDQUEwQztZQUNqRixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUF5QixJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDckgsT0FBTyxXQUFXLElBQUksRUFBQyxZQUFZLEVBQUUsRUFBRSxFQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFDSSxZQUFPLEdBQUcsUUFBUSxDQUEwQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLG1CQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUVwRixlQUFlO1FBQ1IscUJBQWdCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0RSxzQkFBaUIsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlELGtCQUFhLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLENBQUM7UUFFckUscUJBQWdCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDcEUsd0JBQW1CLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO1FBQ3hHLGtCQUFhLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBQUM7UUFFakksZUFBZTtRQUNSLDBCQUFxQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBQ3JHLHlCQUFvQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBRTFHLFFBQVE7UUFDQSx3Q0FBbUMsR0FBRyxLQUFLLENBQUM7UUFHaEQsTUFBTSxDQUNGLEdBQUcsRUFBRTtZQUNELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNyQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLElBQUksVUFBVSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDM0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDL0UsQ0FBQztZQUNELElBQUksVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQzNKLENBQUM7WUFDTixDQUFDO1FBQ0wsQ0FBQyxFQUNELEVBQUMsaUJBQWlCLEVBQUUsSUFBSSxFQUFDLENBQzVCLENBQUM7UUFFRixNQUFNLENBQ0YsR0FBRyxFQUFFO1lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BDLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNMLENBQUMsRUFDRCxFQUFDLGlCQUFpQixFQUFFLElBQUksRUFBQyxDQUM1QixDQUFDO1FBRUYsTUFBTSxDQUNGLEdBQUcsRUFBRTtZQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzdELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxPQUFPLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ3ZCLG1DQUFtQztvQkFDbkMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUMsRUFDRCxFQUFDLGlCQUFpQixFQUFFLElBQUksRUFBQyxDQUM1QixDQUFDO1FBRUYsTUFBTSxDQUNGLEdBQUcsRUFBRTtZQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0IsSUFBSSxNQUFNLElBQUksU0FBUyxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDN0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxPQUFPLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ3ZCLG1DQUFtQztvQkFDbkMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUMsRUFDRCxFQUFDLGlCQUFpQixFQUFFLElBQUksRUFBQyxDQUM1QixDQUFDO1FBRUYsTUFBTSxDQUNGLEdBQUcsRUFBRTtZQUNELElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDbEksQ0FBQyxFQUNELEVBQUMsaUJBQWlCLEVBQUUsSUFBSSxFQUFDLENBQzVCLENBQUM7UUFFRixlQUFlLENBQUMsR0FBRyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7YUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDbEQsU0FBUyxDQUFDO1lBQ1AsSUFBSSxFQUFFLEdBQUcsRUFBRTtnQkFDUCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEIsQ0FBQztTQUNKLENBQUMsQ0FBQztRQUVQLGFBQWEsQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7YUFDbEgsSUFBSTtRQUNELHlFQUF5RTtRQUN6RSw2REFBNkQ7UUFDN0QsU0FBUyxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsWUFBWSxFQUFFLGNBQWMsQ0FBQyxFQUFFLEVBQUU7WUFDMUQsSUFBSSxlQUFlLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3pDLENBQUM7WUFDRCxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNqQix5Q0FBeUM7Z0JBQ3pDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7WUFDbEMsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BCLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FDTDthQUNBLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUNaLElBQUksRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNkLHFJQUFxSTtnQkFDckksTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLFdBQVcsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN6QyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ25ELENBQUM7Z0JBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzlDLElBQUksYUFBYSxFQUFFLENBQUM7b0JBQ2hCLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDdkQsQ0FBQztnQkFDRCxJQUFJLENBQUMseUJBQXlCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkMsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0QyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFUCxZQUFZLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQzthQUM1QixJQUFJLENBQ0QsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUN4RCxNQUFNLENBQ0YsQ0FBQyxDQUFDLEVBQUUsQ0FDQSxDQUFDLENBQUMsWUFBWSxlQUFlLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkgsQ0FBQyxZQUFZLGFBQWE7WUFDMUIsQ0FBQyxZQUFZLGdCQUFnQjtZQUM3QixDQUFDLFlBQVksZUFBZSxDQUNuQyxDQUNKO2FBQ0EsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ1gsSUFBSSxDQUFDLG1DQUFtQyxHQUFHLENBQUMsWUFBWSxlQUFlLENBQUM7UUFDNUUsQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRU0sTUFBTSxDQUFDLFNBQVMsR0FBRyxLQUFLLEVBQUUsV0FBVyxHQUFHLEtBQUs7UUFDaEQsTUFBTSxrQkFBa0IsR0FDcEIsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLCtCQUErQixDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUNoSyxJQUFJLENBQUMseUJBQXlCLENBQUMsa0JBQWtCLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVNLGVBQWUsQ0FBQyxLQUF5QjtRQUM1QyxJQUFJLENBQUMsK0JBQStCLEdBQUcsS0FBSyxDQUFDO1FBQzdDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBRWxDLE1BQU0sTUFBTSxHQUFHLDZCQUE2QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXBELElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDO2dCQUM1QyxvSUFBb0k7Z0JBQ3BJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRTtvQkFDckIsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLO29CQUN0QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsV0FBVyxFQUFFLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7aUJBQ3RFLENBQUMsQ0FBQztZQUNQLENBQUM7UUFDTCxDQUFDO2FBQU0sQ0FBQztZQUNKLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywrQkFBK0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsRyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFdBQVcsQ0FBQyxLQUFZLEVBQUUsR0FBZ0MsRUFBRSxJQUFVLEVBQUUsR0FBVztRQUN0RixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUM3QixPQUFPO1FBQ1gsQ0FBQztRQUNELE1BQU0sVUFBVSxHQUE4QjtZQUMxQyxNQUFNLEVBQUUsR0FBRztZQUNYLE9BQU8sRUFBRSxJQUFJO1lBQ2IsUUFBUSxFQUFFLEdBQUc7WUFDYixLQUFLLEVBQUUsS0FBSztTQUNmLENBQUM7UUFDRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTSxpQkFBaUIsQ0FBQyxLQUFrQjtRQUN2QyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRU0sWUFBWSxDQUFDLEtBQTJCO1FBQzNDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7O09BR0c7SUFDSSxtQkFBbUIsQ0FBQyxFQUFDLE9BQU8sRUFBTTtRQUNyQyxNQUFNLE9BQU8sR0FBVyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFXLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFFMUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDN0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQyxDQUFDO1FBQzFFLElBQUksR0FBRztZQUFFLEdBQUcsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWTtZQUFFLFdBQVcsQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBRTdELFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRU8seUJBQXlCLENBQUMsa0JBQWtDLEVBQUUsU0FBUyxHQUFHLElBQUk7UUFDbEYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxZQUFZLElBQUksa0JBQWtCLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xELE9BQU87UUFDWCxDQUFDO1FBRUQsSUFBSSxDQUFDLHdCQUF3QixFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsa0JBQWtCLENBQUM7UUFDbkQsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFFdkMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLG1CQUFtQixDQUMvQyxZQUFZLENBQUMsTUFBTSxDQUNmLGtCQUFvRCxFQUNwRCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsRUFDMUIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FDeEYsQ0FDSixDQUFDLFNBQVMsQ0FBQztZQUNSLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRTtnQkFDUixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQy9DLElBQUksZUFBZSxZQUFZLDBCQUEwQixFQUFFLENBQUM7b0JBQ3hELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4RSxDQUFDO2dCQUNELElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVDLENBQUM7WUFDRCxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ1Qsc0JBQXNCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDcEYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFeEMsTUFBTSxLQUFLLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxFQUFFLHFCQUFxQixFQUFFO29CQUN6RCxVQUFVLEVBQUUsa0JBQWtCO2lCQUNqQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDcEQsQ0FBQztTQUNKLENBQUMsQ0FBQztRQUVILElBQUksU0FBUyxFQUFFLENBQUM7WUFDWixNQUFNLFVBQVUsR0FBbUI7Z0JBQy9CLGFBQWEsRUFBRSxJQUFJLENBQUMsK0JBQStCO2dCQUNuRCxNQUFNLEVBQUUsa0JBQWtCO2FBQzdCLENBQUM7WUFDRixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHdCQUF3QixDQUFDLFNBQWlCO1FBQzlDLE1BQU0sa0JBQWtCLEdBQUcsK0JBQStCLENBQUMsNEJBQTRCLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDMUgsSUFBSSxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLCtCQUErQixHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzdFLDhEQUE4RDtZQUM5RCxJQUFJLENBQUMsd0JBQXdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMseUJBQXlCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRU8sd0JBQXdCLENBQUMsa0JBQWtDO1FBQy9ELElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxrQkFBbUM7UUFDeEQsTUFBTSxlQUFlLEdBQWtDLEVBQUUsQ0FBQztRQUMxRCxrRUFBa0U7UUFDbEUsSUFBSSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUM5QixNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7Z0JBQ2hFLGVBQWUsQ0FBQyxHQUFHLENBQUMsR0FBRztvQkFDbkIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO29CQUNsQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7aUJBQzdCLENBQUM7WUFDTixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7UUFFRCxPQUFPLGVBQWUsQ0FBQztJQUMzQixDQUFDO0lBRU8sY0FBYyxDQUFDLGtCQUFtQztRQUN0RCxJQUFJLGtCQUFrQixFQUFFLElBQUksS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsSUFBSSxrQkFBa0IsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNILE9BQU8sa0JBQWtCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FDL0IsQ0FBQyxDQUFDLEVBQUUsQ0FDQSxDQUFVO2dCQUNOLEtBQUssRUFBRSxDQUFDLENBQUMsUUFBUTtnQkFDakIsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzlCLENBQUEsQ0FDUixDQUFDO1FBQ04sQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTSxjQUFjLENBQUMsS0FBNkI7UUFDL0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDN0MsTUFBTSxlQUFlLEdBQUksS0FBSyxDQUFDLEtBQWlDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFO2FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDL0QsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyQyxXQUFXLENBQUMsWUFBWSxHQUFHLGFBQWEsQ0FBQztRQUN6QyxJQUFJLENBQUMscUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVNLGlCQUFpQjtRQUNwQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUM3QyxNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDcEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pELEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7WUFDeEIsSUFBSSxTQUFTLEtBQUssR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUM5QixHQUFHLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUM5QixDQUFDO1FBQ0wsQ0FBQztRQUNELFdBQVcsQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0YsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFTSxlQUFlLENBQUMsS0FBOEI7UUFDakQsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN4SixNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBQ3ZDLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7WUFDdkMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM5RSxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFOUUsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLElBQUksT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDbEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xDLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLFNBQVMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlHLE9BQU8sR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEVBQUUsU0FBUyxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNuRixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDN0MsV0FBVyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzVDLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVPLHFCQUFxQixDQUFDLFdBQW1DO1FBQzdELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNuQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ04sSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDaEUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLDRCQUE0QjtRQUNoQyxNQUFNLE1BQU0sR0FBbUI7WUFDM0IsTUFBTSxFQUFFLENBQUM7WUFDVCxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNuRCxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRTtpQkFDbEIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQztpQkFDckMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDUCxRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVE7Z0JBQ3BCLFNBQVMsRUFBRSxDQUFDLENBQUMsa0JBQWtCO2FBQ2xDLENBQUMsQ0FBQztZQUNQLE9BQU8sRUFBRSxFQUFFO1NBQ2QsQ0FBQztRQUVGLElBQUksQ0FBQyxpQkFBaUIsRUFBRTthQUNuQixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO2FBQzlCLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNULElBQUksU0FBUyxHQUF1QixDQUFDLENBQUMsZ0JBQWdCLENBQUM7WUFDdkQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNiLFFBQVEsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUNuQixLQUFLLGNBQWMsQ0FBQyxNQUFNO3dCQUN0QixTQUFTLEdBQUcsZUFBZSxDQUFDLFFBQVEsQ0FBQzt3QkFDckMsTUFBTTtvQkFDVixLQUFLLGNBQWMsQ0FBQyxNQUFNLENBQUM7b0JBQzNCLEtBQUssY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7d0JBQzdCLE1BQU0sWUFBWSxHQUFHLENBQXNDLENBQUM7d0JBQzVELElBQUksWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDOzRCQUMzQixTQUFTLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQzt3QkFDbkMsQ0FBQzt3QkFDRCxNQUFNO29CQUNWLENBQUM7b0JBQ0Q7d0JBQ0ksTUFBTTtnQkFDZCxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDYixTQUFTLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQztZQUN2QyxDQUFDO1lBRUQsSUFBSSxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDckQsU0FBUyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsQ0FBQztZQUVELElBQUksS0FBSyxHQUE0QixTQUFTLENBQUM7WUFDL0MsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDdkIsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLEtBQUssR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDO1lBQzNCLENBQUM7WUFFRCxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxPQUFRLENBQUMsUUFBUSxDQUFDLEdBQUc7Z0JBQ3hCLEtBQUssRUFBRSxLQUFLO2dCQUNaLFNBQVMsRUFBRSxTQUFTO2FBQ3ZCLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQUVQLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFTyx3QkFBd0I7UUFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRTdDLGdEQUFnRDtRQUNoRCxNQUFNLFNBQVMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sT0FBTyxHQUE0QixVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLFFBQVEsSUFBSSxTQUFTLEVBQUU7WUFDbEMsVUFBVSxFQUFFLEdBQUc7WUFDZixNQUFNLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxLQUFLLEdBQUcsQ0FBQyxRQUFRLENBQUM7WUFDckUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksS0FBSyxHQUFHLENBQUMsUUFBUSxDQUFDO1lBQ2pFLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxZQUFZO1lBQzNCLFNBQVMsRUFBRSxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVM7WUFDdEcsS0FBSyxFQUFFLFdBQVcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO1NBQ2xELENBQUMsQ0FBQyxDQUFDO1FBRUosSUFBSSxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3RELE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsS0FBSyxPQUFPLENBQUMsQ0FBQztnQkFDNUUsSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDZixZQUFZLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztnQkFDOUIsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hILENBQUM7SUFFRDs7T0FFRztJQUNJLGtCQUFrQjtRQUNyQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDbkMsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNOLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0wsQ0FBQzs4R0Fsa0JRLGNBQWM7a0dBQWQsY0FBYyxxMkVBSFosQ0FBQyxlQUFlLENBQUMsb0RBd0RPLGlCQUFpQiw0RUFDbkIsQ0FBQSxrQkFBdUIsQ0FBQSw2RkFDakIsS0FBSyxnRUM5SmhELDQvbEJBNFNBLDRDRHpOUSxrQkFBa0IsNEtBQ2xCLGdCQUFnQix3REFDaEIsT0FBTyxvRkFDUCxPQUFPLDJFQUNQLGdCQUFnQixvSkFDaEIseUJBQXlCLDhGQUN6QixZQUFZLCtDQUNaLHlCQUF5QixpRUFDekIsOEJBQThCLDRGQUM5QiwwQkFBMEIsaUVBQzFCLFdBQVcseTRHQUNYLGlCQUFpQixvMUNBQ2pCLFlBQVksMmtCQUNaLGFBQWEscVhBQ2IsZUFBZSwyRkFDZixXQUFXOzsyRkFLTixjQUFjO2tCQTFCMUIsU0FBUztpQ0FDTSxJQUFJLFlBQ04sV0FBVyxXQUVaO3dCQUNMLFNBQVM7d0JBQ1Qsa0JBQWtCO3dCQUNsQixnQkFBZ0I7d0JBQ2hCLE9BQU87d0JBQ1AsT0FBTzt3QkFDUCxnQkFBZ0I7d0JBQ2hCLHlCQUF5Qjt3QkFDekIsWUFBWTt3QkFDWix5QkFBeUI7d0JBQ3pCLDhCQUE4Qjt3QkFDOUIsMEJBQTBCO3dCQUMxQixXQUFXO3dCQUNYLGlCQUFpQjt3QkFDakIsWUFBWTt3QkFDWixhQUFhO3dCQUNiLGVBQWU7d0JBQ2YsV0FBVztxQkFDZCxhQUNVLENBQUMsZUFBZSxDQUFDLG1CQUNYLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FzeW5jUGlwZSwgTmdDbGFzcywgTmdTdHlsZSwgTmdUZW1wbGF0ZU91dGxldH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIEluamVjdG9yLFxuICAgIE9uRGVzdHJveSxcbiAgICBTaWduYWwsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVHlwZSxcbiAgICBhZnRlck5leHRSZW5kZXIsXG4gICAgY29tcHV0ZWQsXG4gICAgY29udGVudENoaWxkcmVuLFxuICAgIGVmZmVjdCxcbiAgICBpbmplY3QsXG4gICAgaW5wdXQsXG4gICAgb3V0cHV0LFxuICAgIHNpZ25hbCxcbiAgICB2aWV3Q2hpbGQsXG4gICAgdmlld0NoaWxkcmVuXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtvdXRwdXRGcm9tT2JzZXJ2YWJsZSwgdG9PYnNlcnZhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge0Zvcm1zTW9kdWxlfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBOYXZpZ2F0aW9uQ2FuY2VsLCBOYXZpZ2F0aW9uRW5kLCBOYXZpZ2F0aW9uRXJyb3IsIE5hdmlnYXRpb25TdGFydCwgUGFyYW1zLCBSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlLCBUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7RmlsdGVyTWV0YWRhdGEsIE1lc3NhZ2VTZXJ2aWNlLCBTb3J0TWV0YX0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHtCdXR0b25Nb2R1bGV9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7TXVsdGlTZWxlY3RDaGFuZ2VFdmVudCwgTXVsdGlTZWxlY3RNb2R1bGV9IGZyb20gJ3ByaW1lbmcvbXVsdGlzZWxlY3QnO1xuaW1wb3J0IHtUYWJsZSwgVGFibGVDb2x1bW5SZW9yZGVyRXZlbnQsIFRhYmxlTGF6eUxvYWRFdmVudCwgVGFibGVNb2R1bGUsIFRhYmxlUm93UmVvcmRlckV2ZW50fSBmcm9tICdwcmltZW5nL3RhYmxlJztcbmltcG9ydCB7VG9vbHRpcE1vZHVsZX0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7TkVWRVIsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgY29tYmluZUxhdGVzdCwgb2YsIHN3aXRjaE1hcH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2ZpbHRlcn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICAgIENsYXNzTWFwUGlwZSxcbiAgICBDb21tb25zU2VydmljZSxcbiAgICBDb21tb25zU3RvcmFnZVNlcnZpY2UsXG4gICAgQ29tcG9uZW50RGlyZWN0aXZlLFxuICAgIERhdGFMaXN0UGFyYW1zLFxuICAgIERhdGFMaXN0UmVzdWx0LFxuICAgIEZpbHRlck1hdGNoTW9kZSxcbiAgICBJMThuUHJvcGVydHlQaXBlLFxuICAgIExvZ2dlclNlcnZpY2UsXG4gICAgVGVtcGxhdGVEaXJlY3RpdmUsXG4gICAgYm9vbGVhbk9yVW5kZWZpbmVkQXR0cmlidXRlLFxuICAgIHRvT2JzZXJ2YWJsZSBhcyBjb21tb25zVG9PYnNlcnZhYmxlLFxuICAgIGRhdGFMaXN0UGFyYW1zVG9VcmxRdWVyeSxcbiAgICBmaW5kVGVtcGxhdGVCeU5hbWUsXG4gICAgZnJvbVN1YnNjcmliZUVycm9yLFxuICAgIGZyb21UYWJsZUxvYWRUb0RhdGFMaXN0UGFyYW1zLFxuICAgIGZyb21VcmxRdWVyeVRvRGF0YUxpc3RQYXJhbXMsXG4gICAgZ2V0RXJyb3JMb2dMZXZlbCxcbiAgICBtZXJnZURhdGFMaXN0UGFyYW1zV2l0aERlZmF1bHRzXG59IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvY29yZSc7XG5pbXBvcnQge0ZpbHRlckxvb2t1cERlc2NyaXB0b3IsIEZpbHRlclR5cGVFbnVtfSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2ZpbHRlcic7XG5pbXBvcnQge1xuICAgIENvbHVtbkRlc2NyaXB0b3IsXG4gICAgSVRhYmxlRGF0YVByb3ZpZGVyLFxuICAgIFRhYmxlQ2VsbENsaWNrRXZlbnQsXG4gICAgVGFibGVEZXNjcmlwdG9ySW5zdCxcbiAgICBUYWJsZUR5bmFtaWNEZXNjcmlwdG9ySW5zdCxcbiAgICBUYWJsZUxheW91dFByZWZlcmVuY2VzLFxuICAgIFRhYmxlTG9hZEV2ZW50LFxuICAgIFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLFxuICAgIFRhYmxlU2l6ZUVudW0sXG4gICAgdGFibGVEZXNjcmlwdG9yXG59IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvdGFibGUvYXBpJztcblxuaW1wb3J0IHt0YWJsZU5vdGlmaWNhdGlvbkVycm9yfSBmcm9tICcuLi8uLi9oZWxwZXJzL25vdGlmaWNhdGlvbic7XG5pbXBvcnQge2dlbmVyYXRlVGFibGVMYXlvdXRQcmVmc0tleX0gZnJvbSAnLi4vLi4vaGVscGVycy90YWJsZS1sYXlvdXQtcHJlZnMnO1xuaW1wb3J0IHtDb2x1bW5XaXRoUHJlZmVyZW5jZXN9IGZyb20gJy4uLy4uL21vZGVscy9jb2x1bW4tcHJlZmVyZW5jZXMubW9kZWwnO1xuaW1wb3J0IHtMb2NhbGVEZWZhdWx0Um93Q2xhc3NQaXBlfSBmcm9tICcuLi8uLi9waXBlcy9sb2NhbGUtZGVmYXVsdC1yb3ctY2xhc3MucGlwZSc7XG5pbXBvcnQge1RhYmxlQ29sdW1uRmlsdGVyQ2xhc3NQaXBlfSBmcm9tICcuLi8uLi9waXBlcy90YWJsZS1jb2x1bW4tZmlsdGVyLWNsYXNzLnBpcGUnO1xuaW1wb3J0IHtEYXRhTGlzdFNlcnZpY2V9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RhdGEtbGlzdC5zZXJ2aWNlJztcbmltcG9ydCB7VGFibGVDb2x1bW5GaWx0ZXJGdWxsQ29tcG9uZW50fSBmcm9tICcuLi9jb2x1bW4tZmlsdGVyLWZ1bGwvY29sdW1uLWZpbHRlci1mdWxsLmNvbXBvbmVudCc7XG5pbXBvcnQge1RhYmxlQ29sdW1uVmFsdWVDb21wb25lbnR9IGZyb20gJy4uL2NvbHVtbi12YWx1ZS9jb2x1bW4tdmFsdWUuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzZWxlY3RvcjogJ21uZy10YWJsZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIEFzeW5jUGlwZSxcbiAgICAgICAgQ29tcG9uZW50RGlyZWN0aXZlLFxuICAgICAgICBJMThuUHJvcGVydHlQaXBlLFxuICAgICAgICBOZ0NsYXNzLFxuICAgICAgICBOZ1N0eWxlLFxuICAgICAgICBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgICAgICBUYWJsZUNvbHVtblZhbHVlQ29tcG9uZW50LFxuICAgICAgICBDbGFzc01hcFBpcGUsXG4gICAgICAgIExvY2FsZURlZmF1bHRSb3dDbGFzc1BpcGUsXG4gICAgICAgIFRhYmxlQ29sdW1uRmlsdGVyRnVsbENvbXBvbmVudCxcbiAgICAgICAgVGFibGVDb2x1bW5GaWx0ZXJDbGFzc1BpcGUsXG4gICAgICAgIFRhYmxlTW9kdWxlLFxuICAgICAgICBNdWx0aVNlbGVjdE1vZHVsZSxcbiAgICAgICAgQnV0dG9uTW9kdWxlLFxuICAgICAgICBUb29sdGlwTW9kdWxlLFxuICAgICAgICBUcmFuc2xhdGVNb2R1bGUsXG4gICAgICAgIEZvcm1zTW9kdWxlXG4gICAgXSxcbiAgICBwcm92aWRlcnM6IFtEYXRhTGlzdFNlcnZpY2VdLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlQ29tcG9uZW50PEl0ZW0gPSBhbnksIFNlcnZpY2UgPSB1bmRlZmluZWQsIFNvcnRzID0gYW55LCBGaWx0ZXJzIGV4dGVuZHMga2V5b2YgYW55ID0gYW55PiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgcHVibGljIHJlYWRvbmx5IGNtcFR5cGVOYW1lID0gJ1RhYmxlQ29tcG9uZW50JztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyID0gaW5qZWN0KExvZ2dlclNlcnZpY2UpLmNyZWF0ZSh0aGlzLmNtcFR5cGVOYW1lKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGUgPSBpbmplY3QoQWN0aXZhdGVkUm91dGUpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNsYXRlID0gaW5qZWN0KFRyYW5zbGF0ZVNlcnZpY2UpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbWVzc2FnZVNlcnZpY2UgPSBpbmplY3QoTWVzc2FnZVNlcnZpY2UpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY29tbW9ucyA9IGluamVjdChDb21tb25zU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlU2VydmljZSA9IGluamVjdChDb21tb25zU3RvcmFnZVNlcnZpY2UpO1xuICAgIHB1YmxpYyByZWFkb25seSBkYXRhTGlzdFNlcnZpY2UgPSBpbmplY3QoRGF0YUxpc3RTZXJ2aWNlPEl0ZW0+KTtcblxuICAgIC8vIG1ldGFkYXRhIGlucHV0XG4gICAgcHVibGljIGRlc2NyaXB0b3JJbnB1dCA9IGlucHV0LnJlcXVpcmVkPFRhYmxlRGVzY3JpcHRvckluc3Q8SXRlbSwgU29ydHMsIEZpbHRlcnM+Pih7YWxpYXM6ICdkZXNjcmlwdG9yJ30pO1xuXG4gICAgLy8gZGF0YSBzb3VyY2UgaW5wdXRzXG4gICAgcHVibGljIGl0ZW1zID0gaW5wdXQ8SXRlbVtdPigpO1xuICAgIHB1YmxpYyByZXN1bHQgPSBpbnB1dDxEYXRhTGlzdFJlc3VsdDxJdGVtPj4oKTtcbiAgICBwdWJsaWMgbG9hZGluZ0lucHV0ID0gaW5wdXQodW5kZWZpbmVkLCB7YWxpYXM6ICdsb2FkaW5nJywgdHJhbnNmb3JtOiBib29sZWFuT3JVbmRlZmluZWRBdHRyaWJ1dGV9KTtcbiAgICBwdWJsaWMgZGF0YVByb3ZpZGVyID0gaW5wdXQ8SVRhYmxlRGF0YVByb3ZpZGVyPEl0ZW0sIFNlcnZpY2UsIFNvcnRzLCBGaWx0ZXJzPj4oKTtcblxuICAgIC8vIGV4dHJhIGZlYXR1cmVzIGlucHV0XG4gICAgcHVibGljIHVzZVF1ZXJ5UGFyYW1zID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyBjZWxsQ2xpY2tFbmFibGVkID0gaW5wdXQodHJ1ZSk7XG4gICAgcHVibGljIHNlbGVjdGlvbk1vZGUgPSBpbnB1dDwnc2luZ2xlJyB8ICdtdWx0aXBsZSc+KCdtdWx0aXBsZScpO1xuICAgIHB1YmxpYyBzZWxlY3Rpb25FbmFibGVkID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyByb3dSZW9yZGVyRW5hYmxlZElucHV0ID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSwge2FsaWFzOiAncm93UmVvcmRlckVuYWJsZWQnfSk7XG4gICAgcHVibGljIHJvd1Jlb3JkZXJFbmFibGVkID0gY29tcHV0ZWQ8Ym9vbGVhbj4oKCkgPT4gdGhpcy5yb3dSZW9yZGVyRW5hYmxlZElucHV0KCkgJiYgdGhpcy5kZXNjcmlwdG9yKCkucm93UmVvcmRlcmFibGUpO1xuXG4gICAgLy8gc3R5bGluZ1xuICAgIHB1YmxpYyBjb2x1bW5MYXN0TWluV2lkdGggPSBpbnB1dDxudW1iZXI+KCk7XG4gICAgcHVibGljIGNvbHVtbnNDb2xzcGFuID0gY29tcHV0ZWQoKCkgPT4gdGhpcy52aXNpYmxlQ29sdW1ucygpLmxlbmd0aCArICh0aGlzLmhhc0xhc3RDb2x1bW4oKSA/IDEgOiAwKSArICh0aGlzLnNlbGVjdGlvbkVuYWJsZWQoKSA/IDEgOiAwKSArICh0aGlzLnJvd1Jlb3JkZXJFbmFibGVkKCkgPyAxIDogMCkpO1xuXG4gICAgLy8gY29tcG9uZW50IGlucHV0c1xuICAgIHB1YmxpYyBjYXB0aW9uQ29tcG9uZW50ID0gaW5wdXQ8VHlwZTxhbnk+PigpO1xuICAgIHB1YmxpYyBjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50ID0gaW5wdXQ8VHlwZTxhbnk+PigpO1xuICAgIHB1YmxpYyBnbG9iYWxGaWx0ZXJGaWVsZHNJbnB1dCA9IGlucHV0PHN0cmluZ1tdIHwgdW5kZWZpbmVkPih1bmRlZmluZWQsIHthbGlhczogJ2dsb2JhbEZpbHRlckZpZWxkcyd9KTtcblxuICAgIC8vIGNlbGwgY2xpY2tcbiAgICBwcml2YXRlIGNlbGxDbGlja1N1YmplY3QgPSBuZXcgU3ViamVjdDxUYWJsZUNlbGxDbGlja0V2ZW50PEl0ZW0+PigpO1xuICAgIHB1YmxpYyBpc0NlbGxDbGlja09ic2VydmVkID0gc2lnbmFsKHRoaXMuY2VsbENsaWNrU3ViamVjdC5vYnNlcnZlZCk7XG4gICAgcHVibGljIGlzQ2VsbENsaWNrRW5hYmxlZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY2VsbENsaWNrRW5hYmxlZCgpICYmIHRoaXMuaXNDZWxsQ2xpY2tPYnNlcnZlZCgpKTtcblxuICAgIC8vIGV2ZW50IG91dHB1dHNcbiAgICBwdWJsaWMgdGFibGVMb2FkID0gb3V0cHV0PFRhYmxlTG9hZEV2ZW50PigpO1xuICAgIHB1YmxpYyBjZWxsQ2xpY2sgPSBvdXRwdXRGcm9tT2JzZXJ2YWJsZSh0aGlzLmNlbGxDbGlja1N1YmplY3QpO1xuICAgIHB1YmxpYyBzZWxlY3Rpb25DaGFuZ2UgPSBvdXRwdXQ8QXJyYXk8SXRlbT4+KCk7XG4gICAgcHVibGljIGNhcHRpb25Db21wb25lbnRJbnN0YW5jZSA9IG91dHB1dDxhbnk+KCk7XG4gICAgcHVibGljIGNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnRJbnN0YW5jZSA9IG91dHB1dDxhbnk+KCk7XG4gICAgcHVibGljIHJvd1Jlb3JkZXIgPSBvdXRwdXQ8VGFibGVSb3dSZW9yZGVyRXZlbnQ+KCk7XG5cbiAgICAvLyBjb250ZW50IGFuZCB2aWV3IHF1ZXJpZXNcbiAgICBwdWJsaWMgdGVtcGxhdGVzID0gY29udGVudENoaWxkcmVuKFRlbXBsYXRlRGlyZWN0aXZlKTtcbiAgICBwdWJsaWMgY29tcG9uZW50cyA9IHZpZXdDaGlsZHJlbihDb21wb25lbnREaXJlY3RpdmU8YW55Pik7XG4gICAgcHVibGljIHByaW1lVGFibGUgPSB2aWV3Q2hpbGQucmVxdWlyZWQoVGFibGUpO1xuXG4gICAgLy8gdGVtcGxhdGVzXG4gICAgcHVibGljIGNhcHRpb25UZW1wbGF0ZTogU2lnbmFsPFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPiA9IGNvbXB1dGVkKCgpID0+IGZpbmRUZW1wbGF0ZUJ5TmFtZShbLi4udGhpcy50ZW1wbGF0ZXMoKV0sICdjYXB0aW9uJykpO1xuICAgIHB1YmxpYyBjb2x1bW5DdXN0b21MYXN0VGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnY29sdW1uQ3VzdG9tTGFzdCcpKTtcbiAgICBwdWJsaWMgZm9vdGVyVGVtcGxhdGU6IFNpZ25hbDxUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PiBmaW5kVGVtcGxhdGVCeU5hbWUoWy4uLnRoaXMudGVtcGxhdGVzKCldLCAnZm9vdGVyJykpO1xuICAgIHB1YmxpYyByb3dFeHBhbmRUZW1wbGF0ZTogU2lnbmFsPFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPiA9IGNvbXB1dGVkKCgpID0+IGZpbmRUZW1wbGF0ZUJ5TmFtZShbLi4udGhpcy50ZW1wbGF0ZXMoKV0sICdyb3dFeHBhbmRDb250ZW50JykpO1xuXG4gICAgLy8gZGF0YSBwcm92aWRlciBhbmQgaXRlbXNcbiAgICBwdWJsaWMgaXNMYXp5ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kYXRhUHJvdmlkZXIoKT8uaXNMYXp5ID09PSB0cnVlKTtcbiAgICBwdWJsaWMgaXNQYWdpbmF0aW9uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5wYWdpbmF0aW9uTW9kZSgpID09PSBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5QYWdpbmF0aW9uKTtcbiAgICBwdWJsaWMgdXNlUXVlcnlQYXJhbXNJbml0aWFsaXplZCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgICAvLyB2aXN1YWxcbiAgICBwcml2YXRlIHBhZ2luYXRpb25Nb2RlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuZGVzY3JpcHRvcigpLnBhZ2luYXRpb25Nb2RlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gZGVzY3JpcHRvciBjaG9pY2UgaXMgdGhlIHN0cm9uZ2VzdCAtIGlmIGRlZmluZWQsIHVzZSB0aGlzIHZhbHVlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXNjcmlwdG9yKCkucGFnaW5hdGlvbk1vZGU7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuZGF0YVByb3ZpZGVyKCkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAvLyB3aGVuIGRhdGEgcHJvdmlkZXIgaXMgdXNlZCwgdXNlIHBhZ2luYXRpb25cbiAgICAgICAgICAgIHJldHVybiBUYWJsZVBhZ2luYXRpb25Nb2RlRW51bS5QYWdpbmF0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFRhYmxlUGFnaW5hdGlvbk1vZGVFbnVtLk5vbmU7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBwdWJsaWMgY2xhc3NOYW1lID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBsZXQgY2xhc3NOYW1lID0gdGhpcy5kZXNjcmlwdG9yKCkuY2xhc3NOYW1lID8/ICcnO1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZGVzY3JpcHRvcigpLnNpemUpIHtcbiAgICAgICAgICAgIGNhc2UgVGFibGVTaXplRW51bS5TbWFsbDpcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gJyBwLWRhdGF0YWJsZS1zbSc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFRhYmxlU2l6ZUVudW0uTGFyZ2U6XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgcC1kYXRhdGFibGUtbGcnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IoKS5oYXNHcmlkbGluZXMpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHAtZGF0YXRhYmxlLWdyaWRsaW5lcyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgICB9KTtcblxuICAgIC8vIGRhdGEgcHJvdmlkZXJcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlclNlcnZpY2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGFQcm92aWRlciA9IHRoaXMuZGF0YVByb3ZpZGVyKCk7XG4gICAgICAgIHJldHVybiBkYXRhUHJvdmlkZXI/LnNlcnZpY2VUeXBlID8gdGhpcy5pbmplY3Rvci5nZXQ8YW55PihkYXRhUHJvdmlkZXIuc2VydmljZVR5cGUpIDogbnVsbDtcbiAgICB9KTtcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQ/OiBUYWJsZUxhenlMb2FkRXZlbnQ7XG4gICAgcHJpdmF0ZSBsYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbiA9IDA7XG4gICAgcHJpdmF0ZSBsYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHM/OiBEYXRhTGlzdFBhcmFtcztcbiAgICBwcml2YXRlIGxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0c1ZlcnNpb24gPSAwO1xuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gICAgLy8gZGVzY3JpcHRvcnNcbiAgICBwdWJsaWMgZGVzY3JpcHRvciA9IHNpZ25hbDxUYWJsZURlc2NyaXB0b3JJbnN0PGFueSwgYW55LCBhbnk+Pih0YWJsZURlc2NyaXB0b3I8c3RyaW5nLCBzdHJpbmcsIHN0cmluZz4oKSk7XG4gICAgcHJpdmF0ZSBsb2NhbHN0b3JhZ2VLZXkgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcbiAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3IubW9kZWwuaTE4bkJhc2VLZXkgPyBnZW5lcmF0ZVRhYmxlTGF5b3V0UHJlZnNLZXkoZGVzY3JpcHRvci5tb2RlbC5pMThuQmFzZUtleSwgdGhpcy5yb3V0ZXIudXJsLCBkZXNjcmlwdG9yLmlkZW50aWZpZXIpIDogbnVsbDtcbiAgICB9KTtcbiAgICBwcml2YXRlIGxheW91dFByZWZzU2F2ZUNudCA9IHNpZ25hbCgwKTtcbiAgICBwcml2YXRlIGxheW91dFByZWZlcmVuY2VzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBsc0tleSA9IHRoaXMubG9jYWxzdG9yYWdlS2V5KCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgY29uc3QgY250ID0gdGhpcy5sYXlvdXRQcmVmc1NhdmVDbnQoKTsgLy8gbmVlZGVkIHRvIGZvcmNlIHVwZGF0ZXMgb24gdXNlciBjaGFuZ2VzXG4gICAgICAgIGNvbnN0IGxheW91dFByZWZzID0gbHNLZXkgPyB0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW08VGFibGVMYXlvdXRQcmVmZXJlbmNlcz4odGhpcy5jbXBUeXBlTmFtZSwgbHNLZXkpIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbGF5b3V0UHJlZnMgPz8ge2NvbHVtbldpZHRoczoge319O1xuICAgIH0pO1xuICAgIHB1YmxpYyBjb2x1bW5zID0gY29tcHV0ZWQ8Q29sdW1uV2l0aFByZWZlcmVuY2VzW10+KCgpID0+IHRoaXMuY29tcHV0ZUNvbHVtbnNXaXRoTGF5b3V0KCkpO1xuICAgIHB1YmxpYyB2aXNpYmxlQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29sdW1ucygpLmZpbHRlcihjb2wgPT4gY29sLmlzVmlzaWJsZSkpO1xuXG4gICAgLy8gZmlsdGVyLCBzb3J0XG4gICAgcHVibGljIGhhc0NvbHVtbkZpbHRlcnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmZpbHRlckRlc2NyaXB0b3JzKCkubGVuZ3RoID4gMCk7XG4gICAgcHJpdmF0ZSBmaWx0ZXJEZXNjcmlwdG9ycyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVzY3JpcHRvcigpLmZpbHRlcnMpO1xuICAgIHByaXZhdGUgZGVmYXVsdFBhcmFtcyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcHV0ZURlZmF1bHREYXRhTGlzdFBhcmFtcygpKTtcblxuICAgIHB1YmxpYyBhbnlDb2x1bW5WaXNpYmxlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy52aXNpYmxlQ29sdW1ucygpLmxlbmd0aCA+IDApO1xuICAgIHB1YmxpYyBoYXNDdXN0b21MYXN0Q29sdW1uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50IHx8IHRoaXMuY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlKCkpO1xuICAgIHB1YmxpYyBoYXNMYXN0Q29sdW1uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5oYXNDdXN0b21MYXN0Q29sdW1uKCkgfHwgdGhpcy5hcmVDb2x1bW5zVG9nZ2xlYWJsZSgpIHx8IHRoaXMuYXJlQ29sdW1uc1Jlb3JkZXJhYmxlKCkpO1xuXG4gICAgLy8gbGF5b3V0IHByZWZzXG4gICAgcHVibGljIGFyZUNvbHVtbnNSZW9yZGVyYWJsZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVzY3JpcHRvcigpLmNvbHVtbnMuc29tZSh2YWx1ZSA9PiB2YWx1ZS5pc1Jlb3JkZXJhYmxlKSk7XG4gICAgcHVibGljIGFyZUNvbHVtbnNUb2dnbGVhYmxlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZXNjcmlwdG9yKCkuY29sdW1ucy5zb21lKHZhbHVlID0+IHZhbHVlLmlzVG9nZ2xlYWJsZSkpO1xuXG4gICAgLy8gb3RoZXJcbiAgICBwcml2YXRlIHJvdXRlcklzTmF2aWdhdGlvbk91dHNpZGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkZXNjcmlwdG9yLnJvd3NQZXJQYWdlT3B0aW9ucykgJiYgZGVzY3JpcHRvci5yb3dzUGVyUGFnZU9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMuc2V0KGRlc2NyaXB0b3Iucm93c1BlclBhZ2VPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3IuZGVmYXVsdE51bVJvd3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cy5zZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKS5pbmNsdWRlcyhkZXNjcmlwdG9yLmRlZmF1bHROdW1Sb3dzKSA/IGRlc2NyaXB0b3IuZGVmYXVsdE51bVJvd3MgOiB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKVswXVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRpbmcgPSB0aGlzLmxvYWRpbmdJbnB1dCgpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQobG9hZGluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZXN1bHQoKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uuc2V0RGF0YShyZXN1bHQuZGF0YSwgcmVzdWx0LnRvdGFsQ291bnQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2FkaW5nID0gdGhpcy5sb2FkaW5nSW5wdXQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWRpbmcgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHNldCBpZiBpbnB1dCBpcyBub3QgZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZXN1bHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXMoKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IHVuZGVmaW5lZCAmJiBpdGVtcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNldERhdGEoaXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2FkaW5nID0gdGhpcy5sb2FkaW5nSW5wdXQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWRpbmcgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHNldCBpZiBpbnB1dCBpcyBub3QgZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UuZ2xvYmFsRmlsdGVyRmllbGRzLnNldCh0aGlzLmdsb2JhbEZpbHRlckZpZWxkc0lucHV0KCkgPz8gdGhpcy5jb2x1bW5zKCkubWFwKGMgPT4gYy5kZXNjcmlwdG9yLnByb3BlcnR5KSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge2FsbG93U2lnbmFsV3JpdGVzOiB0cnVlfVxuICAgICAgICApO1xuXG4gICAgICAgIGFmdGVyTmV4dFJlbmRlcigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzQ2VsbENsaWNrT2JzZXJ2ZWQuc2V0KHRoaXMuY2VsbENsaWNrU3ViamVjdC5vYnNlcnZlZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRvT2JzZXJ2YWJsZSh0aGlzLmRhdGFQcm92aWRlcilcbiAgICAgICAgICAgIC5waXBlKHN3aXRjaE1hcChkcCA9PiBkcD8uZ2V0QWxsUmVsb2FkJCA/PyBvZih7fSkpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbWJpbmVMYXRlc3QoW3RvT2JzZXJ2YWJsZSh0aGlzLmRlc2NyaXB0b3JJbnB1dCksIHRvT2JzZXJ2YWJsZSh0aGlzLmRhdGFQcm92aWRlciksIHRvT2JzZXJ2YWJsZSh0aGlzLnVzZVF1ZXJ5UGFyYW1zKV0pXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAvLyBkYXRhUHJvdmlkZXIgaXMgbmVlZGVkIHRvIGVuc3VyZSBjb3JyZWN0IG9yZGVyIG9mIGV4ZWN1dGlvbiBhbmQgcmVsb2FkXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoW2Rlc2NyaXB0b3JJbnB1dCwgZGF0YVByb3ZpZGVyLCB1c2VRdWVyeVBhcmFtc10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3JJbnB1dCAhPT0gdGhpcy5kZXNjcmlwdG9yKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvci5zZXQoZGVzY3JpcHRvcklucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodXNlUXVlcnlQYXJhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgdGFibGUgbG9hZHMgZnJvbSByb3V0ZSB1cGRhdGVzXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZS5xdWVyeVBhcmFtcztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHFwID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocXAgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbG9hZCBkYXRhIGltbWVkaWF0ZWx5IGJ5IGNyZWF0aW5nIGRlZmF1bHQgc29ydHMgYW5kIGZpbHRlcnMgKHByaW1lbmcgd2lsbCB0cmlnZ2VyIG9uTGF6eUxvYWQgZXZlbnQgb24gc29ydCZmaWx0ZXIgbWV0YWRhdGEgY2hhbmdlKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0U29ydCA9IHRoaXMuY3JlYXRlU29ydE1ldGEodGhpcy5kZWZhdWx0UGFyYW1zKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlZmF1bHRTb3J0IHx8IGRlZmF1bHRTb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLnNvcnRNZXRhLnNldChkZWZhdWx0U29ydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0RmlsdGVyID0gdGhpcy5jcmVhdGVGaWx0ZXJNZXRhKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0RmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5maWx0ZXJNZXRhLnNldChkZWZhdWx0RmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIoe30pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZFRhYmxlRnJvbVJvdXRlVXBkYXRlKHFwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0b09ic2VydmFibGUodGhpcy51c2VRdWVyeVBhcmFtcylcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCh1c2VRcCA9PiAodXNlUXAgPyB0aGlzLnJvdXRlci5ldmVudHMgOiBORVZFUikpLFxuICAgICAgICAgICAgICAgIGZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgZSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQgJiYgZS51cmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdICE9PSB0aGlzLnJvdXRlci51cmwuc3BsaXQoJz8nKVswXS5zcGxpdCgnIycpWzBdKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uQ2FuY2VsIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVycm9yXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZShlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlcklzTmF2aWdhdGlvbk91dHNpZGVJblByb2dyZXNzID0gZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydDtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbG9hZChlbWl0RXZlbnQgPSBmYWxzZSwgcmVzZXRQYXJhbXMgPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBwYXJhbXNXaXRoRGVmYXVsdHM6IERhdGFMaXN0UGFyYW1zID1cbiAgICAgICAgICAgIHJlc2V0UGFyYW1zIHx8ICF0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cyA/IHRoaXMuZGVmYXVsdFBhcmFtcygpIDogbWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyh0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cywgdGhpcy5kZWZhdWx0UGFyYW1zKCkpO1xuICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzLCBlbWl0RXZlbnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblRhYmxlTGF6eUxvYWQoZXZlbnQ6IFRhYmxlTGF6eUxvYWRFdmVudCkge1xuICAgICAgICB0aGlzLmRhdGFQcm92aWRlckxhdGVzdExhenlMb2FkRXZlbnQgPSBldmVudDtcbiAgICAgICAgdGhpcy5sYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbisrO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IGZyb21UYWJsZUxvYWRUb0RhdGFMaXN0UGFyYW1zKGV2ZW50KTtcblxuICAgICAgICBpZiAodGhpcy51c2VRdWVyeVBhcmFtcygpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucm91dGVySXNOYXZpZ2F0aW9uT3V0c2lkZUluUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGNoZWNrIGlzIG5lY2Vzc2FyeTogZnJvbSBzb21lIHJlYXNvbiwgcHJpbWVORyBjb21taXRzIG9uZSBsYXN0IGxhenkgbG9hZCBldmVudCB3aGVuZXZlciBhbnkgYW5ndWxhciByb3V0ZXIgbmF2aWdhdGlvbiBvY2N1cnNcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXSwge1xuICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlLFxuICAgICAgICAgICAgICAgICAgICByZXBsYWNlVXJsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczogZGF0YUxpc3RQYXJhbXNUb1VybFF1ZXJ5KHBhcmFtcywgdGhpcy5kZWZhdWx0UGFyYW1zKCkpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIobWVyZ2VEYXRhTGlzdFBhcmFtc1dpdGhEZWZhdWx0cyhwYXJhbXMsIHRoaXMuZGVmYXVsdFBhcmFtcygpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25DZWxsQ2xpY2soZXZlbnQ6IEV2ZW50LCBjb2w6IENvbHVtbkRlc2NyaXB0b3I8YW55LCBJdGVtPiwgaXRlbTogSXRlbSwgaWR4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzQ2VsbENsaWNrRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFibGVFdmVudDogVGFibGVDZWxsQ2xpY2tFdmVudDxJdGVtPiA9IHtcbiAgICAgICAgICAgIGNvbHVtbjogY29sLFxuICAgICAgICAgICAgcm93SXRlbTogaXRlbSxcbiAgICAgICAgICAgIHJvd0luZGV4OiBpZHgsXG4gICAgICAgICAgICBldmVudDogZXZlbnRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jZWxsQ2xpY2tTdWJqZWN0Lm5leHQodGFibGVFdmVudCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uU2VsZWN0aW9uQ2hhbmdlKGV2ZW50OiBBcnJheTxJdGVtPikge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KGV2ZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Sb3dSZW9yZGVyKGV2ZW50OiBUYWJsZVJvd1Jlb3JkZXJFdmVudCkge1xuICAgICAgICB0aGlzLnJvd1Jlb3JkZXIuZW1pdChldmVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIGlzIGNhbGxlZCBvbiBjb2x1bW4gcmVzaXplXG4gICAgICogQHBhcmFtIGVsZW1lbnQgZXZlbnQncyBlbGVtZW50XG4gICAgICovXG4gICAgcHVibGljIG9uVGFibGVDb2x1bW5SZXNpemUoe2VsZW1lbnR9OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmllbGRJZDogc3RyaW5nID0gZWxlbWVudC5pZDtcbiAgICAgICAgY29uc3Qgd2lkdGg6IG51bWJlciA9IGVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgIGNvbnN0IGNvbCA9IHRoaXMuY29sdW1ucygpLmZpbmQoZWwgPT4gZWwuZGVzY3JpcHRvci5wcm9wZXJ0eSA9PT0gZmllbGRJZCk7XG4gICAgICAgIGlmIChjb2wpIGNvbC53aWR0aCA9IHdpZHRoO1xuICAgICAgICBpZiAoIWxheW91dFByZWZzLmNvbHVtbldpZHRocykgbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzID0ge307XG5cbiAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzW2ZpZWxkSWRdID0gd2lkdGg7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRUYWJsZVdpdGhEYXRhUHJvdmlkZXIocGFyYW1zV2l0aERlZmF1bHRzOiBEYXRhTGlzdFBhcmFtcywgZW1pdEV2ZW50ID0gdHJ1ZSkge1xuICAgICAgICBjb25zdCBkYXRhUHJvdmlkZXIgPSB0aGlzLmRhdGFQcm92aWRlcigpO1xuICAgICAgICBpZiAoIWRhdGFQcm92aWRlciB8fCBwYXJhbXNXaXRoRGVmYXVsdHMubGltaXQgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5sb2FkaW5nLnNldCh0cnVlKTtcblxuICAgICAgICB0aGlzLmxhdGVzdFBhcmFtc1dpdGhEZWZhdWx0cyA9IHBhcmFtc1dpdGhEZWZhdWx0cztcbiAgICAgICAgdGhpcy5sYXRlc3RQYXJhbXNXaXRoRGVmYXVsdHNWZXJzaW9uKys7XG5cbiAgICAgICAgdGhpcy5kYXRhUHJvdmlkZXJTdWJzY3JpcHRpb24gPSBjb21tb25zVG9PYnNlcnZhYmxlKFxuICAgICAgICAgICAgZGF0YVByb3ZpZGVyLmdldEFsbChcbiAgICAgICAgICAgICAgICBwYXJhbXNXaXRoRGVmYXVsdHMgYXMgRGF0YUxpc3RQYXJhbXM8U29ydHMsIEZpbHRlcnM+LFxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YVByb3ZpZGVyU2VydmljZSgpLFxuICAgICAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRvcigpLmlzTG9jYWxpemVkID8gdGhpcy5jb21tb25zLmFwcERhdGFMb2NhbGUoKSA/PyB1bmRlZmluZWQgOiB1bmRlZmluZWRcbiAgICAgICAgICAgIClcbiAgICAgICAgKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogcmVzID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZXNjcmlwdG9ySW5wdXQgPSB0aGlzLmRlc2NyaXB0b3JJbnB1dCgpO1xuICAgICAgICAgICAgICAgIGlmIChkZXNjcmlwdG9ySW5wdXQgaW5zdGFuY2VvZiBUYWJsZUR5bmFtaWNEZXNjcmlwdG9ySW5zdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3Iuc2V0KGRlc2NyaXB0b3JJbnB1dC50b1RhYmxlRGVzY3JpcHRvckZyb21EYXRhKHJlcykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5zZXREYXRhKHJlcz8uZGF0YSA/PyBbXSwgcmVzPy50b3RhbENvdW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IGVyciA9PiB7XG4gICAgICAgICAgICAgICAgdGFibGVOb3RpZmljYXRpb25FcnJvcih0aGlzLnRyYW5zbGF0ZSwgdGhpcy5kZXNjcmlwdG9yKCksIGVyciwgdGhpcy5tZXNzYWdlU2VydmljZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uuc2V0RGF0YShbXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2UubG9hZGluZy5zZXQoZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBmcm9tU3Vic2NyaWJlRXJyb3IoZXJyLCAnVGFibGVDb21wb25lbnRFcnJvcicsIHtcbiAgICAgICAgICAgICAgICAgICAgcXVlcnlQYXJhbTogcGFyYW1zV2l0aERlZmF1bHRzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIubG9nKGVycm9yLCBnZXRFcnJvckxvZ0xldmVsKGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChlbWl0RXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhYmxlRXZlbnQ6IFRhYmxlTG9hZEV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IHRoaXMuZGF0YVByb3ZpZGVyTGF0ZXN0TGF6eUxvYWRFdmVudCxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHBhcmFtc1dpdGhEZWZhdWx0c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMudGFibGVMb2FkLmVtaXQodGFibGVFdmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRUYWJsZUZyb21Sb3V0ZVVwZGF0ZSh1cmxQYXJhbXM6IFBhcmFtcykge1xuICAgICAgICBjb25zdCBwYXJhbXNXaXRoRGVmYXVsdHMgPSBtZXJnZURhdGFMaXN0UGFyYW1zV2l0aERlZmF1bHRzKGZyb21VcmxRdWVyeVRvRGF0YUxpc3RQYXJhbXModXJsUGFyYW1zKSwgdGhpcy5kZWZhdWx0UGFyYW1zKCkpO1xuICAgICAgICBpZiAodGhpcy5sYXRlc3RMYXp5TG9hZEV2ZW50VmVyc2lvbiA8IHRoaXMubGF0ZXN0UGFyYW1zV2l0aERlZmF1bHRzVmVyc2lvbiArIDEpIHtcbiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbmx5IGlmIG5ldyB2ZXJzaW9uIGZyb20gcXVlcnkgcGFyYW1zIHdpbGwgYmUgaGlnaGVyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVByaW1lU29ydEFuZEZpbHRlcihwYXJhbXNXaXRoRGVmYXVsdHMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXNlUXVlcnlQYXJhbXNJbml0aWFsaXplZC5zZXQodHJ1ZSk7XG4gICAgICAgIHRoaXMubG9hZFRhYmxlV2l0aERhdGFQcm92aWRlcihwYXJhbXNXaXRoRGVmYXVsdHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlUHJpbWVTb3J0QW5kRmlsdGVyKHBhcmFtc1dpdGhEZWZhdWx0czogRGF0YUxpc3RQYXJhbXMpIHtcbiAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uuc29ydE1ldGEuc2V0KHRoaXMuY3JlYXRlU29ydE1ldGEocGFyYW1zV2l0aERlZmF1bHRzKSk7XG4gICAgICAgIHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmZpbHRlck1ldGEuc2V0KHRoaXMuY3JlYXRlRmlsdGVyTWV0YShwYXJhbXNXaXRoRGVmYXVsdHMpKTtcbiAgICAgICAgdGhpcy5kYXRhTGlzdFNlcnZpY2Uucm93cy5zZXQocGFyYW1zV2l0aERlZmF1bHRzPy5saW1pdCA/PyB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzKCkpO1xuICAgICAgICB0aGlzLmRhdGFMaXN0U2VydmljZS5vZmZzZXQuc2V0KHBhcmFtc1dpdGhEZWZhdWx0cz8ub2Zmc2V0ID8/IDApO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlRmlsdGVyTWV0YShwYXJhbXNXaXRoRGVmYXVsdHM/OiBEYXRhTGlzdFBhcmFtcykge1xuICAgICAgICBjb25zdCBwcmltZUZpbHRlck1ldGE6IHtbczogc3RyaW5nXTogRmlsdGVyTWV0YWRhdGF9ID0ge307XG4gICAgICAgIC8vIGlmIGFueSBmaWx0ZXIgaXMgcHJlc2VudCwgbm8gZGVmYXVsdCBmaWx0ZXJzIHNob3VsZCBiZSBhcHBsaWVkIVxuICAgICAgICBpZiAocGFyYW1zV2l0aERlZmF1bHRzPy5maWx0ZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhwYXJhbXNXaXRoRGVmYXVsdHMuZmlsdGVycykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgcHJpbWVGaWx0ZXJNZXRhW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiB2YWx1ZS5tYXRjaE1vZGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJpbWVGaWx0ZXJNZXRhO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlU29ydE1ldGEocGFyYW1zV2l0aERlZmF1bHRzPzogRGF0YUxpc3RQYXJhbXMpOiBTb3J0TWV0YVtdIHwgbnVsbCB7XG4gICAgICAgIGlmIChwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQgIT09IHVuZGVmaW5lZCAmJiBBcnJheS5pc0FycmF5KHBhcmFtc1dpdGhEZWZhdWx0cz8uc29ydCkgJiYgcGFyYW1zV2l0aERlZmF1bHRzPy5zb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXNXaXRoRGVmYXVsdHM/LnNvcnQubWFwKFxuICAgICAgICAgICAgICAgIHMgPT5cbiAgICAgICAgICAgICAgICAgICAgPFNvcnRNZXRhPntcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkOiBzLnByb3BlcnR5LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXI6IHMuYXNjZW5kaW5nID8gMSA6IC0xXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db2x1bW5Ub2dnbGUoZXZlbnQ6IE11bHRpU2VsZWN0Q2hhbmdlRXZlbnQpIHtcbiAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkQ29sdW1ucyA9IChldmVudC52YWx1ZSBhcyBDb2x1bW5XaXRoUHJlZmVyZW5jZXNbXSkubWFwKHYgPT4gdi5kZXNjcmlwdG9yLnByb3BlcnR5KTtcbiAgICAgICAgY29uc3QgaGlkZGVuQ29sdW1ucyA9IHRoaXMuY29sdW1ucygpXG4gICAgICAgICAgICAuZmlsdGVyKGMgPT4gc2VsZWN0ZWRDb2x1bW5zLmluZGV4T2YoYy5kZXNjcmlwdG9yLnByb3BlcnR5KSA8IDApXG4gICAgICAgICAgICAubWFwKGMgPT4gYy5kZXNjcmlwdG9yLnByb3BlcnR5KTtcbiAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uSGlkZGVuID0gaGlkZGVuQ29sdW1ucztcbiAgICAgICAgdGhpcy5zYXZlTGF5b3V0UHJlZmVyZW5jZXMobGF5b3V0UHJlZnMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNvbHVtblRvZ2dsZUFsbCgpIHtcbiAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBbLi4udGhpcy5jb2x1bW5zKCldO1xuICAgICAgICBjb25zdCBpc1Zpc2libGUgPSAhdGhpcy5jb2x1bW5zKCkuc29tZShjID0+IGMuaXNWaXNpYmxlKTtcbiAgICAgICAgZm9yIChjb25zdCBjb2wgb2YgY29sdW1ucykge1xuICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSAhPT0gY29sLmlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIGNvbC5pc1Zpc2libGUgPSBpc1Zpc2libGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGF5b3V0UHJlZnMuY29sdW1uSGlkZGVuID0gY29sdW1ucy5maWx0ZXIoYyA9PiAhYy5pc1Zpc2libGUpLm1hcChjID0+IGMuZGVzY3JpcHRvci5wcm9wZXJ0eSk7XG4gICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db2x1bW5SZW9yZGVyKGV2ZW50OiBUYWJsZUNvbHVtblJlb3JkZXJFdmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuZHJvcEluZGV4ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQuZHJvcEluZGV4ID49IDAgJiYgZXZlbnQuZHJhZ0luZGV4ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQuZHJhZ0luZGV4ID49IDAgJiYgZXZlbnQuZHJvcEluZGV4ICE9PSBldmVudC5kcmFnSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RHJvcEluZGV4ID0gZXZlbnQuZHJvcEluZGV4O1xuICAgICAgICAgICAgY29uc3QgZXZlbnREcmFnSW5kZXggPSBldmVudC5kcmFnSW5kZXg7XG4gICAgICAgICAgICBjb25zdCBwcmV2VmlzaWJsZUNvbHVtbnMgPSB0aGlzLmNvbHVtbnMoKS5maWx0ZXIoYyA9PiBjLmlzVmlzaWJsZSk7XG4gICAgICAgICAgICBjb25zdCBjb2xBdERyb3AgPSBwcmV2VmlzaWJsZUNvbHVtbnNbZXZlbnREcm9wSW5kZXhdO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcmFnID0gcHJldlZpc2libGVDb2x1bW5zW2V2ZW50RHJhZ0luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGNvbEF0RHJvcEluZGV4ID0gdGhpcy5jb2x1bW5zKCkuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyb3AuaWQpO1xuICAgICAgICAgICAgY29uc3QgY29sQXREcmFnSW5kZXggPSB0aGlzLmNvbHVtbnMoKS5maW5kSW5kZXgoZWwgPT4gZWwuaWQgPT09IGNvbEF0RHJhZy5pZCk7XG5cbiAgICAgICAgICAgIGlmIChjb2xBdERyb3BJbmRleCA+IC0xICYmIGNvbEF0RHJhZ0luZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICBsZXQgY29sdW1ucyA9IFsuLi50aGlzLmNvbHVtbnMoKV07XG4gICAgICAgICAgICAgICAgY29sdW1ucy5zcGxpY2UoY29sQXREcmFnSW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRyb3BJbmRleCA9IGNvbHVtbnMuZmluZEluZGV4KGVsID0+IGVsLmlkID09PSBjb2xBdERyb3AuaWQpICsgKGV2ZW50RHJvcEluZGV4ID4gZXZlbnREcmFnSW5kZXggPyAxIDogMCk7XG4gICAgICAgICAgICAgICAgY29sdW1ucyA9IFsuLi5jb2x1bW5zLnNsaWNlKDAsIGRyb3BJbmRleCksIGNvbEF0RHJhZywgLi4uY29sdW1ucy5zbGljZShkcm9wSW5kZXgpXTtcbiAgICAgICAgICAgICAgICBjb25zdCBsYXlvdXRQcmVmcyA9IHRoaXMubGF5b3V0UHJlZmVyZW5jZXMoKTtcbiAgICAgICAgICAgICAgICBsYXlvdXRQcmVmcy5jb2x1bW5PcmRlciA9IGNvbHVtbnMubWFwKGVsID0+IGVsLmRlc2NyaXB0b3IucHJvcGVydHkpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2F2ZUxheW91dFByZWZlcmVuY2VzKGxheW91dFByZWZzOiBUYWJsZUxheW91dFByZWZlcmVuY2VzKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMubG9jYWxzdG9yYWdlS2V5KCk7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZVNlcnZpY2Uuc2V0SXRlbSh0aGlzLmNtcFR5cGVOYW1lLCBrZXksIGxheW91dFByZWZzKTtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0UHJlZnNTYXZlQ250LnVwZGF0ZSh2ID0+IHYgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZURlZmF1bHREYXRhTGlzdFBhcmFtcygpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zOiBEYXRhTGlzdFBhcmFtcyA9IHtcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIGxpbWl0OiB0aGlzLmRhdGFMaXN0U2VydmljZS5yb3dzUGVyUGFnZU9wdGlvbnMoKVswXSxcbiAgICAgICAgICAgIHNvcnQ6IHRoaXMuZGVzY3JpcHRvcigpXG4gICAgICAgICAgICAgICAgLnNvcnRzLmZpbHRlcihzID0+IHMuZGVmYXVsdElzRW5hYmxlZClcbiAgICAgICAgICAgICAgICAubWFwKHMgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6IHMucHJvcGVydHksXG4gICAgICAgICAgICAgICAgICAgIGFzY2VuZGluZzogcy5kZWZhdWx0SXNBc2NlbmRpbmdcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICBmaWx0ZXJzOiB7fVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZmlsdGVyRGVzY3JpcHRvcnMoKVxuICAgICAgICAgICAgLmZpbHRlcihkID0+IGQuaGFzRGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgLmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG1hdGNoTW9kZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gZi5kZWZhdWx0TWF0Y2hNb2RlO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZi5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLlN0cmluZzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGUgPSBGaWx0ZXJNYXRjaE1vZGUuQ29udGFpbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZpbHRlclR5cGVFbnVtLkxvb2t1cDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRmlsdGVyVHlwZUVudW0uTG9va3VwRW51bToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvb2t1cEZpbHRlciA9IGYgYXMgRmlsdGVyTG9va3VwRGVzY3JpcHRvcjxhbnksIEl0ZW0+O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb29rdXBGaWx0ZXIubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkluO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtYXRjaE1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlLkVxdWFscztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZi5tYXRjaE1vZGVzICYmICFmLm1hdGNoTW9kZXM/LmluY2x1ZGVzKG1hdGNoTW9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlID0gZi5tYXRjaE1vZGVzWzBdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZTogYW55IHwgYW55W10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gWy4uLnZhbHVlXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGYuZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gZi5wcm9wZXJ0eTtcbiAgICAgICAgICAgICAgICBwYXJhbXMuZmlsdGVycyFbcHJvcGVydHldID0ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoTW9kZTogbWF0Y2hNb2RlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlQ29sdW1uc1dpdGhMYXlvdXQoKSB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3IoKTtcbiAgICAgICAgY29uc3QgbGF5b3V0UHJlZnMgPSB0aGlzLmxheW91dFByZWZlcmVuY2VzKCk7XG5cbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBjb2x1bW5zIHdpdGggYWRkaXRpb25hbCBwcm9wZXJ0aWVzXG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBjb2x1bW5zOiBDb2x1bW5XaXRoUHJlZmVyZW5jZXNbXSA9IGRlc2NyaXB0b3IuY29sdW1ucy5tYXAoY29sID0+ICh7XG4gICAgICAgICAgICBpZDogYCR7Y29sLnByb3BlcnR5fS0ke3RpbWVzdGFtcH1gLFxuICAgICAgICAgICAgZGVzY3JpcHRvcjogY29sLFxuICAgICAgICAgICAgZmlsdGVyOiBkZXNjcmlwdG9yLmZpbHRlcnMuZmluZChmID0+IGYuc2hvd09uQ29sdW1uID09PSBjb2wucHJvcGVydHkpLFxuICAgICAgICAgICAgc29ydDogZGVzY3JpcHRvci5zb3J0cy5maW5kKGYgPT4gZi5zaG93T25Db2x1bW4gPT09IGNvbC5wcm9wZXJ0eSksXG4gICAgICAgICAgICBkaXNhYmxlZDogIWNvbC5pc1RvZ2dsZWFibGUsXG4gICAgICAgICAgICBpc1Zpc2libGU6IGxheW91dFByZWZzLmNvbHVtbkhpZGRlbiA/ICFsYXlvdXRQcmVmcy5jb2x1bW5IaWRkZW4uaW5jbHVkZXMoY29sLnByb3BlcnR5KSA6IGNvbC5pc1Zpc2libGUsXG4gICAgICAgICAgICB3aWR0aDogbGF5b3V0UHJlZnMuY29sdW1uV2lkdGhzPy5bY29sLnByb3BlcnR5XVxuICAgICAgICB9KSk7XG5cbiAgICAgICAgaWYgKGxheW91dFByZWZzLmNvbHVtbk9yZGVyKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxheW91dFByZWZzLmNvbHVtbk9yZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sTmFtZSA9IGxheW91dFByZWZzLmNvbHVtbk9yZGVyW2ldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpdGhQcmVmcyA9IGNvbHVtbnMuZmluZChlbCA9PiBlbC5kZXNjcmlwdG9yLnByb3BlcnR5ID09PSBjb2xOYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoY29sV2l0aFByZWZzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbFdpdGhQcmVmcy5vcmRlcklkeCA9IGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbHVtbnMuc29ydCgoYSwgYikgPT4gKGEub3JkZXJJZHggIT09IHVuZGVmaW5lZCAmJiBiLm9yZGVySWR4ICE9PSB1bmRlZmluZWQgPyBhLm9yZGVySWR4IC0gYi5vcmRlcklkeCA6IDApKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldCBjb2x1bW4gb3JkZXIgYW5kIGNvbHVtbiB2aXNpYmlsaXR5IHRvIGRlZmF1bHQgc2V0dGluZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVzZXREZWZhdWx0TGF5b3V0KCkge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmxvY2Fsc3RvcmFnZUtleSgpO1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICB0aGlzLnN0b3JhZ2VTZXJ2aWNlLnJlbW92ZUl0ZW0odGhpcy5jbXBUeXBlTmFtZSwga2V5KTtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0UHJlZnNTYXZlQ250LnVwZGF0ZSh2ID0+IHYgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxkaXY+XG4gICAgPCEtLSBNVVNUIE5PVCB1c2Ugb2JzZXJ2YWJsZSBmb3IgdmFsdWUgd2hlbiB1c2luZyB2aXJ0dWFsIHNjcm9sbCAtIGRvZXMgbm90IHdvcmsgZm9yIHNvbWUgcmVhc29uIC0tPlxuICAgIEBpZiAoIXVzZVF1ZXJ5UGFyYW1zKCkgfHwgdXNlUXVlcnlQYXJhbXNJbml0aWFsaXplZCgpKSB7XG4gICAgICAgIDxwLXRhYmxlXG4gICAgICAgICAgICBbdmFsdWVdPVwiZGF0YUxpc3RTZXJ2aWNlLmRhdGEoKVwiXG4gICAgICAgICAgICBbZGF0YUtleV09XCJkZXNjcmlwdG9yKCkudHJhY2tQcm9wZXJ0eVwiXG4gICAgICAgICAgICBbbGF6eV09XCJpc0xhenkoKVwiXG4gICAgICAgICAgICBbbG9hZGluZ109XCJkYXRhTGlzdFNlcnZpY2UubG9hZGluZygpXCJcbiAgICAgICAgICAgIFtwYWdpbmF0b3JdPVwiaXNQYWdpbmF0aW9uKClcIlxuICAgICAgICAgICAgW3Jvd3NdPVwiZGF0YUxpc3RTZXJ2aWNlLnJvd3MoKVwiXG4gICAgICAgICAgICBbZmlyc3RdPVwiZGF0YUxpc3RTZXJ2aWNlLm9mZnNldCgpXCJcbiAgICAgICAgICAgIFt0b3RhbFJlY29yZHNdPVwiZGF0YUxpc3RTZXJ2aWNlLmNvdW50KClcIlxuICAgICAgICAgICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJkYXRhTGlzdFNlcnZpY2Uucm93c1BlclBhZ2VPcHRpb25zKClcIlxuICAgICAgICAgICAgW3Nob3dDdXJyZW50UGFnZVJlcG9ydF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtjdXJyZW50UGFnZVJlcG9ydFRlbXBsYXRlXT1cIidtbmdUYWJsZS5wYWdpbmF0aW9uTXNnJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICBbbXVsdGlTb3J0TWV0YV09XCJkYXRhTGlzdFNlcnZpY2Uuc29ydE1ldGEoKVwiXG4gICAgICAgICAgICBbZmlsdGVyc109XCJkYXRhTGlzdFNlcnZpY2UuZmlsdGVyTWV0YSgpXCJcbiAgICAgICAgICAgIFtnbG9iYWxGaWx0ZXJGaWVsZHNdPVwiZGF0YUxpc3RTZXJ2aWNlLmdsb2JhbEZpbHRlckZpZWxkcygpXCJcbiAgICAgICAgICAgIHNvcnRNb2RlPVwibXVsdGlwbGVcIlxuICAgICAgICAgICAgW3NlbGVjdGlvbl09XCJbXVwiXG4gICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgW3NlbGVjdGlvbk1vZGVdPVwic2VsZWN0aW9uRW5hYmxlZCgpID8gc2VsZWN0aW9uTW9kZSgpIDogbnVsbFwiXG4gICAgICAgICAgICBbc2Nyb2xsYWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodD1cImZsZXhcIlxuICAgICAgICAgICAgW3Jvd0hvdmVyXT1cImRlc2NyaXB0b3IoKS5oYXNIb3ZlclwiXG4gICAgICAgICAgICBbc3R5bGVDbGFzc109XCJjbGFzc05hbWUoKVwiXG4gICAgICAgICAgICBbcmVzaXphYmxlQ29sdW1uc109XCJkZXNjcmlwdG9yKCkuaGFzUmVzaXphYmxlQ29sdW1uc1wiXG4gICAgICAgICAgICBbY29sdW1uUmVzaXplTW9kZV09XCJkZXNjcmlwdG9yKCkuY29sdW1uUmVzaXplTW9kZSA/PyAnZXhwYW5kJ1wiXG4gICAgICAgICAgICBbcmVvcmRlcmFibGVDb2x1bW5zXT1cImFyZUNvbHVtbnNSZW9yZGVyYWJsZSgpXCJcbiAgICAgICAgICAgIHBhZ2luYXRvckRyb3Bkb3duQXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgIFtjb2x1bW5zXT1cInZpc2libGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgKG9uQ29sUmVzaXplKT1cIm9uVGFibGVDb2x1bW5SZXNpemUoJGV2ZW50KVwiXG4gICAgICAgICAgICAob25Db2xSZW9yZGVyKT1cIm9uQ29sdW1uUmVvcmRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgIChvbkxhenlMb2FkKT1cIm9uVGFibGVMYXp5TG9hZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChvblJvd1Jlb3JkZXIpPVwib25Sb3dSZW9yZGVyKCRldmVudClcIj5cbiAgICAgICAgICAgIEBpZiAoY2FwdGlvblRlbXBsYXRlKCkgfHwgY2FwdGlvbkNvbXBvbmVudCgpIHx8IGRlc2NyaXB0b3IoKS50aXRsZSkge1xuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoY2FwdGlvblRlbXBsYXRlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjYXB0aW9uVGVtcGxhdGUoKVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjYXB0aW9uQ29tcG9uZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW21uZ0NvbXBvbmVudF09XCJjYXB0aW9uQ29tcG9uZW50KClcIiAoaW5zdGFuY2VDcmVhdGVkKT1cImNhcHRpb25Db21wb25lbnRJbnN0YW5jZS5lbWl0KCRldmVudClcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDUgY2xhc3M9XCJwLTAgbS0wXCI+e3sgZGVzY3JpcHRvcigpLnRpdGxlIH19PC9oNT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgQGlmICghZGVzY3JpcHRvcigpLmhpZGVIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwibW5nLXRhYmxlLWhlYWRlclwiIFtjbGFzc109XCJkZXNjcmlwdG9yKCkuaGVhZGVyQ2xhc3NOYW1lXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25Nb2RlKCkgPT09ICdtdWx0aXBsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHN0eWxlPVwibWluLXdpZHRoOiAzNnB4XCIgcEZyb3plbkNvbHVtbiBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5zZWxlY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFibGVIZWFkZXJDaGVja2JveD48L3AtdGFibGVIZWFkZXJDaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBXZSBuZWVkIHRoZSBsaW5lIGJlbG93LCBiZWNhdXNlIG90aGVyd2lzZSBwLXRhYmxlUmFkaW9CdXR0b24gc2hpZnRzIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zIGluIHRhYmxlIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCIgY2xhc3M9XCJjb2wtMVwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJ0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocm93UmVvcmRlckVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzb3J0YWJsZUNvbHVtblRIVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sLmRlc2NyaXB0b3IudGl0bGUgPz8gKGNvbC5kZXNjcmlwdG9yLnByb3BlcnR5IHwgbW5nSTE4blByb3BlcnR5OiBkZXNjcmlwdG9yKCkubW9kZWwpIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1zb3J0SWNvbiBbZmllbGRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIj48L3Atc29ydEljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub25Tb3J0YWJsZUNvbHVtblRIVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChjb2wuZGVzY3JpcHRvci5pc1Jlb3JkZXJhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJlc2l6YWJsZUNvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJlb3JkZXJhYmxlQ29sdW1uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiY29sLmRlc2NyaXB0b3IucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbl09XCJjb2wuc29ydD8ucHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BTb3J0YWJsZUNvbHVtbkRpc2FibGVkXT1cIiFjb2wuc29ydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29sLndpZHRoID8gY29sLndpZHRoICsgJ3B4JyA6IGNvbC5kZXNjcmlwdG9yLndpZHRoICsgJyUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5kZXNjcmlwdG9yLm1pbldpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZGVzY3JpcHRvci5oZWFkZXJDbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb2wuc29ydCA/IHNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZSA6IG5vblNvcnRhYmxlQ29sdW1uVEhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZXNpemFibGVDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uXT1cImNvbC5zb3J0Py5wcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFNvcnRhYmxlQ29sdW1uRGlzYWJsZWRdPVwiIWNvbC5zb3J0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggPyBjb2wud2lkdGggKyAncHgnIDogY29sLmRlc2NyaXB0b3Iud2lkdGggKyAnJSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wud2lkdGggPyBudWxsIDogY29sLmRlc2NyaXB0b3IubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2wud2lkdGggPz8gY29sLmRlc2NyaXB0b3IubWF4V2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cImNvbC5kZXNjcmlwdG9yLmhlYWRlckNsYXNzTmFtZSB8IG1uZ1RhYmxlQ29sdW1uRmlsdGVyQ2xhc3M6IGNvbC5maWx0ZXIgOiBoYXNDb2x1bW5GaWx0ZXJzKCkgJiYgIWNvbC53aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbC5zb3J0ID8gc29ydGFibGVDb2x1bW5USFRlbXBsYXRlIDogbm9uU29ydGFibGVDb2x1bW5USFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChoYXNMYXN0Q29sdW1uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2x1bW5MYXN0TWluV2lkdGgoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuYWN0aW9uQ29sdW1uRnJvemVuID8/IGFyZUNvbHVtbnNUb2dnbGVhYmxlKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbkZyb3plbj1cInJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2x1bW4tY3VzdG9tLWxhc3QgdGV4dC1yaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGRlc2NyaXB0b3IoKS5oYXNSZXNpemFibGVDb2x1bW5zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3M9XCJwLWJ1dHRvbi1wcmltYXJ5IG1uZy10YWJsZS1jb2x1bW5zLW11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFLZXk9XCJpZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwibGVmdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyb3Bkb3duSWNvbj1cInBpIHBpLXNsaWRlcnMtaFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZpbHRlcl09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwiY29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ2aXNpYmxlQ29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcFRvb2x0aXBdPVwiJ21uZ1RhYmxlLmFkanVzdFRhYmxlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc3BsYXlTZWxlY3RlZExhYmVsXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25Db2x1bW5Ub2dnbGUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmaWx0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY2hlY2tib3ggcC1jb21wb25lbnQgbWwtMVwiIFtuZ0NsYXNzXT1cInsncC1jaGVja2JveC1kaXNhYmxlZCc6ICFhcmVDb2x1bW5zVG9nZ2xlYWJsZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWhpZGRlbi1hY2Nlc3NpYmxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRvbmx5PVwicmVhZG9ubHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5hbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5vbkhlYWRlckNoZWNrYm94Rm9jdXMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChibHVyKT1cImNvbHVtblRvZ2dsZU11bHRpc2VsZWN0Lm9uSGVhZGVyQ2hlY2tib3hCbHVyKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5vblRvZ2dsZUFsbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFhcmVDb2x1bW5zVG9nZ2xlYWJsZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInAtY2hlY2tib3gtYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJjb2x1bW5Ub2dnbGVNdWx0aXNlbGVjdC5hbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1oaWdobGlnaHQnOiBhbnlDb2x1bW5WaXNpYmxlKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25Db2x1bW5Ub2dnbGVBbGwoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicC1jaGVja2JveC1pY29uXCIgW25nQ2xhc3NdPVwieydwaSBwaS1jaGVjayc6IGFueUNvbHVtblZpc2libGUoKX1cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLXJlcGxheVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUNsYXNzPVwicC1idXR0b24tc2Vjb25kYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwVG9vbHRpcF09XCInbW5nVGFibGUucmVzZXRMYXlvdXQnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImxlZnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlc2V0RGVmYXVsdExheW91dCgpXCI+PC9wLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0uZGVzY3JpcHRvci50aXRsZSA/PyAoaXRlbS5kZXNjcmlwdG9yLnByb3BlcnR5IHwgbW5nSTE4blByb3BlcnR5OiBkZXNjcmlwdG9yKCkubW9kZWwpIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBpZiAoaGFzQ29sdW1uRmlsdGVycygpKSB7XG4gICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cIm1uZy1jb2x1bW4tZmlsdGVyLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBXZSBuZWVkIHRoZSBsaW5lIGJlbG93LCBiZWNhdXNlIG90aGVyd2lzZSBwLXRhYmxlUmFkaW9CdXR0b24gc2hpZnRzIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zIGluIHRhYmxlIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3Rpb25FbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocm93UmVvcmRlckVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJjb2wuZmlsdGVyPy5jb2x1bW5DbGFzc05hbWUgfCBtbmdUYWJsZUNvbHVtbkZpbHRlckNsYXNzOiBjb2wuZmlsdGVyIDogaGFzQ29sdW1uRmlsdGVycygpICYmICFjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwiY29sLndpZHRoID8gbnVsbCA6IGNvbC5maWx0ZXI/LmNvbHVtbldpZHRoID8/IGNvbC5kZXNjcmlwdG9yLndpZHRoID8/IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbC53aWR0aCA/IG51bGwgOiBjb2wuZmlsdGVyPy5jb2x1bW5NaW5XaWR0aCA/PyBjb2wuZGVzY3JpcHRvci5taW5XaWR0aFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1uZy10YWJsZS1jb2x1bW4tZmlsdGVyLWZ1bGwgW2Rlc2NyaXB0b3JdPVwiY29sLmZpbHRlclwiPjwvbW5nLXRhYmxlLWNvbHVtbi1maWx0ZXItZnVsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGhhc0xhc3RDb2x1bW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdFwiIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoKClcIj48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiYm9keVwiIGxldC1pdGVtIGxldC1pZHg9XCJyb3dJbmRleFwiIGxldC1leHBhbmRlZD1cImV4cGFuZGVkXCI+XG4gICAgICAgICAgICAgICAgPHRyXG4gICAgICAgICAgICAgICAgICAgIFtwUmVvcmRlcmFibGVSb3ddPVwiaWR4XCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZGVzY3JpcHRvcigpLnJvd0NsYXNzTmFtZSB8IG1uZ0NsYXNzTWFwOiBkZXNjcmlwdG9yKCkucm93Q2xhc3NOYW1lTWFwRm4gOiBpdGVtIHwgbW5nTG9jYWxlRGVmYXVsdFJvd0NsYXNzOiBkZXNjcmlwdG9yKCkgOiBpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoc2VsZWN0aW9uRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHNlbGVjdGlvbk1vZGUoKSA9PT0gJ211bHRpcGxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cIm1pbi13aWR0aDogMzZweFwiIHBGcm96ZW5Db2x1bW4gW2Zyb3plbl09XCJkZXNjcmlwdG9yKCkuc2VsZWN0aW9uQ29sdW1uRnJvemVuID8/IHRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFibGVDaGVja2JveCBbdmFsdWVdPVwiaXRlbVwiPjwvcC10YWJsZUNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XCJtaW4td2lkdGg6IDM2cHhcIiBwRnJvemVuQ29sdW1uIFtmcm96ZW5dPVwiZGVzY3JpcHRvcigpLnNlbGVjdGlvbkNvbHVtbkZyb3plbiA/PyB0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwLXRhYmxlUmFkaW9CdXR0b24gW3ZhbHVlXT1cIml0ZW1cIj48L3AtdGFibGVSYWRpb0J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGVQcm9wZXJ0eSB8fCBpdGVtW2Rlc2NyaXB0b3IoKS5yb3dFeHBhbmRhYmxlUHJvcGVydHkhXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwUm93VG9nZ2xlcl09XCJpdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tdGV4dCBwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXBsYWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpY29uXT1cImV4cGFuZGVkID8gJ3BpIHBpLWNoZXZyb24tZG93bicgOiAncGkgcGktY2hldnJvbi1yaWdodCdcIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAocm93UmVvcmRlckVuYWJsZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGkgcGktYmFyc1wiIHBSZW9yZGVyYWJsZVJvd0hhbmRsZT48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiB2aXNpYmxlQ29sdW1ucygpOyB0cmFjayBjb2wuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkNlbGxDbGljaygkZXZlbnQsIGNvbC5kZXNjcmlwdG9yLCBpdGVtLCBpZHgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5kZXNjcmlwdG9yLmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBtbmdDbGFzc01hcDogY29sLmRlc2NyaXB0b3IuY2xhc3NOYW1lTWFwRm4gOiBpdGVtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG1uZ1RhYmxlQ29sdW1uRmlsdGVyQ2xhc3M6IGNvbC5maWx0ZXIgOiBoYXNDb2x1bW5GaWx0ZXJzKCkgJiYgIWNvbC53aWR0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmNsaWNrYWJsZV09XCJpc0NlbGxDbGlja0VuYWJsZWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbC53aWR0aCA/IGNvbC53aWR0aCArICdweCcgOiBjb2wuZGVzY3JpcHRvci53aWR0aCArICclJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2wud2lkdGggPyBudWxsIDogY29sLmRlc2NyaXB0b3IubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sLndpZHRoID8/IGNvbC5kZXNjcmlwdG9yLm1heFdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwLWNvbHVtbi10aXRsZVwiPnt7IGNvbC5kZXNjcmlwdG9yLnRpdGxlID8/IChjb2wuZGVzY3JpcHRvci5wcm9wZXJ0eSB8IG1uZ0kxOG5Qcm9wZXJ0eTogZGVzY3JpcHRvcigpLm1vZGVsKSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLXRhYmxlLWNvbHVtbi12YWx1ZSBbZGVzY3JpcHRvcl09XCJjb2wuZGVzY3JpcHRvclwiIFtpdGVtXT1cIml0ZW1cIj48L21uZy10YWJsZS1jb2x1bW4tdmFsdWU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoaGFzTGFzdENvbHVtbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbHVtbi1jdXN0b20tbGFzdCBqdXN0aWZ5LWNvbnRlbnQtZW5kIHRleHQtcmlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uTGFzdE1pbldpZHRoKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBGcm96ZW5Db2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZnJvemVuXT1cImRlc2NyaXB0b3IoKS5hY3Rpb25Db2x1bW5Gcm96ZW4gPz8gdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25Gcm96ZW49XCJyaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sdW1uQ3VzdG9tTGFzdFRlbXBsYXRlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbHVtbkN1c3RvbUxhc3RUZW1wbGF0ZSgpOyBjb250ZXh0OiB7cm93SXRlbTogaXRlbSwgcm93SW5kZXg6IGlkeH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjb2x1bW5DdXN0b21MYXN0Q29tcG9uZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbW5nQ29tcG9uZW50XT1cImNvbHVtbkN1c3RvbUxhc3RDb21wb25lbnQoKVwiIChpbnN0YW5jZUNyZWF0ZWQpPVwiY29sdW1uQ3VzdG9tTGFzdENvbXBvbmVudEluc3RhbmNlLmVtaXQoJGV2ZW50KVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIEBpZiAoZGVzY3JpcHRvcigpLnJvd0V4cGFuZGFibGUpIHtcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwicm93ZXhwYW5zaW9uXCIgbGV0LWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC0xXCI+PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBbY29sU3Bhbl09XCJkZXNjcmlwdG9yKCkucm93RXhwYW5kYWJsZUNvbFNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicm93RXhwYW5kVGVtcGxhdGUoKTsgY29udGV4dDoge3Jvd0l0ZW06IGl0ZW19XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwibG9hZGluZ2ljb25cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkubG9hZGluZ0ljb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIFtjbGFzc109XCIndGV4dC13aGl0ZSB0ZXh0LTR4bCBwaS1zcGluICcgKyBkZXNjcmlwdG9yKCkubG9hZGluZ0ljb25cIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChkZXNjcmlwdG9yKCkubG9hZGluZ1RleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0IHRleHQtd2hpdGUgdGV4dC1sZyBmb250LXNlbWlib2xkXCIgW25nQ2xhc3NdPVwieydtdC0zJzogZGVzY3JpcHRvcigpLmxvYWRpbmdJY29ufVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRlc2NyaXB0b3IoKS5sb2FkaW5nVGV4dCA/PyAnJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwibG9hZGluZ2JvZHlcIj5cbiAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnNDb2xzcGFuKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nLXRleHRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLXNrZWxldG9uIFtuZ1N0eWxlXT1cInt3aWR0aDogJzEwMCUnfVwiPjwvcC1za2VsZXRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJlbXB0eW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnNDb2xzcGFuKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7ICdtbmdUYWJsZS5ub0l0ZW1zJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgQGlmIChmb290ZXJUZW1wbGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cInN1bW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvb3RlclRlbXBsYXRlKCk7IGNvbnRleHQ6IHtkYXRhOiBkYXRhTGlzdFNlcnZpY2UuZGF0YSgpLCB0b3RhbENvdW50OiBkYXRhTGlzdFNlcnZpY2UuY291bnQoKX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgfVxuICAgICAgICA8L3AtdGFibGU+XG4gICAgfVxuPC9kaXY+XG4iXX0=