@skyux/tabs 5.9.4 → 6.0.0-beta.10
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/documentation.json +1 -1
- package/esm2020/index.mjs +23 -0
- package/esm2020/lib/modules/sectioned-form/sectioned-form-section.component.mjs +62 -0
- package/esm2020/lib/modules/sectioned-form/sectioned-form.component.mjs +109 -0
- package/esm2020/lib/modules/sectioned-form/sectioned-form.module.mjs +35 -0
- package/esm2020/lib/modules/sectioned-form/sectioned-form.service.mjs +35 -0
- package/esm2020/lib/modules/shared/sky-tabs-resources.module.mjs +52 -0
- package/esm2020/lib/modules/tabs/tab-button.component.mjs +70 -0
- package/esm2020/lib/modules/tabs/tab-index.mjs +2 -0
- package/esm2020/lib/modules/tabs/tab.component.mjs +131 -0
- package/esm2020/lib/modules/tabs/tabs.module.mjs +57 -0
- package/esm2020/lib/modules/tabs/tabset-active-tab-unregistered-args.mjs +2 -0
- package/esm2020/lib/modules/tabs/tabset-adapter.service.mjs +56 -0
- package/esm2020/lib/modules/tabs/tabset-buttons-display-mode.mjs +2 -0
- package/esm2020/lib/modules/tabs/tabset-nav-button.component.mjs +116 -0
- package/esm2020/lib/modules/tabs/tabset-permalink.service.mjs +124 -0
- package/esm2020/lib/modules/tabs/tabset-style.mjs +2 -0
- package/esm2020/lib/modules/tabs/tabset-tab-indexes-change.mjs +2 -0
- package/esm2020/lib/modules/tabs/tabset.component.mjs +395 -0
- package/esm2020/lib/modules/tabs/tabset.service.mjs +110 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tab-media-query.service.mjs +72 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tab.component.mjs +197 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tabset-adapter.service.mjs +48 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tabset-group.component.mjs +83 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tabset.component.mjs +150 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tabset.module.mjs +60 -0
- package/esm2020/lib/modules/vertical-tabset/vertical-tabset.service.mjs +168 -0
- package/esm2020/skyux-tabs.mjs +5 -0
- package/esm2020/testing/public-api.mjs +3 -0
- package/esm2020/testing/skyux-tabs-testing.mjs +5 -0
- package/esm2020/testing/tabs/tab-fixture-tab.mjs +2 -0
- package/esm2020/testing/tabs/tabset-fixture.mjs +130 -0
- package/fesm2015/{skyux-tabs-testing.js → skyux-tabs-testing.mjs} +1 -1
- package/fesm2015/skyux-tabs-testing.mjs.map +1 -0
- package/fesm2015/{skyux-tabs.js → skyux-tabs.mjs} +184 -238
- package/fesm2015/skyux-tabs.mjs.map +1 -0
- package/{esm2015/testing/tabs/tabset-fixture.js → fesm2020/skyux-tabs-testing.mjs} +39 -43
- package/fesm2020/skyux-tabs-testing.mjs.map +1 -0
- package/fesm2020/skyux-tabs.mjs +2002 -0
- package/fesm2020/skyux-tabs.mjs.map +1 -0
- package/package.json +43 -19
- package/testing/package.json +5 -5
- package/bundles/skyux-tabs-testing.umd.js +0 -498
- package/bundles/skyux-tabs.umd.js +0 -2260
- package/esm2015/index.js +0 -23
- package/esm2015/index.js.map +0 -1
- package/esm2015/lib/modules/sectioned-form/sectioned-form-section.component.js +0 -67
- package/esm2015/lib/modules/sectioned-form/sectioned-form-section.component.js.map +0 -1
- package/esm2015/lib/modules/sectioned-form/sectioned-form.component.js +0 -116
- package/esm2015/lib/modules/sectioned-form/sectioned-form.component.js.map +0 -1
- package/esm2015/lib/modules/sectioned-form/sectioned-form.module.js +0 -35
- package/esm2015/lib/modules/sectioned-form/sectioned-form.module.js.map +0 -1
- package/esm2015/lib/modules/sectioned-form/sectioned-form.service.js +0 -35
- package/esm2015/lib/modules/sectioned-form/sectioned-form.service.js.map +0 -1
- package/esm2015/lib/modules/shared/sky-tabs-resources.module.js +0 -52
- package/esm2015/lib/modules/shared/sky-tabs-resources.module.js.map +0 -1
- package/esm2015/lib/modules/tabs/tab-button.component.js +0 -76
- package/esm2015/lib/modules/tabs/tab-button.component.js.map +0 -1
- package/esm2015/lib/modules/tabs/tab-index.js +0 -2
- package/esm2015/lib/modules/tabs/tab-index.js.map +0 -1
- package/esm2015/lib/modules/tabs/tab.component.js +0 -135
- package/esm2015/lib/modules/tabs/tab.component.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabs.module.js +0 -57
- package/esm2015/lib/modules/tabs/tabs.module.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-active-tab-unregistered-args.js +0 -2
- package/esm2015/lib/modules/tabs/tabset-active-tab-unregistered-args.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-adapter.service.js +0 -56
- package/esm2015/lib/modules/tabs/tabset-adapter.service.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-buttons-display-mode.js +0 -2
- package/esm2015/lib/modules/tabs/tabset-buttons-display-mode.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-nav-button.component.js +0 -119
- package/esm2015/lib/modules/tabs/tabset-nav-button.component.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-permalink.service.js +0 -126
- package/esm2015/lib/modules/tabs/tabset-permalink.service.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-style.js +0 -2
- package/esm2015/lib/modules/tabs/tabset-style.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset-tab-indexes-change.js +0 -2
- package/esm2015/lib/modules/tabs/tabset-tab-indexes-change.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset.component.js +0 -407
- package/esm2015/lib/modules/tabs/tabset.component.js.map +0 -1
- package/esm2015/lib/modules/tabs/tabset.service.js +0 -110
- package/esm2015/lib/modules/tabs/tabset.service.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tab-media-query.service.js +0 -72
- package/esm2015/lib/modules/vertical-tabset/vertical-tab-media-query.service.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tab.component.js +0 -203
- package/esm2015/lib/modules/vertical-tabset/vertical-tab.component.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset-adapter.service.js +0 -48
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset-adapter.service.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset-group.component.js +0 -89
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset-group.component.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.component.js +0 -157
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.component.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.module.js +0 -60
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.module.js.map +0 -1
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.service.js +0 -170
- package/esm2015/lib/modules/vertical-tabset/vertical-tabset.service.js.map +0 -1
- package/esm2015/skyux-tabs.js +0 -5
- package/esm2015/skyux-tabs.js.map +0 -1
- package/esm2015/testing/public-api.js +0 -3
- package/esm2015/testing/public-api.js.map +0 -1
- package/esm2015/testing/skyux-tabs-testing.js +0 -5
- package/esm2015/testing/skyux-tabs-testing.js.map +0 -1
- package/esm2015/testing/tabs/tab-fixture-tab.js +0 -2
- package/esm2015/testing/tabs/tab-fixture-tab.js.map +0 -1
- package/esm2015/testing/tabs/tabset-fixture.js.map +0 -1
- package/fesm2015/skyux-tabs-testing.js.map +0 -1
- package/fesm2015/skyux-tabs.js.map +0 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, Output, QueryList, ViewEncapsulation, } from '@angular/core';
|
|
2
|
+
import { Subject, combineLatest, race } from 'rxjs';
|
|
3
|
+
import { distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
4
|
+
import { SkyTabComponent } from './tab.component';
|
|
5
|
+
import { SkyTabsetAdapterService } from './tabset-adapter.service';
|
|
6
|
+
import { SkyTabsetPermalinkService } from './tabset-permalink.service';
|
|
7
|
+
import { SkyTabsetService } from './tabset.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "./tabset-adapter.service";
|
|
10
|
+
import * as i2 from "./tabset-permalink.service";
|
|
11
|
+
import * as i3 from "./tabset.service";
|
|
12
|
+
import * as i4 from "@skyux/popovers";
|
|
13
|
+
import * as i5 from "@skyux/indicators";
|
|
14
|
+
import * as i6 from "./tab-button.component";
|
|
15
|
+
import * as i7 from "@angular/common";
|
|
16
|
+
import * as i8 from "@skyux/theme";
|
|
17
|
+
import * as i9 from "@skyux/i18n";
|
|
18
|
+
export class SkyTabsetComponent {
|
|
19
|
+
constructor(changeDetector, elementRef, adapterService, permalinkService, tabsetService) {
|
|
20
|
+
this.changeDetector = changeDetector;
|
|
21
|
+
this.elementRef = elementRef;
|
|
22
|
+
this.adapterService = adapterService;
|
|
23
|
+
this.permalinkService = permalinkService;
|
|
24
|
+
this.tabsetService = tabsetService;
|
|
25
|
+
/**
|
|
26
|
+
* Fires when the active tab changes. This event emits the index of the active tab.
|
|
27
|
+
*/
|
|
28
|
+
this.activeChange = new EventEmitter();
|
|
29
|
+
/**
|
|
30
|
+
* Fires when users click the button to add a new tab.
|
|
31
|
+
* The new tab button is added to the tab area when you specify a listener for this event.
|
|
32
|
+
*/
|
|
33
|
+
this.newTab = new EventEmitter();
|
|
34
|
+
/**
|
|
35
|
+
* Fires when users click the button to open a tab.
|
|
36
|
+
* The open tab button is added to the tab area when you specify a listener for this event.
|
|
37
|
+
*/
|
|
38
|
+
this.openTab = new EventEmitter();
|
|
39
|
+
/**
|
|
40
|
+
* Fires when any tab's `tabIndex` value changes.
|
|
41
|
+
*/
|
|
42
|
+
this.tabIndexesChange = new EventEmitter();
|
|
43
|
+
this.tabButtons = [];
|
|
44
|
+
this.ngUnsubscribe = new Subject();
|
|
45
|
+
this.tabComponentsStateChangeUnsubscribe = new Subject();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Activates a tab by its `tabIndex` property.
|
|
49
|
+
*/
|
|
50
|
+
set active(value) {
|
|
51
|
+
if (value === undefined ||
|
|
52
|
+
this.tabsetService.tabIndexesEqual(value, this._active)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this._active = value;
|
|
56
|
+
if (this.tabs) {
|
|
57
|
+
this.tabsetService.setActiveTabIndex(value);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// On init, wait for children tabs to render before broadcasting the active tab index.
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
if (this.tabsetService.isValidTabIndex(value)) {
|
|
63
|
+
// On init, yield to the permalink ID, if it exists.
|
|
64
|
+
if (this.getActiveTabIndexByPermalinkId() === undefined) {
|
|
65
|
+
this.tabsetService.setActiveTabIndex(value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Activate the first tab if the new tab index is invalid.
|
|
70
|
+
this._active = this.tabsetService.activateFirstTab();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
get active() {
|
|
76
|
+
return this._active;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Distinguishes a tabset's unique state in the URL by generating a query parameter
|
|
80
|
+
* that is written as `?<queryParam>-active-tab=<sanitized-tab-heading>`.
|
|
81
|
+
* The query parameter's value is parsed automatically from the selected tab's heading text,
|
|
82
|
+
* but you can supply a custom query parameter value for each tab with its `permalinkValue`.
|
|
83
|
+
*/
|
|
84
|
+
set permalinkId(value) {
|
|
85
|
+
if (!value) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const sanitized = this.permalinkService.urlify(value);
|
|
89
|
+
this._permalinkId = `${sanitized}-active-tab`;
|
|
90
|
+
}
|
|
91
|
+
get permalinkId() {
|
|
92
|
+
return this._permalinkId || '';
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Specifies the behavior for a series of tabs.
|
|
96
|
+
* @deprecated The property was designed to create wizards by setting tabStyle="wizard" on tabsets in modals,
|
|
97
|
+
* but this wizard implementation was replaced by the
|
|
98
|
+
* [progress indicator component](https://developer.blackbaud.com/skyux/components/progress-indicator).
|
|
99
|
+
* @default "tabs"
|
|
100
|
+
*/
|
|
101
|
+
set tabStyle(value) {
|
|
102
|
+
/*istanbul ignore else*/
|
|
103
|
+
if (value && value.toLowerCase() === 'wizard') {
|
|
104
|
+
console.warn('The tabset wizard is deprecated. Please implement the new approach using ' +
|
|
105
|
+
'progress indicator as documented here: https://developer.blackbaud.com/skyux/components/wizard.');
|
|
106
|
+
}
|
|
107
|
+
this._tabStyle = value;
|
|
108
|
+
}
|
|
109
|
+
get tabStyle() {
|
|
110
|
+
return this._tabStyle || 'tabs';
|
|
111
|
+
}
|
|
112
|
+
set tabDisplayMode(value) {
|
|
113
|
+
this._tabDisplayMode = value;
|
|
114
|
+
this.changeDetector.markForCheck();
|
|
115
|
+
}
|
|
116
|
+
get tabDisplayMode() {
|
|
117
|
+
return this._tabDisplayMode || 'tabs';
|
|
118
|
+
}
|
|
119
|
+
ngAfterViewInit() {
|
|
120
|
+
this.initTabComponents();
|
|
121
|
+
this.listenTabComponentsStructuralChange();
|
|
122
|
+
const initialTabIndex = this.getInitialTabIndex();
|
|
123
|
+
this.tabsetService.setActiveTabIndex(initialTabIndex);
|
|
124
|
+
this.listenTabButtonsOverflowChange();
|
|
125
|
+
this.listenLocationPopStateChange();
|
|
126
|
+
// If the currently active tab is getting unregistered, activate the next one.
|
|
127
|
+
this.tabsetService.activeTabUnregistered
|
|
128
|
+
.pipe(takeUntil(this.ngUnsubscribe))
|
|
129
|
+
.subscribe((tab) => {
|
|
130
|
+
// Wait for the new tabs to render before activating.
|
|
131
|
+
setTimeout(() => {
|
|
132
|
+
this.tabsetService.activateNearestTab(tab.arrayIndex);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// Let the tabset render the initial active index before listening for changes.
|
|
136
|
+
setTimeout(() => {
|
|
137
|
+
this.listenTabComponentsStateChange();
|
|
138
|
+
this.listenActiveIndexChange();
|
|
139
|
+
this.permalinkService.init();
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
ngOnDestroy() {
|
|
143
|
+
this.ngUnsubscribe.next();
|
|
144
|
+
this.ngUnsubscribe.complete();
|
|
145
|
+
this.unsubscribeTabComponentsStateChange();
|
|
146
|
+
if (this.permalinkId) {
|
|
147
|
+
this.permalinkService.clearParam(this.permalinkId);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
onWindowResize() {
|
|
151
|
+
this.adapterService.detectOverflow();
|
|
152
|
+
}
|
|
153
|
+
onTabCloseClick(tabButton) {
|
|
154
|
+
const tabComponent = this.tabs.find((tab) => this.tabsetService.tabIndexesEqual(tab.tabIndex, tabButton.tabIndex));
|
|
155
|
+
tabComponent.close.emit();
|
|
156
|
+
}
|
|
157
|
+
onTabButtonClick(tabButton) {
|
|
158
|
+
this.tabsetService.setActiveTabIndex(tabButton.tabIndex);
|
|
159
|
+
}
|
|
160
|
+
onNewTabClick() {
|
|
161
|
+
this.newTab.emit();
|
|
162
|
+
}
|
|
163
|
+
onOpenTabClick() {
|
|
164
|
+
this.openTab.emit();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Sets the initial active tab index based on the following criteria.
|
|
168
|
+
* 1. Does the URL include a query param that reflects this tabset's active tab?
|
|
169
|
+
* 2. Does one of the tab components have their `active` property set to `true`?
|
|
170
|
+
* 3. Is the tabset component's `active` property set to a specific tab index?
|
|
171
|
+
*/
|
|
172
|
+
getInitialTabIndex() {
|
|
173
|
+
let activeIndex = this.getActiveTabIndexByPermalinkId();
|
|
174
|
+
if (activeIndex === undefined) {
|
|
175
|
+
activeIndex = this.getActiveTabComponent()?.tabIndex;
|
|
176
|
+
if (activeIndex === undefined) {
|
|
177
|
+
activeIndex = this.active;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return activeIndex;
|
|
181
|
+
}
|
|
182
|
+
listenActiveIndexChange() {
|
|
183
|
+
this.tabsetService.activeTabIndex
|
|
184
|
+
.pipe(distinctUntilChanged(), takeUntil(this.ngUnsubscribe))
|
|
185
|
+
.subscribe((activeIndex) => {
|
|
186
|
+
this.updateTabsetComponent(activeIndex);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
listenTabComponentsStructuralChange() {
|
|
190
|
+
this.tabs.changes.pipe(takeUntil(this.ngUnsubscribe)).subscribe(() => {
|
|
191
|
+
this.resetTabComponents();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
listenTabComponentsStateChange() {
|
|
195
|
+
combineLatest(this.tabs.map((tab) => tab.activeChange))
|
|
196
|
+
.pipe(takeUntil(race(this.tabComponentsStateChangeUnsubscribe, this.ngUnsubscribe)))
|
|
197
|
+
.subscribe(() => {
|
|
198
|
+
// Wait for the tab components to render changes before finding the active one.
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
const tabIndex = this.getActiveTabComponent()?.tabIndex;
|
|
201
|
+
this.tabsetService.setActiveTabIndex(tabIndex);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
combineLatest(this.tabs.map((tab) => tab.tabIndexChange))
|
|
205
|
+
.pipe(takeUntil(race(this.tabComponentsStateChangeUnsubscribe, this.ngUnsubscribe)))
|
|
206
|
+
.subscribe(() => {
|
|
207
|
+
// Don't emit the first change.
|
|
208
|
+
if (this.lastActiveTabIndex !== undefined) {
|
|
209
|
+
// Wait for the tab components to render changes before updating the view.
|
|
210
|
+
setTimeout(() => {
|
|
211
|
+
this.updateTabsetComponent(this.tabsetService.currentActiveTabIndex, true);
|
|
212
|
+
this.emitTabIndexChange();
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
combineLatest(this.tabs.map((tab) => tab.stateChange))
|
|
217
|
+
.pipe(takeUntil(race(this.tabComponentsStateChangeUnsubscribe, this.ngUnsubscribe)))
|
|
218
|
+
.subscribe(() => {
|
|
219
|
+
// Wait for the tab components to render changes before finding the active one.
|
|
220
|
+
setTimeout(() => {
|
|
221
|
+
this.updateTabsetComponent(this.tabsetService.currentActiveTabIndex, true);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
initTabComponents() {
|
|
226
|
+
this.tabs.forEach((tab) => tab.init());
|
|
227
|
+
}
|
|
228
|
+
resetTabComponents() {
|
|
229
|
+
this.unsubscribeTabComponentsStateChange();
|
|
230
|
+
this.tabsetService.unregisterAll();
|
|
231
|
+
// If there are no tab components, do a hard reset of the view.
|
|
232
|
+
if (this.tabs.length === 0) {
|
|
233
|
+
this.updateTabsetComponent(0, true);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
this.initTabComponents();
|
|
237
|
+
const activeIndex = this.getActiveTabComponent()?.tabIndex;
|
|
238
|
+
this.tabsetService.setActiveTabIndex(activeIndex, {
|
|
239
|
+
emitChange: false,
|
|
240
|
+
});
|
|
241
|
+
this.listenTabComponentsStateChange();
|
|
242
|
+
}
|
|
243
|
+
emitTabIndexChange() {
|
|
244
|
+
this.tabIndexesChange.emit({
|
|
245
|
+
tabs: this.tabs.map((tab) => ({
|
|
246
|
+
tabHeading: tab.tabHeading,
|
|
247
|
+
tabIndex: tab.tabIndex,
|
|
248
|
+
})),
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
unsubscribeTabComponentsStateChange() {
|
|
252
|
+
this.tabComponentsStateChangeUnsubscribe.next();
|
|
253
|
+
this.tabComponentsStateChangeUnsubscribe.complete();
|
|
254
|
+
this.tabComponentsStateChangeUnsubscribe = new Subject();
|
|
255
|
+
}
|
|
256
|
+
listenTabButtonsOverflowChange() {
|
|
257
|
+
this.adapterService.registerTabset(this.elementRef);
|
|
258
|
+
this.adapterService.overflowChange
|
|
259
|
+
.pipe(takeUntil(this.ngUnsubscribe))
|
|
260
|
+
.subscribe((isOverflowing) => {
|
|
261
|
+
this.tabDisplayMode = isOverflowing ? 'dropdown' : 'tabs';
|
|
262
|
+
this.changeDetector.markForCheck();
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Listen for back/forward history button presses to detect query param changes in the URL.
|
|
267
|
+
*/
|
|
268
|
+
listenLocationPopStateChange() {
|
|
269
|
+
this.permalinkService.popStateChange
|
|
270
|
+
.pipe(takeUntil(this.ngUnsubscribe))
|
|
271
|
+
.subscribe(() => {
|
|
272
|
+
this.setActiveTabIndexByPermalinkId();
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
setActiveTabIndexByPermalinkId() {
|
|
276
|
+
const activeIndex = this.getActiveTabIndexByPermalinkId();
|
|
277
|
+
this.tabsetService.setActiveTabIndex(activeIndex);
|
|
278
|
+
}
|
|
279
|
+
getActiveTabIndexByPermalinkId() {
|
|
280
|
+
if (this.permalinkId) {
|
|
281
|
+
const paramValue = this.permalinkService.getParam(this.permalinkId);
|
|
282
|
+
if (paramValue) {
|
|
283
|
+
return this.tabs.find((tab) => tab.permalinkValue === paramValue)
|
|
284
|
+
?.tabIndex;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
getActiveTabComponent() {
|
|
289
|
+
return this.tabs
|
|
290
|
+
.toArray()
|
|
291
|
+
.reverse()
|
|
292
|
+
.find((tab) => tab.active === true);
|
|
293
|
+
}
|
|
294
|
+
createTabButtons(activeIndex) {
|
|
295
|
+
return this.tabs.map((tab) => ({
|
|
296
|
+
active: this.tabsetService.tabIndexesEqual(tab.tabIndex, activeIndex),
|
|
297
|
+
closeable: tab.closeable,
|
|
298
|
+
ariaControls: tab.tabPanelId,
|
|
299
|
+
disabled: tab.disabled,
|
|
300
|
+
buttonHref: tab.disabled
|
|
301
|
+
? null
|
|
302
|
+
: this.permalinkService.getParamHref(this.permalinkId, tab.permalinkValue),
|
|
303
|
+
buttonId: tab.tabButtonId,
|
|
304
|
+
buttonTextCount: tab.tabHeaderCount,
|
|
305
|
+
buttonText: tab.tabHeading,
|
|
306
|
+
tabIndex: tab.tabIndex,
|
|
307
|
+
}));
|
|
308
|
+
}
|
|
309
|
+
updateTabButtons(activeIndex) {
|
|
310
|
+
this.tabButtons.forEach((button) => {
|
|
311
|
+
button.active = this.tabsetService.tabIndexesEqual(button.tabIndex, activeIndex);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Updates the UI and state of the tabset component after the tab index or
|
|
316
|
+
* tab components have changed.
|
|
317
|
+
* @param activeIndex The currently active tab index.
|
|
318
|
+
* @param regenerateTabButtons Indicates if tab button view models should be regenerated.
|
|
319
|
+
* Setting this value to `false` will simply update the existing tab buttons. Setting this value
|
|
320
|
+
* to `true` is only necessary when the underlying tab components have changed and the tab
|
|
321
|
+
* buttons must reflect those changes.
|
|
322
|
+
*/
|
|
323
|
+
updateTabsetComponent(activeIndex, regenerateTabButtons = false) {
|
|
324
|
+
// Activate/deactivate tab components.
|
|
325
|
+
this.tabs.forEach((tab) => {
|
|
326
|
+
this.tabsetService.tabIndexesEqual(tab.tabIndex, activeIndex)
|
|
327
|
+
? tab.activate()
|
|
328
|
+
: tab.deactivate();
|
|
329
|
+
});
|
|
330
|
+
// Update the tab button models.
|
|
331
|
+
if (regenerateTabButtons || !this.tabButtons.length) {
|
|
332
|
+
this.tabButtons = this.createTabButtons(activeIndex);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.updateTabButtons(activeIndex);
|
|
336
|
+
}
|
|
337
|
+
// Update the dropdown trigger button text.
|
|
338
|
+
this.dropdownTriggerButtonText = this.tabButtons.find((b) => {
|
|
339
|
+
return this.tabsetService.tabIndexesEqual(b.tabIndex, activeIndex);
|
|
340
|
+
})?.buttonText;
|
|
341
|
+
// Set the query params based on active tab.
|
|
342
|
+
if (this.permalinkId) {
|
|
343
|
+
const activeTabComponent = this.tabs.find((tab) => {
|
|
344
|
+
return this.tabsetService.tabIndexesEqual(tab.tabIndex, activeIndex);
|
|
345
|
+
});
|
|
346
|
+
this.permalinkService.setParam(this.permalinkId, activeTabComponent.permalinkValue);
|
|
347
|
+
}
|
|
348
|
+
// Wait for tab button view models to render before gauging dimensions.
|
|
349
|
+
setTimeout(() => {
|
|
350
|
+
this.adapterService.detectOverflow();
|
|
351
|
+
});
|
|
352
|
+
this.changeDetector.markForCheck();
|
|
353
|
+
// Emit the new active index value to consumers.
|
|
354
|
+
if (this.lastActiveTabIndex !== activeIndex) {
|
|
355
|
+
this.lastActiveTabIndex = activeIndex;
|
|
356
|
+
this.activeChange.emit(activeIndex);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
SkyTabsetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTabsetComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.SkyTabsetAdapterService }, { token: i2.SkyTabsetPermalinkService }, { token: i3.SkyTabsetService }], target: i0.ɵɵFactoryTarget.Component });
|
|
361
|
+
SkyTabsetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: SkyTabsetComponent, selector: "sky-tabset", inputs: { active: "active", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", permalinkId: "permalinkId", tabStyle: "tabStyle" }, outputs: { activeChange: "activeChange", newTab: "newTab", openTab: "openTab", tabIndexesChange: "tabIndexesChange" }, providers: [
|
|
362
|
+
SkyTabsetAdapterService,
|
|
363
|
+
SkyTabsetPermalinkService,
|
|
364
|
+
SkyTabsetService,
|
|
365
|
+
], queries: [{ propertyName: "tabs", predicate: SkyTabComponent }], ngImport: i0, template: "<div\n class=\"sky-tabset\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [ngClass]=\"\n 'sky-tabset-mode-' + tabDisplayMode + ' sky-tabset-style-' + tabStyle\n \"\n (window:resize)=\"onWindowResize()\"\n>\n <span class=\"sky-tabset-dropdown\">\n <sky-dropdown *ngIf=\"tabDisplayMode === 'dropdown'\" buttonType=\"tab\">\n <sky-dropdown-button>\n {{ dropdownTriggerButtonText }}\n </sky-dropdown-button>\n <sky-dropdown-menu>\n <sky-dropdown-item\n *ngFor=\"let tabButton of tabButtons\"\n class=\"sky-tab-dropdown-menu-item\"\n >\n <div\n class=\"sky-tab-dropdown-item\"\n [ngClass]=\"{\n 'sky-tab-dropdown-item-selected': tabButton.active\n }\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n tabButtonTemplate;\n context: {\n $implicit: tabButton\n }\n \"\n ></ng-container>\n </div>\n </sky-dropdown-item>\n </sky-dropdown-menu>\n </sky-dropdown>\n </span>\n <span class=\"sky-tabset-tabs\">\n <ng-container *ngFor=\"let tabButton of tabButtons\">\n <ng-container\n *ngTemplateOutlet=\"\n tabButtonTemplate;\n context: {\n $implicit: tabButton\n }\n \"\n ></ng-container>\n </ng-container>\n </span>\n <span class=\"sky-tabset-btns\">\n <button\n *ngIf=\"newTab.observers.length > 0\"\n class=\"sky-btn sky-btn-icon sky-tabset-btn-new sky-margin-inline-compact\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_tab_add' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern'\n }\"\n (click)=\"onNewTabClick()\"\n >\n <sky-icon icon=\"plus-circle\" size=\"lg\"> </sky-icon>\n </button>\n <button\n *ngIf=\"openTab.observers.length > 0\"\n class=\"sky-btn sky-btn-icon sky-tabset-btn-open sky-margin-inline-compact\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_tab_open' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern'\n }\"\n (click)=\"onOpenTabClick()\"\n >\n <sky-icon icon=\"folder-open-o\" size=\"lg\"> </sky-icon>\n </button>\n </span>\n</div>\n<ng-content></ng-content>\n\n<ng-template let-tabButton #tabButtonTemplate>\n <sky-tab-button\n [active]=\"tabButton.active\"\n [ariaControls]=\"tabButton.ariaControls\"\n [buttonHref]=\"tabButton.buttonHref\"\n [buttonId]=\"tabButton.buttonId\"\n [buttonText]=\"tabButton.buttonText\"\n [buttonTextCount]=\"tabButton.buttonTextCount\"\n [closeable]=\"tabButton.closeable\"\n [disabled]=\"tabButton.disabled\"\n [tabStyle]=\"tabStyle\"\n (buttonClick)=\"onTabButtonClick(tabButton)\"\n (closeClick)=\"onTabCloseClick(tabButton)\"\n ></sky-tab-button>\n</ng-template>\n", styles: [".sky-tabset{align-items:center;border-bottom:2px solid #0974a1;display:flex;list-style-type:none;margin:0;overflow:hidden;padding:0 0 0 15px;white-space:nowrap}.sky-tabset.sky-tabset-style-wizard{border-bottom:none;padding-bottom:10px;padding-left:0}.sky-tabset-btns{order:1;padding-left:10px}.sky-tabset-dropdown{order:0;max-width:100%}.sky-tabset-mode-dropdown{line-height:0}.sky-tabset-mode-dropdown .sky-tabset-tabs{visibility:hidden;order:2}.sky-tab-dropdown-menu-item sky-tab-button{display:flex;min-width:300px}.sky-tab-dropdown-menu-item .sky-dropdown-item{margin:0}.sky-tab-dropdown-menu-item .sky-btn-tab-wrapper{width:100%;margin-right:0}.sky-tab-dropdown-menu-item .sky-btn-tab{margin:0;border-radius:0;width:100%;display:flex}.sky-tab-dropdown-menu-item .sky-btn-tab>.sky-tab-heading{flex:1 1 auto}.sky-tab-dropdown-menu-item .sky-btn-tab>.sky-btn-tab-close{flex:0 1 auto}.sky-tabset-tabs{order:0;white-space:nowrap}.sky-tabset-btn-new,.sky-tabset-btn-open{color:#0974a1}.sky-theme-modern .sky-tabset{border-bottom:1px solid #d2d2d2;overflow:visible}.sky-theme-modern .sky-tab-dropdown-menu-item .sky-btn-tab-wrapper{margin-right:0}\n"], components: [{ type: i4.λ3, selector: "sky-dropdown", inputs: ["buttonStyle", "buttonType", "disabled", "dismissOnBlur", "label", "horizontalAlignment", "messageStream", "title", "trigger"] }, { type: i4.λ2, selector: "sky-dropdown-button" }, { type: i4.λ4, selector: "sky-dropdown-menu", inputs: ["ariaLabelledBy", "ariaRole", "useNativeFocus"], outputs: ["menuChanges"] }, { type: i4.λ1, selector: "sky-dropdown-item", inputs: ["ariaRole"] }, { type: i5.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { type: i6.SkyTabButtonComponent, selector: "sky-tab-button", inputs: ["active", "ariaControls", "buttonHref", "buttonId", "buttonText", "buttonTextCount", "closeable", "disabled", "tabStyle"], outputs: ["buttonClick", "closeClick"] }], directives: [{ type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }], pipes: { "skyLibResources": i9.SkyLibResourcesPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
366
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTabsetComponent, decorators: [{
|
|
367
|
+
type: Component,
|
|
368
|
+
args: [{ selector: 'sky-tabset', providers: [
|
|
369
|
+
SkyTabsetAdapterService,
|
|
370
|
+
SkyTabsetPermalinkService,
|
|
371
|
+
SkyTabsetService,
|
|
372
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"sky-tabset\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [ngClass]=\"\n 'sky-tabset-mode-' + tabDisplayMode + ' sky-tabset-style-' + tabStyle\n \"\n (window:resize)=\"onWindowResize()\"\n>\n <span class=\"sky-tabset-dropdown\">\n <sky-dropdown *ngIf=\"tabDisplayMode === 'dropdown'\" buttonType=\"tab\">\n <sky-dropdown-button>\n {{ dropdownTriggerButtonText }}\n </sky-dropdown-button>\n <sky-dropdown-menu>\n <sky-dropdown-item\n *ngFor=\"let tabButton of tabButtons\"\n class=\"sky-tab-dropdown-menu-item\"\n >\n <div\n class=\"sky-tab-dropdown-item\"\n [ngClass]=\"{\n 'sky-tab-dropdown-item-selected': tabButton.active\n }\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n tabButtonTemplate;\n context: {\n $implicit: tabButton\n }\n \"\n ></ng-container>\n </div>\n </sky-dropdown-item>\n </sky-dropdown-menu>\n </sky-dropdown>\n </span>\n <span class=\"sky-tabset-tabs\">\n <ng-container *ngFor=\"let tabButton of tabButtons\">\n <ng-container\n *ngTemplateOutlet=\"\n tabButtonTemplate;\n context: {\n $implicit: tabButton\n }\n \"\n ></ng-container>\n </ng-container>\n </span>\n <span class=\"sky-tabset-btns\">\n <button\n *ngIf=\"newTab.observers.length > 0\"\n class=\"sky-btn sky-btn-icon sky-tabset-btn-new sky-margin-inline-compact\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_tab_add' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern'\n }\"\n (click)=\"onNewTabClick()\"\n >\n <sky-icon icon=\"plus-circle\" size=\"lg\"> </sky-icon>\n </button>\n <button\n *ngIf=\"openTab.observers.length > 0\"\n class=\"sky-btn sky-btn-icon sky-tabset-btn-open sky-margin-inline-compact\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_tab_open' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern'\n }\"\n (click)=\"onOpenTabClick()\"\n >\n <sky-icon icon=\"folder-open-o\" size=\"lg\"> </sky-icon>\n </button>\n </span>\n</div>\n<ng-content></ng-content>\n\n<ng-template let-tabButton #tabButtonTemplate>\n <sky-tab-button\n [active]=\"tabButton.active\"\n [ariaControls]=\"tabButton.ariaControls\"\n [buttonHref]=\"tabButton.buttonHref\"\n [buttonId]=\"tabButton.buttonId\"\n [buttonText]=\"tabButton.buttonText\"\n [buttonTextCount]=\"tabButton.buttonTextCount\"\n [closeable]=\"tabButton.closeable\"\n [disabled]=\"tabButton.disabled\"\n [tabStyle]=\"tabStyle\"\n (buttonClick)=\"onTabButtonClick(tabButton)\"\n (closeClick)=\"onTabCloseClick(tabButton)\"\n ></sky-tab-button>\n</ng-template>\n", styles: [".sky-tabset{align-items:center;border-bottom:2px solid #0974a1;display:flex;list-style-type:none;margin:0;overflow:hidden;padding:0 0 0 15px;white-space:nowrap}.sky-tabset.sky-tabset-style-wizard{border-bottom:none;padding-bottom:10px;padding-left:0}.sky-tabset-btns{order:1;padding-left:10px}.sky-tabset-dropdown{order:0;max-width:100%}.sky-tabset-mode-dropdown{line-height:0}.sky-tabset-mode-dropdown .sky-tabset-tabs{visibility:hidden;order:2}.sky-tab-dropdown-menu-item sky-tab-button{display:flex;min-width:300px}.sky-tab-dropdown-menu-item .sky-dropdown-item{margin:0}.sky-tab-dropdown-menu-item .sky-btn-tab-wrapper{width:100%;margin-right:0}.sky-tab-dropdown-menu-item .sky-btn-tab{margin:0;border-radius:0;width:100%;display:flex}.sky-tab-dropdown-menu-item .sky-btn-tab>.sky-tab-heading{flex:1 1 auto}.sky-tab-dropdown-menu-item .sky-btn-tab>.sky-btn-tab-close{flex:0 1 auto}.sky-tabset-tabs{order:0;white-space:nowrap}.sky-tabset-btn-new,.sky-tabset-btn-open{color:#0974a1}.sky-theme-modern .sky-tabset{border-bottom:1px solid #d2d2d2;overflow:visible}.sky-theme-modern .sky-tab-dropdown-menu-item .sky-btn-tab-wrapper{margin-right:0}\n"] }]
|
|
373
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.SkyTabsetAdapterService }, { type: i2.SkyTabsetPermalinkService }, { type: i3.SkyTabsetService }]; }, propDecorators: { active: [{
|
|
374
|
+
type: Input
|
|
375
|
+
}], ariaLabel: [{
|
|
376
|
+
type: Input
|
|
377
|
+
}], ariaLabelledBy: [{
|
|
378
|
+
type: Input
|
|
379
|
+
}], permalinkId: [{
|
|
380
|
+
type: Input
|
|
381
|
+
}], tabStyle: [{
|
|
382
|
+
type: Input
|
|
383
|
+
}], activeChange: [{
|
|
384
|
+
type: Output
|
|
385
|
+
}], newTab: [{
|
|
386
|
+
type: Output
|
|
387
|
+
}], openTab: [{
|
|
388
|
+
type: Output
|
|
389
|
+
}], tabIndexesChange: [{
|
|
390
|
+
type: Output
|
|
391
|
+
}], tabs: [{
|
|
392
|
+
type: ContentChildren,
|
|
393
|
+
args: [SkyTabComponent]
|
|
394
|
+
}] } });
|
|
395
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29tcG9uZW50cy90YWJzL3NyYy9saWIvbW9kdWxlcy90YWJzL3RhYnNldC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvdGFicy9zcmMvbGliL21vZHVsZXMvdGFicy90YWJzZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR2pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVuRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUd2RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQzs7Ozs7Ozs7Ozs7QUE2QnBELE1BQU0sT0FBTyxrQkFBa0I7SUE4SjdCLFlBQ1UsY0FBaUMsRUFDakMsVUFBc0IsRUFDdEIsY0FBdUMsRUFDdkMsZ0JBQTJDLEVBQzNDLGFBQStCO1FBSi9CLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNqQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLG1CQUFjLEdBQWQsY0FBYyxDQUF5QjtRQUN2QyxxQkFBZ0Is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QUFjLEVBQUUsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbkMsZ0RBQWdEO1FBQ2hELElBQUksSUFBSSxDQUFDLGtCQUFrQixLQUFLLFdBQVcsRUFBRTtZQUMzQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsV0FBVyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ3JDO0lBQ0gsQ0FBQzs7K0dBMWRVLGtCQUFrQjttR0FBbEIsa0JBQWtCLHNTQVJsQjtRQUNULHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIsZ0JBQWdCO0tBQ2pCLCtDQXlJZ0IsZUFBZSw2QkMzTGxDLG84RkErRkE7MkZEekNhLGtCQUFrQjtrQkFaOUIsU0FBUzsrQkFDRSxZQUFZLGFBR1g7d0JBQ1QsdUJBQXVCO3dCQUN2Qix5QkFBeUI7d0JBQ3pCLGdCQUFnQjtxQkFDakIsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU0saUJBQ2hDLGlCQUFpQixDQUFDLElBQUk7OE9BTzFCLE1BQU07c0JBRGhCLEtBQUs7Z0JBdUNDLFNBQVM7c0JBRGYsS0FBSztnQkFVQyxjQUFjO3NCQURwQixLQUFLO2dCQVVLLFdBQVc7c0JBRHJCLEtBQUs7Z0JBc0JLLFFBQVE7c0JBRGxCLEtBQUs7Z0JBcUJDLFlBQVk7c0JBRGxCLE1BQU07Z0JBUUEsTUFBTTtzQkFEWixNQUFNO2dCQVFBLE9BQU87c0JBRGIsTUFBTTtnQkFPQSxnQkFBZ0I7c0JBRHRCLE1BQU07Z0JBYUEsSUFBSTtzQkFEVixlQUFlO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIHJhY2UgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFNreVRhYkluZGV4IH0gZnJvbSAnLi90YWItaW5kZXgnO1xuaW1wb3J0IHsgU2t5VGFiQ29tcG9uZW50IH0gZnJvbSAnLi90YWIuY29tcG9uZW50JztcbmltcG9ydCB7IFNreVRhYnNldEFkYXB0ZXJTZXJ2aWNlIH0gZnJvbSAnLi90YWJzZXQtYWRhcHRlci5zZXJ2aWNlJztcbmltcG9ydCB7IFNreVRhYnNldEJ1dHRvbnNEaXNwbGF5TW9kZSB9IGZyb20gJy4vdGFic2V0LWJ1dHRvbnMtZGlzcGxheS1tb2RlJztcbmltcG9ydCB7IFNreVRhYnNldFBlcm1hbGlua1NlcnZpY2UgfSBmcm9tICcuL3RhYnNldC1wZXJtYWxpbmsuc2VydmljZSc7XG5pbXBvcnQgeyBTa3lUYWJzZXRTdHlsZSB9IGZyb20gJy4vdGFic2V0LXN0eWxlJztcbmltcG9ydCB7IFNreVRhYnNldFRhYkluZGV4ZXNDaGFuZ2UgfSBmcm9tICcuL3RhYnNldC10YWItaW5kZXhlcy1jaGFuZ2UnO1xuaW1wb3J0IHsgU2t5VGFic2V0U2VydmljZSB9IGZyb20gJy4vdGFic2V0LnNlcnZpY2UnO1xuXG4vKipcbiAqIEBpbnRlcm5hbFxuICovXG5pbnRlcmZhY2UgVGFiQnV0dG9uVmlld01vZGVsIHtcbiAgYWN0aXZlOiBib29sZWFuO1xuICBhcmlhQ29udHJvbHM6IHN0cmluZztcbiAgYnV0dG9uSHJlZjogc3RyaW5nO1xuICBidXR0b25JZDogc3RyaW5nO1xuICBidXR0b25UZXh0OiBzdHJpbmc7XG4gIGJ1dHRvblRleHRDb3VudDogc3RyaW5nO1xuICBjbG9zZWFibGU6IGJvb2xlYW47XG4gIGRpc2FibGVkOiBib29sZWFuO1xuICB0YWJJbmRleDogU2t5VGFiSW5kZXg7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NreS10YWJzZXQnLFxuICBzdHlsZVVybHM6IFsnLi90YWJzZXQuY29tcG9uZW50LnNjc3MnXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYnNldC5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIFNreVRhYnNldEFkYXB0ZXJTZXJ2aWNlLFxuICAgIFNreVRhYnNldFBlcm1hbGlua1NlcnZpY2UsXG4gICAgU2t5VGFic2V0U2VydmljZSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIFNreVRhYnNldENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBBY3RpdmF0ZXMgYSB0YWIgYnkgaXRzIGB0YWJJbmRleGAgcHJvcGVydHkuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IGFjdGl2ZSh2YWx1ZTogU2t5VGFiSW5kZXgpIHtcbiAgICBpZiAoXG4gICAgICB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICB0aGlzLnRhYnNldFNlcnZpY2UudGFiSW5kZXhlc0VxdWFsKHZhbHVlLCB0aGlzLl9hY3RpdmUpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZlID0gdmFsdWU7XG5cbiAgICBpZiAodGhpcy50YWJzKSB7XG4gICAgICB0aGlzLnRhYnNldFNlcnZpY2Uuc2V0QWN0aXZlVGFiSW5kZXgodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPbiBpbml0LCB3YWl0IGZvciBjaGlsZHJlbiB0YWJzIHRvIHJlbmRlciBiZWZvcmUgYnJvYWRjYXN0aW5nIHRoZSBhY3RpdmUgdGFiIGluZGV4LlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnRhYnNldFNlcnZpY2UuaXNWYWxpZFRhYkluZGV4KHZhbHVlKSkge1xuICAgICAgICAgIC8vIE9uIGluaXQsIHlpZWxkIHRvIHRoZSBwZXJtYWxpbmsgSUQsIGlmIGl0IGV4aXN0cy5cbiAgICAgICAgICBpZiAodGhpcy5nZXRBY3RpdmVUYWJJbmRleEJ5UGVybWFsaW5rSWQoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLnRhYnNldFNlcnZpY2Uuc2V0QWN0aXZlVGFiSW5kZXgodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBBY3RpdmF0ZSB0aGUgZmlyc3QgdGFiIGlmIHRoZSBuZXcgdGFiIGluZGV4IGlzIGludmFsaWQuXG4gICAgICAgICAgdGhpcy5fYWN0aXZlID0gdGhpcy50YWJzZXRTZXJ2aWNlLmFjdGl2YXRlRmlyc3RUYWIoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldCBhY3RpdmUoKTogU2t5VGFiSW5kZXgge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gIH1cblxuICAvKipcbiAgICogU3BlY2lmaWVzIGFuIEFSSUEgbGFiZWwgZm9yIHRoZSB0YWJzZXQuIFRoaXMgc2V0cyB0aGUgdGFic2V0J3MgYGFyaWEtbGFiZWxgIGF0dHJpYnV0ZVxuICAgKiBbdG8gc3VwcG9ydCBhY2Nlc3NpYmlsaXR5XShodHRwczovL2RldmVsb3Blci5ibGFja2JhdWQuY29tL3NreXV4L2xlYXJuL2FjY2Vzc2liaWxpdHkpLlxuICAgKiBJZiB0aGUgdGFic2V0IGluY2x1ZGVzIGEgdmlzaWJsZSBsYWJlbCwgdXNlIGBhcmlhTGFiZWxsZWRCeWAgaW5zdGVhZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBhcmlhTGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBIVE1MIGVsZW1lbnQgSUQgKHdpdGhvdXQgdGhlIGxlYWRpbmcgYCNgKSBvZiB0aGUgZWxlbWVudCB0aGF0IGxhYmVsc1xuICAgKiB0aGUgdGFic2V0LiBUaGlzIHNldHMgdGhlIHRhYnNldCdzIGBhcmlhLWxhYmVsbGVkYnlgIGF0dHJpYnV0ZVxuICAgKiBbdG8gc3VwcG9ydCBhY2Nlc3NpYmlsaXR5XShodHRwczovL2RldmVsb3Blci5ibGFja2JhdWQuY29tL3NreXV4L2xlYXJuL2FjY2Vzc2liaWxpdHkpLlxuICAgKiBJZiB0aGUgdGFic2V0IGRvZXMgbm90IGluY2x1ZGUgYSB2aXNpYmxlIGxhYmVsLCB1c2UgYGFyaWFMYWJlbGAgaW5zdGVhZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBhcmlhTGFiZWxsZWRCeTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEaXN0aW5ndWlzaGVzIGEgdGFic2V0J3MgdW5pcXVlIHN0YXRlIGluIHRoZSBVUkwgYnkgZ2VuZXJhdGluZyBhIHF1ZXJ5IHBhcmFtZXRlclxuICAgKiB0aGF0IGlzIHdyaXR0ZW4gYXMgYD88cXVlcnlQYXJhbT4tYWN0aXZlLXRhYj08c2FuaXRpemVkLXRhYi1oZWFkaW5nPmAuXG4gICAqIFRoZSBxdWVyeSBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBwYXJzZWQgYXV0b21hdGljYWxseSBmcm9tIHRoZSBzZWxlY3RlZCB0YWIncyBoZWFkaW5nIHRleHQsXG4gICAqIGJ1dCB5b3UgY2FuIHN1cHBseSBhIGN1c3RvbSBxdWVyeSBwYXJhbWV0ZXIgdmFsdWUgZm9yIGVhY2ggdGFiIHdpdGggaXRzIGBwZXJtYWxpbmtWYWx1ZWAuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IHBlcm1hbGlua0lkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2FuaXRpemVkID0gdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLnVybGlmeSh2YWx1ZSk7XG4gICAgdGhpcy5fcGVybWFsaW5rSWQgPSBgJHtzYW5pdGl6ZWR9LWFjdGl2ZS10YWJgO1xuICB9XG5cbiAgcHVibGljIGdldCBwZXJtYWxpbmtJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9wZXJtYWxpbmtJZCB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIGJlaGF2aW9yIGZvciBhIHNlcmllcyBvZiB0YWJzLlxuICAgKiBAZGVwcmVjYXRlZCBUaGUgcHJvcGVydHkgd2FzIGRlc2lnbmVkIHRvIGNyZWF0ZSB3aXphcmRzIGJ5IHNldHRpbmcgdGFiU3R5bGU9XCJ3aXphcmRcIiBvbiB0YWJzZXRzIGluIG1vZGFscyxcbiAgICogYnV0IHRoaXMgd2l6YXJkIGltcGxlbWVudGF0aW9uIHdhcyByZXBsYWNlZCBieSB0aGVcbiAgICogW3Byb2dyZXNzIGluZGljYXRvciBjb21wb25lbnRdKGh0dHBzOi8vZGV2ZWxvcGVyLmJsYWNrYmF1ZC5jb20vc2t5dXgvY29tcG9uZW50cy9wcm9ncmVzcy1pbmRpY2F0b3IpLlxuICAgKiBAZGVmYXVsdCBcInRhYnNcIlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHNldCB0YWJTdHlsZSh2YWx1ZTogU2t5VGFic2V0U3R5bGUpIHtcbiAgICAvKmlzdGFuYnVsIGlnbm9yZSBlbHNlKi9cbiAgICBpZiAodmFsdWUgJiYgdmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gJ3dpemFyZCcpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1RoZSB0YWJzZXQgd2l6YXJkIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSBpbXBsZW1lbnQgdGhlIG5ldyBhcHByb2FjaCB1c2luZyAnICtcbiAgICAgICAgICAncHJvZ3Jlc3MgaW5kaWNhdG9yIGFzIGRvY3VtZW50ZWQgaGVyZTogaHR0cHM6Ly9kZXZlbG9wZXIuYmxhY2tiYXVkLmNvbS9za3l1eC9jb21wb25lbnRzL3dpemFyZC4nXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuX3RhYlN0eWxlID0gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHRhYlN0eWxlKCk6IFNreVRhYnNldFN0eWxlIHtcbiAgICByZXR1cm4gdGhpcy5fdGFiU3R5bGUgfHwgJ3RhYnMnO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpcmVzIHdoZW4gdGhlIGFjdGl2ZSB0YWIgY2hhbmdlcy4gVGhpcyBldmVudCBlbWl0cyB0aGUgaW5kZXggb2YgdGhlIGFjdGl2ZSB0YWIuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIGFjdGl2ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8U2t5VGFiSW5kZXg+KCk7XG5cbiAgLyoqXG4gICAqIEZpcmVzIHdoZW4gdXNlcnMgY2xpY2sgdGhlIGJ1dHRvbiB0byBhZGQgYSBuZXcgdGFiLlxuICAgKiBUaGUgbmV3IHRhYiBidXR0b24gaXMgYWRkZWQgdG8gdGhlIHRhYiBhcmVhIHdoZW4geW91IHNwZWNpZnkgYSBsaXN0ZW5lciBmb3IgdGhpcyBldmVudC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgbmV3VGFiID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIHVzZXJzIGNsaWNrIHRoZSBidXR0b24gdG8gb3BlbiBhIHRhYi5cbiAgICogVGhlIG9wZW4gdGFiIGJ1dHRvbiBpcyBhZGRlZCB0byB0aGUgdGFiIGFyZWEgd2hlbiB5b3Ugc3BlY2lmeSBhIGxpc3RlbmVyIGZvciB0aGlzIGV2ZW50LlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBvcGVuVGFiID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIGFueSB0YWIncyBgdGFiSW5kZXhgIHZhbHVlIGNoYW5nZXMuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIHRhYkluZGV4ZXNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFNreVRhYnNldFRhYkluZGV4ZXNDaGFuZ2U+KCk7XG5cbiAgcHVibGljIHNldCB0YWJEaXNwbGF5TW9kZSh2YWx1ZTogU2t5VGFic2V0QnV0dG9uc0Rpc3BsYXlNb2RlKSB7XG4gICAgdGhpcy5fdGFiRGlzcGxheU1vZGUgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHVibGljIGdldCB0YWJEaXNwbGF5TW9kZSgpOiBTa3lUYWJzZXRCdXR0b25zRGlzcGxheU1vZGUge1xuICAgIHJldHVybiB0aGlzLl90YWJEaXNwbGF5TW9kZSB8fCAndGFicyc7XG4gIH1cblxuICBAQ29udGVudENoaWxkcmVuKFNreVRhYkNvbXBvbmVudClcbiAgcHVibGljIHRhYnM6IFF1ZXJ5TGlzdDxTa3lUYWJDb21wb25lbnQ+O1xuXG4gIHB1YmxpYyBkcm9wZG93blRyaWdnZXJCdXR0b25UZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBieSB0aGUgZGVwcmVjYXRlZCB0YWJzZXQtbmF2LWJ1dHRvbiBjb21wb25lbnQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIGxhc3RBY3RpdmVUYWJJbmRleDogU2t5VGFiSW5kZXg7XG5cbiAgcHVibGljIHRhYkJ1dHRvbnM6IFRhYkJ1dHRvblZpZXdNb2RlbFtdID0gW107XG5cbiAgcHJpdmF0ZSBuZ1Vuc3Vic2NyaWJlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIHRhYkNvbXBvbmVudHNTdGF0ZUNoYW5nZVVuc3Vic2NyaWJlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIF9hY3RpdmU6IFNreVRhYkluZGV4O1xuXG4gIHByaXZhdGUgX3Blcm1hbGlua0lkOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBfdGFiRGlzcGxheU1vZGU6IFNreVRhYnNldEJ1dHRvbnNEaXNwbGF5TW9kZTtcblxuICBwcml2YXRlIF90YWJTdHlsZTogU2t5VGFic2V0U3R5bGU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgYWRhcHRlclNlcnZpY2U6IFNreVRhYnNldEFkYXB0ZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGVybWFsaW5rU2VydmljZTogU2t5VGFic2V0UGVybWFsaW5rU2VydmljZSxcbiAgICBwcml2YXRlIHRhYnNldFNlcnZpY2U6IFNreVRhYnNldFNlcnZpY2VcbiAgKSB7fVxuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0VGFiQ29tcG9uZW50cygpO1xuICAgIHRoaXMubGlzdGVuVGFiQ29tcG9uZW50c1N0cnVjdHVyYWxDaGFuZ2UoKTtcblxuICAgIGNvbnN0IGluaXRpYWxUYWJJbmRleCA9IHRoaXMuZ2V0SW5pdGlhbFRhYkluZGV4KCk7XG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLnNldEFjdGl2ZVRhYkluZGV4KGluaXRpYWxUYWJJbmRleCk7XG5cbiAgICB0aGlzLmxpc3RlblRhYkJ1dHRvbnNPdmVyZmxvd0NoYW5nZSgpO1xuICAgIHRoaXMubGlzdGVuTG9jYXRpb25Qb3BTdGF0ZUNoYW5nZSgpO1xuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnRseSBhY3RpdmUgdGFiIGlzIGdldHRpbmcgdW5yZWdpc3RlcmVkLCBhY3RpdmF0ZSB0aGUgbmV4dCBvbmUuXG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLmFjdGl2ZVRhYlVucmVnaXN0ZXJlZFxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKCh0YWIpID0+IHtcbiAgICAgICAgLy8gV2FpdCBmb3IgdGhlIG5ldyB0YWJzIHRvIHJlbmRlciBiZWZvcmUgYWN0aXZhdGluZy5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy50YWJzZXRTZXJ2aWNlLmFjdGl2YXRlTmVhcmVzdFRhYih0YWIuYXJyYXlJbmRleCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAvLyBMZXQgdGhlIHRhYnNldCByZW5kZXIgdGhlIGluaXRpYWwgYWN0aXZlIGluZGV4IGJlZm9yZSBsaXN0ZW5pbmcgZm9yIGNoYW5nZXMuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmxpc3RlblRhYkNvbXBvbmVudHNTdGF0ZUNoYW5nZSgpO1xuICAgICAgdGhpcy5saXN0ZW5BY3RpdmVJbmRleENoYW5nZSgpO1xuICAgICAgdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLmluaXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm5nVW5zdWJzY3JpYmUubmV4dCgpO1xuICAgIHRoaXMubmdVbnN1YnNjcmliZS5jb21wbGV0ZSgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVUYWJDb21wb25lbnRzU3RhdGVDaGFuZ2UoKTtcbiAgICBpZiAodGhpcy5wZXJtYWxpbmtJZCkge1xuICAgICAgdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLmNsZWFyUGFyYW0odGhpcy5wZXJtYWxpbmtJZCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uV2luZG93UmVzaXplKCk6IHZvaWQge1xuICAgIHRoaXMuYWRhcHRlclNlcnZpY2UuZGV0ZWN0T3ZlcmZsb3coKTtcbiAgfVxuXG4gIHB1YmxpYyBvblRhYkNsb3NlQ2xpY2sodGFiQnV0dG9uOiBUYWJCdXR0b25WaWV3TW9kZWwpOiB2b2lkIHtcbiAgICBjb25zdCB0YWJDb21wb25lbnQgPSB0aGlzLnRhYnMuZmluZCgodGFiKSA9PlxuICAgICAgdGhpcy50YWJzZXRTZXJ2aWNlLnRhYkluZGV4ZXNFcXVhbCh0YWIudGFiSW5kZXgsIHRhYkJ1dHRvbi50YWJJbmRleClcbiAgICApO1xuXG4gICAgdGFiQ29tcG9uZW50LmNsb3NlLmVtaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBvblRhYkJ1dHRvbkNsaWNrKHRhYkJ1dHRvbjogVGFiQnV0dG9uVmlld01vZGVsKTogdm9pZCB7XG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLnNldEFjdGl2ZVRhYkluZGV4KHRhYkJ1dHRvbi50YWJJbmRleCk7XG4gIH1cblxuICBwdWJsaWMgb25OZXdUYWJDbGljaygpOiB2b2lkIHtcbiAgICB0aGlzLm5ld1RhYi5lbWl0KCk7XG4gIH1cblxuICBwdWJsaWMgb25PcGVuVGFiQ2xpY2soKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuVGFiLmVtaXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBpbml0aWFsIGFjdGl2ZSB0YWIgaW5kZXggYmFzZWQgb24gdGhlIGZvbGxvd2luZyBjcml0ZXJpYS5cbiAgICogMS4gRG9lcyB0aGUgVVJMIGluY2x1ZGUgYSBxdWVyeSBwYXJhbSB0aGF0IHJlZmxlY3RzIHRoaXMgdGFic2V0J3MgYWN0aXZlIHRhYj9cbiAgICogMi4gRG9lcyBvbmUgb2YgdGhlIHRhYiBjb21wb25lbnRzIGhhdmUgdGhlaXIgYGFjdGl2ZWAgcHJvcGVydHkgc2V0IHRvIGB0cnVlYD9cbiAgICogMy4gSXMgdGhlIHRhYnNldCBjb21wb25lbnQncyBgYWN0aXZlYCBwcm9wZXJ0eSBzZXQgdG8gYSBzcGVjaWZpYyB0YWIgaW5kZXg/XG4gICAqL1xuICBwcml2YXRlIGdldEluaXRpYWxUYWJJbmRleCgpOiBTa3lUYWJJbmRleCB7XG4gICAgbGV0IGFjdGl2ZUluZGV4OiBTa3lUYWJJbmRleCA9IHRoaXMuZ2V0QWN0aXZlVGFiSW5kZXhCeVBlcm1hbGlua0lkKCk7XG4gICAgaWYgKGFjdGl2ZUluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJDb21wb25lbnQoKT8udGFiSW5kZXg7XG4gICAgICBpZiAoYWN0aXZlSW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhY3RpdmVJbmRleCA9IHRoaXMuYWN0aXZlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhY3RpdmVJbmRleDtcbiAgfVxuXG4gIHByaXZhdGUgbGlzdGVuQWN0aXZlSW5kZXhDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLmFjdGl2ZVRhYkluZGV4XG4gICAgICAucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCB0YWtlVW50aWwodGhpcy5uZ1Vuc3Vic2NyaWJlKSlcbiAgICAgIC5zdWJzY3JpYmUoKGFjdGl2ZUluZGV4KSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlVGFic2V0Q29tcG9uZW50KGFjdGl2ZUluZGV4KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsaXN0ZW5UYWJDb21wb25lbnRzU3RydWN0dXJhbENoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLnRhYnMuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLm5nVW5zdWJzY3JpYmUpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZXNldFRhYkNvbXBvbmVudHMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbGlzdGVuVGFiQ29tcG9uZW50c1N0YXRlQ2hhbmdlKCk6IHZvaWQge1xuICAgIGNvbWJpbmVMYXRlc3QodGhpcy50YWJzLm1hcCgodGFiKSA9PiB0YWIuYWN0aXZlQ2hhbmdlKSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwoXG4gICAgICAgICAgcmFjZSh0aGlzLnRhYkNvbXBvbmVudHNTdGF0ZUNoYW5nZVVuc3Vic2NyaWJlLCB0aGlzLm5nVW5zdWJzY3JpYmUpXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAvLyBXYWl0IGZvciB0aGUgdGFiIGNvbXBvbmVudHMgdG8gcmVuZGVyIGNoYW5nZXMgYmVmb3JlIGZpbmRpbmcgdGhlIGFjdGl2ZSBvbmUuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRhYkluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJDb21wb25lbnQoKT8udGFiSW5kZXg7XG4gICAgICAgICAgdGhpcy50YWJzZXRTZXJ2aWNlLnNldEFjdGl2ZVRhYkluZGV4KHRhYkluZGV4KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgIGNvbWJpbmVMYXRlc3QodGhpcy50YWJzLm1hcCgodGFiKSA9PiB0YWIudGFiSW5kZXhDaGFuZ2UpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbChcbiAgICAgICAgICByYWNlKHRoaXMudGFiQ29tcG9uZW50c1N0YXRlQ2hhbmdlVW5zdWJzY3JpYmUsIHRoaXMubmdVbnN1YnNjcmliZSlcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIERvbid0IGVtaXQgdGhlIGZpcnN0IGNoYW5nZS5cbiAgICAgICAgaWYgKHRoaXMubGFzdEFjdGl2ZVRhYkluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBXYWl0IGZvciB0aGUgdGFiIGNvbXBvbmVudHMgdG8gcmVuZGVyIGNoYW5nZXMgYmVmb3JlIHVwZGF0aW5nIHRoZSB2aWV3LlxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVUYWJzZXRDb21wb25lbnQoXG4gICAgICAgICAgICAgIHRoaXMudGFic2V0U2VydmljZS5jdXJyZW50QWN0aXZlVGFiSW5kZXgsXG4gICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmVtaXRUYWJJbmRleENoYW5nZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIGNvbWJpbmVMYXRlc3QodGhpcy50YWJzLm1hcCgodGFiKSA9PiB0YWIuc3RhdGVDaGFuZ2UpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbChcbiAgICAgICAgICByYWNlKHRoaXMudGFiQ29tcG9uZW50c1N0YXRlQ2hhbmdlVW5zdWJzY3JpYmUsIHRoaXMubmdVbnN1YnNjcmliZSlcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIFdhaXQgZm9yIHRoZSB0YWIgY29tcG9uZW50cyB0byByZW5kZXIgY2hhbmdlcyBiZWZvcmUgZmluZGluZyB0aGUgYWN0aXZlIG9uZS5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy51cGRhdGVUYWJzZXRDb21wb25lbnQoXG4gICAgICAgICAgICB0aGlzLnRhYnNldFNlcnZpY2UuY3VycmVudEFjdGl2ZVRhYkluZGV4LFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRUYWJDb21wb25lbnRzKCk6IHZvaWQge1xuICAgIHRoaXMudGFicy5mb3JFYWNoKCh0YWIpID0+IHRhYi5pbml0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNldFRhYkNvbXBvbmVudHMoKTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZVRhYkNvbXBvbmVudHNTdGF0ZUNoYW5nZSgpO1xuICAgIHRoaXMudGFic2V0U2VydmljZS51bnJlZ2lzdGVyQWxsKCk7XG5cbiAgICAvLyBJZiB0aGVyZSBhcmUgbm8gdGFiIGNvbXBvbmVudHMsIGRvIGEgaGFyZCByZXNldCBvZiB0aGUgdmlldy5cbiAgICBpZiAodGhpcy50YWJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy51cGRhdGVUYWJzZXRDb21wb25lbnQoMCwgdHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pbml0VGFiQ29tcG9uZW50cygpO1xuICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJDb21wb25lbnQoKT8udGFiSW5kZXg7XG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLnNldEFjdGl2ZVRhYkluZGV4KGFjdGl2ZUluZGV4LCB7XG4gICAgICBlbWl0Q2hhbmdlOiBmYWxzZSxcbiAgICB9KTtcbiAgICB0aGlzLmxpc3RlblRhYkNvbXBvbmVudHNTdGF0ZUNoYW5nZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0VGFiSW5kZXhDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy50YWJJbmRleGVzQ2hhbmdlLmVtaXQoe1xuICAgICAgdGFiczogdGhpcy50YWJzLm1hcCgodGFiKSA9PiAoe1xuICAgICAgICB0YWJIZWFkaW5nOiB0YWIudGFiSGVhZGluZyxcbiAgICAgICAgdGFiSW5kZXg6IHRhYi50YWJJbmRleCxcbiAgICAgIH0pKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdW5zdWJzY3JpYmVUYWJDb21wb25lbnRzU3RhdGVDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy50YWJDb21wb25lbnRzU3RhdGVDaGFuZ2VVbnN1YnNjcmliZS5uZXh0KCk7XG4gICAgdGhpcy50YWJDb21wb25lbnRzU3RhdGVDaGFuZ2VVbnN1YnNjcmliZS5jb21wbGV0ZSgpO1xuICAgIHRoaXMudGFiQ29tcG9uZW50c1N0YXRlQ2hhbmdlVW5zdWJzY3JpYmUgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICB9XG5cbiAgcHJpdmF0ZSBsaXN0ZW5UYWJCdXR0b25zT3ZlcmZsb3dDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5hZGFwdGVyU2VydmljZS5yZWdpc3RlclRhYnNldCh0aGlzLmVsZW1lbnRSZWYpO1xuICAgIHRoaXMuYWRhcHRlclNlcnZpY2Uub3ZlcmZsb3dDaGFuZ2VcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLm5nVW5zdWJzY3JpYmUpKVxuICAgICAgLnN1YnNjcmliZSgoaXNPdmVyZmxvd2luZykgPT4ge1xuICAgICAgICB0aGlzLnRhYkRpc3BsYXlNb2RlID0gaXNPdmVyZmxvd2luZyA/ICdkcm9wZG93bicgOiAndGFicyc7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gZm9yIGJhY2svZm9yd2FyZCBoaXN0b3J5IGJ1dHRvbiBwcmVzc2VzIHRvIGRldGVjdCBxdWVyeSBwYXJhbSBjaGFuZ2VzIGluIHRoZSBVUkwuXG4gICAqL1xuICBwcml2YXRlIGxpc3RlbkxvY2F0aW9uUG9wU3RhdGVDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLnBvcFN0YXRlQ2hhbmdlXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5uZ1Vuc3Vic2NyaWJlKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNldEFjdGl2ZVRhYkluZGV4QnlQZXJtYWxpbmtJZCgpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldEFjdGl2ZVRhYkluZGV4QnlQZXJtYWxpbmtJZCgpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0QWN0aXZlVGFiSW5kZXhCeVBlcm1hbGlua0lkKCk7XG4gICAgdGhpcy50YWJzZXRTZXJ2aWNlLnNldEFjdGl2ZVRhYkluZGV4KGFjdGl2ZUluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWN0aXZlVGFiSW5kZXhCeVBlcm1hbGlua0lkKCk6IFNreVRhYkluZGV4IHtcbiAgICBpZiAodGhpcy5wZXJtYWxpbmtJZCkge1xuICAgICAgY29uc3QgcGFyYW1WYWx1ZSA9IHRoaXMucGVybWFsaW5rU2VydmljZS5nZXRQYXJhbSh0aGlzLnBlcm1hbGlua0lkKTtcbiAgICAgIGlmIChwYXJhbVZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRhYnMuZmluZCgodGFiKSA9PiB0YWIucGVybWFsaW5rVmFsdWUgPT09IHBhcmFtVmFsdWUpXG4gICAgICAgICAgPy50YWJJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEFjdGl2ZVRhYkNvbXBvbmVudCgpOiBTa3lUYWJDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLnRhYnNcbiAgICAgIC50b0FycmF5KClcbiAgICAgIC5yZXZlcnNlKClcbiAgICAgIC5maW5kKCh0YWIpID0+IHRhYi5hY3RpdmUgPT09IHRydWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVUYWJCdXR0b25zKGFjdGl2ZUluZGV4OiBTa3lUYWJJbmRleCk6IFRhYkJ1dHRvblZpZXdNb2RlbFtdIHtcbiAgICByZXR1cm4gdGhpcy50YWJzLm1hcCgodGFiKSA9PiAoe1xuICAgICAgYWN0aXZlOiB0aGlzLnRhYnNldFNlcnZpY2UudGFiSW5kZXhlc0VxdWFsKHRhYi50YWJJbmRleCwgYWN0aXZlSW5kZXgpLFxuICAgICAgY2xvc2VhYmxlOiB0YWIuY2xvc2VhYmxlLFxuICAgICAgYXJpYUNvbnRyb2xzOiB0YWIudGFiUGFuZWxJZCxcbiAgICAgIGRpc2FibGVkOiB0YWIuZGlzYWJsZWQsXG4gICAgICBidXR0b25IcmVmOiB0YWIuZGlzYWJsZWRcbiAgICAgICAgPyBudWxsXG4gICAgICAgIDogdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLmdldFBhcmFtSHJlZihcbiAgICAgICAgICAgIHRoaXMucGVybWFsaW5rSWQsXG4gICAgICAgICAgICB0YWIucGVybWFsaW5rVmFsdWVcbiAgICAgICAgICApLFxuICAgICAgYnV0dG9uSWQ6IHRhYi50YWJCdXR0b25JZCxcbiAgICAgIGJ1dHRvblRleHRDb3VudDogdGFiLnRhYkhlYWRlckNvdW50LFxuICAgICAgYnV0dG9uVGV4dDogdGFiLnRhYkhlYWRpbmcsXG4gICAgICB0YWJJbmRleDogdGFiLnRhYkluZGV4LFxuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlVGFiQnV0dG9ucyhhY3RpdmVJbmRleDogU2t5VGFiSW5kZXgpOiB2b2lkIHtcbiAgICB0aGlzLnRhYkJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICBidXR0b24uYWN0aXZlID0gdGhpcy50YWJzZXRTZXJ2aWNlLnRhYkluZGV4ZXNFcXVhbChcbiAgICAgICAgYnV0dG9uLnRhYkluZGV4LFxuICAgICAgICBhY3RpdmVJbmRleFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBVSSBhbmQgc3RhdGUgb2YgdGhlIHRhYnNldCBjb21wb25lbnQgYWZ0ZXIgdGhlIHRhYiBpbmRleCBvclxuICAgKiB0YWIgY29tcG9uZW50cyBoYXZlIGNoYW5nZWQuXG4gICAqIEBwYXJhbSBhY3RpdmVJbmRleCBUaGUgY3VycmVudGx5IGFjdGl2ZSB0YWIgaW5kZXguXG4gICAqIEBwYXJhbSByZWdlbmVyYXRlVGFiQnV0dG9ucyBJbmRpY2F0ZXMgaWYgdGFiIGJ1dHRvbiB2aWV3IG1vZGVscyBzaG91bGQgYmUgcmVnZW5lcmF0ZWQuXG4gICAqIFNldHRpbmcgdGhpcyB2YWx1ZSB0byBgZmFsc2VgIHdpbGwgc2ltcGx5IHVwZGF0ZSB0aGUgZXhpc3RpbmcgdGFiIGJ1dHRvbnMuIFNldHRpbmcgdGhpcyB2YWx1ZVxuICAgKiB0byBgdHJ1ZWAgaXMgb25seSBuZWNlc3Nhcnkgd2hlbiB0aGUgdW5kZXJseWluZyB0YWIgY29tcG9uZW50cyBoYXZlIGNoYW5nZWQgYW5kIHRoZSB0YWJcbiAgICogYnV0dG9ucyBtdXN0IHJlZmxlY3QgdGhvc2UgY2hhbmdlcy5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlVGFic2V0Q29tcG9uZW50KFxuICAgIGFjdGl2ZUluZGV4OiBTa3lUYWJJbmRleCxcbiAgICByZWdlbmVyYXRlVGFiQnV0dG9ucyA9IGZhbHNlXG4gICk6IHZvaWQge1xuICAgIC8vIEFjdGl2YXRlL2RlYWN0aXZhdGUgdGFiIGNvbXBvbmVudHMuXG4gICAgdGhpcy50YWJzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgdGhpcy50YWJzZXRTZXJ2aWNlLnRhYkluZGV4ZXNFcXVhbCh0YWIudGFiSW5kZXgsIGFjdGl2ZUluZGV4KVxuICAgICAgICA/IHRhYi5hY3RpdmF0ZSgpXG4gICAgICAgIDogdGFiLmRlYWN0aXZhdGUoKTtcbiAgICB9KTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgdGFiIGJ1dHRvbiBtb2RlbHMuXG4gICAgaWYgKHJlZ2VuZXJhdGVUYWJCdXR0b25zIHx8ICF0aGlzLnRhYkJ1dHRvbnMubGVuZ3RoKSB7XG4gICAgICB0aGlzLnRhYkJ1dHRvbnMgPSB0aGlzLmNyZWF0ZVRhYkJ1dHRvbnMoYWN0aXZlSW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZVRhYkJ1dHRvbnMoYWN0aXZlSW5kZXgpO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgZHJvcGRvd24gdHJpZ2dlciBidXR0b24gdGV4dC5cbiAgICB0aGlzLmRyb3Bkb3duVHJpZ2dlckJ1dHRvblRleHQgPSB0aGlzLnRhYkJ1dHRvbnMuZmluZCgoYikgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudGFic2V0U2VydmljZS50YWJJbmRleGVzRXF1YWwoYi50YWJJbmRleCwgYWN0aXZlSW5kZXgpO1xuICAgIH0pPy5idXR0b25UZXh0O1xuXG4gICAgLy8gU2V0IHRoZSBxdWVyeSBwYXJhbXMgYmFzZWQgb24gYWN0aXZlIHRhYi5cbiAgICBpZiAodGhpcy5wZXJtYWxpbmtJZCkge1xuICAgICAgY29uc3QgYWN0aXZlVGFiQ29tcG9uZW50ID0gdGhpcy50YWJzLmZpbmQoKHRhYikgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy50YWJzZXRTZXJ2aWNlLnRhYkluZGV4ZXNFcXVhbCh0YWIudGFiSW5kZXgsIGFjdGl2ZUluZGV4KTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wZXJtYWxpbmtTZXJ2aWNlLnNldFBhcmFtKFxuICAgICAgICB0aGlzLnBlcm1hbGlua0lkLFxuICAgICAgICBhY3RpdmVUYWJDb21wb25lbnQucGVybWFsaW5rVmFsdWVcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gV2FpdCBmb3IgdGFiIGJ1dHRvbiB2aWV3IG1vZGVscyB0byByZW5kZXIgYmVmb3JlIGdhdWdpbmcgZGltZW5zaW9ucy5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuYWRhcHRlclNlcnZpY2UuZGV0ZWN0T3ZlcmZsb3coKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG5cbiAgICAvLyBFbWl0IHRoZSBuZXcgYWN0aXZlIGluZGV4IHZhbHVlIHRvIGNvbnN1bWVycy5cbiAgICBpZiAodGhpcy5sYXN0QWN0aXZlVGFiSW5kZXggIT09IGFjdGl2ZUluZGV4KSB7XG4gICAgICB0aGlzLmxhc3RBY3RpdmVUYWJJbmRleCA9IGFjdGl2ZUluZGV4O1xuICAgICAgdGhpcy5hY3RpdmVDaGFuZ2UuZW1pdChhY3RpdmVJbmRleCk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2XG4gIGNsYXNzPVwic2t5LXRhYnNldFwiXG4gIHJvbGU9XCJ0YWJsaXN0XCJcbiAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWxcIlxuICBbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiYXJpYUxhYmVsbGVkQnlcIlxuICBbbmdDbGFzc109XCJcbiAgICAnc2t5LXRhYnNldC1tb2RlLScgKyB0YWJEaXNwbGF5TW9kZSArICcgc2t5LXRhYnNldC1zdHlsZS0nICsgdGFiU3R5bGVcbiAgXCJcbiAgKHdpbmRvdzpyZXNpemUpPVwib25XaW5kb3dSZXNpemUoKVwiXG4+XG4gIDxzcGFuIGNsYXNzPVwic2t5LXRhYnNldC1kcm9wZG93blwiPlxuICAgIDxza3ktZHJvcGRvd24gKm5nSWY9XCJ0YWJEaXNwbGF5TW9kZSA9PT0gJ2Ryb3Bkb3duJ1wiIGJ1dHRvblR5cGU9XCJ0YWJcIj5cbiAgICAgIDxza3ktZHJvcGRvd24tYnV0dG9uPlxuICAgICAgICB7eyBkcm9wZG93blRyaWdnZXJCdXR0b25UZXh0IH19XG4gICAgICA8L3NreS1kcm9wZG93bi1idXR0b24+XG4gICAgICA8c2t5LWRyb3Bkb3duLW1lbnU+XG4gICAgICAgIDxza3ktZHJvcGRvd24taXRlbVxuICAgICAgICAgICpuZ0Zvcj1cImxldCB0YWJCdXR0b24gb2YgdGFiQnV0dG9uc1wiXG4gICAgICAgICAgY2xhc3M9XCJza3ktdGFiLWRyb3Bkb3duLW1lbnUtaXRlbVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cInNreS10YWItZHJvcGRvd24taXRlbVwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICdza3ktdGFiLWRyb3Bkb3duLWl0ZW0tc2VsZWN0ZWQnOiB0YWJCdXR0b24uYWN0aXZlXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAgICAgdGFiQnV0dG9uVGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiB0YWJCdXR0b25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvc2t5LWRyb3Bkb3duLWl0ZW0+XG4gICAgICA8L3NreS1kcm9wZG93bi1tZW51PlxuICAgIDwvc2t5LWRyb3Bkb3duPlxuICA8L3NwYW4+XG4gIDxzcGFuIGNsYXNzPVwic2t5LXRhYnNldC10YWJzXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdGFiQnV0dG9uIG9mIHRhYkJ1dHRvbnNcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICB0YWJCdXR0b25UZW1wbGF0ZTtcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICAkaW1wbGljaXQ6IHRhYkJ1dHRvblxuICAgICAgICAgIH1cbiAgICAgICAgXCJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9zcGFuPlxuICA8c3BhbiBjbGFzcz1cInNreS10YWJzZXQtYnRuc1wiPlxuICAgIDxidXR0b25cbiAgICAgICpuZ0lmPVwibmV3VGFiLm9ic2VydmVycy5sZW5ndGggPiAwXCJcbiAgICAgIGNsYXNzPVwic2t5LWJ0biBza3ktYnRuLWljb24gc2t5LXRhYnNldC1idG4tbmV3IHNreS1tYXJnaW4taW5saW5lLWNvbXBhY3RcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidza3l1eF90YWJfYWRkJyB8IHNreUxpYlJlc291cmNlc1wiXG4gICAgICBbc2t5VGhlbWVDbGFzc109XCJ7XG4gICAgICAgICdza3ktbWFyZ2luLWlubGluZS1zbSc6ICdtb2Rlcm4nXG4gICAgICB9XCJcbiAgICAgIChjbGljayk9XCJvbk5ld1RhYkNsaWNrKClcIlxuICAgID5cbiAgICAgIDxza3ktaWNvbiBpY29uPVwicGx1cy1jaXJjbGVcIiBzaXplPVwibGdcIj4gPC9za3ktaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAqbmdJZj1cIm9wZW5UYWIub2JzZXJ2ZXJzLmxlbmd0aCA+IDBcIlxuICAgICAgY2xhc3M9XCJza3ktYnRuIHNreS1idG4taWNvbiBza3ktdGFic2V0LWJ0bi1vcGVuIHNreS1tYXJnaW4taW5saW5lLWNvbXBhY3RcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidza3l1eF90YWJfb3BlbicgfCBza3lMaWJSZXNvdXJjZXNcIlxuICAgICAgW3NreVRoZW1lQ2xhc3NdPVwie1xuICAgICAgICAnc2t5LW1hcmdpbi1pbmxpbmUtc20nOiAnbW9kZXJuJ1xuICAgICAgfVwiXG4gICAgICAoY2xpY2spPVwib25PcGVuVGFiQ2xpY2soKVwiXG4gICAgPlxuICAgICAgPHNreS1pY29uIGljb249XCJmb2xkZXItb3Blbi1vXCIgc2l6ZT1cImxnXCI+IDwvc2t5LWljb24+XG4gICAgPC9idXR0b24+XG4gIDwvc3Bhbj5cbjwvZGl2PlxuPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuXG48bmctdGVtcGxhdGUgbGV0LXRhYkJ1dHRvbiAjdGFiQnV0dG9uVGVtcGxhdGU+XG4gIDxza3ktdGFiLWJ1dHRvblxuICAgIFthY3RpdmVdPVwidGFiQnV0dG9uLmFjdGl2ZVwiXG4gICAgW2FyaWFDb250cm9sc109XCJ0YWJCdXR0b24uYXJpYUNvbnRyb2xzXCJcbiAgICBbYnV0dG9uSHJlZl09XCJ0YWJCdXR0b24uYnV0dG9uSHJlZlwiXG4gICAgW2J1dHRvbklkXT1cInRhYkJ1dHRvbi5idXR0b25JZFwiXG4gICAgW2J1dHRvblRleHRdPVwidGFiQnV0dG9uLmJ1dHRvblRleHRcIlxuICAgIFtidXR0b25UZXh0Q291bnRdPVwidGFiQnV0dG9uLmJ1dHRvblRleHRDb3VudFwiXG4gICAgW2Nsb3NlYWJsZV09XCJ0YWJCdXR0b24uY2xvc2VhYmxlXCJcbiAgICBbZGlzYWJsZWRdPVwidGFiQnV0dG9uLmRpc2FibGVkXCJcbiAgICBbdGFiU3R5bGVdPVwidGFiU3R5bGVcIlxuICAgIChidXR0b25DbGljayk9XCJvblRhYkJ1dHRvbkNsaWNrKHRhYkJ1dHRvbilcIlxuICAgIChjbG9zZUNsaWNrKT1cIm9uVGFiQ2xvc2VDbGljayh0YWJCdXR0b24pXCJcbiAgPjwvc2t5LXRhYi1idXR0b24+XG48L25nLXRlbXBsYXRlPlxuIl19
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export class SkyTabsetService {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.currentActiveTabIndex = 0;
|
|
10
|
+
this._activeTabIndex = new BehaviorSubject(0);
|
|
11
|
+
this._activeTabUnregistered = new Subject();
|
|
12
|
+
this.tabs = [];
|
|
13
|
+
this.tabCounter = 0;
|
|
14
|
+
}
|
|
15
|
+
get activeTabUnregistered() {
|
|
16
|
+
return this._activeTabUnregistered.asObservable();
|
|
17
|
+
}
|
|
18
|
+
get activeTabIndex() {
|
|
19
|
+
return this._activeTabIndex.asObservable();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sets the active tab by its unique `tabIndex` property.
|
|
23
|
+
*/
|
|
24
|
+
setActiveTabIndex(value, config = {
|
|
25
|
+
emitChange: true,
|
|
26
|
+
}) {
|
|
27
|
+
if (value !== undefined &&
|
|
28
|
+
!this.tabIndexesEqual(value, this.currentActiveTabIndex)) {
|
|
29
|
+
this.currentActiveTabIndex = value;
|
|
30
|
+
/* istanbul ignore else */
|
|
31
|
+
if (config.emitChange) {
|
|
32
|
+
this._activeTabIndex.next(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Registers a tab component.
|
|
38
|
+
*/
|
|
39
|
+
registerTab(tabIndex) {
|
|
40
|
+
if (tabIndex === undefined) {
|
|
41
|
+
tabIndex = this.tabCounter;
|
|
42
|
+
this.tabCounter++;
|
|
43
|
+
}
|
|
44
|
+
this.tabs.push({ tabIndex });
|
|
45
|
+
return tabIndex;
|
|
46
|
+
}
|
|
47
|
+
updateTabIndex(currentTabIndex, newTabIndex) {
|
|
48
|
+
const found = this.tabs.find((tab) => this.tabIndexesEqual(tab.tabIndex, currentTabIndex));
|
|
49
|
+
found.tabIndex = newTabIndex;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Unregisters a tab component.
|
|
53
|
+
*/
|
|
54
|
+
unregisterTab(tabIndex) {
|
|
55
|
+
const index = this.tabs.findIndex((tab) => this.tabIndexesEqual(tab.tabIndex, tabIndex));
|
|
56
|
+
// Notify the tabset component when an active tab is unregistered.
|
|
57
|
+
if (this.isTabIndexActive(this.tabs[index].tabIndex)) {
|
|
58
|
+
this._activeTabUnregistered.next({
|
|
59
|
+
arrayIndex: index,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
this.tabs.splice(index, 1);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Unregisters all tab components at once.
|
|
66
|
+
*/
|
|
67
|
+
unregisterAll() {
|
|
68
|
+
this.tabs = [];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compares two tab indexes and returns `true` if they are equal.
|
|
72
|
+
*/
|
|
73
|
+
tabIndexesEqual(tabIndex1, tabIndex2) {
|
|
74
|
+
return tabIndex1 === tabIndex2 || +tabIndex1 === +tabIndex2;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Verifies if a provided tab index is registered.
|
|
78
|
+
*/
|
|
79
|
+
isValidTabIndex(tabIndex) {
|
|
80
|
+
return this.tabs.some((tab) => this.tabIndexesEqual(tab.tabIndex, tabIndex));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Activates the first registered tab.
|
|
84
|
+
*/
|
|
85
|
+
activateFirstTab() {
|
|
86
|
+
const firstTabIndex = this.tabs[0] && this.tabs[0].tabIndex;
|
|
87
|
+
if (firstTabIndex !== undefined) {
|
|
88
|
+
this.setActiveTabIndex(firstTabIndex);
|
|
89
|
+
return firstTabIndex;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Activates the next registered tab, or the previous one based on a provided array index.
|
|
94
|
+
*/
|
|
95
|
+
activateNearestTab(arrayIndex) {
|
|
96
|
+
const newActiveTab = this.tabs[arrayIndex] || this.tabs[arrayIndex - 1];
|
|
97
|
+
if (newActiveTab) {
|
|
98
|
+
this.currentActiveTabIndex = newActiveTab.tabIndex;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
isTabIndexActive(tabIndex) {
|
|
102
|
+
return this.tabIndexesEqual(tabIndex, this.currentActiveTabIndex);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
SkyTabsetService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTabsetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
106
|
+
SkyTabsetService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTabsetService });
|
|
107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTabsetService, decorators: [{
|
|
108
|
+
type: Injectable
|
|
109
|
+
}] });
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvdGFicy9zcmMvbGliL21vZHVsZXMvdGFicy90YWJzZXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQUs1RDs7R0FFRztBQUVILE1BQU0sT0FBTyxnQkFBZ0I7SUFEN0I7UUFVUywwQkFBcUIsR0FBZ0IsQ0FBQyxDQUFDO1FBRXRDLG9CQUFlLEdBQUcsSUFBSSxlQUFlLENBQWMsQ0FBQyxDQUFDLENBQUM7UUFFdEQsMkJBQXNCLEdBQzVCLElBQUksT0FBTyxFQUFzQyxDQUFDO1FBRTVDLFNBQUksR0FFTixFQUFFLENBQUM7UUFFRCxlQUFVLEdBQUcsQ0FBQyxDQUFDO0tBbUh4QjtJQXRJQyxJQUFXLHFCQUFxQjtRQUM5QixPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNwRCxDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBZUQ7O09BRUc7SUFDSSxpQkFBaUIsQ0FDdEIsS0FBa0IsRUFDbEIsTUFBTSxHQUFHO1FBQ1AsVUFBVSxFQUFFLElBQUk7S0FDakI7UUFFRCxJQUNFLEtBQUssS0FBSyxTQUFTO1lBQ25CLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQ3hEO1lBQ0EsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQztZQUNuQywwQkFBMEI7WUFDMUIsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO2dCQUNyQixJQUFJLENBQUMs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QUMscUJBQXFCLENBQUMsQ0FBQztJQUNwRSxDQUFDOzs2R0F0SVUsZ0JBQWdCO2lIQUFoQixnQkFBZ0I7MkZBQWhCLGdCQUFnQjtrQkFENUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFNreVRhYkluZGV4IH0gZnJvbSAnLi90YWItaW5kZXgnO1xuaW1wb3J0IHsgU2t5VGFic2V0QWN0aXZlVGFiVW5yZWdpc3RlcmVkQXJncyB9IGZyb20gJy4vdGFic2V0LWFjdGl2ZS10YWItdW5yZWdpc3RlcmVkLWFyZ3MnO1xuXG4vKipcbiAqIEBpbnRlcm5hbFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgU2t5VGFic2V0U2VydmljZSB7XG4gIHB1YmxpYyBnZXQgYWN0aXZlVGFiVW5yZWdpc3RlcmVkKCk6IE9ic2VydmFibGU8U2t5VGFic2V0QWN0aXZlVGFiVW5yZWdpc3RlcmVkQXJncz4ge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmVUYWJVbnJlZ2lzdGVyZWQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGFjdGl2ZVRhYkluZGV4KCk6IE9ic2VydmFibGU8U2t5VGFiSW5kZXg+IHtcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlVGFiSW5kZXguYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgY3VycmVudEFjdGl2ZVRhYkluZGV4OiBTa3lUYWJJbmRleCA9IDA7XG5cbiAgcHJpdmF0ZSBfYWN0aXZlVGFiSW5kZXggPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNreVRhYkluZGV4PigwKTtcblxuICBwcml2YXRlIF9hY3RpdmVUYWJVbnJlZ2lzdGVyZWQgPVxuICAgIG5ldyBTdWJqZWN0PFNreVRhYnNldEFjdGl2ZVRhYlVucmVnaXN0ZXJlZEFyZ3M+KCk7XG5cbiAgcHJpdmF0ZSB0YWJzOiB7XG4gICAgdGFiSW5kZXg6IFNreVRhYkluZGV4O1xuICB9W10gPSBbXTtcblxuICBwcml2YXRlIHRhYkNvdW50ZXIgPSAwO1xuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBhY3RpdmUgdGFiIGJ5IGl0cyB1bmlxdWUgYHRhYkluZGV4YCBwcm9wZXJ0eS5cbiAgICovXG4gIHB1YmxpYyBzZXRBY3RpdmVUYWJJbmRleChcbiAgICB2YWx1ZTogU2t5VGFiSW5kZXgsXG4gICAgY29uZmlnID0ge1xuICAgICAgZW1pdENoYW5nZTogdHJ1ZSxcbiAgICB9XG4gICk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICF0aGlzLnRhYkluZGV4ZXNFcXVhbCh2YWx1ZSwgdGhpcy5jdXJyZW50QWN0aXZlVGFiSW5kZXgpXG4gICAgKSB7XG4gICAgICB0aGlzLmN1cnJlbnRBY3RpdmVUYWJJbmRleCA9IHZhbHVlO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChjb25maWcuZW1pdENoYW5nZSkge1xuICAgICAgICB0aGlzLl9hY3RpdmVUYWJJbmRleC5uZXh0KHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdGFiIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyByZWdpc3RlclRhYih0YWJJbmRleD86IFNreVRhYkluZGV4KTogU2t5VGFiSW5kZXgge1xuICAgIGlmICh0YWJJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YWJJbmRleCA9IHRoaXMudGFiQ291bnRlcjtcbiAgICAgIHRoaXMudGFiQ291bnRlcisrO1xuICAgIH1cblxuICAgIHRoaXMudGFicy5wdXNoKHsgdGFiSW5kZXggfSk7XG5cbiAgICByZXR1cm4gdGFiSW5kZXg7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlVGFiSW5kZXgoXG4gICAgY3VycmVudFRhYkluZGV4OiBTa3lUYWJJbmRleCxcbiAgICBuZXdUYWJJbmRleDogU2t5VGFiSW5kZXhcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZm91bmQgPSB0aGlzLnRhYnMuZmluZCgodGFiKSA9PlxuICAgICAgdGhpcy50YWJJbmRleGVzRXF1YWwodGFiLnRhYkluZGV4LCBjdXJyZW50VGFiSW5kZXgpXG4gICAgKTtcbiAgICBmb3VuZC50YWJJbmRleCA9IG5ld1RhYkluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGEgdGFiIGNvbXBvbmVudC5cbiAgICovXG4gIHB1YmxpYyB1bnJlZ2lzdGVyVGFiKHRhYkluZGV4OiBTa3lUYWJJbmRleCk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy50YWJzLmZpbmRJbmRleCgodGFiKSA9PlxuICAgICAgdGhpcy50YWJJbmRleGVzRXF1YWwodGFiLnRhYkluZGV4LCB0YWJJbmRleClcbiAgICApO1xuXG4gICAgLy8gTm90aWZ5IHRoZSB0YWJzZXQgY29tcG9uZW50IHdoZW4gYW4gYWN0aXZlIHRhYiBpcyB1bnJlZ2lzdGVyZWQuXG4gICAgaWYgKHRoaXMuaXNUYWJJbmRleEFjdGl2ZSh0aGlzLnRhYnNbaW5kZXhdLnRhYkluZGV4KSkge1xuICAgICAgdGhpcy5fYWN0aXZlVGFiVW5yZWdpc3RlcmVkLm5leHQoe1xuICAgICAgICBhcnJheUluZGV4OiBpbmRleCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMudGFicy5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGFsbCB0YWIgY29tcG9uZW50cyBhdCBvbmNlLlxuICAgKi9cbiAgcHVibGljIHVucmVnaXN0ZXJBbGwoKTogdm9pZCB7XG4gICAgdGhpcy50YWJzID0gW107XG4gIH1cblxuICAvKipcbiAgICogQ29tcGFyZXMgdHdvIHRhYiBpbmRleGVzIGFuZCByZXR1cm5zIGB0cnVlYCBpZiB0aGV5IGFyZSBlcXVhbC5cbiAgICovXG4gIHB1YmxpYyB0YWJJbmRleGVzRXF1YWwoXG4gICAgdGFiSW5kZXgxOiBTa3lUYWJJbmRleCxcbiAgICB0YWJJbmRleDI6IFNreVRhYkluZGV4XG4gICk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0YWJJbmRleDEgPT09IHRhYkluZGV4MiB8fCArdGFiSW5kZXgxID09PSArdGFiSW5kZXgyO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIGlmIGEgcHJvdmlkZWQgdGFiIGluZGV4IGlzIHJlZ2lzdGVyZWQuXG4gICAqL1xuICBwdWJsaWMgaXNWYWxpZFRhYkluZGV4KHRhYkluZGV4OiBTa3lUYWJJbmRleCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRhYnMuc29tZSgodGFiKSA9PlxuICAgICAgdGhpcy50YWJJbmRleGVzRXF1YWwodGFiLnRhYkluZGV4LCB0YWJJbmRleClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdGl2YXRlcyB0aGUgZmlyc3QgcmVnaXN0ZXJlZCB0YWIuXG4gICAqL1xuICBwdWJsaWMgYWN0aXZhdGVGaXJzdFRhYigpOiBTa3lUYWJJbmRleCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZmlyc3RUYWJJbmRleCA9IHRoaXMudGFic1swXSAmJiB0aGlzLnRhYnNbMF0udGFiSW5kZXg7XG4gICAgaWYgKGZpcnN0VGFiSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXRBY3RpdmVUYWJJbmRleChmaXJzdFRhYkluZGV4KTtcbiAgICAgIHJldHVybiBmaXJzdFRhYkluZGV4O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RpdmF0ZXMgdGhlIG5leHQgcmVnaXN0ZXJlZCB0YWIsIG9yIHRoZSBwcmV2aW91cyBvbmUgYmFzZWQgb24gYSBwcm92aWRlZCBhcnJheSBpbmRleC5cbiAgICovXG4gIHB1YmxpYyBhY3RpdmF0ZU5lYXJlc3RUYWIoYXJyYXlJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV3QWN0aXZlVGFiID0gdGhpcy50YWJzW2FycmF5SW5kZXhdIHx8IHRoaXMudGFic1thcnJheUluZGV4IC0gMV07XG4gICAgaWYgKG5ld0FjdGl2ZVRhYikge1xuICAgICAgdGhpcy5jdXJyZW50QWN0aXZlVGFiSW5kZXggPSBuZXdBY3RpdmVUYWIudGFiSW5kZXg7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1RhYkluZGV4QWN0aXZlKHRhYkluZGV4OiBTa3lUYWJJbmRleCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRhYkluZGV4ZXNFcXVhbCh0YWJJbmRleCwgdGhpcy5jdXJyZW50QWN0aXZlVGFiSW5kZXgpO1xuICB9XG59XG4iXX0=
|