@energycap/components 0.44.8 → 0.44.9-Angular19Upgrade.20260217-1620

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 (145) hide show
  1. package/fesm2022/energycap-components.mjs +379 -354
  2. package/fesm2022/energycap-components.mjs.map +1 -1
  3. package/lib/controls/button/copy-button-base.directive.d.ts +1 -1
  4. package/lib/controls/date-input/date-input.component.d.ts +1 -1
  5. package/lib/controls/form-control-base.d.ts +1 -1
  6. package/lib/core/date-time-helper.d.ts +2 -2
  7. package/lib/display/hierarchy/hierarchy-base.d.ts +1 -1
  8. package/lib/display/hierarchy/hierarchy-mocks.spec.d.ts +1 -1
  9. package/lib/display/resizable/resizable-base.d.ts +1 -1
  10. package/lib/shared/display/pipes/date-display.pipe.d.ts +1 -1
  11. package/lib/shared/page/page-base/page-base.component.d.ts +1 -1
  12. package/lib/shared/testing/public-mocks.spec.d.ts +1 -1
  13. package/lib/shared/wizard/wizard-base/wizard-base.component.d.ts +1 -1
  14. package/package.json +1 -3
  15. package/schematics/utilities/typescript.js +3 -4
  16. package/schematics/utilities/typescript.js.map +1 -1
  17. package/schematics/utilities/workspace.d.ts +0 -8
  18. package/schematics/utilities/workspace.js +48 -71
  19. package/schematics/utilities/workspace.js.map +1 -1
  20. package/esm2022/energycap-components.mjs +0 -5
  21. package/esm2022/lib/components.module.mjs +0 -425
  22. package/esm2022/lib/controls/banner/banner.component.mjs +0 -112
  23. package/esm2022/lib/controls/button/button.component.mjs +0 -114
  24. package/esm2022/lib/controls/button/copy-button-base.directive.mjs +0 -67
  25. package/esm2022/lib/controls/button/copy-button.directive.mjs +0 -28
  26. package/esm2022/lib/controls/button/copy-table-button.directive.mjs +0 -43
  27. package/esm2022/lib/controls/calendar/calendar-item.component.mjs +0 -91
  28. package/esm2022/lib/controls/calendar/calendar.component.mjs +0 -251
  29. package/esm2022/lib/controls/calendar/calendar.types.mjs +0 -2
  30. package/esm2022/lib/controls/checkbox/checkbox.component.mjs +0 -140
  31. package/esm2022/lib/controls/collapsible-toggle/collapsible-toggle.component.mjs +0 -38
  32. package/esm2022/lib/controls/combobox/combobox.component.mjs +0 -879
  33. package/esm2022/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.mjs +0 -57
  34. package/esm2022/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.mjs +0 -62
  35. package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.mjs +0 -100
  36. package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.mjs +0 -101
  37. package/esm2022/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.mjs +0 -76
  38. package/esm2022/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.mjs +0 -79
  39. package/esm2022/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.mjs +0 -210
  40. package/esm2022/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.mjs +0 -81
  41. package/esm2022/lib/controls/date-input/date-input.component.mjs +0 -466
  42. package/esm2022/lib/controls/date-input/date-input.types.mjs +0 -44
  43. package/esm2022/lib/controls/dropdown/dropdown.component.mjs +0 -243
  44. package/esm2022/lib/controls/file-upload/file-upload.component.mjs +0 -261
  45. package/esm2022/lib/controls/form-control/form-control.component.mjs +0 -110
  46. package/esm2022/lib/controls/form-control-base.mjs +0 -151
  47. package/esm2022/lib/controls/form-control-label/form-control-label.component.mjs +0 -136
  48. package/esm2022/lib/controls/form-group/form-group.component.mjs +0 -261
  49. package/esm2022/lib/controls/help-popover/help-popover.component.mjs +0 -31
  50. package/esm2022/lib/controls/item-picker/item-picker.component.mjs +0 -329
  51. package/esm2022/lib/controls/link-button/link-button.component.mjs +0 -11
  52. package/esm2022/lib/controls/menu/menu.component.mjs +0 -485
  53. package/esm2022/lib/controls/navigation/link-item.mjs +0 -2
  54. package/esm2022/lib/controls/navigation/nav-group.mjs +0 -39
  55. package/esm2022/lib/controls/navigation/nav-item-active.directive.mjs +0 -92
  56. package/esm2022/lib/controls/navigation/nav-item.mjs +0 -2
  57. package/esm2022/lib/controls/numericbox/numericbox.component.mjs +0 -372
  58. package/esm2022/lib/controls/popover/popover.component.mjs +0 -117
  59. package/esm2022/lib/controls/radio-button/radio-button-option.mjs +0 -3
  60. package/esm2022/lib/controls/radio-button/radio-button.component.mjs +0 -82
  61. package/esm2022/lib/controls/select/select.component.mjs +0 -88
  62. package/esm2022/lib/controls/tabs/tabs.component.mjs +0 -47
  63. package/esm2022/lib/controls/textbox/textbox.component.mjs +0 -155
  64. package/esm2022/lib/core/cache.service.mjs +0 -105
  65. package/esm2022/lib/core/custom-validators.mjs +0 -29
  66. package/esm2022/lib/core/date-time-helper.mjs +0 -228
  67. package/esm2022/lib/core/error.service.mjs +0 -61
  68. package/esm2022/lib/core/router-helper.service.mjs +0 -111
  69. package/esm2022/lib/core/scroll.service.mjs +0 -89
  70. package/esm2022/lib/core/telemetry-tracker.service.mjs +0 -16
  71. package/esm2022/lib/core/telemetry.service.mjs +0 -38
  72. package/esm2022/lib/core/validation-message.service.mjs +0 -185
  73. package/esm2022/lib/core/validation-patterns.mjs +0 -31
  74. package/esm2022/lib/core/window.service.mjs +0 -186
  75. package/esm2022/lib/display/app-bar/app-bar.component.mjs +0 -49
  76. package/esm2022/lib/display/avatar/avatar.component.mjs +0 -67
  77. package/esm2022/lib/display/avatar/avatar.service.mjs +0 -64
  78. package/esm2022/lib/display/confirm/confirm.component.mjs +0 -168
  79. package/esm2022/lib/display/dialog/dialog-content.mjs +0 -2
  80. package/esm2022/lib/display/dialog/dialog-group/dialog-group.component.mjs +0 -63
  81. package/esm2022/lib/display/dialog/dialog-types.mjs +0 -77
  82. package/esm2022/lib/display/dialog/dialog.component.mjs +0 -287
  83. package/esm2022/lib/display/dialog/dialog.service.mjs +0 -71
  84. package/esm2022/lib/display/help/help-types.mjs +0 -2
  85. package/esm2022/lib/display/hierarchy/hierarchy-base.mjs +0 -111
  86. package/esm2022/lib/display/hierarchy/hierarchy-mocks.spec.mjs +0 -54
  87. package/esm2022/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +0 -65
  88. package/esm2022/lib/display/item-display/item-display.component.mjs +0 -83
  89. package/esm2022/lib/display/json-display/json-display.component.mjs +0 -47
  90. package/esm2022/lib/display/resizable/resizable-base.mjs +0 -120
  91. package/esm2022/lib/display/resizable/resizable.component.mjs +0 -57
  92. package/esm2022/lib/display/spinner/spinner.component.mjs +0 -12
  93. package/esm2022/lib/display/splash/splash.component.mjs +0 -61
  94. package/esm2022/lib/display/splash/splash.service.mjs +0 -35
  95. package/esm2022/lib/display/table/resizable-column.component.mjs +0 -20
  96. package/esm2022/lib/display/table/resizable-table.directive.mjs +0 -227
  97. package/esm2022/lib/display/table/searchable-table.component.mjs +0 -344
  98. package/esm2022/lib/display/table/table-detail-row.component.mjs +0 -28
  99. package/esm2022/lib/display/table/table-locked-column.component.mjs +0 -58
  100. package/esm2022/lib/display/table/table-master-header-row.component.mjs +0 -14
  101. package/esm2022/lib/display/table/table-master-row.component.mjs +0 -163
  102. package/esm2022/lib/display/table/table-pagination.component.mjs +0 -155
  103. package/esm2022/lib/display/table/table-selectable-row.component.mjs +0 -235
  104. package/esm2022/lib/display/table/table.component.mjs +0 -257
  105. package/esm2022/lib/display/tags/tag.mjs +0 -18
  106. package/esm2022/lib/display/tags/tags.component.mjs +0 -82
  107. package/esm2022/lib/display/toast/toast/toast.component.mjs +0 -77
  108. package/esm2022/lib/display/toast/toast-types.mjs +0 -8
  109. package/esm2022/lib/display/toast/toast.service.mjs +0 -35
  110. package/esm2022/lib/display/toast/toaster/toaster.component.mjs +0 -114
  111. package/esm2022/lib/display/tooltip/tooltip.component.mjs +0 -28
  112. package/esm2022/lib/display/tooltip/tooltip.service.mjs +0 -78
  113. package/esm2022/lib/display/tooltip-directive/tooltip.directive.mjs +0 -173
  114. package/esm2022/lib/display/tree/tree.component.mjs +0 -139
  115. package/esm2022/lib/display/view-overlay/view-overlay.component.mjs +0 -58
  116. package/esm2022/lib/shared/directives/click-area-for/click-area-for.directive.mjs +0 -32
  117. package/esm2022/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +0 -111
  118. package/esm2022/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.mjs +0 -103
  119. package/esm2022/lib/shared/directives/popup/popup-container.directive.mjs +0 -166
  120. package/esm2022/lib/shared/display/pipes/date-display-2.pipe.mjs +0 -39
  121. package/esm2022/lib/shared/display/pipes/date-display.pipe.mjs +0 -51
  122. package/esm2022/lib/shared/display/pipes/highlight-text.pipe.mjs +0 -30
  123. package/esm2022/lib/shared/display/pipes/relative-date.pipe.mjs +0 -62
  124. package/esm2022/lib/shared/display/pipes/row-count.pipe.mjs +0 -48
  125. package/esm2022/lib/shared/display/pipes/time-display.pipe.mjs +0 -41
  126. package/esm2022/lib/shared/display.mjs +0 -6
  127. package/esm2022/lib/shared/form-group.helper.mjs +0 -67
  128. package/esm2022/lib/shared/json-helper.mjs +0 -19
  129. package/esm2022/lib/shared/lodash-helper.mjs +0 -52
  130. package/esm2022/lib/shared/page/page-base/page-base.component.mjs +0 -387
  131. package/esm2022/lib/shared/page/page-statuses.mjs +0 -23
  132. package/esm2022/lib/shared/page/page-title/page-title.component.mjs +0 -23
  133. package/esm2022/lib/shared/page/page-view/page-view.component.mjs +0 -147
  134. package/esm2022/lib/shared/testing/copy-button-base-test-injector-factory.spec.mjs +0 -17
  135. package/esm2022/lib/shared/testing/hierarchy-base-test-injector-factory.spec.mjs +0 -17
  136. package/esm2022/lib/shared/testing/page-base-component-test-helper.spec.mjs +0 -38
  137. package/esm2022/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +0 -98
  138. package/esm2022/lib/shared/testing/public-mocks.spec.mjs +0 -148
  139. package/esm2022/lib/shared/testing/spy-factory.spec.mjs +0 -40
  140. package/esm2022/lib/shared/testing/translation-mocks.spec.mjs +0 -57
  141. package/esm2022/lib/shared/user-preference.service.mjs +0 -17
  142. package/esm2022/lib/shared/wizard/wizard-base/wizard-base.component.mjs +0 -246
  143. package/esm2022/lib/shared/wizard/wizard-buttons/wizard-buttons.component.mjs +0 -68
  144. package/esm2022/lib/shared/wizard/wizard-progress/wizard-progress.component.mjs +0 -18
  145. package/esm2022/public-api.mjs +0 -115
