@design-factory/design-factory 18.1.1 → 19.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/design-factory-initial-branding.css +1 -1
- package/design-factory.css +1 -1
- package/fesm2022/design-factory.mjs +748 -921
- package/fesm2022/design-factory.mjs.map +1 -1
- package/lib/angular/accessibility/components/skip-links-container/skip-links-container.component.d.ts +3 -9
- package/lib/angular/accessibility/directives/skip-link.directive.d.ts +3 -9
- package/lib/angular/card/manage-card-selection.directive.d.ts +5 -5
- package/lib/angular/datepicker/datepicker-range.directive.d.ts +5 -6
- package/lib/angular/datepicker/datepicker.module.d.ts +3 -5
- package/lib/angular/inputs/icon/inputicon.directive.d.ts +5 -6
- package/lib/angular/mediaqueries/ifMedia.directive.d.ts +8 -9
- package/lib/angular/modal/modal.service.d.ts +4 -0
- package/lib/angular/progressbar/progressbar.component.d.ts +18 -28
- package/lib/angular/progressindicator/default/default-spinner.component.d.ts +4 -4
- package/lib/angular/progressindicator/progressindicator-backdrop.component.d.ts +4 -4
- package/lib/angular/progressindicator/progressindicator-container.component.d.ts +5 -7
- package/lib/angular/progressindicator/progressindicator.directive.d.ts +9 -11
- package/lib/angular/selects/events/manage-badge-events.directive.d.ts +4 -5
- package/lib/angular/selects/option-highlight.directive.d.ts +7 -12
- package/lib/angular/sidenav/dfSideNavCollapse.d.ts +16 -18
- package/lib/angular/sidenav/excludeTrap.directive.d.ts +9 -10
- package/lib/angular/sidenav/sidenav.component.d.ts +7 -8
- package/lib/angular/sidenav/sidenavlist.component.d.ts +8 -8
- package/lib/angular/slider/direction/sliderdirection.directive.d.ts +5 -7
- package/lib/angular/slider/lib/slider-element.directive.d.ts +2 -1
- package/lib/angular/slider/lib/slider-handle.directive.d.ts +1 -1
- package/lib/angular/slider/lib/slider-label.directive.d.ts +1 -1
- package/lib/angular/slider/lib/slider.component.d.ts +1 -1
- package/lib/angular/slider/lib/tooltip-wrapper.component.d.ts +1 -1
- package/lib/angular/slider/slider.module.d.ts +1 -1
- package/lib/angular/stepper/stepper.component.d.ts +7 -8
- package/lib/angular/utils/titleTruncate.directive.d.ts +2 -3
- package/lib/angular/waves-of-progress/waves.directive.d.ts +4 -3
- package/lib/index.d.ts +0 -1
- package/package.json +16 -16
- package/schematics/ng-add/index.js +1 -1
- package/styles/scss/agnosui/_variables.scss +9 -3
- package/styles/scss/bootstrap/_variables.scss +54 -12
- package/styles/scss/components/accordion/_accordion.scss +67 -6
- package/styles/scss/components/accordion/_accordion.variables.scss +2 -0
- package/styles/scss/components/alert/_alert.scss +3 -2
- package/styles/scss/components/badge/_badge.scss +13 -3
- package/styles/scss/components/badge/_badge.variables.scss +1 -0
- package/styles/scss/components/button/_button.scss +5 -0
- package/styles/scss/components/form/_form.scss +8 -0
- package/styles/scss/components/sidenav/_sidenav.scss +5 -2
- package/styles/scss/components/toggle/_toggle.scss +1 -0
- package/styles/scss/df-styles-namespace.scss +3 -1
- package/styles/scss/df-styles.scss +3 -1
- package/styles/scss/themes/brand2023/_variables.scss +80 -28
- package/esm2022/design-factory.mjs +0 -5
- package/esm2022/environment.mjs +0 -5
- package/esm2022/index.mjs +0 -5
- package/esm2022/lib/angular/accessibility/accessibility.module.mjs +0 -19
- package/esm2022/lib/angular/accessibility/components/skip-links-container/skip-links-container.component.mjs +0 -32
- package/esm2022/lib/angular/accessibility/directives/skip-link.directive.mjs +0 -64
- package/esm2022/lib/angular/alert/alert.module.mjs +0 -17
- package/esm2022/lib/angular/animation/ngbTransition.mjs +0 -76
- package/esm2022/lib/angular/animation/util.mjs +0 -30
- package/esm2022/lib/angular/card/card-advanced.module.mjs +0 -17
- package/esm2022/lib/angular/card/manage-card-selection.directive.mjs +0 -47
- package/esm2022/lib/angular/datepicker/closedatepicker.directive.mjs +0 -38
- package/esm2022/lib/angular/datepicker/datepicker-keyboard-nav.service.mjs +0 -39
- package/esm2022/lib/angular/datepicker/datepicker-range.directive.mjs +0 -101
- package/esm2022/lib/angular/datepicker/datepicker-range.service.mjs +0 -97
- package/esm2022/lib/angular/datepicker/datepicker.module.mjs +0 -42
- package/esm2022/lib/angular/df.module.mjs +0 -102
- package/esm2022/lib/angular/footer/footer.module.mjs +0 -17
- package/esm2022/lib/angular/icon/amadeus-icon.mjs +0 -79
- package/esm2022/lib/angular/icon/icon.module.mjs +0 -17
- package/esm2022/lib/angular/icon/insert/insert-icon.directive.mjs +0 -47
- package/esm2022/lib/angular/icon/insert/insert-icon.module.mjs +0 -17
- package/esm2022/lib/angular/inputs/click/trigger-click.directive.mjs +0 -28
- package/esm2022/lib/angular/inputs/icon/inputicon.directive.mjs +0 -95
- package/esm2022/lib/angular/inputs/input-advanced.module.mjs +0 -19
- package/esm2022/lib/angular/mediaqueries/ifMedia.directive.mjs +0 -52
- package/esm2022/lib/angular/mediaqueries/media.module.mjs +0 -17
- package/esm2022/lib/angular/mediaqueries/media.service.mjs +0 -46
- package/esm2022/lib/angular/mediaqueries/mediaUtils.service.mjs +0 -185
- package/esm2022/lib/angular/modal/modal.service.mjs +0 -36
- package/esm2022/lib/angular/popover/config/popover.config.mjs +0 -15
- package/esm2022/lib/angular/popover/popover.module.mjs +0 -17
- package/esm2022/lib/angular/progressbar/progressbar.component.mjs +0 -156
- package/esm2022/lib/angular/progressbar/progressbar.module.mjs +0 -18
- package/esm2022/lib/angular/progressindicator/default/default-spinner.component.mjs +0 -23
- package/esm2022/lib/angular/progressindicator/progressindicator-backdrop.component.mjs +0 -29
- package/esm2022/lib/angular/progressindicator/progressindicator-config.mjs +0 -25
- package/esm2022/lib/angular/progressindicator/progressindicator-container.component.mjs +0 -52
- package/esm2022/lib/angular/progressindicator/progressindicator-ref.mjs +0 -8
- package/esm2022/lib/angular/progressindicator/progressindicator.directive.mjs +0 -39
- package/esm2022/lib/angular/progressindicator/progressindicator.module.mjs +0 -45
- package/esm2022/lib/angular/progressindicator/progressindicator.service.mjs +0 -170
- package/esm2022/lib/angular/right-to-left/directionDetection.service.mjs +0 -32
- package/esm2022/lib/angular/selects/events/manage-badge-events.directive.mjs +0 -65
- package/esm2022/lib/angular/selects/nav/manage-nav-select.directive.mjs +0 -108
- package/esm2022/lib/angular/selects/option-highlight.directive.mjs +0 -59
- package/esm2022/lib/angular/selects/select.model.mjs +0 -2
- package/esm2022/lib/angular/selects/select.module.mjs +0 -22
- package/esm2022/lib/angular/sidenav/dfSideNavAnimation.mjs +0 -73
- package/esm2022/lib/angular/sidenav/dfSideNavCollapse.mjs +0 -94
- package/esm2022/lib/angular/sidenav/dfSideNavCollapse.module.mjs +0 -18
- package/esm2022/lib/angular/sidenav/dfSideNavCollapse.service.mjs +0 -37
- package/esm2022/lib/angular/sidenav/dfSideNavCollapseConfig.mjs +0 -27
- package/esm2022/lib/angular/sidenav/excludeTrap.directive.mjs +0 -55
- package/esm2022/lib/angular/sidenav/manage-sidenav.directive.mjs +0 -26
- package/esm2022/lib/angular/sidenav/sidenav-config.mjs +0 -25
- package/esm2022/lib/angular/sidenav/sidenav.component.mjs +0 -86
- package/esm2022/lib/angular/sidenav/sidenav.module.mjs +0 -52
- package/esm2022/lib/angular/sidenav/sidenav.service.mjs +0 -316
- package/esm2022/lib/angular/sidenav/sidenavlist.component.mjs +0 -59
- package/esm2022/lib/angular/slider/direction/sliderdirection.directive.mjs +0 -36
- package/esm2022/lib/angular/slider/lib/change-context.mjs +0 -3
- package/esm2022/lib/angular/slider/lib/compatibility-helper.mjs +0 -15
- package/esm2022/lib/angular/slider/lib/event-listener-helper.mjs +0 -77
- package/esm2022/lib/angular/slider/lib/event-listener.mjs +0 -3
- package/esm2022/lib/angular/slider/lib/math-helper.mjs +0 -15
- package/esm2022/lib/angular/slider/lib/options.mjs +0 -123
- package/esm2022/lib/angular/slider/lib/pointer-type.mjs +0 -9
- package/esm2022/lib/angular/slider/lib/slider-element.directive.mjs +0 -190
- package/esm2022/lib/angular/slider/lib/slider-handle.directive.mjs +0 -65
- package/esm2022/lib/angular/slider/lib/slider-label.directive.mjs +0 -41
- package/esm2022/lib/angular/slider/lib/slider.component.mjs +0 -1998
- package/esm2022/lib/angular/slider/lib/tooltip-wrapper.component.mjs +0 -23
- package/esm2022/lib/angular/slider/lib/value-helper.mjs +0 -50
- package/esm2022/lib/angular/slider/slider.module.mjs +0 -37
- package/esm2022/lib/angular/stepper/stepper.component.mjs +0 -65
- package/esm2022/lib/angular/stepper/stepper.directive.mjs +0 -174
- package/esm2022/lib/angular/stepper/stepper.module.mjs +0 -17
- package/esm2022/lib/angular/stepper/stepper.service.mjs +0 -213
- package/esm2022/lib/angular/toast/toast.module.mjs +0 -17
- package/esm2022/lib/angular/tooltip/tooltip.module.mjs +0 -18
- package/esm2022/lib/angular/tooltip/truncate/tooltipTruncate.directive.mjs +0 -31
- package/esm2022/lib/angular/utils/html-element-helper.mjs +0 -8
- package/esm2022/lib/angular/utils/scrollbar.service.mjs +0 -79
- package/esm2022/lib/angular/utils/titleTruncate.directive.mjs +0 -39
- package/esm2022/lib/angular/waves-of-progress/waves.directive.mjs +0 -86
- package/esm2022/lib/angular/waves-of-progress/waves.module.mjs +0 -16
- package/esm2022/lib/index.mjs +0 -93
- package/lib/angular/datepicker/closedatepicker.directive.d.ts +0 -10
|
@@ -1,1998 +0,0 @@
|
|
|
1
|
-
import { Component, ViewChild, HostBinding, HostListener, Input, EventEmitter, Output, ContentChild, forwardRef } from '@angular/core';
|
|
2
|
-
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
|
-
import { Subject } from 'rxjs';
|
|
4
|
-
import { distinctUntilChanged, filter } from 'rxjs/operators';
|
|
5
|
-
import { Options, LabelType } from './options';
|
|
6
|
-
import { PointerType } from './pointer-type';
|
|
7
|
-
import { ChangeContext } from './change-context';
|
|
8
|
-
import { ValueHelper } from './value-helper';
|
|
9
|
-
import { CompatibilityHelper } from './compatibility-helper';
|
|
10
|
-
import { MathHelper } from './math-helper';
|
|
11
|
-
import { EventListenerHelper, supportsPassiveEvents } from './event-listener-helper';
|
|
12
|
-
import { SliderElementDirective } from './slider-element.directive';
|
|
13
|
-
import { SliderHandleDirective } from './slider-handle.directive';
|
|
14
|
-
import { SliderLabelDirective } from './slider-label.directive';
|
|
15
|
-
import { CommonModule } from '@angular/common';
|
|
16
|
-
import { TooltipWrapperComponent } from './tooltip-wrapper.component';
|
|
17
|
-
import * as i0 from "@angular/core";
|
|
18
|
-
import * as i1 from "@angular/common";
|
|
19
|
-
export class Tick {
|
|
20
|
-
constructor() {
|
|
21
|
-
this.selected = false;
|
|
22
|
-
this.style = {};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
class Dragging {
|
|
26
|
-
constructor() {
|
|
27
|
-
this.active = false;
|
|
28
|
-
this.value = 0;
|
|
29
|
-
this.difference = 0;
|
|
30
|
-
this.position = 0;
|
|
31
|
-
this.lowLimit = 0;
|
|
32
|
-
this.highLimit = 0;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
class ModelValues {
|
|
36
|
-
static compare(x, y) {
|
|
37
|
-
if (ValueHelper.isNullOrUndefined(x) && ValueHelper.isNullOrUndefined(y)) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
if (ValueHelper.isNullOrUndefined(x) !== ValueHelper.isNullOrUndefined(y)) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
return x.value === y.value && x.highValue === y.highValue;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
class ModelChange extends ModelValues {
|
|
47
|
-
static compare(x, y) {
|
|
48
|
-
if (ValueHelper.isNullOrUndefined(x) && ValueHelper.isNullOrUndefined(y)) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
if (ValueHelper.isNullOrUndefined(x) !== ValueHelper.isNullOrUndefined(y)) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
return x.value === y.value && x.highValue === y.highValue && x.forceChange === y.forceChange;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
class InputModelChange extends ModelChange {
|
|
58
|
-
}
|
|
59
|
-
class OutputModelChange extends ModelChange {
|
|
60
|
-
}
|
|
61
|
-
const NGX_SLIDER_CONTROL_VALUE_ACCESSOR = {
|
|
62
|
-
provide: NG_VALUE_ACCESSOR,
|
|
63
|
-
/* tslint:disable-next-line: no-use-before-declare */
|
|
64
|
-
useExisting: forwardRef(() => SliderComponent),
|
|
65
|
-
multi: true
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* @deprecated SliderComponent is deprecated. Use {@link https://design-factory-int.app.net6.paas.westeurope.rnd.az.amadeus.net/#/components/slider/agnosui AgnosUI Slider} instead.
|
|
69
|
-
*/
|
|
70
|
-
export class SliderComponent {
|
|
71
|
-
// Input event that triggers slider refresh (re-positioning of slider elements)
|
|
72
|
-
set manualRefresh(manualRefresh) {
|
|
73
|
-
this.unsubscribeManualRefresh();
|
|
74
|
-
this.manualRefreshSubscription = manualRefresh.subscribe(() => {
|
|
75
|
-
setTimeout(() => this.calculateViewDimensionsAndDetectChanges());
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
// Input event that triggers setting focus on given slider handle
|
|
79
|
-
set triggerFocus(triggerFocus) {
|
|
80
|
-
this.unsubscribeTriggerFocus();
|
|
81
|
-
this.triggerFocusSubscription = triggerFocus.subscribe((pointerType) => {
|
|
82
|
-
this.focusPointer(pointerType);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
// Slider type, true means range slider
|
|
86
|
-
get range() {
|
|
87
|
-
return !ValueHelper.isNullOrUndefined(this.value) && !ValueHelper.isNullOrUndefined(this.highValue);
|
|
88
|
-
}
|
|
89
|
-
// Whether to show/hide ticks
|
|
90
|
-
get showTicks() {
|
|
91
|
-
return this.viewOptions.showTicks || false;
|
|
92
|
-
}
|
|
93
|
-
constructor(renderer, elementRef, changeDetectionRef, zone) {
|
|
94
|
-
this.renderer = renderer;
|
|
95
|
-
this.elementRef = elementRef;
|
|
96
|
-
this.changeDetectionRef = changeDetectionRef;
|
|
97
|
-
this.zone = zone;
|
|
98
|
-
this.class = 'ngx-slider';
|
|
99
|
-
// Output for low value slider to support two-way bindings
|
|
100
|
-
this.valueChange = new EventEmitter();
|
|
101
|
-
// Output for high value slider to support two-way bindings
|
|
102
|
-
this.highValueChange = new EventEmitter();
|
|
103
|
-
// An object with all the other options of the slider.
|
|
104
|
-
// Each option can be updated at runtime and the slider will automatically be re-rendered.
|
|
105
|
-
this.options = new Options();
|
|
106
|
-
// Event emitted when user starts interaction with the slider
|
|
107
|
-
this.userChangeStart = new EventEmitter();
|
|
108
|
-
// Event emitted on each change coming from user interaction
|
|
109
|
-
this.userChange = new EventEmitter();
|
|
110
|
-
// Event emitted when user finishes interaction with the slider
|
|
111
|
-
this.userChangeEnd = new EventEmitter();
|
|
112
|
-
// Set to true if init method already executed
|
|
113
|
-
this.initHasRun = false;
|
|
114
|
-
// Changes in model inputs are passed through this subject
|
|
115
|
-
// These are all changes coming in from outside the component through input bindings or reactive form inputs
|
|
116
|
-
this.inputModelChangeSubject = new Subject();
|
|
117
|
-
// Changes to model outputs are passed through this subject
|
|
118
|
-
// These are all changes that need to be communicated to output emitters and registered callbacks
|
|
119
|
-
this.outputModelChangeSubject = new Subject();
|
|
120
|
-
// Options synced to model options, based on defaults
|
|
121
|
-
this.viewOptions = new Options();
|
|
122
|
-
// Half of the width or height of the slider handles
|
|
123
|
-
this.handleHalfDimension = 0;
|
|
124
|
-
// Maximum position the slider handle can have
|
|
125
|
-
this.maxHandlePosition = 0;
|
|
126
|
-
// Used to call onStart on the first keydown event
|
|
127
|
-
this.firstKeyDown = false;
|
|
128
|
-
// Values recorded when first dragging the bar
|
|
129
|
-
this.dragging = new Dragging();
|
|
130
|
-
// Host element class bindings
|
|
131
|
-
this.sliderElementVerticalClass = false;
|
|
132
|
-
this.sliderElementAnimateClass = false;
|
|
133
|
-
this.sliderElementWithLegendClass = false;
|
|
134
|
-
this.sliderElementAriaLabel = 'ngx-slider';
|
|
135
|
-
// CSS styles and class flags
|
|
136
|
-
this.barStyle = {};
|
|
137
|
-
this.minPointerStyle = {};
|
|
138
|
-
this.maxPointerStyle = {};
|
|
139
|
-
this.fullBarTransparentClass = false;
|
|
140
|
-
this.selectionBarDraggableClass = false;
|
|
141
|
-
this.ticksUnderValuesClass = false;
|
|
142
|
-
/* If tickStep is set or ticksArray is specified.
|
|
143
|
-
In this case, ticks values should be displayed below the slider. */
|
|
144
|
-
this.intermediateTicks = false;
|
|
145
|
-
// Ticks array as displayed in view
|
|
146
|
-
this.ticks = [];
|
|
147
|
-
// Whether currently moving the slider (between onStart() and onEnd())
|
|
148
|
-
this.moving = false;
|
|
149
|
-
this.eventListenerHelper = new EventListenerHelper(this.renderer);
|
|
150
|
-
}
|
|
151
|
-
// OnInit interface
|
|
152
|
-
ngOnInit() {
|
|
153
|
-
this.viewOptions = new Options();
|
|
154
|
-
Object.assign(this.viewOptions, this.options);
|
|
155
|
-
// We need to run these two things first, before the rest of the init in ngAfterViewInit(),
|
|
156
|
-
// because these two settings are set through @HostBinding and Angular change detection
|
|
157
|
-
// mechanism doesn't like them changing in ngAfterViewInit()
|
|
158
|
-
this.updateDisabledState();
|
|
159
|
-
this.updateVerticalState();
|
|
160
|
-
this.updateAriaLabel();
|
|
161
|
-
}
|
|
162
|
-
// AfterViewInit interface
|
|
163
|
-
ngAfterViewInit() {
|
|
164
|
-
this.applyOptions();
|
|
165
|
-
this.subscribeInputModelChangeSubject();
|
|
166
|
-
this.subscribeOutputModelChangeSubject();
|
|
167
|
-
// Once we apply options, we need to normalise model values for the first time
|
|
168
|
-
this.renormaliseModelValues();
|
|
169
|
-
this.viewLowValue = this.modelValueToViewValue(this.value);
|
|
170
|
-
if (this.range) {
|
|
171
|
-
this.viewHighValue = this.modelValueToViewValue(this.highValue);
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
this.viewHighValue = undefined;
|
|
175
|
-
}
|
|
176
|
-
this.updateVerticalState(); // need to run this again to cover changes to slider elements
|
|
177
|
-
this.manageElementsStyle();
|
|
178
|
-
this.updateDisabledState();
|
|
179
|
-
this.calculateViewDimensions();
|
|
180
|
-
this.addAccessibility();
|
|
181
|
-
this.updateCeilLabel();
|
|
182
|
-
this.updateFloorLabel();
|
|
183
|
-
this.initHandles();
|
|
184
|
-
this.manageEventsBindings();
|
|
185
|
-
this.updateAriaLabel();
|
|
186
|
-
this.subscribeResizeObserver();
|
|
187
|
-
this.initHasRun = true;
|
|
188
|
-
// Run change detection manually to resolve some issues when init procedure changes values used in the view
|
|
189
|
-
if (!this.isRefDestroyed()) {
|
|
190
|
-
this.changeDetectionRef.detectChanges();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// OnChanges interface
|
|
194
|
-
ngOnChanges(changes) {
|
|
195
|
-
// Always apply options first
|
|
196
|
-
const options = changes['options'];
|
|
197
|
-
if (!ValueHelper.isNullOrUndefined(options) &&
|
|
198
|
-
JSON.stringify(options.previousValue) !== JSON.stringify(options.currentValue)) {
|
|
199
|
-
this.onChangeOptions();
|
|
200
|
-
}
|
|
201
|
-
// Then value changes
|
|
202
|
-
if (!ValueHelper.isNullOrUndefined(changes['value']) || !ValueHelper.isNullOrUndefined(changes['highValue'])) {
|
|
203
|
-
this.inputModelChangeSubject.next({
|
|
204
|
-
value: this.value,
|
|
205
|
-
highValue: this.highValue,
|
|
206
|
-
forceChange: false,
|
|
207
|
-
internalChange: false
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// OnDestroy interface
|
|
212
|
-
ngOnDestroy() {
|
|
213
|
-
this.unbindEvents();
|
|
214
|
-
this.unsubscribeResizeObserver();
|
|
215
|
-
this.unsubscribeInputModelChangeSubject();
|
|
216
|
-
this.unsubscribeOutputModelChangeSubject();
|
|
217
|
-
this.unsubscribeManualRefresh();
|
|
218
|
-
this.unsubscribeTriggerFocus();
|
|
219
|
-
}
|
|
220
|
-
// ControlValueAccessor interface
|
|
221
|
-
writeValue(obj) {
|
|
222
|
-
if (obj instanceof Array) {
|
|
223
|
-
this.value = obj[0];
|
|
224
|
-
this.highValue = obj[1];
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
this.value = obj;
|
|
228
|
-
}
|
|
229
|
-
// ngOnChanges() is not called in this instance, so we need to communicate the change manually
|
|
230
|
-
this.inputModelChangeSubject.next({
|
|
231
|
-
value: this.value,
|
|
232
|
-
highValue: this.highValue,
|
|
233
|
-
forceChange: false,
|
|
234
|
-
internalChange: false
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
// ControlValueAccessor interface
|
|
238
|
-
registerOnChange(onChangeCallback) {
|
|
239
|
-
this.onChangeCallback = onChangeCallback;
|
|
240
|
-
}
|
|
241
|
-
// ControlValueAccessor interface
|
|
242
|
-
registerOnTouched(onTouchedCallback) {
|
|
243
|
-
this.onTouchedCallback = onTouchedCallback;
|
|
244
|
-
}
|
|
245
|
-
// ControlValueAccessor interface
|
|
246
|
-
setDisabledState(isDisabled) {
|
|
247
|
-
this.viewOptions.disabled = isDisabled;
|
|
248
|
-
this.updateDisabledState();
|
|
249
|
-
}
|
|
250
|
-
setAriaLabel(ariaLabel) {
|
|
251
|
-
this.viewOptions.ariaLabel = ariaLabel;
|
|
252
|
-
this.updateAriaLabel();
|
|
253
|
-
}
|
|
254
|
-
onResize(event) {
|
|
255
|
-
this.calculateViewDimensionsAndDetectChanges();
|
|
256
|
-
}
|
|
257
|
-
subscribeInputModelChangeSubject() {
|
|
258
|
-
this.inputModelChangeSubscription = this.inputModelChangeSubject
|
|
259
|
-
.pipe(distinctUntilChanged(ModelChange.compare),
|
|
260
|
-
// Hack to reset the status of the distinctUntilChanged() - if a "fake" event comes through with forceChange=true,
|
|
261
|
-
// we forcefully by-pass distinctUntilChanged(), but otherwise drop the event
|
|
262
|
-
filter((modelChange) => !modelChange.forceChange && !modelChange.internalChange))
|
|
263
|
-
.subscribe((modelChange) => this.applyInputModelChange(modelChange));
|
|
264
|
-
}
|
|
265
|
-
subscribeOutputModelChangeSubject() {
|
|
266
|
-
this.outputModelChangeSubscription = this.outputModelChangeSubject
|
|
267
|
-
.pipe(distinctUntilChanged(ModelChange.compare))
|
|
268
|
-
.subscribe((modelChange) => this.publishOutputModelChange(modelChange));
|
|
269
|
-
}
|
|
270
|
-
subscribeResizeObserver() {
|
|
271
|
-
if (CompatibilityHelper.isResizeObserverAvailable()) {
|
|
272
|
-
this.resizeObserver = new ResizeObserver(() => this.calculateViewDimensionsAndDetectChanges());
|
|
273
|
-
this.resizeObserver.observe(this.elementRef.nativeElement);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
unsubscribeResizeObserver() {
|
|
277
|
-
if (CompatibilityHelper.isResizeObserverAvailable() && this.resizeObserver !== null) {
|
|
278
|
-
this.resizeObserver?.disconnect();
|
|
279
|
-
this.resizeObserver = undefined;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
unsubscribeOnMove() {
|
|
283
|
-
if (!ValueHelper.isNullOrUndefined(this.onMoveEventListener)) {
|
|
284
|
-
this.eventListenerHelper?.detachEventListener(this.onMoveEventListener);
|
|
285
|
-
this.onMoveEventListener = undefined;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
unsubscribeOnEnd() {
|
|
289
|
-
if (!ValueHelper.isNullOrUndefined(this.onEndEventListener)) {
|
|
290
|
-
this.eventListenerHelper?.detachEventListener(this.onEndEventListener);
|
|
291
|
-
this.onEndEventListener = undefined;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
unsubscribeInputModelChangeSubject() {
|
|
295
|
-
if (!ValueHelper.isNullOrUndefined(this.inputModelChangeSubscription)) {
|
|
296
|
-
this.inputModelChangeSubscription?.unsubscribe();
|
|
297
|
-
this.inputModelChangeSubscription = undefined;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
unsubscribeOutputModelChangeSubject() {
|
|
301
|
-
if (!ValueHelper.isNullOrUndefined(this.outputModelChangeSubscription)) {
|
|
302
|
-
this.outputModelChangeSubscription?.unsubscribe();
|
|
303
|
-
this.outputModelChangeSubscription = undefined;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
unsubscribeManualRefresh() {
|
|
307
|
-
if (!ValueHelper.isNullOrUndefined(this.manualRefreshSubscription)) {
|
|
308
|
-
this.manualRefreshSubscription.unsubscribe();
|
|
309
|
-
this.manualRefreshSubscription = undefined;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
unsubscribeTriggerFocus() {
|
|
313
|
-
if (!ValueHelper.isNullOrUndefined(this.triggerFocusSubscription)) {
|
|
314
|
-
this.triggerFocusSubscription.unsubscribe();
|
|
315
|
-
this.triggerFocusSubscription = null;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
getPointerElement(pointerType) {
|
|
319
|
-
if (pointerType === PointerType.Min) {
|
|
320
|
-
return this.minHandleElement;
|
|
321
|
-
}
|
|
322
|
-
else if (pointerType === PointerType.Max) {
|
|
323
|
-
return this.maxHandleElement;
|
|
324
|
-
}
|
|
325
|
-
return undefined;
|
|
326
|
-
}
|
|
327
|
-
getCurrentTrackingValue() {
|
|
328
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
329
|
-
return this.viewLowValue;
|
|
330
|
-
}
|
|
331
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
332
|
-
return this.viewHighValue;
|
|
333
|
-
}
|
|
334
|
-
return undefined;
|
|
335
|
-
}
|
|
336
|
-
modelValueToViewValue(modelValue) {
|
|
337
|
-
if (ValueHelper.isNullOrUndefined(modelValue)) {
|
|
338
|
-
return NaN;
|
|
339
|
-
}
|
|
340
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) {
|
|
341
|
-
return ValueHelper.findStepIndex(+modelValue, this.viewOptions.stepsArray);
|
|
342
|
-
}
|
|
343
|
-
return +modelValue;
|
|
344
|
-
}
|
|
345
|
-
viewValueToModelValue(viewValue) {
|
|
346
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) {
|
|
347
|
-
return this.getStepValue(viewValue);
|
|
348
|
-
}
|
|
349
|
-
return viewValue;
|
|
350
|
-
}
|
|
351
|
-
getStepValue(sliderValue) {
|
|
352
|
-
const step = this.viewOptions.stepsArray[sliderValue];
|
|
353
|
-
return !ValueHelper.isNullOrUndefined(step) ? step.value : NaN;
|
|
354
|
-
}
|
|
355
|
-
applyViewChange() {
|
|
356
|
-
this.value = this.viewValueToModelValue(this.viewLowValue);
|
|
357
|
-
if (this.range) {
|
|
358
|
-
this.highValue = this.viewValueToModelValue(this.viewHighValue);
|
|
359
|
-
}
|
|
360
|
-
this.outputModelChangeSubject.next({
|
|
361
|
-
value: this.value,
|
|
362
|
-
highValue: this.highValue,
|
|
363
|
-
userEventInitiated: true,
|
|
364
|
-
forceChange: false
|
|
365
|
-
});
|
|
366
|
-
// At this point all changes are applied and outputs are emitted, so we should be done.
|
|
367
|
-
// However, input changes are communicated in different stream and we need to be ready to
|
|
368
|
-
// act on the next input change even if it is exactly the same as last input change.
|
|
369
|
-
// Therefore, we send a special event to reset the stream.
|
|
370
|
-
this.inputModelChangeSubject.next({
|
|
371
|
-
value: this.value,
|
|
372
|
-
highValue: this.highValue,
|
|
373
|
-
forceChange: false,
|
|
374
|
-
internalChange: true
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
// Apply model change to the slider view
|
|
378
|
-
applyInputModelChange(modelChange) {
|
|
379
|
-
const normalisedModelChange = this.normaliseModelValues(modelChange);
|
|
380
|
-
// If normalised model change is different, apply the change to the model values
|
|
381
|
-
const normalisationChange = !ModelValues.compare(modelChange, normalisedModelChange);
|
|
382
|
-
if (normalisationChange) {
|
|
383
|
-
this.value = normalisedModelChange.value;
|
|
384
|
-
this.highValue = normalisedModelChange.highValue;
|
|
385
|
-
}
|
|
386
|
-
this.viewLowValue = this.modelValueToViewValue(normalisedModelChange.value);
|
|
387
|
-
if (this.range) {
|
|
388
|
-
this.viewHighValue = this.modelValueToViewValue(normalisedModelChange.highValue);
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
this.viewHighValue = undefined;
|
|
392
|
-
}
|
|
393
|
-
this.updateLowHandle(this.valueToPosition(this.viewLowValue));
|
|
394
|
-
if (this.range) {
|
|
395
|
-
this.updateHighHandle(this.valueToPosition(this.viewHighValue));
|
|
396
|
-
}
|
|
397
|
-
this.updateSelectionBar();
|
|
398
|
-
this.updateTicksScale();
|
|
399
|
-
this.updateAriaAttributes();
|
|
400
|
-
if (this.range) {
|
|
401
|
-
this.updateCombinedLabel();
|
|
402
|
-
}
|
|
403
|
-
// At the end, we need to communicate the model change to the outputs as well
|
|
404
|
-
// Normalisation changes are also always forced out to ensure that subscribers always end up in correct state
|
|
405
|
-
this.outputModelChangeSubject.next({
|
|
406
|
-
value: normalisedModelChange.value,
|
|
407
|
-
highValue: normalisedModelChange.highValue,
|
|
408
|
-
forceChange: normalisationChange,
|
|
409
|
-
userEventInitiated: false
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
// Publish model change to output event emitters and registered callbacks
|
|
413
|
-
publishOutputModelChange(modelChange) {
|
|
414
|
-
const emitOutputs = () => {
|
|
415
|
-
this.valueChange.emit(modelChange.value);
|
|
416
|
-
if (this.range) {
|
|
417
|
-
this.highValueChange.emit(modelChange.highValue);
|
|
418
|
-
}
|
|
419
|
-
if (!ValueHelper.isNullOrUndefined(this.onChangeCallback)) {
|
|
420
|
-
if (this.range) {
|
|
421
|
-
this.onChangeCallback([modelChange.value, modelChange.highValue]);
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
this.onChangeCallback(modelChange.value);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
if (!ValueHelper.isNullOrUndefined(this.onTouchedCallback)) {
|
|
428
|
-
if (this.range) {
|
|
429
|
-
this.onTouchedCallback([modelChange.value, modelChange.highValue]);
|
|
430
|
-
}
|
|
431
|
-
else {
|
|
432
|
-
this.onTouchedCallback(modelChange.value);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
if (modelChange.userEventInitiated) {
|
|
437
|
-
// If this change was initiated by a user event, we can emit outputs in the same tick
|
|
438
|
-
emitOutputs();
|
|
439
|
-
this.userChange.emit(this.getChangeContext());
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
// But, if the change was initated by something else like a change in input bindings,
|
|
443
|
-
// we need to wait until next tick to emit the outputs to keep Angular change detection happy
|
|
444
|
-
setTimeout(() => {
|
|
445
|
-
emitOutputs();
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
normaliseModelValues(input) {
|
|
450
|
-
const normalisedInput = new ModelValues();
|
|
451
|
-
normalisedInput.value = input.value;
|
|
452
|
-
normalisedInput.highValue = input.highValue;
|
|
453
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray)) {
|
|
454
|
-
// When using steps array, only round to nearest step in the array
|
|
455
|
-
// No other enforcement can be done, as the step array may be out of order, and that is perfectly fine
|
|
456
|
-
if (this.viewOptions.enforceStepsArray) {
|
|
457
|
-
const valueIndex = ValueHelper.findStepIndex(normalisedInput.value, this.viewOptions.stepsArray);
|
|
458
|
-
normalisedInput.value = this.viewOptions.stepsArray[valueIndex].value;
|
|
459
|
-
if (this.range) {
|
|
460
|
-
const highValueIndex = ValueHelper.findStepIndex(normalisedInput.highValue, this.viewOptions.stepsArray);
|
|
461
|
-
normalisedInput.highValue = this.viewOptions.stepsArray[highValueIndex].value;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return normalisedInput;
|
|
465
|
-
}
|
|
466
|
-
if (this.viewOptions.enforceStep) {
|
|
467
|
-
normalisedInput.value = this.roundStep(normalisedInput.value);
|
|
468
|
-
if (this.range) {
|
|
469
|
-
normalisedInput.highValue = this.roundStep(normalisedInput.highValue);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
if (this.viewOptions.enforceRange) {
|
|
473
|
-
normalisedInput.value = MathHelper.clampToRange(normalisedInput.value, this.viewOptions.floor, this.viewOptions.ceil);
|
|
474
|
-
if (this.range) {
|
|
475
|
-
normalisedInput.highValue = MathHelper.clampToRange(normalisedInput.highValue, this.viewOptions.floor, this.viewOptions.ceil);
|
|
476
|
-
}
|
|
477
|
-
// Make sure that range slider invariant (value <= highValue) is always satisfied
|
|
478
|
-
if (this.range && input.value > input.highValue) {
|
|
479
|
-
// We know that both values are now clamped correctly, they may just be in the wrong order
|
|
480
|
-
// So the easy solution is to swap them... except swapping is sometimes disabled in options, so we make the two values the same
|
|
481
|
-
if (this.viewOptions.noSwitching) {
|
|
482
|
-
normalisedInput.value = normalisedInput.highValue;
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
const tempValue = input.value;
|
|
486
|
-
normalisedInput.value = input.highValue;
|
|
487
|
-
normalisedInput.highValue = tempValue;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return normalisedInput;
|
|
492
|
-
}
|
|
493
|
-
renormaliseModelValues() {
|
|
494
|
-
const previousModelValues = {
|
|
495
|
-
value: this.value,
|
|
496
|
-
highValue: this.highValue
|
|
497
|
-
};
|
|
498
|
-
const normalisedModelValues = this.normaliseModelValues(previousModelValues);
|
|
499
|
-
if (!ModelValues.compare(normalisedModelValues, previousModelValues)) {
|
|
500
|
-
this.value = normalisedModelValues.value;
|
|
501
|
-
this.highValue = normalisedModelValues.highValue;
|
|
502
|
-
this.outputModelChangeSubject.next({
|
|
503
|
-
value: this.value,
|
|
504
|
-
highValue: this.highValue,
|
|
505
|
-
forceChange: true,
|
|
506
|
-
userEventInitiated: false
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
onChangeOptions() {
|
|
511
|
-
if (!this.initHasRun) {
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
const previousOptionsInfluencingEventBindings = this.getOptionsInfluencingEventBindings(this.viewOptions);
|
|
515
|
-
this.applyOptions();
|
|
516
|
-
const newOptionsInfluencingEventBindings = this.getOptionsInfluencingEventBindings(this.viewOptions);
|
|
517
|
-
// Avoid re-binding events in case nothing changes that can influence it
|
|
518
|
-
// It makes it possible to change options while dragging the slider
|
|
519
|
-
const rebindEvents = !ValueHelper.areArraysEqual(previousOptionsInfluencingEventBindings, newOptionsInfluencingEventBindings);
|
|
520
|
-
// With new options, we need to re-normalise model values if necessary
|
|
521
|
-
this.renormaliseModelValues();
|
|
522
|
-
this.viewLowValue = this.modelValueToViewValue(this.value);
|
|
523
|
-
if (this.range) {
|
|
524
|
-
this.viewHighValue = this.modelValueToViewValue(this.highValue);
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
this.viewHighValue = undefined;
|
|
528
|
-
}
|
|
529
|
-
this.resetSlider(rebindEvents);
|
|
530
|
-
}
|
|
531
|
-
// Read the user options and apply them to the slider model
|
|
532
|
-
applyOptions() {
|
|
533
|
-
this.viewOptions = new Options();
|
|
534
|
-
Object.assign(this.viewOptions, this.options);
|
|
535
|
-
this.viewOptions.draggableRange = this.range && this.viewOptions.draggableRange;
|
|
536
|
-
this.viewOptions.draggableRangeOnly = this.range && this.viewOptions.draggableRangeOnly;
|
|
537
|
-
if (this.viewOptions.draggableRangeOnly) {
|
|
538
|
-
this.viewOptions.draggableRange = true;
|
|
539
|
-
}
|
|
540
|
-
this.viewOptions.showTicks =
|
|
541
|
-
this.viewOptions.showTicks ||
|
|
542
|
-
this.viewOptions.showTicksValues ||
|
|
543
|
-
!ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray);
|
|
544
|
-
if (this.viewOptions.showTicks &&
|
|
545
|
-
(!ValueHelper.isNullOrUndefined(this.viewOptions.tickStep) ||
|
|
546
|
-
!ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray))) {
|
|
547
|
-
this.intermediateTicks = true;
|
|
548
|
-
}
|
|
549
|
-
this.viewOptions.showSelectionBar =
|
|
550
|
-
this.viewOptions.showSelectionBar ||
|
|
551
|
-
this.viewOptions.showSelectionBarEnd ||
|
|
552
|
-
!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue);
|
|
553
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray)) {
|
|
554
|
-
this.applyStepsArrayOptions();
|
|
555
|
-
}
|
|
556
|
-
else {
|
|
557
|
-
this.applyFloorCeilOptions();
|
|
558
|
-
}
|
|
559
|
-
if (ValueHelper.isNullOrUndefined(this.viewOptions.combineLabels)) {
|
|
560
|
-
this.viewOptions.combineLabels = (minValue, maxValue) => {
|
|
561
|
-
return minValue + ' - ' + maxValue;
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
if (this.viewOptions.logScale && this.viewOptions.floor === 0) {
|
|
565
|
-
throw Error("Can't use floor=0 with logarithmic scale");
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
applyStepsArrayOptions() {
|
|
569
|
-
this.viewOptions.floor = 0;
|
|
570
|
-
this.viewOptions.ceil = this.viewOptions.stepsArray.length - 1;
|
|
571
|
-
this.viewOptions.step = 1;
|
|
572
|
-
if (ValueHelper.isNullOrUndefined(this.viewOptions.translate)) {
|
|
573
|
-
this.viewOptions.translate = (modelValue) => {
|
|
574
|
-
if (this.viewOptions.bindIndexForStepsArray) {
|
|
575
|
-
return String(this.getStepValue(modelValue));
|
|
576
|
-
}
|
|
577
|
-
return String(modelValue);
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
applyFloorCeilOptions() {
|
|
582
|
-
if (ValueHelper.isNullOrUndefined(this.viewOptions.step)) {
|
|
583
|
-
this.viewOptions.step = 1;
|
|
584
|
-
}
|
|
585
|
-
else {
|
|
586
|
-
this.viewOptions.step = +this.viewOptions.step;
|
|
587
|
-
if (this.viewOptions.step <= 0) {
|
|
588
|
-
this.viewOptions.step = 1;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
if (ValueHelper.isNullOrUndefined(this.viewOptions.ceil) || ValueHelper.isNullOrUndefined(this.viewOptions.floor)) {
|
|
592
|
-
throw Error('floor and ceil options must be supplied');
|
|
593
|
-
}
|
|
594
|
-
this.viewOptions.ceil = +this.viewOptions.ceil;
|
|
595
|
-
this.viewOptions.floor = +this.viewOptions.floor;
|
|
596
|
-
if (ValueHelper.isNullOrUndefined(this.viewOptions.translate)) {
|
|
597
|
-
this.viewOptions.translate = (value) => String(value);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
// Resets slider
|
|
601
|
-
resetSlider(rebindEvents = true) {
|
|
602
|
-
this.manageElementsStyle();
|
|
603
|
-
this.addAccessibility();
|
|
604
|
-
this.updateCeilLabel();
|
|
605
|
-
this.updateFloorLabel();
|
|
606
|
-
if (rebindEvents) {
|
|
607
|
-
this.unbindEvents();
|
|
608
|
-
this.manageEventsBindings();
|
|
609
|
-
}
|
|
610
|
-
this.updateDisabledState();
|
|
611
|
-
this.updateAriaLabel();
|
|
612
|
-
this.calculateViewDimensions();
|
|
613
|
-
this.refocusPointerIfNeeded();
|
|
614
|
-
}
|
|
615
|
-
// Sets focus on the specified pointer
|
|
616
|
-
focusPointer(pointerType) {
|
|
617
|
-
// If not supplied, use min pointer as default
|
|
618
|
-
if (pointerType !== PointerType.Min && pointerType !== PointerType.Max) {
|
|
619
|
-
pointerType = PointerType.Min;
|
|
620
|
-
}
|
|
621
|
-
if (pointerType === PointerType.Min) {
|
|
622
|
-
this.minHandleElement?.focus();
|
|
623
|
-
}
|
|
624
|
-
else if (this.range && pointerType === PointerType.Max) {
|
|
625
|
-
this.maxHandleElement?.focus();
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
refocusPointerIfNeeded() {
|
|
629
|
-
if (!ValueHelper.isNullOrUndefined(this.currentFocusPointer)) {
|
|
630
|
-
this.onPointerFocus(this.currentFocusPointer);
|
|
631
|
-
const element = this.getPointerElement(this.currentFocusPointer);
|
|
632
|
-
element?.focus();
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
// Update each elements style based on options
|
|
636
|
-
manageElementsStyle() {
|
|
637
|
-
this.updateScale();
|
|
638
|
-
this.floorLabelElement?.setAlwaysHide(this.viewOptions.showTicksValues || this.viewOptions.hideLimitLabels);
|
|
639
|
-
this.ceilLabelElement?.setAlwaysHide(this.viewOptions.showTicksValues || this.viewOptions.hideLimitLabels);
|
|
640
|
-
const hideLabelsForTicks = this.viewOptions.showTicksValues && !this.intermediateTicks;
|
|
641
|
-
this.minHandleLabelElement?.setAlwaysHide(hideLabelsForTicks || this.viewOptions.hidePointerLabels);
|
|
642
|
-
this.maxHandleLabelElement?.setAlwaysHide(hideLabelsForTicks || !this.range || this.viewOptions.hidePointerLabels);
|
|
643
|
-
this.combinedLabelElement?.setAlwaysHide(hideLabelsForTicks || !this.range || this.viewOptions.hidePointerLabels);
|
|
644
|
-
this.selectionBarElement?.setAlwaysHide(!this.range && !this.viewOptions.showSelectionBar);
|
|
645
|
-
this.leftOuterSelectionBarElement?.setAlwaysHide(!this.range || !this.viewOptions.showOuterSelectionBars);
|
|
646
|
-
this.rightOuterSelectionBarElement?.setAlwaysHide(!this.range || !this.viewOptions.showOuterSelectionBars);
|
|
647
|
-
this.fullBarTransparentClass = this.range && this.viewOptions.showOuterSelectionBars;
|
|
648
|
-
this.selectionBarDraggableClass = this.viewOptions.draggableRange && !this.viewOptions.onlyBindHandles;
|
|
649
|
-
this.ticksUnderValuesClass = this.intermediateTicks && this.options.showTicksValues;
|
|
650
|
-
if (this.sliderElementVerticalClass !== this.viewOptions.vertical) {
|
|
651
|
-
this.updateVerticalState();
|
|
652
|
-
// The above change in host component class will not be applied until the end of this cycle
|
|
653
|
-
// However, functions calculating the slider position expect the slider to be already styled as vertical
|
|
654
|
-
// So as a workaround, we need to reset the slider once again to compute the correct values
|
|
655
|
-
setTimeout(() => {
|
|
656
|
-
this.resetSlider();
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
// Changing animate class may interfere with slider reset/initialisation, so we should set it separately,
|
|
660
|
-
// after all is properly set up
|
|
661
|
-
if (this.sliderElementAnimateClass !== this.viewOptions.animate) {
|
|
662
|
-
setTimeout(() => {
|
|
663
|
-
this.sliderElementAnimateClass = this.viewOptions.animate;
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
this.updateRotate();
|
|
667
|
-
}
|
|
668
|
-
// Manage the events bindings based on readOnly and disabled options
|
|
669
|
-
manageEventsBindings() {
|
|
670
|
-
if (this.viewOptions.disabled || this.viewOptions.readOnly) {
|
|
671
|
-
this.unbindEvents();
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
this.bindEvents();
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
// Set the disabled state based on disabled option
|
|
678
|
-
updateDisabledState() {
|
|
679
|
-
this.sliderElementDisabledAttr = this.viewOptions.disabled ? 'disabled' : undefined;
|
|
680
|
-
}
|
|
681
|
-
// Set the aria-label state based on ariaLabel option
|
|
682
|
-
updateAriaLabel() {
|
|
683
|
-
this.sliderElementAriaLabel = this.viewOptions.ariaLabel || 'nxg-slider';
|
|
684
|
-
}
|
|
685
|
-
// Set vertical state based on vertical option
|
|
686
|
-
updateVerticalState() {
|
|
687
|
-
this.sliderElementVerticalClass = this.viewOptions.vertical;
|
|
688
|
-
for (const element of this.getAllSliderElements()) {
|
|
689
|
-
// This is also called before ngAfterInit, so need to check that view child bindings work
|
|
690
|
-
if (!ValueHelper.isNullOrUndefined(element)) {
|
|
691
|
-
element.setVertical(this.viewOptions.vertical);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
updateScale() {
|
|
696
|
-
for (const element of this.getAllSliderElements()) {
|
|
697
|
-
element.setScale(this.viewOptions.scale);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
updateRotate() {
|
|
701
|
-
for (const element of this.getAllSliderElements()) {
|
|
702
|
-
element.setRotate(this.viewOptions.rotate);
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
getAllSliderElements() {
|
|
706
|
-
return [
|
|
707
|
-
this.leftOuterSelectionBarElement,
|
|
708
|
-
this.rightOuterSelectionBarElement,
|
|
709
|
-
this.fullBarElement,
|
|
710
|
-
this.selectionBarElement,
|
|
711
|
-
this.minHandleElement,
|
|
712
|
-
this.maxHandleElement,
|
|
713
|
-
this.floorLabelElement,
|
|
714
|
-
this.ceilLabelElement,
|
|
715
|
-
this.minHandleLabelElement,
|
|
716
|
-
this.maxHandleLabelElement,
|
|
717
|
-
this.combinedLabelElement,
|
|
718
|
-
this.ticksElement
|
|
719
|
-
];
|
|
720
|
-
}
|
|
721
|
-
// Initialize slider handles positions and labels
|
|
722
|
-
// Run only once during initialization and every time view port changes size
|
|
723
|
-
initHandles() {
|
|
724
|
-
this.updateLowHandle(this.valueToPosition(this.viewLowValue));
|
|
725
|
-
/*
|
|
726
|
-
the order here is important since the selection bar should be
|
|
727
|
-
updated after the high handle but before the combined label
|
|
728
|
-
*/
|
|
729
|
-
if (this.range) {
|
|
730
|
-
this.updateHighHandle(this.valueToPosition(this.viewHighValue));
|
|
731
|
-
}
|
|
732
|
-
this.updateSelectionBar();
|
|
733
|
-
if (this.range) {
|
|
734
|
-
this.updateCombinedLabel();
|
|
735
|
-
}
|
|
736
|
-
this.updateTicksScale();
|
|
737
|
-
}
|
|
738
|
-
// Adds accessibility attributes, run only once during initialization
|
|
739
|
-
addAccessibility() {
|
|
740
|
-
this.updateAriaAttributes();
|
|
741
|
-
this.minHandleElement.role = 'slider';
|
|
742
|
-
if (this.viewOptions.keyboardSupport && !(this.viewOptions.readOnly || this.viewOptions.disabled)) {
|
|
743
|
-
this.minHandleElement.tabindex = '0';
|
|
744
|
-
}
|
|
745
|
-
else {
|
|
746
|
-
this.minHandleElement.tabindex = '';
|
|
747
|
-
}
|
|
748
|
-
this.minHandleElement.ariaOrientation =
|
|
749
|
-
this.viewOptions.vertical || this.viewOptions.rotate !== 0 ? 'vertical' : 'horizontal';
|
|
750
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabel)) {
|
|
751
|
-
this.minHandleElement.ariaLabel = this.viewOptions.ariaLabel;
|
|
752
|
-
}
|
|
753
|
-
else if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelledBy)) {
|
|
754
|
-
this.minHandleElement.ariaLabelledBy = this.viewOptions.ariaLabelledBy;
|
|
755
|
-
}
|
|
756
|
-
if (this.range) {
|
|
757
|
-
this.maxHandleElement.role = 'slider';
|
|
758
|
-
if (this.viewOptions.keyboardSupport && !(this.viewOptions.readOnly || this.viewOptions.disabled)) {
|
|
759
|
-
this.maxHandleElement.tabindex = '0';
|
|
760
|
-
}
|
|
761
|
-
else {
|
|
762
|
-
this.maxHandleElement.tabindex = '';
|
|
763
|
-
}
|
|
764
|
-
this.maxHandleElement.ariaOrientation =
|
|
765
|
-
this.viewOptions.vertical || this.viewOptions.rotate !== 0 ? 'vertical' : 'horizontal';
|
|
766
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelHigh)) {
|
|
767
|
-
this.maxHandleElement.ariaLabel = this.viewOptions.ariaLabelHigh;
|
|
768
|
-
}
|
|
769
|
-
else if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelledByHigh)) {
|
|
770
|
-
this.maxHandleElement.ariaLabelledBy = this.viewOptions.ariaLabelledByHigh;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
// Updates aria attributes according to current values
|
|
775
|
-
updateAriaAttributes() {
|
|
776
|
-
this.minHandleElement.ariaValueNow = (+this.value).toString();
|
|
777
|
-
this.minHandleElement.ariaValueText = this.viewOptions.translate(+this.value, LabelType.Low);
|
|
778
|
-
this.minHandleElement.ariaValueMin = this.viewOptions.floor.toString();
|
|
779
|
-
this.minHandleElement.ariaValueMax = this.viewOptions.ceil.toString();
|
|
780
|
-
if (this.range) {
|
|
781
|
-
this.maxHandleElement.ariaValueNow = (+this.highValue).toString();
|
|
782
|
-
this.maxHandleElement.ariaValueText = this.viewOptions.translate(+this.highValue, LabelType.High);
|
|
783
|
-
this.maxHandleElement.ariaValueMin = this.viewOptions.floor.toString();
|
|
784
|
-
this.maxHandleElement.ariaValueMax = this.viewOptions.ceil.toString();
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
// Calculate dimensions that are dependent on view port size
|
|
788
|
-
// Run once during initialization and every time view port changes size.
|
|
789
|
-
calculateViewDimensions() {
|
|
790
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.handleDimension)) {
|
|
791
|
-
this.minHandleElement.setDimension(this.viewOptions.handleDimension);
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
this.minHandleElement.calculateDimension();
|
|
795
|
-
}
|
|
796
|
-
const handleWidth = this.minHandleElement.dimension;
|
|
797
|
-
this.handleHalfDimension = handleWidth / 2;
|
|
798
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.barDimension)) {
|
|
799
|
-
this.fullBarElement.setDimension(this.viewOptions.barDimension);
|
|
800
|
-
}
|
|
801
|
-
else {
|
|
802
|
-
this.fullBarElement.calculateDimension();
|
|
803
|
-
}
|
|
804
|
-
this.maxHandlePosition = this.fullBarElement.dimension - handleWidth;
|
|
805
|
-
if (this.initHasRun) {
|
|
806
|
-
this.updateFloorLabel();
|
|
807
|
-
this.updateCeilLabel();
|
|
808
|
-
this.initHandles();
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
calculateViewDimensionsAndDetectChanges() {
|
|
812
|
-
this.calculateViewDimensions();
|
|
813
|
-
if (!this.isRefDestroyed()) {
|
|
814
|
-
this.changeDetectionRef.detectChanges();
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* If the slider reference is already destroyed
|
|
819
|
-
* @returns boolean - true if ref is destroyed
|
|
820
|
-
*/
|
|
821
|
-
isRefDestroyed() {
|
|
822
|
-
return this.changeDetectionRef['destroyed'];
|
|
823
|
-
}
|
|
824
|
-
// Update the ticks position
|
|
825
|
-
updateTicksScale() {
|
|
826
|
-
if (!this.viewOptions.showTicks) {
|
|
827
|
-
setTimeout(() => {
|
|
828
|
-
this.sliderElementWithLegendClass = false;
|
|
829
|
-
});
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
832
|
-
const ticksArray = !ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray)
|
|
833
|
-
? this.viewOptions.ticksArray
|
|
834
|
-
: this.getTicksArray();
|
|
835
|
-
const translate = this.viewOptions.vertical ? 'translateY' : 'translateX';
|
|
836
|
-
if (this.viewOptions.rightToLeft) {
|
|
837
|
-
ticksArray.reverse();
|
|
838
|
-
}
|
|
839
|
-
const tickValueStep = !ValueHelper.isNullOrUndefined(this.viewOptions.tickValueStep)
|
|
840
|
-
? this.viewOptions.tickValueStep
|
|
841
|
-
: !ValueHelper.isNullOrUndefined(this.viewOptions.tickStep)
|
|
842
|
-
? this.viewOptions.tickStep
|
|
843
|
-
: this.viewOptions.step;
|
|
844
|
-
let hasAtLeastOneLegend = false;
|
|
845
|
-
const newTicks = ticksArray.map((value) => {
|
|
846
|
-
let position = this.valueToPosition(value);
|
|
847
|
-
if (this.viewOptions.vertical) {
|
|
848
|
-
position = this.maxHandlePosition - position;
|
|
849
|
-
}
|
|
850
|
-
const translation = translate + '(' + Math.round(position) + 'px)';
|
|
851
|
-
const tick = new Tick();
|
|
852
|
-
tick.selected = this.isTickSelected(value);
|
|
853
|
-
tick.style = {
|
|
854
|
-
'-webkit-transform': translation,
|
|
855
|
-
'-moz-transform': translation,
|
|
856
|
-
'-o-transform': translation,
|
|
857
|
-
'-ms-transform': translation,
|
|
858
|
-
transform: translation
|
|
859
|
-
};
|
|
860
|
-
if (tick.selected && !ValueHelper.isNullOrUndefined(this.viewOptions.getSelectionBarColor)) {
|
|
861
|
-
tick.style['background-color'] = this.getSelectionBarColor();
|
|
862
|
-
}
|
|
863
|
-
if (!tick.selected && !ValueHelper.isNullOrUndefined(this.viewOptions.getTickColor)) {
|
|
864
|
-
tick.style['background-color'] = this.getTickColor(value);
|
|
865
|
-
}
|
|
866
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.ticksTooltip)) {
|
|
867
|
-
tick.tooltip = this.viewOptions.ticksTooltip(value);
|
|
868
|
-
tick.tooltipPlacement = this.viewOptions.vertical ? 'right' : 'top';
|
|
869
|
-
}
|
|
870
|
-
if (this.viewOptions.showTicksValues &&
|
|
871
|
-
!ValueHelper.isNullOrUndefined(tickValueStep) &&
|
|
872
|
-
MathHelper.isModuloWithinPrecisionLimit(value, tickValueStep, this.viewOptions.precisionLimit)) {
|
|
873
|
-
tick.value = this.getDisplayValue(value, LabelType.TickValue);
|
|
874
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.ticksValuesTooltip)) {
|
|
875
|
-
tick.valueTooltip = this.viewOptions.ticksValuesTooltip(value);
|
|
876
|
-
tick.valueTooltipPlacement = this.viewOptions.vertical ? 'right' : 'top';
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
let legend;
|
|
880
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray)) {
|
|
881
|
-
const step = this.viewOptions.stepsArray[value];
|
|
882
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.getStepLegend)) {
|
|
883
|
-
legend = this.viewOptions.getStepLegend(step);
|
|
884
|
-
}
|
|
885
|
-
else if (!ValueHelper.isNullOrUndefined(step)) {
|
|
886
|
-
legend = step.legend;
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
else if (!ValueHelper.isNullOrUndefined(this.viewOptions.getLegend)) {
|
|
890
|
-
legend = this.viewOptions.getLegend(value);
|
|
891
|
-
}
|
|
892
|
-
if (!ValueHelper.isNullOrUndefined(legend)) {
|
|
893
|
-
tick.legend = legend;
|
|
894
|
-
hasAtLeastOneLegend = true;
|
|
895
|
-
}
|
|
896
|
-
return tick;
|
|
897
|
-
});
|
|
898
|
-
setTimeout(() => {
|
|
899
|
-
this.sliderElementWithLegendClass = hasAtLeastOneLegend;
|
|
900
|
-
});
|
|
901
|
-
// We should avoid re-creating the ticks array if possible
|
|
902
|
-
// This both improves performance and makes CSS animations work correctly
|
|
903
|
-
if (!ValueHelper.isNullOrUndefined(this.ticks) && this.ticks.length === newTicks.length) {
|
|
904
|
-
for (let i = 0; i < newTicks.length; ++i) {
|
|
905
|
-
Object.assign(this.ticks[i], newTicks[i]);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
else {
|
|
909
|
-
this.ticks = newTicks;
|
|
910
|
-
}
|
|
911
|
-
if (!this.isRefDestroyed()) {
|
|
912
|
-
this.changeDetectionRef.detectChanges();
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
getTicksArray() {
|
|
916
|
-
const step = !ValueHelper.isNullOrUndefined(this.viewOptions.tickStep)
|
|
917
|
-
? this.viewOptions.tickStep
|
|
918
|
-
: this.viewOptions.step;
|
|
919
|
-
const ticksArray = [];
|
|
920
|
-
const numberOfValues = 1 +
|
|
921
|
-
Math.floor(MathHelper.roundToPrecisionLimit(Math.abs(this.viewOptions.ceil - this.viewOptions.floor) / step, this.viewOptions.precisionLimit));
|
|
922
|
-
for (let index = 0; index < numberOfValues; ++index) {
|
|
923
|
-
ticksArray.push(MathHelper.roundToPrecisionLimit(this.viewOptions.floor + step * index, this.viewOptions.precisionLimit));
|
|
924
|
-
}
|
|
925
|
-
return ticksArray;
|
|
926
|
-
}
|
|
927
|
-
isTickSelected(value) {
|
|
928
|
-
if (!this.range) {
|
|
929
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)) {
|
|
930
|
-
const center = this.viewOptions.showSelectionBarFromValue;
|
|
931
|
-
if (this.viewLowValue > center && value >= center && value <= this.viewLowValue) {
|
|
932
|
-
return true;
|
|
933
|
-
}
|
|
934
|
-
else if (this.viewLowValue < center && value <= center && value >= this.viewLowValue) {
|
|
935
|
-
return true;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
else if (this.viewOptions.showSelectionBarEnd) {
|
|
939
|
-
if (value >= this.viewLowValue) {
|
|
940
|
-
return true;
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
else if (this.viewOptions.showSelectionBar && value <= this.viewLowValue) {
|
|
944
|
-
return true;
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
if (this.range && value >= this.viewLowValue && value <= this.viewHighValue) {
|
|
948
|
-
return true;
|
|
949
|
-
}
|
|
950
|
-
return false;
|
|
951
|
-
}
|
|
952
|
-
// Update position of the floor label
|
|
953
|
-
updateFloorLabel() {
|
|
954
|
-
if (!this.floorLabelElement.alwaysHide) {
|
|
955
|
-
this.floorLabelElement.setValue(this.getDisplayValue(this.viewOptions.floor, LabelType.Floor));
|
|
956
|
-
this.floorLabelElement.calculateDimension();
|
|
957
|
-
const position = this.viewOptions.rightToLeft
|
|
958
|
-
? this.fullBarElement.dimension - this.floorLabelElement.dimension
|
|
959
|
-
: 0;
|
|
960
|
-
this.floorLabelElement.setPosition(position);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
// Update position of the ceiling label
|
|
964
|
-
updateCeilLabel() {
|
|
965
|
-
if (!this.ceilLabelElement.alwaysHide) {
|
|
966
|
-
this.ceilLabelElement.setValue(this.getDisplayValue(this.viewOptions.ceil, LabelType.Ceil));
|
|
967
|
-
this.ceilLabelElement.calculateDimension();
|
|
968
|
-
const position = this.viewOptions.rightToLeft
|
|
969
|
-
? 0
|
|
970
|
-
: this.fullBarElement.dimension - this.ceilLabelElement.dimension;
|
|
971
|
-
this.ceilLabelElement.setPosition(position);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
// Update slider handles and label positions
|
|
975
|
-
updateHandles(which, newPos) {
|
|
976
|
-
if (which === PointerType.Min) {
|
|
977
|
-
this.updateLowHandle(newPos);
|
|
978
|
-
}
|
|
979
|
-
else if (which === PointerType.Max) {
|
|
980
|
-
this.updateHighHandle(newPos);
|
|
981
|
-
}
|
|
982
|
-
this.updateSelectionBar();
|
|
983
|
-
this.updateTicksScale();
|
|
984
|
-
if (this.range) {
|
|
985
|
-
this.updateCombinedLabel();
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
// Helper function to work out the position for handle labels depending on RTL or not
|
|
989
|
-
getHandleLabelPos(labelType, newPos) {
|
|
990
|
-
const labelDimension = labelType === PointerType.Min ? this.minHandleLabelElement.dimension : this.maxHandleLabelElement.dimension;
|
|
991
|
-
const nearHandlePos = newPos - labelDimension / 2 + this.handleHalfDimension;
|
|
992
|
-
const endOfBarPos = this.fullBarElement.dimension - labelDimension;
|
|
993
|
-
if (!this.viewOptions.boundPointerLabels) {
|
|
994
|
-
return nearHandlePos;
|
|
995
|
-
}
|
|
996
|
-
if ((this.viewOptions.rightToLeft && labelType === PointerType.Min) ||
|
|
997
|
-
(!this.viewOptions.rightToLeft && labelType === PointerType.Max)) {
|
|
998
|
-
return Math.min(nearHandlePos, endOfBarPos);
|
|
999
|
-
}
|
|
1000
|
-
else {
|
|
1001
|
-
return Math.min(Math.max(nearHandlePos, 0), endOfBarPos);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
// Update low slider handle position and label
|
|
1005
|
-
updateLowHandle(newPos) {
|
|
1006
|
-
this.minHandleElement.setPosition(newPos);
|
|
1007
|
-
this.minHandleLabelElement.setValue(this.getDisplayValue(this.viewLowValue, LabelType.Low));
|
|
1008
|
-
this.minHandleLabelElement.setPosition(this.getHandleLabelPos(PointerType.Min, newPos));
|
|
1009
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.getPointerColor)) {
|
|
1010
|
-
this.minPointerStyle = {
|
|
1011
|
-
backgroundColor: this.getPointerColor(PointerType.Min)
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
if (this.viewOptions.autoHideLimitLabels) {
|
|
1015
|
-
this.updateFloorAndCeilLabelsVisibility();
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
// Update high slider handle position and label
|
|
1019
|
-
updateHighHandle(newPos) {
|
|
1020
|
-
this.maxHandleElement.setPosition(newPos);
|
|
1021
|
-
this.maxHandleLabelElement.setValue(this.getDisplayValue(this.viewHighValue, LabelType.High));
|
|
1022
|
-
this.maxHandleLabelElement.setPosition(this.getHandleLabelPos(PointerType.Max, newPos));
|
|
1023
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.getPointerColor)) {
|
|
1024
|
-
this.maxPointerStyle = {
|
|
1025
|
-
backgroundColor: this.getPointerColor(PointerType.Max)
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
if (this.viewOptions.autoHideLimitLabels) {
|
|
1029
|
-
this.updateFloorAndCeilLabelsVisibility();
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
// Show/hide floor/ceiling label
|
|
1033
|
-
updateFloorAndCeilLabelsVisibility() {
|
|
1034
|
-
// Show based only on hideLimitLabels if pointer labels are hidden
|
|
1035
|
-
if (this.viewOptions.hidePointerLabels) {
|
|
1036
|
-
return;
|
|
1037
|
-
}
|
|
1038
|
-
let floorLabelHidden = false;
|
|
1039
|
-
let ceilLabelHidden = false;
|
|
1040
|
-
const isMinLabelAtFloor = this.isLabelBelowFloorLabel(this.minHandleLabelElement);
|
|
1041
|
-
const isMinLabelAtCeil = this.isLabelAboveCeilLabel(this.minHandleLabelElement);
|
|
1042
|
-
const isMaxLabelAtCeil = this.isLabelAboveCeilLabel(this.maxHandleLabelElement);
|
|
1043
|
-
const isCombinedLabelAtFloor = this.isLabelBelowFloorLabel(this.combinedLabelElement);
|
|
1044
|
-
const isCombinedLabelAtCeil = this.isLabelAboveCeilLabel(this.combinedLabelElement);
|
|
1045
|
-
if (isMinLabelAtFloor) {
|
|
1046
|
-
floorLabelHidden = true;
|
|
1047
|
-
this.floorLabelElement.hide();
|
|
1048
|
-
}
|
|
1049
|
-
else {
|
|
1050
|
-
floorLabelHidden = false;
|
|
1051
|
-
this.floorLabelElement.show();
|
|
1052
|
-
}
|
|
1053
|
-
if (isMinLabelAtCeil) {
|
|
1054
|
-
ceilLabelHidden = true;
|
|
1055
|
-
this.ceilLabelElement.hide();
|
|
1056
|
-
}
|
|
1057
|
-
else {
|
|
1058
|
-
ceilLabelHidden = false;
|
|
1059
|
-
this.ceilLabelElement.show();
|
|
1060
|
-
}
|
|
1061
|
-
if (this.range) {
|
|
1062
|
-
const hideCeil = this.combinedLabelElement.isVisible() ? isCombinedLabelAtCeil : isMaxLabelAtCeil;
|
|
1063
|
-
const hideFloor = this.combinedLabelElement.isVisible() ? isCombinedLabelAtFloor : isMinLabelAtFloor;
|
|
1064
|
-
if (hideCeil) {
|
|
1065
|
-
this.ceilLabelElement.hide();
|
|
1066
|
-
}
|
|
1067
|
-
else if (!ceilLabelHidden) {
|
|
1068
|
-
this.ceilLabelElement.show();
|
|
1069
|
-
}
|
|
1070
|
-
// Hide or show floor label
|
|
1071
|
-
if (hideFloor) {
|
|
1072
|
-
this.floorLabelElement.hide();
|
|
1073
|
-
}
|
|
1074
|
-
else if (!floorLabelHidden) {
|
|
1075
|
-
this.floorLabelElement.show();
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
isLabelBelowFloorLabel(label) {
|
|
1080
|
-
const pos = label.position;
|
|
1081
|
-
const dim = label.dimension;
|
|
1082
|
-
const floorPos = this.floorLabelElement.position;
|
|
1083
|
-
const floorDim = this.floorLabelElement.dimension;
|
|
1084
|
-
return this.viewOptions.rightToLeft ? pos + dim >= floorPos - 2 : pos <= floorPos + floorDim + 2;
|
|
1085
|
-
}
|
|
1086
|
-
isLabelAboveCeilLabel(label) {
|
|
1087
|
-
const pos = label.position;
|
|
1088
|
-
const dim = label.dimension;
|
|
1089
|
-
const ceilPos = this.ceilLabelElement.position;
|
|
1090
|
-
const ceilDim = this.ceilLabelElement.dimension;
|
|
1091
|
-
return this.viewOptions.rightToLeft ? pos <= ceilPos + ceilDim + 2 : pos + dim >= ceilPos - 2;
|
|
1092
|
-
}
|
|
1093
|
-
// Update slider selection bar, combined label and range label
|
|
1094
|
-
updateSelectionBar() {
|
|
1095
|
-
let position = 0;
|
|
1096
|
-
let dimension = 0;
|
|
1097
|
-
const isSelectionBarFromRight = this.viewOptions.rightToLeft
|
|
1098
|
-
? !this.viewOptions.showSelectionBarEnd
|
|
1099
|
-
: this.viewOptions.showSelectionBarEnd;
|
|
1100
|
-
const positionForRange = this.viewOptions.rightToLeft
|
|
1101
|
-
? this.maxHandleElement.position + this.handleHalfDimension
|
|
1102
|
-
: this.minHandleElement.position + this.handleHalfDimension;
|
|
1103
|
-
if (this.range) {
|
|
1104
|
-
dimension = Math.abs(this.maxHandleElement.position - this.minHandleElement.position);
|
|
1105
|
-
position = positionForRange;
|
|
1106
|
-
}
|
|
1107
|
-
else {
|
|
1108
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)) {
|
|
1109
|
-
const center = this.viewOptions.showSelectionBarFromValue;
|
|
1110
|
-
const centerPosition = this.valueToPosition(center);
|
|
1111
|
-
const isModelGreaterThanCenter = this.viewOptions.rightToLeft
|
|
1112
|
-
? this.viewLowValue <= center
|
|
1113
|
-
: this.viewLowValue > center;
|
|
1114
|
-
if (isModelGreaterThanCenter) {
|
|
1115
|
-
dimension = this.minHandleElement.position - centerPosition;
|
|
1116
|
-
position = centerPosition + this.handleHalfDimension;
|
|
1117
|
-
}
|
|
1118
|
-
else {
|
|
1119
|
-
dimension = centerPosition - this.minHandleElement.position;
|
|
1120
|
-
position = this.minHandleElement.position + this.handleHalfDimension;
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
else if (isSelectionBarFromRight) {
|
|
1124
|
-
dimension = Math.ceil(Math.abs(this.maxHandlePosition - this.minHandleElement.position) + this.handleHalfDimension);
|
|
1125
|
-
position = Math.floor(this.minHandleElement.position + this.handleHalfDimension);
|
|
1126
|
-
}
|
|
1127
|
-
else {
|
|
1128
|
-
dimension = this.minHandleElement.position + this.handleHalfDimension;
|
|
1129
|
-
position = 0;
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
this.selectionBarElement.setDimension(dimension);
|
|
1133
|
-
this.selectionBarElement.setPosition(position);
|
|
1134
|
-
if (this.range && this.viewOptions.showOuterSelectionBars) {
|
|
1135
|
-
if (this.viewOptions.rightToLeft) {
|
|
1136
|
-
this.rightOuterSelectionBarElement.setDimension(position);
|
|
1137
|
-
this.rightOuterSelectionBarElement.setPosition(0);
|
|
1138
|
-
this.fullBarElement.calculateDimension();
|
|
1139
|
-
this.leftOuterSelectionBarElement.setDimension(this.fullBarElement.dimension - (position + dimension));
|
|
1140
|
-
this.leftOuterSelectionBarElement.setPosition(position + dimension);
|
|
1141
|
-
}
|
|
1142
|
-
else {
|
|
1143
|
-
this.leftOuterSelectionBarElement.setDimension(position);
|
|
1144
|
-
this.leftOuterSelectionBarElement.setPosition(0);
|
|
1145
|
-
this.fullBarElement.calculateDimension();
|
|
1146
|
-
this.rightOuterSelectionBarElement.setDimension(this.fullBarElement.dimension - (position + dimension));
|
|
1147
|
-
this.rightOuterSelectionBarElement.setPosition(position + dimension);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.getSelectionBarColor)) {
|
|
1151
|
-
const color = this.getSelectionBarColor();
|
|
1152
|
-
this.barStyle = {
|
|
1153
|
-
backgroundColor: color
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
else if (!ValueHelper.isNullOrUndefined(this.viewOptions.selectionBarGradient)) {
|
|
1157
|
-
const offset = !ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)
|
|
1158
|
-
? this.valueToPosition(this.viewOptions.showSelectionBarFromValue)
|
|
1159
|
-
: 0;
|
|
1160
|
-
const reversed = (offset - position > 0 && !isSelectionBarFromRight) || (offset - position <= 0 && isSelectionBarFromRight);
|
|
1161
|
-
const direction = this.viewOptions.vertical ? (reversed ? 'bottom' : 'top') : reversed ? 'left' : 'right';
|
|
1162
|
-
this.barStyle = {
|
|
1163
|
-
backgroundImage: 'linear-gradient(to ' +
|
|
1164
|
-
direction +
|
|
1165
|
-
', ' +
|
|
1166
|
-
this.viewOptions.selectionBarGradient.from +
|
|
1167
|
-
' 0%,' +
|
|
1168
|
-
this.viewOptions.selectionBarGradient.to +
|
|
1169
|
-
' 100%)'
|
|
1170
|
-
};
|
|
1171
|
-
if (this.viewOptions.vertical) {
|
|
1172
|
-
this.barStyle.backgroundPosition =
|
|
1173
|
-
'center ' + (offset + dimension + position + (reversed ? -this.handleHalfDimension : 0)) + 'px';
|
|
1174
|
-
this.barStyle.backgroundSize = '100% ' + (this.fullBarElement.dimension - this.handleHalfDimension) + 'px';
|
|
1175
|
-
}
|
|
1176
|
-
else {
|
|
1177
|
-
this.barStyle.backgroundPosition = offset - position + (reversed ? this.handleHalfDimension : 0) + 'px center';
|
|
1178
|
-
this.barStyle.backgroundSize = this.fullBarElement.dimension - this.handleHalfDimension + 'px 100%';
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
// Wrapper around the getSelectionBarColor of the user to pass to correct parameters
|
|
1183
|
-
getSelectionBarColor() {
|
|
1184
|
-
if (this.range) {
|
|
1185
|
-
return this.viewOptions.getSelectionBarColor(this.value, this.highValue);
|
|
1186
|
-
}
|
|
1187
|
-
return this.viewOptions.getSelectionBarColor(this.value);
|
|
1188
|
-
}
|
|
1189
|
-
// Wrapper around the getPointerColor of the user to pass to correct parameters
|
|
1190
|
-
getPointerColor(pointerType) {
|
|
1191
|
-
if (pointerType === PointerType.Max) {
|
|
1192
|
-
return this.viewOptions.getPointerColor(this.highValue, pointerType);
|
|
1193
|
-
}
|
|
1194
|
-
return this.viewOptions.getPointerColor(this.value, pointerType);
|
|
1195
|
-
}
|
|
1196
|
-
// Wrapper around the getTickColor of the user to pass to correct parameters
|
|
1197
|
-
getTickColor(value) {
|
|
1198
|
-
return this.viewOptions.getTickColor(value);
|
|
1199
|
-
}
|
|
1200
|
-
// Update combined label position and value
|
|
1201
|
-
updateCombinedLabel() {
|
|
1202
|
-
let isLabelOverlap = false;
|
|
1203
|
-
if (this.viewOptions.rightToLeft) {
|
|
1204
|
-
isLabelOverlap =
|
|
1205
|
-
this.minHandleLabelElement.position - this.minHandleLabelElement.dimension - 10 <=
|
|
1206
|
-
this.maxHandleLabelElement.position;
|
|
1207
|
-
}
|
|
1208
|
-
else {
|
|
1209
|
-
isLabelOverlap =
|
|
1210
|
-
this.minHandleLabelElement.position + this.minHandleLabelElement.dimension + 10 >=
|
|
1211
|
-
this.maxHandleLabelElement.position;
|
|
1212
|
-
}
|
|
1213
|
-
if (isLabelOverlap) {
|
|
1214
|
-
const lowDisplayValue = this.getDisplayValue(this.viewLowValue, LabelType.Low);
|
|
1215
|
-
const highDisplayValue = this.getDisplayValue(this.viewHighValue, LabelType.High);
|
|
1216
|
-
const combinedLabelValue = this.viewOptions.rightToLeft
|
|
1217
|
-
? this.viewOptions.combineLabels(highDisplayValue, lowDisplayValue)
|
|
1218
|
-
: this.viewOptions.combineLabels(lowDisplayValue, highDisplayValue);
|
|
1219
|
-
this.combinedLabelElement.setValue(combinedLabelValue);
|
|
1220
|
-
const pos = this.viewOptions.boundPointerLabels
|
|
1221
|
-
? Math.min(Math.max(this.selectionBarElement.position +
|
|
1222
|
-
this.selectionBarElement.dimension / 2 -
|
|
1223
|
-
this.combinedLabelElement.dimension / 2, 0), this.fullBarElement.dimension - this.combinedLabelElement.dimension)
|
|
1224
|
-
: this.selectionBarElement.position +
|
|
1225
|
-
this.selectionBarElement.dimension / 2 -
|
|
1226
|
-
this.combinedLabelElement.dimension / 2;
|
|
1227
|
-
this.combinedLabelElement.setPosition(pos);
|
|
1228
|
-
this.minHandleLabelElement.hide();
|
|
1229
|
-
this.maxHandleLabelElement.hide();
|
|
1230
|
-
this.combinedLabelElement.show();
|
|
1231
|
-
}
|
|
1232
|
-
else {
|
|
1233
|
-
this.updateHighHandle(this.valueToPosition(this.viewHighValue));
|
|
1234
|
-
this.updateLowHandle(this.valueToPosition(this.viewLowValue));
|
|
1235
|
-
this.maxHandleLabelElement.show();
|
|
1236
|
-
this.minHandleLabelElement.show();
|
|
1237
|
-
this.combinedLabelElement.hide();
|
|
1238
|
-
}
|
|
1239
|
-
if (this.viewOptions.autoHideLimitLabels) {
|
|
1240
|
-
this.updateFloorAndCeilLabelsVisibility();
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
// Return the translated value if a translate function is provided else the original value
|
|
1244
|
-
getDisplayValue(value, which) {
|
|
1245
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) {
|
|
1246
|
-
value = this.getStepValue(value);
|
|
1247
|
-
}
|
|
1248
|
-
return this.viewOptions.translate(value, which);
|
|
1249
|
-
}
|
|
1250
|
-
// Round value to step and precision based on minValue
|
|
1251
|
-
roundStep(value, customStep) {
|
|
1252
|
-
const step = !ValueHelper.isNullOrUndefined(customStep) ? customStep : this.viewOptions.step;
|
|
1253
|
-
let steppedDifference = MathHelper.roundToPrecisionLimit((value - this.viewOptions.floor) / step, this.viewOptions.precisionLimit);
|
|
1254
|
-
steppedDifference = Math.round(steppedDifference) * step;
|
|
1255
|
-
return MathHelper.roundToPrecisionLimit(this.viewOptions.floor + steppedDifference, this.viewOptions.precisionLimit);
|
|
1256
|
-
}
|
|
1257
|
-
// Translate value to pixel position
|
|
1258
|
-
valueToPosition(val) {
|
|
1259
|
-
let fn = ValueHelper.linearValueToPosition;
|
|
1260
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.customValueToPosition)) {
|
|
1261
|
-
fn = this.viewOptions.customValueToPosition;
|
|
1262
|
-
}
|
|
1263
|
-
else if (this.viewOptions.logScale) {
|
|
1264
|
-
fn = ValueHelper.logValueToPosition;
|
|
1265
|
-
}
|
|
1266
|
-
val = MathHelper.clampToRange(val, this.viewOptions.floor, this.viewOptions.ceil);
|
|
1267
|
-
let percent = fn(val, this.viewOptions.floor, this.viewOptions.ceil);
|
|
1268
|
-
if (ValueHelper.isNullOrUndefined(percent)) {
|
|
1269
|
-
percent = 0;
|
|
1270
|
-
}
|
|
1271
|
-
if (this.viewOptions.rightToLeft) {
|
|
1272
|
-
percent = 1 - percent;
|
|
1273
|
-
}
|
|
1274
|
-
return percent * this.maxHandlePosition;
|
|
1275
|
-
}
|
|
1276
|
-
// Translate position to model value
|
|
1277
|
-
positionToValue(position) {
|
|
1278
|
-
let percent = position / this.maxHandlePosition;
|
|
1279
|
-
if (this.viewOptions.rightToLeft) {
|
|
1280
|
-
percent = 1 - percent;
|
|
1281
|
-
}
|
|
1282
|
-
let fn = ValueHelper.linearPositionToValue;
|
|
1283
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.customPositionToValue)) {
|
|
1284
|
-
fn = this.viewOptions.customPositionToValue;
|
|
1285
|
-
}
|
|
1286
|
-
else if (this.viewOptions.logScale) {
|
|
1287
|
-
fn = ValueHelper.logPositionToValue;
|
|
1288
|
-
}
|
|
1289
|
-
const value = fn(percent, this.viewOptions.floor, this.viewOptions.ceil);
|
|
1290
|
-
return !ValueHelper.isNullOrUndefined(value) ? value : 0;
|
|
1291
|
-
}
|
|
1292
|
-
// Get the X-coordinate or Y-coordinate of an event
|
|
1293
|
-
getEventXY(event, targetTouchId) {
|
|
1294
|
-
if (event instanceof MouseEvent) {
|
|
1295
|
-
return this.viewOptions.vertical || this.viewOptions.rotate !== 0 ? event.clientY : event.clientX;
|
|
1296
|
-
}
|
|
1297
|
-
let touchIndex = 0;
|
|
1298
|
-
const touches = event.touches;
|
|
1299
|
-
if (!ValueHelper.isNullOrUndefined(targetTouchId)) {
|
|
1300
|
-
for (let i = 0; i < touches.length; i++) {
|
|
1301
|
-
if (touches[i].identifier === targetTouchId) {
|
|
1302
|
-
touchIndex = i;
|
|
1303
|
-
break;
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
// Return the target touch or if the target touch was not found in the event
|
|
1308
|
-
// returns the coordinates of the first touch
|
|
1309
|
-
return this.viewOptions.vertical || this.viewOptions.rotate !== 0
|
|
1310
|
-
? touches[touchIndex].clientY
|
|
1311
|
-
: touches[touchIndex].clientX;
|
|
1312
|
-
}
|
|
1313
|
-
// Compute the event position depending on whether the slider is horizontal or vertical
|
|
1314
|
-
getEventPosition(event, targetTouchId) {
|
|
1315
|
-
const sliderElementBoundingRect = this.elementRef.nativeElement.getBoundingClientRect();
|
|
1316
|
-
const sliderPos = this.viewOptions.vertical || this.viewOptions.rotate !== 0
|
|
1317
|
-
? sliderElementBoundingRect.bottom
|
|
1318
|
-
: sliderElementBoundingRect.left;
|
|
1319
|
-
let eventPos = 0;
|
|
1320
|
-
if (this.viewOptions.vertical || this.viewOptions.rotate !== 0) {
|
|
1321
|
-
eventPos = -this.getEventXY(event, targetTouchId) + sliderPos;
|
|
1322
|
-
}
|
|
1323
|
-
else {
|
|
1324
|
-
eventPos = this.getEventXY(event, targetTouchId) - sliderPos;
|
|
1325
|
-
}
|
|
1326
|
-
return eventPos * this.viewOptions.scale - this.handleHalfDimension;
|
|
1327
|
-
}
|
|
1328
|
-
// Get the handle closest to an event
|
|
1329
|
-
getNearestHandle(event) {
|
|
1330
|
-
if (!this.range) {
|
|
1331
|
-
return PointerType.Min;
|
|
1332
|
-
}
|
|
1333
|
-
const position = this.getEventPosition(event);
|
|
1334
|
-
const distanceMin = Math.abs(position - this.minHandleElement.position);
|
|
1335
|
-
const distanceMax = Math.abs(position - this.maxHandleElement.position);
|
|
1336
|
-
if (distanceMin < distanceMax) {
|
|
1337
|
-
return PointerType.Min;
|
|
1338
|
-
}
|
|
1339
|
-
else if (distanceMin > distanceMax) {
|
|
1340
|
-
return PointerType.Max;
|
|
1341
|
-
}
|
|
1342
|
-
else if (!this.viewOptions.rightToLeft) {
|
|
1343
|
-
// if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH
|
|
1344
|
-
return position < this.minHandleElement.position ? PointerType.Min : PointerType.Max;
|
|
1345
|
-
}
|
|
1346
|
-
// reverse in rtl
|
|
1347
|
-
return position > this.minHandleElement.position ? PointerType.Min : PointerType.Max;
|
|
1348
|
-
}
|
|
1349
|
-
// Bind mouse and touch events to slider handles
|
|
1350
|
-
bindEvents() {
|
|
1351
|
-
const draggableRange = this.viewOptions.draggableRange;
|
|
1352
|
-
if (!this.viewOptions.onlyBindHandles) {
|
|
1353
|
-
this.selectionBarElement.on('mousedown', (event) => this.onBarStart(draggableRange, event, true, true, undefined, true));
|
|
1354
|
-
}
|
|
1355
|
-
if (this.viewOptions.draggableRangeOnly) {
|
|
1356
|
-
this.minHandleElement.on('mousedown', (event) => this.onBarStart(draggableRange, event, true, true, PointerType.Min));
|
|
1357
|
-
this.maxHandleElement.on('mousedown', (event) => this.onBarStart(draggableRange, event, true, true, PointerType.Max));
|
|
1358
|
-
}
|
|
1359
|
-
else {
|
|
1360
|
-
this.minHandleElement.on('mousedown', (event) => this.onStart(event, true, true, PointerType.Min));
|
|
1361
|
-
if (this.range) {
|
|
1362
|
-
this.maxHandleElement.on('mousedown', (event) => this.onStart(event, true, true, PointerType.Max));
|
|
1363
|
-
}
|
|
1364
|
-
if (!this.viewOptions.onlyBindHandles) {
|
|
1365
|
-
this.fullBarElement.on('mousedown', (event) => this.onStart(event, true, true, undefined, true));
|
|
1366
|
-
this.ticksElement.on('mousedown', (event) => this.onStart(event, true, true, undefined, true, true));
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
if (!this.viewOptions.onlyBindHandles) {
|
|
1370
|
-
this.selectionBarElement.onPassive('touchstart', (event) => this.onBarStart(draggableRange, event, true, true, undefined, true));
|
|
1371
|
-
}
|
|
1372
|
-
if (this.viewOptions.draggableRangeOnly) {
|
|
1373
|
-
this.minHandleElement.onPassive('touchstart', (event) => this.onBarStart(draggableRange, event, true, true, PointerType.Min));
|
|
1374
|
-
this.maxHandleElement.onPassive('touchstart', (event) => this.onBarStart(draggableRange, event, true, true, PointerType.Max));
|
|
1375
|
-
}
|
|
1376
|
-
else {
|
|
1377
|
-
this.minHandleElement.onPassive('touchstart', (event) => this.onStart(event, true, true, PointerType.Min));
|
|
1378
|
-
if (this.range) {
|
|
1379
|
-
this.maxHandleElement.onPassive('touchstart', (event) => this.onStart(event, true, true, PointerType.Max));
|
|
1380
|
-
}
|
|
1381
|
-
if (!this.viewOptions.onlyBindHandles) {
|
|
1382
|
-
this.fullBarElement.onPassive('touchstart', (event) => this.onStart(event, true, true, undefined, true));
|
|
1383
|
-
this.ticksElement.onPassive('touchstart', (event) => this.onStart(event, false, false, undefined, true, true));
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
if (this.viewOptions.keyboardSupport) {
|
|
1387
|
-
this.minHandleElement.on('focus', () => this.onPointerFocus(PointerType.Min));
|
|
1388
|
-
if (this.range) {
|
|
1389
|
-
this.maxHandleElement.on('focus', () => this.onPointerFocus(PointerType.Max));
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
getOptionsInfluencingEventBindings(options) {
|
|
1394
|
-
return [
|
|
1395
|
-
options.disabled,
|
|
1396
|
-
options.readOnly,
|
|
1397
|
-
options.draggableRange,
|
|
1398
|
-
options.draggableRangeOnly,
|
|
1399
|
-
options.onlyBindHandles,
|
|
1400
|
-
options.keyboardSupport
|
|
1401
|
-
];
|
|
1402
|
-
}
|
|
1403
|
-
// Unbind mouse and touch events to slider handles
|
|
1404
|
-
unbindEvents() {
|
|
1405
|
-
this.unsubscribeOnMove();
|
|
1406
|
-
this.unsubscribeOnEnd();
|
|
1407
|
-
for (const element of this.getAllSliderElements()) {
|
|
1408
|
-
if (!ValueHelper.isNullOrUndefined(element)) {
|
|
1409
|
-
element.off();
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
onBarStart(draggableRange, event, bindMove, bindEnd, pointerType, simulateImmediateMove, simulateImmediateEnd) {
|
|
1414
|
-
if (draggableRange) {
|
|
1415
|
-
this.onDragStart(event, bindMove, bindEnd, pointerType);
|
|
1416
|
-
}
|
|
1417
|
-
else {
|
|
1418
|
-
this.onStart(event, bindMove, bindEnd, pointerType, simulateImmediateMove, simulateImmediateEnd);
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
// onStart event handler
|
|
1422
|
-
onStart(event, bindMove, bindEnd, pointerType, simulateImmediateMove, simulateImmediateEnd) {
|
|
1423
|
-
event.stopPropagation();
|
|
1424
|
-
// Only call preventDefault() when handling non-passive events (passive events don't need it)
|
|
1425
|
-
if (!CompatibilityHelper.isTouchEvent(event) && !supportsPassiveEvents) {
|
|
1426
|
-
event.preventDefault();
|
|
1427
|
-
}
|
|
1428
|
-
this.moving = false;
|
|
1429
|
-
// We have to do this in case the HTML where the sliders are on
|
|
1430
|
-
// have been animated into view.
|
|
1431
|
-
this.calculateViewDimensions();
|
|
1432
|
-
if (ValueHelper.isNullOrUndefined(pointerType)) {
|
|
1433
|
-
pointerType = this.getNearestHandle(event);
|
|
1434
|
-
}
|
|
1435
|
-
this.currentTrackingPointer = pointerType;
|
|
1436
|
-
const pointerElement = this.getPointerElement(pointerType);
|
|
1437
|
-
pointerElement.active = true;
|
|
1438
|
-
if (this.viewOptions.keyboardSupport) {
|
|
1439
|
-
pointerElement.focus();
|
|
1440
|
-
}
|
|
1441
|
-
if (bindMove) {
|
|
1442
|
-
this.unsubscribeOnMove();
|
|
1443
|
-
const onMoveCallback = (e) => this.dragging.active ? this.onDragMove(e) : this.onMove(e);
|
|
1444
|
-
if (CompatibilityHelper.isTouchEvent(event)) {
|
|
1445
|
-
this.onMoveEventListener = this.eventListenerHelper.attachPassiveEventListener(document, 'touchmove', onMoveCallback);
|
|
1446
|
-
}
|
|
1447
|
-
else {
|
|
1448
|
-
this.onMoveEventListener = this.eventListenerHelper.attachEventListener(document, 'mousemove', onMoveCallback);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
if (bindEnd) {
|
|
1452
|
-
this.unsubscribeOnEnd();
|
|
1453
|
-
const onEndCallback = (e) => this.onEnd(e);
|
|
1454
|
-
if (CompatibilityHelper.isTouchEvent(event)) {
|
|
1455
|
-
this.onEndEventListener = this.eventListenerHelper.attachPassiveEventListener(document, 'touchend', onEndCallback);
|
|
1456
|
-
}
|
|
1457
|
-
else {
|
|
1458
|
-
this.onEndEventListener = this.eventListenerHelper.attachEventListener(document, 'mouseup', onEndCallback);
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
this.userChangeStart.emit(this.getChangeContext());
|
|
1462
|
-
if (CompatibilityHelper.isTouchEvent(event) &&
|
|
1463
|
-
!ValueHelper.isNullOrUndefined(event.changedTouches)) {
|
|
1464
|
-
// Store the touch identifier
|
|
1465
|
-
if (ValueHelper.isNullOrUndefined(this.touchId)) {
|
|
1466
|
-
this.touchId = event.changedTouches[0].identifier;
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
// Click events, either with mouse or touch gesture are weird. Sometimes they result in full
|
|
1470
|
-
// start, move, end sequence, and sometimes, they don't - they only invoke mousedown
|
|
1471
|
-
// As a workaround, we simulate the first move event and the end event if it's necessary
|
|
1472
|
-
if (simulateImmediateMove) {
|
|
1473
|
-
this.onMove(event, true);
|
|
1474
|
-
}
|
|
1475
|
-
if (simulateImmediateEnd) {
|
|
1476
|
-
this.onEnd(event);
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
// onMove event handler
|
|
1480
|
-
onMove(event, fromTick) {
|
|
1481
|
-
let touchForThisSlider;
|
|
1482
|
-
if (CompatibilityHelper.isTouchEvent(event)) {
|
|
1483
|
-
const changedTouches = event.changedTouches;
|
|
1484
|
-
for (let i = 0; i < changedTouches.length; i++) {
|
|
1485
|
-
if (changedTouches[i].identifier === this.touchId) {
|
|
1486
|
-
touchForThisSlider = changedTouches[i];
|
|
1487
|
-
break;
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
if (ValueHelper.isNullOrUndefined(touchForThisSlider)) {
|
|
1491
|
-
return;
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
if (this.viewOptions.animate && !this.viewOptions.animateOnMove) {
|
|
1495
|
-
if (this.moving) {
|
|
1496
|
-
this.sliderElementAnimateClass = false;
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
this.moving = true;
|
|
1500
|
-
const newPos = !ValueHelper.isNullOrUndefined(touchForThisSlider)
|
|
1501
|
-
? this.getEventPosition(event, touchForThisSlider.identifier)
|
|
1502
|
-
: this.getEventPosition(event);
|
|
1503
|
-
let newValue;
|
|
1504
|
-
const ceilValue = this.viewOptions.rightToLeft ? this.viewOptions.floor : this.viewOptions.ceil;
|
|
1505
|
-
const floorValue = this.viewOptions.rightToLeft ? this.viewOptions.ceil : this.viewOptions.floor;
|
|
1506
|
-
if (newPos <= 0) {
|
|
1507
|
-
newValue = floorValue;
|
|
1508
|
-
}
|
|
1509
|
-
else if (newPos >= this.maxHandlePosition) {
|
|
1510
|
-
newValue = ceilValue;
|
|
1511
|
-
}
|
|
1512
|
-
else {
|
|
1513
|
-
newValue = this.positionToValue(newPos);
|
|
1514
|
-
if (fromTick && !ValueHelper.isNullOrUndefined(this.viewOptions.tickStep)) {
|
|
1515
|
-
newValue = this.roundStep(newValue, this.viewOptions.tickStep);
|
|
1516
|
-
}
|
|
1517
|
-
else {
|
|
1518
|
-
newValue = this.roundStep(newValue);
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
this.positionTrackingHandle(newValue);
|
|
1522
|
-
}
|
|
1523
|
-
onEnd(event) {
|
|
1524
|
-
if (CompatibilityHelper.isTouchEvent(event)) {
|
|
1525
|
-
const changedTouches = event.changedTouches;
|
|
1526
|
-
if (changedTouches[0].identifier !== this.touchId) {
|
|
1527
|
-
return;
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
this.moving = false;
|
|
1531
|
-
if (this.viewOptions.animate) {
|
|
1532
|
-
this.sliderElementAnimateClass = true;
|
|
1533
|
-
}
|
|
1534
|
-
this.touchId = undefined;
|
|
1535
|
-
if (!this.viewOptions.keyboardSupport) {
|
|
1536
|
-
this.minHandleElement.active = false;
|
|
1537
|
-
this.maxHandleElement.active = false;
|
|
1538
|
-
this.currentTrackingPointer = undefined;
|
|
1539
|
-
}
|
|
1540
|
-
this.dragging.active = false;
|
|
1541
|
-
this.unsubscribeOnMove();
|
|
1542
|
-
this.unsubscribeOnEnd();
|
|
1543
|
-
this.userChangeEnd.emit(this.getChangeContext());
|
|
1544
|
-
}
|
|
1545
|
-
onPointerFocus(pointerType) {
|
|
1546
|
-
const pointerElement = this.getPointerElement(pointerType);
|
|
1547
|
-
pointerElement.on('blur', () => this.onPointerBlur(pointerElement));
|
|
1548
|
-
pointerElement.on('keydown', (event) => this.onKeyboardEvent(event));
|
|
1549
|
-
pointerElement.on('keyup', () => this.onKeyUp());
|
|
1550
|
-
pointerElement.active = true;
|
|
1551
|
-
this.currentTrackingPointer = pointerType;
|
|
1552
|
-
this.currentFocusPointer = pointerType;
|
|
1553
|
-
this.firstKeyDown = true;
|
|
1554
|
-
}
|
|
1555
|
-
onKeyUp() {
|
|
1556
|
-
this.firstKeyDown = true;
|
|
1557
|
-
this.userChangeEnd.emit(this.getChangeContext());
|
|
1558
|
-
}
|
|
1559
|
-
onPointerBlur(pointer) {
|
|
1560
|
-
pointer.off('blur');
|
|
1561
|
-
pointer.off('keydown');
|
|
1562
|
-
pointer.off('keyup');
|
|
1563
|
-
pointer.active = false;
|
|
1564
|
-
if (ValueHelper.isNullOrUndefined(this.touchId)) {
|
|
1565
|
-
this.currentTrackingPointer = undefined;
|
|
1566
|
-
this.currentFocusPointer = undefined;
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
getKeyActions(currentValue) {
|
|
1570
|
-
const valueRange = this.viewOptions.ceil - this.viewOptions.floor;
|
|
1571
|
-
let increaseStep = currentValue + this.viewOptions.step;
|
|
1572
|
-
let decreaseStep = currentValue - this.viewOptions.step;
|
|
1573
|
-
let increasePage = currentValue + valueRange / 10;
|
|
1574
|
-
let decreasePage = currentValue - valueRange / 10;
|
|
1575
|
-
if (this.viewOptions.reversedControls) {
|
|
1576
|
-
increaseStep = currentValue - this.viewOptions.step;
|
|
1577
|
-
decreaseStep = currentValue + this.viewOptions.step;
|
|
1578
|
-
increasePage = currentValue - valueRange / 10;
|
|
1579
|
-
decreasePage = currentValue + valueRange / 10;
|
|
1580
|
-
}
|
|
1581
|
-
// Left to right default actions
|
|
1582
|
-
const actions = {
|
|
1583
|
-
UP: increaseStep,
|
|
1584
|
-
DOWN: decreaseStep,
|
|
1585
|
-
LEFT: decreaseStep,
|
|
1586
|
-
RIGHT: increaseStep,
|
|
1587
|
-
PAGEUP: increasePage,
|
|
1588
|
-
PAGEDOWN: decreasePage,
|
|
1589
|
-
HOME: this.viewOptions.reversedControls ? this.viewOptions.ceil : this.viewOptions.floor,
|
|
1590
|
-
END: this.viewOptions.reversedControls ? this.viewOptions.floor : this.viewOptions.ceil
|
|
1591
|
-
};
|
|
1592
|
-
// right to left means swapping right and left arrows
|
|
1593
|
-
if (this.viewOptions.rightToLeft) {
|
|
1594
|
-
actions['LEFT'] = increaseStep;
|
|
1595
|
-
actions['RIGHT'] = decreaseStep;
|
|
1596
|
-
// right to left and vertical means we also swap up and down
|
|
1597
|
-
if (this.viewOptions.vertical || this.viewOptions.rotate !== 0) {
|
|
1598
|
-
actions['UP'] = decreaseStep;
|
|
1599
|
-
actions['DOWN'] = increaseStep;
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
return actions;
|
|
1603
|
-
}
|
|
1604
|
-
onKeyboardEvent(event) {
|
|
1605
|
-
const currentValue = this.getCurrentTrackingValue();
|
|
1606
|
-
const keyCode = !ValueHelper.isNullOrUndefined(event.keyCode) ? event.keyCode : event.which;
|
|
1607
|
-
const keys = {
|
|
1608
|
-
38: 'UP',
|
|
1609
|
-
40: 'DOWN',
|
|
1610
|
-
37: 'LEFT',
|
|
1611
|
-
39: 'RIGHT',
|
|
1612
|
-
33: 'PAGEUP',
|
|
1613
|
-
34: 'PAGEDOWN',
|
|
1614
|
-
36: 'HOME',
|
|
1615
|
-
35: 'END'
|
|
1616
|
-
};
|
|
1617
|
-
const actions = this.getKeyActions(currentValue);
|
|
1618
|
-
const key = keys[keyCode];
|
|
1619
|
-
const action = actions[key];
|
|
1620
|
-
if (ValueHelper.isNullOrUndefined(action) || ValueHelper.isNullOrUndefined(this.currentTrackingPointer)) {
|
|
1621
|
-
return;
|
|
1622
|
-
}
|
|
1623
|
-
event.preventDefault();
|
|
1624
|
-
if (this.firstKeyDown) {
|
|
1625
|
-
this.firstKeyDown = false;
|
|
1626
|
-
this.userChangeStart.emit(this.getChangeContext());
|
|
1627
|
-
}
|
|
1628
|
-
const actionValue = MathHelper.clampToRange(action, this.viewOptions.floor, this.viewOptions.ceil);
|
|
1629
|
-
const newValue = this.roundStep(actionValue);
|
|
1630
|
-
if (!this.viewOptions.draggableRangeOnly) {
|
|
1631
|
-
this.positionTrackingHandle(newValue);
|
|
1632
|
-
}
|
|
1633
|
-
else {
|
|
1634
|
-
const difference = this.viewHighValue - this.viewLowValue;
|
|
1635
|
-
let newMinValue;
|
|
1636
|
-
let newMaxValue;
|
|
1637
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1638
|
-
newMinValue = newValue;
|
|
1639
|
-
newMaxValue = newValue + difference;
|
|
1640
|
-
if (newMaxValue > this.viewOptions.ceil) {
|
|
1641
|
-
newMaxValue = this.viewOptions.ceil;
|
|
1642
|
-
newMinValue = newMaxValue - difference;
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1646
|
-
newMaxValue = newValue;
|
|
1647
|
-
newMinValue = newValue - difference;
|
|
1648
|
-
if (newMinValue < this.viewOptions.floor) {
|
|
1649
|
-
newMinValue = this.viewOptions.floor;
|
|
1650
|
-
newMaxValue = newMinValue + difference;
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
this.positionTrackingBar(newMinValue, newMaxValue);
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
// onDragStart event handler, handles dragging of the middle bar
|
|
1657
|
-
onDragStart(event, bindMove, bindEnd, pointerType) {
|
|
1658
|
-
const position = this.getEventPosition(event);
|
|
1659
|
-
this.dragging = new Dragging();
|
|
1660
|
-
this.dragging.active = true;
|
|
1661
|
-
this.dragging.value = this.positionToValue(position);
|
|
1662
|
-
this.dragging.difference = this.viewHighValue - this.viewLowValue;
|
|
1663
|
-
this.dragging.lowLimit = this.viewOptions.rightToLeft
|
|
1664
|
-
? this.minHandleElement.position - position
|
|
1665
|
-
: position - this.minHandleElement.position;
|
|
1666
|
-
this.dragging.highLimit = this.viewOptions.rightToLeft
|
|
1667
|
-
? position - this.maxHandleElement.position
|
|
1668
|
-
: this.maxHandleElement.position - position;
|
|
1669
|
-
this.onStart(event, bindMove, bindEnd, pointerType);
|
|
1670
|
-
}
|
|
1671
|
-
/** Get min value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft */
|
|
1672
|
-
getMinValue(newPos, outOfBounds, isAbove) {
|
|
1673
|
-
const isRTL = this.viewOptions.rightToLeft;
|
|
1674
|
-
let value;
|
|
1675
|
-
if (outOfBounds) {
|
|
1676
|
-
if (isAbove) {
|
|
1677
|
-
value = isRTL ? this.viewOptions.floor : this.viewOptions.ceil - this.dragging.difference;
|
|
1678
|
-
}
|
|
1679
|
-
else {
|
|
1680
|
-
value = isRTL ? this.viewOptions.ceil - this.dragging.difference : this.viewOptions.floor;
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
else {
|
|
1684
|
-
value = isRTL
|
|
1685
|
-
? this.positionToValue(newPos + this.dragging.lowLimit)
|
|
1686
|
-
: this.positionToValue(newPos - this.dragging.lowLimit);
|
|
1687
|
-
}
|
|
1688
|
-
return this.roundStep(value);
|
|
1689
|
-
}
|
|
1690
|
-
/** Get max value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft */
|
|
1691
|
-
getMaxValue(newPos, outOfBounds, isAbove) {
|
|
1692
|
-
const isRTL = this.viewOptions.rightToLeft;
|
|
1693
|
-
let value;
|
|
1694
|
-
if (outOfBounds) {
|
|
1695
|
-
if (isAbove) {
|
|
1696
|
-
value = isRTL ? this.viewOptions.floor + this.dragging.difference : this.viewOptions.ceil;
|
|
1697
|
-
}
|
|
1698
|
-
else {
|
|
1699
|
-
value = isRTL ? this.viewOptions.ceil : this.viewOptions.floor + this.dragging.difference;
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
else {
|
|
1703
|
-
if (isRTL) {
|
|
1704
|
-
value = this.positionToValue(newPos + this.dragging.lowLimit) + this.dragging.difference;
|
|
1705
|
-
}
|
|
1706
|
-
else {
|
|
1707
|
-
value = this.positionToValue(newPos - this.dragging.lowLimit) + this.dragging.difference;
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
return this.roundStep(value);
|
|
1711
|
-
}
|
|
1712
|
-
onDragMove(event) {
|
|
1713
|
-
const newPos = this.getEventPosition(event);
|
|
1714
|
-
if (this.viewOptions.animate && !this.viewOptions.animateOnMove) {
|
|
1715
|
-
if (this.moving) {
|
|
1716
|
-
this.sliderElementAnimateClass = false;
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
this.moving = true;
|
|
1720
|
-
let ceilLimit, floorLimit, floorHandleElement, ceilHandleElement;
|
|
1721
|
-
if (this.viewOptions.rightToLeft) {
|
|
1722
|
-
ceilLimit = this.dragging.lowLimit;
|
|
1723
|
-
floorLimit = this.dragging.highLimit;
|
|
1724
|
-
floorHandleElement = this.maxHandleElement;
|
|
1725
|
-
ceilHandleElement = this.minHandleElement;
|
|
1726
|
-
}
|
|
1727
|
-
else {
|
|
1728
|
-
ceilLimit = this.dragging.highLimit;
|
|
1729
|
-
floorLimit = this.dragging.lowLimit;
|
|
1730
|
-
floorHandleElement = this.minHandleElement;
|
|
1731
|
-
ceilHandleElement = this.maxHandleElement;
|
|
1732
|
-
}
|
|
1733
|
-
const isUnderFloorLimit = newPos <= floorLimit;
|
|
1734
|
-
const isOverCeilLimit = newPos >= this.maxHandlePosition - ceilLimit;
|
|
1735
|
-
let newMinValue;
|
|
1736
|
-
let newMaxValue;
|
|
1737
|
-
if (isUnderFloorLimit) {
|
|
1738
|
-
if (floorHandleElement.position === 0) {
|
|
1739
|
-
return;
|
|
1740
|
-
}
|
|
1741
|
-
newMinValue = this.getMinValue(newPos, true, false);
|
|
1742
|
-
newMaxValue = this.getMaxValue(newPos, true, false);
|
|
1743
|
-
}
|
|
1744
|
-
else if (isOverCeilLimit) {
|
|
1745
|
-
if (ceilHandleElement.position === this.maxHandlePosition) {
|
|
1746
|
-
return;
|
|
1747
|
-
}
|
|
1748
|
-
newMaxValue = this.getMaxValue(newPos, true, true);
|
|
1749
|
-
newMinValue = this.getMinValue(newPos, true, true);
|
|
1750
|
-
}
|
|
1751
|
-
else {
|
|
1752
|
-
newMinValue = this.getMinValue(newPos, false, false);
|
|
1753
|
-
newMaxValue = this.getMaxValue(newPos, false, false);
|
|
1754
|
-
}
|
|
1755
|
-
this.positionTrackingBar(newMinValue, newMaxValue);
|
|
1756
|
-
}
|
|
1757
|
-
// Set the new value and position for the entire bar
|
|
1758
|
-
positionTrackingBar(newMinValue, newMaxValue) {
|
|
1759
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.minLimit) && newMinValue < this.viewOptions.minLimit) {
|
|
1760
|
-
newMinValue = this.viewOptions.minLimit;
|
|
1761
|
-
newMaxValue = MathHelper.roundToPrecisionLimit(newMinValue + this.dragging.difference, this.viewOptions.precisionLimit);
|
|
1762
|
-
}
|
|
1763
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxLimit) && newMaxValue > this.viewOptions.maxLimit) {
|
|
1764
|
-
newMaxValue = this.viewOptions.maxLimit;
|
|
1765
|
-
newMinValue = MathHelper.roundToPrecisionLimit(newMaxValue - this.dragging.difference, this.viewOptions.precisionLimit);
|
|
1766
|
-
}
|
|
1767
|
-
this.viewLowValue = newMinValue;
|
|
1768
|
-
this.viewHighValue = newMaxValue;
|
|
1769
|
-
this.applyViewChange();
|
|
1770
|
-
this.updateHandles(PointerType.Min, this.valueToPosition(newMinValue));
|
|
1771
|
-
this.updateHandles(PointerType.Max, this.valueToPosition(newMaxValue));
|
|
1772
|
-
}
|
|
1773
|
-
// Set the new value and position to the current tracking handle
|
|
1774
|
-
positionTrackingHandle(newValue) {
|
|
1775
|
-
newValue = this.applyMinMaxLimit(newValue);
|
|
1776
|
-
if (this.range) {
|
|
1777
|
-
if (this.viewOptions.pushRange) {
|
|
1778
|
-
newValue = this.applyPushRange(newValue);
|
|
1779
|
-
}
|
|
1780
|
-
else {
|
|
1781
|
-
if (this.viewOptions.noSwitching) {
|
|
1782
|
-
if (this.currentTrackingPointer === PointerType.Min && newValue > this.viewHighValue) {
|
|
1783
|
-
newValue = this.applyMinMaxRange(this.viewHighValue);
|
|
1784
|
-
}
|
|
1785
|
-
else if (this.currentTrackingPointer === PointerType.Max && newValue < this.viewLowValue) {
|
|
1786
|
-
newValue = this.applyMinMaxRange(this.viewLowValue);
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
newValue = this.applyMinMaxRange(newValue);
|
|
1790
|
-
/* This is to check if we need to switch the min and max handles */
|
|
1791
|
-
if (this.currentTrackingPointer === PointerType.Min && newValue > this.viewHighValue) {
|
|
1792
|
-
this.viewLowValue = this.viewHighValue;
|
|
1793
|
-
this.applyViewChange();
|
|
1794
|
-
this.updateHandles(PointerType.Min, this.maxHandleElement.position);
|
|
1795
|
-
this.updateAriaAttributes();
|
|
1796
|
-
this.currentTrackingPointer = PointerType.Max;
|
|
1797
|
-
this.minHandleElement.active = false;
|
|
1798
|
-
this.maxHandleElement.active = true;
|
|
1799
|
-
if (this.viewOptions.keyboardSupport) {
|
|
1800
|
-
this.maxHandleElement.focus();
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
else if (this.currentTrackingPointer === PointerType.Max && newValue < this.viewLowValue) {
|
|
1804
|
-
this.viewHighValue = this.viewLowValue;
|
|
1805
|
-
this.applyViewChange();
|
|
1806
|
-
this.updateHandles(PointerType.Max, this.minHandleElement.position);
|
|
1807
|
-
this.updateAriaAttributes();
|
|
1808
|
-
this.currentTrackingPointer = PointerType.Min;
|
|
1809
|
-
this.maxHandleElement.active = false;
|
|
1810
|
-
this.minHandleElement.active = true;
|
|
1811
|
-
if (this.viewOptions.keyboardSupport) {
|
|
1812
|
-
this.minHandleElement.focus();
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
if (this.getCurrentTrackingValue() !== newValue) {
|
|
1818
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1819
|
-
this.viewLowValue = newValue;
|
|
1820
|
-
this.applyViewChange();
|
|
1821
|
-
}
|
|
1822
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1823
|
-
this.viewHighValue = newValue;
|
|
1824
|
-
this.applyViewChange();
|
|
1825
|
-
}
|
|
1826
|
-
this.updateHandles(this.currentTrackingPointer, this.valueToPosition(newValue));
|
|
1827
|
-
this.updateAriaAttributes();
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
applyMinMaxLimit(newValue) {
|
|
1831
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.minLimit) && newValue < this.viewOptions.minLimit) {
|
|
1832
|
-
return this.viewOptions.minLimit;
|
|
1833
|
-
}
|
|
1834
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxLimit) && newValue > this.viewOptions.maxLimit) {
|
|
1835
|
-
return this.viewOptions.maxLimit;
|
|
1836
|
-
}
|
|
1837
|
-
return newValue;
|
|
1838
|
-
}
|
|
1839
|
-
applyMinMaxRange(newValue) {
|
|
1840
|
-
const oppositeValue = this.currentTrackingPointer === PointerType.Min ? this.viewHighValue : this.viewLowValue;
|
|
1841
|
-
const difference = Math.abs(newValue - oppositeValue);
|
|
1842
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.minRange)) {
|
|
1843
|
-
if (difference < this.viewOptions.minRange) {
|
|
1844
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1845
|
-
return MathHelper.roundToPrecisionLimit(this.viewHighValue - this.viewOptions.minRange, this.viewOptions.precisionLimit);
|
|
1846
|
-
}
|
|
1847
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1848
|
-
return MathHelper.roundToPrecisionLimit(this.viewLowValue + this.viewOptions.minRange, this.viewOptions.precisionLimit);
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxRange)) {
|
|
1853
|
-
if (difference > this.viewOptions.maxRange) {
|
|
1854
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1855
|
-
return MathHelper.roundToPrecisionLimit(this.viewHighValue - this.viewOptions.maxRange, this.viewOptions.precisionLimit);
|
|
1856
|
-
}
|
|
1857
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1858
|
-
return MathHelper.roundToPrecisionLimit(this.viewLowValue + this.viewOptions.maxRange, this.viewOptions.precisionLimit);
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
return newValue;
|
|
1863
|
-
}
|
|
1864
|
-
applyPushRange(newValue) {
|
|
1865
|
-
const difference = this.currentTrackingPointer === PointerType.Min ? this.viewHighValue - newValue : newValue - this.viewLowValue;
|
|
1866
|
-
const minRange = !ValueHelper.isNullOrUndefined(this.viewOptions.minRange)
|
|
1867
|
-
? this.viewOptions.minRange
|
|
1868
|
-
: this.viewOptions.step;
|
|
1869
|
-
const maxRange = this.viewOptions.maxRange;
|
|
1870
|
-
// if smaller than minRange
|
|
1871
|
-
if (difference < minRange) {
|
|
1872
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1873
|
-
this.viewHighValue = MathHelper.roundToPrecisionLimit(Math.min(newValue + minRange, this.viewOptions.ceil), this.viewOptions.precisionLimit);
|
|
1874
|
-
newValue = MathHelper.roundToPrecisionLimit(this.viewHighValue - minRange, this.viewOptions.precisionLimit);
|
|
1875
|
-
this.applyViewChange();
|
|
1876
|
-
this.updateHandles(PointerType.Max, this.valueToPosition(this.viewHighValue));
|
|
1877
|
-
}
|
|
1878
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1879
|
-
this.viewLowValue = MathHelper.roundToPrecisionLimit(Math.max(newValue - minRange, this.viewOptions.floor), this.viewOptions.precisionLimit);
|
|
1880
|
-
newValue = MathHelper.roundToPrecisionLimit(this.viewLowValue + minRange, this.viewOptions.precisionLimit);
|
|
1881
|
-
this.applyViewChange();
|
|
1882
|
-
this.updateHandles(PointerType.Min, this.valueToPosition(this.viewLowValue));
|
|
1883
|
-
}
|
|
1884
|
-
this.updateAriaAttributes();
|
|
1885
|
-
}
|
|
1886
|
-
else if (!ValueHelper.isNullOrUndefined(maxRange) && difference > maxRange) {
|
|
1887
|
-
// if greater than maxRange
|
|
1888
|
-
if (this.currentTrackingPointer === PointerType.Min) {
|
|
1889
|
-
this.viewHighValue = MathHelper.roundToPrecisionLimit(newValue + maxRange, this.viewOptions.precisionLimit);
|
|
1890
|
-
this.applyViewChange();
|
|
1891
|
-
this.updateHandles(PointerType.Max, this.valueToPosition(this.viewHighValue));
|
|
1892
|
-
}
|
|
1893
|
-
else if (this.currentTrackingPointer === PointerType.Max) {
|
|
1894
|
-
this.viewLowValue = MathHelper.roundToPrecisionLimit(newValue - maxRange, this.viewOptions.precisionLimit);
|
|
1895
|
-
this.applyViewChange();
|
|
1896
|
-
this.updateHandles(PointerType.Min, this.valueToPosition(this.viewLowValue));
|
|
1897
|
-
}
|
|
1898
|
-
this.updateAriaAttributes();
|
|
1899
|
-
}
|
|
1900
|
-
return newValue;
|
|
1901
|
-
}
|
|
1902
|
-
getChangeContext() {
|
|
1903
|
-
const changeContext = new ChangeContext();
|
|
1904
|
-
changeContext.pointerType = this.currentTrackingPointer;
|
|
1905
|
-
changeContext.value = +this.value;
|
|
1906
|
-
if (this.range) {
|
|
1907
|
-
changeContext.highValue = +this.highValue;
|
|
1908
|
-
}
|
|
1909
|
-
return changeContext;
|
|
1910
|
-
}
|
|
1911
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SliderComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1912
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: SliderComponent, isStandalone: true, selector: "ngx-slider", inputs: { value: "value", highValue: "highValue", options: "options", manualRefresh: "manualRefresh", triggerFocus: "triggerFocus" }, outputs: { valueChange: "valueChange", highValueChange: "highValueChange", userChangeStart: "userChangeStart", userChange: "userChange", userChangeEnd: "userChangeEnd" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class": "this.class", "class.vertical": "this.sliderElementVerticalClass", "class.animate": "this.sliderElementAnimateClass", "class.with-legend": "this.sliderElementWithLegendClass", "attr.disabled": "this.sliderElementDisabledAttr", "attr.aria-label": "this.sliderElementAriaLabel" } }, providers: [NGX_SLIDER_CONTROL_VALUE_ACCESSOR], queries: [{ propertyName: "tooltipTemplate", first: true, predicate: ["tooltipTemplate"], descendants: true }], viewQueries: [{ propertyName: "leftOuterSelectionBarElement", first: true, predicate: ["leftOuterSelectionBar"], descendants: true, read: SliderElementDirective }, { propertyName: "rightOuterSelectionBarElement", first: true, predicate: ["rightOuterSelectionBar"], descendants: true, read: SliderElementDirective }, { propertyName: "fullBarElement", first: true, predicate: ["fullBar"], descendants: true, read: SliderElementDirective }, { propertyName: "selectionBarElement", first: true, predicate: ["selectionBar"], descendants: true, read: SliderElementDirective }, { propertyName: "minHandleElement", first: true, predicate: ["minHandle"], descendants: true, read: SliderHandleDirective }, { propertyName: "maxHandleElement", first: true, predicate: ["maxHandle"], descendants: true, read: SliderHandleDirective }, { propertyName: "floorLabelElement", first: true, predicate: ["floorLabel"], descendants: true, read: SliderLabelDirective }, { propertyName: "ceilLabelElement", first: true, predicate: ["ceilLabel"], descendants: true, read: SliderLabelDirective }, { propertyName: "minHandleLabelElement", first: true, predicate: ["minHandleLabel"], descendants: true, read: SliderLabelDirective }, { propertyName: "maxHandleLabelElement", first: true, predicate: ["maxHandleLabel"], descendants: true, read: SliderLabelDirective }, { propertyName: "combinedLabelElement", first: true, predicate: ["combinedLabel"], descendants: true, read: SliderLabelDirective }, { propertyName: "ticksElement", first: true, predicate: ["ticksElement"], descendants: true, read: SliderElementDirective }], usesOnChanges: true, ngImport: i0, template: "<!-- // 0 Left selection bar outside two handles -->\n<span\n ngxSliderElement\n #leftOuterSelectionBar\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-left-out-selection\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 1 Right selection bar outside two handles -->\n<span\n ngxSliderElement\n #rightOuterSelectionBar\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-right-out-selection\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 2 The whole slider bar -->\n<span\n ngxSliderElement\n #fullBar\n [class.ngx-slider-transparent]=\"fullBarTransparentClass\"\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-full-bar\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 3 Selection bar between two handles -->\n<span\n ngxSliderElement\n #selectionBar\n [class.ngx-slider-draggable]=\"selectionBarDraggableClass\"\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-selection-bar\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar ngx-slider-selection\" [ngStyle]=\"barStyle\"></span>\n</span>\n<!-- // 4 Low slider handle -->\n<span\n ngxSliderHandle\n #minHandle\n class=\"ngx-slider-span ngx-slider-pointer ngx-slider-pointer-min\"\n [ngStyle]=\"minPointerStyle\"\n></span>\n<!-- // 5 High slider handle -->\n<span\n ngxSliderHandle\n #maxHandle\n [style.display]=\"range ? 'inherit' : 'none'\"\n class=\"ngx-slider-span ngx-slider-pointer ngx-slider-pointer-max\"\n [ngStyle]=\"maxPointerStyle\"\n></span>\n<!-- // 6 Floor label -->\n<span ngxSliderLabel #floorLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-limit ngx-slider-floor\"></span>\n<!-- // 7 Ceiling label -->\n<span ngxSliderLabel #ceilLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-limit ngx-slider-ceil\"></span>\n<!-- // 8 Label above the low slider handle -->\n<span ngxSliderLabel #minHandleLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-model-value\"></span>\n<!-- // 9 Label above the high slider handle -->\n<span ngxSliderLabel #maxHandleLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-model-high\"></span>\n<!-- // 10 Combined range label when the slider handles are close ex. 15 - 17 -->\n<span ngxSliderLabel #combinedLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-combined\"></span>\n<!-- // 11 The ticks -->\n<span\n ngxSliderElement\n #ticksElement\n [hidden]=\"!showTicks\"\n [class.ngx-slider-ticks-values-under]=\"ticksUnderValuesClass\"\n class=\"ngx-slider-ticks\"\n>\n @for (t of ticks; track t) {\n <span class=\"ngx-slider-tick\" [ngClass]=\"{ 'ngx-slider-selected': t.selected }\" [ngStyle]=\"t.style\">\n <ngx-slider-tooltip-wrapper\n [template]=\"tooltipTemplate\"\n [tooltip]=\"t.tooltip\"\n [placement]=\"t.tooltipPlacement\"\n ></ngx-slider-tooltip-wrapper>\n @if (t.value !== null) {\n <ngx-slider-tooltip-wrapper\n class=\"ngx-slider-span ngx-slider-tick-value\"\n [template]=\"tooltipTemplate\"\n [tooltip]=\"t.valueTooltip\"\n [placement]=\"t.valueTooltipPlacement\"\n [content]=\"t.value\"\n ></ngx-slider-tooltip-wrapper>\n }\n @if (t.legend !== null) {\n <span class=\"ngx-slider-span ngx-slider-tick-legend\" [innerHTML]=\"t.legend\"></span>\n }\n </span>\n }\n</span>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: TooltipWrapperComponent, selector: "ngx-slider-tooltip-wrapper", inputs: ["template", "tooltip", "placement", "content"] }, { kind: "directive", type: SliderLabelDirective, selector: "[ngxSliderLabel]" }, { kind: "directive", type: SliderHandleDirective, selector: "[ngxSliderHandle]" }, { kind: "directive", type: SliderElementDirective, selector: "[ngxSliderElement]" }] }); }
|
|
1913
|
-
}
|
|
1914
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SliderComponent, decorators: [{
|
|
1915
|
-
type: Component,
|
|
1916
|
-
args: [{ selector: 'ngx-slider', providers: [NGX_SLIDER_CONTROL_VALUE_ACCESSOR], standalone: true, imports: [CommonModule, TooltipWrapperComponent, SliderLabelDirective, SliderHandleDirective, SliderElementDirective], template: "<!-- // 0 Left selection bar outside two handles -->\n<span\n ngxSliderElement\n #leftOuterSelectionBar\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-left-out-selection\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 1 Right selection bar outside two handles -->\n<span\n ngxSliderElement\n #rightOuterSelectionBar\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-right-out-selection\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 2 The whole slider bar -->\n<span\n ngxSliderElement\n #fullBar\n [class.ngx-slider-transparent]=\"fullBarTransparentClass\"\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-full-bar\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar\"></span>\n</span>\n<!-- // 3 Selection bar between two handles -->\n<span\n ngxSliderElement\n #selectionBar\n [class.ngx-slider-draggable]=\"selectionBarDraggableClass\"\n class=\"ngx-slider-span ngx-slider-bar-wrapper ngx-slider-selection-bar\"\n>\n <span class=\"ngx-slider-span ngx-slider-bar ngx-slider-selection\" [ngStyle]=\"barStyle\"></span>\n</span>\n<!-- // 4 Low slider handle -->\n<span\n ngxSliderHandle\n #minHandle\n class=\"ngx-slider-span ngx-slider-pointer ngx-slider-pointer-min\"\n [ngStyle]=\"minPointerStyle\"\n></span>\n<!-- // 5 High slider handle -->\n<span\n ngxSliderHandle\n #maxHandle\n [style.display]=\"range ? 'inherit' : 'none'\"\n class=\"ngx-slider-span ngx-slider-pointer ngx-slider-pointer-max\"\n [ngStyle]=\"maxPointerStyle\"\n></span>\n<!-- // 6 Floor label -->\n<span ngxSliderLabel #floorLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-limit ngx-slider-floor\"></span>\n<!-- // 7 Ceiling label -->\n<span ngxSliderLabel #ceilLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-limit ngx-slider-ceil\"></span>\n<!-- // 8 Label above the low slider handle -->\n<span ngxSliderLabel #minHandleLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-model-value\"></span>\n<!-- // 9 Label above the high slider handle -->\n<span ngxSliderLabel #maxHandleLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-model-high\"></span>\n<!-- // 10 Combined range label when the slider handles are close ex. 15 - 17 -->\n<span ngxSliderLabel #combinedLabel class=\"ngx-slider-span ngx-slider-bubble ngx-slider-combined\"></span>\n<!-- // 11 The ticks -->\n<span\n ngxSliderElement\n #ticksElement\n [hidden]=\"!showTicks\"\n [class.ngx-slider-ticks-values-under]=\"ticksUnderValuesClass\"\n class=\"ngx-slider-ticks\"\n>\n @for (t of ticks; track t) {\n <span class=\"ngx-slider-tick\" [ngClass]=\"{ 'ngx-slider-selected': t.selected }\" [ngStyle]=\"t.style\">\n <ngx-slider-tooltip-wrapper\n [template]=\"tooltipTemplate\"\n [tooltip]=\"t.tooltip\"\n [placement]=\"t.tooltipPlacement\"\n ></ngx-slider-tooltip-wrapper>\n @if (t.value !== null) {\n <ngx-slider-tooltip-wrapper\n class=\"ngx-slider-span ngx-slider-tick-value\"\n [template]=\"tooltipTemplate\"\n [tooltip]=\"t.valueTooltip\"\n [placement]=\"t.valueTooltipPlacement\"\n [content]=\"t.value\"\n ></ngx-slider-tooltip-wrapper>\n }\n @if (t.legend !== null) {\n <span class=\"ngx-slider-span ngx-slider-tick-legend\" [innerHTML]=\"t.legend\"></span>\n }\n </span>\n }\n</span>\n" }]
|
|
1917
|
-
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { class: [{
|
|
1918
|
-
type: HostBinding,
|
|
1919
|
-
args: ['class']
|
|
1920
|
-
}], value: [{
|
|
1921
|
-
type: Input
|
|
1922
|
-
}], valueChange: [{
|
|
1923
|
-
type: Output
|
|
1924
|
-
}], highValue: [{
|
|
1925
|
-
type: Input
|
|
1926
|
-
}], highValueChange: [{
|
|
1927
|
-
type: Output
|
|
1928
|
-
}], options: [{
|
|
1929
|
-
type: Input
|
|
1930
|
-
}], userChangeStart: [{
|
|
1931
|
-
type: Output
|
|
1932
|
-
}], userChange: [{
|
|
1933
|
-
type: Output
|
|
1934
|
-
}], userChangeEnd: [{
|
|
1935
|
-
type: Output
|
|
1936
|
-
}], manualRefresh: [{
|
|
1937
|
-
type: Input
|
|
1938
|
-
}], triggerFocus: [{
|
|
1939
|
-
type: Input
|
|
1940
|
-
}], leftOuterSelectionBarElement: [{
|
|
1941
|
-
type: ViewChild,
|
|
1942
|
-
args: ['leftOuterSelectionBar', { read: SliderElementDirective }]
|
|
1943
|
-
}], rightOuterSelectionBarElement: [{
|
|
1944
|
-
type: ViewChild,
|
|
1945
|
-
args: ['rightOuterSelectionBar', { read: SliderElementDirective }]
|
|
1946
|
-
}], fullBarElement: [{
|
|
1947
|
-
type: ViewChild,
|
|
1948
|
-
args: ['fullBar', { read: SliderElementDirective }]
|
|
1949
|
-
}], selectionBarElement: [{
|
|
1950
|
-
type: ViewChild,
|
|
1951
|
-
args: ['selectionBar', { read: SliderElementDirective }]
|
|
1952
|
-
}], minHandleElement: [{
|
|
1953
|
-
type: ViewChild,
|
|
1954
|
-
args: ['minHandle', { read: SliderHandleDirective }]
|
|
1955
|
-
}], maxHandleElement: [{
|
|
1956
|
-
type: ViewChild,
|
|
1957
|
-
args: ['maxHandle', { read: SliderHandleDirective }]
|
|
1958
|
-
}], floorLabelElement: [{
|
|
1959
|
-
type: ViewChild,
|
|
1960
|
-
args: ['floorLabel', { read: SliderLabelDirective }]
|
|
1961
|
-
}], ceilLabelElement: [{
|
|
1962
|
-
type: ViewChild,
|
|
1963
|
-
args: ['ceilLabel', { read: SliderLabelDirective }]
|
|
1964
|
-
}], minHandleLabelElement: [{
|
|
1965
|
-
type: ViewChild,
|
|
1966
|
-
args: ['minHandleLabel', { read: SliderLabelDirective }]
|
|
1967
|
-
}], maxHandleLabelElement: [{
|
|
1968
|
-
type: ViewChild,
|
|
1969
|
-
args: ['maxHandleLabel', { read: SliderLabelDirective }]
|
|
1970
|
-
}], combinedLabelElement: [{
|
|
1971
|
-
type: ViewChild,
|
|
1972
|
-
args: ['combinedLabel', { read: SliderLabelDirective }]
|
|
1973
|
-
}], ticksElement: [{
|
|
1974
|
-
type: ViewChild,
|
|
1975
|
-
args: ['ticksElement', { read: SliderElementDirective }]
|
|
1976
|
-
}], tooltipTemplate: [{
|
|
1977
|
-
type: ContentChild,
|
|
1978
|
-
args: ['tooltipTemplate']
|
|
1979
|
-
}], sliderElementVerticalClass: [{
|
|
1980
|
-
type: HostBinding,
|
|
1981
|
-
args: ['class.vertical']
|
|
1982
|
-
}], sliderElementAnimateClass: [{
|
|
1983
|
-
type: HostBinding,
|
|
1984
|
-
args: ['class.animate']
|
|
1985
|
-
}], sliderElementWithLegendClass: [{
|
|
1986
|
-
type: HostBinding,
|
|
1987
|
-
args: ['class.with-legend']
|
|
1988
|
-
}], sliderElementDisabledAttr: [{
|
|
1989
|
-
type: HostBinding,
|
|
1990
|
-
args: ['attr.disabled']
|
|
1991
|
-
}], sliderElementAriaLabel: [{
|
|
1992
|
-
type: HostBinding,
|
|
1993
|
-
args: ['attr.aria-label']
|
|
1994
|
-
}], onResize: [{
|
|
1995
|
-
type: HostListener,
|
|
1996
|
-
args: ['window:resize', ['$event']]
|
|
1997
|
-
}] } });
|
|
1998
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbi1mYWN0b3J5L3NyYy9saWIvYW5ndWxhci9zbGlkZXIvbGliL3NsaWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kZXNpZ24tZmFjdG9yeS9zcmMvbGliL2FuZ3VsYXIvc2xpZGVyL2xpYi9zbGlkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxTQUFTLEVBSVQsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBR0wsWUFBWSxFQUNaLE1BQU0sRUFDTixZQUFZLEVBSVosVUFBVSxFQUVYLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQTBFLE1BQU0sV0FBVyxDQUFDO0FBQ3ZILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1B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UUFBUTtzQkFEZCxZQUFZO3VCQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGQsXG4gIEFmdGVyVmlld0luaXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgRWxlbWVudFJlZixcbiAgUmVuZGVyZXIyLFxuICBFdmVudEVtaXR0ZXIsXG4gIE91dHB1dCxcbiAgQ29udGVudENoaWxkLFxuICBUZW1wbGF0ZVJlZixcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIGZvcndhcmRSZWYsXG4gIE5nWm9uZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE9wdGlvbnMsIExhYmVsVHlwZSwgVmFsdWVUb1Bvc2l0aW9uRnVuY3Rpb24sIFBvc2l0aW9uVG9WYWx1ZUZ1bmN0aW9uLCBDdXN0b21TdGVwRGVmaW5pdGlvbiB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBQb2ludGVyVHlwZSB9IGZyb20gJy4vcG9pbnRlci10eXBlJztcbmltcG9ydCB7IENoYW5nZUNvbnRleHQgfSBmcm9tICcuL2NoYW5nZS1jb250ZXh0JztcbmltcG9ydCB7IFZhbHVlSGVscGVyIH0gZnJvbSAnLi92YWx1ZS1oZWxwZXInO1xuaW1wb3J0IHsgQ29tcGF0aWJpbGl0eUhlbHBlciB9IGZyb20gJy4vY29tcGF0aWJpbGl0eS1oZWxwZXInO1xuaW1wb3J0IHsgTWF0aEhlbHBlciB9IGZyb20gJy4vbWF0aC1oZWxwZXInO1xuaW1wb3J0IHsgRXZlbnRMaXN0ZW5lciB9IGZyb20gJy4vZXZlbnQtbGlzdGVuZXInO1xuaW1wb3J0IHsgRXZlbnRMaXN0ZW5lckhlbHBlciwgc3VwcG9ydHNQYXNzaXZlRXZlbnRzIH0gZnJvbSAnLi9ldmVudC1saXN0ZW5lci1oZWxwZXInO1xuaW1wb3J0IHsgU2xpZGVyRWxlbWVudERpcmVjdGl2ZSB9IGZyb20gJy4vc2xpZGVyLWVsZW1lbnQuZGlyZWN0aXZlJztcbmltcG9ydCB7IFNsaWRlckhhbmRsZURpcmVjdGl2ZSB9IGZyb20gJy4vc2xpZGVyLWhhbmRsZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgU2xpZGVyTGFiZWxEaXJlY3RpdmUgfSBmcm9tICcuL3NsaWRlci1sYWJlbC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFRvb2x0aXBXcmFwcGVyQ29tcG9uZW50IH0gZnJvbSAnLi90b29sdGlwLXdyYXBwZXIuY29tcG9uZW50JztcblxuLy8gRGVjbGFyYXRpb24gZm9yIFJlc2l6ZU9ic2VydmVyIGEgbmV3IEFQSSBhdmFpbGFibGUgaW4gc29tZSBvZiBuZXdlc3QgYnJvd3NlcnM6XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVzaXplT2JzZXJ2ZXJcbmRlY2xhcmUgY2xhc3MgUmVzaXplT2JzZXJ2ZXIge1xuICBjb25zdHJ1Y3RvcihjYWxsYmFjazogKCkgPT4gdm9pZCk7XG4gIG9ic2VydmUodGFyZ2V0OiBhbnkpOiB2b2lkO1xuICB1bm9ic2VydmUodGFyZ2V0OiBhbnkpOiB2b2lkO1xuICBkaXNjb25uZWN0KCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBUaWNrIHtcbiAgc2VsZWN0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc3R5bGU6IGFueSA9IHt9O1xuICB0b29sdGlwPzogc3RyaW5nO1xuICB0b29sdGlwUGxhY2VtZW50Pzogc3RyaW5nO1xuICB2YWx1ZT86IHN0cmluZztcbiAgdmFsdWVUb29sdGlwPzogc3RyaW5nO1xuICB2YWx1ZVRvb2x0aXBQbGFjZW1lbnQ/OiBzdHJpbmc7XG4gIGxlZ2VuZD86IHN0cmluZztcbn1cblxuY2xhc3MgRHJhZ2dpbmcge1xuICBhY3RpdmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgdmFsdWU6IG51bWJlciA9IDA7XG4gIGRpZmZlcmVuY2U6IG51bWJlciA9IDA7XG4gIHBvc2l0aW9uOiBudW1iZXIgPSAwO1xuICBsb3dMaW1pdDogbnVtYmVyID0gMDtcbiAgaGlnaExpbWl0OiBudW1iZXIgPSAwO1xufVxuXG5jbGFzcyBNb2RlbFZhbHVlcyB7XG4gIHZhbHVlPzogbnVtYmVyO1xuICBoaWdoVmFsdWU/OiBudW1iZXI7XG5cbiAgcHVibGljIHN0YXRpYyBjb21wYXJlKHg/OiBNb2RlbFZhbHVlcywgeT86IE1vZGVsVmFsdWVzKTogYm9vbGVhbiB7XG4gICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHgpICYmIFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh4KSAhPT0gVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoeSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHghLnZhbHVlID09PSB5IS52YWx1ZSAmJiB4IS5oaWdoVmFsdWUgPT09IHkhLmhpZ2hWYWx1ZTtcbiAgfVxufVxuXG5jbGFzcyBNb2RlbENoYW5nZSBleHRlbmRzIE1vZGVsVmFsdWVzIHtcbiAgLy8gRmxhZyB1c2VkIHRvIGJ5LXBhc3MgZGlzdGluY3RVbnRpbENoYW5nZWQoKSBmaWx0ZXIgb24gaW5wdXQgdmFsdWVzXG4gIC8vIChzb21ldGltZXMgdGhlcmUgaXMgYSBuZWVkIHRvIHBhc3MgdmFsdWVzIHRocm91Z2ggZXZlbiB0aG91Z2ggdGhlIG1vZGVsIHZhbHVlcyBoYXZlIG5vdCBjaGFuZ2VkKVxuICBmb3JjZUNoYW5nZT86IGJvb2xlYW47XG5cbiAgcHVibGljIHN0YXRpYyBvdmVycmlkZSBjb21wYXJlKHg/OiBNb2RlbENoYW5nZSwgeT86IE1vZGVsQ2hhbmdlKTogYm9vbGVhbiB7XG4gICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHgpICYmIFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh4KSAhPT0gVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoeSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHghLnZhbHVlID09PSB5IS52YWx1ZSAmJiB4IS5oaWdoVmFsdWUgPT09IHkhLmhpZ2hWYWx1ZSAmJiB4IS5mb3JjZUNoYW5nZSA9PT0geSEuZm9yY2VDaGFuZ2U7XG4gIH1cbn1cblxuY2xhc3MgSW5wdXRNb2RlbENoYW5nZSBleHRlbmRzIE1vZGVsQ2hhbmdlIHtcbiAgaW50ZXJuYWxDaGFuZ2U/OiBib29sZWFuO1xufVxuXG5jbGFzcyBPdXRwdXRNb2RlbENoYW5nZSBleHRlbmRzIE1vZGVsQ2hhbmdlIHtcbiAgdXNlckV2ZW50SW5pdGlhdGVkPzogYm9vbGVhbjtcbn1cblxuY29uc3QgTkdYX1NMSURFUl9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLXVzZS1iZWZvcmUtZGVjbGFyZSAqL1xuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBTbGlkZXJDb21wb25lbnQpLFxuICBtdWx0aTogdHJ1ZVxufTtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBTbGlkZXJDb21wb25lbnQgaXMgZGVwcmVjYXRlZC4gVXNlIHtAbGluayBodHRwczovL2Rlc2lnbi1mYWN0b3J5LWludC5hcHAubmV0Ni5wYWFzLndlc3RldXJvcGUucm5kLmF6LmFtYWRldXMubmV0LyMvY29tcG9uZW50cy9zbGlkZXIvYWdub3N1aSAgQWdub3NVSSBTbGlkZXJ9IGluc3RlYWQuXG4gKi9cbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ25neC1zbGlkZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vc2xpZGVyLmNvbXBvbmVudC5odG1sJyxcbiAgcHJvdmlkZXJzOiBbTkdYX1NMSURFUl9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgVG9vbHRpcFdyYXBwZXJDb21wb25lbnQsIFNsaWRlckxhYmVsRGlyZWN0aXZlLCBTbGlkZXJIYW5kbGVEaXJlY3RpdmUsIFNsaWRlckVsZW1lbnREaXJlY3RpdmVdXG59KVxuZXhwb3J0IGNsYXNzIFNsaWRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpIGNsYXNzID0gJ25neC1zbGlkZXInO1xuICAvLyBNb2RlbCBmb3IgbG93IHZhbHVlIG9mIHNsaWRlci4gRm9yIHNpbXBsZSBzbGlkZXIsIHRoaXMgaXMgdGhlIG9ubHkgaW5wdXQuIEZvciByYW5nZSBzbGlkZXIsIHRoaXMgaXMgdGhlIGxvdyB2YWx1ZS5cbiAgQElucHV0KClcbiAgcHVibGljIHZhbHVlPzogbnVtYmVyO1xuICAvLyBPdXRwdXQgZm9yIGxvdyB2YWx1ZSBzbGlkZXIgdG8gc3VwcG9ydCB0d28td2F5IGJpbmRpbmdzXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIC8vIE1vZGVsIGZvciBoaWdoIHZhbHVlIG9mIHNsaWRlci4gTm90IHVzZWQgaW4gc2ltcGxlIHNsaWRlci4gRm9yIHJhbmdlIHNsaWRlciwgdGhpcyBpcyB0aGUgaGlnaCB2YWx1ZS5cbiAgQElucHV0KClcbiAgcHVibGljIGhpZ2hWYWx1ZT86IG51bWJlcjtcbiAgLy8gT3V0cHV0IGZvciBoaWdoIHZhbHVlIHNsaWRlciB0byBzdXBwb3J0IHR3by13YXkgYmluZGluZ3NcbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBoaWdoVmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIC8vIEFuIG9iamVjdCB3aXRoIGFsbCB0aGUgb3RoZXIgb3B0aW9ucyBvZiB0aGUgc2xpZGVyLlxuICAvLyBFYWNoIG9wdGlvbiBjYW4gYmUgdXBkYXRlZCBhdCBydW50aW1lIGFuZCB0aGUgc2xpZGVyIHdpbGwgYXV0b21hdGljYWxseSBiZSByZS1yZW5kZXJlZC5cbiAgQElucHV0KClcbiAgcHVibGljIG9wdGlvbnM6IE9wdGlvbnMgPSBuZXcgT3B0aW9ucygpO1xuXG4gIC8vIEV2ZW50IGVtaXR0ZWQgd2hlbiB1c2VyIHN0YXJ0cyBpbnRlcmFjdGlvbiB3aXRoIHRoZSBzbGlkZXJcbiAgQE91dHB1dCgpXG4gIHB1YmxpYyB1c2VyQ2hhbmdlU3RhcnQ6IEV2ZW50RW1pdHRlcjxDaGFuZ2VDb250ZXh0PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAvLyBFdmVudCBlbWl0dGVkIG9uIGVhY2ggY2hhbmdlIGNvbWluZyBmcm9tIHVzZXIgaW50ZXJhY3Rpb25cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyB1c2VyQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Q2hhbmdlQ29udGV4dD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLy8gRXZlbnQgZW1pdHRlZCB3aGVuIHVzZXIgZmluaXNoZXMgaW50ZXJhY3Rpb24gd2l0aCB0aGUgc2xpZGVyXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgdXNlckNoYW5nZUVuZDogRXZlbnRFbWl0dGVyPENoYW5nZUNvbnRleHQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHByaXZhdGUgbWFudWFsUmVmcmVzaFN1YnNjcmlwdGlvbjogYW55O1xuICAvLyBJbnB1dCBldmVudCB0aGF0IHRyaWdnZXJzIHNsaWRlciByZWZyZXNoIChyZS1wb3NpdGlvbmluZyBvZiBzbGlkZXIgZWxlbWVudHMpXG4gIEBJbnB1dCgpIHNldCBtYW51YWxSZWZyZXNoKG1hbnVhbFJlZnJlc2g6IEV2ZW50RW1pdHRlcjx2b2lkPikge1xuICAgIHRoaXMudW5zdWJzY3JpYmVNYW51YWxSZWZyZXNoKCk7XG5cbiAgICB0aGlzLm1hbnVhbFJlZnJlc2hTdWJzY3JpcHRpb24gPSBtYW51YWxSZWZyZXNoLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY2FsY3VsYXRlVmlld0RpbWVuc2lvbnNBbmREZXRlY3RDaGFuZ2VzKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0cmlnZ2VyRm9jdXNTdWJzY3JpcHRpb246IGFueTtcbiAgLy8gSW5wdXQgZXZlbnQgdGhhdCB0cmlnZ2VycyBzZXR0aW5nIGZvY3VzIG9uIGdpdmVuIHNsaWRlciBoYW5kbGVcbiAgQElucHV0KCkgc2V0IHRyaWdnZXJGb2N1cyh0cmlnZ2VyRm9jdXM6IEV2ZW50RW1pdHRlcjx2b2lkPikge1xuICAgIHRoaXMudW5zdWJzY3JpYmVUcmlnZ2VyRm9jdXMoKTtcblxuICAgIHRoaXMudHJpZ2dlckZvY3VzU3Vic2NyaXB0aW9uID0gdHJpZ2dlckZvY3VzLnN1YnNjcmliZSgocG9pbnRlclR5cGU6IFBvaW50ZXJUeXBlKSA9PiB7XG4gICAgICB0aGlzLmZvY3VzUG9pbnRlcihwb2ludGVyVHlwZSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBTbGlkZXIgdHlwZSwgdHJ1ZSBtZWFucyByYW5nZSBzbGlkZXJcbiAgcHVibGljIGdldCByYW5nZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmFsdWUpICYmICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLmhpZ2hWYWx1ZSk7XG4gIH1cblxuICAvLyBTZXQgdG8gdHJ1ZSBpZiBpbml0IG1ldGhvZCBhbHJlYWR5IGV4ZWN1dGVkXG4gIHByaXZhdGUgaW5pdEhhc1J1bjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIENoYW5nZXMgaW4gbW9kZWwgaW5wdXRzIGFyZSBwYXNzZWQgdGhyb3VnaCB0aGlzIHN1YmplY3RcbiAgLy8gVGhlc2UgYXJlIGFsbCBjaGFuZ2VzIGNvbWluZyBpbiBmcm9tIG91dHNpZGUgdGhlIGNvbXBvbmVudCB0aHJvdWdoIGlucHV0IGJpbmRpbmdzIG9yIHJlYWN0aXZlIGZvcm0gaW5wdXRzXG4gIHByaXZhdGUgaW5wdXRNb2RlbENoYW5nZVN1YmplY3Q6IFN1YmplY3Q8SW5wdXRNb2RlbENoYW5nZT4gPSBuZXcgU3ViamVjdDxJbnB1dE1vZGVsQ2hhbmdlPigpO1xuICBwcml2YXRlIGlucHV0TW9kZWxDaGFuZ2VTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgLy8gQ2hhbmdlcyB0byBtb2RlbCBvdXRwdXRzIGFyZSBwYXNzZWQgdGhyb3VnaCB0aGlzIHN1YmplY3RcbiAgLy8gVGhlc2UgYXJlIGFsbCBjaGFuZ2VzIHRoYXQgbmVlZCB0byBiZSBjb21tdW5pY2F0ZWQgdG8gb3V0cHV0IGVtaXR0ZXJzIGFuZCByZWdpc3RlcmVkIGNhbGxiYWNrc1xuICBwcml2YXRlIG91dHB1dE1vZGVsQ2hhbmdlU3ViamVjdDogU3ViamVjdDxPdXRwdXRNb2RlbENoYW5nZT4gPSBuZXcgU3ViamVjdDxPdXRwdXRNb2RlbENoYW5nZT4oKTtcbiAgcHJpdmF0ZSBvdXRwdXRNb2RlbENoYW5nZVN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICAvLyBMb3cgdmFsdWUgc3luY2VkIHRvIG1vZGVsIGxvdyB2YWx1ZVxuICBwcml2YXRlIHZpZXdMb3dWYWx1ZT86IG51bWJlcjtcbiAgLy8gSGlnaCB2YWx1ZSBzeW5jZWQgdG8gbW9kZWwgaGlnaCB2YWx1ZVxuICBwcml2YXRlIHZpZXdIaWdoVmFsdWU/OiBudW1iZXI7XG4gIC8vIE9wdGlvbnMgc3luY2VkIHRvIG1vZGVsIG9wdGlvbnMsIGJhc2VkIG9uIGRlZmF1bHRzXG4gIHByaXZhdGUgdmlld09wdGlvbnM6IE9wdGlvbnMgPSBuZXcgT3B0aW9ucygpO1xuXG4gIC8vIEhhbGYgb2YgdGhlIHdpZHRoIG9yIGhlaWdodCBvZiB0aGUgc2xpZGVyIGhhbmRsZXNcbiAgcHJpdmF0ZSBoYW5kbGVIYWxmRGltZW5zaW9uOiBudW1iZXIgPSAwO1xuICAvLyBNYXhpbXVtIHBvc2l0aW9uIHRoZSBzbGlkZXIgaGFuZGxlIGNhbiBoYXZlXG4gIHByaXZhdGUgbWF4SGFuZGxlUG9zaXRpb246IG51bWJlciA9IDA7XG5cbiAgLy8gV2hpY2ggaGFuZGxlIGlzIGN1cnJlbnRseSB0cmFja2VkIGZvciBtb3ZlIGV2ZW50c1xuICBwcml2YXRlIGN1cnJlbnRUcmFja2luZ1BvaW50ZXI/OiBQb2ludGVyVHlwZTtcbiAgLy8gSW50ZXJuYWwgdmFyaWFibGUgdG8ga2VlcCB0cmFjayBvZiB0aGUgZm9jdXMgZWxlbWVudFxuICBwcml2YXRlIGN1cnJlbnRGb2N1c1BvaW50ZXI/OiBQb2ludGVyVHlwZTtcbiAgLy8gVXNlZCB0byBjYWxsIG9uU3RhcnQgb24gdGhlIGZpcnN0IGtleWRvd24gZXZlbnRcbiAgcHJpdmF0ZSBmaXJzdEtleURvd24gPSBmYWxzZTtcbiAgLy8gQ3VycmVudCB0b3VjaCBpZCBvZiB0b3VjaCBldmVudCBiZWluZyBoYW5kbGVkXG4gIHByaXZhdGUgdG91Y2hJZD86IG51bWJlcjtcbiAgLy8gVmFsdWVzIHJlY29yZGVkIHdoZW4gZmlyc3QgZHJhZ2dpbmcgdGhlIGJhclxuICBwcml2YXRlIGRyYWdnaW5nOiBEcmFnZ2luZyA9IG5ldyBEcmFnZ2luZygpO1xuXG4gIC8qIFNsaWRlciBET00gZWxlbWVudHMgKi9cblxuICAvLyBMZWZ0IHNlbGVjdGlvbiBiYXIgb3V0c2lkZSB0d28gaGFuZGxlc1xuICBAVmlld0NoaWxkKCdsZWZ0T3V0ZXJTZWxlY3Rpb25CYXInLCB7IHJlYWQ6IFNsaWRlckVsZW1lbnREaXJlY3RpdmUgfSlcbiAgcHJpdmF0ZSBsZWZ0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50PzogU2xpZGVyRWxlbWVudERpcmVjdGl2ZTtcblxuICAvLyBSaWdodCBzZWxlY3Rpb24gYmFyIG91dHNpZGUgdHdvIGhhbmRsZXNcbiAgQFZpZXdDaGlsZCgncmlnaHRPdXRlclNlbGVjdGlvbkJhcicsIHsgcmVhZDogU2xpZGVyRWxlbWVudERpcmVjdGl2ZSB9KVxuICBwcml2YXRlIHJpZ2h0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50PzogU2xpZGVyRWxlbWVudERpcmVjdGl2ZTtcblxuICAvLyBUaGUgd2hvbGUgc2xpZGVyIGJhclxuICBAVmlld0NoaWxkKCdmdWxsQmFyJywgeyByZWFkOiBTbGlkZXJFbGVtZW50RGlyZWN0aXZlIH0pXG4gIHByaXZhdGUgZnVsbEJhckVsZW1lbnQ/OiBTbGlkZXJFbGVtZW50RGlyZWN0aXZlO1xuXG4gIC8vIEhpZ2hsaWdodCBiZXR3ZWVuIHR3byBoYW5kbGVzXG4gIEBWaWV3Q2hpbGQoJ3NlbGVjdGlvbkJhcicsIHsgcmVhZDogU2xpZGVyRWxlbWVudERpcmVjdGl2ZSB9KVxuICBwcml2YXRlIHNlbGVjdGlvbkJhckVsZW1lbnQ/OiBTbGlkZXJFbGVtZW50RGlyZWN0aXZlO1xuXG4gIC8vIExlZnQgc2xpZGVyIGhhbmRsZVxuICBAVmlld0NoaWxkKCdtaW5IYW5kbGUnLCB7IHJlYWQ6IFNsaWRlckhhbmRsZURpcmVjdGl2ZSB9KVxuICBwcml2YXRlIG1pbkhhbmRsZUVsZW1lbnQ/OiBTbGlkZXJIYW5kbGVEaXJlY3RpdmU7XG5cbiAgLy8gUmlnaHQgc2xpZGVyIGhhbmRsZVxuICBAVmlld0NoaWxkKCdtYXhIYW5kbGUnLCB7IHJlYWQ6IFNsaWRlckhhbmRsZURpcmVjdGl2ZSB9KVxuICBwcml2YXRlIG1heEhhbmRsZUVsZW1lbnQ/OiBTbGlkZXJIYW5kbGVEaXJlY3RpdmU7XG5cbiAgLy8gRmxvb3IgbGFiZWxcbiAgQFZpZXdDaGlsZCgnZmxvb3JMYWJlbCcsIHsgcmVhZDogU2xpZGVyTGFiZWxEaXJlY3RpdmUgfSlcbiAgcHJpdmF0ZSBmbG9vckxhYmVsRWxlbWVudD86IFNsaWRlckxhYmVsRGlyZWN0aXZlO1xuXG4gIC8vIENlaWxpbmcgbGFiZWxcbiAgQFZpZXdDaGlsZCgnY2VpbExhYmVsJywgeyByZWFkOiBTbGlkZXJMYWJlbERpcmVjdGl2ZSB9KVxuICBwcml2YXRlIGNlaWxMYWJlbEVsZW1lbnQ/OiBTbGlkZXJMYWJlbERpcmVjdGl2ZTtcblxuICAvLyBMYWJlbCBhYm92ZSB0aGUgbG93IHZhbHVlXG4gIEBWaWV3Q2hpbGQoJ21pbkhhbmRsZUxhYmVsJywgeyByZWFkOiBTbGlkZXJMYWJlbERpcmVjdGl2ZSB9KVxuICBwcml2YXRlIG1pbkhhbmRsZUxhYmVsRWxlbWVudD86IFNsaWRlckxhYmVsRGlyZWN0aXZlO1xuXG4gIC8vIExhYmVsIGFib3ZlIHRoZSBoaWdoIHZhbHVlXG4gIEBWaWV3Q2hpbGQoJ21heEhhbmRsZUxhYmVsJywgeyByZWFkOiBTbGlkZXJMYWJlbERpcmVjdGl2ZSB9KVxuICBwcml2YXRlIG1heEhhbmRsZUxhYmVsRWxlbWVudD86IFNsaWRlckxhYmVsRGlyZWN0aXZlO1xuXG4gIC8vIENvbWJpbmVkIGxhYmVsXG4gIEBWaWV3Q2hpbGQoJ2NvbWJpbmVkTGFiZWwnLCB7IHJlYWQ6IFNsaWRlckxhYmVsRGlyZWN0aXZlIH0pXG4gIHByaXZhdGUgY29tYmluZWRMYWJlbEVsZW1lbnQ/OiBTbGlkZXJMYWJlbERpcmVjdGl2ZTtcblxuICAvLyBUaGUgdGlja3NcbiAgQFZpZXdDaGlsZCgndGlja3NFbGVtZW50JywgeyByZWFkOiBTbGlkZXJFbGVtZW50RGlyZWN0aXZlIH0pXG4gIHByaXZhdGUgdGlja3NFbGVtZW50PzogU2xpZGVyRWxlbWVudERpcmVjdGl2ZTtcblxuICAvLyBPcHRpb25hbCBjdXN0b20gdGVtcGxhdGUgZm9yIGRpc3BsYXlpbmcgdG9vbHRpcHNcbiAgQENvbnRlbnRDaGlsZCgndG9vbHRpcFRlbXBsYXRlJylcbiAgcHVibGljIHRvb2x0aXBUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLy8gSG9zdCBlbGVtZW50IGNsYXNzIGJpbmRpbmdzXG4gIEBIb3N0QmluZGluZygnY2xhc3MudmVydGljYWwnKVxuICBwdWJsaWMgc2xpZGVyRWxlbWVudFZlcnRpY2FsQ2xhc3MgPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5hbmltYXRlJylcbiAgcHVibGljIHNsaWRlckVsZW1lbnRBbmltYXRlQ2xhc3MgPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy53aXRoLWxlZ2VuZCcpXG4gIHB1YmxpYyBzbGlkZXJFbGVtZW50V2l0aExlZ2VuZENsYXNzID0gZmFsc2U7XG4gIEBIb3N0QmluZGluZygnYXR0ci5kaXNhYmxlZCcpXG4gIHB1YmxpYyBzbGlkZXJFbGVtZW50RGlzYWJsZWRBdHRyPzogc3RyaW5nO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1sYWJlbCcpXG4gIHB1YmxpYyBzbGlkZXJFbGVtZW50QXJpYUxhYmVsOiBzdHJpbmcgPSAnbmd4LXNsaWRlcic7XG5cbiAgLy8gQ1NTIHN0eWxlcyBhbmQgY2xhc3MgZmxhZ3NcbiAgcHVibGljIGJhclN0eWxlOiBhbnkgPSB7fTtcbiAgcHVibGljIG1pblBvaW50ZXJTdHlsZTogYW55ID0ge307XG4gIHB1YmxpYyBtYXhQb2ludGVyU3R5bGU6IGFueSA9IHt9O1xuICBwdWJsaWMgZnVsbEJhclRyYW5zcGFyZW50Q2xhc3MgPSBmYWxzZTtcbiAgcHVibGljIHNlbGVjdGlvbkJhckRyYWdnYWJsZUNsYXNzID0gZmFsc2U7XG4gIHB1YmxpYyB0aWNrc1VuZGVyVmFsdWVzQ2xhc3MgPSBmYWxzZTtcblxuICAvLyBXaGV0aGVyIHRvIHNob3cvaGlkZSB0aWNrc1xuICBwdWJsaWMgZ2V0IHNob3dUaWNrcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3MgfHwgZmFsc2U7XG4gIH1cblxuICAvKiBJZiB0aWNrU3RlcCBpcyBzZXQgb3IgdGlja3NBcnJheSBpcyBzcGVjaWZpZWQuXG4gICAgIEluIHRoaXMgY2FzZSwgdGlja3MgdmFsdWVzIHNob3VsZCBiZSBkaXNwbGF5ZWQgYmVsb3cgdGhlIHNsaWRlci4gKi9cbiAgcHJpdmF0ZSBpbnRlcm1lZGlhdGVUaWNrczogYm9vbGVhbiA9IGZhbHNlO1xuICAvLyBUaWNrcyBhcnJheSBhcyBkaXNwbGF5ZWQgaW4gdmlld1xuICBwdWJsaWMgdGlja3M6IFRpY2tbXSA9IFtdO1xuXG4gIC8vIEV2ZW50IGxpc3RlbmVyc1xuICBwcml2YXRlIGV2ZW50TGlzdGVuZXJIZWxwZXI/OiBFdmVudExpc3RlbmVySGVscGVyO1xuICBwcml2YXRlIG9uTW92ZUV2ZW50TGlzdGVuZXI/OiBFdmVudExpc3RlbmVyO1xuICBwcml2YXRlIG9uRW5kRXZlbnRMaXN0ZW5lcj86IEV2ZW50TGlzdGVuZXI7XG4gIC8vIFdoZXRoZXIgY3VycmVudGx5IG1vdmluZyB0aGUgc2xpZGVyIChiZXR3ZWVuIG9uU3RhcnQoKSBhbmQgb25FbmQoKSlcbiAgcHJpdmF0ZSBtb3Zpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBPYnNlcnZlciBmb3Igc2xpZGVyIGVsZW1lbnQgcmVzaXplIGV2ZW50c1xuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyPzogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgLy8gQ2FsbGJhY2tzIGZvciByZWFjdGl2ZSBmb3JtcyBzdXBwb3J0XG4gIHByaXZhdGUgb25Ub3VjaGVkQ2FsbGJhY2s/OiAodmFsdWU6IGFueSkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBvbkNoYW5nZUNhbGxiYWNrPzogKHZhbHVlOiBhbnkpID0+IHZvaWQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3Rpb25SZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgem9uZTogTmdab25lXG4gICkge1xuICAgIHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlciA9IG5ldyBFdmVudExpc3RlbmVySGVscGVyKHRoaXMucmVuZGVyZXIpO1xuICB9XG5cbiAgLy8gT25Jbml0IGludGVyZmFjZVxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy52aWV3T3B0aW9ucyA9IG5ldyBPcHRpb25zKCk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnZpZXdPcHRpb25zLCB0aGlzLm9wdGlvbnMpO1xuXG4gICAgLy8gV2UgbmVlZCB0byBydW4gdGhlc2UgdHdvIHRoaW5ncyBmaXJzdCwgYmVmb3JlIHRoZSByZXN0IG9mIHRoZSBpbml0IGluIG5nQWZ0ZXJWaWV3SW5pdCgpLFxuICAgIC8vIGJlY2F1c2UgdGhlc2UgdHdvIHNldHRpbmdzIGFyZSBzZXQgdGhyb3VnaCBASG9zdEJpbmRpbmcgYW5kIEFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvblxuICAgIC8vIG1lY2hhbmlzbSBkb2Vzbid0IGxpa2UgdGhlbSBjaGFuZ2luZyBpbiBuZ0FmdGVyVmlld0luaXQoKVxuXG4gICAgdGhpcy51cGRhdGVEaXNhYmxlZFN0YXRlKCk7XG4gICAgdGhpcy51cGRhdGVWZXJ0aWNhbFN0YXRlKCk7XG4gICAgdGhpcy51cGRhdGVBcmlhTGFiZWwoKTtcbiAgfVxuXG4gIC8vIEFmdGVyVmlld0luaXQgaW50ZXJmYWNlXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5hcHBseU9wdGlvbnMoKTtcblxuICAgIHRoaXMuc3Vic2NyaWJlSW5wdXRNb2RlbENoYW5nZVN1YmplY3QoKTtcbiAgICB0aGlzLnN1YnNjcmliZU91dHB1dE1vZGVsQ2hhbmdlU3ViamVjdCgpO1xuXG4gICAgLy8gT25jZSB3ZSBhcHBseSBvcHRpb25zLCB3ZSBuZWVkIHRvIG5vcm1hbGlzZSBtb2RlbCB2YWx1ZXMgZm9yIHRoZSBmaXJzdCB0aW1lXG4gICAgdGhpcy5yZW5vcm1hbGlzZU1vZGVsVmFsdWVzKCk7XG5cbiAgICB0aGlzLnZpZXdMb3dWYWx1ZSA9IHRoaXMubW9kZWxWYWx1ZVRvVmlld1ZhbHVlKHRoaXMudmFsdWUhKTtcbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgdGhpcy52aWV3SGlnaFZhbHVlID0gdGhpcy5tb2RlbFZhbHVlVG9WaWV3VmFsdWUodGhpcy5oaWdoVmFsdWUhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWV3SGlnaFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlVmVydGljYWxTdGF0ZSgpOyAvLyBuZWVkIHRvIHJ1biB0aGlzIGFnYWluIHRvIGNvdmVyIGNoYW5nZXMgdG8gc2xpZGVyIGVsZW1lbnRzXG4gICAgdGhpcy5tYW5hZ2VFbGVtZW50c1N0eWxlKCk7XG4gICAgdGhpcy51cGRhdGVEaXNhYmxlZFN0YXRlKCk7XG4gICAgdGhpcy5jYWxjdWxhdGVWaWV3RGltZW5zaW9ucygpO1xuICAgIHRoaXMuYWRkQWNjZXNzaWJpbGl0eSgpO1xuICAgIHRoaXMudXBkYXRlQ2VpbExhYmVsKCk7XG4gICAgdGhpcy51cGRhdGVGbG9vckxhYmVsKCk7XG4gICAgdGhpcy5pbml0SGFuZGxlcygpO1xuICAgIHRoaXMubWFuYWdlRXZlbnRzQmluZGluZ3MoKTtcbiAgICB0aGlzLnVwZGF0ZUFyaWFMYWJlbCgpO1xuXG4gICAgdGhpcy5zdWJzY3JpYmVSZXNpemVPYnNlcnZlcigpO1xuXG4gICAgdGhpcy5pbml0SGFzUnVuID0gdHJ1ZTtcblxuICAgIC8vIFJ1biBjaGFuZ2UgZGV0ZWN0aW9uIG1hbnVhbGx5IHRvIHJlc29sdmUgc29tZSBpc3N1ZXMgd2hlbiBpbml0IHByb2NlZHVyZSBjaGFuZ2VzIHZhbHVlcyB1c2VkIGluIHRoZSB2aWV3XG4gICAgaWYgKCF0aGlzLmlzUmVmRGVzdHJveWVkKCkpIHtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0aW9uUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICAvLyBPbkNoYW5nZXMgaW50ZXJmYWNlXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgLy8gQWx3YXlzIGFwcGx5IG9wdGlvbnMgZmlyc3RcbiAgICBjb25zdCBvcHRpb25zID0gY2hhbmdlc1snb3B0aW9ucyddO1xuICAgIGlmIChcbiAgICAgICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZChvcHRpb25zKSAmJlxuICAgICAgSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5wcmV2aW91c1ZhbHVlKSAhPT0gSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5jdXJyZW50VmFsdWUpXG4gICAgKSB7XG4gICAgICB0aGlzLm9uQ2hhbmdlT3B0aW9ucygpO1xuICAgIH1cblxuICAgIC8vIFRoZW4gdmFsdWUgY2hhbmdlc1xuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoY2hhbmdlc1sndmFsdWUnXSkgfHwgIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKGNoYW5nZXNbJ2hpZ2hWYWx1ZSddKSkge1xuICAgICAgdGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3ViamVjdC5uZXh0KHtcbiAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgIGhpZ2hWYWx1ZTogdGhpcy5oaWdoVmFsdWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlOiBmYWxzZSxcbiAgICAgICAgaW50ZXJuYWxDaGFuZ2U6IGZhbHNlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBPbkRlc3Ryb3kgaW50ZXJmYWNlXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVuYmluZEV2ZW50cygpO1xuXG4gICAgdGhpcy51bnN1YnNjcmliZVJlc2l6ZU9ic2VydmVyKCk7XG4gICAgdGhpcy51bnN1YnNjcmliZUlucHV0TW9kZWxDaGFuZ2VTdWJqZWN0KCk7XG4gICAgdGhpcy51bnN1YnNjcmliZU91dHB1dE1vZGVsQ2hhbmdlU3ViamVjdCgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVNYW51YWxSZWZyZXNoKCk7XG4gICAgdGhpcy51bnN1YnNjcmliZVRyaWdnZXJGb2N1cygpO1xuICB9XG5cbiAgLy8gQ29udHJvbFZhbHVlQWNjZXNzb3IgaW50ZXJmYWNlXG4gIHB1YmxpYyB3cml0ZVZhbHVlKG9iajogYW55KTogdm9pZCB7XG4gICAgaWYgKG9iaiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICB0aGlzLnZhbHVlID0gb2JqWzBdO1xuICAgICAgdGhpcy5oaWdoVmFsdWUgPSBvYmpbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSBvYmo7XG4gICAgfVxuXG4gICAgLy8gbmdPbkNoYW5nZXMoKSBpcyBub3QgY2FsbGVkIGluIHRoaXMgaW5zdGFuY2UsIHNvIHdlIG5lZWQgdG8gY29tbXVuaWNhdGUgdGhlIGNoYW5nZSBtYW51YWxseVxuICAgIHRoaXMuaW5wdXRNb2RlbENoYW5nZVN1YmplY3QubmV4dCh7XG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgIGhpZ2hWYWx1ZTogdGhpcy5oaWdoVmFsdWUsXG4gICAgICBmb3JjZUNoYW5nZTogZmFsc2UsXG4gICAgICBpbnRlcm5hbENoYW5nZTogZmFsc2VcbiAgICB9KTtcbiAgfVxuXG4gIC8vIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGludGVyZmFjZVxuICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShvbkNoYW5nZUNhbGxiYWNrOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBvbkNoYW5nZUNhbGxiYWNrO1xuICB9XG5cbiAgLy8gQ29udHJvbFZhbHVlQWNjZXNzb3IgaW50ZXJmYWNlXG4gIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChvblRvdWNoZWRDYWxsYmFjazogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9IG9uVG91Y2hlZENhbGxiYWNrO1xuICB9XG5cbiAgLy8gQ29udHJvbFZhbHVlQWNjZXNzb3IgaW50ZXJmYWNlXG4gIHB1YmxpYyBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdPcHRpb25zLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB0aGlzLnVwZGF0ZURpc2FibGVkU3RhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRBcmlhTGFiZWwoYXJpYUxhYmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdPcHRpb25zLmFyaWFMYWJlbCA9IGFyaWFMYWJlbDtcbiAgICB0aGlzLnVwZGF0ZUFyaWFMYWJlbCgpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBvblJlc2l6ZShldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5jYWxjdWxhdGVWaWV3RGltZW5zaW9uc0FuZERldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlSW5wdXRNb2RlbENoYW5nZVN1YmplY3QoKTogdm9pZCB7XG4gICAgdGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uID0gdGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3ViamVjdFxuICAgICAgLnBpcGUoXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKE1vZGVsQ2hhbmdlLmNvbXBhcmUgYXMgdW5rbm93biBhcyBhbnkpLFxuICAgICAgICAvLyBIYWNrIHRvIHJlc2V0IHRoZSBzdGF0dXMgb2YgdGhlIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkgLSBpZiBhIFwiZmFrZVwiIGV2ZW50IGNvbWVzIHRocm91Z2ggd2l0aCBmb3JjZUNoYW5nZT10cnVlLFxuICAgICAgICAvLyB3ZSBmb3JjZWZ1bGx5IGJ5LXBhc3MgZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgYnV0IG90aGVyd2lzZSBkcm9wIHRoZSBldmVudFxuICAgICAgICBmaWx0ZXIoKG1vZGVsQ2hhbmdlOiBJbnB1dE1vZGVsQ2hhbmdlKSA9PiAhbW9kZWxDaGFuZ2UuZm9yY2VDaGFuZ2UgJiYgIW1vZGVsQ2hhbmdlLmludGVybmFsQ2hhbmdlKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobW9kZWxDaGFuZ2U6IElucHV0TW9kZWxDaGFuZ2UpID0+IHRoaXMuYXBwbHlJbnB1dE1vZGVsQ2hhbmdlKG1vZGVsQ2hhbmdlKSk7XG4gIH1cblxuICBwcml2YXRlIHN1YnNjcmliZU91dHB1dE1vZGVsQ2hhbmdlU3ViamVjdCgpOiB2b2lkIHtcbiAgICB0aGlzLm91dHB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uID0gdGhpcy5vdXRwdXRNb2RlbENoYW5nZVN1YmplY3RcbiAgICAgIC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKE1vZGVsQ2hhbmdlLmNvbXBhcmUpKVxuICAgICAgLnN1YnNjcmliZSgobW9kZWxDaGFuZ2U6IGFueSkgPT4gdGhpcy5wdWJsaXNoT3V0cHV0TW9kZWxDaGFuZ2UobW9kZWxDaGFuZ2UpKTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlUmVzaXplT2JzZXJ2ZXIoKTogdm9pZCB7XG4gICAgaWYgKENvbXBhdGliaWxpdHlIZWxwZXIuaXNSZXNpemVPYnNlcnZlckF2YWlsYWJsZSgpKSB7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpOiB2b2lkID0+IHRoaXMuY2FsY3VsYXRlVmlld0RpbWVuc2lvbnNBbmREZXRlY3RDaGFuZ2VzKCkpO1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVuc3Vic2NyaWJlUmVzaXplT2JzZXJ2ZXIoKTogdm9pZCB7XG4gICAgaWYgKENvbXBhdGliaWxpdHlIZWxwZXIuaXNSZXNpemVPYnNlcnZlckF2YWlsYWJsZSgpICYmIHRoaXMucmVzaXplT2JzZXJ2ZXIgIT09IG51bGwpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZU9uTW92ZSgpOiB2b2lkIHtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMub25Nb3ZlRXZlbnRMaXN0ZW5lcikpIHtcbiAgICAgIHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlcj8uZGV0YWNoRXZlbnRMaXN0ZW5lcih0aGlzLm9uTW92ZUV2ZW50TGlzdGVuZXIhKTtcbiAgICAgIHRoaXMub25Nb3ZlRXZlbnRMaXN0ZW5lciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVuc3Vic2NyaWJlT25FbmQoKTogdm9pZCB7XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLm9uRW5kRXZlbnRMaXN0ZW5lcikpIHtcbiAgICAgIHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlcj8uZGV0YWNoRXZlbnRMaXN0ZW5lcih0aGlzLm9uRW5kRXZlbnRMaXN0ZW5lciEpO1xuICAgICAgdGhpcy5vbkVuZEV2ZW50TGlzdGVuZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZUlucHV0TW9kZWxDaGFuZ2VTdWJqZWN0KCk6IHZvaWQge1xuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uKSkge1xuICAgICAgdGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5pbnB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdW5zdWJzY3JpYmVPdXRwdXRNb2RlbENoYW5nZVN1YmplY3QoKTogdm9pZCB7XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLm91dHB1dE1vZGVsQ2hhbmdlU3Vic2NyaXB0aW9uKSkge1xuICAgICAgdGhpcy5vdXRwdXRNb2RlbENoYW5nZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMub3V0cHV0TW9kZWxDaGFuZ2VTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZU1hbnVhbFJlZnJlc2goKTogdm9pZCB7XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLm1hbnVhbFJlZnJlc2hTdWJzY3JpcHRpb24pKSB7XG4gICAgICB0aGlzLm1hbnVhbFJlZnJlc2hTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubWFudWFsUmVmcmVzaFN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVuc3Vic2NyaWJlVHJpZ2dlckZvY3VzKCk6IHZvaWQge1xuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy50cmlnZ2VyRm9jdXNTdWJzY3JpcHRpb24pKSB7XG4gICAgICB0aGlzLnRyaWdnZXJGb2N1c1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy50cmlnZ2VyRm9jdXNTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0UG9pbnRlckVsZW1lbnQocG9pbnRlclR5cGU6IFBvaW50ZXJUeXBlKTogU2xpZGVySGFuZGxlRGlyZWN0aXZlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAocG9pbnRlclR5cGUgPT09IFBvaW50ZXJUeXBlLk1pbikge1xuICAgICAgcmV0dXJuIHRoaXMubWluSGFuZGxlRWxlbWVudDtcbiAgICB9IGVsc2UgaWYgKHBvaW50ZXJUeXBlID09PSBQb2ludGVyVHlwZS5NYXgpIHtcbiAgICAgIHJldHVybiB0aGlzLm1heEhhbmRsZUVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldEN1cnJlbnRUcmFja2luZ1ZhbHVlKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWluKSB7XG4gICAgICByZXR1cm4gdGhpcy52aWV3TG93VmFsdWU7XG4gICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgcmV0dXJuIHRoaXMudmlld0hpZ2hWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgbW9kZWxWYWx1ZVRvVmlld1ZhbHVlKG1vZGVsVmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKG1vZGVsVmFsdWUpKSB7XG4gICAgICByZXR1cm4gTmFOO1xuICAgIH1cblxuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5zdGVwc0FycmF5KSAmJiAhdGhpcy52aWV3T3B0aW9ucy5iaW5kSW5kZXhGb3JTdGVwc0FycmF5KSB7XG4gICAgICByZXR1cm4gVmFsdWVIZWxwZXIuZmluZFN0ZXBJbmRleCgrbW9kZWxWYWx1ZSwgdGhpcy52aWV3T3B0aW9ucy5zdGVwc0FycmF5ISk7XG4gICAgfVxuICAgIHJldHVybiArbW9kZWxWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgdmlld1ZhbHVlVG9Nb2RlbFZhbHVlKHZpZXdWYWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSkgJiYgIXRoaXMudmlld09wdGlvbnMuYmluZEluZGV4Rm9yU3RlcHNBcnJheSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RlcFZhbHVlKHZpZXdWYWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB2aWV3VmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGdldFN0ZXBWYWx1ZShzbGlkZXJWYWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzdGVwOiBDdXN0b21TdGVwRGVmaW5pdGlvbiA9IHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSFbc2xpZGVyVmFsdWVdO1xuICAgIHJldHVybiAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoc3RlcCkgPyBzdGVwLnZhbHVlIDogTmFOO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVZpZXdDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHRoaXMudmlld1ZhbHVlVG9Nb2RlbFZhbHVlKHRoaXMudmlld0xvd1ZhbHVlISk7XG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIHRoaXMuaGlnaFZhbHVlID0gdGhpcy52aWV3VmFsdWVUb01vZGVsVmFsdWUodGhpcy52aWV3SGlnaFZhbHVlISk7XG4gICAgfVxuXG4gICAgdGhpcy5vdXRwdXRNb2RlbENoYW5nZVN1YmplY3QubmV4dCh7XG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgIGhpZ2hWYWx1ZTogdGhpcy5oaWdoVmFsdWUsXG4gICAgICB1c2VyRXZlbnRJbml0aWF0ZWQ6IHRydWUsXG4gICAgICBmb3JjZUNoYW5nZTogZmFsc2VcbiAgICB9KTtcblxuICAgIC8vIEF0IHRoaXMgcG9pbnQgYWxsIGNoYW5nZXMgYXJlIGFwcGxpZWQgYW5kIG91dHB1dHMgYXJlIGVtaXR0ZWQsIHNvIHdlIHNob3VsZCBiZSBkb25lLlxuICAgIC8vIEhvd2V2ZXIsIGlucHV0IGNoYW5nZXMgYXJlIGNvbW11bmljYXRlZCBpbiBkaWZmZXJlbnQgc3RyZWFtIGFuZCB3ZSBuZWVkIHRvIGJlIHJlYWR5IHRvXG4gICAgLy8gYWN0IG9uIHRoZSBuZXh0IGlucHV0IGNoYW5nZSBldmVuIGlmIGl0IGlzIGV4YWN0bHkgdGhlIHNhbWUgYXMgbGFzdCBpbnB1dCBjaGFuZ2UuXG4gICAgLy8gVGhlcmVmb3JlLCB3ZSBzZW5kIGEgc3BlY2lhbCBldmVudCB0byByZXNldCB0aGUgc3RyZWFtLlxuICAgIHRoaXMuaW5wdXRNb2RlbENoYW5nZVN1YmplY3QubmV4dCh7XG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgIGhpZ2hWYWx1ZTogdGhpcy5oaWdoVmFsdWUsXG4gICAgICBmb3JjZUNoYW5nZTogZmFsc2UsXG4gICAgICBpbnRlcm5hbENoYW5nZTogdHJ1ZVxuICAgIH0pO1xuICB9XG5cbiAgLy8gQXBwbHkgbW9kZWwgY2hhbmdlIHRvIHRoZSBzbGlkZXIgdmlld1xuICBwcml2YXRlIGFwcGx5SW5wdXRNb2RlbENoYW5nZShtb2RlbENoYW5nZTogSW5wdXRNb2RlbENoYW5nZSk6IHZvaWQge1xuICAgIGNvbnN0IG5vcm1hbGlzZWRNb2RlbENoYW5nZTogTW9kZWxWYWx1ZXMgPSB0aGlzLm5vcm1hbGlzZU1vZGVsVmFsdWVzKG1vZGVsQ2hhbmdlKTtcblxuICAgIC8vIElmIG5vcm1hbGlzZWQgbW9kZWwgY2hhbmdlIGlzIGRpZmZlcmVudCwgYXBwbHkgdGhlIGNoYW5nZSB0byB0aGUgbW9kZWwgdmFsdWVzXG4gICAgY29uc3Qgbm9ybWFsaXNhdGlvbkNoYW5nZTogYm9vbGVhbiA9ICFNb2RlbFZhbHVlcy5jb21wYXJlKG1vZGVsQ2hhbmdlLCBub3JtYWxpc2VkTW9kZWxDaGFuZ2UpO1xuICAgIGlmIChub3JtYWxpc2F0aW9uQ2hhbmdlKSB7XG4gICAgICB0aGlzLnZhbHVlID0gbm9ybWFsaXNlZE1vZGVsQ2hhbmdlLnZhbHVlO1xuICAgICAgdGhpcy5oaWdoVmFsdWUgPSBub3JtYWxpc2VkTW9kZWxDaGFuZ2UuaGlnaFZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMudmlld0xvd1ZhbHVlID0gdGhpcy5tb2RlbFZhbHVlVG9WaWV3VmFsdWUobm9ybWFsaXNlZE1vZGVsQ2hhbmdlLnZhbHVlISk7XG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIHRoaXMudmlld0hpZ2hWYWx1ZSA9IHRoaXMubW9kZWxWYWx1ZVRvVmlld1ZhbHVlKG5vcm1hbGlzZWRNb2RlbENoYW5nZS5oaWdoVmFsdWUhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWV3SGlnaFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlTG93SGFuZGxlKHRoaXMudmFsdWVUb1Bvc2l0aW9uKHRoaXMudmlld0xvd1ZhbHVlKSk7XG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIHRoaXMudXBkYXRlSGlnaEhhbmRsZSh0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdIaWdoVmFsdWUhKSk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uQmFyKCk7XG4gICAgdGhpcy51cGRhdGVUaWNrc1NjYWxlKCk7XG4gICAgdGhpcy51cGRhdGVBcmlhQXR0cmlidXRlcygpO1xuICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUNvbWJpbmVkTGFiZWwoKTtcbiAgICB9XG5cbiAgICAvLyBBdCB0aGUgZW5kLCB3ZSBuZWVkIHRvIGNvbW11bmljYXRlIHRoZSBtb2RlbCBjaGFuZ2UgdG8gdGhlIG91dHB1dHMgYXMgd2VsbFxuICAgIC8vIE5vcm1hbGlzYXRpb24gY2hhbmdlcyBhcmUgYWxzbyBhbHdheXMgZm9yY2VkIG91dCB0byBlbnN1cmUgdGhhdCBzdWJzY3JpYmVycyBhbHdheXMgZW5kIHVwIGluIGNvcnJlY3Qgc3RhdGVcbiAgICB0aGlzLm91dHB1dE1vZGVsQ2hhbmdlU3ViamVjdC5uZXh0KHtcbiAgICAgIHZhbHVlOiBub3JtYWxpc2VkTW9kZWxDaGFuZ2UudmFsdWUsXG4gICAgICBoaWdoVmFsdWU6IG5vcm1hbGlzZWRNb2RlbENoYW5nZS5oaWdoVmFsdWUsXG4gICAgICBmb3JjZUNoYW5nZTogbm9ybWFsaXNhdGlvbkNoYW5nZSxcbiAgICAgIHVzZXJFdmVudEluaXRpYXRlZDogZmFsc2VcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFB1Ymxpc2ggbW9kZWwgY2hhbmdlIHRvIG91dHB1dCBldmVudCBlbWl0dGVycyBhbmQgcmVnaXN0ZXJlZCBjYWxsYmFja3NcbiAgcHJpdmF0ZSBwdWJsaXNoT3V0cHV0TW9kZWxDaGFuZ2UobW9kZWxDaGFuZ2U6IE91dHB1dE1vZGVsQ2hhbmdlKTogdm9pZCB7XG4gICAgY29uc3QgZW1pdE91dHB1dHM6ICgpID0+IHZvaWQgPSAoKTogdm9pZCA9PiB7XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQobW9kZWxDaGFuZ2UudmFsdWUpO1xuICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgdGhpcy5oaWdoVmFsdWVDaGFuZ2UuZW1pdChtb2RlbENoYW5nZS5oaWdoVmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMub25DaGFuZ2VDYWxsYmFjaykpIHtcbiAgICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2shKFttb2RlbENoYW5nZS52YWx1ZSwgbW9kZWxDaGFuZ2UuaGlnaFZhbHVlXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrIShtb2RlbENoYW5nZS52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5vblRvdWNoZWRDYWxsYmFjaykpIHtcbiAgICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgICB0aGlzLm9uVG91Y2hlZENhbGxiYWNrIShbbW9kZWxDaGFuZ2UudmFsdWUsIG1vZGVsQ2hhbmdlLmhpZ2hWYWx1ZV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMub25Ub3VjaGVkQ2FsbGJhY2shKG1vZGVsQ2hhbmdlLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAobW9kZWxDaGFuZ2UudXNlckV2ZW50SW5pdGlhdGVkKSB7XG4gICAgICAvLyBJZiB0aGlzIGNoYW5nZSB3YXMgaW5pdGlhdGVkIGJ5IGEgdXNlciBldmVudCwgd2UgY2FuIGVtaXQgb3V0cHV0cyBpbiB0aGUgc2FtZSB0aWNrXG4gICAgICBlbWl0T3V0cHV0cygpO1xuICAgICAgdGhpcy51c2VyQ2hhbmdlLmVtaXQodGhpcy5nZXRDaGFuZ2VDb250ZXh0KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBCdXQsIGlmIHRoZSBjaGFuZ2Ugd2FzIGluaXRhdGVkIGJ5IHNvbWV0aGluZyBlbHNlIGxpa2UgYSBjaGFuZ2UgaW4gaW5wdXQgYmluZGluZ3MsXG4gICAgICAvLyB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgbmV4dCB0aWNrIHRvIGVtaXQgdGhlIG91dHB1dHMgdG8ga2VlcCBBbmd1bGFyIGNoYW5nZSBkZXRlY3Rpb24gaGFwcHlcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBlbWl0T3V0cHV0cygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpc2VNb2RlbFZhbHVlcyhpbnB1dDogTW9kZWxWYWx1ZXMpOiBNb2RlbFZhbHVlcyB7XG4gICAgY29uc3Qgbm9ybWFsaXNlZElucHV0OiBNb2RlbFZhbHVlcyA9IG5ldyBNb2RlbFZhbHVlcygpO1xuICAgIG5vcm1hbGlzZWRJbnB1dC52YWx1ZSA9IGlucHV0LnZhbHVlO1xuICAgIG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWUgPSBpbnB1dC5oaWdoVmFsdWU7XG5cbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSkpIHtcbiAgICAgIC8vIFdoZW4gdXNpbmcgc3RlcHMgYXJyYXksIG9ubHkgcm91bmQgdG8gbmVhcmVzdCBzdGVwIGluIHRoZSBhcnJheVxuICAgICAgLy8gTm8gb3RoZXIgZW5mb3JjZW1lbnQgY2FuIGJlIGRvbmUsIGFzIHRoZSBzdGVwIGFycmF5IG1heSBiZSBvdXQgb2Ygb3JkZXIsIGFuZCB0aGF0IGlzIHBlcmZlY3RseSBmaW5lXG4gICAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5lbmZvcmNlU3RlcHNBcnJheSkge1xuICAgICAgICBjb25zdCB2YWx1ZUluZGV4OiBudW1iZXIgPSBWYWx1ZUhlbHBlci5maW5kU3RlcEluZGV4KG5vcm1hbGlzZWRJbnB1dC52YWx1ZSEsIHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSEpO1xuICAgICAgICBub3JtYWxpc2VkSW5wdXQudmFsdWUgPSB0aGlzLnZpZXdPcHRpb25zLnN0ZXBzQXJyYXkhW3ZhbHVlSW5kZXhdLnZhbHVlO1xuXG4gICAgICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICAgICAgY29uc3QgaGlnaFZhbHVlSW5kZXg6IG51bWJlciA9IFZhbHVlSGVscGVyLmZpbmRTdGVwSW5kZXgoXG4gICAgICAgICAgICBub3JtYWxpc2VkSW5wdXQuaGlnaFZhbHVlISxcbiAgICAgICAgICAgIHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSFcbiAgICAgICAgICApO1xuICAgICAgICAgIG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWUgPSB0aGlzLnZpZXdPcHRpb25zLnN0ZXBzQXJyYXkhW2hpZ2hWYWx1ZUluZGV4XS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbm9ybWFsaXNlZElucHV0O1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmVuZm9yY2VTdGVwKSB7XG4gICAgICBub3JtYWxpc2VkSW5wdXQudmFsdWUgPSB0aGlzLnJvdW5kU3RlcChub3JtYWxpc2VkSW5wdXQudmFsdWUhKTtcbiAgICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICAgIG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWUgPSB0aGlzLnJvdW5kU3RlcChub3JtYWxpc2VkSW5wdXQuaGlnaFZhbHVlISk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmlld09wdGlvbnMuZW5mb3JjZVJhbmdlKSB7XG4gICAgICBub3JtYWxpc2VkSW5wdXQudmFsdWUgPSBNYXRoSGVscGVyLmNsYW1wVG9SYW5nZShcbiAgICAgICAgbm9ybWFsaXNlZElucHV0LnZhbHVlISxcbiAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5mbG9vciEsXG4gICAgICAgIHRoaXMudmlld09wdGlvbnMuY2VpbCFcbiAgICAgICk7XG5cbiAgICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICAgIG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWUgPSBNYXRoSGVscGVyLmNsYW1wVG9SYW5nZShcbiAgICAgICAgICBub3JtYWxpc2VkSW5wdXQuaGlnaFZhbHVlISxcbiAgICAgICAgICB0aGlzLnZpZXdPcHRpb25zLmZsb29yISxcbiAgICAgICAgICB0aGlzLnZpZXdPcHRpb25zLmNlaWwhXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHJhbmdlIHNsaWRlciBpbnZhcmlhbnQgKHZhbHVlIDw9IGhpZ2hWYWx1ZSkgaXMgYWx3YXlzIHNhdGlzZmllZFxuICAgICAgaWYgKHRoaXMucmFuZ2UgJiYgaW5wdXQudmFsdWUhID4gaW5wdXQuaGlnaFZhbHVlISkge1xuICAgICAgICAvLyBXZSBrbm93IHRoYXQgYm90aCB2YWx1ZXMgYXJlIG5vdyBjbGFtcGVkIGNvcnJlY3RseSwgdGhleSBtYXkganVzdCBiZSBpbiB0aGUgd3Jvbmcgb3JkZXJcbiAgICAgICAgLy8gU28gdGhlIGVhc3kgc29sdXRpb24gaXMgdG8gc3dhcCB0aGVtLi4uIGV4Y2VwdCBzd2FwcGluZyBpcyBzb21ldGltZXMgZGlzYWJsZWQgaW4gb3B0aW9ucywgc28gd2UgbWFrZSB0aGUgdHdvIHZhbHVlcyB0aGUgc2FtZVxuICAgICAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5ub1N3aXRjaGluZykge1xuICAgICAgICAgIG5vcm1hbGlzZWRJbnB1dC52YWx1ZSA9IG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgdGVtcFZhbHVlID0gaW5wdXQudmFsdWU7XG4gICAgICAgICAgbm9ybWFsaXNlZElucHV0LnZhbHVlID0gaW5wdXQuaGlnaFZhbHVlO1xuICAgICAgICAgIG5vcm1hbGlzZWRJbnB1dC5oaWdoVmFsdWUgPSB0ZW1wVmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXNlZElucHV0O1xuICB9XG5cbiAgcHJpdmF0ZSByZW5vcm1hbGlzZU1vZGVsVmFsdWVzKCk6IHZvaWQge1xuICAgIGNvbnN0IHByZXZpb3VzTW9kZWxWYWx1ZXM6IE1vZGVsVmFsdWVzID0ge1xuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICBoaWdoVmFsdWU6IHRoaXMuaGlnaFZhbHVlXG4gICAgfTtcbiAgICBjb25zdCBub3JtYWxpc2VkTW9kZWxWYWx1ZXM6IE1vZGVsVmFsdWVzID0gdGhpcy5ub3JtYWxpc2VNb2RlbFZhbHVlcyhwcmV2aW91c01vZGVsVmFsdWVzKTtcbiAgICBpZiAoIU1vZGVsVmFsdWVzLmNvbXBhcmUobm9ybWFsaXNlZE1vZGVsVmFsdWVzLCBwcmV2aW91c01vZGVsVmFsdWVzKSkge1xuICAgICAgdGhpcy52YWx1ZSA9IG5vcm1hbGlzZWRNb2RlbFZhbHVlcy52YWx1ZTtcbiAgICAgIHRoaXMuaGlnaFZhbHVlID0gbm9ybWFsaXNlZE1vZGVsVmFsdWVzLmhpZ2hWYWx1ZTtcblxuICAgICAgdGhpcy5vdXRwdXRNb2RlbENoYW5nZVN1YmplY3QubmV4dCh7XG4gICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlLFxuICAgICAgICBoaWdoVmFsdWU6IHRoaXMuaGlnaFZhbHVlLFxuICAgICAgICBmb3JjZUNoYW5nZTogdHJ1ZSxcbiAgICAgICAgdXNlckV2ZW50SW5pdGlhdGVkOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkNoYW5nZU9wdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmluaXRIYXNSdW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aW91c09wdGlvbnNJbmZsdWVuY2luZ0V2ZW50QmluZGluZ3M6IGJvb2xlYW5bXSA9IHRoaXMuZ2V0T3B0aW9uc0luZmx1ZW5jaW5nRXZlbnRCaW5kaW5ncyhcbiAgICAgIHRoaXMudmlld09wdGlvbnNcbiAgICApO1xuXG4gICAgdGhpcy5hcHBseU9wdGlvbnMoKTtcblxuICAgIGNvbnN0IG5ld09wdGlvbnNJbmZsdWVuY2luZ0V2ZW50QmluZGluZ3M6IGJvb2xlYW5bXSA9IHRoaXMuZ2V0T3B0aW9uc0luZmx1ZW5jaW5nRXZlbnRCaW5kaW5ncyh0aGlzLnZpZXdPcHRpb25zKTtcbiAgICAvLyBBdm9pZCByZS1iaW5kaW5nIGV2ZW50cyBpbiBjYXNlIG5vdGhpbmcgY2hhbmdlcyB0aGF0IGNhbiBpbmZsdWVuY2UgaXRcbiAgICAvLyBJdCBtYWtlcyBpdCBwb3NzaWJsZSB0byBjaGFuZ2Ugb3B0aW9ucyB3aGlsZSBkcmFnZ2luZyB0aGUgc2xpZGVyXG4gICAgY29uc3QgcmViaW5kRXZlbnRzOiBib29sZWFuID0gIVZhbHVlSGVscGVyLmFyZUFycmF5c0VxdWFsKFxuICAgICAgcHJldmlvdXNPcHRpb25zSW5mbHVlbmNpbmdFdmVudEJpbmRpbmdzLFxuICAgICAgbmV3T3B0aW9uc0luZmx1ZW5jaW5nRXZlbnRCaW5kaW5nc1xuICAgICk7XG5cbiAgICAvLyBXaXRoIG5ldyBvcHRpb25zLCB3ZSBuZWVkIHRvIHJlLW5vcm1hbGlzZSBtb2RlbCB2YWx1ZXMgaWYgbmVjZXNzYXJ5XG4gICAgdGhpcy5yZW5vcm1hbGlzZU1vZGVsVmFsdWVzKCk7XG5cbiAgICB0aGlzLnZpZXdMb3dWYWx1ZSA9IHRoaXMubW9kZWxWYWx1ZVRvVmlld1ZhbHVlKHRoaXMudmFsdWUhKTtcbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgdGhpcy52aWV3SGlnaFZhbHVlID0gdGhpcy5tb2RlbFZhbHVlVG9WaWV3VmFsdWUodGhpcy5oaWdoVmFsdWUhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWV3SGlnaFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRTbGlkZXIocmViaW5kRXZlbnRzKTtcbiAgfVxuXG4gIC8vIFJlYWQgdGhlIHVzZXIgb3B0aW9ucyBhbmQgYXBwbHkgdGhlbSB0byB0aGUgc2xpZGVyIG1vZGVsXG4gIHByaXZhdGUgYXBwbHlPcHRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMudmlld09wdGlvbnMgPSBuZXcgT3B0aW9ucygpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy52aWV3T3B0aW9ucywgdGhpcy5vcHRpb25zKTtcblxuICAgIHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2UgPSB0aGlzLnJhbmdlICYmIHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2U7XG4gICAgdGhpcy52aWV3T3B0aW9ucy5kcmFnZ2FibGVSYW5nZU9ubHkgPSB0aGlzLnJhbmdlICYmIHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2VPbmx5O1xuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmRyYWdnYWJsZVJhbmdlT25seSkge1xuICAgICAgdGhpcy52aWV3T3B0aW9ucy5kcmFnZ2FibGVSYW5nZSA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3MgPVxuICAgICAgdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3MgfHxcbiAgICAgIHRoaXMudmlld09wdGlvbnMuc2hvd1RpY2tzVmFsdWVzIHx8XG4gICAgICAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy50aWNrc0FycmF5KTtcbiAgICBpZiAoXG4gICAgICB0aGlzLnZpZXdPcHRpb25zLnNob3dUaWNrcyAmJlxuICAgICAgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnRpY2tTdGVwKSB8fFxuICAgICAgICAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy50aWNrc0FycmF5KSlcbiAgICApIHtcbiAgICAgIHRoaXMuaW50ZXJtZWRpYXRlVGlja3MgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhciA9XG4gICAgICB0aGlzLnZpZXdPcHRpb25zLnNob3dTZWxlY3Rpb25CYXIgfHxcbiAgICAgIHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhckVuZCB8fFxuICAgICAgIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhckZyb21WYWx1ZSk7XG5cbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSkpIHtcbiAgICAgIHRoaXMuYXBwbHlTdGVwc0FycmF5T3B0aW9ucygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGx5Rmxvb3JDZWlsT3B0aW9ucygpO1xuICAgIH1cblxuICAgIGlmIChWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmNvbWJpbmVMYWJlbHMpKSB7XG4gICAgICB0aGlzLnZpZXdPcHRpb25zLmNvbWJpbmVMYWJlbHMgPSAobWluVmFsdWU6IHN0cmluZywgbWF4VmFsdWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICAgIHJldHVybiBtaW5WYWx1ZSArICcgLSAnICsgbWF4VmFsdWU7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmxvZ1NjYWxlICYmIHRoaXMudmlld09wdGlvbnMuZmxvb3IgPT09IDApIHtcbiAgICAgIHRocm93IEVycm9yKFwiQ2FuJ3QgdXNlIGZsb29yPTAgd2l0aCBsb2dhcml0aG1pYyBzY2FsZVwiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwcGx5U3RlcHNBcnJheU9wdGlvbnMoKTogdm9pZCB7XG4gICAgdGhpcy52aWV3T3B0aW9ucy5mbG9vciA9IDA7XG4gICAgdGhpcy52aWV3T3B0aW9ucy5jZWlsID0gdGhpcy52aWV3T3B0aW9ucy5zdGVwc0FycmF5IS5sZW5ndGggLSAxO1xuICAgIHRoaXMudmlld09wdGlvbnMuc3RlcCA9IDE7XG5cbiAgICBpZiAoVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy50cmFuc2xhdGUpKSB7XG4gICAgICB0aGlzLnZpZXdPcHRpb25zLnRyYW5zbGF0ZSA9IChtb2RlbFZhbHVlOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5iaW5kSW5kZXhGb3JTdGVwc0FycmF5KSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZyh0aGlzLmdldFN0ZXBWYWx1ZShtb2RlbFZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFN0cmluZyhtb2RlbFZhbHVlKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBseUZsb29yQ2VpbE9wdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc3RlcCkpIHtcbiAgICAgIHRoaXMudmlld09wdGlvbnMuc3RlcCA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmlld09wdGlvbnMuc3RlcCA9ICt0aGlzLnZpZXdPcHRpb25zLnN0ZXAhO1xuICAgICAgaWYgKHRoaXMudmlld09wdGlvbnMuc3RlcCA8PSAwKSB7XG4gICAgICAgIHRoaXMudmlld09wdGlvbnMuc3RlcCA9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuY2VpbCkgfHwgVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5mbG9vcikpIHtcbiAgICAgIHRocm93IEVycm9yKCdmbG9vciBhbmQgY2VpbCBvcHRpb25zIG11c3QgYmUgc3VwcGxpZWQnKTtcbiAgICB9XG4gICAgdGhpcy52aWV3T3B0aW9ucy5jZWlsID0gK3RoaXMudmlld09wdGlvbnMuY2VpbCE7XG4gICAgdGhpcy52aWV3T3B0aW9ucy5mbG9vciA9ICt0aGlzLnZpZXdPcHRpb25zLmZsb29yITtcblxuICAgIGlmIChWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnRyYW5zbGF0ZSkpIHtcbiAgICAgIHRoaXMudmlld09wdGlvbnMudHJhbnNsYXRlID0gKHZhbHVlOiBudW1iZXIpOiBzdHJpbmcgPT4gU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXNldHMgc2xpZGVyXG4gIHByaXZhdGUgcmVzZXRTbGlkZXIocmViaW5kRXZlbnRzOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgIHRoaXMubWFuYWdlRWxlbWVudHNTdHlsZSgpO1xuICAgIHRoaXMuYWRkQWNjZXNzaWJpbGl0eSgpO1xuICAgIHRoaXMudXBkYXRlQ2VpbExhYmVsKCk7XG4gICAgdGhpcy51cGRhdGVGbG9vckxhYmVsKCk7XG4gICAgaWYgKHJlYmluZEV2ZW50cykge1xuICAgICAgdGhpcy51bmJpbmRFdmVudHMoKTtcbiAgICAgIHRoaXMubWFuYWdlRXZlbnRzQmluZGluZ3MoKTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVEaXNhYmxlZFN0YXRlKCk7XG4gICAgdGhpcy51cGRhdGVBcmlhTGFiZWwoKTtcbiAgICB0aGlzLmNhbGN1bGF0ZVZpZXdEaW1lbnNpb25zKCk7XG4gICAgdGhpcy5yZWZvY3VzUG9pbnRlcklmTmVlZGVkKCk7XG4gIH1cblxuICAvLyBTZXRzIGZvY3VzIG9uIHRoZSBzcGVjaWZpZWQgcG9pbnRlclxuICBwcml2YXRlIGZvY3VzUG9pbnRlcihwb2ludGVyVHlwZTogUG9pbnRlclR5cGUpOiB2b2lkIHtcbiAgICAvLyBJZiBub3Qgc3VwcGxpZWQsIHVzZSBtaW4gcG9pbnRlciBhcyBkZWZhdWx0XG4gICAgaWYgKHBvaW50ZXJUeXBlICE9PSBQb2ludGVyVHlwZS5NaW4gJiYgcG9pbnRlclR5cGUgIT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgcG9pbnRlclR5cGUgPSBQb2ludGVyVHlwZS5NaW47XG4gICAgfVxuXG4gICAgaWYgKHBvaW50ZXJUeXBlID09PSBQb2ludGVyVHlwZS5NaW4pIHtcbiAgICAgIHRoaXMubWluSGFuZGxlRWxlbWVudD8uZm9jdXMoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMucmFuZ2UgJiYgcG9pbnRlclR5cGUgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVmb2N1c1BvaW50ZXJJZk5lZWRlZCgpOiB2b2lkIHtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuY3VycmVudEZvY3VzUG9pbnRlcikpIHtcbiAgICAgIHRoaXMub25Qb2ludGVyRm9jdXModGhpcy5jdXJyZW50Rm9jdXNQb2ludGVyISk7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5nZXRQb2ludGVyRWxlbWVudCh0aGlzLmN1cnJlbnRGb2N1c1BvaW50ZXIhKTtcbiAgICAgIGVsZW1lbnQ/LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVXBkYXRlIGVhY2ggZWxlbWVudHMgc3R5bGUgYmFzZWQgb24gb3B0aW9uc1xuICBwcml2YXRlIG1hbmFnZUVsZW1lbnRzU3R5bGUoKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVTY2FsZSgpO1xuICAgIHRoaXMuZmxvb3JMYWJlbEVsZW1lbnQ/LnNldEFsd2F5c0hpZGUodGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3NWYWx1ZXMhIHx8IHRoaXMudmlld09wdGlvbnMuaGlkZUxpbWl0TGFiZWxzISk7XG4gICAgdGhpcy5jZWlsTGFiZWxFbGVtZW50Py5zZXRBbHdheXNIaWRlKHRoaXMudmlld09wdGlvbnMuc2hvd1RpY2tzVmFsdWVzISB8fCB0aGlzLnZpZXdPcHRpb25zLmhpZGVMaW1pdExhYmVscyEpO1xuXG4gICAgY29uc3QgaGlkZUxhYmVsc0ZvclRpY2tzOiBib29sZWFuID0gdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3NWYWx1ZXMhICYmICF0aGlzLmludGVybWVkaWF0ZVRpY2tzITtcbiAgICB0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudD8uc2V0QWx3YXlzSGlkZShoaWRlTGFiZWxzRm9yVGlja3MgfHwgdGhpcy52aWV3T3B0aW9ucy5oaWRlUG9pbnRlckxhYmVscyEpO1xuICAgIHRoaXMubWF4SGFuZGxlTGFiZWxFbGVtZW50Py5zZXRBbHdheXNIaWRlKGhpZGVMYWJlbHNGb3JUaWNrcyB8fCAhdGhpcy5yYW5nZSB8fCB0aGlzLnZpZXdPcHRpb25zLmhpZGVQb2ludGVyTGFiZWxzISk7XG4gICAgdGhpcy5jb21iaW5lZExhYmVsRWxlbWVudD8uc2V0QWx3YXlzSGlkZShoaWRlTGFiZWxzRm9yVGlja3MgfHwgIXRoaXMucmFuZ2UgfHwgdGhpcy52aWV3T3B0aW9ucy5oaWRlUG9pbnRlckxhYmVscyEpO1xuICAgIHRoaXMuc2VsZWN0aW9uQmFyRWxlbWVudD8uc2V0QWx3YXlzSGlkZSghdGhpcy5yYW5nZSAmJiAhdGhpcy52aWV3T3B0aW9ucy5zaG93U2VsZWN0aW9uQmFyKTtcbiAgICB0aGlzLmxlZnRPdXRlclNlbGVjdGlvbkJhckVsZW1lbnQ/LnNldEFsd2F5c0hpZGUoIXRoaXMucmFuZ2UgfHwgIXRoaXMudmlld09wdGlvbnMuc2hvd091dGVyU2VsZWN0aW9uQmFycyk7XG4gICAgdGhpcy5yaWdodE91dGVyU2VsZWN0aW9uQmFyRWxlbWVudD8uc2V0QWx3YXlzSGlkZSghdGhpcy5yYW5nZSB8fCAhdGhpcy52aWV3T3B0aW9ucy5zaG93T3V0ZXJTZWxlY3Rpb25CYXJzKTtcblxuICAgIHRoaXMuZnVsbEJhclRyYW5zcGFyZW50Q2xhc3MgPSB0aGlzLnJhbmdlICYmIHRoaXMudmlld09wdGlvbnMuc2hvd091dGVyU2VsZWN0aW9uQmFycyE7XG4gICAgdGhpcy5zZWxlY3Rpb25CYXJEcmFnZ2FibGVDbGFzcyA9IHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2UhICYmICF0aGlzLnZpZXdPcHRpb25zLm9ubHlCaW5kSGFuZGxlcyE7XG4gICAgdGhpcy50aWNrc1VuZGVyVmFsdWVzQ2xhc3MgPSB0aGlzLmludGVybWVkaWF0ZVRpY2tzICYmIHRoaXMub3B0aW9ucy5zaG93VGlja3NWYWx1ZXMhO1xuXG4gICAgaWYgKHRoaXMuc2xpZGVyRWxlbWVudFZlcnRpY2FsQ2xhc3MgIT09IHRoaXMudmlld09wdGlvbnMudmVydGljYWwpIHtcbiAgICAgIHRoaXMudXBkYXRlVmVydGljYWxTdGF0ZSgpO1xuICAgICAgLy8gVGhlIGFib3ZlIGNoYW5nZSBpbiBob3N0IGNvbXBvbmVudCBjbGFzcyB3aWxsIG5vdCBiZSBhcHBsaWVkIHVudGlsIHRoZSBlbmQgb2YgdGhpcyBjeWNsZVxuICAgICAgLy8gSG93ZXZlciwgZnVuY3Rpb25zIGNhbGN1bGF0aW5nIHRoZSBzbGlkZXIgcG9zaXRpb24gZXhwZWN0IHRoZSBzbGlkZXIgdG8gYmUgYWxyZWFkeSBzdHlsZWQgYXMgdmVydGljYWxcbiAgICAgIC8vIFNvIGFzIGEgd29ya2Fyb3VuZCwgd2UgbmVlZCB0byByZXNldCB0aGUgc2xpZGVyIG9uY2UgYWdhaW4gdG8gY29tcHV0ZSB0aGUgY29ycmVjdCB2YWx1ZXNcbiAgICAgIHNldFRpbWVvdXQoKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnJlc2V0U2xpZGVyKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDaGFuZ2luZyBhbmltYXRlIGNsYXNzIG1heSBpbnRlcmZlcmUgd2l0aCBzbGlkZXIgcmVzZXQvaW5pdGlhbGlzYXRpb24sIHNvIHdlIHNob3VsZCBzZXQgaXQgc2VwYXJhdGVseSxcbiAgICAvLyBhZnRlciBhbGwgaXMgcHJvcGVybHkgc2V0IHVwXG4gICAgaWYgKHRoaXMuc2xpZGVyRWxlbWVudEFuaW1hdGVDbGFzcyAhPT0gdGhpcy52aWV3T3B0aW9ucy5hbmltYXRlKSB7XG4gICAgICBzZXRUaW1lb3V0KCgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zbGlkZXJFbGVtZW50QW5pbWF0ZUNsYXNzID0gdGhpcy52aWV3T3B0aW9ucy5hbmltYXRlITtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVJvdGF0ZSgpO1xuICB9XG5cbiAgLy8gTWFuYWdlIHRoZSBldmVudHMgYmluZGluZ3MgYmFzZWQgb24gcmVhZE9ubHkgYW5kIGRpc2FibGVkIG9wdGlvbnNcbiAgcHJpdmF0ZSBtYW5hZ2VFdmVudHNCaW5kaW5ncygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5kaXNhYmxlZCB8fCB0aGlzLnZpZXdPcHRpb25zLnJlYWRPbmx5KSB7XG4gICAgICB0aGlzLnVuYmluZEV2ZW50cygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJpbmRFdmVudHMoKTtcbiAgICB9XG4gIH1cblxuICAvLyBTZXQgdGhlIGRpc2FibGVkIHN0YXRlIGJhc2VkIG9uIGRpc2FibGVkIG9wdGlvblxuICBwcml2YXRlIHVwZGF0ZURpc2FibGVkU3RhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5zbGlkZXJFbGVtZW50RGlzYWJsZWRBdHRyID0gdGhpcy52aWV3T3B0aW9ucy5kaXNhYmxlZCA/ICdkaXNhYmxlZCcgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBTZXQgdGhlIGFyaWEtbGFiZWwgc3RhdGUgYmFzZWQgb24gYXJpYUxhYmVsIG9wdGlvblxuICBwcml2YXRlIHVwZGF0ZUFyaWFMYWJlbCgpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWRlckVsZW1lbnRBcmlhTGFiZWwgPSB0aGlzLnZpZXdPcHRpb25zLmFyaWFMYWJlbCB8fCAnbnhnLXNsaWRlcic7XG4gIH1cblxuICAvLyBTZXQgdmVydGljYWwgc3RhdGUgYmFzZWQgb24gdmVydGljYWwgb3B0aW9uXG4gIHByaXZhdGUgdXBkYXRlVmVydGljYWxTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWRlckVsZW1lbnRWZXJ0aWNhbENsYXNzID0gdGhpcy52aWV3T3B0aW9ucy52ZXJ0aWNhbCE7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuZ2V0QWxsU2xpZGVyRWxlbWVudHMoKSkge1xuICAgICAgLy8gVGhpcyBpcyBhbHNvIGNhbGxlZCBiZWZvcmUgbmdBZnRlckluaXQsIHNvIG5lZWQgdG8gY2hlY2sgdGhhdCB2aWV3IGNoaWxkIGJpbmRpbmdzIHdvcmtcbiAgICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoZWxlbWVudCkpIHtcbiAgICAgICAgZWxlbWVudC5zZXRWZXJ0aWNhbCh0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsISk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTY2FsZSgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGhpcy5nZXRBbGxTbGlkZXJFbGVtZW50cygpKSB7XG4gICAgICBlbGVtZW50LnNldFNjYWxlKHRoaXMudmlld09wdGlvbnMuc2NhbGUhKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVJvdGF0ZSgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGhpcy5nZXRBbGxTbGlkZXJFbGVtZW50cygpKSB7XG4gICAgICBlbGVtZW50LnNldFJvdGF0ZSh0aGlzLnZpZXdPcHRpb25zLnJvdGF0ZSEpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWxsU2xpZGVyRWxlbWVudHMoKTogU2xpZGVyRWxlbWVudERpcmVjdGl2ZVtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5sZWZ0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50ISxcbiAgICAgIHRoaXMucmlnaHRPdXRlclNlbGVjdGlvbkJhckVsZW1lbnQhLFxuICAgICAgdGhpcy5mdWxsQmFyRWxlbWVudCEsXG4gICAgICB0aGlzLnNlbGVjdGlvbkJhckVsZW1lbnQhLFxuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50ISxcbiAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEsXG4gICAgICB0aGlzLmZsb29yTGFiZWxFbGVtZW50ISxcbiAgICAgIHRoaXMuY2VpbExhYmVsRWxlbWVudCEsXG4gICAgICB0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudCEsXG4gICAgICB0aGlzLm1heEhhbmRsZUxhYmVsRWxlbWVudCEsXG4gICAgICB0aGlzLmNvbWJpbmVkTGFiZWxFbGVtZW50ISxcbiAgICAgIHRoaXMudGlja3NFbGVtZW50IVxuICAgIF07XG4gIH1cblxuICAvLyBJbml0aWFsaXplIHNsaWRlciBoYW5kbGVzIHBvc2l0aW9ucyBhbmQgbGFiZWxzXG4gIC8vIFJ1biBvbmx5IG9uY2UgZHVyaW5nIGluaXRpYWxpemF0aW9uIGFuZCBldmVyeSB0aW1lIHZpZXcgcG9ydCBjaGFuZ2VzIHNpemVcbiAgcHJpdmF0ZSBpbml0SGFuZGxlcygpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUxvd0hhbmRsZSh0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdMb3dWYWx1ZSEpKTtcblxuICAgIC8qXG4gICB0aGUgb3JkZXIgaGVyZSBpcyBpbXBvcnRhbnQgc2luY2UgdGhlIHNlbGVjdGlvbiBiYXIgc2hvdWxkIGJlXG4gICB1cGRhdGVkIGFmdGVyIHRoZSBoaWdoIGhhbmRsZSBidXQgYmVmb3JlIHRoZSBjb21iaW5lZCBsYWJlbFxuICAgKi9cbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgdGhpcy51cGRhdGVIaWdoSGFuZGxlKHRoaXMudmFsdWVUb1Bvc2l0aW9uKHRoaXMudmlld0hpZ2hWYWx1ZSEpKTtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbkJhcigpO1xuXG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIHRoaXMudXBkYXRlQ29tYmluZWRMYWJlbCgpO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlVGlja3NTY2FsZSgpO1xuICB9XG5cbiAgLy8gQWRkcyBhY2Nlc3NpYmlsaXR5IGF0dHJpYnV0ZXMsIHJ1biBvbmx5IG9uY2UgZHVyaW5nIGluaXRpYWxpemF0aW9uXG4gIHByaXZhdGUgYWRkQWNjZXNzaWJpbGl0eSgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUFyaWFBdHRyaWJ1dGVzKCk7XG5cbiAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLnJvbGUgPSAnc2xpZGVyJztcblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmtleWJvYXJkU3VwcG9ydCAmJiAhKHRoaXMudmlld09wdGlvbnMucmVhZE9ubHkgfHwgdGhpcy52aWV3T3B0aW9ucy5kaXNhYmxlZCkpIHtcbiAgICAgIHRoaXMubWluSGFuZGxlRWxlbWVudCEudGFiaW5kZXggPSAnMCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWluSGFuZGxlRWxlbWVudCEudGFiaW5kZXggPSAnJztcbiAgICB9XG5cbiAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmFyaWFPcmllbnRhdGlvbiA9XG4gICAgICB0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsIHx8IHRoaXMudmlld09wdGlvbnMucm90YXRlICE9PSAwID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcblxuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5hcmlhTGFiZWwpKSB7XG4gICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmFyaWFMYWJlbCA9IHRoaXMudmlld09wdGlvbnMuYXJpYUxhYmVsITtcbiAgICB9IGVsc2UgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmFyaWFMYWJlbGxlZEJ5KSkge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5hcmlhTGFiZWxsZWRCeSA9IHRoaXMudmlld09wdGlvbnMuYXJpYUxhYmVsbGVkQnkhO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLnJvbGUgPSAnc2xpZGVyJztcblxuICAgICAgaWYgKHRoaXMudmlld09wdGlvbnMua2V5Ym9hcmRTdXBwb3J0ICYmICEodGhpcy52aWV3T3B0aW9ucy5yZWFkT25seSB8fCB0aGlzLnZpZXdPcHRpb25zLmRpc2FibGVkKSkge1xuICAgICAgICB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLnRhYmluZGV4ID0gJzAnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS50YWJpbmRleCA9ICcnO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLmFyaWFPcmllbnRhdGlvbiA9XG4gICAgICAgIHRoaXMudmlld09wdGlvbnMudmVydGljYWwgfHwgdGhpcy52aWV3T3B0aW9ucy5yb3RhdGUgIT09IDAgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuXG4gICAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuYXJpYUxhYmVsSGlnaCkpIHtcbiAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5hcmlhTGFiZWwgPSB0aGlzLnZpZXdPcHRpb25zLmFyaWFMYWJlbEhpZ2ghO1xuICAgICAgfSBlbHNlIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5hcmlhTGFiZWxsZWRCeUhpZ2gpKSB7XG4gICAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuYXJpYUxhYmVsbGVkQnkgPSB0aGlzLnZpZXdPcHRpb25zLmFyaWFMYWJlbGxlZEJ5SGlnaCE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gVXBkYXRlcyBhcmlhIGF0dHJpYnV0ZXMgYWNjb3JkaW5nIHRvIGN1cnJlbnQgdmFsdWVzXG4gIHByaXZhdGUgdXBkYXRlQXJpYUF0dHJpYnV0ZXMoKTogdm9pZCB7XG4gICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5hcmlhVmFsdWVOb3cgPSAoK3RoaXMudmFsdWUhKS50b1N0cmluZygpO1xuICAgIHRoaXMubWluSGFuZGxlRWxlbWVudCEuYXJpYVZhbHVlVGV4dCA9IHRoaXMudmlld09wdGlvbnMudHJhbnNsYXRlISgrdGhpcy52YWx1ZSEsIExhYmVsVHlwZS5Mb3cpO1xuICAgIHRoaXMubWluSGFuZGxlRWxlbWVudCEuYXJpYVZhbHVlTWluID0gdGhpcy52aWV3T3B0aW9ucy5mbG9vciEudG9TdHJpbmcoKTtcbiAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmFyaWFWYWx1ZU1heCA9IHRoaXMudmlld09wdGlvbnMuY2VpbCEudG9TdHJpbmcoKTtcblxuICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLmFyaWFWYWx1ZU5vdyA9ICgrdGhpcy5oaWdoVmFsdWUhKS50b1N0cmluZygpO1xuICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5hcmlhVmFsdWVUZXh0ID0gdGhpcy52aWV3T3B0aW9ucy50cmFuc2xhdGUhKCt0aGlzLmhpZ2hWYWx1ZSEsIExhYmVsVHlwZS5IaWdoKTtcbiAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuYXJpYVZhbHVlTWluID0gdGhpcy52aWV3T3B0aW9ucy5mbG9vciEudG9TdHJpbmcoKTtcbiAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuYXJpYVZhbHVlTWF4ID0gdGhpcy52aWV3T3B0aW9ucy5jZWlsIS50b1N0cmluZygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSBkaW1lbnNpb25zIHRoYXQgYXJlIGRlcGVuZGVudCBvbiB2aWV3IHBvcnQgc2l6ZVxuICAvLyBSdW4gb25jZSBkdXJpbmcgaW5pdGlhbGl6YXRpb24gYW5kIGV2ZXJ5IHRpbWUgdmlldyBwb3J0IGNoYW5nZXMgc2l6ZS5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVWaWV3RGltZW5zaW9ucygpOiB2b2lkIHtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuaGFuZGxlRGltZW5zaW9uKSkge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5zZXREaW1lbnNpb24odGhpcy52aWV3T3B0aW9ucy5oYW5kbGVEaW1lbnNpb24hKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5jYWxjdWxhdGVEaW1lbnNpb24oKTtcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVXaWR0aCA9IHRoaXMubWluSGFuZGxlRWxlbWVudCEuZGltZW5zaW9uO1xuXG4gICAgdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uID0gaGFuZGxlV2lkdGggLyAyO1xuXG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmJhckRpbWVuc2lvbikpIHtcbiAgICAgIHRoaXMuZnVsbEJhckVsZW1lbnQhLnNldERpbWVuc2lvbih0aGlzLnZpZXdPcHRpb25zLmJhckRpbWVuc2lvbiEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZ1bGxCYXJFbGVtZW50IS5jYWxjdWxhdGVEaW1lbnNpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLm1heEhhbmRsZVBvc2l0aW9uID0gdGhpcy5mdWxsQmFyRWxlbWVudCEuZGltZW5zaW9uIC0gaGFuZGxlV2lkdGg7XG5cbiAgICBpZiAodGhpcy5pbml0SGFzUnVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUZsb29yTGFiZWwoKTtcbiAgICAgIHRoaXMudXBkYXRlQ2VpbExhYmVsKCk7XG4gICAgICB0aGlzLmluaXRIYW5kbGVzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVWaWV3RGltZW5zaW9uc0FuZERldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxjdWxhdGVWaWV3RGltZW5zaW9ucygpO1xuICAgIGlmICghdGhpcy5pc1JlZkRlc3Ryb3llZCgpKSB7XG4gICAgICB0aGlzLmNoYW5nZURldGVjdGlvblJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElmIHRoZSBzbGlkZXIgcmVmZXJlbmNlIGlzIGFscmVhZHkgZGVzdHJveWVkXG4gICAqIEByZXR1cm5zIGJvb2xlYW4gLSB0cnVlIGlmIHJlZiBpcyBkZXN0cm95ZWRcbiAgICovXG4gIHByaXZhdGUgaXNSZWZEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmNoYW5nZURldGVjdGlvblJlZiBhcyBhbnkpWydkZXN0cm95ZWQnXTtcbiAgfVxuXG4gIC8vIFVwZGF0ZSB0aGUgdGlja3MgcG9zaXRpb25cbiAgcHJpdmF0ZSB1cGRhdGVUaWNrc1NjYWxlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3MpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNsaWRlckVsZW1lbnRXaXRoTGVnZW5kQ2xhc3MgPSBmYWxzZTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRpY2tzQXJyYXkgPSAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy50aWNrc0FycmF5KVxuICAgICAgPyB0aGlzLnZpZXdPcHRpb25zLnRpY2tzQXJyYXlcbiAgICAgIDogdGhpcy5nZXRUaWNrc0FycmF5KCk7XG4gICAgY29uc3QgdHJhbnNsYXRlOiBzdHJpbmcgPSB0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsID8gJ3RyYW5zbGF0ZVknIDogJ3RyYW5zbGF0ZVgnO1xuXG4gICAgaWYgKHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnQpIHtcbiAgICAgIHRpY2tzQXJyYXkhLnJldmVyc2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrVmFsdWVTdGVwID0gIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMudGlja1ZhbHVlU3RlcClcbiAgICAgID8gdGhpcy52aWV3T3B0aW9ucy50aWNrVmFsdWVTdGVwXG4gICAgICA6ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnRpY2tTdGVwKVxuICAgICAgICA/IHRoaXMudmlld09wdGlvbnMudGlja1N0ZXBcbiAgICAgICAgOiB0aGlzLnZpZXdPcHRpb25zLnN0ZXA7XG5cbiAgICBsZXQgaGFzQXRMZWFzdE9uZUxlZ2VuZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgY29uc3QgbmV3VGlja3M6IFRpY2tbXSA9IHRpY2tzQXJyYXkhLm1hcCgodmFsdWU6IG51bWJlcik6IFRpY2sgPT4ge1xuICAgICAgbGV0IHBvc2l0aW9uOiBudW1iZXIgPSB0aGlzLnZhbHVlVG9Qb3NpdGlvbih2YWx1ZSk7XG5cbiAgICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsKSB7XG4gICAgICAgIHBvc2l0aW9uID0gdGhpcy5tYXhIYW5kbGVQb3NpdGlvbiAtIHBvc2l0aW9uO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0cmFuc2xhdGlvbjogc3RyaW5nID0gdHJhbnNsYXRlICsgJygnICsgTWF0aC5yb3VuZChwb3NpdGlvbikgKyAncHgpJztcbiAgICAgIGNvbnN0IHRpY2s6IFRpY2sgPSBuZXcgVGljaygpO1xuICAgICAgdGljay5zZWxlY3RlZCA9IHRoaXMuaXNUaWNrU2VsZWN0ZWQodmFsdWUpO1xuICAgICAgdGljay5zdHlsZSA9IHtcbiAgICAgICAgJy13ZWJraXQtdHJhbnNmb3JtJzogdHJhbnNsYXRpb24sXG4gICAgICAgICctbW96LXRyYW5zZm9ybSc6IHRyYW5zbGF0aW9uLFxuICAgICAgICAnLW8tdHJhbnNmb3JtJzogdHJhbnNsYXRpb24sXG4gICAgICAgICctbXMtdHJhbnNmb3JtJzogdHJhbnNsYXRpb24sXG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRpb25cbiAgICAgIH07XG4gICAgICBpZiAodGljay5zZWxlY3RlZCAmJiAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5nZXRTZWxlY3Rpb25CYXJDb2xvcikpIHtcbiAgICAgICAgdGljay5zdHlsZVsnYmFja2dyb3VuZC1jb2xvciddID0gdGhpcy5nZXRTZWxlY3Rpb25CYXJDb2xvcigpO1xuICAgICAgfVxuICAgICAgaWYgKCF0aWNrLnNlbGVjdGVkICYmICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmdldFRpY2tDb2xvcikpIHtcbiAgICAgICAgdGljay5zdHlsZVsnYmFja2dyb3VuZC1jb2xvciddID0gdGhpcy5nZXRUaWNrQ29sb3IodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnRpY2tzVG9vbHRpcCkpIHtcbiAgICAgICAgdGljay50b29sdGlwID0gdGhpcy52aWV3T3B0aW9ucy50aWNrc1Rvb2x0aXAhKHZhbHVlKTtcbiAgICAgICAgdGljay50b29sdGlwUGxhY2VtZW50ID0gdGhpcy52aWV3T3B0aW9ucy52ZXJ0aWNhbCA/ICdyaWdodCcgOiAndG9wJztcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5zaG93VGlja3NWYWx1ZXMgJiZcbiAgICAgICAgIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRpY2tWYWx1ZVN0ZXApICYmXG4gICAgICAgIE1hdGhIZWxwZXIuaXNNb2R1bG9XaXRoaW5QcmVjaXNpb25MaW1pdCh2YWx1ZSwgdGlja1ZhbHVlU3RlcCEsIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhKVxuICAgICAgKSB7XG4gICAgICAgIHRpY2sudmFsdWUgPSB0aGlzLmdldERpc3BsYXlWYWx1ZSh2YWx1ZSwgTGFiZWxUeXBlLlRpY2tWYWx1ZSk7XG4gICAgICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy50aWNrc1ZhbHVlc1Rvb2x0aXApKSB7XG4gICAgICAgICAgdGljay52YWx1ZVRvb2x0aXAgPSB0aGlzLnZpZXdPcHRpb25zLnRpY2tzVmFsdWVzVG9vbHRpcCEodmFsdWUpO1xuICAgICAgICAgIHRpY2sudmFsdWVUb29sdGlwUGxhY2VtZW50ID0gdGhpcy52aWV3T3B0aW9ucy52ZXJ0aWNhbCA/ICdyaWdodCcgOiAndG9wJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsZXQgbGVnZW5kOiBzdHJpbmc7XG4gICAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc3RlcHNBcnJheSkpIHtcbiAgICAgICAgY29uc3Qgc3RlcDogQ3VzdG9tU3RlcERlZmluaXRpb24gPSB0aGlzLnZpZXdPcHRpb25zLnN0ZXBzQXJyYXkhW3ZhbHVlXTtcbiAgICAgICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmdldFN0ZXBMZWdlbmQpKSB7XG4gICAgICAgICAgbGVnZW5kID0gdGhpcy52aWV3T3B0aW9ucy5nZXRTdGVwTGVnZW5kIShzdGVwKTtcbiAgICAgICAgfSBlbHNlIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoc3RlcCkpIHtcbiAgICAgICAgICBsZWdlbmQgPSBzdGVwLmxlZ2VuZCE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuZ2V0TGVnZW5kKSkge1xuICAgICAgICBsZWdlbmQgPSB0aGlzLnZpZXdPcHRpb25zLmdldExlZ2VuZCEodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZChsZWdlbmQhKSkge1xuICAgICAgICB0aWNrLmxlZ2VuZCA9IGxlZ2VuZCE7XG4gICAgICAgIGhhc0F0TGVhc3RPbmVMZWdlbmQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGljaztcbiAgICB9KTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zbGlkZXJFbGVtZW50V2l0aExlZ2VuZENsYXNzID0gaGFzQXRMZWFzdE9uZUxlZ2VuZDtcbiAgICB9KTtcblxuICAgIC8vIFdlIHNob3VsZCBhdm9pZCByZS1jcmVhdGluZyB0aGUgdGlja3MgYXJyYXkgaWYgcG9zc2libGVcbiAgICAvLyBUaGlzIGJvdGggaW1wcm92ZXMgcGVyZm9ybWFuY2UgYW5kIG1ha2VzIENTUyBhbmltYXRpb25zIHdvcmsgY29ycmVjdGx5XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnRpY2tzKSAmJiB0aGlzLnRpY2tzLmxlbmd0aCA9PT0gbmV3VGlja3MubGVuZ3RoKSB7XG4gICAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgbmV3VGlja3MubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLnRpY2tzW2ldLCBuZXdUaWNrc1tpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGlja3MgPSBuZXdUaWNrcztcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaXNSZWZEZXN0cm95ZWQoKSkge1xuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rpb25SZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGlja3NBcnJheSgpOiBudW1iZXJbXSB7XG4gICAgY29uc3Qgc3RlcCA9ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnRpY2tTdGVwKVxuICAgICAgPyB0aGlzLnZpZXdPcHRpb25zLnRpY2tTdGVwXG4gICAgICA6IHRoaXMudmlld09wdGlvbnMuc3RlcDtcbiAgICBjb25zdCB0aWNrc0FycmF5OiBudW1iZXJbXSA9IFtdO1xuXG4gICAgY29uc3QgbnVtYmVyT2ZWYWx1ZXM6IG51bWJlciA9XG4gICAgICAxICtcbiAgICAgIE1hdGguZmxvb3IoXG4gICAgICAgIE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KFxuICAgICAgICAgIE1hdGguYWJzKHRoaXMudmlld09wdGlvbnMuY2VpbCEgLSB0aGlzLnZpZXdPcHRpb25zLmZsb29yISkgLyBzdGVwISxcbiAgICAgICAgICB0aGlzLnZpZXdPcHRpb25zLnByZWNpc2lvbkxpbWl0IVxuICAgICAgICApXG4gICAgICApO1xuICAgIGZvciAobGV0IGluZGV4OiBudW1iZXIgPSAwOyBpbmRleCA8IG51bWJlck9mVmFsdWVzOyArK2luZGV4KSB7XG4gICAgICB0aWNrc0FycmF5LnB1c2goXG4gICAgICAgIE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KHRoaXMudmlld09wdGlvbnMuZmxvb3IhICsgc3RlcCEgKiBpbmRleCwgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCEpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aWNrc0FycmF5O1xuICB9XG5cbiAgcHJpdmF0ZSBpc1RpY2tTZWxlY3RlZCh2YWx1ZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLnJhbmdlKSB7XG4gICAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhckZyb21WYWx1ZSkpIHtcbiAgICAgICAgY29uc3QgY2VudGVyID0gdGhpcy52aWV3T3B0aW9ucy5zaG93U2VsZWN0aW9uQmFyRnJvbVZhbHVlO1xuICAgICAgICBpZiAodGhpcy52aWV3TG93VmFsdWUhID4gY2VudGVyISAmJiB2YWx1ZSA+PSBjZW50ZXIhICYmIHZhbHVlIDw9IHRoaXMudmlld0xvd1ZhbHVlISkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudmlld0xvd1ZhbHVlISA8IGNlbnRlciEgJiYgdmFsdWUgPD0gY2VudGVyISAmJiB2YWx1ZSA+PSB0aGlzLnZpZXdMb3dWYWx1ZSEpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLnZpZXdPcHRpb25zLnNob3dTZWxlY3Rpb25CYXJFbmQpIHtcbiAgICAgICAgaWYgKHZhbHVlID49IHRoaXMudmlld0xvd1ZhbHVlISkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhciAmJiB2YWx1ZSA8PSB0aGlzLnZpZXdMb3dWYWx1ZSEpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmFuZ2UgJiYgdmFsdWUgPj0gdGhpcy52aWV3TG93VmFsdWUhICYmIHZhbHVlIDw9IHRoaXMudmlld0hpZ2hWYWx1ZSEpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFVwZGF0ZSBwb3NpdGlvbiBvZiB0aGUgZmxvb3IgbGFiZWxcbiAgcHJpdmF0ZSB1cGRhdGVGbG9vckxhYmVsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5mbG9vckxhYmVsRWxlbWVudCEuYWx3YXlzSGlkZSkge1xuICAgICAgdGhpcy5mbG9vckxhYmVsRWxlbWVudCEuc2V0VmFsdWUodGhpcy5nZXREaXNwbGF5VmFsdWUodGhpcy52aWV3T3B0aW9ucy5mbG9vciEsIExhYmVsVHlwZS5GbG9vcikpO1xuICAgICAgdGhpcy5mbG9vckxhYmVsRWxlbWVudCEuY2FsY3VsYXRlRGltZW5zaW9uKCk7XG4gICAgICBjb25zdCBwb3NpdGlvbjogbnVtYmVyID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdFxuICAgICAgICA/IHRoaXMuZnVsbEJhckVsZW1lbnQhLmRpbWVuc2lvbiAtIHRoaXMuZmxvb3JMYWJlbEVsZW1lbnQhLmRpbWVuc2lvblxuICAgICAgICA6IDA7XG4gICAgICB0aGlzLmZsb29yTGFiZWxFbGVtZW50IS5zZXRQb3NpdGlvbihwb3NpdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLy8gVXBkYXRlIHBvc2l0aW9uIG9mIHRoZSBjZWlsaW5nIGxhYmVsXG4gIHByaXZhdGUgdXBkYXRlQ2VpbExhYmVsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jZWlsTGFiZWxFbGVtZW50IS5hbHdheXNIaWRlKSB7XG4gICAgICB0aGlzLmNlaWxMYWJlbEVsZW1lbnQhLnNldFZhbHVlKHRoaXMuZ2V0RGlzcGxheVZhbHVlKHRoaXMudmlld09wdGlvbnMuY2VpbCEsIExhYmVsVHlwZS5DZWlsKSk7XG4gICAgICB0aGlzLmNlaWxMYWJlbEVsZW1lbnQhLmNhbGN1bGF0ZURpbWVuc2lvbigpO1xuICAgICAgY29uc3QgcG9zaXRpb246IG51bWJlciA9IHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnRcbiAgICAgICAgPyAwXG4gICAgICAgIDogdGhpcy5mdWxsQmFyRWxlbWVudCEuZGltZW5zaW9uIC0gdGhpcy5jZWlsTGFiZWxFbGVtZW50IS5kaW1lbnNpb247XG4gICAgICB0aGlzLmNlaWxMYWJlbEVsZW1lbnQhLnNldFBvc2l0aW9uKHBvc2l0aW9uKTtcbiAgICB9XG4gIH1cblxuICAvLyBVcGRhdGUgc2xpZGVyIGhhbmRsZXMgYW5kIGxhYmVsIHBvc2l0aW9uc1xuICBwcml2YXRlIHVwZGF0ZUhhbmRsZXMod2hpY2g6IFBvaW50ZXJUeXBlLCBuZXdQb3M6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh3aGljaCA9PT0gUG9pbnRlclR5cGUuTWluKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxvd0hhbmRsZShuZXdQb3MpO1xuICAgIH0gZWxzZSBpZiAod2hpY2ggPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgdGhpcy51cGRhdGVIaWdoSGFuZGxlKG5ld1Bvcyk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVTZWxlY3Rpb25CYXIoKTtcbiAgICB0aGlzLnVwZGF0ZVRpY2tzU2NhbGUoKTtcbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgdGhpcy51cGRhdGVDb21iaW5lZExhYmVsKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIHdvcmsgb3V0IHRoZSBwb3NpdGlvbiBmb3IgaGFuZGxlIGxhYmVscyBkZXBlbmRpbmcgb24gUlRMIG9yIG5vdFxuICBwcml2YXRlIGdldEhhbmRsZUxhYmVsUG9zKGxhYmVsVHlwZTogUG9pbnRlclR5cGUsIG5ld1BvczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBsYWJlbERpbWVuc2lvbjogbnVtYmVyID1cbiAgICAgIGxhYmVsVHlwZSA9PT0gUG9pbnRlclR5cGUuTWluID8gdGhpcy5taW5IYW5kbGVMYWJlbEVsZW1lbnQhLmRpbWVuc2lvbiA6IHRoaXMubWF4SGFuZGxlTGFiZWxFbGVtZW50IS5kaW1lbnNpb247XG4gICAgY29uc3QgbmVhckhhbmRsZVBvczogbnVtYmVyID0gbmV3UG9zIC0gbGFiZWxEaW1lbnNpb24gLyAyICsgdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uO1xuICAgIGNvbnN0IGVuZE9mQmFyUG9zOiBudW1iZXIgPSB0aGlzLmZ1bGxCYXJFbGVtZW50IS5kaW1lbnNpb24gLSBsYWJlbERpbWVuc2lvbjtcblxuICAgIGlmICghdGhpcy52aWV3T3B0aW9ucy5ib3VuZFBvaW50ZXJMYWJlbHMpIHtcbiAgICAgIHJldHVybiBuZWFySGFuZGxlUG9zO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICh0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0ICYmIGxhYmVsVHlwZSA9PT0gUG9pbnRlclR5cGUuTWluKSB8fFxuICAgICAgKCF0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0ICYmIGxhYmVsVHlwZSA9PT0gUG9pbnRlclR5cGUuTWF4KVxuICAgICkge1xuICAgICAgcmV0dXJuIE1hdGgubWluKG5lYXJIYW5kbGVQb3MsIGVuZE9mQmFyUG9zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG5lYXJIYW5kbGVQb3MsIDApLCBlbmRPZkJhclBvcyk7XG4gICAgfVxuICB9XG5cbiAgLy8gVXBkYXRlIGxvdyBzbGlkZXIgaGFuZGxlIHBvc2l0aW9uIGFuZCBsYWJlbFxuICBwcml2YXRlIHVwZGF0ZUxvd0hhbmRsZShuZXdQb3M6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubWluSGFuZGxlRWxlbWVudCEuc2V0UG9zaXRpb24obmV3UG9zKTtcbiAgICB0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudCEuc2V0VmFsdWUodGhpcy5nZXREaXNwbGF5VmFsdWUodGhpcy52aWV3TG93VmFsdWUhLCBMYWJlbFR5cGUuTG93KSk7XG4gICAgdGhpcy5taW5IYW5kbGVMYWJlbEVsZW1lbnQhLnNldFBvc2l0aW9uKHRoaXMuZ2V0SGFuZGxlTGFiZWxQb3MoUG9pbnRlclR5cGUuTWluLCBuZXdQb3MpKTtcblxuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5nZXRQb2ludGVyQ29sb3IpKSB7XG4gICAgICB0aGlzLm1pblBvaW50ZXJTdHlsZSA9IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLmdldFBvaW50ZXJDb2xvcihQb2ludGVyVHlwZS5NaW4pXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmF1dG9IaWRlTGltaXRMYWJlbHMpIHtcbiAgICAgIHRoaXMudXBkYXRlRmxvb3JBbmRDZWlsTGFiZWxzVmlzaWJpbGl0eSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFVwZGF0ZSBoaWdoIHNsaWRlciBoYW5kbGUgcG9zaXRpb24gYW5kIGxhYmVsXG4gIHByaXZhdGUgdXBkYXRlSGlnaEhhbmRsZShuZXdQb3M6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuc2V0UG9zaXRpb24obmV3UG9zKTtcbiAgICB0aGlzLm1heEhhbmRsZUxhYmVsRWxlbWVudCEuc2V0VmFsdWUodGhpcy5nZXREaXNwbGF5VmFsdWUodGhpcy52aWV3SGlnaFZhbHVlISwgTGFiZWxUeXBlLkhpZ2gpKTtcbiAgICB0aGlzLm1heEhhbmRsZUxhYmVsRWxlbWVudCEuc2V0UG9zaXRpb24odGhpcy5nZXRIYW5kbGVMYWJlbFBvcyhQb2ludGVyVHlwZS5NYXgsIG5ld1BvcykpO1xuXG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLmdldFBvaW50ZXJDb2xvcikpIHtcbiAgICAgIHRoaXMubWF4UG9pbnRlclN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuZ2V0UG9pbnRlckNvbG9yKFBvaW50ZXJUeXBlLk1heClcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmF1dG9IaWRlTGltaXRMYWJlbHMpIHtcbiAgICAgIHRoaXMudXBkYXRlRmxvb3JBbmRDZWlsTGFiZWxzVmlzaWJpbGl0eSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNob3cvaGlkZSBmbG9vci9jZWlsaW5nIGxhYmVsXG4gIHByaXZhdGUgdXBkYXRlRmxvb3JBbmRDZWlsTGFiZWxzVmlzaWJpbGl0eSgpOiB2b2lkIHtcbiAgICAvLyBTaG93IGJhc2VkIG9ubHkgb24gaGlkZUxpbWl0TGFiZWxzIGlmIHBvaW50ZXIgbGFiZWxzIGFyZSBoaWRkZW5cbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5oaWRlUG9pbnRlckxhYmVscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgZmxvb3JMYWJlbEhpZGRlbjogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGxldCBjZWlsTGFiZWxIaWRkZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBjb25zdCBpc01pbkxhYmVsQXRGbG9vcjogYm9vbGVhbiA9IHRoaXMuaXNMYWJlbEJlbG93Rmxvb3JMYWJlbCh0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudCEpO1xuICAgIGNvbnN0IGlzTWluTGFiZWxBdENlaWw6IGJvb2xlYW4gPSB0aGlzLmlzTGFiZWxBYm92ZUNlaWxMYWJlbCh0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudCEpO1xuICAgIGNvbnN0IGlzTWF4TGFiZWxBdENlaWw6IGJvb2xlYW4gPSB0aGlzLmlzTGFiZWxBYm92ZUNlaWxMYWJlbCh0aGlzLm1heEhhbmRsZUxhYmVsRWxlbWVudCEpO1xuICAgIGNvbnN0IGlzQ29tYmluZWRMYWJlbEF0Rmxvb3I6IGJvb2xlYW4gPSB0aGlzLmlzTGFiZWxCZWxvd0Zsb29yTGFiZWwodGhpcy5jb21iaW5lZExhYmVsRWxlbWVudCEpO1xuICAgIGNvbnN0IGlzQ29tYmluZWRMYWJlbEF0Q2VpbDogYm9vbGVhbiA9IHRoaXMuaXNMYWJlbEFib3ZlQ2VpbExhYmVsKHRoaXMuY29tYmluZWRMYWJlbEVsZW1lbnQhKTtcblxuICAgIGlmIChpc01pbkxhYmVsQXRGbG9vcikge1xuICAgICAgZmxvb3JMYWJlbEhpZGRlbiA9IHRydWU7XG4gICAgICB0aGlzLmZsb29yTGFiZWxFbGVtZW50IS5oaWRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZsb29yTGFiZWxIaWRkZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMuZmxvb3JMYWJlbEVsZW1lbnQhLnNob3coKTtcbiAgICB9XG5cbiAgICBpZiAoaXNNaW5MYWJlbEF0Q2VpbCkge1xuICAgICAgY2VpbExhYmVsSGlkZGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2VpbExhYmVsRWxlbWVudCEuaGlkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjZWlsTGFiZWxIaWRkZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMuY2VpbExhYmVsRWxlbWVudCEuc2hvdygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICBjb25zdCBoaWRlQ2VpbDogYm9vbGVhbiA9IHRoaXMuY29tYmluZWRMYWJlbEVsZW1lbnQhLmlzVmlzaWJsZSgpID8gaXNDb21iaW5lZExhYmVsQXRDZWlsIDogaXNNYXhMYWJlbEF0Q2VpbDtcbiAgICAgIGNvbnN0IGhpZGVGbG9vcjogYm9vbGVhbiA9IHRoaXMuY29tYmluZWRMYWJlbEVsZW1lbnQhLmlzVmlzaWJsZSgpID8gaXNDb21iaW5lZExhYmVsQXRGbG9vciA6IGlzTWluTGFiZWxBdEZsb29yO1xuXG4gICAgICBpZiAoaGlkZUNlaWwpIHtcbiAgICAgICAgdGhpcy5jZWlsTGFiZWxFbGVtZW50IS5oaWRlKCk7XG4gICAgICB9IGVsc2UgaWYgKCFjZWlsTGFiZWxIaWRkZW4pIHtcbiAgICAgICAgdGhpcy5jZWlsTGFiZWxFbGVtZW50IS5zaG93KCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEhpZGUgb3Igc2hvdyBmbG9vciBsYWJlbFxuICAgICAgaWYgKGhpZGVGbG9vcikge1xuICAgICAgICB0aGlzLmZsb29yTGFiZWxFbGVtZW50IS5oaWRlKCk7XG4gICAgICB9IGVsc2UgaWYgKCFmbG9vckxhYmVsSGlkZGVuKSB7XG4gICAgICAgIHRoaXMuZmxvb3JMYWJlbEVsZW1lbnQhLnNob3coKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzTGFiZWxCZWxvd0Zsb29yTGFiZWwobGFiZWw6IFNsaWRlckxhYmVsRGlyZWN0aXZlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcG9zOiBudW1iZXIgPSBsYWJlbC5wb3NpdGlvbjtcbiAgICBjb25zdCBkaW06IG51bWJlciA9IGxhYmVsLmRpbWVuc2lvbjtcbiAgICBjb25zdCBmbG9vclBvczogbnVtYmVyID0gdGhpcy5mbG9vckxhYmVsRWxlbWVudCEucG9zaXRpb247XG4gICAgY29uc3QgZmxvb3JEaW06IG51bWJlciA9IHRoaXMuZmxvb3JMYWJlbEVsZW1lbnQhLmRpbWVuc2lvbjtcbiAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCA/IHBvcyArIGRpbSA+PSBmbG9vclBvcyAtIDIgOiBwb3MgPD0gZmxvb3JQb3MgKyBmbG9vckRpbSArIDI7XG4gIH1cblxuICBwcml2YXRlIGlzTGFiZWxBYm92ZUNlaWxMYWJlbChsYWJlbDogU2xpZGVyTGFiZWxEaXJlY3RpdmUpOiBib29sZWFuIHtcbiAgICBjb25zdCBwb3M6IG51bWJlciA9IGxhYmVsLnBvc2l0aW9uO1xuICAgIGNvbnN0IGRpbTogbnVtYmVyID0gbGFiZWwuZGltZW5zaW9uO1xuICAgIGNvbnN0IGNlaWxQb3M6IG51bWJlciA9IHRoaXMuY2VpbExhYmVsRWxlbWVudCEucG9zaXRpb247XG4gICAgY29uc3QgY2VpbERpbTogbnVtYmVyID0gdGhpcy5jZWlsTGFiZWxFbGVtZW50IS5kaW1lbnNpb247XG4gICAgcmV0dXJuIHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnQgPyBwb3MgPD0gY2VpbFBvcyArIGNlaWxEaW0gKyAyIDogcG9zICsgZGltID49IGNlaWxQb3MgLSAyO1xuICB9XG5cbiAgLy8gVXBkYXRlIHNsaWRlciBzZWxlY3Rpb24gYmFyLCBjb21iaW5lZCBsYWJlbCBhbmQgcmFuZ2UgbGFiZWxcbiAgcHJpdmF0ZSB1cGRhdGVTZWxlY3Rpb25CYXIoKTogdm9pZCB7XG4gICAgbGV0IHBvc2l0aW9uOiBudW1iZXIgPSAwO1xuICAgIGxldCBkaW1lbnNpb246IG51bWJlciA9IDA7XG4gICAgY29uc3QgaXNTZWxlY3Rpb25CYXJGcm9tUmlnaHQ6IGJvb2xlYW4gPSB0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0XG4gICAgICA/ICF0aGlzLnZpZXdPcHRpb25zLnNob3dTZWxlY3Rpb25CYXJFbmQhXG4gICAgICA6IHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhckVuZCE7XG4gICAgY29uc3QgcG9zaXRpb25Gb3JSYW5nZTogbnVtYmVyID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdFxuICAgICAgPyB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLnBvc2l0aW9uICsgdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uXG4gICAgICA6IHRoaXMubWluSGFuZGxlRWxlbWVudCEucG9zaXRpb24gKyB0aGlzLmhhbmRsZUhhbGZEaW1lbnNpb247XG5cbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgZGltZW5zaW9uID0gTWF0aC5hYnModGhpcy5tYXhIYW5kbGVFbGVtZW50IS5wb3NpdGlvbiAtIHRoaXMubWluSGFuZGxlRWxlbWVudCEucG9zaXRpb24pO1xuICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbkZvclJhbmdlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc2hvd1NlbGVjdGlvbkJhckZyb21WYWx1ZSkpIHtcbiAgICAgICAgY29uc3QgY2VudGVyID0gdGhpcy52aWV3T3B0aW9ucy5zaG93U2VsZWN0aW9uQmFyRnJvbVZhbHVlO1xuICAgICAgICBjb25zdCBjZW50ZXJQb3NpdGlvbjogbnVtYmVyID0gdGhpcy52YWx1ZVRvUG9zaXRpb24oY2VudGVyISk7XG4gICAgICAgIGNvbnN0IGlzTW9kZWxHcmVhdGVyVGhhbkNlbnRlcjogYm9vbGVhbiA9IHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnRcbiAgICAgICAgICA/IHRoaXMudmlld0xvd1ZhbHVlISA8PSBjZW50ZXIhXG4gICAgICAgICAgOiB0aGlzLnZpZXdMb3dWYWx1ZSEgPiBjZW50ZXIhO1xuICAgICAgICBpZiAoaXNNb2RlbEdyZWF0ZXJUaGFuQ2VudGVyKSB7XG4gICAgICAgICAgZGltZW5zaW9uID0gdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbiAtIGNlbnRlclBvc2l0aW9uO1xuICAgICAgICAgIHBvc2l0aW9uID0gY2VudGVyUG9zaXRpb24gKyB0aGlzLmhhbmRsZUhhbGZEaW1lbnNpb247XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGltZW5zaW9uID0gY2VudGVyUG9zaXRpb24gLSB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLnBvc2l0aW9uO1xuICAgICAgICAgIHBvc2l0aW9uID0gdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbiArIHRoaXMuaGFuZGxlSGFsZkRpbWVuc2lvbjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpc1NlbGVjdGlvbkJhckZyb21SaWdodCkge1xuICAgICAgICBkaW1lbnNpb24gPSBNYXRoLmNlaWwoXG4gICAgICAgICAgTWF0aC5hYnModGhpcy5tYXhIYW5kbGVQb3NpdGlvbiAtIHRoaXMubWluSGFuZGxlRWxlbWVudCEucG9zaXRpb24pICsgdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uXG4gICAgICAgICk7XG4gICAgICAgIHBvc2l0aW9uID0gTWF0aC5mbG9vcih0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLnBvc2l0aW9uICsgdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpbWVuc2lvbiA9IHRoaXMubWluSGFuZGxlRWxlbWVudCEucG9zaXRpb24gKyB0aGlzLmhhbmRsZUhhbGZEaW1lbnNpb247XG4gICAgICAgIHBvc2l0aW9uID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rpb25CYXJFbGVtZW50IS5zZXREaW1lbnNpb24oZGltZW5zaW9uKTtcbiAgICB0aGlzLnNlbGVjdGlvbkJhckVsZW1lbnQhLnNldFBvc2l0aW9uKHBvc2l0aW9uKTtcbiAgICBpZiAodGhpcy5yYW5nZSAmJiB0aGlzLnZpZXdPcHRpb25zLnNob3dPdXRlclNlbGVjdGlvbkJhcnMpIHtcbiAgICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0KSB7XG4gICAgICAgIHRoaXMucmlnaHRPdXRlclNlbGVjdGlvbkJhckVsZW1lbnQhLnNldERpbWVuc2lvbihwb3NpdGlvbik7XG4gICAgICAgIHRoaXMucmlnaHRPdXRlclNlbGVjdGlvbkJhckVsZW1lbnQhLnNldFBvc2l0aW9uKDApO1xuICAgICAgICB0aGlzLmZ1bGxCYXJFbGVtZW50IS5jYWxjdWxhdGVEaW1lbnNpb24oKTtcbiAgICAgICAgdGhpcy5sZWZ0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50IS5zZXREaW1lbnNpb24odGhpcy5mdWxsQmFyRWxlbWVudCEuZGltZW5zaW9uIC0gKHBvc2l0aW9uICsgZGltZW5zaW9uKSk7XG4gICAgICAgIHRoaXMubGVmdE91dGVyU2VsZWN0aW9uQmFyRWxlbWVudCEuc2V0UG9zaXRpb24ocG9zaXRpb24gKyBkaW1lbnNpb24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sZWZ0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50IS5zZXREaW1lbnNpb24ocG9zaXRpb24pO1xuICAgICAgICB0aGlzLmxlZnRPdXRlclNlbGVjdGlvbkJhckVsZW1lbnQhLnNldFBvc2l0aW9uKDApO1xuICAgICAgICB0aGlzLmZ1bGxCYXJFbGVtZW50IS5jYWxjdWxhdGVEaW1lbnNpb24oKTtcbiAgICAgICAgdGhpcy5yaWdodE91dGVyU2VsZWN0aW9uQmFyRWxlbWVudCEuc2V0RGltZW5zaW9uKHRoaXMuZnVsbEJhckVsZW1lbnQhLmRpbWVuc2lvbiAtIChwb3NpdGlvbiArIGRpbWVuc2lvbikpO1xuICAgICAgICB0aGlzLnJpZ2h0T3V0ZXJTZWxlY3Rpb25CYXJFbGVtZW50IS5zZXRQb3NpdGlvbihwb3NpdGlvbiArIGRpbWVuc2lvbik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5nZXRTZWxlY3Rpb25CYXJDb2xvcikpIHtcbiAgICAgIGNvbnN0IGNvbG9yOiBzdHJpbmcgPSB0aGlzLmdldFNlbGVjdGlvbkJhckNvbG9yKCk7XG4gICAgICB0aGlzLmJhclN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9yXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMuc2VsZWN0aW9uQmFyR3JhZGllbnQpKSB7XG4gICAgICBjb25zdCBvZmZzZXQ6IG51bWJlciA9ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnNob3dTZWxlY3Rpb25CYXJGcm9tVmFsdWUpXG4gICAgICAgID8gdGhpcy52YWx1ZVRvUG9zaXRpb24odGhpcy52aWV3T3B0aW9ucy5zaG93U2VsZWN0aW9uQmFyRnJvbVZhbHVlISlcbiAgICAgICAgOiAwO1xuICAgICAgY29uc3QgcmV2ZXJzZWQ6IGJvb2xlYW4gPVxuICAgICAgICAob2Zmc2V0IC0gcG9zaXRpb24gPiAwICYmICFpc1NlbGVjdGlvbkJhckZyb21SaWdodCkgfHwgKG9mZnNldCAtIHBvc2l0aW9uIDw9IDAgJiYgaXNTZWxlY3Rpb25CYXJGcm9tUmlnaHQpO1xuICAgICAgY29uc3QgZGlyZWN0aW9uOiBzdHJpbmcgPSB0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsID8gKHJldmVyc2VkID8gJ2JvdHRvbScgOiAndG9wJykgOiByZXZlcnNlZCA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgICB0aGlzLmJhclN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kSW1hZ2U6XG4gICAgICAgICAgJ2xpbmVhci1ncmFkaWVudCh0byAnICtcbiAgICAgICAgICBkaXJlY3Rpb24gK1xuICAgICAgICAgICcsICcgK1xuICAgICAgICAgIHRoaXMudmlld09wdGlvbnMuc2VsZWN0aW9uQmFyR3JhZGllbnQhLmZyb20gK1xuICAgICAgICAgICcgMCUsJyArXG4gICAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5zZWxlY3Rpb25CYXJHcmFkaWVudCEudG8gK1xuICAgICAgICAgICcgMTAwJSknXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMudmlld09wdGlvbnMudmVydGljYWwpIHtcbiAgICAgICAgdGhpcy5iYXJTdHlsZS5iYWNrZ3JvdW5kUG9zaXRpb24gPVxuICAgICAgICAgICdjZW50ZXIgJyArIChvZmZzZXQgKyBkaW1lbnNpb24gKyBwb3NpdGlvbiArIChyZXZlcnNlZCA/IC10aGlzLmhhbmRsZUhhbGZEaW1lbnNpb24gOiAwKSkgKyAncHgnO1xuICAgICAgICB0aGlzLmJhclN0eWxlLmJhY2tncm91bmRTaXplID0gJzEwMCUgJyArICh0aGlzLmZ1bGxCYXJFbGVtZW50IS5kaW1lbnNpb24gLSB0aGlzLmhhbmRsZUhhbGZEaW1lbnNpb24pICsgJ3B4JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYmFyU3R5bGUuYmFja2dyb3VuZFBvc2l0aW9uID0gb2Zmc2V0IC0gcG9zaXRpb24gKyAocmV2ZXJzZWQgPyB0aGlzLmhhbmRsZUhhbGZEaW1lbnNpb24gOiAwKSArICdweCBjZW50ZXInO1xuICAgICAgICB0aGlzLmJhclN0eWxlLmJhY2tncm91bmRTaXplID0gdGhpcy5mdWxsQmFyRWxlbWVudCEuZGltZW5zaW9uIC0gdGhpcy5oYW5kbGVIYWxmRGltZW5zaW9uICsgJ3B4IDEwMCUnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFdyYXBwZXIgYXJvdW5kIHRoZSBnZXRTZWxlY3Rpb25CYXJDb2xvciBvZiB0aGUgdXNlciB0byBwYXNzIHRvIGNvcnJlY3QgcGFyYW1ldGVyc1xuICBwcml2YXRlIGdldFNlbGVjdGlvbkJhckNvbG9yKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdPcHRpb25zLmdldFNlbGVjdGlvbkJhckNvbG9yISh0aGlzLnZhbHVlISwgdGhpcy5oaWdoVmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy5nZXRTZWxlY3Rpb25CYXJDb2xvciEodGhpcy52YWx1ZSEpO1xuICB9XG5cbiAgLy8gV3JhcHBlciBhcm91bmQgdGhlIGdldFBvaW50ZXJDb2xvciBvZiB0aGUgdXNlciB0byBwYXNzIHRvICBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgcHJpdmF0ZSBnZXRQb2ludGVyQ29sb3IocG9pbnRlclR5cGU6IFBvaW50ZXJUeXBlKTogc3RyaW5nIHtcbiAgICBpZiAocG9pbnRlclR5cGUgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgcmV0dXJuIHRoaXMudmlld09wdGlvbnMuZ2V0UG9pbnRlckNvbG9yISh0aGlzLmhpZ2hWYWx1ZSEsIHBvaW50ZXJUeXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmlld09wdGlvbnMuZ2V0UG9pbnRlckNvbG9yISh0aGlzLnZhbHVlISwgcG9pbnRlclR5cGUpO1xuICB9XG5cbiAgLy8gV3JhcHBlciBhcm91bmQgdGhlIGdldFRpY2tDb2xvciBvZiB0aGUgdXNlciB0byBwYXNzIHRvIGNvcnJlY3QgcGFyYW1ldGVyc1xuICBwcml2YXRlIGdldFRpY2tDb2xvcih2YWx1ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy5nZXRUaWNrQ29sb3IhKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFVwZGF0ZSBjb21iaW5lZCBsYWJlbCBwb3NpdGlvbiBhbmQgdmFsdWVcbiAgcHJpdmF0ZSB1cGRhdGVDb21iaW5lZExhYmVsKCk6IHZvaWQge1xuICAgIGxldCBpc0xhYmVsT3ZlcmxhcCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0KSB7XG4gICAgICBpc0xhYmVsT3ZlcmxhcCA9XG4gICAgICAgIHRoaXMubWluSGFuZGxlTGFiZWxFbGVtZW50IS5wb3NpdGlvbiAtIHRoaXMubWluSGFuZGxlTGFiZWxFbGVtZW50IS5kaW1lbnNpb24gLSAxMCA8PVxuICAgICAgICB0aGlzLm1heEhhbmRsZUxhYmVsRWxlbWVudCEucG9zaXRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGlzTGFiZWxPdmVybGFwID1cbiAgICAgICAgdGhpcy5taW5IYW5kbGVMYWJlbEVsZW1lbnQhLnBvc2l0aW9uICsgdGhpcy5taW5IYW5kbGVMYWJlbEVsZW1lbnQhLmRpbWVuc2lvbiArIDEwID49XG4gICAgICAgIHRoaXMubWF4SGFuZGxlTGFiZWxFbGVtZW50IS5wb3NpdGlvbjtcbiAgICB9XG5cbiAgICBpZiAoaXNMYWJlbE92ZXJsYXApIHtcbiAgICAgIGNvbnN0IGxvd0Rpc3BsYXlWYWx1ZTogc3RyaW5nID0gdGhpcy5nZXREaXNwbGF5VmFsdWUodGhpcy52aWV3TG93VmFsdWUhLCBMYWJlbFR5cGUuTG93KTtcbiAgICAgIGNvbnN0IGhpZ2hEaXNwbGF5VmFsdWU6IHN0cmluZyA9IHRoaXMuZ2V0RGlzcGxheVZhbHVlKHRoaXMudmlld0hpZ2hWYWx1ZSEsIExhYmVsVHlwZS5IaWdoKTtcbiAgICAgIGNvbnN0IGNvbWJpbmVkTGFiZWxWYWx1ZTogc3RyaW5nID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdFxuICAgICAgICA/IHRoaXMudmlld09wdGlvbnMuY29tYmluZUxhYmVscyEoaGlnaERpc3BsYXlWYWx1ZSwgbG93RGlzcGxheVZhbHVlKVxuICAgICAgICA6IHRoaXMudmlld09wdGlvbnMuY29tYmluZUxhYmVscyEobG93RGlzcGxheVZhbHVlLCBoaWdoRGlzcGxheVZhbHVlKTtcblxuICAgICAgdGhpcy5jb21iaW5lZExhYmVsRWxlbWVudCEuc2V0VmFsdWUoY29tYmluZWRMYWJlbFZhbHVlKTtcbiAgICAgIGNvbnN0IHBvczogbnVtYmVyID0gdGhpcy52aWV3T3B0aW9ucy5ib3VuZFBvaW50ZXJMYWJlbHNcbiAgICAgICAgPyBNYXRoLm1pbihcbiAgICAgICAgICAgIE1hdGgubWF4KFxuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbkJhckVsZW1lbnQhLnBvc2l0aW9uICtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbkJhckVsZW1lbnQhLmRpbWVuc2lvbiAvIDIgLVxuICAgICAgICAgICAgICAgIHRoaXMuY29tYmluZWRMYWJlbEVsZW1lbnQhLmRpbWVuc2lvbiAvIDIsXG4gICAgICAgICAgICAgIDBcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0aGlzLmZ1bGxCYXJFbGVtZW50IS5kaW1lbnNpb24gLSB0aGlzLmNvbWJpbmVkTGFiZWxFbGVtZW50IS5kaW1lbnNpb25cbiAgICAgICAgICApXG4gICAgICAgIDogdGhpcy5zZWxlY3Rpb25CYXJFbGVtZW50IS5wb3NpdGlvbiArXG4gICAgICAgICAgdGhpcy5zZWxlY3Rpb25CYXJFbGVtZW50IS5kaW1lbnNpb24gLyAyIC1cbiAgICAgICAgICB0aGlzLmNvbWJpbmVkTGFiZWxFbGVtZW50IS5kaW1lbnNpb24gLyAyO1xuXG4gICAgICB0aGlzLmNvbWJpbmVkTGFiZWxFbGVtZW50IS5zZXRQb3NpdGlvbihwb3MpO1xuICAgICAgdGhpcy5taW5IYW5kbGVMYWJlbEVsZW1lbnQhLmhpZGUoKTtcbiAgICAgIHRoaXMubWF4SGFuZGxlTGFiZWxFbGVtZW50IS5oaWRlKCk7XG4gICAgICB0aGlzLmNvbWJpbmVkTGFiZWxFbGVtZW50IS5zaG93KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlSGlnaEhhbmRsZSh0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdIaWdoVmFsdWUhKSk7XG4gICAgICB0aGlzLnVwZGF0ZUxvd0hhbmRsZSh0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdMb3dWYWx1ZSEpKTtcbiAgICAgIHRoaXMubWF4SGFuZGxlTGFiZWxFbGVtZW50IS5zaG93KCk7XG4gICAgICB0aGlzLm1pbkhhbmRsZUxhYmVsRWxlbWVudCEuc2hvdygpO1xuICAgICAgdGhpcy5jb21iaW5lZExhYmVsRWxlbWVudCEuaGlkZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5hdXRvSGlkZUxpbWl0TGFiZWxzKSB7XG4gICAgICB0aGlzLnVwZGF0ZUZsb29yQW5kQ2VpbExhYmVsc1Zpc2liaWxpdHkoKTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm4gdGhlIHRyYW5zbGF0ZWQgdmFsdWUgaWYgYSB0cmFuc2xhdGUgZnVuY3Rpb24gaXMgcHJvdmlkZWQgZWxzZSB0aGUgb3JpZ2luYWwgdmFsdWVcbiAgcHJpdmF0ZSBnZXREaXNwbGF5VmFsdWUodmFsdWU6IG51bWJlciwgd2hpY2g6IExhYmVsVHlwZSk6IHN0cmluZyB7XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLnN0ZXBzQXJyYXkpICYmICF0aGlzLnZpZXdPcHRpb25zLmJpbmRJbmRleEZvclN0ZXBzQXJyYXkpIHtcbiAgICAgIHZhbHVlID0gdGhpcy5nZXRTdGVwVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy50cmFuc2xhdGUhKHZhbHVlLCB3aGljaCk7XG4gIH1cblxuICAvLyBSb3VuZCB2YWx1ZSB0byBzdGVwIGFuZCBwcmVjaXNpb24gYmFzZWQgb24gbWluVmFsdWVcbiAgcHJpdmF0ZSByb3VuZFN0ZXAodmFsdWU6IG51bWJlciwgY3VzdG9tU3RlcD86IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3Qgc3RlcCA9ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZChjdXN0b21TdGVwKSA/IGN1c3RvbVN0ZXAgOiB0aGlzLnZpZXdPcHRpb25zLnN0ZXA7XG4gICAgbGV0IHN0ZXBwZWREaWZmZXJlbmNlOiBudW1iZXIgPSBNYXRoSGVscGVyLnJvdW5kVG9QcmVjaXNpb25MaW1pdChcbiAgICAgICh2YWx1ZSAtIHRoaXMudmlld09wdGlvbnMuZmxvb3IhKSAvIHN0ZXAhLFxuICAgICAgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCFcbiAgICApO1xuICAgIHN0ZXBwZWREaWZmZXJlbmNlID0gTWF0aC5yb3VuZChzdGVwcGVkRGlmZmVyZW5jZSkgKiBzdGVwITtcbiAgICByZXR1cm4gTWF0aEhlbHBlci5yb3VuZFRvUHJlY2lzaW9uTGltaXQoXG4gICAgICB0aGlzLnZpZXdPcHRpb25zLmZsb29yISArIHN0ZXBwZWREaWZmZXJlbmNlLFxuICAgICAgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCFcbiAgICApO1xuICB9XG5cbiAgLy8gVHJhbnNsYXRlIHZhbHVlIHRvIHBpeGVsIHBvc2l0aW9uXG4gIHByaXZhdGUgdmFsdWVUb1Bvc2l0aW9uKHZhbDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgZm46IFZhbHVlVG9Qb3NpdGlvbkZ1bmN0aW9uID0gVmFsdWVIZWxwZXIubGluZWFyVmFsdWVUb1Bvc2l0aW9uO1xuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5jdXN0b21WYWx1ZVRvUG9zaXRpb24pKSB7XG4gICAgICBmbiA9IHRoaXMudmlld09wdGlvbnMuY3VzdG9tVmFsdWVUb1Bvc2l0aW9uITtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmlld09wdGlvbnMubG9nU2NhbGUpIHtcbiAgICAgIGZuID0gVmFsdWVIZWxwZXIubG9nVmFsdWVUb1Bvc2l0aW9uO1xuICAgIH1cblxuICAgIHZhbCA9IE1hdGhIZWxwZXIuY2xhbXBUb1JhbmdlKHZhbCwgdGhpcy52aWV3T3B0aW9ucy5mbG9vciEsIHRoaXMudmlld09wdGlvbnMuY2VpbCEpO1xuICAgIGxldCBwZXJjZW50OiBudW1iZXIgPSBmbih2YWwsIHRoaXMudmlld09wdGlvbnMuZmxvb3IhLCB0aGlzLnZpZXdPcHRpb25zLmNlaWwhKTtcbiAgICBpZiAoVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQocGVyY2VudCkpIHtcbiAgICAgIHBlcmNlbnQgPSAwO1xuICAgIH1cbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCkge1xuICAgICAgcGVyY2VudCA9IDEgLSBwZXJjZW50O1xuICAgIH1cbiAgICByZXR1cm4gcGVyY2VudCAqIHRoaXMubWF4SGFuZGxlUG9zaXRpb247XG4gIH1cblxuICAvLyBUcmFuc2xhdGUgcG9zaXRpb24gdG8gbW9kZWwgdmFsdWVcbiAgcHJpdmF0ZSBwb3NpdGlvblRvVmFsdWUocG9zaXRpb246IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IHBlcmNlbnQ6IG51bWJlciA9IHBvc2l0aW9uIC8gdGhpcy5tYXhIYW5kbGVQb3NpdGlvbjtcbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCkge1xuICAgICAgcGVyY2VudCA9IDEgLSBwZXJjZW50O1xuICAgIH1cbiAgICBsZXQgZm46IFBvc2l0aW9uVG9WYWx1ZUZ1bmN0aW9uID0gVmFsdWVIZWxwZXIubGluZWFyUG9zaXRpb25Ub1ZhbHVlO1xuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5jdXN0b21Qb3NpdGlvblRvVmFsdWUpKSB7XG4gICAgICBmbiA9IHRoaXMudmlld09wdGlvbnMuY3VzdG9tUG9zaXRpb25Ub1ZhbHVlITtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmlld09wdGlvbnMubG9nU2NhbGUpIHtcbiAgICAgIGZuID0gVmFsdWVIZWxwZXIubG9nUG9zaXRpb25Ub1ZhbHVlO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZTogbnVtYmVyID0gZm4ocGVyY2VudCwgdGhpcy52aWV3T3B0aW9ucy5mbG9vciEsIHRoaXMudmlld09wdGlvbnMuY2VpbCEpO1xuICAgIHJldHVybiAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpID8gdmFsdWUgOiAwO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBYLWNvb3JkaW5hdGUgb3IgWS1jb29yZGluYXRlIG9mIGFuIGV2ZW50XG4gIHByaXZhdGUgZ2V0RXZlbnRYWShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIHRhcmdldFRvdWNoSWQ/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChldmVudCBpbnN0YW5jZW9mIE1vdXNlRXZlbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsIHx8IHRoaXMudmlld09wdGlvbnMucm90YXRlICE9PSAwID8gZXZlbnQuY2xpZW50WSA6IGV2ZW50LmNsaWVudFg7XG4gICAgfVxuXG4gICAgbGV0IHRvdWNoSW5kZXg6IG51bWJlciA9IDA7XG4gICAgY29uc3QgdG91Y2hlczogVG91Y2hMaXN0ID0gZXZlbnQudG91Y2hlcztcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRhcmdldFRvdWNoSWQpKSB7XG4gICAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdG91Y2hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodG91Y2hlc1tpXS5pZGVudGlmaWVyID09PSB0YXJnZXRUb3VjaElkKSB7XG4gICAgICAgICAgdG91Y2hJbmRleCA9IGk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gdGhlIHRhcmdldCB0b3VjaCBvciBpZiB0aGUgdGFyZ2V0IHRvdWNoIHdhcyBub3QgZm91bmQgaW4gdGhlIGV2ZW50XG4gICAgLy8gcmV0dXJucyB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGZpcnN0IHRvdWNoXG4gICAgcmV0dXJuIHRoaXMudmlld09wdGlvbnMudmVydGljYWwgfHwgdGhpcy52aWV3T3B0aW9ucy5yb3RhdGUgIT09IDBcbiAgICAgID8gdG91Y2hlc1t0b3VjaEluZGV4XS5jbGllbnRZXG4gICAgICA6IHRvdWNoZXNbdG91Y2hJbmRleF0uY2xpZW50WDtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIGV2ZW50IHBvc2l0aW9uIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBzbGlkZXIgaXMgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbFxuICBwcml2YXRlIGdldEV2ZW50UG9zaXRpb24oZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50LCB0YXJnZXRUb3VjaElkPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzbGlkZXJFbGVtZW50Qm91bmRpbmdSZWN0OiBDbGllbnRSZWN0ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBzbGlkZXJQb3M6IG51bWJlciA9XG4gICAgICB0aGlzLnZpZXdPcHRpb25zLnZlcnRpY2FsIHx8IHRoaXMudmlld09wdGlvbnMucm90YXRlICE9PSAwXG4gICAgICAgID8gc2xpZGVyRWxlbWVudEJvdW5kaW5nUmVjdC5ib3R0b21cbiAgICAgICAgOiBzbGlkZXJFbGVtZW50Qm91bmRpbmdSZWN0LmxlZnQ7XG4gICAgbGV0IGV2ZW50UG9zOiBudW1iZXIgPSAwO1xuXG4gICAgaWYgKHRoaXMudmlld09wdGlvbnMudmVydGljYWwgfHwgdGhpcy52aWV3T3B0aW9ucy5yb3RhdGUgIT09IDApIHtcbiAgICAgIGV2ZW50UG9zID0gLXRoaXMuZ2V0RXZlbnRYWShldmVudCwgdGFyZ2V0VG91Y2hJZCkgKyBzbGlkZXJQb3M7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50UG9zID0gdGhpcy5nZXRFdmVudFhZKGV2ZW50LCB0YXJnZXRUb3VjaElkKSAtIHNsaWRlclBvcztcbiAgICB9XG5cbiAgICByZXR1cm4gZXZlbnRQb3MgKiB0aGlzLnZpZXdPcHRpb25zLnNjYWxlISAtIHRoaXMuaGFuZGxlSGFsZkRpbWVuc2lvbjtcbiAgfVxuXG4gIC8vIEdldCB0aGUgaGFuZGxlIGNsb3Nlc3QgdG8gYW4gZXZlbnRcbiAgcHJpdmF0ZSBnZXROZWFyZXN0SGFuZGxlKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IFBvaW50ZXJUeXBlIHtcbiAgICBpZiAoIXRoaXMucmFuZ2UpIHtcbiAgICAgIHJldHVybiBQb2ludGVyVHlwZS5NaW47XG4gICAgfVxuXG4gICAgY29uc3QgcG9zaXRpb246IG51bWJlciA9IHRoaXMuZ2V0RXZlbnRQb3NpdGlvbihldmVudCk7XG4gICAgY29uc3QgZGlzdGFuY2VNaW46IG51bWJlciA9IE1hdGguYWJzKHBvc2l0aW9uIC0gdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbik7XG4gICAgY29uc3QgZGlzdGFuY2VNYXg6IG51bWJlciA9IE1hdGguYWJzKHBvc2l0aW9uIC0gdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5wb3NpdGlvbik7XG5cbiAgICBpZiAoZGlzdGFuY2VNaW4gPCBkaXN0YW5jZU1heCkge1xuICAgICAgcmV0dXJuIFBvaW50ZXJUeXBlLk1pbjtcbiAgICB9IGVsc2UgaWYgKGRpc3RhbmNlTWluID4gZGlzdGFuY2VNYXgpIHtcbiAgICAgIHJldHVybiBQb2ludGVyVHlwZS5NYXg7XG4gICAgfSBlbHNlIGlmICghdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCkge1xuICAgICAgLy8gaWYgZXZlbnQgaXMgYXQgdGhlIHNhbWUgZGlzdGFuY2UgZnJvbSBtaW4vbWF4IHRoZW4gaWYgaXQncyBhdCBsZWZ0IG9mIG1pbkgsIHdlIHJldHVybiBtaW5IIGVsc2UgbWF4SFxuICAgICAgcmV0dXJuIHBvc2l0aW9uIDwgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbiA/IFBvaW50ZXJUeXBlLk1pbiA6IFBvaW50ZXJUeXBlLk1heDtcbiAgICB9XG4gICAgLy8gcmV2ZXJzZSBpbiBydGxcbiAgICByZXR1cm4gcG9zaXRpb24gPiB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLnBvc2l0aW9uID8gUG9pbnRlclR5cGUuTWluIDogUG9pbnRlclR5cGUuTWF4O1xuICB9XG5cbiAgLy8gQmluZCBtb3VzZSBhbmQgdG91Y2ggZXZlbnRzIHRvIHNsaWRlciBoYW5kbGVzXG4gIHByaXZhdGUgYmluZEV2ZW50cygpOiB2b2lkIHtcbiAgICBjb25zdCBkcmFnZ2FibGVSYW5nZTogYm9vbGVhbiA9IHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2UhO1xuXG4gICAgaWYgKCF0aGlzLnZpZXdPcHRpb25zLm9ubHlCaW5kSGFuZGxlcykge1xuICAgICAgdGhpcy5zZWxlY3Rpb25CYXJFbGVtZW50IS5vbignbW91c2Vkb3duJywgKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PlxuICAgICAgICB0aGlzLm9uQmFyU3RhcnQoZHJhZ2dhYmxlUmFuZ2UsIGV2ZW50LCB0cnVlLCB0cnVlLCB1bmRlZmluZWQsIHRydWUpXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmRyYWdnYWJsZVJhbmdlT25seSkge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5vbignbW91c2Vkb3duJywgKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PlxuICAgICAgICB0aGlzLm9uQmFyU3RhcnQoZHJhZ2dhYmxlUmFuZ2UsIGV2ZW50LCB0cnVlLCB0cnVlLCBQb2ludGVyVHlwZS5NaW4pXG4gICAgICApO1xuICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5vbignbW91c2Vkb3duJywgKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PlxuICAgICAgICB0aGlzLm9uQmFyU3RhcnQoZHJhZ2dhYmxlUmFuZ2UsIGV2ZW50LCB0cnVlLCB0cnVlLCBQb2ludGVyVHlwZS5NYXgpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLm9uKCdtb3VzZWRvd24nLCAoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkID0+XG4gICAgICAgIHRoaXMub25TdGFydChldmVudCwgdHJ1ZSwgdHJ1ZSwgUG9pbnRlclR5cGUuTWluKVxuICAgICAgKTtcblxuICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5vbignbW91c2Vkb3duJywgKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PlxuICAgICAgICAgIHRoaXMub25TdGFydChldmVudCwgdHJ1ZSwgdHJ1ZSwgUG9pbnRlclR5cGUuTWF4KVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnZpZXdPcHRpb25zLm9ubHlCaW5kSGFuZGxlcykge1xuICAgICAgICB0aGlzLmZ1bGxCYXJFbGVtZW50IS5vbignbW91c2Vkb3duJywgKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PlxuICAgICAgICAgIHRoaXMub25TdGFydChldmVudCwgdHJ1ZSwgdHJ1ZSwgdW5kZWZpbmVkLCB0cnVlKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnRpY2tzRWxlbWVudCEub24oJ21vdXNlZG93bicsIChldmVudDogTW91c2VFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgICB0aGlzLm9uU3RhcnQoZXZlbnQsIHRydWUsIHRydWUsIHVuZGVmaW5lZCwgdHJ1ZSwgdHJ1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudmlld09wdGlvbnMub25seUJpbmRIYW5kbGVzKSB7XG4gICAgICB0aGlzLnNlbGVjdGlvbkJhckVsZW1lbnQhLm9uUGFzc2l2ZSgndG91Y2hzdGFydCcsIChldmVudDogVG91Y2hFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgdGhpcy5vbkJhclN0YXJ0KGRyYWdnYWJsZVJhbmdlLCBldmVudCwgdHJ1ZSwgdHJ1ZSwgdW5kZWZpbmVkLCB0cnVlKVxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2VPbmx5KSB7XG4gICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLm9uUGFzc2l2ZSgndG91Y2hzdGFydCcsIChldmVudDogVG91Y2hFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgdGhpcy5vbkJhclN0YXJ0KGRyYWdnYWJsZVJhbmdlLCBldmVudCwgdHJ1ZSwgdHJ1ZSwgUG9pbnRlclR5cGUuTWluKVxuICAgICAgKTtcbiAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEub25QYXNzaXZlKCd0b3VjaHN0YXJ0JywgKGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCA9PlxuICAgICAgICB0aGlzLm9uQmFyU3RhcnQoZHJhZ2dhYmxlUmFuZ2UsIGV2ZW50LCB0cnVlLCB0cnVlLCBQb2ludGVyVHlwZS5NYXgpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLm9uUGFzc2l2ZSgndG91Y2hzdGFydCcsIChldmVudDogVG91Y2hFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgdGhpcy5vblN0YXJ0KGV2ZW50LCB0cnVlLCB0cnVlLCBQb2ludGVyVHlwZS5NaW4pXG4gICAgICApO1xuICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5vblBhc3NpdmUoJ3RvdWNoc3RhcnQnLCAoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkID0+XG4gICAgICAgICAgdGhpcy5vblN0YXJ0KGV2ZW50LCB0cnVlLCB0cnVlLCBQb2ludGVyVHlwZS5NYXgpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMudmlld09wdGlvbnMub25seUJpbmRIYW5kbGVzKSB7XG4gICAgICAgIHRoaXMuZnVsbEJhckVsZW1lbnQhLm9uUGFzc2l2ZSgndG91Y2hzdGFydCcsIChldmVudDogVG91Y2hFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgICB0aGlzLm9uU3RhcnQoZXZlbnQsIHRydWUsIHRydWUsIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy50aWNrc0VsZW1lbnQhLm9uUGFzc2l2ZSgndG91Y2hzdGFydCcsIChldmVudDogVG91Y2hFdmVudCk6IHZvaWQgPT5cbiAgICAgICAgICB0aGlzLm9uU3RhcnQoZXZlbnQsIGZhbHNlLCBmYWxzZSwgdW5kZWZpbmVkLCB0cnVlLCB0cnVlKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmtleWJvYXJkU3VwcG9ydCkge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5vbignZm9jdXMnLCAoKTogdm9pZCA9PiB0aGlzLm9uUG9pbnRlckZvY3VzKFBvaW50ZXJUeXBlLk1pbikpO1xuICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5vbignZm9jdXMnLCAoKTogdm9pZCA9PiB0aGlzLm9uUG9pbnRlckZvY3VzKFBvaW50ZXJUeXBlLk1heCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3B0aW9uc0luZmx1ZW5jaW5nRXZlbnRCaW5kaW5ncyhvcHRpb25zOiBPcHRpb25zKTogYm9vbGVhbltdIHtcbiAgICByZXR1cm4gW1xuICAgICAgb3B0aW9ucy5kaXNhYmxlZCEsXG4gICAgICBvcHRpb25zLnJlYWRPbmx5ISxcbiAgICAgIG9wdGlvbnMuZHJhZ2dhYmxlUmFuZ2UhLFxuICAgICAgb3B0aW9ucy5kcmFnZ2FibGVSYW5nZU9ubHkhLFxuICAgICAgb3B0aW9ucy5vbmx5QmluZEhhbmRsZXMhLFxuICAgICAgb3B0aW9ucy5rZXlib2FyZFN1cHBvcnQhXG4gICAgXTtcbiAgfVxuXG4gIC8vIFVuYmluZCBtb3VzZSBhbmQgdG91Y2ggZXZlbnRzIHRvIHNsaWRlciBoYW5kbGVzXG4gIHByaXZhdGUgdW5iaW5kRXZlbnRzKCk6IHZvaWQge1xuICAgIHRoaXMudW5zdWJzY3JpYmVPbk1vdmUoKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlT25FbmQoKTtcblxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0aGlzLmdldEFsbFNsaWRlckVsZW1lbnRzKCkpIHtcbiAgICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoZWxlbWVudCkpIHtcbiAgICAgICAgZWxlbWVudC5vZmYoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uQmFyU3RhcnQoXG4gICAgZHJhZ2dhYmxlUmFuZ2U6IGJvb2xlYW4sXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50LFxuICAgIGJpbmRNb3ZlOiBib29sZWFuLFxuICAgIGJpbmRFbmQ6IGJvb2xlYW4sXG4gICAgcG9pbnRlclR5cGU/OiBQb2ludGVyVHlwZSxcbiAgICBzaW11bGF0ZUltbWVkaWF0ZU1vdmU/OiBib29sZWFuLFxuICAgIHNpbXVsYXRlSW1tZWRpYXRlRW5kPzogYm9vbGVhblxuICApOiB2b2lkIHtcbiAgICBpZiAoZHJhZ2dhYmxlUmFuZ2UpIHtcbiAgICAgIHRoaXMub25EcmFnU3RhcnQoZXZlbnQsIGJpbmRNb3ZlLCBiaW5kRW5kLCBwb2ludGVyVHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub25TdGFydChldmVudCwgYmluZE1vdmUsIGJpbmRFbmQsIHBvaW50ZXJUeXBlLCBzaW11bGF0ZUltbWVkaWF0ZU1vdmUsIHNpbXVsYXRlSW1tZWRpYXRlRW5kKTtcbiAgICB9XG4gIH1cblxuICAvLyBvblN0YXJ0IGV2ZW50IGhhbmRsZXJcbiAgcHJpdmF0ZSBvblN0YXJ0KFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCxcbiAgICBiaW5kTW92ZTogYm9vbGVhbixcbiAgICBiaW5kRW5kOiBib29sZWFuLFxuICAgIHBvaW50ZXJUeXBlPzogUG9pbnRlclR5cGUsXG4gICAgc2ltdWxhdGVJbW1lZGlhdGVNb3ZlPzogYm9vbGVhbixcbiAgICBzaW11bGF0ZUltbWVkaWF0ZUVuZD86IGJvb2xlYW5cbiAgKTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgLy8gT25seSBjYWxsIHByZXZlbnREZWZhdWx0KCkgd2hlbiBoYW5kbGluZyBub24tcGFzc2l2ZSBldmVudHMgKHBhc3NpdmUgZXZlbnRzIGRvbid0IG5lZWQgaXQpXG4gICAgaWYgKCFDb21wYXRpYmlsaXR5SGVscGVyLmlzVG91Y2hFdmVudChldmVudCkgJiYgIXN1cHBvcnRzUGFzc2l2ZUV2ZW50cykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICB0aGlzLm1vdmluZyA9IGZhbHNlO1xuXG4gICAgLy8gV2UgaGF2ZSB0byBkbyB0aGlzIGluIGNhc2UgdGhlIEhUTUwgd2hlcmUgdGhlIHNsaWRlcnMgYXJlIG9uXG4gICAgLy8gaGF2ZSBiZWVuIGFuaW1hdGVkIGludG8gdmlldy5cbiAgICB0aGlzLmNhbGN1bGF0ZVZpZXdEaW1lbnNpb25zKCk7XG5cbiAgICBpZiAoVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQocG9pbnRlclR5cGUpKSB7XG4gICAgICBwb2ludGVyVHlwZSA9IHRoaXMuZ2V0TmVhcmVzdEhhbmRsZShldmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50VHJhY2tpbmdQb2ludGVyID0gcG9pbnRlclR5cGU7XG5cbiAgICBjb25zdCBwb2ludGVyRWxlbWVudDogU2xpZGVySGFuZGxlRGlyZWN0aXZlID0gdGhpcy5nZXRQb2ludGVyRWxlbWVudChwb2ludGVyVHlwZSEpITtcbiAgICBwb2ludGVyRWxlbWVudC5hY3RpdmUgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMudmlld09wdGlvbnMua2V5Ym9hcmRTdXBwb3J0KSB7XG4gICAgICBwb2ludGVyRWxlbWVudC5mb2N1cygpO1xuICAgIH1cblxuICAgIGlmIChiaW5kTW92ZSkge1xuICAgICAgdGhpcy51bnN1YnNjcmliZU9uTW92ZSgpO1xuXG4gICAgICBjb25zdCBvbk1vdmVDYWxsYmFjazogKGU6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB2b2lkID0gKGU6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZCA9PlxuICAgICAgICB0aGlzLmRyYWdnaW5nLmFjdGl2ZSA/IHRoaXMub25EcmFnTW92ZShlKSA6IHRoaXMub25Nb3ZlKGUpO1xuXG4gICAgICBpZiAoQ29tcGF0aWJpbGl0eUhlbHBlci5pc1RvdWNoRXZlbnQoZXZlbnQpKSB7XG4gICAgICAgIHRoaXMub25Nb3ZlRXZlbnRMaXN0ZW5lciA9IHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlciEuYXR0YWNoUGFzc2l2ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgZG9jdW1lbnQsXG4gICAgICAgICAgJ3RvdWNobW92ZScsXG4gICAgICAgICAgb25Nb3ZlQ2FsbGJhY2tcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25Nb3ZlRXZlbnRMaXN0ZW5lciA9IHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlciEuYXR0YWNoRXZlbnRMaXN0ZW5lcihkb2N1bWVudCwgJ21vdXNlbW92ZScsIG9uTW92ZUNhbGxiYWNrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYmluZEVuZCkge1xuICAgICAgdGhpcy51bnN1YnNjcmliZU9uRW5kKCk7XG5cbiAgICAgIGNvbnN0IG9uRW5kQ2FsbGJhY2s6IChlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4gdm9pZCA9IChlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IHZvaWQgPT4gdGhpcy5vbkVuZChlKTtcblxuICAgICAgaWYgKENvbXBhdGliaWxpdHlIZWxwZXIuaXNUb3VjaEV2ZW50KGV2ZW50KSkge1xuICAgICAgICB0aGlzLm9uRW5kRXZlbnRMaXN0ZW5lciA9IHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlciEuYXR0YWNoUGFzc2l2ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgZG9jdW1lbnQsXG4gICAgICAgICAgJ3RvdWNoZW5kJyxcbiAgICAgICAgICBvbkVuZENhbGxiYWNrXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uRW5kRXZlbnRMaXN0ZW5lciA9IHRoaXMuZXZlbnRMaXN0ZW5lckhlbHBlciEuYXR0YWNoRXZlbnRMaXN0ZW5lcihkb2N1bWVudCwgJ21vdXNldXAnLCBvbkVuZENhbGxiYWNrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnVzZXJDaGFuZ2VTdGFydC5lbWl0KHRoaXMuZ2V0Q2hhbmdlQ29udGV4dCgpKTtcblxuICAgIGlmIChcbiAgICAgIENvbXBhdGliaWxpdHlIZWxwZXIuaXNUb3VjaEV2ZW50KGV2ZW50KSAmJlxuICAgICAgIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKChldmVudCBhcyBUb3VjaEV2ZW50KS5jaGFuZ2VkVG91Y2hlcylcbiAgICApIHtcbiAgICAgIC8vIFN0b3JlIHRoZSB0b3VjaCBpZGVudGlmaWVyXG4gICAgICBpZiAoVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy50b3VjaElkKSkge1xuICAgICAgICB0aGlzLnRvdWNoSWQgPSAoZXZlbnQgYXMgVG91Y2hFdmVudCkuY2hhbmdlZFRvdWNoZXNbMF0uaWRlbnRpZmllcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDbGljayBldmVudHMsIGVpdGhlciB3aXRoIG1vdXNlIG9yIHRvdWNoIGdlc3R1cmUgYXJlIHdlaXJkLiBTb21ldGltZXMgdGhleSByZXN1bHQgaW4gZnVsbFxuICAgIC8vIHN0YXJ0LCBtb3ZlLCBlbmQgc2VxdWVuY2UsIGFuZCBzb21ldGltZXMsIHRoZXkgZG9uJ3QgLSB0aGV5IG9ubHkgaW52b2tlIG1vdXNlZG93blxuICAgIC8vIEFzIGEgd29ya2Fyb3VuZCwgd2Ugc2ltdWxhdGUgdGhlIGZpcnN0IG1vdmUgZXZlbnQgYW5kIHRoZSBlbmQgZXZlbnQgaWYgaXQncyBuZWNlc3NhcnlcbiAgICBpZiAoc2ltdWxhdGVJbW1lZGlhdGVNb3ZlKSB7XG4gICAgICB0aGlzLm9uTW92ZShldmVudCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHNpbXVsYXRlSW1tZWRpYXRlRW5kKSB7XG4gICAgICB0aGlzLm9uRW5kKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBvbk1vdmUgZXZlbnQgaGFuZGxlclxuICBwcml2YXRlIG9uTW92ZShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIGZyb21UaWNrPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGxldCB0b3VjaEZvclRoaXNTbGlkZXI6IFRvdWNoO1xuXG4gICAgaWYgKENvbXBhdGliaWxpdHlIZWxwZXIuaXNUb3VjaEV2ZW50KGV2ZW50KSkge1xuICAgICAgY29uc3QgY2hhbmdlZFRvdWNoZXM6IFRvdWNoTGlzdCA9IChldmVudCBhcyBUb3VjaEV2ZW50KS5jaGFuZ2VkVG91Y2hlcztcbiAgICAgIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCBjaGFuZ2VkVG91Y2hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoY2hhbmdlZFRvdWNoZXNbaV0uaWRlbnRpZmllciA9PT0gdGhpcy50b3VjaElkKSB7XG4gICAgICAgICAgdG91Y2hGb3JUaGlzU2xpZGVyID0gY2hhbmdlZFRvdWNoZXNbaV07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRvdWNoRm9yVGhpc1NsaWRlciEpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5hbmltYXRlICYmICF0aGlzLnZpZXdPcHRpb25zLmFuaW1hdGVPbk1vdmUpIHtcbiAgICAgIGlmICh0aGlzLm1vdmluZykge1xuICAgICAgICB0aGlzLnNsaWRlckVsZW1lbnRBbmltYXRlQ2xhc3MgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm1vdmluZyA9IHRydWU7XG5cbiAgICBjb25zdCBuZXdQb3M6IG51bWJlciA9ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0b3VjaEZvclRoaXNTbGlkZXIhKVxuICAgICAgPyB0aGlzLmdldEV2ZW50UG9zaXRpb24oZXZlbnQsIHRvdWNoRm9yVGhpc1NsaWRlciEuaWRlbnRpZmllcilcbiAgICAgIDogdGhpcy5nZXRFdmVudFBvc2l0aW9uKGV2ZW50KTtcbiAgICBsZXQgbmV3VmFsdWU6IG51bWJlcjtcbiAgICBjb25zdCBjZWlsVmFsdWU6IG51bWJlciA9IHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnQgPyB0aGlzLnZpZXdPcHRpb25zLmZsb29yISA6IHRoaXMudmlld09wdGlvbnMuY2VpbCE7XG4gICAgY29uc3QgZmxvb3JWYWx1ZTogbnVtYmVyID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCA/IHRoaXMudmlld09wdGlvbnMuY2VpbCEgOiB0aGlzLnZpZXdPcHRpb25zLmZsb29yITtcblxuICAgIGlmIChuZXdQb3MgPD0gMCkge1xuICAgICAgbmV3VmFsdWUgPSBmbG9vclZhbHVlO1xuICAgIH0gZWxzZSBpZiAobmV3UG9zID49IHRoaXMubWF4SGFuZGxlUG9zaXRpb24pIHtcbiAgICAgIG5ld1ZhbHVlID0gY2VpbFZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdWYWx1ZSA9IHRoaXMucG9zaXRpb25Ub1ZhbHVlKG5ld1Bvcyk7XG4gICAgICBpZiAoZnJvbVRpY2sgJiYgIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMudGlja1N0ZXApKSB7XG4gICAgICAgIG5ld1ZhbHVlID0gdGhpcy5yb3VuZFN0ZXAobmV3VmFsdWUsIHRoaXMudmlld09wdGlvbnMudGlja1N0ZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3VmFsdWUgPSB0aGlzLnJvdW5kU3RlcChuZXdWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25UcmFja2luZ0hhbmRsZShuZXdWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uRW5kKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IHZvaWQge1xuICAgIGlmIChDb21wYXRpYmlsaXR5SGVscGVyLmlzVG91Y2hFdmVudChldmVudCkpIHtcbiAgICAgIGNvbnN0IGNoYW5nZWRUb3VjaGVzOiBUb3VjaExpc3QgPSAoZXZlbnQgYXMgVG91Y2hFdmVudCkuY2hhbmdlZFRvdWNoZXM7XG4gICAgICBpZiAoY2hhbmdlZFRvdWNoZXNbMF0uaWRlbnRpZmllciAhPT0gdGhpcy50b3VjaElkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm1vdmluZyA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmFuaW1hdGUpIHtcbiAgICAgIHRoaXMuc2xpZGVyRWxlbWVudEFuaW1hdGVDbGFzcyA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy50b3VjaElkID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKCF0aGlzLnZpZXdPcHRpb25zLmtleWJvYXJkU3VwcG9ydCkge1xuICAgICAgdGhpcy5taW5IYW5kbGVFbGVtZW50IS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZHJhZ2dpbmcuYWN0aXZlID0gZmFsc2U7XG5cbiAgICB0aGlzLnVuc3Vic2NyaWJlT25Nb3ZlKCk7XG4gICAgdGhpcy51bnN1YnNjcmliZU9uRW5kKCk7XG5cbiAgICB0aGlzLnVzZXJDaGFuZ2VFbmQuZW1pdCh0aGlzLmdldENoYW5nZUNvbnRleHQoKSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlckZvY3VzKHBvaW50ZXJUeXBlOiBQb2ludGVyVHlwZSk6IHZvaWQge1xuICAgIGNvbnN0IHBvaW50ZXJFbGVtZW50OiBTbGlkZXJIYW5kbGVEaXJlY3RpdmUgPSB0aGlzLmdldFBvaW50ZXJFbGVtZW50KHBvaW50ZXJUeXBlKSE7XG4gICAgcG9pbnRlckVsZW1lbnQub24oJ2JsdXInLCAoKTogdm9pZCA9PiB0aGlzLm9uUG9pbnRlckJsdXIocG9pbnRlckVsZW1lbnQpKTtcbiAgICBwb2ludGVyRWxlbWVudC5vbigna2V5ZG93bicsIChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4gdGhpcy5vbktleWJvYXJkRXZlbnQoZXZlbnQpKTtcbiAgICBwb2ludGVyRWxlbWVudC5vbigna2V5dXAnLCAoKTogdm9pZCA9PiB0aGlzLm9uS2V5VXAoKSk7XG4gICAgcG9pbnRlckVsZW1lbnQuYWN0aXZlID0gdHJ1ZTtcblxuICAgIHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9IHBvaW50ZXJUeXBlO1xuICAgIHRoaXMuY3VycmVudEZvY3VzUG9pbnRlciA9IHBvaW50ZXJUeXBlO1xuICAgIHRoaXMuZmlyc3RLZXlEb3duID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgb25LZXlVcCgpOiB2b2lkIHtcbiAgICB0aGlzLmZpcnN0S2V5RG93biA9IHRydWU7XG4gICAgdGhpcy51c2VyQ2hhbmdlRW5kLmVtaXQodGhpcy5nZXRDaGFuZ2VDb250ZXh0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJCbHVyKHBvaW50ZXI6IFNsaWRlckhhbmRsZURpcmVjdGl2ZSk6IHZvaWQge1xuICAgIHBvaW50ZXIub2ZmKCdibHVyJyk7XG4gICAgcG9pbnRlci5vZmYoJ2tleWRvd24nKTtcbiAgICBwb2ludGVyLm9mZigna2V5dXAnKTtcbiAgICBwb2ludGVyLmFjdGl2ZSA9IGZhbHNlO1xuICAgIGlmIChWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnRvdWNoSWQpKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmN1cnJlbnRGb2N1c1BvaW50ZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRLZXlBY3Rpb25zKGN1cnJlbnRWYWx1ZTogbnVtYmVyKTogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSB7XG4gICAgY29uc3QgdmFsdWVSYW5nZTogbnVtYmVyID0gdGhpcy52aWV3T3B0aW9ucy5jZWlsISAtIHRoaXMudmlld09wdGlvbnMuZmxvb3IhO1xuXG4gICAgbGV0IGluY3JlYXNlU3RlcDogbnVtYmVyID0gY3VycmVudFZhbHVlICsgdGhpcy52aWV3T3B0aW9ucy5zdGVwITtcbiAgICBsZXQgZGVjcmVhc2VTdGVwOiBudW1iZXIgPSBjdXJyZW50VmFsdWUgLSB0aGlzLnZpZXdPcHRpb25zLnN0ZXAhO1xuICAgIGxldCBpbmNyZWFzZVBhZ2U6IG51bWJlciA9IGN1cnJlbnRWYWx1ZSArIHZhbHVlUmFuZ2UgLyAxMDtcbiAgICBsZXQgZGVjcmVhc2VQYWdlOiBudW1iZXIgPSBjdXJyZW50VmFsdWUgLSB2YWx1ZVJhbmdlIC8gMTA7XG5cbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5yZXZlcnNlZENvbnRyb2xzKSB7XG4gICAgICBpbmNyZWFzZVN0ZXAgPSBjdXJyZW50VmFsdWUgLSB0aGlzLnZpZXdPcHRpb25zLnN0ZXAhO1xuICAgICAgZGVjcmVhc2VTdGVwID0gY3VycmVudFZhbHVlICsgdGhpcy52aWV3T3B0aW9ucy5zdGVwITtcbiAgICAgIGluY3JlYXNlUGFnZSA9IGN1cnJlbnRWYWx1ZSAtIHZhbHVlUmFuZ2UgLyAxMDtcbiAgICAgIGRlY3JlYXNlUGFnZSA9IGN1cnJlbnRWYWx1ZSArIHZhbHVlUmFuZ2UgLyAxMDtcbiAgICB9XG5cbiAgICAvLyBMZWZ0IHRvIHJpZ2h0IGRlZmF1bHQgYWN0aW9uc1xuICAgIGNvbnN0IGFjdGlvbnM6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7XG4gICAgICBVUDogaW5jcmVhc2VTdGVwLFxuICAgICAgRE9XTjogZGVjcmVhc2VTdGVwLFxuICAgICAgTEVGVDogZGVjcmVhc2VTdGVwLFxuICAgICAgUklHSFQ6IGluY3JlYXNlU3RlcCxcbiAgICAgIFBBR0VVUDogaW5jcmVhc2VQYWdlLFxuICAgICAgUEFHRURPV046IGRlY3JlYXNlUGFnZSxcbiAgICAgIEhPTUU6IHRoaXMudmlld09wdGlvbnMucmV2ZXJzZWRDb250cm9scyA/IHRoaXMudmlld09wdGlvbnMuY2VpbCEgOiB0aGlzLnZpZXdPcHRpb25zLmZsb29yISxcbiAgICAgIEVORDogdGhpcy52aWV3T3B0aW9ucy5yZXZlcnNlZENvbnRyb2xzID8gdGhpcy52aWV3T3B0aW9ucy5mbG9vciEgOiB0aGlzLnZpZXdPcHRpb25zLmNlaWwhXG4gICAgfTtcbiAgICAvLyByaWdodCB0byBsZWZ0IG1lYW5zIHN3YXBwaW5nIHJpZ2h0IGFuZCBsZWZ0IGFycm93c1xuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLnJpZ2h0VG9MZWZ0KSB7XG4gICAgICBhY3Rpb25zWydMRUZUJ10gPSBpbmNyZWFzZVN0ZXA7XG4gICAgICBhY3Rpb25zWydSSUdIVCddID0gZGVjcmVhc2VTdGVwO1xuICAgICAgLy8gcmlnaHQgdG8gbGVmdCBhbmQgdmVydGljYWwgbWVhbnMgd2UgYWxzbyBzd2FwIHVwIGFuZCBkb3duXG4gICAgICBpZiAodGhpcy52aWV3T3B0aW9ucy52ZXJ0aWNhbCB8fCB0aGlzLnZpZXdPcHRpb25zLnJvdGF0ZSAhPT0gMCkge1xuICAgICAgICBhY3Rpb25zWydVUCddID0gZGVjcmVhc2VTdGVwO1xuICAgICAgICBhY3Rpb25zWydET1dOJ10gPSBpbmNyZWFzZVN0ZXA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhY3Rpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSBvbktleWJvYXJkRXZlbnQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldEN1cnJlbnRUcmFja2luZ1ZhbHVlKCkhO1xuICAgIGNvbnN0IGtleUNvZGUgPSAhVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoZXZlbnQua2V5Q29kZSkgPyBldmVudC5rZXlDb2RlIDogZXZlbnQud2hpY2g7XG4gICAgY29uc3Qga2V5czogeyBba2V5Q29kZTogbnVtYmVyXTogc3RyaW5nIH0gPSB7XG4gICAgICAzODogJ1VQJyxcbiAgICAgIDQwOiAnRE9XTicsXG4gICAgICAzNzogJ0xFRlQnLFxuICAgICAgMzk6ICdSSUdIVCcsXG4gICAgICAzMzogJ1BBR0VVUCcsXG4gICAgICAzNDogJ1BBR0VET1dOJyxcbiAgICAgIDM2OiAnSE9NRScsXG4gICAgICAzNTogJ0VORCdcbiAgICB9O1xuICAgIGNvbnN0IGFjdGlvbnM6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB0aGlzLmdldEtleUFjdGlvbnMoY3VycmVudFZhbHVlKTtcbiAgICBjb25zdCBrZXk6IHN0cmluZyA9IGtleXNba2V5Q29kZV07XG4gICAgY29uc3QgYWN0aW9uOiBudW1iZXIgPSBhY3Rpb25zW2tleV07XG5cbiAgICBpZiAoVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQoYWN0aW9uKSB8fCBWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy5maXJzdEtleURvd24pIHtcbiAgICAgIHRoaXMuZmlyc3RLZXlEb3duID0gZmFsc2U7XG4gICAgICB0aGlzLnVzZXJDaGFuZ2VTdGFydC5lbWl0KHRoaXMuZ2V0Q2hhbmdlQ29udGV4dCgpKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY3Rpb25WYWx1ZTogbnVtYmVyID0gTWF0aEhlbHBlci5jbGFtcFRvUmFuZ2UoYWN0aW9uLCB0aGlzLnZpZXdPcHRpb25zLmZsb29yISwgdGhpcy52aWV3T3B0aW9ucy5jZWlsISk7XG4gICAgY29uc3QgbmV3VmFsdWU6IG51bWJlciA9IHRoaXMucm91bmRTdGVwKGFjdGlvblZhbHVlKTtcbiAgICBpZiAoIXRoaXMudmlld09wdGlvbnMuZHJhZ2dhYmxlUmFuZ2VPbmx5KSB7XG4gICAgICB0aGlzLnBvc2l0aW9uVHJhY2tpbmdIYW5kbGUobmV3VmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkaWZmZXJlbmNlID0gdGhpcy52aWV3SGlnaFZhbHVlISAtIHRoaXMudmlld0xvd1ZhbHVlITtcbiAgICAgIGxldCBuZXdNaW5WYWx1ZTogbnVtYmVyO1xuICAgICAgbGV0IG5ld01heFZhbHVlOiBudW1iZXI7XG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1pbikge1xuICAgICAgICBuZXdNaW5WYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICBuZXdNYXhWYWx1ZSA9IG5ld1ZhbHVlICsgZGlmZmVyZW5jZTtcbiAgICAgICAgaWYgKG5ld01heFZhbHVlID4gdGhpcy52aWV3T3B0aW9ucy5jZWlsISkge1xuICAgICAgICAgIG5ld01heFZhbHVlID0gdGhpcy52aWV3T3B0aW9ucy5jZWlsITtcbiAgICAgICAgICBuZXdNaW5WYWx1ZSA9IG5ld01heFZhbHVlIC0gZGlmZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgICBuZXdNYXhWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICBuZXdNaW5WYWx1ZSA9IG5ld1ZhbHVlIC0gZGlmZmVyZW5jZTtcbiAgICAgICAgaWYgKG5ld01pblZhbHVlIDwgdGhpcy52aWV3T3B0aW9ucy5mbG9vciEpIHtcbiAgICAgICAgICBuZXdNaW5WYWx1ZSA9IHRoaXMudmlld09wdGlvbnMuZmxvb3IhO1xuICAgICAgICAgIG5ld01heFZhbHVlID0gbmV3TWluVmFsdWUgKyBkaWZmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLnBvc2l0aW9uVHJhY2tpbmdCYXIobmV3TWluVmFsdWUhLCBuZXdNYXhWYWx1ZSEpO1xuICAgIH1cbiAgfVxuXG4gIC8vIG9uRHJhZ1N0YXJ0IGV2ZW50IGhhbmRsZXIsIGhhbmRsZXMgZHJhZ2dpbmcgb2YgdGhlIG1pZGRsZSBiYXJcbiAgcHJpdmF0ZSBvbkRyYWdTdGFydChcbiAgICBldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsXG4gICAgYmluZE1vdmU6IGJvb2xlYW4sXG4gICAgYmluZEVuZDogYm9vbGVhbixcbiAgICBwb2ludGVyVHlwZT86IFBvaW50ZXJUeXBlXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHBvc2l0aW9uOiBudW1iZXIgPSB0aGlzLmdldEV2ZW50UG9zaXRpb24oZXZlbnQpO1xuXG4gICAgdGhpcy5kcmFnZ2luZyA9IG5ldyBEcmFnZ2luZygpO1xuICAgIHRoaXMuZHJhZ2dpbmcuYWN0aXZlID0gdHJ1ZTtcbiAgICB0aGlzLmRyYWdnaW5nLnZhbHVlID0gdGhpcy5wb3NpdGlvblRvVmFsdWUocG9zaXRpb24pO1xuICAgIHRoaXMuZHJhZ2dpbmcuZGlmZmVyZW5jZSA9IHRoaXMudmlld0hpZ2hWYWx1ZSEgLSB0aGlzLnZpZXdMb3dWYWx1ZSE7XG4gICAgdGhpcy5kcmFnZ2luZy5sb3dMaW1pdCA9IHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnRcbiAgICAgID8gdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbiAtIHBvc2l0aW9uXG4gICAgICA6IHBvc2l0aW9uIC0gdGhpcy5taW5IYW5kbGVFbGVtZW50IS5wb3NpdGlvbjtcbiAgICB0aGlzLmRyYWdnaW5nLmhpZ2hMaW1pdCA9IHRoaXMudmlld09wdGlvbnMucmlnaHRUb0xlZnRcbiAgICAgID8gcG9zaXRpb24gLSB0aGlzLm1heEhhbmRsZUVsZW1lbnQhLnBvc2l0aW9uXG4gICAgICA6IHRoaXMubWF4SGFuZGxlRWxlbWVudCEucG9zaXRpb24gLSBwb3NpdGlvbjtcblxuICAgIHRoaXMub25TdGFydChldmVudCwgYmluZE1vdmUsIGJpbmRFbmQsIHBvaW50ZXJUeXBlKTtcbiAgfVxuXG4gIC8qKiBHZXQgbWluIHZhbHVlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBuZXdQb3MgaXMgb3V0T2ZCb3VuZHMgYWJvdmUgb3IgYmVsb3cgdGhlIGJhciBhbmQgcmlnaHRUb0xlZnQgKi9cbiAgcHJpdmF0ZSBnZXRNaW5WYWx1ZShuZXdQb3M6IG51bWJlciwgb3V0T2ZCb3VuZHM6IGJvb2xlYW4sIGlzQWJvdmU6IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGNvbnN0IGlzUlRMID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCE7XG4gICAgbGV0IHZhbHVlOiBudW1iZXI7XG5cbiAgICBpZiAob3V0T2ZCb3VuZHMpIHtcbiAgICAgIGlmIChpc0Fib3ZlKSB7XG4gICAgICAgIHZhbHVlID0gaXNSVEwgPyB0aGlzLnZpZXdPcHRpb25zLmZsb29yISA6IHRoaXMudmlld09wdGlvbnMuY2VpbCEgLSB0aGlzLmRyYWdnaW5nLmRpZmZlcmVuY2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IGlzUlRMID8gdGhpcy52aWV3T3B0aW9ucy5jZWlsISAtIHRoaXMuZHJhZ2dpbmcuZGlmZmVyZW5jZSA6IHRoaXMudmlld09wdGlvbnMuZmxvb3IhO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA9IGlzUlRMXG4gICAgICAgID8gdGhpcy5wb3NpdGlvblRvVmFsdWUobmV3UG9zICsgdGhpcy5kcmFnZ2luZy5sb3dMaW1pdClcbiAgICAgICAgOiB0aGlzLnBvc2l0aW9uVG9WYWx1ZShuZXdQb3MgLSB0aGlzLmRyYWdnaW5nLmxvd0xpbWl0KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucm91bmRTdGVwKHZhbHVlKTtcbiAgfVxuXG4gIC8qKiBHZXQgbWF4IHZhbHVlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBuZXdQb3MgaXMgb3V0T2ZCb3VuZHMgYWJvdmUgb3IgYmVsb3cgdGhlIGJhciBhbmQgcmlnaHRUb0xlZnQgKi9cbiAgcHJpdmF0ZSBnZXRNYXhWYWx1ZShuZXdQb3M6IG51bWJlciwgb3V0T2ZCb3VuZHM6IGJvb2xlYW4sIGlzQWJvdmU6IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGNvbnN0IGlzUlRMID0gdGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCE7XG4gICAgbGV0IHZhbHVlOiBudW1iZXI7XG5cbiAgICBpZiAob3V0T2ZCb3VuZHMpIHtcbiAgICAgIGlmIChpc0Fib3ZlKSB7XG4gICAgICAgIHZhbHVlID0gaXNSVEwgPyB0aGlzLnZpZXdPcHRpb25zLmZsb29yISArIHRoaXMuZHJhZ2dpbmcuZGlmZmVyZW5jZSA6IHRoaXMudmlld09wdGlvbnMuY2VpbCE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IGlzUlRMID8gdGhpcy52aWV3T3B0aW9ucy5jZWlsISA6IHRoaXMudmlld09wdGlvbnMuZmxvb3IhICsgdGhpcy5kcmFnZ2luZy5kaWZmZXJlbmNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNSVEwpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLnBvc2l0aW9uVG9WYWx1ZShuZXdQb3MgKyB0aGlzLmRyYWdnaW5nLmxvd0xpbWl0KSArIHRoaXMuZHJhZ2dpbmcuZGlmZmVyZW5jZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5wb3NpdGlvblRvVmFsdWUobmV3UG9zIC0gdGhpcy5kcmFnZ2luZy5sb3dMaW1pdCkgKyB0aGlzLmRyYWdnaW5nLmRpZmZlcmVuY2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucm91bmRTdGVwKHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgb25EcmFnTW92ZShldmVudD86IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgbmV3UG9zOiBudW1iZXIgPSB0aGlzLmdldEV2ZW50UG9zaXRpb24oZXZlbnQhKTtcblxuICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLmFuaW1hdGUgJiYgIXRoaXMudmlld09wdGlvbnMuYW5pbWF0ZU9uTW92ZSkge1xuICAgICAgaWYgKHRoaXMubW92aW5nKSB7XG4gICAgICAgIHRoaXMuc2xpZGVyRWxlbWVudEFuaW1hdGVDbGFzcyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubW92aW5nID0gdHJ1ZTtcblxuICAgIGxldCBjZWlsTGltaXQ6IG51bWJlcixcbiAgICAgIGZsb29yTGltaXQ6IG51bWJlcixcbiAgICAgIGZsb29ySGFuZGxlRWxlbWVudDogU2xpZGVySGFuZGxlRGlyZWN0aXZlLFxuICAgICAgY2VpbEhhbmRsZUVsZW1lbnQ6IFNsaWRlckhhbmRsZURpcmVjdGl2ZTtcbiAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5yaWdodFRvTGVmdCkge1xuICAgICAgY2VpbExpbWl0ID0gdGhpcy5kcmFnZ2luZy5sb3dMaW1pdDtcbiAgICAgIGZsb29yTGltaXQgPSB0aGlzLmRyYWdnaW5nLmhpZ2hMaW1pdDtcbiAgICAgIGZsb29ySGFuZGxlRWxlbWVudCA9IHRoaXMubWF4SGFuZGxlRWxlbWVudCE7XG4gICAgICBjZWlsSGFuZGxlRWxlbWVudCA9IHRoaXMubWluSGFuZGxlRWxlbWVudCE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNlaWxMaW1pdCA9IHRoaXMuZHJhZ2dpbmcuaGlnaExpbWl0O1xuICAgICAgZmxvb3JMaW1pdCA9IHRoaXMuZHJhZ2dpbmcubG93TGltaXQ7XG4gICAgICBmbG9vckhhbmRsZUVsZW1lbnQgPSB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhO1xuICAgICAgY2VpbEhhbmRsZUVsZW1lbnQgPSB0aGlzLm1heEhhbmRsZUVsZW1lbnQhO1xuICAgIH1cblxuICAgIGNvbnN0IGlzVW5kZXJGbG9vckxpbWl0OiBib29sZWFuID0gbmV3UG9zIDw9IGZsb29yTGltaXQ7XG4gICAgY29uc3QgaXNPdmVyQ2VpbExpbWl0OiBib29sZWFuID0gbmV3UG9zID49IHRoaXMubWF4SGFuZGxlUG9zaXRpb24gLSBjZWlsTGltaXQ7XG5cbiAgICBsZXQgbmV3TWluVmFsdWU6IG51bWJlcjtcbiAgICBsZXQgbmV3TWF4VmFsdWU6IG51bWJlcjtcbiAgICBpZiAoaXNVbmRlckZsb29yTGltaXQpIHtcbiAgICAgIGlmIChmbG9vckhhbmRsZUVsZW1lbnQucG9zaXRpb24gPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbmV3TWluVmFsdWUgPSB0aGlzLmdldE1pblZhbHVlKG5ld1BvcywgdHJ1ZSwgZmFsc2UpO1xuICAgICAgbmV3TWF4VmFsdWUgPSB0aGlzLmdldE1heFZhbHVlKG5ld1BvcywgdHJ1ZSwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoaXNPdmVyQ2VpbExpbWl0KSB7XG4gICAgICBpZiAoY2VpbEhhbmRsZUVsZW1lbnQucG9zaXRpb24gPT09IHRoaXMubWF4SGFuZGxlUG9zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbmV3TWF4VmFsdWUgPSB0aGlzLmdldE1heFZhbHVlKG5ld1BvcywgdHJ1ZSwgdHJ1ZSk7XG4gICAgICBuZXdNaW5WYWx1ZSA9IHRoaXMuZ2V0TWluVmFsdWUobmV3UG9zLCB0cnVlLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3TWluVmFsdWUgPSB0aGlzLmdldE1pblZhbHVlKG5ld1BvcywgZmFsc2UsIGZhbHNlKTtcbiAgICAgIG5ld01heFZhbHVlID0gdGhpcy5nZXRNYXhWYWx1ZShuZXdQb3MsIGZhbHNlLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdGhpcy5wb3NpdGlvblRyYWNraW5nQmFyKG5ld01pblZhbHVlLCBuZXdNYXhWYWx1ZSk7XG4gIH1cblxuICAvLyBTZXQgdGhlIG5ldyB2YWx1ZSBhbmQgcG9zaXRpb24gZm9yIHRoZSBlbnRpcmUgYmFyXG4gIHByaXZhdGUgcG9zaXRpb25UcmFja2luZ0JhcihuZXdNaW5WYWx1ZTogbnVtYmVyLCBuZXdNYXhWYWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLm1pbkxpbWl0KSAmJiBuZXdNaW5WYWx1ZSA8IHRoaXMudmlld09wdGlvbnMubWluTGltaXQhKSB7XG4gICAgICBuZXdNaW5WYWx1ZSA9IHRoaXMudmlld09wdGlvbnMubWluTGltaXQhO1xuICAgICAgbmV3TWF4VmFsdWUgPSBNYXRoSGVscGVyLnJvdW5kVG9QcmVjaXNpb25MaW1pdChcbiAgICAgICAgbmV3TWluVmFsdWUgKyB0aGlzLmRyYWdnaW5nLmRpZmZlcmVuY2UsXG4gICAgICAgIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMubWF4TGltaXQpICYmIG5ld01heFZhbHVlID4gdGhpcy52aWV3T3B0aW9ucy5tYXhMaW1pdCEpIHtcbiAgICAgIG5ld01heFZhbHVlID0gdGhpcy52aWV3T3B0aW9ucy5tYXhMaW1pdCE7XG4gICAgICBuZXdNaW5WYWx1ZSA9IE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KFxuICAgICAgICBuZXdNYXhWYWx1ZSAtIHRoaXMuZHJhZ2dpbmcuZGlmZmVyZW5jZSxcbiAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCFcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy52aWV3TG93VmFsdWUgPSBuZXdNaW5WYWx1ZTtcbiAgICB0aGlzLnZpZXdIaWdoVmFsdWUgPSBuZXdNYXhWYWx1ZTtcbiAgICB0aGlzLmFwcGx5Vmlld0NoYW5nZSgpO1xuICAgIHRoaXMudXBkYXRlSGFuZGxlcyhQb2ludGVyVHlwZS5NaW4sIHRoaXMudmFsdWVUb1Bvc2l0aW9uKG5ld01pblZhbHVlKSk7XG4gICAgdGhpcy51cGRhdGVIYW5kbGVzKFBvaW50ZXJUeXBlLk1heCwgdGhpcy52YWx1ZVRvUG9zaXRpb24obmV3TWF4VmFsdWUpKTtcbiAgfVxuXG4gIC8vIFNldCB0aGUgbmV3IHZhbHVlIGFuZCBwb3NpdGlvbiB0byB0aGUgY3VycmVudCB0cmFja2luZyBoYW5kbGVcbiAgcHJpdmF0ZSBwb3NpdGlvblRyYWNraW5nSGFuZGxlKG5ld1ZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBuZXdWYWx1ZSA9IHRoaXMuYXBwbHlNaW5NYXhMaW1pdChuZXdWYWx1ZSk7XG4gICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgIGlmICh0aGlzLnZpZXdPcHRpb25zLnB1c2hSYW5nZSkge1xuICAgICAgICBuZXdWYWx1ZSA9IHRoaXMuYXBwbHlQdXNoUmFuZ2UobmV3VmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMudmlld09wdGlvbnMubm9Td2l0Y2hpbmcpIHtcbiAgICAgICAgICBpZiAodGhpcy5jdXJyZW50VHJhY2tpbmdQb2ludGVyID09PSBQb2ludGVyVHlwZS5NaW4gJiYgbmV3VmFsdWUgPiB0aGlzLnZpZXdIaWdoVmFsdWUhKSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IHRoaXMuYXBwbHlNaW5NYXhSYW5nZSh0aGlzLnZpZXdIaWdoVmFsdWUhKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWF4ICYmIG5ld1ZhbHVlIDwgdGhpcy52aWV3TG93VmFsdWUhKSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IHRoaXMuYXBwbHlNaW5NYXhSYW5nZSh0aGlzLnZpZXdMb3dWYWx1ZSEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBuZXdWYWx1ZSA9IHRoaXMuYXBwbHlNaW5NYXhSYW5nZShuZXdWYWx1ZSk7XG4gICAgICAgIC8qIFRoaXMgaXMgdG8gY2hlY2sgaWYgd2UgbmVlZCB0byBzd2l0Y2ggdGhlIG1pbiBhbmQgbWF4IGhhbmRsZXMgKi9cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWluICYmIG5ld1ZhbHVlID4gdGhpcy52aWV3SGlnaFZhbHVlISkge1xuICAgICAgICAgIHRoaXMudmlld0xvd1ZhbHVlID0gdGhpcy52aWV3SGlnaFZhbHVlO1xuICAgICAgICAgIHRoaXMuYXBwbHlWaWV3Q2hhbmdlKCk7XG4gICAgICAgICAgdGhpcy51cGRhdGVIYW5kbGVzKFBvaW50ZXJUeXBlLk1pbiwgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5wb3NpdGlvbik7XG4gICAgICAgICAgdGhpcy51cGRhdGVBcmlhQXR0cmlidXRlcygpO1xuICAgICAgICAgIHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9IFBvaW50ZXJUeXBlLk1heDtcbiAgICAgICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICBpZiAodGhpcy52aWV3T3B0aW9ucy5rZXlib2FyZFN1cHBvcnQpIHtcbiAgICAgICAgICAgIHRoaXMubWF4SGFuZGxlRWxlbWVudCEuZm9jdXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50VHJhY2tpbmdQb2ludGVyID09PSBQb2ludGVyVHlwZS5NYXggJiYgbmV3VmFsdWUgPCB0aGlzLnZpZXdMb3dWYWx1ZSEpIHtcbiAgICAgICAgICB0aGlzLnZpZXdIaWdoVmFsdWUgPSB0aGlzLnZpZXdMb3dWYWx1ZTtcbiAgICAgICAgICB0aGlzLmFwcGx5Vmlld0NoYW5nZSgpO1xuICAgICAgICAgIHRoaXMudXBkYXRlSGFuZGxlcyhQb2ludGVyVHlwZS5NYXgsIHRoaXMubWluSGFuZGxlRWxlbWVudCEucG9zaXRpb24pO1xuICAgICAgICAgIHRoaXMudXBkYXRlQXJpYUF0dHJpYnV0ZXMoKTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPSBQb2ludGVyVHlwZS5NaW47XG4gICAgICAgICAgdGhpcy5tYXhIYW5kbGVFbGVtZW50IS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgaWYgKHRoaXMudmlld09wdGlvbnMua2V5Ym9hcmRTdXBwb3J0KSB7XG4gICAgICAgICAgICB0aGlzLm1pbkhhbmRsZUVsZW1lbnQhLmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZ2V0Q3VycmVudFRyYWNraW5nVmFsdWUoKSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1pbikge1xuICAgICAgICB0aGlzLnZpZXdMb3dWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLmFwcGx5Vmlld0NoYW5nZSgpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgICB0aGlzLnZpZXdIaWdoVmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5hcHBseVZpZXdDaGFuZ2UoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlSGFuZGxlcyh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIhLCB0aGlzLnZhbHVlVG9Qb3NpdGlvbihuZXdWYWx1ZSkpO1xuICAgICAgdGhpcy51cGRhdGVBcmlhQXR0cmlidXRlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlNaW5NYXhMaW1pdChuZXdWYWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMubWluTGltaXQpICYmIG5ld1ZhbHVlIDwgdGhpcy52aWV3T3B0aW9ucy5taW5MaW1pdCEpIHtcbiAgICAgIHJldHVybiB0aGlzLnZpZXdPcHRpb25zLm1pbkxpbWl0ITtcbiAgICB9XG4gICAgaWYgKCFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLm1heExpbWl0KSAmJiBuZXdWYWx1ZSA+IHRoaXMudmlld09wdGlvbnMubWF4TGltaXQhKSB7XG4gICAgICByZXR1cm4gdGhpcy52aWV3T3B0aW9ucy5tYXhMaW1pdCE7XG4gICAgfVxuICAgIHJldHVybiBuZXdWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlNaW5NYXhSYW5nZShuZXdWYWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBvcHBvc2l0ZVZhbHVlID0gdGhpcy5jdXJyZW50VHJhY2tpbmdQb2ludGVyID09PSBQb2ludGVyVHlwZS5NaW4gPyB0aGlzLnZpZXdIaWdoVmFsdWUgOiB0aGlzLnZpZXdMb3dWYWx1ZTtcbiAgICBjb25zdCBkaWZmZXJlbmNlOiBudW1iZXIgPSBNYXRoLmFicyhuZXdWYWx1ZSAtIG9wcG9zaXRlVmFsdWUhKTtcbiAgICBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudmlld09wdGlvbnMubWluUmFuZ2UpKSB7XG4gICAgICBpZiAoZGlmZmVyZW5jZSA8IHRoaXMudmlld09wdGlvbnMubWluUmFuZ2UhKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1pbikge1xuICAgICAgICAgIHJldHVybiBNYXRoSGVscGVyLnJvdW5kVG9QcmVjaXNpb25MaW1pdChcbiAgICAgICAgICAgIHRoaXMudmlld0hpZ2hWYWx1ZSEgLSB0aGlzLnZpZXdPcHRpb25zLm1pblJhbmdlISxcbiAgICAgICAgICAgIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRUcmFja2luZ1BvaW50ZXIgPT09IFBvaW50ZXJUeXBlLk1heCkge1xuICAgICAgICAgIHJldHVybiBNYXRoSGVscGVyLnJvdW5kVG9QcmVjaXNpb25MaW1pdChcbiAgICAgICAgICAgIHRoaXMudmlld0xvd1ZhbHVlISArIHRoaXMudmlld09wdGlvbnMubWluUmFuZ2UhLFxuICAgICAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCFcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghVmFsdWVIZWxwZXIuaXNOdWxsT3JVbmRlZmluZWQodGhpcy52aWV3T3B0aW9ucy5tYXhSYW5nZSkpIHtcbiAgICAgIGlmIChkaWZmZXJlbmNlID4gdGhpcy52aWV3T3B0aW9ucy5tYXhSYW5nZSEpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWluKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KFxuICAgICAgICAgICAgdGhpcy52aWV3SGlnaFZhbHVlISAtIHRoaXMudmlld09wdGlvbnMubWF4UmFuZ2UhLFxuICAgICAgICAgICAgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCFcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWF4KSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KFxuICAgICAgICAgICAgdGhpcy52aWV3TG93VmFsdWUhICsgdGhpcy52aWV3T3B0aW9ucy5tYXhSYW5nZSEsXG4gICAgICAgICAgICB0aGlzLnZpZXdPcHRpb25zLnByZWNpc2lvbkxpbWl0IVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ld1ZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVB1c2hSYW5nZShuZXdWYWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBkaWZmZXJlbmNlOiBudW1iZXIgPVxuICAgICAgdGhpcy5jdXJyZW50VHJhY2tpbmdQb2ludGVyID09PSBQb2ludGVyVHlwZS5NaW4gPyB0aGlzLnZpZXdIaWdoVmFsdWUhIC0gbmV3VmFsdWUgOiBuZXdWYWx1ZSAtIHRoaXMudmlld0xvd1ZhbHVlITtcbiAgICBjb25zdCBtaW5SYW5nZSA9ICFWYWx1ZUhlbHBlci5pc051bGxPclVuZGVmaW5lZCh0aGlzLnZpZXdPcHRpb25zLm1pblJhbmdlKVxuICAgICAgPyB0aGlzLnZpZXdPcHRpb25zLm1pblJhbmdlIVxuICAgICAgOiB0aGlzLnZpZXdPcHRpb25zLnN0ZXAhO1xuICAgIGNvbnN0IG1heFJhbmdlID0gdGhpcy52aWV3T3B0aW9ucy5tYXhSYW5nZSE7XG4gICAgLy8gaWYgc21hbGxlciB0aGFuIG1pblJhbmdlXG4gICAgaWYgKGRpZmZlcmVuY2UgPCBtaW5SYW5nZSkge1xuICAgICAgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWluKSB7XG4gICAgICAgIHRoaXMudmlld0hpZ2hWYWx1ZSA9IE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KFxuICAgICAgICAgIE1hdGgubWluKG5ld1ZhbHVlICsgbWluUmFuZ2UsIHRoaXMudmlld09wdGlvbnMuY2VpbCEpLFxuICAgICAgICAgIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhXG4gICAgICAgICk7XG4gICAgICAgIG5ld1ZhbHVlID0gTWF0aEhlbHBlci5yb3VuZFRvUHJlY2lzaW9uTGltaXQodGhpcy52aWV3SGlnaFZhbHVlIC0gbWluUmFuZ2UsIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhKTtcbiAgICAgICAgdGhpcy5hcHBseVZpZXdDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy51cGRhdGVIYW5kbGVzKFBvaW50ZXJUeXBlLk1heCwgdGhpcy52YWx1ZVRvUG9zaXRpb24odGhpcy52aWV3SGlnaFZhbHVlKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWF4KSB7XG4gICAgICAgIHRoaXMudmlld0xvd1ZhbHVlID0gTWF0aEhlbHBlci5yb3VuZFRvUHJlY2lzaW9uTGltaXQoXG4gICAgICAgICAgTWF0aC5tYXgobmV3VmFsdWUgLSBtaW5SYW5nZSwgdGhpcy52aWV3T3B0aW9ucy5mbG9vciEpLFxuICAgICAgICAgIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhXG4gICAgICAgICk7XG4gICAgICAgIG5ld1ZhbHVlID0gTWF0aEhlbHBlci5yb3VuZFRvUHJlY2lzaW9uTGltaXQodGhpcy52aWV3TG93VmFsdWUgKyBtaW5SYW5nZSwgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCEpO1xuICAgICAgICB0aGlzLmFwcGx5Vmlld0NoYW5nZSgpO1xuICAgICAgICB0aGlzLnVwZGF0ZUhhbmRsZXMoUG9pbnRlclR5cGUuTWluLCB0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdMb3dWYWx1ZSkpO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVBcmlhQXR0cmlidXRlcygpO1xuICAgIH0gZWxzZSBpZiAoIVZhbHVlSGVscGVyLmlzTnVsbE9yVW5kZWZpbmVkKG1heFJhbmdlKSAmJiBkaWZmZXJlbmNlID4gbWF4UmFuZ2UpIHtcbiAgICAgIC8vIGlmIGdyZWF0ZXIgdGhhbiBtYXhSYW5nZVxuICAgICAgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWluKSB7XG4gICAgICAgIHRoaXMudmlld0hpZ2hWYWx1ZSA9IE1hdGhIZWxwZXIucm91bmRUb1ByZWNpc2lvbkxpbWl0KG5ld1ZhbHVlICsgbWF4UmFuZ2UsIHRoaXMudmlld09wdGlvbnMucHJlY2lzaW9uTGltaXQhKTtcbiAgICAgICAgdGhpcy5hcHBseVZpZXdDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy51cGRhdGVIYW5kbGVzKFBvaW50ZXJUeXBlLk1heCwgdGhpcy52YWx1ZVRvUG9zaXRpb24odGhpcy52aWV3SGlnaFZhbHVlKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlciA9PT0gUG9pbnRlclR5cGUuTWF4KSB7XG4gICAgICAgIHRoaXMudmlld0xvd1ZhbHVlID0gTWF0aEhlbHBlci5yb3VuZFRvUHJlY2lzaW9uTGltaXQobmV3VmFsdWUgLSBtYXhSYW5nZSwgdGhpcy52aWV3T3B0aW9ucy5wcmVjaXNpb25MaW1pdCEpO1xuICAgICAgICB0aGlzLmFwcGx5Vmlld0NoYW5nZSgpO1xuICAgICAgICB0aGlzLnVwZGF0ZUhhbmRsZXMoUG9pbnRlclR5cGUuTWluLCB0aGlzLnZhbHVlVG9Qb3NpdGlvbih0aGlzLnZpZXdMb3dWYWx1ZSkpO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVBcmlhQXR0cmlidXRlcygpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3VmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGdldENoYW5nZUNvbnRleHQoKTogQ2hhbmdlQ29udGV4dCB7XG4gICAgY29uc3QgY2hhbmdlQ29udGV4dDogQ2hhbmdlQ29udGV4dCA9IG5ldyBDaGFuZ2VDb250ZXh0KCk7XG4gICAgY2hhbmdlQ29udGV4dC5wb2ludGVyVHlwZSA9IHRoaXMuY3VycmVudFRyYWNraW5nUG9pbnRlcjtcbiAgICBjaGFuZ2VDb250ZXh0LnZhbHVlID0gK3RoaXMudmFsdWUhO1xuICAgIGlmICh0aGlzLnJhbmdlKSB7XG4gICAgICBjaGFuZ2VDb250ZXh0LmhpZ2hWYWx1ZSA9ICt0aGlzLmhpZ2hWYWx1ZSE7XG4gICAgfVxuICAgIHJldHVybiBjaGFuZ2VDb250ZXh0O1xuICB9XG59XG4iLCI8IS0tIC8vIDAgTGVmdCBzZWxlY3Rpb24gYmFyIG91dHNpZGUgdHdvIGhhbmRsZXMgLS0+XG48c3BhblxuICBuZ3hTbGlkZXJFbGVtZW50XG4gICNsZWZ0T3V0ZXJTZWxlY3Rpb25CYXJcbiAgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci1iYXItd3JhcHBlciBuZ3gtc2xpZGVyLWxlZnQtb3V0LXNlbGVjdGlvblwiXG4+XG4gIDxzcGFuIGNsYXNzPVwibmd4LXNsaWRlci1zcGFuIG5neC1zbGlkZXItYmFyXCI+PC9zcGFuPlxuPC9zcGFuPlxuPCEtLSAvLyAxIFJpZ2h0IHNlbGVjdGlvbiBiYXIgb3V0c2lkZSB0d28gaGFuZGxlcyAtLT5cbjxzcGFuXG4gIG5neFNsaWRlckVsZW1lbnRcbiAgI3JpZ2h0T3V0ZXJTZWxlY3Rpb25CYXJcbiAgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci1iYXItd3JhcHBlciBuZ3gtc2xpZGVyLXJpZ2h0LW91dC1zZWxlY3Rpb25cIlxuPlxuICA8c3BhbiBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJhclwiPjwvc3Bhbj5cbjwvc3Bhbj5cbjwhLS0gLy8gMiBUaGUgd2hvbGUgc2xpZGVyIGJhciAtLT5cbjxzcGFuXG4gIG5neFNsaWRlckVsZW1lbnRcbiAgI2Z1bGxCYXJcbiAgW2NsYXNzLm5neC1zbGlkZXItdHJhbnNwYXJlbnRdPVwiZnVsbEJhclRyYW5zcGFyZW50Q2xhc3NcIlxuICBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJhci13cmFwcGVyIG5neC1zbGlkZXItZnVsbC1iYXJcIlxuPlxuICA8c3BhbiBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJhclwiPjwvc3Bhbj5cbjwvc3Bhbj5cbjwhLS0gLy8gMyBTZWxlY3Rpb24gYmFyIGJldHdlZW4gdHdvIGhhbmRsZXMgLS0+XG48c3BhblxuICBuZ3hTbGlkZXJFbGVtZW50XG4gICNzZWxlY3Rpb25CYXJcbiAgW2NsYXNzLm5neC1zbGlkZXItZHJhZ2dhYmxlXT1cInNlbGVjdGlvbkJhckRyYWdnYWJsZUNsYXNzXCJcbiAgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci1iYXItd3JhcHBlciBuZ3gtc2xpZGVyLXNlbGVjdGlvbi1iYXJcIlxuPlxuICA8c3BhbiBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJhciBuZ3gtc2xpZGVyLXNlbGVjdGlvblwiIFtuZ1N0eWxlXT1cImJhclN0eWxlXCI+PC9zcGFuPlxuPC9zcGFuPlxuPCEtLSAvLyA0IExvdyBzbGlkZXIgaGFuZGxlIC0tPlxuPHNwYW5cbiAgbmd4U2xpZGVySGFuZGxlXG4gICNtaW5IYW5kbGVcbiAgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci1wb2ludGVyIG5neC1zbGlkZXItcG9pbnRlci1taW5cIlxuICBbbmdTdHlsZV09XCJtaW5Qb2ludGVyU3R5bGVcIlxuPjwvc3Bhbj5cbjwhLS0gLy8gNSBIaWdoIHNsaWRlciBoYW5kbGUgLS0+XG48c3BhblxuICBuZ3hTbGlkZXJIYW5kbGVcbiAgI21heEhhbmRsZVxuICBbc3R5bGUuZGlzcGxheV09XCJyYW5nZSA/ICdpbmhlcml0JyA6ICdub25lJ1wiXG4gIGNsYXNzPVwibmd4LXNsaWRlci1zcGFuIG5neC1zbGlkZXItcG9pbnRlciBuZ3gtc2xpZGVyLXBvaW50ZXItbWF4XCJcbiAgW25nU3R5bGVdPVwibWF4UG9pbnRlclN0eWxlXCJcbj48L3NwYW4+XG48IS0tIC8vIDYgRmxvb3IgbGFiZWwgLS0+XG48c3BhbiBuZ3hTbGlkZXJMYWJlbCAjZmxvb3JMYWJlbCBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJ1YmJsZSBuZ3gtc2xpZGVyLWxpbWl0IG5neC1zbGlkZXItZmxvb3JcIj48L3NwYW4+XG48IS0tIC8vIDcgQ2VpbGluZyBsYWJlbCAtLT5cbjxzcGFuIG5neFNsaWRlckxhYmVsICNjZWlsTGFiZWwgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci1idWJibGUgbmd4LXNsaWRlci1saW1pdCBuZ3gtc2xpZGVyLWNlaWxcIj48L3NwYW4+XG48IS0tIC8vIDggTGFiZWwgYWJvdmUgdGhlIGxvdyBzbGlkZXIgaGFuZGxlIC0tPlxuPHNwYW4gbmd4U2xpZGVyTGFiZWwgI21pbkhhbmRsZUxhYmVsIGNsYXNzPVwibmd4LXNsaWRlci1zcGFuIG5neC1zbGlkZXItYnViYmxlIG5neC1zbGlkZXItbW9kZWwtdmFsdWVcIj48L3NwYW4+XG48IS0tIC8vIDkgTGFiZWwgYWJvdmUgdGhlIGhpZ2ggc2xpZGVyIGhhbmRsZSAtLT5cbjxzcGFuIG5neFNsaWRlckxhYmVsICNtYXhIYW5kbGVMYWJlbCBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLWJ1YmJsZSBuZ3gtc2xpZGVyLW1vZGVsLWhpZ2hcIj48L3NwYW4+XG48IS0tIC8vIDEwIENvbWJpbmVkIHJhbmdlIGxhYmVsIHdoZW4gdGhlIHNsaWRlciBoYW5kbGVzIGFyZSBjbG9zZSBleC4gMTUgLSAxNyAtLT5cbjxzcGFuIG5neFNsaWRlckxhYmVsICNjb21iaW5lZExhYmVsIGNsYXNzPVwibmd4LXNsaWRlci1zcGFuIG5neC1zbGlkZXItYnViYmxlIG5neC1zbGlkZXItY29tYmluZWRcIj48L3NwYW4+XG48IS0tIC8vIDExIFRoZSB0aWNrcyAtLT5cbjxzcGFuXG4gIG5neFNsaWRlckVsZW1lbnRcbiAgI3RpY2tzRWxlbWVudFxuICBbaGlkZGVuXT1cIiFzaG93VGlja3NcIlxuICBbY2xhc3Mubmd4LXNsaWRlci10aWNrcy12YWx1ZXMtdW5kZXJdPVwidGlja3NVbmRlclZhbHVlc0NsYXNzXCJcbiAgY2xhc3M9XCJuZ3gtc2xpZGVyLXRpY2tzXCJcbj5cbiAgQGZvciAodCBvZiB0aWNrczsgdHJhY2sgdCkge1xuICAgIDxzcGFuIGNsYXNzPVwibmd4LXNsaWRlci10aWNrXCIgW25nQ2xhc3NdPVwieyAnbmd4LXNsaWRlci1zZWxlY3RlZCc6IHQuc2VsZWN0ZWQgfVwiIFtuZ1N0eWxlXT1cInQuc3R5bGVcIj5cbiAgICAgIDxuZ3gtc2xpZGVyLXRvb2x0aXAtd3JhcHBlclxuICAgICAgICBbdGVtcGxhdGVdPVwidG9vbHRpcFRlbXBsYXRlXCJcbiAgICAgICAgW3Rvb2x0aXBdPVwidC50b29sdGlwXCJcbiAgICAgICAgW3BsYWNlbWVudF09XCJ0LnRvb2x0aXBQbGFjZW1lbnRcIlxuICAgICAgPjwvbmd4LXNsaWRlci10b29sdGlwLXdyYXBwZXI+XG4gICAgICBAaWYgKHQudmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgPG5neC1zbGlkZXItdG9vbHRpcC13cmFwcGVyXG4gICAgICAgICAgY2xhc3M9XCJuZ3gtc2xpZGVyLXNwYW4gbmd4LXNsaWRlci10aWNrLXZhbHVlXCJcbiAgICAgICAgICBbdGVtcGxhdGVdPVwidG9vbHRpcFRlbXBsYXRlXCJcbiAgICAgICAgICBbdG9vbHRpcF09XCJ0LnZhbHVlVG9vbHRpcFwiXG4gICAgICAgICAgW3BsYWNlbWVudF09XCJ0LnZhbHVlVG9vbHRpcFBsYWNlbWVudFwiXG4gICAgICAgICAgW2NvbnRlbnRdPVwidC52YWx1ZVwiXG4gICAgICAgID48L25neC1zbGlkZXItdG9vbHRpcC13cmFwcGVyPlxuICAgICAgfVxuICAgICAgQGlmICh0LmxlZ2VuZCAhPT0gbnVsbCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1zbGlkZXItc3BhbiBuZ3gtc2xpZGVyLXRpY2stbGVnZW5kXCIgW2lubmVySFRNTF09XCJ0LmxlZ2VuZFwiPjwvc3Bhbj5cbiAgICAgIH1cbiAgICA8L3NwYW4+XG4gIH1cbjwvc3Bhbj5cbiJdfQ==
|