@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.
- package/fesm2022/energycap-components.mjs +379 -354
- package/fesm2022/energycap-components.mjs.map +1 -1
- package/lib/controls/button/copy-button-base.directive.d.ts +1 -1
- package/lib/controls/date-input/date-input.component.d.ts +1 -1
- package/lib/controls/form-control-base.d.ts +1 -1
- package/lib/core/date-time-helper.d.ts +2 -2
- package/lib/display/hierarchy/hierarchy-base.d.ts +1 -1
- package/lib/display/hierarchy/hierarchy-mocks.spec.d.ts +1 -1
- package/lib/display/resizable/resizable-base.d.ts +1 -1
- package/lib/shared/display/pipes/date-display.pipe.d.ts +1 -1
- package/lib/shared/page/page-base/page-base.component.d.ts +1 -1
- package/lib/shared/testing/public-mocks.spec.d.ts +1 -1
- package/lib/shared/wizard/wizard-base/wizard-base.component.d.ts +1 -1
- package/package.json +1 -3
- package/schematics/utilities/typescript.js +3 -4
- package/schematics/utilities/typescript.js.map +1 -1
- package/schematics/utilities/workspace.d.ts +0 -8
- package/schematics/utilities/workspace.js +48 -71
- package/schematics/utilities/workspace.js.map +1 -1
- package/esm2022/energycap-components.mjs +0 -5
- package/esm2022/lib/components.module.mjs +0 -425
- package/esm2022/lib/controls/banner/banner.component.mjs +0 -112
- package/esm2022/lib/controls/button/button.component.mjs +0 -114
- package/esm2022/lib/controls/button/copy-button-base.directive.mjs +0 -67
- package/esm2022/lib/controls/button/copy-button.directive.mjs +0 -28
- package/esm2022/lib/controls/button/copy-table-button.directive.mjs +0 -43
- package/esm2022/lib/controls/calendar/calendar-item.component.mjs +0 -91
- package/esm2022/lib/controls/calendar/calendar.component.mjs +0 -251
- package/esm2022/lib/controls/calendar/calendar.types.mjs +0 -2
- package/esm2022/lib/controls/checkbox/checkbox.component.mjs +0 -140
- package/esm2022/lib/controls/collapsible-toggle/collapsible-toggle.component.mjs +0 -38
- package/esm2022/lib/controls/combobox/combobox.component.mjs +0 -879
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.mjs +0 -57
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.mjs +0 -62
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.mjs +0 -100
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.mjs +0 -101
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.mjs +0 -76
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.mjs +0 -79
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.mjs +0 -210
- package/esm2022/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.mjs +0 -81
- package/esm2022/lib/controls/date-input/date-input.component.mjs +0 -466
- package/esm2022/lib/controls/date-input/date-input.types.mjs +0 -44
- package/esm2022/lib/controls/dropdown/dropdown.component.mjs +0 -243
- package/esm2022/lib/controls/file-upload/file-upload.component.mjs +0 -261
- package/esm2022/lib/controls/form-control/form-control.component.mjs +0 -110
- package/esm2022/lib/controls/form-control-base.mjs +0 -151
- package/esm2022/lib/controls/form-control-label/form-control-label.component.mjs +0 -136
- package/esm2022/lib/controls/form-group/form-group.component.mjs +0 -261
- package/esm2022/lib/controls/help-popover/help-popover.component.mjs +0 -31
- package/esm2022/lib/controls/item-picker/item-picker.component.mjs +0 -329
- package/esm2022/lib/controls/link-button/link-button.component.mjs +0 -11
- package/esm2022/lib/controls/menu/menu.component.mjs +0 -485
- package/esm2022/lib/controls/navigation/link-item.mjs +0 -2
- package/esm2022/lib/controls/navigation/nav-group.mjs +0 -39
- package/esm2022/lib/controls/navigation/nav-item-active.directive.mjs +0 -92
- package/esm2022/lib/controls/navigation/nav-item.mjs +0 -2
- package/esm2022/lib/controls/numericbox/numericbox.component.mjs +0 -372
- package/esm2022/lib/controls/popover/popover.component.mjs +0 -117
- package/esm2022/lib/controls/radio-button/radio-button-option.mjs +0 -3
- package/esm2022/lib/controls/radio-button/radio-button.component.mjs +0 -82
- package/esm2022/lib/controls/select/select.component.mjs +0 -88
- package/esm2022/lib/controls/tabs/tabs.component.mjs +0 -47
- package/esm2022/lib/controls/textbox/textbox.component.mjs +0 -155
- package/esm2022/lib/core/cache.service.mjs +0 -105
- package/esm2022/lib/core/custom-validators.mjs +0 -29
- package/esm2022/lib/core/date-time-helper.mjs +0 -228
- package/esm2022/lib/core/error.service.mjs +0 -61
- package/esm2022/lib/core/router-helper.service.mjs +0 -111
- package/esm2022/lib/core/scroll.service.mjs +0 -89
- package/esm2022/lib/core/telemetry-tracker.service.mjs +0 -16
- package/esm2022/lib/core/telemetry.service.mjs +0 -38
- package/esm2022/lib/core/validation-message.service.mjs +0 -185
- package/esm2022/lib/core/validation-patterns.mjs +0 -31
- package/esm2022/lib/core/window.service.mjs +0 -186
- package/esm2022/lib/display/app-bar/app-bar.component.mjs +0 -49
- package/esm2022/lib/display/avatar/avatar.component.mjs +0 -67
- package/esm2022/lib/display/avatar/avatar.service.mjs +0 -64
- package/esm2022/lib/display/confirm/confirm.component.mjs +0 -168
- package/esm2022/lib/display/dialog/dialog-content.mjs +0 -2
- package/esm2022/lib/display/dialog/dialog-group/dialog-group.component.mjs +0 -63
- package/esm2022/lib/display/dialog/dialog-types.mjs +0 -77
- package/esm2022/lib/display/dialog/dialog.component.mjs +0 -287
- package/esm2022/lib/display/dialog/dialog.service.mjs +0 -71
- package/esm2022/lib/display/help/help-types.mjs +0 -2
- package/esm2022/lib/display/hierarchy/hierarchy-base.mjs +0 -111
- package/esm2022/lib/display/hierarchy/hierarchy-mocks.spec.mjs +0 -54
- package/esm2022/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +0 -65
- package/esm2022/lib/display/item-display/item-display.component.mjs +0 -83
- package/esm2022/lib/display/json-display/json-display.component.mjs +0 -47
- package/esm2022/lib/display/resizable/resizable-base.mjs +0 -120
- package/esm2022/lib/display/resizable/resizable.component.mjs +0 -57
- package/esm2022/lib/display/spinner/spinner.component.mjs +0 -12
- package/esm2022/lib/display/splash/splash.component.mjs +0 -61
- package/esm2022/lib/display/splash/splash.service.mjs +0 -35
- package/esm2022/lib/display/table/resizable-column.component.mjs +0 -20
- package/esm2022/lib/display/table/resizable-table.directive.mjs +0 -227
- package/esm2022/lib/display/table/searchable-table.component.mjs +0 -344
- package/esm2022/lib/display/table/table-detail-row.component.mjs +0 -28
- package/esm2022/lib/display/table/table-locked-column.component.mjs +0 -58
- package/esm2022/lib/display/table/table-master-header-row.component.mjs +0 -14
- package/esm2022/lib/display/table/table-master-row.component.mjs +0 -163
- package/esm2022/lib/display/table/table-pagination.component.mjs +0 -155
- package/esm2022/lib/display/table/table-selectable-row.component.mjs +0 -235
- package/esm2022/lib/display/table/table.component.mjs +0 -257
- package/esm2022/lib/display/tags/tag.mjs +0 -18
- package/esm2022/lib/display/tags/tags.component.mjs +0 -82
- package/esm2022/lib/display/toast/toast/toast.component.mjs +0 -77
- package/esm2022/lib/display/toast/toast-types.mjs +0 -8
- package/esm2022/lib/display/toast/toast.service.mjs +0 -35
- package/esm2022/lib/display/toast/toaster/toaster.component.mjs +0 -114
- package/esm2022/lib/display/tooltip/tooltip.component.mjs +0 -28
- package/esm2022/lib/display/tooltip/tooltip.service.mjs +0 -78
- package/esm2022/lib/display/tooltip-directive/tooltip.directive.mjs +0 -173
- package/esm2022/lib/display/tree/tree.component.mjs +0 -139
- package/esm2022/lib/display/view-overlay/view-overlay.component.mjs +0 -58
- package/esm2022/lib/shared/directives/click-area-for/click-area-for.directive.mjs +0 -32
- package/esm2022/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +0 -111
- package/esm2022/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.mjs +0 -103
- package/esm2022/lib/shared/directives/popup/popup-container.directive.mjs +0 -166
- package/esm2022/lib/shared/display/pipes/date-display-2.pipe.mjs +0 -39
- package/esm2022/lib/shared/display/pipes/date-display.pipe.mjs +0 -51
- package/esm2022/lib/shared/display/pipes/highlight-text.pipe.mjs +0 -30
- package/esm2022/lib/shared/display/pipes/relative-date.pipe.mjs +0 -62
- package/esm2022/lib/shared/display/pipes/row-count.pipe.mjs +0 -48
- package/esm2022/lib/shared/display/pipes/time-display.pipe.mjs +0 -41
- package/esm2022/lib/shared/display.mjs +0 -6
- package/esm2022/lib/shared/form-group.helper.mjs +0 -67
- package/esm2022/lib/shared/json-helper.mjs +0 -19
- package/esm2022/lib/shared/lodash-helper.mjs +0 -52
- package/esm2022/lib/shared/page/page-base/page-base.component.mjs +0 -387
- package/esm2022/lib/shared/page/page-statuses.mjs +0 -23
- package/esm2022/lib/shared/page/page-title/page-title.component.mjs +0 -23
- package/esm2022/lib/shared/page/page-view/page-view.component.mjs +0 -147
- package/esm2022/lib/shared/testing/copy-button-base-test-injector-factory.spec.mjs +0 -17
- package/esm2022/lib/shared/testing/hierarchy-base-test-injector-factory.spec.mjs +0 -17
- package/esm2022/lib/shared/testing/page-base-component-test-helper.spec.mjs +0 -38
- package/esm2022/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +0 -98
- package/esm2022/lib/shared/testing/public-mocks.spec.mjs +0 -148
- package/esm2022/lib/shared/testing/spy-factory.spec.mjs +0 -40
- package/esm2022/lib/shared/testing/translation-mocks.spec.mjs +0 -57
- package/esm2022/lib/shared/user-preference.service.mjs +0 -17
- package/esm2022/lib/shared/wizard/wizard-base/wizard-base.component.mjs +0 -246
- package/esm2022/lib/shared/wizard/wizard-buttons/wizard-buttons.component.mjs +0 -68
- package/esm2022/lib/shared/wizard/wizard-progress/wizard-progress.component.mjs +0 -18
- 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvbWVudS9tZW51LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9tZW51L21lbnUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQWMsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQXdCLE1BQU0sRUFBeUMsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7Ozs7QUFxQ3pMLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFFdEM7Ozs7R0FJRztBQU1ILE1BQU0sT0FBTyxhQUFhO0lBZ0x0Qjs7O09BR0c7SUFDSSxNQUFNLENBQUMsa0JBQWtCLENBQUMsS0FBaUI7UUFDOUMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQzFDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLHlCQUF5QixFQUFFLENBQUM7Z0JBQ2pILGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDL0IsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDcEIsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksU0FBUyxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxTQUFTLENBQUMsT0FBTyxLQUFLLHlCQUF5QixDQUFDLENBQUMsQ0FBQztZQUMzTCxDQUFDO1lBQ0QsT0FBTyxlQUFlLENBQUM7UUFDM0IsQ0FBQyxFQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQWlCLEVBQUUsSUFBc0IsRUFBRSxlQUF3QjtRQUM5RixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1AsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM1QixJQUFJLFVBQVUsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNsQyxPQUFPLEdBQUcsZUFBZSxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxDQUFDO2dCQUVELGtFQUFrRTtnQkFDbEUsSUFBSSxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksVUFBVSxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxVQUFVLENBQUMsT0FBTyxLQUFLLHlCQUF5QixDQUFDLEVBQUUsQ0FBQztvQkFDekosS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7d0JBQy9DLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLHNFQUFzRTt3QkFDdEUsSUFBSSxTQUFTLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFDakMsT0FBTyxHQUFHLGVBQWUsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQzlDLENBQUM7b0JBQ0wsQ0FBQztnQkFDTCxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsWUFDWSxFQUFjLEVBQ2QsUUFBbUIsRUFDbkIsYUFBNEIsRUFDNUIsYUFBNEI7UUFINUIsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUF2TnhDOzs7O1dBSUc7UUFDYSxVQUFLLEdBQW9CLEVBQUUsQ0FBQztRQUc1Qzs7Ozs7V0FLRztRQUNhLGFBQVEsR0FBb0IsSUFBSSxDQUFDO1FBVWpEOzs7O1dBSUc7UUFDYSxpQkFBWSxHQUFxQixPQUFPLENBQUM7UUFtQnpEOztXQUVHO1FBQ2EsZ0JBQVcsR0FBYSxLQUFLLENBQUM7UUFFOUM7O1dBRUc7UUFDYSxlQUFVLEdBQVcsWUFBWSxDQUFDO1FBR2xEOztXQUVHO1FBQ2EsaUJBQVksR0FBYSxLQUFLLENBQUM7UUFHL0M7O1dBRUc7UUFDYSxvQkFBZSxHQUFvQixJQUFJLENBQUM7UUFFeEQ7Ozs7V0FJRztRQUNhLHlCQUFvQixHQUFZLElBQUksQ0FBQztRQUVyRDs7V0FFRztRQUNhLGtCQUFhLEdBQVksS0FBSyxDQUFDO1FBRS9DOzs7V0FHRztRQUNhLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQU9uRDs7OztXQUlHO1FBQ2Msb0JBQWUsR0FBMkIsSUFBSSxZQUFZLEVBQVksQ0FBQztRQUd4Rjs7O1dBR0c7UUFDYyxlQUFVLEdBQXVCLElBQUksWUFBWSxFQUFRLENBQUM7UUFVM0U7O1dBRUc7UUFDSSx5QkFBb0IsR0FBVyxDQUFDLENBQUMsQ0FBQztRQThCekM7Ozs7O1dBS0c7UUFDSyxpQkFBWSxHQUFvQixJQUFJLENBQUM7UUFFN0M7O1dBRUc7UUFDSyxvQkFBZSxHQUFlLEVBQUUsQ0FBQztJQXlEckMsQ0FBQztJQUVFLFdBQVcsQ0FBQyxPQUFzQjtRQUNyQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsYUFBYSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGtCQUFrQjtRQUNyQixRQUFRLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QixLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUNWLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7Z0JBQ3RELE1BQU07WUFDVixLQUFLLENBQUMsY0FBYyxDQUFDO2dCQUNqQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2dCQUN0RCxNQUFNO1lBQ1YsS0FBSyxDQUFDLGVBQWUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztnQkFDdkQsTUFBTTtZQUNWLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFDckIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQztnQkFDMUQsTUFBTTtZQUNWO2dCQUNJLE1BQU0sSUFBSSxLQUFLLENBQUMsdUdBQXVHLENBQUMsQ0FBQTtRQUNoSSxDQUFDO1FBRUQsMkZBQTJGO1FBQzNGLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUN4RCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDVixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDMUIsQ0FBQztRQUVELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVsQixJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0RCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFBLENBQUEsQ0FBQyxDQUFDLENBQUM7UUFDaEgsQ0FBQztRQUVELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFTSxXQUFXO1FBQ2Qsc0RBQXNEO1FBQ3RELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDakMsQ0FBQztJQUNMLENBQUM7SUFHRDs7Ozs7O09BTUc7SUFDSSxVQUFVLENBQUMsS0FBWSxFQUFFLElBQWMsRUFBRSxVQUFvQjtRQUNoRSxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFeEIsOEZBQThGO1FBQzlGLDZGQUE2RjtRQUM3RiwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxFQUFFLENBQUM7WUFFakUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDWixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDZixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDOUIsQ0FBQztnQkFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLHlCQUF5QixFQUFFLENBQUM7b0JBQy9ILElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQy9CLENBQUM7cUJBQU0sQ0FBQztvQkFDSixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzQixDQUFDO2dCQUNELHlFQUF5RTtZQUM3RSxDQUFDO2lCQUFNLElBQUksVUFBVSxJQUFjLEtBQUssQ0FBQyxNQUFPLEVBQUUsT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNqRSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN2QyxDQUFDO3FCQUFNLENBQUM7b0JBQ0osSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO2dCQUNELHdEQUF3RDtnQkFDeEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixDQUFDO2lCQUFNLENBQUM7Z0JBQ0osSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQzdCLENBQUM7aUJBQU0sQ0FBQztnQkFDSixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDN0IsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksSUFBSSxDQUFDLEtBQVk7UUFDcEIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBR0Q7OztPQUdHO0lBQ0ksV0FBVyxDQUFDLElBQWM7UUFDN0IsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLGlCQUFpQixJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUsseUJBQXlCLEVBQUUsQ0FBQztZQUNqSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0wsQ0FBQztJQUdEOzs7O09BSUc7SUFDSSxlQUFlLENBQUMsSUFBYTtRQUNoQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdkQsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNQLHFFQUFxRTtZQUNyRSxtRUFBbUU7WUFDbkUsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDakMsQ0FBQztZQUVELElBQUksTUFBTSxHQUFXLEtBQUssQ0FBQyxZQUFZLENBQUM7WUFDeEMsSUFBSSxLQUFLLEdBQVcsS0FBSyxDQUFDLFdBQVcsQ0FBQztZQUV0QywrRUFBK0U7WUFDL0UscUZBQXFGO1lBQ3JGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLElBQUksQ0FBQyxDQUFDO1lBRXJELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDakUsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDO2FBQU0sQ0FBQztZQUNKLGlEQUFpRDtZQUNqRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUUxQixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUNoRSxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUV6RCx5Q0FBeUM7Z0JBQ3pDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFBO1FBQzFCLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxXQUFXLENBQUMsS0FBb0I7UUFDbkMsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLG9CQUFvQixFQUFFLGFBQWEsRUFBRSxDQUFDO1lBQ2pGLFFBQVEsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNoQixLQUFLLFNBQVMsQ0FBQztnQkFDZixLQUFLLElBQUksQ0FBQztnQkFDVixLQUFLLFdBQVcsQ0FBQztnQkFDakIsS0FBSyxNQUFNO29CQUNQLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDeEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN2QixJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BDLE1BQU07Z0JBRVYsS0FBSyxZQUFZLENBQUM7Z0JBQ2xCLEtBQUssT0FBTztvQkFDUixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQ3hCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDdkIsd0NBQXdDO29CQUN4QyxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDckQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDdkQsQ0FBQztvQkFDRCxNQUFNO2dCQUVWLEtBQUssV0FBVyxDQUFDO2dCQUNqQixLQUFLLE1BQU07b0JBQ1AsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO29CQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3ZCLHVDQUF1QztvQkFDdkMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7d0JBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDckIsQ0FBQztvQkFDRCxNQUFNO2dCQUVWLEtBQUssR0FBRyxDQUFDO2dCQUNULEtBQUssVUFBVSxDQUFDO2dCQUNoQixLQUFLLE9BQU87b0JBQ1IsK0VBQStFO29CQUMvRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBRXZCLElBQUksSUFBSSxDQUFDLG9CQUFvQixHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzt3QkFDekQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDbkQsK0JBQStCO29CQUNuQyxDQUFDO3lCQUFNLElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBRTFDLGlDQUFpQzt3QkFDakMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7NEJBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDckIsQ0FBQztvQkFDTCxDQUFDO29CQUNELE1BQU07Z0JBRVY7b0JBQ0ksT0FBTztZQUNmLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxvQkFBb0I7UUFDdkIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUM7WUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDdEUsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sdUJBQXVCLENBQUMsS0FBb0I7UUFDaEQsUUFBUSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDaEIsS0FBSyxTQUFTLENBQUM7WUFDZixLQUFLLElBQUk7Z0JBQ0wsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDakMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7Z0JBQ2hDLENBQUM7Z0JBQ0QsTUFBTTtZQUVWLEtBQUssV0FBVyxDQUFDO1lBQ2pCLEtBQUssTUFBTTtnQkFDUCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDOUQsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7Z0JBQ2hDLENBQUM7Z0JBQ0QsTUFBTTtZQUVWO2dCQUNJLE9BQU87UUFDZixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxnREFBZ0Q7WUFDaEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzNFLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDaEMsQ0FBQztRQUNELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxVQUFVLENBQUMsSUFBc0I7UUFDckMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ25DLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNGLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLENBQUM7SUFDTCxDQUFDO0lBRU8sdUJBQXVCO1FBQzNCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFTyxrQkFBa0I7UUFDdEIsOERBQThEO1FBQzlELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLDJGQUEyRjtZQUMzRiw2REFBNkQ7WUFDN0QsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxLQUFvQixFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDaEksQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLFVBQVU7UUFDZCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUMvQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxHQUFHLEtBQUssQ0FBQztnQkFDeEQsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEVBQUU7d0JBQ3pDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLEdBQUcsS0FBSyxHQUFHLEdBQUcsR0FBRyxVQUFVLENBQUM7b0JBQzlGLENBQUMsQ0FBQyxDQUFDO2dCQUNQLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7SUFDTCxDQUFDOytHQWxpQlEsYUFBYTttR0FBYixhQUFhLG9tQ0NuRDFCLG14U0F3TWMsaWxKRHJKRCxhQUFhOzs0RkFBYixhQUFhO2tCQUx6QixTQUFTOytCQUNJLFNBQVM7K0pBVUgsRUFBRTtzQkFBakIsS0FBSztnQkFNeUIsTUFBTTtzQkFBcEMsV0FBVzt1QkFBQyxTQUFTO2dCQVFOLEtBQUs7c0JBQXBCLEtBQUs7Z0JBU1UsUUFBUTtzQkFBdkIsS0FBSztnQkFPVSxNQUFNO3NCQUFyQixLQUFLO2dCQVFVLFlBQVk7c0JBQTNCLEtBQUs7Z0JBVVUsa0JBQWtCO3NCQUFqQyxLQUFLO2dCQU1VLEtBQUs7c0JBQXBCLEtBQUs7Z0JBTVUsV0FBVztzQkFBMUIsS0FBSztnQkFLVSxVQUFVO3NCQUF6QixLQUFLO2dCQU1VLFlBQVk7c0JBQTNCLEtBQUs7Z0JBTVUsZUFBZTtzQkFBOUIsS0FBSztnQkFPVSxvQkFBb0I7c0JBQW5DLEtBQUs7Z0JBS1UsYUFBYTtzQkFBNUIsS0FBSztnQkFNVSxpQkFBaUI7c0JBQWhDLEtBQUs7Z0JBS1Usb0JBQW9CO3NCQUFuQyxLQUFLO2dCQU9XLGVBQWU7c0JBQS9CLE1BQU07Z0JBT1UsVUFBVTtzQkFBMUIsTUFBTTtnQkFtQnVDLGFBQWE7c0JBQTFELFNBQVM7dUJBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFNaUIsb0JBQW9CO3NCQUF4RSxTQUFTO3VCQUFDLGNBQWMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBTVcscUJBQXFCO3NCQUExRSxTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBS2Esd0JBQXdCO3NCQUFoRixTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPdXRwdXQsIFJlbmRlcmVyMiwgU2ltcGxlQ2hhbmdlcywgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zY3JvbGwuc2VydmljZSc7XG5pbXBvcnQgeyBXaW5kb3dTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS93aW5kb3cuc2VydmljZSc7XG5pbXBvcnQgeyBMaW5rVGFyZ2V0IH0gZnJvbSAnLi4vLi4vZGlzcGxheS90YWdzL3RhZyc7XG5pbXBvcnQgeyBOYXZJdGVtIH0gZnJvbSAnLi4vbmF2aWdhdGlvbi9uYXYtaXRlbSc7XG5pbXBvcnQgeyBQb3BvdmVyQ29udGVudFBvc2l0aW9uIH0gZnJvbSAnLi4vcG9wb3Zlci9wb3BvdmVyLmNvbXBvbmVudCc7XG5cbmV4cG9ydCB0eXBlIE1lbnVUZW1wbGF0ZVR5cGUgPSBcImxhYmVsXCIgfCBcImljb25BbmRMYWJlbFwiIHwgXCJjaGVja0FuZExhYmVsXCIgfCBcImljb25MYWJlbENhcHRpb25cIjtcblxuZXhwb3J0IHR5cGUgTWVudUhvc3RFbGVtZW50Q2xhc3NlcyA9ICdiZy10cmFuc3BhcmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVudUl0ZW08VFZhbHVlID0gYW55LCBTSXRlbXMgPSBhbnk+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=
|