@@ -1,485 +0,0 @@
1
- import { Component, EventEmitter, HostBinding, Input, Output, ViewChild } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- import * as i1 from "../../core/window.service";
4
- import * as i2 from "../../core/scroll.service";
5
- import * as i3 from "@angular/common";
6
- import * as i4 from "@angular/router";
7
- import * as i5 from "../navigation/nav-item-active.directive";
8
- import * as i6 from "../help-popover/help-popover.component";
9
- import * as i7 from "@ngx-translate/core";
10
- ;
11
- export const menuAnimationSpeed = 350;
12
- /**
13
- * Primitive Menu component that encapsulates known templates
14
- *
15
- * @export
16
- */
17
- export class MenuComponent {
18
- /**
19
- * Helper function to return a flat list of all selectable items in the provided menu items. Filters out headings and divided-sections.
20
- * This makes it much easier to keep track of currently highlighted items for keyboard navigation.
21
- */
22
- static getSelectableItems(items) {
23
- return items.reduce((selectableItems, item) => {
24
- if (item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section') {
25
- selectableItems.push(item);
26
- }
27
- else if (item.items) {
28
- selectableItems.push(...item.items.filter(childItem => childItem.display !== 'heading' && childItem.display !== 'divided-section' && childItem.display !== 'heading-divided-section'));
29
- }
30
- return selectableItems;
31
- }, []);
32
- }
33
- /**
34
- * Returns an ID for the provided item based on its index in the provided items array. This mimics the behavior of the MenuComponent's
35
- * generated IDs for items that don't have provided IDs. This is used in MenuComponent and ComboboxComponent to scroll to specific items.
36
- * NOTE: If the items array does not match what is displayed in the menu, this function will not return the correct ID.
37
- *
38
- * Returns null if the not found
39
- * @param items The MenuItems array to search through.
40
- * @param item The item to generate the ID for.
41
- * @param menuComponentId Used to prefix the generated ID. This should be the ID of the menu component the item is present in.
42
- * @memberof MenuComponent
43
- */
44
- static getIndexedItemId(items, item, menuComponentId) {
45
- if (item) {
46
- for (let i = 0; i < items.length; i++) {
47
- const itemInList = items[i];
48
- if (itemInList.label === item.label) {
49
- return `${menuComponentId}_item${i}`;
50
- }
51
- // If the item is a heading or divided section, check its children
52
- if (itemInList.items && (itemInList.display === 'heading' || itemInList.display === 'divided-section' || itemInList.display === 'heading-divided-section')) {
53
- for (let j = 0; j < itemInList.items.length; j++) {
54
- const childItem = itemInList.items[j];
55
- // Fall back to checking only the label if the item doesn't have an id
56
- if (childItem.label === item.label) {
57
- return `${menuComponentId}_item${i}-${j}`;
58
- }
59
- }
60
- }
61
- }
62
- }
63
- return null;
64
- }
65
- constructor(el, renderer, windowService, scrollService) {
66
- this.el = el;
67
- this.renderer = renderer;
68
- this.windowService = windowService;
69
- this.scrollService = scrollService;
70
- /**
71
- * Array of items to display
72
- *
73
- * @memberof MenuComponent
74
- */
75
- this.items = [];
76
- /**
77
- * Selected item; annotates the item
78
- * when displayed with 'selected' class
79
- *
80
- * @memberof MenuComponent
81
- */
82
- this.selected = null;
83
- /**
84
- * Display template
85
- *
86
- * @memberof MenuComponent
87
- */
88
- this.templateType = 'label';
89
- /**
90
- * Show message when there are no items
91
- */
92
- this.showNoItems = false;
93
- /**
94
- * Text to show when menu is empty and showNoItems is true
95
- */
96
- this.noDataText = 'NoItems_TC';
97
- /**
98
- * Controls whether keyboard navigation is enabled
99
- */
100
- this.enableKeyNav = false;
101
- /**
102
- * Item currently highlighted by keyboard navigation
103
- */
104
- this.highlightedItem = null;
105
- /**
106
- * Tells the menu to maintain the selected/lastSelected item. Turning this off is useful for
107
- * action type menus that are displayed on the screen at all times and you do not
108
- * want the item to be selected when clicked.
109
- */
110
- this.maintainSelectedItem = true;
111
- /**
112
- * Will prevent text-wrapping of menu items and truncate instead. Also turns on a tooltip for the menu item. Default: false;
113
- */
114
- this.truncateItems = false;
115
- /**
116
- * When true, the space for the icon is preserved for menu items that do not have icons.
117
- * Only applicable for iconAndLabel menus.
118
- */
119
- this.preserveIconSpace = false;
120
- /**
121
- * Emitted when `selected` is changed. Emits the referenced object.
122
- *
123
- * @memberof MenuComponent
124
- */
125
- this.selectedChanged = new EventEmitter();
126
- /**
127
- * Emitted when the menu has a parent and back is clicked
128
- * @memberof MenuComponent
129
- */
130
- this.menuClosed = new EventEmitter();
131
- /**
132
- * Index of the item currently highlighted using keyboard nav
133
- */
134
- this.highlightedItemIndex = -1;
135
- /**
136
- * Last item this.selected was set to via selectItem().
137
- * This isn't necessarily the same as this.selected, because this.selected is an input property
138
- * and could have been changed by a consumer through some means other than selectItem().
139
- * This allows us to prevent double-calls to selectItem() with the same input.
140
- */
141
- this.lastSelected = null;
142
- /**
143
- * Flattened array of all selectable items in the menu. Makes it easier to keep track of the currently highlighted item for keyboard navigation.
144
- */
145
- this.selectableItems = [];
146
- }
147
- ngOnChanges(changes) {
148
- if (changes.items && this.items) {
149
- this.selectableItems = MenuComponent.getSelectableItems(this.items);
150
- }
151
- }
152
- /**
153
- * Sets & displays the interalized template based on
154
- * the set template.
155
- * @see { @link https://angular.io/guide/lifecycle-hooks|Angular Lifecycle Hooks}
156
- *
157
- * @memberof MenuComponent
158
- */
159
- ngAfterContentInit() {
160
- switch (this.templateType) {
161
- case ("label"):
162
- this.internalizedTemplate = this.iconAndLabelTemplate;
163
- break;
164
- case ("iconAndLabel"):
165
- this.internalizedTemplate = this.iconAndLabelTemplate;
166
- break;
167
- case ("checkAndLabel"):
168
- this.internalizedTemplate = this.checkAndLabelTemplate;
169
- break;
170
- case ("iconLabelCaption"):
171
- this.internalizedTemplate = this.iconLabelCaptionTemplate;
172
- break;
173
- default:
174
- throw new Error(`Invalid templateType for MenuComponent. Please use either: 'label', 'iconAndLabel' or 'checkAndLabel'`);
175
- }
176
- //if the consumer provided a menuItemTemplate, override the internalizedTemplate with that.
177
- if (this.customMenuTemplate) {
178
- this.internalizedTemplate = this.customMenuTemplate;
179
- }
180
- if (this.id) {
181
- this.attrId = this.id;
182
- }
183
- this.setItemIds();
184
- if (this.highlightedItem && this.selectableItems.length) {
185
- this.highlightedItemIndex = this.selectableItems.findIndex(item => { return this.highlightedItem === item; });
186
- }
187
- this.addKeydownListener();
188
- }
189
- ngOnDestroy() {
190
- // Remove the listener when the component is destroyed
191
- if (this.removeKeydownListener) {
192
- this.removeKeydownListener();
193
- }
194
- }
195
- /**
196
- * When a menu item is selected, open a child menu if the item has items, call
197
- * the item's click method if defined, or emit the selected item.
198
- *
199
- * @param item The selected item
200
- * @memberof MenuComponent
201
- */
202
- selectItem(event, item, isKeyEvent) {
203
- event.stopPropagation();
204
- //In the case that the user clicks an item, selectItem() will be called from the click handler
205
- //and through onRouterLinkActivated. Only one of these will make it through this if statement
206
- //because the first one will set this.lastSelected = item.
207
- if (!item.disabled && !item.readonly && this.lastSelected !== item) {
208
- if (!item.url) {
209
- if (item.onClick) {
210
- item.onClick(item, false);
211
- }
212
- if (item.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section') {
213
- this.toggleChildMenu(true);
214
- }
215
- else {
216
- this.onSelection(item);
217
- }
218
- // We need to manually handle the url navigation if the keyboard was used
219
- }
220
- else if (isKeyEvent || event.target?.tagName === 'LI') {
221
- if (item.target) {
222
- window.open(item.url, item.target);
223
- }
224
- else {
225
- this.windowService.navigateToUrl(item.url);
226
- }
227
- // Emit so upstream components know an item was selected
228
- this.onSelection(item);
229
- }
230
- else {
231
- this.onSelection(item);
232
- }
233
- if (this.maintainSelectedItem) {
234
- this.selected = item;
235
- this.lastSelected = item;
236
- }
237
- else {
238
- this.selected = null;
239
- this.lastSelected = null;
240
- }
241
- }
242
- }
243
- /**
244
- * Close the current menu and open the parent menu
245
- * @memberof MenuComponent
246
- */
247
- back(event) {
248
- event.stopPropagation();
249
- if (this.parent && this.parent.onClick) {
250
- this.parent.onClick(null, true);
251
- }
252
- this.menuClosed.emit();
253
- }
254
- /**
255
- * Emit the selected item
256
- * @param item The selected item
257
- */
258
- onSelection(item) {
259
- if (item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section') {
260
- this.selectedChanged.emit(item);
261
- }
262
- }
263
- /**
264
- * Open or close the child menu. When the child menu closes, the selected
265
- * item is reset.
266
- * @memberof MenuComponent
267
- */
268
- toggleChildMenu(open) {
269
- let navEl = this.el.nativeElement.querySelector('nav');
270
- if (open) {
271
- // Remove the listener on the parent menu when a child menu is opened
272
- // This is to avoid interference between the parent and child menus
273
- if (this.removeKeydownListener) {
274
- this.removeKeydownListener();
275
- }
276
- let height = navEl.offsetHeight;
277
- let width = navEl.offsetWidth;
278
- // In order to animate the child menu, we need to set height on the nav element
279
- // so we can absolutely position the two menus and maintain the current menu's height
280
- this.renderer.setStyle(navEl, 'height', `${height}px`);
281
- this.renderer.setStyle(navEl, 'width', `${width}px`);
282
- this.renderer.addClass(this.el.nativeElement, 'open');
283
- setTimeout(() => {
284
- this.renderer.addClass(this.el.nativeElement, 'open-active');
285
- });
286
- }
287
- else {
288
- // Re-add the listener once the child menu closes
289
- this.addKeydownListener();
290
- this.renderer.removeClass(this.el.nativeElement, 'open-active');
291
- setTimeout(() => {
292
- this.renderer.removeClass(this.el.nativeElement, 'open');
293
- // Reset the nav element's height to auto
294
- this.renderer.setStyle(navEl, 'height', '100%');
295
- this.selected = null;
296
- }, menuAnimationSpeed);
297
- }
298
- }
299
- /**
300
- * Handle key presses to navigate the menu
301
- */
302
- keyNavigate(event) {
303
- if (this.enableKeyNav && event.target === this.dropdownToggleButton?.nativeElement) {
304
- switch (event.key) {
305
- case 'ArrowUp':
306
- case 'Up':
307
- case 'ArrowDown':
308
- case 'Down':
309
- event.stopPropagation();
310
- event.preventDefault();
311
- this.moveHighlightedUpOrDown(event);
312
- break;
313
- case 'ArrowRight':
314
- case 'Right':
315
- event.stopPropagation();
316
- event.preventDefault();
317
- // Select the item if it has child items
318
- if (this.highlightedItem && this.highlightedItem.items) {
319
- this.selectItem(event, this.highlightedItem, true);
320
- }
321
- break;
322
- case 'ArrowLeft':
323
- case 'Left':
324
- event.stopPropagation();
325
- event.preventDefault();
326
- // Close the menu if it is a child menu
327
- if (this.parent) {
328
- this.back(event);
329
- }
330
- break;
331
- case ' ':
332
- case 'Spacebar':
333
- case 'Enter':
334
- // Prevent 'enter' from doing whatever it does on the currently focused element
335
- event.preventDefault();
336
- if (this.highlightedItemIndex > -1 && this.highlightedItem) {
337
- this.selectItem(event, this.highlightedItem, true);
338
- // If the header is highlighted
339
- }
340
- else if (this.highlightedItemIndex === -1) {
341
- // Close the menu if it's a child
342
- if (this.parent) {
343
- this.back(event);
344
- }
345
- }
346
- break;
347
- default:
348
- return;
349
- }
350
- }
351
- }
352
- /**
353
- * Scroll to the item currently marked as 'is-selected'. Wait a tick for the
354
- * NgClassDirecitve or NavItemActiveDirective to respond to the model changes
355
- * and update the view.
356
- */
357
- scrollToSelectedItem() {
358
- window.setTimeout(() => {
359
- const linkSelector = `li.is-selected`;
360
- this.scrollService.scrollToItem(`#${this.id}_list`, linkSelector);
361
- });
362
- }
363
- moveHighlightedUpOrDown(event) {
364
- switch (event.key) {
365
- case 'ArrowUp':
366
- case 'Up':
367
- if (this.highlightedItemIndex > -1) {
368
- this.highlightedItemIndex--;
369
- }
370
- break;
371
- case 'ArrowDown':
372
- case 'Down':
373
- if (this.highlightedItemIndex < this.selectableItems.length - 1) {
374
- this.highlightedItemIndex++;
375
- }
376
- break;
377
- default:
378
- return;
379
- }
380
- if (this.highlightedItemIndex > -1) {
381
- // Store the item at the current highlight index
382
- this.highlightedItem = this.selectableItems[this.highlightedItemIndex];
383
- }
384
- else {
385
- this.highlightedItem = null;
386
- }
387
- this.scrollToHighlightedItem();
388
- }
389
- /**
390
- * Scroll to the specified menu item.
391
- * If no item is provided, it will scroll to the first item.
392
- *
393
- * @param item The menu item to scroll to.
394
- * @memberof MenuComponent
395
- */
396
- scrollMenu(item) {
397
- if (this.items.length > 0 && this.id) {
398
- item = item ? item : this.items[0];
399
- let itemId = item.id ? item.id : MenuComponent.getIndexedItemId(this.items, item, this.id);
400
- this.scrollService.scrollItemCentered(`#${this.id}_list`, `#${itemId}`);
401
- }
402
- }
403
- scrollToHighlightedItem() {
404
- this.scrollMenu(this.highlightedItem);
405
- }
406
- addKeydownListener() {
407
- // Only attempt to add the listener if keyboard nav is enabled
408
- if (this.enableKeyNav) {
409
- // renderer.listen adds the listener and returns a function to remove it from the renderer.
410
- // The listener remains active until this function is called.
411
- this.removeKeydownListener = this.renderer.listen('document', 'keydown', (event) => this.keyNavigate(event));
412
- }
413
- }
414
- /**
415
- * Sets the menu item ids using its index if item doesn't already have one
416
- */
417
- setItemIds() {
418
- if (this.items) {
419
- this.items.forEach((item, index) => {
420
- item.id = item.id ? item.id : this.id + '_item' + index;
421
- if (item.items) {
422
- item.items.forEach((childItem, childIndex) => {
423
- childItem.id = childItem.id ? childItem.id : this.id + '_item' + index + '-' + childIndex;
424
- });
425
- }
426
- });
427
- }
428
- }
429
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MenuComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.WindowService }, { token: i2.ScrollService }], target: i0.ɵɵFactoryTarget.Component }); }
430
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MenuComponent, selector: "ec-menu", inputs: { id: "id", items: "items", selected: "selected", parent: "parent", templateType: "templateType", customMenuTemplate: "customMenuTemplate", title: "title", showNoItems: "showNoItems", noDataText: "noDataText", enableKeyNav: "enableKeyNav", highlightedItem: "highlightedItem", maintainSelectedItem: "maintainSelectedItem", truncateItems: "truncateItems", preserveIconSpace: "preserveIconSpace", dropdownToggleButton: "dropdownToggleButton" }, outputs: { selectedChanged: "selectedChanged", menuClosed: "menuClosed" }, host: { properties: { "attr.id": "this.attrId" } }, viewQueries: [{ propertyName: "labelTemplate", first: true, predicate: ["label"], descendants: true, static: true }, { propertyName: "iconAndLabelTemplate", first: true, predicate: ["iconAndLabel"], descendants: true, static: true }, { propertyName: "checkAndLabelTemplate", first: true, predicate: ["checkAndLabel"], descendants: true, static: true }, { propertyName: "iconLabelCaptionTemplate", first: true, predicate: ["iconLabelCaption"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<nav>\n <div class=\"parent\"\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\n <header id=\"{{id}}_header\"\n class=\"text-heading-3 p-1\"\n [class.is-selected]=\"highlightedItemIndex === -1\"\n *ngIf=\"parent\"\n (click)=\"back($event)\">\n <div class=\"item-wrapper\">\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\n </div>\n </header>\n\n <ul id=\"{{id}}_list\"\n class=\"py-1\">\n <ng-container *ngFor=\"let item of items; index as i\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: item, index: i}\"></ng-container>\n\n <!-- Show child items under parent item if the item is a heading or divided-section -->\n <ng-container\n *ngIf=\"item.items?.length && (item.display === 'heading' || item.display === 'divided-section' || item.display === 'heading-divided-section')\">\n <ng-container *ngFor=\"let childItem of item.items; index as j; first as isFirst; last as isLast\"\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{$implicit: childItem, index: i + '-' + j, isDividedSectionChild: ( item.display === 'divided-section' || item.display === 'heading-divided-section'), isFirst: isFirst, isLast: isLast}\">\n </ng-container>\n </ng-container>\n </ng-container>\n </ul>\n\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\n </div>\n\n <!-- Child menu (Rendered to the right) -->\n <ec-menu *ngIf=\"selected?.items && selected?.display !== 'heading' && selected?.display !== 'divided-section' && selected?.display !== 'heading-divided-section'\"\n id=\"{{id}}_child\"\n class=\"child\"\n [parent]=\"selected\"\n [items]=\"selected?.items\"\n [showNoItems]=\"true\"\n [templateType]=\"templateType\"\n [enableKeyNav]=\"true\"\n [truncateItems]=\"truncateItems\"\n (selectedChanged)=\"onSelection($event)\"\n (menuClosed)=\"toggleChildMenu(false)\">\n </ec-menu>\n</nav>\n\n<ng-template #itemTemplate\n let-item\n let-i=\"index\"\n let-isDividedSectionChild=\"isDividedSectionChild\"\n let-isFirst=\"isFirst\"\n let-isLast=\"isLast\">\n <li *ngIf=\"!(item.hideIfNoItems && !item.items?.length) && item.display !== 'divided-section'\"\n id=\"{{item.id || id + '_item' + i}}\"\n class=\"{{item.display || 'item'}} {{item.classList}}\"\n [class.divider-top]=\"item.display === 'divider-top' || item.display === 'heading-divided-section' || (isDividedSectionChild && isFirst && item.display === 'heading-divided-section')\"\n [class.divider]=\"item.display === 'divider' || (isDividedSectionChild && isLast)\"\n [attr.disabled]=\"item.disabled\"\n [hidden]=\"item.hidden\"\n ecNavItemActive=\"is-selected\"\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\n [ecNavItemActiveUrl]=\"item.url\"\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\n (routerLinkActivated)=\"selectItem($event, item)\"\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading' && item?.display !== 'heading-divided-section') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': (item?.display === 'heading' || item?.display === 'heading-divided-section')}\"\n (click)=\"selectItem($event, item)\">\n\n <a *ngIf=\"item.url && !item.externalLink\"\n id=\"{{item.id}}_link\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\"\n [routerLink]=\"item.url\"\n [queryParams]=\"item.queryParams || null\"\n target=\"{{item.target || '_self'}}\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </a>\n\n <a *ngIf=\"item.url && item.externalLink\"\n id=\"{{item.id}}_link\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\"\n href=\"{{item.url}}\"\n target=\"{{item.target || '_self'}}\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </a>\n\n <div *ngIf=\"!item.url\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </div>\n </li>\n</ng-template>\n\n<!-- 'label' Item Template -->\n<ng-template #label\n let-item>\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<!-- 'checkAndLabel' Item Template -->\n<ng-template #checkAndLabel\n let-item>\n\n <i class=\"ec-icon icon-check ec-icon-sm\"\n *ngIf=\"item.display !== 'heading' && item.display !== 'heading-divided-section'\"></i>\n\n <i class=\"ec-icon {{item.icon}} ml-2\"\n *ngIf=\"item.icon\"></i>\n\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<!-- 'iconAndLabel' Item Template -->\n<ng-template #iconAndLabel\n let-item>\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\n <i class=\"ec-icon {{item.icon}}\"\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\n\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<ng-template #iconLabelCaption\n let-item>\n <i class=\"ec-icon {{item.icon}}\"\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\n <div *ngIf=\"item.display !== 'heading' && item.display !== 'heading-divided-section'\"\n class=\"label flex-grow\">\n <div id=\"{{item.id}}_label\"\n class=\"text-body-1\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </div>\n <div id=\"{{item.id}}_caption\"\n *ngIf=\"item.caption\"\n class=\"text-caption-1\"\n [class.text-truncate]=\"truncateItems\"\n [innerHTML]=\"item.caption\"></div>\n </div>\n <h3 *ngIf=\"item.display === 'heading' || item.display === 'heading-divided-section'\"\n class=\"flex-grow text-heading-3 align-self-center\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </h3>\n\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<ng-template #helpPopover\n let-item>\n <ec-help-popover id=\"{{item.id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{item.helpPopover | translate}}\"\n contentPosition=\"{{item.helpPopoverPosition ?? 'top-left'}}\">\n </ec-help-popover>\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading-divided-section,ul li.heading{cursor:default}ul li.heading-divided-section .item-wrapper,ul li.heading .item-wrapper{background-color:transparent}ul li.heading-divided-section:not(:first-child),ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider:not(:last-child){border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.divider-top:not(:first-child):not(.divider+.divider-top){border-top:1px solid var(--ec-border-color);padding-top:.25rem;margin-top:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i5.NavItemActiveDirective, selector: "[ecNavItemActive]", inputs: ["ecNavItemActive", "ecNavItemActiveExactMatch", "ecNavItemActiveQueryParams", "ecNavItemActiveUrl"], outputs: ["routerLinkActivated"] }, { kind: "component", type: MenuComponent, selector: "ec-menu", inputs: ["id", "items", "selected", "parent", "templateType", "customMenuTemplate", "title", "showNoItems", "noDataText", "enableKeyNav", "highlightedItem", "maintainSelectedItem", "truncateItems", "preserveIconSpace", "dropdownToggleButton"], outputs: ["selectedChanged", "menuClosed"] }, { kind: "component", type: i6.HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "pipe", type: i7.TranslatePipe, name: "translate" }] }); }
431
- }
432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MenuComponent, decorators: [{
433
- type: Component,
434
- args: [{ selector: 'ec-menu', template: "<nav>\n <div class=\"parent\"\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\n <header id=\"{{id}}_header\"\n class=\"text-heading-3 p-1\"\n [class.is-selected]=\"highlightedItemIndex === -1\"\n *ngIf=\"parent\"\n (click)=\"back($event)\">\n <div class=\"item-wrapper\">\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\n </div>\n </header>\n\n <ul id=\"{{id}}_list\"\n class=\"py-1\">\n <ng-container *ngFor=\"let item of items; index as i\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: item, index: i}\"></ng-container>\n\n <!-- Show child items under parent item if the item is a heading or divided-section -->\n <ng-container\n *ngIf=\"item.items?.length && (item.display === 'heading' || item.display === 'divided-section' || item.display === 'heading-divided-section')\">\n <ng-container *ngFor=\"let childItem of item.items; index as j; first as isFirst; last as isLast\"\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{$implicit: childItem, index: i + '-' + j, isDividedSectionChild: ( item.display === 'divided-section' || item.display === 'heading-divided-section'), isFirst: isFirst, isLast: isLast}\">\n </ng-container>\n </ng-container>\n </ng-container>\n </ul>\n\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\n </div>\n\n <!-- Child menu (Rendered to the right) -->\n <ec-menu *ngIf=\"selected?.items && selected?.display !== 'heading' && selected?.display !== 'divided-section' && selected?.display !== 'heading-divided-section'\"\n id=\"{{id}}_child\"\n class=\"child\"\n [parent]=\"selected\"\n [items]=\"selected?.items\"\n [showNoItems]=\"true\"\n [templateType]=\"templateType\"\n [enableKeyNav]=\"true\"\n [truncateItems]=\"truncateItems\"\n (selectedChanged)=\"onSelection($event)\"\n (menuClosed)=\"toggleChildMenu(false)\">\n </ec-menu>\n</nav>\n\n<ng-template #itemTemplate\n let-item\n let-i=\"index\"\n let-isDividedSectionChild=\"isDividedSectionChild\"\n let-isFirst=\"isFirst\"\n let-isLast=\"isLast\">\n <li *ngIf=\"!(item.hideIfNoItems && !item.items?.length) && item.display !== 'divided-section'\"\n id=\"{{item.id || id + '_item' + i}}\"\n class=\"{{item.display || 'item'}} {{item.classList}}\"\n [class.divider-top]=\"item.display === 'divider-top' || item.display === 'heading-divided-section' || (isDividedSectionChild && isFirst && item.display === 'heading-divided-section')\"\n [class.divider]=\"item.display === 'divider' || (isDividedSectionChild && isLast)\"\n [attr.disabled]=\"item.disabled\"\n [hidden]=\"item.hidden\"\n ecNavItemActive=\"is-selected\"\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\n [ecNavItemActiveUrl]=\"item.url\"\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\n (routerLinkActivated)=\"selectItem($event, item)\"\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading' && item?.display !== 'heading-divided-section') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': (item?.display === 'heading' || item?.display === 'heading-divided-section')}\"\n (click)=\"selectItem($event, item)\">\n\n <a *ngIf=\"item.url && !item.externalLink\"\n id=\"{{item.id}}_link\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\"\n [routerLink]=\"item.url\"\n [queryParams]=\"item.queryParams || null\"\n target=\"{{item.target || '_self'}}\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </a>\n\n <a *ngIf=\"item.url && item.externalLink\"\n id=\"{{item.id}}_link\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\"\n href=\"{{item.url}}\"\n target=\"{{item.target || '_self'}}\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </a>\n\n <div *ngIf=\"!item.url\"\n title=\"{{truncateItems ? item.label : ''}}\"\n class=\"item-wrapper\">\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\n </div>\n </li>\n</ng-template>\n\n<!-- 'label' Item Template -->\n<ng-template #label\n let-item>\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<!-- 'checkAndLabel' Item Template -->\n<ng-template #checkAndLabel\n let-item>\n\n <i class=\"ec-icon icon-check ec-icon-sm\"\n *ngIf=\"item.display !== 'heading' && item.display !== 'heading-divided-section'\"></i>\n\n <i class=\"ec-icon {{item.icon}} ml-2\"\n *ngIf=\"item.icon\"></i>\n\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<!-- 'iconAndLabel' Item Template -->\n<ng-template #iconAndLabel\n let-item>\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\n <i class=\"ec-icon {{item.icon}}\"\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\n\n <span id=\"{{item.id}}_label\"\n class=\"label\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </span>\n\n <i class=\"ec-icon icon-angle-down rotate-270\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<ng-template #iconLabelCaption\n let-item>\n <i class=\"ec-icon {{item.icon}}\"\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\n <div *ngIf=\"item.display !== 'heading' && item.display !== 'heading-divided-section'\"\n class=\"label flex-grow\">\n <div id=\"{{item.id}}_label\"\n class=\"text-body-1\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </div>\n <div id=\"{{item.id}}_caption\"\n *ngIf=\"item.caption\"\n class=\"text-caption-1\"\n [class.text-truncate]=\"truncateItems\"\n [innerHTML]=\"item.caption\"></div>\n </div>\n <h3 *ngIf=\"item.display === 'heading' || item.display === 'heading-divided-section'\"\n class=\"flex-grow text-heading-3 align-self-center\"\n [class.text-truncate]=\"truncateItems\">\n {{item.label}}\n <ng-container *ngIf=\"item.helpPopover\"\n [ngTemplateOutlet]=\"helpPopover\"\n [ngTemplateOutletContext]=\"{$implicit: item}\">\n </ng-container>\n </h3>\n\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section' && item.display !== 'heading-divided-section'\"></i>\n</ng-template>\n\n<ng-template #helpPopover\n let-item>\n <ec-help-popover id=\"{{item.id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{item.helpPopover | translate}}\"\n contentPosition=\"{{item.helpPopoverPosition ?? 'top-left'}}\">\n </ec-help-popover>\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading-divided-section,ul li.heading{cursor:default}ul li.heading-divided-section .item-wrapper,ul li.heading .item-wrapper{background-color:transparent}ul li.heading-divided-section:not(:first-child),ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider:not(:last-child){border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.divider-top:not(:first-child):not(.divider+.divider-top){border-top:1px solid var(--ec-border-color);padding-top:.25rem;margin-top:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"] }]
435
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.WindowService }, { type: i2.ScrollService }], propDecorators: { id: [{
436
- type: Input
437
- }], attrId: [{
438
- type: HostBinding,
439
- args: ['attr.id']
440
- }], items: [{
441
- type: Input
442
- }], selected: [{
443
- type: Input
444
- }], parent: [{
445
- type: Input
446
- }], templateType: [{
447
- type: Input
448
- }], customMenuTemplate: [{
449
- type: Input
450
- }], title: [{
451
- type: Input
452
- }], showNoItems: [{
453
- type: Input
454
- }], noDataText: [{
455
- type: Input
456
- }], enableKeyNav: [{
457
- type: Input
458
- }], highlightedItem: [{
459
- type: Input
460
- }], maintainSelectedItem: [{
461
- type: Input
462
- }], truncateItems: [{
463
- type: Input
464
- }], preserveIconSpace: [{
465
- type: Input
466
- }], dropdownToggleButton: [{
467
- type: Input
468
- }], selectedChanged: [{
469
- type: Output
470
- }], menuClosed: [{
471
- type: Output
472
- }], labelTemplate: [{
473
- type: ViewChild,
474
- args: ['label', { static: true }]
475
- }], iconAndLabelTemplate: [{
476
- type: ViewChild,
477
- args: ['iconAndLabel', { static: true }]
478
- }], checkAndLabelTemplate: [{
479
- type: ViewChild,
480
- args: ['checkAndLabel', { static: true }]
481
- }], iconLabelCaptionTemplate: [{
482
- type: ViewChild,
483
- args: ['iconLabelCaption', { static: true }]
484
- }] } });
485
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvbWVudS9tZW51LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9tZW51L21lbnUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQWMsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQXdCLE1BQU0sRUFBeUMsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7Ozs7QUFxQ3pMLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFFdEM7Ozs7R0FJRztBQU1ILE1BQU0sT0FBTyxhQUFhO0lBZ0x0Qjs7O09BR0c7SUFDSSxNQUFNLENBQUMsa0JBQWtCLENBQUMsS0FBaUI7UUFDOUMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQzFDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLHlCQUF5QixFQUFFLENBQUM7Z0JBQ2pILGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDL0IsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDcEIsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksU0FBUyxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxTQUFTLENB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QkFBaUI7c0JBQWhDLEtBQUs7Z0JBS1Usb0JBQW9CO3NCQUFuQyxLQUFLO2dCQU9XLGVBQWU7c0JBQS9CLE1BQU07Z0JBT1UsVUFBVTtzQkFBMUIsTUFBTTtnQkFtQnVDLGFBQWE7c0JBQTFELFNBQVM7dUJBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFNaUIsb0JBQW9CO3NCQUF4RSxTQUFTO3VCQUFDLGNBQWMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBTVcscUJBQXFCO3NCQUExRSxTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBS2Esd0JBQXdCO3NCQUFoRixTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPdXRwdXQsIFJlbmRlcmVyMiwgU2ltcGxlQ2hhbmdlcywgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zY3JvbGwuc2VydmljZSc7XG5pbXBvcnQgeyBXaW5kb3dTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS93aW5kb3cuc2VydmljZSc7XG5pbXBvcnQgeyBMaW5rVGFyZ2V0IH0gZnJvbSAnLi4vLi4vZGlzcGxheS90YWdzL3RhZyc7XG5pbXBvcnQgeyBOYXZJdGVtIH0gZnJvbSAnLi4vbmF2aWdhdGlvbi9uYXYtaXRlbSc7XG5pbXBvcnQgeyBQb3BvdmVyQ29udGVudFBvc2l0aW9uIH0gZnJvbSAnLi4vcG9wb3Zlci9wb3BvdmVyLmNvbXBvbmVudCc7XG5cbmV4cG9ydCB0eXBlIE1lbnVUZW1wbGF0ZVR5cGUgPSBcImxhYmVsXCIgfCBcImljb25BbmRMYWJlbFwiIHwgXCJjaGVja0FuZExhYmVsXCIgfCBcImljb25MYWJlbENhcHRpb25cIjtcblxuZXhwb3J0IHR5cGUgTWVudUhvc3RFbGVtZW50Q2xhc3NlcyA9ICdiZy10cmFuc3BhcmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVudUl0ZW08VFZhbHVlID0gYW55LCBTSXRlbXMgPSBhbnk+IGV4dGVuZHMgTmF2SXRlbSB7XG4gICAgLy8gTGFiZWwgaXMgb3B0aW9uYWwgaW4gTmF2SXRlbSBidXQgd2FzIG5vdCBpbiBNZW51SXRlbSxcbiAgICAvLyBvdmVycmlkaW5nIHRvIGJlIHJlcXVpcmVkXG4gICAgbGFiZWw6IHN0cmluZyxcbiAgICBjYXB0aW9uPzogc3RyaW5nLFxuICAgIGl0ZW1zPzogTWVudUl0ZW08U0l0ZW1zPltdLFxuICAgIGNoZWNrZWQ/OiBib29sZWFuLFxuICAgIGRpc3BsYXk/OiAnZGVmYXVsdCcgfCAnaGVhZGluZycgfCAnZGl2aWRlcicgfCAnZGl2aWRlZC1zZWN0aW9uJyB8ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbicsXG4gICAgdmFsdWU/OiBUVmFsdWUsXG4gICAgY2xhc3NMaXN0Pzogc3RyaW5nLFxuICAgIGRpc2FibGVkPzogYm9vbGVhbixcbiAgICBoaWRkZW4/OiBib29sZWFuLFxuICAgIHJlYWRvbmx5PzogYm9vbGVhbixcbiAgICB0YXJnZXQ/OiBMaW5rVGFyZ2V0LFxuICAgIGV4dGVybmFsTGluaz86IGJvb2xlYW4sXG4gICAgLyoqIE9wdGlvbmFsIHRleHQgdG8gZGlzcGxheSBpbi1wbGFjZSBvZiB0aGUgZGVmYXVsdCBsYWJlbCB3aGVuIHRoZSBNZW51SXRlbSBpcyBzZWxlY3RlZC4gKi9cbiAgICBzZWxlY3RlZExhYmVsPzogc3RyaW5nLFxuICAgIGhpZGVJZk5vSXRlbXM/OiBib29sZWFuLFxuXG4gICAgLyoqIE9wdGlvbmFsIGhlbHAgcG9wb3ZlciBjb250ZW50IHRvIGRpc3BsYXkgbmV4dCB0byB0aGUgaGVhZGVyIG9yIGluZGl2aWR1YWwgaXRlbS4gTm90ZTogVGhpcyBvbmx5IHdpbGxcbiAgICAgKiAgc2hvdyB3aGVuIHVzaW5nIG91ciBidWlsdCBpbiBpdGVtIHRlbXBsYXRlcy5cbiAgICAgKi9cbiAgICBoZWxwUG9wb3Zlcj86IHN0cmluZyxcbiAgICAvKiogT3B0aW9uYWwgaGVscCBwb3BvdmVyIHBvc2l0aW9uLiBJZiBub3QgZGVmaW5lZCBhIGRlZmF1bHQgb2YgJ3RvcC1sZWZ0JyB3aWxsIGJlIHVzZWQuICovXG4gICAgaGVscFBvcG92ZXJQb3NpdGlvbj86IFBvcG92ZXJDb250ZW50UG9zaXRpb24sXG59O1xuXG5leHBvcnQgY29uc3QgbWVudUFuaW1hdGlvblNwZWVkID0gMzUwO1xuXG4vKipcbiAqIFByaW1pdGl2ZSBNZW51IGNvbXBvbmVudCB0aGF0IGVuY2Fwc3VsYXRlcyBrbm93biB0ZW1wbGF0ZXNcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZWMtbWVudScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL21lbnUuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL21lbnUuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBNZW51Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuXG5cbiAgICAvKipcbiAgICAgKiBJbnB1dCBmb3IgdGhlIG1lbnUncyB0ZW1wbGF0ZSBpZFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBpZD86IHN0cmluZztcblxuXG4gICAgLyoqXG4gICAgICogSWQgYm91bmQgdG8gdGhlIGhvc3QgZWxlbWVudFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5pZCcpIHB1YmxpYyBhdHRySWQ/OiBzdHJpbmc7XG5cblxuICAgIC8qKlxuICAgICAqIEFycmF5IG9mIGl0ZW1zIHRvIGRpc3BsYXlcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNZW51Q29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGl0ZW1zOiBBcnJheTxNZW51SXRlbT4gPSBbXTtcblxuXG4gICAgLyoqXG4gICAgICogIFNlbGVjdGVkIGl0ZW07IGFubm90YXRlcyB0aGUgaXRlbVxuICAgICAqICB3aGVuIGRpc3BsYXllZCB3aXRoICdzZWxlY3RlZCcgY2xhc3NcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNZW51Q29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHNlbGVjdGVkOiBNZW51SXRlbSB8IG51bGwgPSBudWxsO1xuXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGFyZW50IG1lbnUgaXRlbS4gSWYgZGVmaW5lZCwgYSBoZWFkZXIgd2l0aCB0aGUgcGFyZW50J3MgbGFiZWwgYW5kIGFcbiAgICAgKiBiYWNrIGJ1dHRvbiB3aWxsIGJlIGRpc3BsYXllZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgcGFyZW50PzogTWVudUl0ZW07XG5cblxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgdGVtcGxhdGVcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNZW51Q29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHRlbXBsYXRlVHlwZTogTWVudVRlbXBsYXRlVHlwZSA9ICdsYWJlbCc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBjdXN0b20gdGVtcGxhdGUgZm9yIHRoZSBtZW51IGl0ZW1zLiBNdXN0IGRlY2xhcmUgYSB0ZW1wbGF0ZVxuICAgICAqIGlucHV0IHZhcmlhYmxlIGNhbGxlZCBcIml0ZW1cIiBsaWtlIHNvOiA8bmctdGVtcGxhdGUgI3RlbXBsYXRlTmFtZSBsZXQtaXRlbT4sXG4gICAgICogd2hlcmUgaXRlbSByZXByZXNlbnRzIHRoZSBtZW51SXRlbS5cbiAgICAgKiBXaWxsIG92ZXJyaWRlIHRoZSBjaG9pY2UgZm9yIHRlbXBsYXRlVHlwZSBpZiBwcm92aWRlZC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBNZW51Q29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGN1c3RvbU1lbnVUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPGFueT47XG5cblxuICAgIC8qKlxuICAgICAqIFRoZSBtZW51J3MgdGl0bGVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGl0bGU/OiBzdHJpbmc7XG5cblxuICAgIC8qKlxuICAgICAqIFNob3cgbWVzc2FnZSB3aGVuIHRoZXJlIGFyZSBubyBpdGVtc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzaG93Tm9JdGVtcz86IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFRleHQgdG8gc2hvdyB3aGVuIG1lbnUgaXMgZW1wdHkgYW5kIHNob3dOb0l0ZW1zIGlzIHRydWVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgbm9EYXRhVGV4dDogc3RyaW5nID0gJ05vSXRlbXNfVEMnO1xuXG5cbiAgICAvKipcbiAgICAgKiBDb250cm9scyB3aGV0aGVyIGtleWJvYXJkIG5hdmlnYXRpb24gaXMgZW5hYmxlZFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBlbmFibGVLZXlOYXY/OiBib29sZWFuID0gZmFsc2U7XG5cblxuICAgIC8qKlxuICAgICAqIEl0ZW0gY3VycmVudGx5IGhpZ2hsaWdodGVkIGJ5IGtleWJvYXJkIG5hdmlnYXRpb25cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgaGlnaGxpZ2h0ZWRJdGVtOiBNZW51SXRlbSB8IG51bGwgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVGVsbHMgdGhlIG1lbnUgdG8gbWFpbnRhaW4gdGhlIHNlbGVjdGVkL2xhc3RTZWxlY3RlZCBpdGVtLiBUdXJuaW5nIHRoaXMgb2ZmIGlzIHVzZWZ1bCBmb3JcbiAgICAgKiBhY3Rpb24gdHlwZSBtZW51cyB0aGF0IGFyZSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbiBhdCBhbGwgdGltZXMgYW5kIHlvdSBkbyBub3RcbiAgICAgKiB3YW50IHRoZSBpdGVtIHRvIGJlIHNlbGVjdGVkIHdoZW4gY2xpY2tlZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgbWFpbnRhaW5TZWxlY3RlZEl0ZW06IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqXG4gICAgICogV2lsbCBwcmV2ZW50IHRleHQtd3JhcHBpbmcgb2YgbWVudSBpdGVtcyBhbmQgdHJ1bmNhdGUgaW5zdGVhZC4gQWxzbyB0dXJucyBvbiBhIHRvb2x0aXAgZm9yIHRoZSBtZW51IGl0ZW0uIERlZmF1bHQ6IGZhbHNlO1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB0cnVuY2F0ZUl0ZW1zOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHRydWUsIHRoZSBzcGFjZSBmb3IgdGhlIGljb24gaXMgcHJlc2VydmVkIGZvciBtZW51IGl0ZW1zIHRoYXQgZG8gbm90IGhhdmUgaWNvbnMuXG4gICAgICogT25seSBhcHBsaWNhYmxlIGZvciBpY29uQW5kTGFiZWwgbWVudXMuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHByZXNlcnZlSWNvblNwYWNlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIHRvZ2dsZSBidXR0b24uICBTZXQgd2hlbiBtZW51IGlzIHVzZWQgYXMgcGFydCBvZiBhIERyb3Bkb3duQ29tcG9uZW50LlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBkcm9wZG93blRvZ2dsZUJ1dHRvbj86IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYHNlbGVjdGVkYCBpcyBjaGFuZ2VkLiBFbWl0cyB0aGUgcmVmZXJlbmNlZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWVudUNvbXBvbmVudFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgc2VsZWN0ZWRDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8TWVudUl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxNZW51SXRlbT4oKTtcblxuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCB3aGVuIHRoZSBtZW51IGhhcyBhIHBhcmVudCBhbmQgYmFjayBpcyBjbGlja2VkXG4gICAgICogQG1lbWJlcm9mIE1lbnVDb21wb25lbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIG1lbnVDbG9zZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuXG4gICAgLyoqXG4gICAgICogVGhlIGl0ZW0gdGVtcGxhdGUgdGhhdCBpcyBsb2FkZWQgaW50byB0aGUgY29tcG9uZW50IHRlbXBsYXRlXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWVudUNvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBpbnRlcm5hbGl6ZWRUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBJbmRleCBvZiB0aGUgaXRlbSBjdXJyZW50bHkgaGlnaGxpZ2h0ZWQgdXNpbmcga2V5Ym9hcmQgbmF2XG4gICAgICovXG4gICAgcHVibGljIGhpZ2hsaWdodGVkSXRlbUluZGV4OiBudW1iZXIgPSAtMTtcblxuXG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIG1lbnUgbGFiZWwgdGVtcGxhdGVcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdsYWJlbCcsIHsgc3RhdGljOiB0cnVlIH0pIHByaXZhdGUgbGFiZWxUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cblxuICAgIC8qKlxuICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBtZW51IGljb24gYW5kIGxhYmVsIHRlbXBsYXRlXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnaWNvbkFuZExhYmVsJywgeyBzdGF0aWM6IHRydWUgfSkgcHJpdmF0ZSBpY29uQW5kTGFiZWxUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cblxuICAgIC8qKlxuICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBtZW51IGNoZWNrIGFuZCBsYWJlbCB0ZW1wbGF0ZVxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2NoZWNrQW5kTGFiZWwnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIGNoZWNrQW5kTGFiZWxUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgbWVudSBpY29uLCBsYWJlbCBhbmQgY2FwdGlvbiB0ZW1wbGF0ZVxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2ljb25MYWJlbENhcHRpb24nLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIGljb25MYWJlbENhcHRpb25UZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBDb250YWlucyB0aGUgZnVuY3Rpb24gdXNlZCB0byByZW1vdmUgdGhlIGV2ZW4gbGlzdGVuZXIgZnJvbSB0aGUgcmVuZGVyZXJcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlbW92ZUtleWRvd25MaXN0ZW5lcj86ICgpID0+IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBMYXN0IGl0ZW0gdGhpcy5zZWxlY3RlZCB3YXMgc2V0IHRvIHZpYSBzZWxlY3RJdGVtKCkuXG4gICAgICogVGhpcyBpc24ndCBuZWNlc3NhcmlseSB0aGUgc2FtZSBhcyB0aGlzLnNlbGVjdGVkLCBiZWNhdXNlIHRoaXMuc2VsZWN0ZWQgaXMgYW4gaW5wdXQgcHJvcGVydHlcbiAgICAgKiBhbmQgY291bGQgaGF2ZSBiZWVuIGNoYW5nZWQgYnkgYSBjb25zdW1lciB0aHJvdWdoIHNvbWUgbWVhbnMgb3RoZXIgdGhhbiBzZWxlY3RJdGVtKCkuXG4gICAgICogVGhpcyBhbGxvd3MgdXMgdG8gcHJldmVudCBkb3VibGUtY2FsbHMgdG8gc2VsZWN0SXRlbSgpIHdpdGggdGhlIHNhbWUgaW5wdXQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBsYXN0U2VsZWN0ZWQ6IE1lbnVJdGVtIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBGbGF0dGVuZWQgYXJyYXkgb2YgYWxsIHNlbGVjdGFibGUgaXRlbXMgaW4gdGhlIG1lbnUuIE1ha2VzIGl0IGVhc2llciB0byBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50bHkgaGlnaGxpZ2h0ZWQgaXRlbSBmb3Iga2V5Ym9hcmQgbmF2aWdhdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNlbGVjdGFibGVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHJldHVybiBhIGZsYXQgbGlzdCBvZiBhbGwgc2VsZWN0YWJsZSBpdGVtcyBpbiB0aGUgcHJvdmlkZWQgbWVudSBpdGVtcy4gRmlsdGVycyBvdXQgaGVhZGluZ3MgYW5kIGRpdmlkZWQtc2VjdGlvbnMuXG4gICAgICogVGhpcyBtYWtlcyBpdCBtdWNoIGVhc2llciB0byBrZWVwIHRyYWNrIG9mIGN1cnJlbnRseSBoaWdobGlnaHRlZCBpdGVtcyBmb3Iga2V5Ym9hcmQgbmF2aWdhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGdldFNlbGVjdGFibGVJdGVtcyhpdGVtczogTWVudUl0ZW1bXSk6IE1lbnVJdGVtW10ge1xuICAgICAgICByZXR1cm4gaXRlbXMucmVkdWNlKChzZWxlY3RhYmxlSXRlbXMsIGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdkaXZpZGVkLXNlY3Rpb24nICYmIGl0ZW0uZGlzcGxheSAhPT0gJ2hlYWRpbmctZGl2aWRlZC1zZWN0aW9uJykge1xuICAgICAgICAgICAgICAgIHNlbGVjdGFibGVJdGVtcy5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0YWJsZUl0ZW1zLnB1c2goLi4uaXRlbS5pdGVtcy5maWx0ZXIoY2hpbGRJdGVtID0+IGNoaWxkSXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgY2hpbGRJdGVtLmRpc3BsYXkgIT09ICdkaXZpZGVkLXNlY3Rpb24nICYmIGNoaWxkSXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0YWJsZUl0ZW1zO1xuICAgICAgICB9LCA8TWVudUl0ZW1bXT5bXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBJRCBmb3IgdGhlIHByb3ZpZGVkIGl0ZW0gYmFzZWQgb24gaXRzIGluZGV4IGluIHRoZSBwcm92aWRlZCBpdGVtcyBhcnJheS4gVGhpcyBtaW1pY3MgdGhlIGJlaGF2aW9yIG9mIHRoZSBNZW51Q29tcG9uZW50J3NcbiAgICAgKiBnZW5lcmF0ZWQgSURzIGZvciBpdGVtcyB0aGF0IGRvbid0IGhhdmUgcHJvdmlkZWQgSURzLiBUaGlzIGlzIHVzZWQgaW4gTWVudUNvbXBvbmVudCBhbmQgQ29tYm9ib3hDb21wb25lbnQgdG8gc2Nyb2xsIHRvIHNwZWNpZmljIGl0ZW1zLlxuICAgICAqIE5PVEU6IElmIHRoZSBpdGVtcyBhcnJheSBkb2VzIG5vdCBtYXRjaCB3aGF0IGlzIGRpc3BsYXllZCBpbiB0aGUgbWVudSwgdGhpcyBmdW5jdGlvbiB3aWxsIG5vdCByZXR1cm4gdGhlIGNvcnJlY3QgSUQuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIG5vdCBmb3VuZFxuICAgICAqIEBwYXJhbSBpdGVtcyBUaGUgTWVudUl0ZW1zIGFycmF5IHRvIHNlYXJjaCB0aHJvdWdoLlxuICAgICAqIEBwYXJhbSBpdGVtIFRoZSBpdGVtIHRvIGdlbmVyYXRlIHRoZSBJRCBmb3IuXG4gICAgICogQHBhcmFtIG1lbnVDb21wb25lbnRJZCBVc2VkIHRvIHByZWZpeCB0aGUgZ2VuZXJhdGVkIElELiBUaGlzIHNob3VsZCBiZSB0aGUgSUQgb2YgdGhlIG1lbnUgY29tcG9uZW50IHRoZSBpdGVtIGlzIHByZXNlbnQgaW4uXG4gICAgICogQG1lbWJlcm9mIE1lbnVDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGdldEluZGV4ZWRJdGVtSWQoaXRlbXM6IE1lbnVJdGVtW10sIGl0ZW0/OiBNZW51SXRlbSB8IG51bGwsIG1lbnVDb21wb25lbnRJZD86IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBpZiAoaXRlbSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1Jbkxpc3QgPSBpdGVtc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbUluTGlzdC5sYWJlbCA9PT0gaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7bWVudUNvbXBvbmVudElkfV9pdGVtJHtpfWA7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGl0ZW0gaXMgYSBoZWFkaW5nIG9yIGRpdmlkZWQgc2VjdGlvbiwgY2hlY2sgaXRzIGNoaWxkcmVuXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW1Jbkxpc3QuaXRlbXMgJiYgKGl0ZW1Jbkxpc3QuZGlzcGxheSA9PT0gJ2hlYWRpbmcnIHx8IGl0ZW1Jbkxpc3QuZGlzcGxheSA9PT0gJ2RpdmlkZWQtc2VjdGlvbicgfHwgaXRlbUluTGlzdC5kaXNwbGF5ID09PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nKSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGl0ZW1Jbkxpc3QuaXRlbXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkSXRlbSA9IGl0ZW1Jbkxpc3QuaXRlbXNbal07XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGYWxsIGJhY2sgdG8gY2hlY2tpbmcgb25seSB0aGUgbGFiZWwgaWYgdGhlIGl0ZW0gZG9lc24ndCBoYXZlIGFuIGlkXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRJdGVtLmxhYmVsID09PSBpdGVtLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke21lbnVDb21wb25lbnRJZH1faXRlbSR7aX0tJHtqfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICBwcml2YXRlIHdpbmRvd1NlcnZpY2U6IFdpbmRvd1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgc2Nyb2xsU2VydmljZTogU2Nyb2xsU2VydmljZVxuICAgICkgeyB9XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBpZiAoY2hhbmdlcy5pdGVtcyAmJiB0aGlzLml0ZW1zKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGFibGVJdGVtcyA9IE1lbnVDb21wb25lbnQuZ2V0U2VsZWN0YWJsZUl0ZW1zKHRoaXMuaXRlbXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyAmIGRpc3BsYXlzIHRoZSBpbnRlcmFsaXplZCB0ZW1wbGF0ZSBiYXNlZCBvblxuICAgICAqIHRoZSBzZXQgdGVtcGxhdGUuXG4gICAgICogQHNlZSB7IEBsaW5rIGh0dHBzOi8vYW5ndWxhci5pby9ndWlkZS9saWZlY3ljbGUtaG9va3N8QW5ndWxhciBMaWZlY3ljbGUgSG9va3N9XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgTWVudUNvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgICAgIHN3aXRjaCAodGhpcy50ZW1wbGF0ZVR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgKFwibGFiZWxcIik6XG4gICAgICAgICAgICAgICAgdGhpcy5pbnRlcm5hbGl6ZWRUZW1wbGF0ZSA9IHRoaXMuaWNvbkFuZExhYmVsVGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIChcImljb25BbmRMYWJlbFwiKTpcbiAgICAgICAgICAgICAgICB0aGlzLmludGVybmFsaXplZFRlbXBsYXRlID0gdGhpcy5pY29uQW5kTGFiZWxUZW1wbGF0ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgKFwiY2hlY2tBbmRMYWJlbFwiKTpcbiAgICAgICAgICAgICAgICB0aGlzLmludGVybmFsaXplZFRlbXBsYXRlID0gdGhpcy5jaGVja0FuZExhYmVsVGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIChcImljb25MYWJlbENhcHRpb25cIik6XG4gICAgICAgICAgICAgICAgdGhpcy5pbnRlcm5hbGl6ZWRUZW1wbGF0ZSA9IHRoaXMuaWNvbkxhYmVsQ2FwdGlvblRlbXBsYXRlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGVtcGxhdGVUeXBlIGZvciBNZW51Q29tcG9uZW50LiBQbGVhc2UgdXNlIGVpdGhlcjogJ2xhYmVsJywgJ2ljb25BbmRMYWJlbCcgb3IgJ2NoZWNrQW5kTGFiZWwnYClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGNvbnN1bWVyIHByb3ZpZGVkIGEgbWVudUl0ZW1UZW1wbGF0ZSwgb3ZlcnJpZGUgdGhlIGludGVybmFsaXplZFRlbXBsYXRlIHdpdGggdGhhdC5cbiAgICAgICAgaWYgKHRoaXMuY3VzdG9tTWVudVRlbXBsYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmludGVybmFsaXplZFRlbXBsYXRlID0gdGhpcy5jdXN0b21NZW51VGVtcGxhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pZCkge1xuICAgICAgICAgICAgdGhpcy5hdHRySWQgPSB0aGlzLmlkO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRJdGVtSWRzKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuaGlnaGxpZ2h0ZWRJdGVtICYmIHRoaXMuc2VsZWN0YWJsZUl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRlZEl0ZW1JbmRleCA9IHRoaXMuc2VsZWN0YWJsZUl0ZW1zLmZpbmRJbmRleChpdGVtID0+IHsgcmV0dXJuIHRoaXMuaGlnaGxpZ2h0ZWRJdGVtID09PSBpdGVtfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFkZEtleWRvd25MaXN0ZW5lcigpO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBsaXN0ZW5lciB3aGVuIHRoZSBjb21wb25lbnQgaXMgZGVzdHJveWVkXG4gICAgICAgIGlmICh0aGlzLnJlbW92ZUtleWRvd25MaXN0ZW5lcikge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVLZXlkb3duTGlzdGVuZXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogV2hlbiBhIG1lbnUgaXRlbSBpcyBzZWxlY3RlZCwgb3BlbiBhIGNoaWxkIG1lbnUgaWYgdGhlIGl0ZW0gaGFzIGl0ZW1zLCBjYWxsXG4gICAgICogdGhlIGl0ZW0ncyBjbGljayBtZXRob2QgaWYgZGVmaW5lZCwgb3IgZW1pdCB0aGUgc2VsZWN0ZWQgaXRlbS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpdGVtIFRoZSBzZWxlY3RlZCBpdGVtXG4gICAgICogQG1lbWJlcm9mIE1lbnVDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0SXRlbShldmVudDogRXZlbnQsIGl0ZW06IE1lbnVJdGVtLCBpc0tleUV2ZW50PzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAvL0luIHRoZSBjYXNlIHRoYXQgdGhlIHVzZXIgY2xpY2tzIGFuIGl0ZW0sIHNlbGVjdEl0ZW0oKSB3aWxsIGJlIGNhbGxlZCBmcm9tIHRoZSBjbGljayBoYW5kbGVyXG4gICAgICAgIC8vYW5kIHRocm91Z2ggb25Sb3V0ZXJMaW5rQWN0aXZhdGVkLiBPbmx5IG9uZSBvZiB0aGVzZSB3aWxsIG1ha2UgaXQgdGhyb3VnaCB0aGlzIGlmIHN0YXRlbWVudFxuICAgICAgICAvL2JlY2F1c2UgdGhlIGZpcnN0IG9uZSB3aWxsIHNldCB0aGlzLmxhc3RTZWxlY3RlZCA9IGl0ZW0uXG4gICAgICAgIGlmICghaXRlbS5kaXNhYmxlZCAmJiAhaXRlbS5yZWFkb25seSAmJiB0aGlzLmxhc3RTZWxlY3RlZCAhPT0gaXRlbSkge1xuXG4gICAgICAgICAgICBpZiAoIWl0ZW0udXJsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0ub25DbGljaykge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLm9uQ2xpY2soaXRlbSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpdGVtLml0ZW1zICYmIGl0ZW0uZGlzcGxheSAhPT0gJ2hlYWRpbmcnICYmIGl0ZW0uZGlzcGxheSAhPT0gJ2RpdmlkZWQtc2VjdGlvbicgJiYgaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlQ2hpbGRNZW51KHRydWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25TZWxlY3Rpb24oaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gbWFudWFsbHkgaGFuZGxlIHRoZSB1cmwgbmF2aWdhdGlvbiBpZiB0aGUga2V5Ym9hcmQgd2FzIHVzZWRcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNLZXlFdmVudCB8fCAoPEVsZW1lbnQ+ZXZlbnQudGFyZ2V0KT8udGFnTmFtZSA9PT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGlmIChpdGVtLnRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cub3BlbihpdGVtLnVybCwgaXRlbS50YXJnZXQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2luZG93U2VydmljZS5uYXZpZ2F0ZVRvVXJsKGl0ZW0udXJsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gRW1pdCBzbyB1cHN0cmVhbSBjb21wb25lbnRzIGtub3cgYW4gaXRlbSB3YXMgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uKGl0ZW0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5tYWludGFpblNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBpdGVtO1xuICAgICAgICAgICAgICAgIHRoaXMubGFzdFNlbGVjdGVkID0gaXRlbTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0U2VsZWN0ZWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIGN1cnJlbnQgbWVudSBhbmQgb3BlbiB0aGUgcGFyZW50IG1lbnVcbiAgICAgKiBAbWVtYmVyb2YgTWVudUNvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBiYWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50ICYmIHRoaXMucGFyZW50Lm9uQ2xpY2spIHtcbiAgICAgICAgICAgIHRoaXMucGFyZW50Lm9uQ2xpY2sobnVsbCwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tZW51Q2xvc2VkLmVtaXQoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEVtaXQgdGhlIHNlbGVjdGVkIGl0ZW1cbiAgICAgKiBAcGFyYW0gaXRlbSBUaGUgc2VsZWN0ZWQgaXRlbVxuICAgICAqL1xuICAgIHB1YmxpYyBvblNlbGVjdGlvbihpdGVtOiBNZW51SXRlbSk6IHZvaWQge1xuICAgICAgICBpZiAoaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgaXRlbS5kaXNwbGF5ICE9PSAnZGl2aWRlZC1zZWN0aW9uJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDaGFuZ2VkLmVtaXQoaXRlbSk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIE9wZW4gb3IgY2xvc2UgdGhlIGNoaWxkIG1lbnUuIFdoZW4gdGhlIGNoaWxkIG1lbnUgY2xvc2VzLCB0aGUgc2VsZWN0ZWRcbiAgICAgKiBpdGVtIGlzIHJlc2V0LlxuICAgICAqIEBtZW1iZXJvZiBNZW51Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZUNoaWxkTWVudShvcGVuOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGxldCBuYXZFbCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCduYXYnKTtcblxuICAgICAgICBpZiAob3Blbikge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBsaXN0ZW5lciBvbiB0aGUgcGFyZW50IG1lbnUgd2hlbiBhIGNoaWxkIG1lbnUgaXMgb3BlbmVkXG4gICAgICAgICAgICAvLyBUaGlzIGlzIHRvIGF2b2lkIGludGVyZmVyZW5jZSBiZXR3ZWVuIHRoZSBwYXJlbnQgYW5kIGNoaWxkIG1lbnVzXG4gICAgICAgICAgICBpZiAodGhpcy5yZW1vdmVLZXlkb3duTGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUtleWRvd25MaXN0ZW5lcigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgaGVpZ2h0OiBudW1iZXIgPSBuYXZFbC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgICBsZXQgd2lkdGg6IG51bWJlciA9IG5hdkVsLm9mZnNldFdpZHRoO1xuXG4gICAgICAgICAgICAvLyBJbiBvcmRlciB0byBhbmltYXRlIHRoZSBjaGlsZCBtZW51LCB3ZSBuZWVkIHRvIHNldCBoZWlnaHQgb24gdGhlIG5hdiBlbGVtZW50XG4gICAgICAgICAgICAvLyBzbyB3ZSBjYW4gYWJzb2x1dGVseSBwb3NpdGlvbiB0aGUgdHdvIG1lbnVzIGFuZCBtYWludGFpbiB0aGUgY3VycmVudCBtZW51J3MgaGVpZ2h0XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKG5hdkVsLCAnaGVpZ2h0JywgYCR7aGVpZ2h0fXB4YCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKG5hdkVsLCAnd2lkdGgnLCBgJHt3aWR0aH1weGApO1xuXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ29wZW4nKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnb3Blbi1hY3RpdmUnKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZS1hZGQgdGhlIGxpc3RlbmVyIG9uY2UgdGhlIGNoaWxkIG1lbnUgY2xvc2VzXG4gICAgICAgICAgICB0aGlzLmFkZEtleWRvd25MaXN0ZW5lcigpO1xuXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ29wZW4tYWN0aXZlJyk7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ29wZW4nKTtcblxuICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBuYXYgZWxlbWVudCdzIGhlaWdodCB0byBhdXRvXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShuYXZFbCwgJ2hlaWdodCcsICcxMDAlJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZCA9IG51bGw7XG4gICAgICAgICAgICB9LCBtZW51QW5pbWF0aW9uU3BlZWQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUga2V5IHByZXNzZXMgdG8gbmF2aWdhdGUgdGhlIG1lbnVcbiAgICAgKi9cbiAgICBwdWJsaWMga2V5TmF2aWdhdGUoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlS2V5TmF2ICYmIGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kcm9wZG93blRvZ2dsZUJ1dHRvbj8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgICAgICAgICBjYXNlICdVcCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICBjYXNlICdEb3duJzpcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW92ZUhpZ2hsaWdodGVkVXBPckRvd24oZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ1JpZ2h0JzpcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNlbGVjdCB0aGUgaXRlbSBpZiBpdCBoYXMgY2hpbGQgaXRlbXNcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaGlnaGxpZ2h0ZWRJdGVtICYmIHRoaXMuaGlnaGxpZ2h0ZWRJdGVtLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEl0ZW0oZXZlbnQsIHRoaXMuaGlnaGxpZ2h0ZWRJdGVtLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgJ0Fycm93TGVmdCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnTGVmdCc6XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBDbG9zZSB0aGUgbWVudSBpZiBpdCBpcyBhIGNoaWxkIG1lbnVcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJhY2soZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnICc6XG4gICAgICAgICAgICAgICAgY2FzZSAnU3BhY2ViYXInOlxuICAgICAgICAgICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJldmVudCAnZW50ZXInIGZyb20gZG9pbmcgd2hhdGV2ZXIgaXQgZG9lcyBvbiB0aGUgY3VycmVudGx5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4ID4gLTEgJiYgdGhpcy5oaWdobGlnaHRlZEl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0SXRlbShldmVudCwgdGhpcy5oaWdobGlnaHRlZEl0ZW0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGhlYWRlciBpcyBoaWdobGlnaHRlZFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaGlnaGxpZ2h0ZWRJdGVtSW5kZXggPT09IC0xKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsb3NlIHRoZSBtZW51IGlmIGl0J3MgYSBjaGlsZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5iYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNjcm9sbCB0byB0aGUgaXRlbSBjdXJyZW50bHkgbWFya2VkIGFzICdpcy1zZWxlY3RlZCcuIFdhaXQgYSB0aWNrIGZvciB0aGVcbiAgICAgKiBOZ0NsYXNzRGlyZWNpdHZlIG9yIE5hdkl0ZW1BY3RpdmVEaXJlY3RpdmUgdG8gcmVzcG9uZCB0byB0aGUgbW9kZWwgY2hhbmdlc1xuICAgICAqIGFuZCB1cGRhdGUgdGhlIHZpZXcuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbFRvU2VsZWN0ZWRJdGVtKCk6IHZvaWQge1xuICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsaW5rU2VsZWN0b3IgPSBgbGkuaXMtc2VsZWN0ZWRgO1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxTZXJ2aWNlLnNjcm9sbFRvSXRlbShgIyR7dGhpcy5pZH1fbGlzdGAsIGxpbmtTZWxlY3Rvcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgbW92ZUhpZ2hsaWdodGVkVXBPckRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgICAgY2FzZSAnVXAnOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRlZEl0ZW1JbmRleC0tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgIGNhc2UgJ0Rvd24nOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4IDwgdGhpcy5zZWxlY3RhYmxlSXRlbXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4Kys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBpdGVtIGF0IHRoZSBjdXJyZW50IGhpZ2hsaWdodCBpbmRleFxuICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRlZEl0ZW0gPSB0aGlzLnNlbGVjdGFibGVJdGVtc1t0aGlzLmhpZ2hsaWdodGVkSXRlbUluZGV4XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGlnaGxpZ2h0ZWRJdGVtID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNjcm9sbFRvSGlnaGxpZ2h0ZWRJdGVtKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2Nyb2xsIHRvIHRoZSBzcGVjaWZpZWQgbWVudSBpdGVtLlxuICAgKiBJZiBubyBpdGVtIGlzIHByb3ZpZGVkLCBpdCB3aWxsIHNjcm9sbCB0byB0aGUgZmlyc3QgaXRlbS5cbiAgICAgKlxuICAgKiBAcGFyYW0gaXRlbSBUaGUgbWVudSBpdGVtIHRvIHNjcm9sbCB0by5cbiAgICAgKiBAbWVtYmVyb2YgTWVudUNvbXBvbmVudFxuICAgICAqL1xuICAgIHByaXZhdGUgc2Nyb2xsTWVudShpdGVtPzogTWVudUl0ZW0gfCBudWxsKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLml0ZW1zLmxlbmd0aCA+IDAgJiYgdGhpcy5pZCkge1xuICAgICAgICAgICAgaXRlbSA9IGl0ZW0gPyBpdGVtIDogdGhpcy5pdGVtc1swXTtcbiAgICAgICAgICAgIGxldCBpdGVtSWQgPSBpdGVtLmlkID8gaXRlbS5pZCA6IE1lbnVDb21wb25lbnQuZ2V0SW5kZXhlZEl0ZW1JZCh0aGlzLml0ZW1zLCBpdGVtLCB0aGlzLmlkKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsU2VydmljZS5zY3JvbGxJdGVtQ2VudGVyZWQoYCMke3RoaXMuaWR9X2xpc3RgLCBgIyR7aXRlbUlkfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzY3JvbGxUb0hpZ2hsaWdodGVkSXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zY3JvbGxNZW51KHRoaXMuaGlnaGxpZ2h0ZWRJdGVtKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZEtleWRvd25MaXN0ZW5lcigpOiB2b2lkIHtcbiAgICAgICAgLy8gT25seSBhdHRlbXB0IHRvIGFkZCB0aGUgbGlzdGVuZXIgaWYga2V5Ym9hcmQgbmF2IGlzIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlS2V5TmF2KSB7XG4gICAgICAgICAgICAvLyByZW5kZXJlci5saXN0ZW4gYWRkcyB0aGUgbGlzdGVuZXIgYW5kIHJldHVybnMgYSBmdW5jdGlvbiB0byByZW1vdmUgaXQgZnJvbSB0aGUgcmVuZGVyZXIuXG4gICAgICAgICAgICAvLyBUaGUgbGlzdGVuZXIgcmVtYWlucyBhY3RpdmUgdW50aWwgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQuXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUtleWRvd25MaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICdrZXlkb3duJywgKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB0aGlzLmtleU5hdmlnYXRlKGV2ZW50KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBtZW51IGl0ZW0gaWRzIHVzaW5nIGl0cyBpbmRleCBpZiBpdGVtIGRvZXNuJ3QgYWxyZWFkeSBoYXZlIG9uZVxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0SXRlbUlkcygpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXRlbXMpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBpdGVtLmlkID0gaXRlbS5pZCA/IGl0ZW0uaWQgOiB0aGlzLmlkICsgJ19pdGVtJyArIGluZGV4O1xuICAgICAgICAgICAgICAgIGlmIChpdGVtLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgIGl0ZW0uaXRlbXMuZm9yRWFjaCgoY2hpbGRJdGVtLCBjaGlsZEluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEl0ZW0uaWQgPSBjaGlsZEl0ZW0uaWQgPyBjaGlsZEl0ZW0uaWQgOiB0aGlzLmlkICsgJ19pdGVtJyArIGluZGV4ICsgJy0nICsgY2hpbGRJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8bmF2PlxuICAgIDxkaXYgY2xhc3M9XCJwYXJlbnRcIlxuICAgICAgICAgW2NsYXNzLm5vLWRhdGFdPVwic2hvd05vSXRlbXMgJiYgKCFpdGVtcyB8fCBpdGVtcy5sZW5ndGggPT09IDApXCI+XG4gICAgICAgIDxoZWFkZXIgaWQ9XCJ7e2lkfX1faGVhZGVyXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtaGVhZGluZy0zIHAtMVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLXNlbGVjdGVkXT1cImhpZ2hsaWdodGVkSXRlbUluZGV4ID09PSAtMVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJwYXJlbnRcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJiYWNrKCRldmVudClcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLXdyYXBwZXJcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS05MCBmbGV4LXNocmlua1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsIHRleHQtdHJ1bmNhdGUgZmxleC1ncm93XCI+e3twYXJlbnQ/LmxhYmVsfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9oZWFkZXI+XG5cbiAgICAgICAgPHVsIGlkPVwie3tpZH19X2xpc3RcIlxuICAgICAgICAgICAgY2xhc3M9XCJweS0xXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zOyBpbmRleCBhcyBpXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIml0ZW1UZW1wbGF0ZTsgY29udGV4dDogeyRpbXBsaWNpdDogaXRlbSwgaW5kZXg6IGl9XCI+PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFNob3cgY2hpbGQgaXRlbXMgdW5kZXIgcGFyZW50IGl0ZW0gaWYgdGhlIGl0ZW0gaXMgYSBoZWFkaW5nIG9yIGRpdmlkZWQtc2VjdGlvbiAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIml0ZW0uaXRlbXM/Lmxlbmd0aCAmJiAoaXRlbS5kaXNwbGF5ID09PSAnaGVhZGluZycgfHwgaXRlbS5kaXNwbGF5ID09PSAnZGl2aWRlZC1zZWN0aW9uJyB8fCBpdGVtLmRpc3BsYXkgPT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbicpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNoaWxkSXRlbSBvZiBpdGVtLml0ZW1zOyBpbmRleCBhcyBqOyBmaXJzdCBhcyBpc0ZpcnN0OyBsYXN0IGFzIGlzTGFzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbVRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY2hpbGRJdGVtLCBpbmRleDogaSArICctJyArIGosIGlzRGl2aWRlZFNlY3Rpb25DaGlsZDogKCBpdGVtLmRpc3BsYXkgPT09ICdkaXZpZGVkLXNlY3Rpb24nIHx8IGl0ZW0uZGlzcGxheSA9PT0gJ2hlYWRpbmctZGl2aWRlZC1zZWN0aW9uJyksIGlzRmlyc3Q6IGlzRmlyc3QsIGlzTGFzdDogaXNMYXN0fVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3VsPlxuXG4gICAgICAgIDxwIGNsYXNzPVwibm8tZGF0YS1tZXNzYWdlXCI+e3tub0RhdGFUZXh0IHwgdHJhbnNsYXRlfX08L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIENoaWxkIG1lbnUgKFJlbmRlcmVkIHRvIHRoZSByaWdodCkgLS0+XG4gICAgPGVjLW1lbnUgKm5nSWY9XCJzZWxlY3RlZD8uaXRlbXMgJiYgc2VsZWN0ZWQ/LmRpc3BsYXkgIT09ICdoZWFkaW5nJyAmJiBzZWxlY3RlZD8uZGlzcGxheSAhPT0gJ2RpdmlkZWQtc2VjdGlvbicgJiYgc2VsZWN0ZWQ/LmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIlxuICAgICAgICAgICAgIGlkPVwie3tpZH19X2NoaWxkXCJcbiAgICAgICAgICAgICBjbGFzcz1cImNoaWxkXCJcbiAgICAgICAgICAgICBbcGFyZW50XT1cInNlbGVjdGVkXCJcbiAgICAgICAgICAgICBbaXRlbXNdPVwic2VsZWN0ZWQ/Lml0ZW1zXCJcbiAgICAgICAgICAgICBbc2hvd05vSXRlbXNdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgW3RlbXBsYXRlVHlwZV09XCJ0ZW1wbGF0ZVR5cGVcIlxuICAgICAgICAgICAgIFtlbmFibGVLZXlOYXZdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgW3RydW5jYXRlSXRlbXNdPVwidHJ1bmNhdGVJdGVtc1wiXG4gICAgICAgICAgICAgKHNlbGVjdGVkQ2hhbmdlZCk9XCJvblNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAobWVudUNsb3NlZCk9XCJ0b2dnbGVDaGlsZE1lbnUoZmFsc2UpXCI+XG4gICAgPC9lYy1tZW51PlxuPC9uYXY+XG5cbjxuZy10ZW1wbGF0ZSAjaXRlbVRlbXBsYXRlXG4gICAgICAgICAgICAgbGV0LWl0ZW1cbiAgICAgICAgICAgICBsZXQtaT1cImluZGV4XCJcbiAgICAgICAgICAgICBsZXQtaXNEaXZpZGVkU2VjdGlvbkNoaWxkPVwiaXNEaXZpZGVkU2VjdGlvbkNoaWxkXCJcbiAgICAgICAgICAgICBsZXQtaXNGaXJzdD1cImlzRmlyc3RcIlxuICAgICAgICAgICAgIGxldC1pc0xhc3Q9XCJpc0xhc3RcIj5cbiAgICA8bGkgKm5nSWY9XCIhKGl0ZW0uaGlkZUlmTm9JdGVtcyAmJiAhaXRlbS5pdGVtcz8ubGVuZ3RoKSAmJiBpdGVtLmRpc3BsYXkgIT09ICdkaXZpZGVkLXNlY3Rpb24nXCJcbiAgICAgICAgaWQ9XCJ7e2l0ZW0uaWQgfHwgaWQgKyAnX2l0ZW0nICsgaX19XCJcbiAgICAgICAgY2xhc3M9XCJ7e2l0ZW0uZGlzcGxheSB8fCAnaXRlbSd9fSB7e2l0ZW0uY2xhc3NMaXN0fX1cIlxuICAgICAgICBbY2xhc3MuZGl2aWRlci10b3BdPVwiaXRlbS5kaXNwbGF5ID09PSAnZGl2aWRlci10b3AnIHx8IGl0ZW0uZGlzcGxheSA9PT0gJ2hlYWRpbmctZGl2aWRlZC1zZWN0aW9uJyB8fCAoaXNEaXZpZGVkU2VjdGlvbkNoaWxkICYmIGlzRmlyc3QgJiYgaXRlbS5kaXNwbGF5ID09PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nKVwiXG4gICAgICAgIFtjbGFzcy5kaXZpZGVyXT1cIml0ZW0uZGlzcGxheSA9PT0gJ2RpdmlkZXInIHx8IChpc0RpdmlkZWRTZWN0aW9uQ2hpbGQgJiYgaXNMYXN0KVwiXG4gICAgICAgIFthdHRyLmRpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIlxuICAgICAgICBbaGlkZGVuXT1cIml0ZW0uaGlkZGVuXCJcbiAgICAgICAgZWNOYXZJdGVtQWN0aXZlPVwiaXMtc2VsZWN0ZWRcIlxuICAgICAgICBbZWNOYXZJdGVtQWN0aXZlUXVlcnlQYXJhbXNdPVwiaXRlbS5xdWVyeVBhcmFtc1wiXG4gICAgICAgIFtlY05hdkl0ZW1BY3RpdmVVcmxdPVwiaXRlbS51cmxcIlxuICAgICAgICBbZWNOYXZJdGVtQWN0aXZlRXhhY3RNYXRjaF09J2l0ZW0uaXNBY3RpdmVFeGFjdE1hdGNoJ1xuICAgICAgICAocm91dGVyTGlua0FjdGl2YXRlZCk9XCJzZWxlY3RJdGVtKCRldmVudCwgaXRlbSlcIlxuICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWhpZ2hsaWdodGVkJzooc2VsZWN0ZWQgPT09IGl0ZW0gJiYgaXRlbT8uZGlzcGxheSAhPT0gJ2hlYWRpbmcnICAmJiBpdGVtPy5kaXNwbGF5ICE9PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nKSB8fCBoaWdobGlnaHRlZEl0ZW0gPT09IGl0ZW0sICdpcy1saW5rJzogaXRlbS51cmwsICdpcy1kaXNhYmxlZCc6IGl0ZW0uZGlzYWJsZWQsICdpcy1yZWFkb25seSc6IGl0ZW0ucmVhZG9ubHksICdpcy1jaGVja2VkJzogaXRlbS5jaGVja2VkLCAndGV4dC1oZWFkaW5nLTMnOiAoaXRlbT8uZGlzcGxheSA9PT0gJ2hlYWRpbmcnIHx8IGl0ZW0/LmRpc3BsYXkgPT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbicpfVwiXG4gICAgICAgIChjbGljayk9XCJzZWxlY3RJdGVtKCRldmVudCwgaXRlbSlcIj5cblxuICAgICAgICA8YSAqbmdJZj1cIml0ZW0udXJsICYmICFpdGVtLmV4dGVybmFsTGlua1wiXG4gICAgICAgICAgIGlkPVwie3tpdGVtLmlkfX1fbGlua1wiXG4gICAgICAgICAgIHRpdGxlPVwie3t0cnVuY2F0ZUl0ZW1zID8gaXRlbS5sYWJlbCA6ICcnfX1cIlxuICAgICAgICAgICBjbGFzcz1cIml0ZW0td3JhcHBlclwiXG4gICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIml0ZW0udXJsXCJcbiAgICAgICAgICAgW3F1ZXJ5UGFyYW1zXT1cIml0ZW0ucXVlcnlQYXJhbXMgfHwgbnVsbFwiXG4gICAgICAgICAgIHRhcmdldD1cInt7aXRlbS50YXJnZXQgfHwgJ19zZWxmJ319XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaW50ZXJuYWxpemVkVGVtcGxhdGU7IGNvbnRleHQ6IHskaW1wbGljaXQ6IGl0ZW19XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvYT5cblxuICAgICAgICA8YSAqbmdJZj1cIml0ZW0udXJsICYmIGl0ZW0uZXh0ZXJuYWxMaW5rXCJcbiAgICAgICAgICAgaWQ9XCJ7e2l0ZW0uaWR9fV9saW5rXCJcbiAgICAgICAgICAgdGl0bGU9XCJ7e3RydW5jYXRlSXRlbXMgPyBpdGVtLmxhYmVsIDogJyd9fVwiXG4gICAgICAgICAgIGNsYXNzPVwiaXRlbS13cmFwcGVyXCJcbiAgICAgICAgICAgaHJlZj1cInt7aXRlbS51cmx9fVwiXG4gICAgICAgICAgIHRhcmdldD1cInt7aXRlbS50YXJnZXQgfHwgJ19zZWxmJ319XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaW50ZXJuYWxpemVkVGVtcGxhdGU7IGNvbnRleHQ6IHskaW1wbGljaXQ6IGl0ZW19XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvYT5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWl0ZW0udXJsXCJcbiAgICAgICAgICAgICB0aXRsZT1cInt7dHJ1bmNhdGVJdGVtcyA/IGl0ZW0ubGFiZWwgOiAnJ319XCJcbiAgICAgICAgICAgICBjbGFzcz1cIml0ZW0td3JhcHBlclwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImludGVybmFsaXplZFRlbXBsYXRlOyBjb250ZXh0OiB7JGltcGxpY2l0OiBpdGVtfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2xpPlxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLSAnbGFiZWwnIEl0ZW0gVGVtcGxhdGUgLS0+XG48bmctdGVtcGxhdGUgI2xhYmVsXG4gICAgICAgICAgICAgbGV0LWl0ZW0+XG4gICAgPHNwYW4gaWQ9XCJ7e2l0ZW0uaWR9fV9sYWJlbFwiXG4gICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgW2NsYXNzLnRleHQtdHJ1bmNhdGVdPVwidHJ1bmNhdGVJdGVtc1wiPlxuICAgICAgICB7e2l0ZW0ubGFiZWx9fVxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5oZWxwUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtfVwiPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3NwYW4+XG5cbiAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS0yNzBcIlxuICAgICAgICpuZ0lmPVwiaXRlbT8uaXRlbXMgJiYgaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgaXRlbS5kaXNwbGF5ICE9PSAnZGl2aWRlZC1zZWN0aW9uJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIj48L2k+XG48L25nLXRlbXBsYXRlPlxuXG48IS0tICdjaGVja0FuZExhYmVsJyBJdGVtIFRlbXBsYXRlIC0tPlxuPG5nLXRlbXBsYXRlICNjaGVja0FuZExhYmVsXG4gICAgICAgICAgICAgbGV0LWl0ZW0+XG5cbiAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1jaGVjayBlYy1pY29uLXNtXCJcbiAgICAgICAqbmdJZj1cIml0ZW0uZGlzcGxheSAhPT0gJ2hlYWRpbmcnICYmIGl0ZW0uZGlzcGxheSAhPT0gJ2hlYWRpbmctZGl2aWRlZC1zZWN0aW9uJ1wiPjwvaT5cblxuICAgIDxpIGNsYXNzPVwiZWMtaWNvbiB7e2l0ZW0uaWNvbn19IG1sLTJcIlxuICAgICAgICpuZ0lmPVwiaXRlbS5pY29uXCI+PC9pPlxuXG4gICAgPHNwYW4gaWQ9XCJ7e2l0ZW0uaWR9fV9sYWJlbFwiXG4gICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgW2NsYXNzLnRleHQtdHJ1bmNhdGVdPVwidHJ1bmNhdGVJdGVtc1wiPlxuICAgICAgICB7e2l0ZW0ubGFiZWx9fVxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5oZWxwUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtfVwiPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3NwYW4+XG5cbiAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS0yNzBcIlxuICAgICAgICpuZ0lmPVwiaXRlbT8uaXRlbXMgJiYgaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgaXRlbS5kaXNwbGF5ICE9PSAnZGl2aWRlZC1zZWN0aW9uJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIj48L2k+XG48L25nLXRlbXBsYXRlPlxuXG48IS0tICdpY29uQW5kTGFiZWwnIEl0ZW0gVGVtcGxhdGUgLS0+XG48bmctdGVtcGxhdGUgI2ljb25BbmRMYWJlbFxuICAgICAgICAgICAgIGxldC1pdGVtPlxuICAgIDwhLS0gSWYgbWVudUl0ZW0uaWNvbiBleGlzdHMgYW5kIGlzIG5vdCBibGFuaywgc2hvdyB0aGUgaWNvbiBpbiB0aGUgbWVudSAtLT5cbiAgICA8aSBjbGFzcz1cImVjLWljb24ge3tpdGVtLmljb259fVwiXG4gICAgICAgKm5nSWY9XCIoaXRlbS5pY29uICYmIGl0ZW0uaWNvbiAhPT0gJycpIHx8IHByZXNlcnZlSWNvblNwYWNlXCI+PC9pPlxuXG4gICAgPHNwYW4gaWQ9XCJ7e2l0ZW0uaWR9fV9sYWJlbFwiXG4gICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgW2NsYXNzLnRleHQtdHJ1bmNhdGVdPVwidHJ1bmNhdGVJdGVtc1wiPlxuICAgICAgICB7e2l0ZW0ubGFiZWx9fVxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5oZWxwUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtfVwiPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3NwYW4+XG5cbiAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS0yNzBcIlxuICAgICAgICpuZ0lmPVwiaXRlbT8uaXRlbXMgJiYgaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgaXRlbS5kaXNwbGF5ICE9PSAnZGl2aWRlZC1zZWN0aW9uJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIj48L2k+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2ljb25MYWJlbENhcHRpb25cbiAgICAgICAgICAgICBsZXQtaXRlbT5cbiAgICA8aSBjbGFzcz1cImVjLWljb24ge3tpdGVtLmljb259fVwiXG4gICAgICAgKm5nSWY9XCIoaXRlbS5pY29uICYmIGl0ZW0uaWNvbiAhPT0gJycpIHx8IHByZXNlcnZlSWNvblNwYWNlXCI+PC9pPlxuICAgIDxkaXYgKm5nSWY9XCJpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIlxuICAgICAgICAgY2xhc3M9XCJsYWJlbCBmbGV4LWdyb3dcIj5cbiAgICAgICAgPGRpdiBpZD1cInt7aXRlbS5pZH19X2xhYmVsXCJcbiAgICAgICAgICAgICBjbGFzcz1cInRleHQtYm9keS0xXCJcbiAgICAgICAgICAgICBbY2xhc3MudGV4dC10cnVuY2F0ZV09XCJ0cnVuY2F0ZUl0ZW1zXCI+XG4gICAgICAgICAgICB7e2l0ZW0ubGFiZWx9fVxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0uaGVscFBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtfVwiPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwie3tpdGVtLmlkfX1fY2FwdGlvblwiXG4gICAgICAgICAgICAgKm5nSWY9XCJpdGVtLmNhcHRpb25cIlxuICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1jYXB0aW9uLTFcIlxuICAgICAgICAgICAgIFtjbGFzcy50ZXh0LXRydW5jYXRlXT1cInRydW5jYXRlSXRlbXNcIlxuICAgICAgICAgICAgIFtpbm5lckhUTUxdPVwiaXRlbS5jYXB0aW9uXCI+PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGgzICpuZ0lmPVwiaXRlbS5kaXNwbGF5ID09PSAnaGVhZGluZycgfHwgaXRlbS5kaXNwbGF5ID09PSAnaGVhZGluZy1kaXZpZGVkLXNlY3Rpb24nXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4LWdyb3cgdGV4dC1oZWFkaW5nLTMgYWxpZ24tc2VsZi1jZW50ZXJcIlxuICAgICAgICBbY2xhc3MudGV4dC10cnVuY2F0ZV09XCJ0cnVuY2F0ZUl0ZW1zXCI+XG4gICAgICAgIHt7aXRlbS5sYWJlbH19XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLmhlbHBQb3BvdmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwUG9wb3ZlclwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGl0ZW19XCI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvaDM+XG5cbiAgICA8aSBjbGFzcz1cImVjLWljb24gaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS0yNzAgYWxpZ24tc2VsZi1jZW50ZXJcIlxuICAgICAgICpuZ0lmPVwiaXRlbT8uaXRlbXMgJiYgaXRlbS5kaXNwbGF5ICE9PSAnaGVhZGluZycgJiYgaXRlbS5kaXNwbGF5ICE9PSAnZGl2aWRlZC1zZWN0aW9uJyAmJiBpdGVtLmRpc3BsYXkgIT09ICdoZWFkaW5nLWRpdmlkZWQtc2VjdGlvbidcIj48L2k+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2hlbHBQb3BvdmVyXG4gICAgICAgICAgICAgbGV0LWl0ZW0+XG4gICAgPGVjLWhlbHAtcG9wb3ZlciBpZD1cInt7aXRlbS5pZH19X2hlbHBQb3BvdmVyXCJcbiAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZC1pbmxpbmUtYmxvY2sgbXktbjMgbXgtbjFcIlxuICAgICAgICAgICAgICAgICAgICAgdGV4dD1cInt7aXRlbS5oZWxwUG9wb3ZlciB8IHRyYW5zbGF0ZX19XCJcbiAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQb3NpdGlvbj1cInt7aXRlbS5oZWxwUG9wb3ZlclBvc2l0aW9uID8/ICd0b3AtbGVmdCd9fVwiPlxuICAgIDwvZWMtaGVscC1wb3BvdmVyPlxuPC9uZy10ZW1wbGF0ZT4iXX0=