@ks89/angular-modal-gallery 8.0.0-rc.1 → 9.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/CHANGELOG.md +123 -0
- package/CONTRIBUTING.md +3 -3
- package/README.md +26 -34
- package/{esm2015/ks89-angular-modal-gallery.js → esm2020/ks89-angular-modal-gallery.mjs} +0 -0
- package/{esm2015/lib/components/accessibility-default.js → esm2020/lib/components/accessibility-default.mjs} +0 -0
- package/{esm2015/lib/components/accessible.component.js → esm2020/lib/components/accessible.component.mjs} +6 -6
- package/esm2020/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +462 -0
- package/esm2020/lib/components/carousel/carousel.component.mjs +747 -0
- package/{esm2015/lib/components/components.js → esm2020/lib/components/components.mjs} +0 -0
- package/esm2020/lib/components/current-image/current-image.component.mjs +616 -0
- package/esm2020/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +80 -0
- package/esm2020/lib/components/dots/dots.component.mjs +127 -0
- package/esm2020/lib/components/modal-gallery/modal-gallery-ref.mjs +103 -0
- package/esm2020/lib/components/modal-gallery/modal-gallery.component.mjs +523 -0
- package/esm2020/lib/components/modal-gallery/modal-gallery.service.mjs +187 -0
- package/esm2020/lib/components/modal-gallery/modal-gallery.tokens.mjs +26 -0
- package/esm2020/lib/components/plain-gallery/plain-gallery.component.mjs +249 -0
- package/esm2020/lib/components/previews/previews.component.mjs +332 -0
- package/{esm2015/lib/components/upper-buttons/upper-buttons-default.js → esm2020/lib/components/upper-buttons/upper-buttons-default.mjs} +0 -0
- package/esm2020/lib/components/upper-buttons/upper-buttons.component.mjs +249 -0
- package/{esm2015/lib/directives/a-tag-bg-image.directive.js → esm2020/lib/directives/a-tag-bg-image.directive.mjs} +3 -3
- package/{esm2015/lib/directives/click-outside.directive.js → esm2020/lib/directives/click-outside.directive.mjs} +3 -3
- package/{esm2015/lib/directives/description.directive.js → esm2020/lib/directives/description.directive.mjs} +3 -3
- package/{esm2015/lib/directives/direction.directive.js → esm2020/lib/directives/direction.directive.mjs} +3 -3
- package/{esm2015/lib/directives/directives.js → esm2020/lib/directives/directives.mjs} +0 -0
- package/esm2020/lib/directives/fallback-image.directive.mjs +59 -0
- package/{esm2015/lib/directives/keyboard-navigation.directive.js → esm2020/lib/directives/keyboard-navigation.directive.mjs} +5 -5
- package/{esm2015/lib/directives/margin.directive.js → esm2020/lib/directives/margin.directive.mjs} +3 -3
- package/{esm2015/lib/directives/max-size.directive.js → esm2020/lib/directives/max-size.directive.mjs} +3 -3
- package/{esm2015/lib/directives/size.directive.js → esm2020/lib/directives/size.directive.mjs} +3 -3
- package/{esm2015/lib/directives/wrap.directive.js → esm2020/lib/directives/wrap.directive.mjs} +6 -6
- package/{esm2015/lib/modal-gallery.module.js → esm2020/lib/modal-gallery.module.mjs} +10 -13
- package/{esm2015/lib/model/accessibility.interface.js → esm2020/lib/model/accessibility.interface.mjs} +0 -0
- package/{esm2015/lib/model/action.enum.js → esm2020/lib/model/action.enum.mjs} +0 -0
- package/esm2020/lib/model/buttons-config.interface.mjs +62 -0
- package/{esm2015/lib/model/carousel-config.interface.js → esm2020/lib/model/carousel-config.interface.mjs} +1 -1
- package/{esm2015/lib/model/carousel-image-config.interface.js → esm2020/lib/model/carousel-image-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/carousel-preview-config.interface.js → esm2020/lib/model/carousel-preview-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/current-image-config.interface.js → esm2020/lib/model/current-image-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/description.interface.js → esm2020/lib/model/description.interface.mjs} +0 -0
- package/{esm2015/lib/model/dots-config.interface.js → esm2020/lib/model/dots-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/image-internal.class.js → esm2020/lib/model/image-internal.class.mjs} +0 -0
- package/{esm2015/lib/model/image.class.js → esm2020/lib/model/image.class.mjs} +0 -0
- package/{esm2015/lib/model/interaction-event.interface.js → esm2020/lib/model/interaction-event.interface.mjs} +0 -0
- package/{esm2015/lib/model/keyboard-config.interface.js → esm2020/lib/model/keyboard-config.interface.mjs} +1 -1
- package/{esm2015/lib/model/keyboard-service-config.interface.js → esm2020/lib/model/keyboard-service-config.interface.mjs} +0 -0
- package/esm2020/lib/model/keyboard.enum.mjs +35 -0
- package/{esm2015/lib/model/lib-config.interface.js → esm2020/lib/model/lib-config.interface.mjs} +1 -1
- package/{esm2015/lib/model/loading-config.interface.js → esm2020/lib/model/loading-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/max-size.interface.js → esm2020/lib/model/max-size.interface.mjs} +0 -0
- package/{esm2015/lib/model/modal-gallery-config.interface.js → esm2020/lib/model/modal-gallery-config.interface.mjs} +1 -1
- package/esm2020/lib/model/plain-gallery-config.interface.mjs +55 -0
- package/{esm2015/lib/model/play-config.interface.js → esm2020/lib/model/play-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/preview-config.interface.js → esm2020/lib/model/preview-config.interface.mjs} +0 -0
- package/{esm2015/lib/model/size.interface.js → esm2020/lib/model/size.interface.mjs} +0 -0
- package/{esm2015/lib/model/slide-config.interface.js → esm2020/lib/model/slide-config.interface.mjs} +0 -0
- package/esm2020/lib/services/config.service.mjs +396 -0
- package/esm2020/lib/services/id-validator.service.mjs +71 -0
- package/{esm2015/lib/services/keyboard.service.js → esm2020/lib/services/keyboard.service.mjs} +3 -3
- package/{esm2015/lib/utils/image.util.js → esm2020/lib/utils/image.util.mjs} +0 -0
- package/esm2020/lib/utils/user-input.util.mjs +104 -0
- package/esm2020/public-api.mjs +42 -0
- package/fesm2015/ks89-angular-modal-gallery.mjs +5782 -0
- package/fesm2015/ks89-angular-modal-gallery.mjs.map +1 -0
- package/{fesm2015/ks89-angular-modal-gallery.js → fesm2020/ks89-angular-modal-gallery.mjs} +521 -544
- package/fesm2020/ks89-angular-modal-gallery.mjs.map +1 -0
- package/lib/components/accessible.component.d.ts +2 -2
- package/lib/components/carousel/carousel-previews/carousel-previews.component.d.ts +0 -7
- package/lib/components/carousel/carousel.component.d.ts +25 -67
- package/lib/components/current-image/current-image.component.d.ts +6 -3
- package/lib/components/dots/dots.component.d.ts +4 -0
- package/lib/components/modal-gallery/modal-gallery-ref.d.ts +35 -0
- package/lib/components/modal-gallery/modal-gallery.component.d.ts +53 -49
- package/lib/components/modal-gallery/modal-gallery.service.d.ts +57 -1
- package/lib/components/plain-gallery/plain-gallery.component.d.ts +16 -10
- package/lib/components/previews/previews.component.d.ts +6 -0
- package/lib/components/upper-buttons/upper-buttons.component.d.ts +5 -1
- package/lib/directives/fallback-image.directive.d.ts +3 -0
- package/lib/directives/keyboard-navigation.directive.d.ts +1 -1
- package/lib/directives/wrap.directive.d.ts +1 -1
- package/lib/model/carousel-config.interface.d.ts +0 -1
- package/lib/model/keyboard-config.interface.d.ts +4 -4
- package/lib/model/keyboard.enum.d.ts +11 -8
- package/lib/model/lib-config.interface.d.ts +20 -7
- package/lib/model/modal-gallery-config.interface.d.ts +2 -2
- package/lib/model/plain-gallery-config.interface.d.ts +1 -9
- package/lib/services/id-validator.service.d.ts +2 -1
- package/lib/utils/user-input.util.d.ts +35 -26
- package/package.json +27 -14
- package/public-api.d.ts +2 -2
- package/bundles/ks89-angular-modal-gallery.umd.js +0 -6067
- package/bundles/ks89-angular-modal-gallery.umd.js.map +0 -1
- package/esm2015/lib/components/carousel/carousel-previews/carousel-previews.component.js +0 -480
- package/esm2015/lib/components/carousel/carousel.component.js +0 -800
- package/esm2015/lib/components/current-image/current-image.component.js +0 -618
- package/esm2015/lib/components/current-image/loading-spinner/loading-spinner.component.js +0 -93
- package/esm2015/lib/components/dots/dots.component.js +0 -132
- package/esm2015/lib/components/modal-gallery/modal-gallery-ref.js +0 -45
- package/esm2015/lib/components/modal-gallery/modal-gallery.component.js +0 -558
- package/esm2015/lib/components/modal-gallery/modal-gallery.service.js +0 -131
- package/esm2015/lib/components/modal-gallery/modal-gallery.tokens.js +0 -3
- package/esm2015/lib/components/plain-gallery/plain-gallery.component.js +0 -253
- package/esm2015/lib/components/previews/previews.component.js +0 -338
- package/esm2015/lib/components/upper-buttons/upper-buttons.component.js +0 -266
- package/esm2015/lib/directives/fallback-image.directive.js +0 -56
- package/esm2015/lib/model/buttons-config.interface.js +0 -66
- package/esm2015/lib/model/keyboard.enum.js +0 -35
- package/esm2015/lib/model/plain-gallery-config.interface.js +0 -64
- package/esm2015/lib/services/config.service.js +0 -395
- package/esm2015/lib/services/id-validator.service.js +0 -73
- package/esm2015/lib/utils/user-input.util.js +0 -95
- package/esm2015/public-api.js +0 -46
- package/fesm2015/ks89-angular-modal-gallery.js.map +0 -1
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
The MIT License (MIT)
|
|
3
|
-
|
|
4
|
-
Copyright (C) 2017-2021 Stefano Cappa (Ks89)
|
|
5
|
-
|
|
6
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
in the Software without restriction, including without limitation the rights
|
|
9
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
furnished to do so, subject to the following conditions:
|
|
12
|
-
|
|
13
|
-
The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
copies or substantial portions of the Software.
|
|
15
|
-
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Inject, Input, Output, PLATFORM_ID } from '@angular/core';
|
|
25
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
26
|
-
import { Subject, timer } from 'rxjs';
|
|
27
|
-
import { filter, map, switchMap, takeUntil } from 'rxjs/operators';
|
|
28
|
-
import { AccessibleComponent } from '../accessible.component';
|
|
29
|
-
import { Action } from '../../model/action.enum';
|
|
30
|
-
import { DescriptionStrategy } from '../../model/description.interface';
|
|
31
|
-
import { ImageModalEvent } from '../../model/image.class';
|
|
32
|
-
import { Keyboard } from '../../model/keyboard.enum';
|
|
33
|
-
import { NEXT, PREV } from '../../utils/user-input.util';
|
|
34
|
-
import { getIndex } from '../../utils/image.util';
|
|
35
|
-
import * as i0 from "@angular/core";
|
|
36
|
-
import * as i1 from "../../services/config.service";
|
|
37
|
-
import * as i2 from "./loading-spinner/loading-spinner.component";
|
|
38
|
-
import * as i3 from "../../directives/keyboard-navigation.directive";
|
|
39
|
-
import * as i4 from "@angular/common";
|
|
40
|
-
import * as i5 from "../../directives/fallback-image.directive";
|
|
41
|
-
import * as i6 from "../../directives/size.directive";
|
|
42
|
-
import * as i7 from "../../directives/description.directive";
|
|
43
|
-
/**
|
|
44
|
-
* Component with the current image with some additional elements like arrows and side previews.
|
|
45
|
-
*/
|
|
46
|
-
export class CurrentImageComponent extends AccessibleComponent {
|
|
47
|
-
// use public ChangeDetectorRef to be able to call it from spec files to trigger change detection
|
|
48
|
-
// tslint:disable-next-line:no-any
|
|
49
|
-
constructor(platformId, ngZone, ref, configService) {
|
|
50
|
-
super();
|
|
51
|
-
this.platformId = platformId;
|
|
52
|
-
this.ngZone = ngZone;
|
|
53
|
-
this.ref = ref;
|
|
54
|
-
this.configService = configService;
|
|
55
|
-
/**
|
|
56
|
-
* Output to emit an event when images are loaded. The payload contains an `ImageLoadEvent`.
|
|
57
|
-
*/
|
|
58
|
-
this.loadImage = new EventEmitter();
|
|
59
|
-
/**
|
|
60
|
-
* Output to emit any changes of the current image. The payload contains an `ImageModalEvent`.
|
|
61
|
-
*/
|
|
62
|
-
this.changeImage = new EventEmitter();
|
|
63
|
-
/**
|
|
64
|
-
* Output to emit an event when the modal gallery is closed. The payload contains an `ImageModalEvent`.
|
|
65
|
-
*/
|
|
66
|
-
this.closeGallery = new EventEmitter();
|
|
67
|
-
/**
|
|
68
|
-
* Subject to play modal-gallery.
|
|
69
|
-
*/
|
|
70
|
-
this.start$ = new Subject();
|
|
71
|
-
/**
|
|
72
|
-
* Subject to stop modal-gallery.
|
|
73
|
-
*/
|
|
74
|
-
this.stop$ = new Subject();
|
|
75
|
-
/**
|
|
76
|
-
* Enum of type `Action` that represents a normal action.
|
|
77
|
-
* Declared here to be used inside the template.
|
|
78
|
-
*/
|
|
79
|
-
this.normalAction = Action.NORMAL;
|
|
80
|
-
/**
|
|
81
|
-
* Enum of type `Action` that represents a mouse click on a button.
|
|
82
|
-
* Declared here to be used inside the template.
|
|
83
|
-
*/
|
|
84
|
-
this.clickAction = Action.CLICK;
|
|
85
|
-
/**
|
|
86
|
-
* Enum of type `Action` that represents a keyboard action.
|
|
87
|
-
* Declared here to be used inside the template.
|
|
88
|
-
*/
|
|
89
|
-
this.keyboardAction = Action.KEYBOARD;
|
|
90
|
-
/**
|
|
91
|
-
* Boolean that it's true when you are watching the first image (currently visible).
|
|
92
|
-
* False by default
|
|
93
|
-
*/
|
|
94
|
-
this.isFirstImage = false;
|
|
95
|
-
/**
|
|
96
|
-
* Boolean that it's true when you are watching the last image (currently visible).
|
|
97
|
-
* False by default
|
|
98
|
-
*/
|
|
99
|
-
this.isLastImage = false;
|
|
100
|
-
/**
|
|
101
|
-
* Boolean that it's true if an image of the modal gallery is still loading.
|
|
102
|
-
* True by default
|
|
103
|
-
*/
|
|
104
|
-
this.loading = true;
|
|
105
|
-
/**
|
|
106
|
-
* Private object without type to define all swipe actions used by hammerjs.
|
|
107
|
-
*/
|
|
108
|
-
this.SWIPE_ACTION = {
|
|
109
|
-
LEFT: 'swipeleft',
|
|
110
|
-
RIGHT: 'swiperight',
|
|
111
|
-
UP: 'swipeup',
|
|
112
|
-
DOWN: 'swipedown'
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Listener to stop the gallery when the mouse pointer is over the current image.
|
|
117
|
-
*/
|
|
118
|
-
onMouseEnter() {
|
|
119
|
-
// if carousel feature is disable, don't do anything in any case
|
|
120
|
-
if (!this.slideConfig || !this.slideConfig.playConfig) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (!this.slideConfig.playConfig.pauseOnHover) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
this.stopCarousel();
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Listener to play the gallery when the mouse pointer leave the current image.
|
|
130
|
-
*/
|
|
131
|
-
onMouseLeave() {
|
|
132
|
-
// if carousel feature is disable, don't do anything in any case
|
|
133
|
-
if (!this.slideConfig || !this.slideConfig.playConfig) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (!this.slideConfig.playConfig.pauseOnHover || !this.slideConfig.playConfig.autoPlay) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
this.playCarousel();
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Method ´ngOnInit´ to init configuration.
|
|
143
|
-
* This is an Angular's lifecycle hook, so its called automatically by Angular itself.
|
|
144
|
-
* In particular, it's called only one time!!!
|
|
145
|
-
*/
|
|
146
|
-
ngOnInit() {
|
|
147
|
-
const libConfig = this.configService.getConfig(this.id);
|
|
148
|
-
if (!libConfig || !libConfig.buttonsConfig) {
|
|
149
|
-
throw new Error('Internal library error - libConfig and buttonsConfig must be defined');
|
|
150
|
-
}
|
|
151
|
-
this.slideConfig = libConfig.slideConfig;
|
|
152
|
-
this.accessibilityConfig = libConfig.accessibilityConfig;
|
|
153
|
-
this.currentImageConfig = libConfig.currentImageConfig;
|
|
154
|
-
this.keyboardConfig = libConfig.keyboardConfig;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Method ´ngOnChanges´ to update `loading` status and emit events.
|
|
158
|
-
* If the gallery is open, then it will also manage boundary arrows and sliding.
|
|
159
|
-
* This is an Angular's lifecycle hook, so its called automatically by Angular itself.
|
|
160
|
-
* In particular, it's called when any data-bound property of a directive changes!!!
|
|
161
|
-
*/
|
|
162
|
-
ngOnChanges(changes) {
|
|
163
|
-
const libConfig = this.configService.getConfig(this.id);
|
|
164
|
-
if (!libConfig) {
|
|
165
|
-
throw new Error('Internal library error - libConfig must be defined');
|
|
166
|
-
}
|
|
167
|
-
const images = changes.images;
|
|
168
|
-
const currentImage = changes.currentImage;
|
|
169
|
-
if (currentImage && currentImage.previousValue !== currentImage.currentValue) {
|
|
170
|
-
this.updateIndexes();
|
|
171
|
-
}
|
|
172
|
-
else if (images && images.previousValue !== images.currentValue) {
|
|
173
|
-
this.updateIndexes();
|
|
174
|
-
}
|
|
175
|
-
const slideConfig = changes.slideConfig;
|
|
176
|
-
if (slideConfig && slideConfig.previousValue !== slideConfig.currentValue) {
|
|
177
|
-
this.slideConfig = libConfig.slideConfig;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
ngAfterContentInit() {
|
|
181
|
-
// interval doesn't play well with SSR and protractor,
|
|
182
|
-
// so we should run it in the browser and outside Angular
|
|
183
|
-
if (isPlatformBrowser(this.platformId)) {
|
|
184
|
-
this.ngZone.runOutsideAngular(() => {
|
|
185
|
-
this.start$
|
|
186
|
-
.pipe(map(() => this.slideConfig && this.slideConfig.playConfig && this.slideConfig.playConfig.autoPlay && this.slideConfig.playConfig.interval),
|
|
187
|
-
// tslint:disable-next-line:no-any
|
|
188
|
-
filter((interval) => interval > 0), switchMap(interval => timer(interval).pipe(takeUntil(this.stop$))))
|
|
189
|
-
.subscribe(() => this.ngZone.run(() => {
|
|
190
|
-
if (!this.isLastImage) {
|
|
191
|
-
this.nextImage(Action.AUTOPLAY);
|
|
192
|
-
}
|
|
193
|
-
this.ref.markForCheck();
|
|
194
|
-
}));
|
|
195
|
-
this.start$.next();
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Method to handle keypress based on the `keyboardConfig` input. It gets the keyCode of
|
|
201
|
-
* the key that triggered the keypress event to navigate between images or to close the modal gallery.
|
|
202
|
-
* @param number keyCode of the key that triggered the keypress event
|
|
203
|
-
*/
|
|
204
|
-
onKeyPress(keyCode) {
|
|
205
|
-
const esc = this.keyboardConfig && this.keyboardConfig.esc ? this.keyboardConfig.esc : Keyboard.ESC;
|
|
206
|
-
const right = this.keyboardConfig && this.keyboardConfig.right ? this.keyboardConfig.right : Keyboard.RIGHT_ARROW;
|
|
207
|
-
const left = this.keyboardConfig && this.keyboardConfig.left ? this.keyboardConfig.left : Keyboard.LEFT_ARROW;
|
|
208
|
-
switch (keyCode) {
|
|
209
|
-
case esc:
|
|
210
|
-
this.closeGallery.emit(new ImageModalEvent(this.id, Action.KEYBOARD, true));
|
|
211
|
-
break;
|
|
212
|
-
case right:
|
|
213
|
-
this.nextImage(Action.KEYBOARD);
|
|
214
|
-
break;
|
|
215
|
-
case left:
|
|
216
|
-
this.prevImage(Action.KEYBOARD);
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Method to get the image description based on input params.
|
|
222
|
-
* If you provide a full description this will be the visible description, otherwise,
|
|
223
|
-
* it will be built using the `Description` object, concatenating its fields.
|
|
224
|
-
* @param Image image to get its description. If not provided it will be the current image
|
|
225
|
-
* @returns String description of the image (or the current image if not provided)
|
|
226
|
-
* @throws an Error if description isn't available
|
|
227
|
-
*/
|
|
228
|
-
getDescriptionToDisplay(image = this.currentImage) {
|
|
229
|
-
if (!this.currentImageConfig || !this.currentImageConfig.description) {
|
|
230
|
-
throw new Error('Description input must be a valid object implementing the Description interface');
|
|
231
|
-
}
|
|
232
|
-
const imageWithoutDescription = !image.modal || !image.modal.description || image.modal.description === '';
|
|
233
|
-
switch (this.currentImageConfig.description.strategy) {
|
|
234
|
-
case DescriptionStrategy.HIDE_IF_EMPTY:
|
|
235
|
-
return imageWithoutDescription ? '' : image.modal.description + '';
|
|
236
|
-
case DescriptionStrategy.ALWAYS_HIDDEN:
|
|
237
|
-
return '';
|
|
238
|
-
default:
|
|
239
|
-
// ----------- DescriptionStrategy.ALWAYS_VISIBLE -----------------
|
|
240
|
-
return this.buildTextDescription(image, imageWithoutDescription);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Method to get `alt attribute`.
|
|
245
|
-
* `alt` specifies an alternate text for an image, if the image cannot be displayed.
|
|
246
|
-
* @param Image image to get its alt description. If not provided it will be the current image
|
|
247
|
-
* @returns String alt description of the image (or the current image if not provided)
|
|
248
|
-
*/
|
|
249
|
-
getAltDescriptionByImage(image = this.currentImage) {
|
|
250
|
-
if (!image) {
|
|
251
|
-
return '';
|
|
252
|
-
}
|
|
253
|
-
return image.modal && image.modal.description ? image.modal.description : `Image ${getIndex(image, this.images) + 1}`;
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Method to get the title attributes based on descriptions.
|
|
257
|
-
* This is useful to prevent accessibility issues, because if DescriptionStrategy is ALWAYS_HIDDEN,
|
|
258
|
-
* it prevents an empty string as title.
|
|
259
|
-
* @param Image image to get its description. If not provided it will be the current image
|
|
260
|
-
* @returns String title of the image based on descriptions
|
|
261
|
-
* @throws an Error if description isn't available
|
|
262
|
-
*/
|
|
263
|
-
getTitleToDisplay(image = this.currentImage) {
|
|
264
|
-
if (!this.currentImageConfig || !this.currentImageConfig.description) {
|
|
265
|
-
throw new Error('Description input must be a valid object implementing the Description interface');
|
|
266
|
-
}
|
|
267
|
-
const imageWithoutDescription = !image.modal || !image.modal.description || image.modal.description === '';
|
|
268
|
-
const description = this.buildTextDescription(image, imageWithoutDescription);
|
|
269
|
-
return description;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Method to get the left side preview image.
|
|
273
|
-
* @returns Image the image to show as size preview on the left
|
|
274
|
-
*/
|
|
275
|
-
getLeftPreviewImage() {
|
|
276
|
-
if (!this.slideConfig) {
|
|
277
|
-
throw new Error('Internal library error - slideConfig must be defined');
|
|
278
|
-
}
|
|
279
|
-
const currentIndex = getIndex(this.currentImage, this.images);
|
|
280
|
-
if (currentIndex === 0 && this.slideConfig.infinite) {
|
|
281
|
-
// the current image is the first one,
|
|
282
|
-
// so the previous one is the last image
|
|
283
|
-
// because infinite is true
|
|
284
|
-
return this.images[this.images.length - 1];
|
|
285
|
-
}
|
|
286
|
-
this.handleBoundaries(currentIndex);
|
|
287
|
-
return this.images[Math.max(currentIndex - 1, 0)];
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Method to get the right side preview image.
|
|
291
|
-
* @returns Image the image to show as size preview on the right
|
|
292
|
-
*/
|
|
293
|
-
getRightPreviewImage() {
|
|
294
|
-
if (!this.slideConfig) {
|
|
295
|
-
throw new Error('Internal library error - slideConfig must be defined');
|
|
296
|
-
}
|
|
297
|
-
const currentIndex = getIndex(this.currentImage, this.images);
|
|
298
|
-
if (currentIndex === this.images.length - 1 && this.slideConfig.infinite) {
|
|
299
|
-
// the current image is the last one,
|
|
300
|
-
// so the next one is the first image
|
|
301
|
-
// because infinite is true
|
|
302
|
-
return this.images[0];
|
|
303
|
-
}
|
|
304
|
-
this.handleBoundaries(currentIndex);
|
|
305
|
-
return this.images[Math.min(currentIndex + 1, this.images.length - 1)];
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Method called by events from both keyboard and mouse on an image.
|
|
309
|
-
* This will invoke the nextImage method.
|
|
310
|
-
* @param KeyboardEvent | MouseEvent event payload
|
|
311
|
-
* @param Action action that triggered the event or `Action.NORMAL` if not provided
|
|
312
|
-
*/
|
|
313
|
-
onImageEvent(event, action = Action.NORMAL) {
|
|
314
|
-
if (!this.currentImageConfig) {
|
|
315
|
-
throw new Error('Internal library error - currentImageConfig must be defined');
|
|
316
|
-
}
|
|
317
|
-
// check if triggered by a mouse click
|
|
318
|
-
// If yes, It should block navigation when navigateOnClick is false
|
|
319
|
-
if (action === Action.CLICK && !this.currentImageConfig.navigateOnClick) {
|
|
320
|
-
// a user has requested to block navigation via configCurrentImage.navigateOnClick property
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
const result = super.handleImageEvent(event);
|
|
324
|
-
if (result === NEXT) {
|
|
325
|
-
this.nextImage(action);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Method called by events from both keyboard and mouse on a navigation arrow.
|
|
330
|
-
* @param string direction of the navigation that can be either 'next' or 'prev'
|
|
331
|
-
* @param KeyboardEvent | MouseEvent event payload
|
|
332
|
-
* @param Action action that triggered the event or `Action.NORMAL` if not provided
|
|
333
|
-
* @param boolean disable to disable navigation
|
|
334
|
-
*/
|
|
335
|
-
onNavigationEvent(direction, event, action = Action.NORMAL, disable = false) {
|
|
336
|
-
if (disable) {
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
const result = super.handleNavigationEvent(direction, event);
|
|
340
|
-
if (result === NEXT) {
|
|
341
|
-
this.nextImage(action);
|
|
342
|
-
}
|
|
343
|
-
else if (result === PREV) {
|
|
344
|
-
this.prevImage(action);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Method to go back to the previous image.
|
|
349
|
-
* @param action Enum of type `Action` that represents the source
|
|
350
|
-
* action that moved back to the previous image. `Action.NORMAL` by default.
|
|
351
|
-
*/
|
|
352
|
-
prevImage(action = Action.NORMAL) {
|
|
353
|
-
// check if prevImage should be blocked
|
|
354
|
-
if (this.isPreventSliding(0)) {
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
const prevImage = this.getPrevImage();
|
|
358
|
-
this.loading = !prevImage.previouslyLoaded;
|
|
359
|
-
this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(prevImage, this.images)));
|
|
360
|
-
this.start$.next();
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Method to go back to the previous image.
|
|
364
|
-
* @param action Enum of type `Action` that represents the source
|
|
365
|
-
* action that moved to the next image. `Action.NORMAL` by default.
|
|
366
|
-
*/
|
|
367
|
-
nextImage(action = Action.NORMAL) {
|
|
368
|
-
// check if nextImage should be blocked
|
|
369
|
-
if (this.isPreventSliding(this.images.length - 1)) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
const nextImage = this.getNextImage();
|
|
373
|
-
this.loading = !nextImage.previouslyLoaded;
|
|
374
|
-
this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(nextImage, this.images)));
|
|
375
|
-
this.start$.next();
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Method to emit an event as loadImage output to say that the requested image if loaded.
|
|
379
|
-
* This method is invoked by the javascript's 'load' event on an img tag.
|
|
380
|
-
* @param Event event that triggered the load
|
|
381
|
-
*/
|
|
382
|
-
onImageLoad(event) {
|
|
383
|
-
const loadImageData = {
|
|
384
|
-
status: true,
|
|
385
|
-
index: getIndex(this.currentImage, this.images),
|
|
386
|
-
id: this.currentImage.id
|
|
387
|
-
};
|
|
388
|
-
this.loadImage.emit(loadImageData);
|
|
389
|
-
this.loading = false;
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Method used by Hammerjs to support touch gestures (you can also invert the swipe direction with configCurrentImage.invertSwipe).
|
|
393
|
-
* @param action String that represent the direction of the swipe action. 'swiperight' by default.
|
|
394
|
-
*/
|
|
395
|
-
swipe(action = this.SWIPE_ACTION.RIGHT) {
|
|
396
|
-
if (!this.currentImageConfig) {
|
|
397
|
-
throw new Error('Internal library error - currentImageConfig must be defined');
|
|
398
|
-
}
|
|
399
|
-
switch (action) {
|
|
400
|
-
case this.SWIPE_ACTION.RIGHT:
|
|
401
|
-
if (this.currentImageConfig.invertSwipe) {
|
|
402
|
-
this.prevImage(Action.SWIPE);
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
this.nextImage(Action.SWIPE);
|
|
406
|
-
}
|
|
407
|
-
break;
|
|
408
|
-
case this.SWIPE_ACTION.LEFT:
|
|
409
|
-
if (this.currentImageConfig.invertSwipe) {
|
|
410
|
-
this.nextImage(Action.SWIPE);
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
this.prevImage(Action.SWIPE);
|
|
414
|
-
}
|
|
415
|
-
break;
|
|
416
|
-
// case this.SWIPE_ACTION.UP:
|
|
417
|
-
// break;
|
|
418
|
-
// case this.SWIPE_ACTION.DOWN:
|
|
419
|
-
// break;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Method used in `modal-gallery.component` to get the index of an image to delete.
|
|
424
|
-
* @param Image image to get the index, or the visible image, if not passed
|
|
425
|
-
* @returns number the index of the image
|
|
426
|
-
*/
|
|
427
|
-
getIndexToDelete(image = this.currentImage) {
|
|
428
|
-
return getIndex(image, this.images);
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Method to play modal gallery.
|
|
432
|
-
*/
|
|
433
|
-
playCarousel() {
|
|
434
|
-
this.start$.next();
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Stops modal gallery from cycling through items.
|
|
438
|
-
*/
|
|
439
|
-
stopCarousel() {
|
|
440
|
-
this.stop$.next();
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Method to cleanup resources. In fact, this will stop the modal gallery.
|
|
444
|
-
* This is an Angular's lifecycle hook that is called when this component is destroyed.
|
|
445
|
-
*/
|
|
446
|
-
ngOnDestroy() {
|
|
447
|
-
this.stopCarousel();
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Private method to update both `isFirstImage` and `isLastImage` based on
|
|
451
|
-
* the index of the current image.
|
|
452
|
-
* @param number currentIndex is the index of the current image
|
|
453
|
-
*/
|
|
454
|
-
handleBoundaries(currentIndex) {
|
|
455
|
-
if (this.images.length === 1) {
|
|
456
|
-
this.isFirstImage = true;
|
|
457
|
-
this.isLastImage = true;
|
|
458
|
-
this.ref.markForCheck();
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
if (!this.slideConfig || this.slideConfig.infinite === true) {
|
|
462
|
-
// infinite sliding enabled
|
|
463
|
-
this.isFirstImage = false;
|
|
464
|
-
this.isLastImage = false;
|
|
465
|
-
this.ref.markForCheck();
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
// execute this only if infinite sliding is disabled
|
|
469
|
-
switch (currentIndex) {
|
|
470
|
-
case 0:
|
|
471
|
-
this.isFirstImage = true;
|
|
472
|
-
this.isLastImage = false;
|
|
473
|
-
this.ref.markForCheck();
|
|
474
|
-
break;
|
|
475
|
-
case this.images.length - 1:
|
|
476
|
-
this.isFirstImage = false;
|
|
477
|
-
this.isLastImage = true;
|
|
478
|
-
this.ref.markForCheck();
|
|
479
|
-
break;
|
|
480
|
-
default:
|
|
481
|
-
this.isFirstImage = false;
|
|
482
|
-
this.isLastImage = false;
|
|
483
|
-
this.ref.markForCheck();
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* Private method to check if next/prev actions should be blocked.
|
|
490
|
-
* It checks if slideConfig.infinite === false and if the image index is equals to the input parameter.
|
|
491
|
-
* If yes, it returns true to say that sliding should be blocked, otherwise not.
|
|
492
|
-
* @param number boundaryIndex that could be either the beginning index (0) or the last index
|
|
493
|
-
* of images (this.images.length - 1).
|
|
494
|
-
* @returns boolean true if slideConfig.infinite === false and the current index is
|
|
495
|
-
* either the first or the last one.
|
|
496
|
-
*/
|
|
497
|
-
isPreventSliding(boundaryIndex) {
|
|
498
|
-
return !!this.slideConfig && this.slideConfig.infinite === false && getIndex(this.currentImage, this.images) === boundaryIndex;
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Private method to get the next index.
|
|
502
|
-
* This is necessary because at the end, when you call next again, you'll go to the first image.
|
|
503
|
-
* That happens because all modal images are shown like in a circle.
|
|
504
|
-
*/
|
|
505
|
-
getNextImage() {
|
|
506
|
-
const currentIndex = getIndex(this.currentImage, this.images);
|
|
507
|
-
let newIndex = 0;
|
|
508
|
-
if (currentIndex >= 0 && currentIndex < this.images.length - 1) {
|
|
509
|
-
newIndex = currentIndex + 1;
|
|
510
|
-
}
|
|
511
|
-
else {
|
|
512
|
-
newIndex = 0; // start from the first index
|
|
513
|
-
}
|
|
514
|
-
return this.images[newIndex];
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* Private method to get the previous index.
|
|
518
|
-
* This is necessary because at index 0, when you call prev again, you'll go to the last image.
|
|
519
|
-
* That happens because all modal images are shown like in a circle.
|
|
520
|
-
*/
|
|
521
|
-
getPrevImage() {
|
|
522
|
-
const currentIndex = getIndex(this.currentImage, this.images);
|
|
523
|
-
let newIndex = 0;
|
|
524
|
-
if (currentIndex > 0 && currentIndex <= this.images.length - 1) {
|
|
525
|
-
newIndex = currentIndex - 1;
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
newIndex = this.images.length - 1; // start from the last index
|
|
529
|
-
}
|
|
530
|
-
return this.images[newIndex];
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Private method to build a text description.
|
|
534
|
-
* This is used also to create titles.
|
|
535
|
-
* @param Image image to get its description. If not provided it will be the current image.
|
|
536
|
-
* @param boolean imageWithoutDescription is a boolean that it's true if the image hasn't a 'modal' description.
|
|
537
|
-
* @returns String description built concatenating image fields with a specific logic.
|
|
538
|
-
*/
|
|
539
|
-
buildTextDescription(image, imageWithoutDescription) {
|
|
540
|
-
if (!this.currentImageConfig || !this.currentImageConfig.description) {
|
|
541
|
-
throw new Error('Description input must be a valid object implementing the Description interface');
|
|
542
|
-
}
|
|
543
|
-
// If customFullDescription use it, otherwise proceed to build a description
|
|
544
|
-
if (this.currentImageConfig.description.customFullDescription && this.currentImageConfig.description.customFullDescription !== '') {
|
|
545
|
-
return this.currentImageConfig.description.customFullDescription;
|
|
546
|
-
}
|
|
547
|
-
const currentIndex = getIndex(image, this.images);
|
|
548
|
-
// If the current image hasn't a description,
|
|
549
|
-
// prevent to write the ' - ' (or this.description.beforeTextDescription)
|
|
550
|
-
const prevDescription = this.currentImageConfig.description.imageText ? this.currentImageConfig.description.imageText : '';
|
|
551
|
-
const midSeparator = this.currentImageConfig.description.numberSeparator ? this.currentImageConfig.description.numberSeparator : '';
|
|
552
|
-
const middleDescription = currentIndex + 1 + midSeparator + this.images.length;
|
|
553
|
-
if (imageWithoutDescription) {
|
|
554
|
-
return prevDescription + middleDescription;
|
|
555
|
-
}
|
|
556
|
-
const currImgDescription = image.modal && image.modal.description ? image.modal.description : '';
|
|
557
|
-
const endDescription = this.currentImageConfig.description.beforeTextDescription + currImgDescription;
|
|
558
|
-
return prevDescription + middleDescription + endDescription;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Private method to call handleBoundaries when ngOnChanges is called.
|
|
562
|
-
*/
|
|
563
|
-
updateIndexes() {
|
|
564
|
-
try {
|
|
565
|
-
if (this.isOpen) {
|
|
566
|
-
const index = getIndex(this.currentImage, this.images);
|
|
567
|
-
this.handleBoundaries(index);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
catch (err) {
|
|
571
|
-
console.error('Cannot get the current image index in current-image');
|
|
572
|
-
throw err;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
CurrentImageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: CurrentImageComponent, deps: [{ token: PLATFORM_ID }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i1.ConfigService }], target: i0.ɵɵFactoryTarget.Component });
|
|
577
|
-
CurrentImageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.3", type: CurrentImageComponent, selector: "ks-current-image", inputs: { id: "id", currentImage: "currentImage", images: "images", isOpen: "isOpen" }, outputs: { loadImage: "loadImage", changeImage: "changeImage", closeGallery: "closeGallery" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<main class=\"main-image-container\"\n ksKeyboardNavigation [isOpen]=\"isOpen\" (keyboardNavigation)=\"onKeyPress($event)\"\n [attr.aria-label]=\"accessibilityConfig?.mainContainerAriaLabel\"\n [title]=\"accessibilityConfig?.mainContainerTitle\">\n\n <div class=\"left-sub-container\">\n <a class=\"nav-left {{isFirstImage ? 'no-pointer' : ''}}\"\n [attr.aria-label]=\"accessibilityConfig?.mainPrevImageAriaLabel\"\n [tabIndex]=\"isFirstImage ? -1 : 0\" role=\"button\"\n (click)=\"onNavigationEvent('left', $event)\" (keyup)=\"onNavigationEvent('left', $event)\">\n <div class=\"inside {{isFirstImage ? 'empty-arrow-image' : 'left-arrow-image'}}\"\n aria-hidden=\"true\"\n [title]=\"isFirstImage ? '' : accessibilityConfig?.mainPrevImageTitle\"></div>\n </a>\n\n <ng-container *ngIf=\"slideConfig?.sidePreviews?.show\">\n <ng-container *ngIf=\"getLeftPreviewImage() as leftPreview\">\n <img *ngIf=\"!isFirstImage; else firstImage\"\n class=\"inside current-image-previous\"\n [src]=\"leftPreview.plain?.img ? leftPreview.plain?.img : leftPreview.modal.img\"\n ksFallbackImage [fallbackImg]=\"leftPreview.plain?.fallbackImg ? leftPreview.plain?.fallbackImg : leftPreview.modal.fallbackImg\"\n [hidden]=\"loading\"\n ksSize [sizeConfig]=\"{width: slideConfig?.sidePreviews?.size.width, height: slideConfig?.sidePreviews?.size.height}\"\n [attr.aria-label]=\"leftPreview.modal.ariaLabel\"\n [title]=\"(leftPreview.modal.title || leftPreview.modal.title === '') ? leftPreview.modal.title : getDescriptionToDisplay(leftPreview)\"\n alt=\"{{leftPreview.modal.alt ? leftPreview.modal.alt : getAltDescriptionByImage(leftPreview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onNavigationEvent('left', $event, clickAction)\" (keyup)=\"onNavigationEvent('left', $event, keyboardAction)\"/>\n <ng-template #firstImage>\n <div class=\"current-image-previous hidden\"\n ksSize [sizeConfig]=\"{width: slideConfig?.sidePreviews?.size.width, height: slideConfig?.sidePreviews?.size.height}\"></div>\n </ng-template>\n </ng-container>\n </ng-container>\n </div>\n\n\n <figure id=\"current-figure\" [style.display]=\"loading ? 'none' : ''\">\n <img id=\"current-image\"\n class=\"inside\"\n [ngClass]=\"currentImageConfig?.navigateOnClick ? '' : 'unclickable'\"\n [src]=\"currentImage.modal.img\"\n ksFallbackImage [fallbackImg]=\"currentImage.modal.fallbackImg\"\n [attr.aria-label]=\"currentImage.modal.ariaLabel\"\n [title]=\"(currentImage.modal.title || currentImage.modal.title === '') ? currentImage.modal.title : getTitleToDisplay()\"\n alt=\"{{currentImage.modal.alt ? currentImage.modal.alt : getAltDescriptionByImage()}}\"\n [tabIndex]=\"0\" role=\"img\"\n (load)=\"onImageLoad($event)\"\n (click)=\"onImageEvent($event, clickAction)\" (keyup)=\"onImageEvent($event, keyboardAction)\"\n (swipeleft)=\"swipe($event.type)\"\n (swiperight)=\"swipe($event.type)\"/>\n <figcaption *ngIf=\"getDescriptionToDisplay() !== ''\"\n class=\"inside description\"\n ksDescription [description]=\"currentImageConfig?.description\"\n [innerHTML]=\"getDescriptionToDisplay()\">\n </figcaption>\n </figure>\n\n <div class=\"right-sub-container\">\n <ng-container *ngIf=\"slideConfig?.sidePreviews?.show\">\n <ng-container *ngIf=\"getRightPreviewImage() as rightPreview\">\n <img *ngIf=\"!isLastImage; else lastImage\"\n class=\"inside current-image-next\"\n [src]=\"rightPreview.plain?.img ? rightPreview.plain?.img : rightPreview.modal.img\"\n ksFallbackImage [fallbackImg]=\"rightPreview.plain?.fallbackImg ? rightPreview.plain?.fallbackImg : rightPreview.modal.fallbackImg\"\n [hidden]=\"loading\"\n ksSize [sizeConfig]=\"{width: slideConfig?.sidePreviews?.size.width, height: slideConfig?.sidePreviews?.size.height}\"\n [attr.aria-label]=\"rightPreview.modal.ariaLabel\"\n [title]=\"(rightPreview.modal.title || rightPreview.modal.title === '') ? rightPreview.modal.title : getDescriptionToDisplay(rightPreview)\"\n alt=\"{{rightPreview.modal.alt ? rightPreview.modal.alt : getAltDescriptionByImage(rightPreview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onNavigationEvent('right', $event, clickAction)\" (keyup)=\"onNavigationEvent('right', $event, keyboardAction)\"/>\n <ng-template #lastImage>\n <div class=\"current-image-next hidden\"\n ksSize [sizeConfig]=\"{width: slideConfig?.sidePreviews?.size.width, height: slideConfig?.sidePreviews?.size.height}\">\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"loading && currentImageConfig?.loadingConfig?.enable\">\n <ks-loading-spinner [loadingConfig]=\"currentImageConfig?.loadingConfig\"\n [accessibilityConfig]=\"accessibilityConfig\"></ks-loading-spinner>\n </ng-container>\n\n <a class=\"nav-right {{isFirstImage ? 'no-pointer' : ''}}\"\n [attr.aria-label]=\"accessibilityConfig?.mainNextImageAriaLabel\"\n [tabIndex]=\"isLastImage ? -1 : 0\" role=\"button\"\n (click)=\"onNavigationEvent('right', $event)\" (keyup)=\"onNavigationEvent('right', $event)\">\n <div class=\"inside {{isLastImage ? 'empty-arrow-image' : 'right-arrow-image'}}\"\n aria-hidden=\"true\"\n [title]=\"isLastImage ? '' : accessibilityConfig?.mainNextImageTitle\"></div>\n </a>\n </div>\n</main>\n", styles: [":host{display:flex;flex-direction:column;justify-content:center}.main-image-container{display:flex;flex-direction:row;align-items:center;justify-content:space-between}.main-image-container .nav,.main-image-container>.left-sub-container>.nav-left,.main-image-container>.right-sub-container>.nav-right{animation:animatezoom 1s;cursor:pointer;transition:all .5s}.main-image-container .nav:hover,.main-image-container>.left-sub-container>.nav-left:hover,.main-image-container>.right-sub-container>.nav-right:hover{transform:scale(1.1)}.main-image-container>.left-sub-container{display:flex;flex-direction:row;justify-content:space-around;align-items:center}.main-image-container>.left-sub-container>.nav-left{margin-right:5px;margin-left:15px}.main-image-container>.left-sub-container>.nav-left.no-pointer{cursor:default!important}.main-image-container>.right-sub-container{display:flex;flex-direction:row;justify-content:space-around;align-items:center}.main-image-container>.right-sub-container>.nav-right{margin-right:15px;margin-left:5px}.main-image-container>.right-sub-container>.nav-right.no-pointer{cursor:default!important}.main-image-container #current-figure{animation:fadein-visible .8s;text-align:center;margin:0;position:relative}.main-image-container #current-figure>#current-image{max-width:100%;height:auto;display:block}.main-image-container #current-figure>#current-image.unclickable{cursor:not-allowed}.main-image-container #current-figure figcaption{padding:10px;position:absolute;bottom:0;left:0;right:0}.main-image-container #current-figure figcaption .description{font-weight:700;text-align:center}#current-image{height:auto;max-width:80vw;max-height:60vh;cursor:pointer}@media screen and (min-width:70vw){#current-image{max-width:70vw}}@keyframes fadein-visible{0%{opacity:0}to{opacity:1}}@keyframes fadein-semi-visible05{0%{opacity:0}to{opacity:.5}}@keyframes fadein-semi-visible08{0%{opacity:0}to{opacity:.8}}@keyframes fadein-semi-visible09{0%{opacity:0}to{opacity:.9}}", ".arrow-image,.empty-arrow-image,.left-arrow-image,.right-arrow-image{width:30px;height:30px;background-size:30px}.empty-arrow-image{background:#000;opacity:0}.left-arrow-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");opacity:.8;transition:all .5s}.left-arrow-image:hover{transform:scale(1.2)}.right-arrow-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");opacity:.8;transition:all .5s}.right-arrow-image:hover{transform:scale(1.2)}", "@media only screen and (max-device-width:1024px),only screen and (max-width:1024px){.current-image-next,.current-image-previous{display:none}}@media only screen and (min-device-width:1025px){.current-image-next,.current-image-preview,.current-image-previous{height:auto;cursor:pointer;opacity:.5;animation:fadein-semi-visible05 .8s;filter:alpha(opacity=50)}.current-image-next:hover,.current-image-preview:hover,.current-image-previous:hover{opacity:1;transition-property:opacity;transition:all .5s ease}.current-image-previous{margin-left:10px;margin-right:5px}.current-image-next{margin-right:10px;margin-left:5px}}@keyframes fadein-semi-visible05{0%{opacity:0}to{opacity:.5}}"], components: [{ type: i2.LoadingSpinnerComponent, selector: "ks-loading-spinner", inputs: ["loadingConfig", "accessibilityConfig"] }], directives: [{ type: i3.KeyboardNavigationDirective, selector: "[ksKeyboardNavigation]", inputs: ["isOpen"], outputs: ["keyboardNavigation"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.FallbackImageDirective, selector: "[ksFallbackImage]", inputs: ["fallbackImg"], outputs: ["fallbackApplied"] }, { type: i6.SizeDirective, selector: "[ksSize]", inputs: ["sizeConfig"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i7.DescriptionDirective, selector: "[ksDescription]", inputs: ["description"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
578
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: CurrentImageComponent, decorators: [{
|
|
579
|
-
type: Component,
|
|
580
|
-
args: [{
|
|
581
|
-
selector: 'ks-current-image',
|
|
582
|
-
styleUrls: ['current-image.scss', '../image-arrows.scss', 'current-image-previews.scss'],
|
|
583
|
-
templateUrl: 'current-image.html',
|
|
584
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
585
|
-
}]
|
|
586
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
587
|
-
type: Inject,
|
|
588
|
-
args: [PLATFORM_ID]
|
|
589
|
-
}] }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i1.ConfigService }]; }, propDecorators: {
|
|
590
|
-
// @ts-ignore
|
|
591
|
-
id: [{
|
|
592
|
-
type: Input
|
|
593
|
-
}],
|
|
594
|
-
// @ts-ignore
|
|
595
|
-
currentImage: [{
|
|
596
|
-
type: Input
|
|
597
|
-
}],
|
|
598
|
-
// @ts-ignore
|
|
599
|
-
images: [{
|
|
600
|
-
type: Input
|
|
601
|
-
}],
|
|
602
|
-
// @ts-ignore
|
|
603
|
-
isOpen: [{
|
|
604
|
-
type: Input
|
|
605
|
-
}], loadImage: [{
|
|
606
|
-
type: Output
|
|
607
|
-
}], changeImage: [{
|
|
608
|
-
type: Output
|
|
609
|
-
}], closeGallery: [{
|
|
610
|
-
type: Output
|
|
611
|
-
}], onMouseEnter: [{
|
|
612
|
-
type: HostListener,
|
|
613
|
-
args: ['mouseenter']
|
|
614
|
-
}], onMouseLeave: [{
|
|
615
|
-
type: HostListener,
|
|
616
|
-
args: ['mouseleave']
|
|
617
|
-
}] } });
|
|
618
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VycmVudC1pbWFnZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rczg5L2FuZ3VsYXItbW9kYWwtZ2FsbGVyeS9zcmMvbGliL2NvbXBvbmVudHMvY3VycmVudC1pbWFnZS9jdXJyZW50LWltYWdlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tzODkvYW5ndWxhci1tb2RhbC1nYWxsZXJ5L3NyYy9saWIvY29tcG9uZW50cy9jdXJyZW50LWltYWdlL2N1cnJlbnQtaW1hZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFLTCxNQUFNLEVBQ04sV0FBVyxFQUdaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXBELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUc5RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDeEUsT0FBTyxFQUFTLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRWpFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUlyRCxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxN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LEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1lBQ3JFLE1BQU0sR0FBRyxDQUFDO1NBQ1g7SUFDSCxDQUFDOztrSEEzbUJVLHFCQUFxQixrQkFtSFosV0FBVztzR0FuSHBCLHFCQUFxQixvWENuRmxDLHFzTEErRkE7MkZEWmEscUJBQXFCO2tCQU5qQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixFQUFFLHNCQUFzQixFQUFFLDZCQUE2QixDQUFDO29CQUN4RixXQUFXLEVBQUUsb0JBQW9CO29CQUNqQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtpQkFDaEQ7OzBCQW9IYyxNQUFNOzJCQUFDLFdBQVc7O1FBN0cvQixhQUFhO1FBQ2IsRUFBRTtzQkFGRCxLQUFLOztRQU9OLGFBQWE7UUFDYixZQUFZO3NCQUZYLEtBQUs7O1FBUU4sYUFBYTtRQUNiLE1BQU07c0JBRkwsS0FBSzs7UUFRTixhQUFhO1FBQ2IsTUFBTTtzQkFGTCxLQUFLO2dCQVFOLFNBQVM7c0JBRFIsTUFBTTtnQkFNUCxXQUFXO3NCQURWLE1BQU07Z0JBTVAsWUFBWTtzQkFEWCxNQUFNO2dCQWlGUCxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWTtnQkFnQjFCLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcblxuIENvcHlyaWdodCAoQykgMjAxNy0yMDIxIFN0ZWZhbm8gQ2FwcGEgKEtzODkpXG5cbiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cbiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTiBJTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUExBVEZPUk1fSUQsXG4gIFNpbXBsZUNoYW5nZSxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgU3ViamVjdCwgdGltZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQWNjZXNzaWJsZUNvbXBvbmVudCB9IGZyb20gJy4uL2FjY2Vzc2libGUuY29tcG9uZW50JztcblxuaW1wb3J0IHsgQWNjZXNzaWJpbGl0eUNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVsL2FjY2Vzc2liaWxpdHkuaW50ZXJmYWNlJztcbmltcG9ydCB7IEFjdGlvbiB9IGZyb20gJy4uLy4uL21vZGVsL2FjdGlvbi5lbnVtJztcbmltcG9ydCB7IERlc2NyaXB0aW9uU3RyYXRlZ3kgfSBmcm9tICcuLi8uLi9tb2RlbC9kZXNjcmlwdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSW1hZ2UsIEltYWdlTW9kYWxFdmVudCB9IGZyb20gJy4uLy4uL21vZGVsL2ltYWdlLmNsYXNzJztcbmltcG9ydCB7IEludGVybmFsTGliSW1hZ2UgfSBmcm9tICcuLi8uLi9tb2RlbC9pbWFnZS1pbnRlcm5hbC5jbGFzcyc7XG5pbXBvcnQgeyBLZXlib2FyZCB9IGZyb20gJy4uLy4uL21vZGVsL2tleWJvYXJkLmVudW0nO1xuaW1wb3J0IHsgS2V5Ym9hcmRDb25maWcgfSBmcm9tICcuLi8uLi9tb2RlbC9rZXlib2FyZC1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7IFNsaWRlQ29uZmlnIH0gZnJvbSAnLi4vLi4vbW9kZWwvc2xpZGUtY29uZmlnLmludGVyZmFjZSc7XG5cbmltcG9ydCB7IE5FWFQsIFBSRVYgfSBmcm9tICcuLi8uLi91dGlscy91c2VyLWlucHV0LnV0aWwnO1xuaW1wb3J0IHsgZ2V0SW5kZXggfSBmcm9tICcuLi8uLi91dGlscy9pbWFnZS51dGlsJztcbmltcG9ydCB7IEN1cnJlbnRJbWFnZUNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVsL2N1cnJlbnQtaW1hZ2UtY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGliQ29uZmlnIH0gZnJvbSAnLi4vLi4vbW9kZWwvbGliLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIEludGVyZmFjZSB0byBkZXNjcmliZSB0aGUgTG9hZCBFdmVudCwgdXNlZCB0b1xuICogZW1pdCBhbiBldmVudCB3aGVuIHRoZSBpbWFnZSBpcyBmaW5hbGx5IGxvYWRlZCBhbmQgdGhlIHNwaW5uZXIgaGFzIGdvbmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VMb2FkRXZlbnQge1xuICBzdGF0dXM6IGJvb2xlYW47XG4gIGluZGV4OiBudW1iZXI7XG4gIGlkOiBudW1iZXI7XG59XG5cbi8qKlxuICogQ29tcG9uZW50IHdpdGggdGhlIGN1cnJlbnQgaW1hZ2Ugd2l0aCBzb21lIGFkZGl0aW9uYWwgZWxlbWVudHMgbGlrZSBhcnJvd3MgYW5kIHNpZGUgcHJldmlld3MuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2tzLWN1cnJlbnQtaW1hZ2UnLFxuICBzdHlsZVVybHM6IFsnY3VycmVudC1pbWFnZS5zY3NzJywgJy4uL2ltYWdlLWFycm93cy5zY3NzJywgJ2N1cnJlbnQtaW1hZ2UtcHJldmlld3Muc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJ2N1cnJlbnQtaW1hZ2UuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIEN1cnJlbnRJbWFnZUNvbXBvbmVudCBleHRlbmRzIEFjY2Vzc2libGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqXG4gICAqIFVuaXF1ZSBpZCAoPj0wKSBvZiB0aGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGlzIGxpYnJhcnkuIFRoaXMgaXMgdXNlZnVsIHdoZW4geW91IGFyZSB1c2luZ1xuICAgKiB0aGUgc2VydmljZSB0byBjYWxsIG1vZGFsIGdhbGxlcnkgd2l0aG91dCBvcGVuIGl0IG1hbnVhbGx5LlxuICAgKi9cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBpZDogbnVtYmVyO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYEludGVybmFsTGliSW1hZ2VgIHRoYXQgcmVwcmVzZW50IHRoZSB2aXNpYmxlIGltYWdlLlxuICAgKi9cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBjdXJyZW50SW1hZ2U6IEludGVybmFsTGliSW1hZ2U7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBgSW50ZXJuYWxMaWJJbWFnZWAgdGhhdCByZXByZXNlbnQgdGhlIG1vZGVsIG9mIHRoaXMgbGlicmFyeSB3aXRoIGFsbCBpbWFnZXMsXG4gICAqIHRodW1icyBhbmQgc28gb24uXG4gICAqL1xuICBASW5wdXQoKVxuICAvLyBAdHMtaWdub3JlXG4gIGltYWdlczogSW50ZXJuYWxMaWJJbWFnZVtdO1xuICAvKipcbiAgICogQm9vbGVhbiB0aGF0IGl0IGlzIHRydWUgaWYgdGhlIG1vZGFsIGdhbGxlcnkgaXMgdmlzaWJsZS5cbiAgICogSWYgeWVzLCBhbHNvIHRoaXMgY29tcG9uZW50IHNob3VsZCBiZSB2aXNpYmxlLlxuICAgKi9cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBpc09wZW46IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE91dHB1dCB0byBlbWl0IGFuIGV2ZW50IHdoZW4gaW1hZ2VzIGFyZSBsb2FkZWQuIFRoZSBwYXlsb2FkIGNvbnRhaW5zIGFuIGBJbWFnZUxvYWRFdmVudGAuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgbG9hZEltYWdlOiBFdmVudEVtaXR0ZXI8SW1hZ2VMb2FkRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWFnZUxvYWRFdmVudD4oKTtcbiAgLyoqXG4gICAqIE91dHB1dCB0byBlbWl0IGFueSBjaGFuZ2VzIG9mIHRoZSBjdXJyZW50IGltYWdlLiBUaGUgcGF5bG9hZCBjb250YWlucyBhbiBgSW1hZ2VNb2RhbEV2ZW50YC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBjaGFuZ2VJbWFnZTogRXZlbnRFbWl0dGVyPEltYWdlTW9kYWxFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEltYWdlTW9kYWxFdmVudD4oKTtcbiAgLyoqXG4gICAqIE91dHB1dCB0byBlbWl0IGFuIGV2ZW50IHdoZW4gdGhlIG1vZGFsIGdhbGxlcnkgaXMgY2xvc2VkLiBUaGUgcGF5bG9hZCBjb250YWlucyBhbiBgSW1hZ2VNb2RhbEV2ZW50YC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBjbG9zZUdhbGxlcnk6IEV2ZW50RW1pdHRlcjxJbWFnZU1vZGFsRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWFnZU1vZGFsRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIFN1YmplY3QgdG8gcGxheSBtb2RhbC1nYWxsZXJ5LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGFydCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAvKipcbiAgICogU3ViamVjdCB0byBzdG9wIG1vZGFsLWdhbGxlcnkuXG4gICAqL1xuICBwcml2YXRlIHN0b3AkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKipcbiAgICogRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyBhIG5vcm1hbCBhY3Rpb24uXG4gICAqIERlY2xhcmVkIGhlcmUgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIHRlbXBsYXRlLlxuICAgKi9cbiAgbm9ybWFsQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYEFjY2Vzc2liaWxpdHlDb25maWdgIHRvIGluaXQgY3VzdG9tIGFjY2Vzc2liaWxpdHkgZmVhdHVyZXMuXG4gICAqIEZvciBpbnN0YW5jZSwgaXQgY29udGFpbnMgdGl0bGVzLCBhbHQgdGV4dHMsIGFyaWEtbGFiZWxzIGFuZCBzbyBvbi5cbiAgICovXG4gIGFjY2Vzc2liaWxpdHlDb25maWc6IEFjY2Vzc2liaWxpdHlDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgU2xpZGVDb25maWdgIHRvIGdldCBgaW5maW5pdGUgc2xpZGluZ2AuXG4gICAqL1xuICBzbGlkZUNvbmZpZzogU2xpZGVDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBPYmplY3QgdG8gY29uZmlndXJlIGN1cnJlbnQgaW1hZ2UgaW4gbW9kYWwtZ2FsbGVyeS5cbiAgICogRm9yIGluc3RhbmNlIHlvdSBjYW4gZGlzYWJsZSBuYXZpZ2F0aW9uIG9uIGNsaWNrIG9uIGN1cnJlbnQgaW1hZ2UgKGVuYWJsZWQgYnkgZGVmYXVsdCkuXG4gICAqL1xuICBjdXJyZW50SW1hZ2VDb25maWc6IEN1cnJlbnRJbWFnZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBLZXlib2FyZENvbmZpZ2AgdG8gYXNzaWduIGN1c3RvbSBrZXlzIHRvIGJvdGggRVNDLCBSSUdIVCBhbmQgTEVGVCBrZXlib2FyZCdzIGFjdGlvbnMuXG4gICAqL1xuICBrZXlib2FyZENvbmZpZzogS2V5Ym9hcmRDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBFbnVtIG9mIHR5cGUgYEFjdGlvbmAgdGhhdCByZXByZXNlbnRzIGEgbW91c2UgY2xpY2sgb24gYSBidXR0b24uXG4gICAqIERlY2xhcmVkIGhlcmUgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIHRlbXBsYXRlLlxuICAgKi9cbiAgY2xpY2tBY3Rpb246IEFjdGlvbiA9IEFjdGlvbi5DTElDSztcbiAgLyoqXG4gICAqIEVudW0gb2YgdHlwZSBgQWN0aW9uYCB0aGF0IHJlcHJlc2VudHMgYSBrZXlib2FyZCBhY3Rpb24uXG4gICAqIERlY2xhcmVkIGhlcmUgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIHRlbXBsYXRlLlxuICAgKi9cbiAga2V5Ym9hcmRBY3Rpb246IEFjdGlvbiA9IEFjdGlvbi5LRVlCT0FSRDtcbiAgLyoqXG4gICAqIEJvb2xlYW4gdGhhdCBpdCdzIHRydWUgd2hlbiB5b3UgYXJlIHdhdGNoaW5nIHRoZSBmaXJzdCBpbWFnZSAoY3VycmVudGx5IHZpc2libGUpLlxuICAgKiBGYWxzZSBieSBkZWZhdWx0XG4gICAqL1xuICBpc0ZpcnN0SW1hZ2UgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEJvb2xlYW4gdGhhdCBpdCdzIHRydWUgd2hlbiB5b3UgYXJlIHdhdGNoaW5nIHRoZSBsYXN0IGltYWdlIChjdXJyZW50bHkgdmlzaWJsZSkuXG4gICAqIEZhbHNlIGJ5IGRlZmF1bHRcbiAgICovXG4gIGlzTGFzdEltYWdlID0gZmFsc2U7XG4gIC8qKlxuICAgKiBCb29sZWFuIHRoYXQgaXQncyB0cnVlIGlmIGFuIGltYWdlIG9mIHRoZSBtb2RhbCBnYWxsZXJ5IGlzIHN0aWxsIGxvYWRpbmcuXG4gICAqIFRydWUgYnkgZGVmYXVsdFxuICAgKi9cbiAgbG9hZGluZyA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgb2JqZWN0IHdpdGhvdXQgdHlwZSB0byBkZWZpbmUgYWxsIHN3aXBlIGFjdGlvbnMgdXNlZCBieSBoYW1tZXJqcy5cbiAgICovXG4gIHByaXZhdGUgU1dJUEVfQUNUSU9OID0ge1xuICAgIExFRlQ6ICdzd2lwZWxlZnQnLFxuICAgIFJJR0hUOiAnc3dpcGVyaWdodCcsXG4gICAgVVA6ICdzd2lwZXVwJyxcbiAgICBET1dOOiAnc3dpcGVkb3duJ1xuICB9O1xuXG4gIC8vIHVzZSBwdWJsaWMgQ2hhbmdlRGV0ZWN0b3JSZWYgdG8gYmUgYWJsZSB0byBjYWxsIGl0IGZyb20gc3BlYyBmaWxlcyB0byB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICBjb25zdHJ1Y3RvcihASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IGFueSwgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSwgcHVibGljIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuZXIgdG8gc3RvcCB0aGUgZ2FsbGVyeSB3aGVuIHRoZSBtb3VzZSBwb2ludGVyIGlzIG92ZXIgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcbiAgb25Nb3VzZUVudGVyKCk6IHZvaWQge1xuICAgIC8vIGlmIGNhcm91c2VsIGZlYXR1cmUgaXMgZGlzYWJsZSwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gYW55IGNhc2VcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5wYXVzZU9uSG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdG9wQ2Fyb3VzZWwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW5lciB0byBwbGF5IHRoZSBnYWxsZXJ5IHdoZW4gdGhlIG1vdXNlIHBvaW50ZXIgbGVhdmUgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJylcbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgIC8vIGlmIGNhcm91c2VsIGZlYXR1cmUgaXMgZGlzYWJsZSwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gYW55IGNhc2VcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5wYXVzZU9uSG92ZXIgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5hdXRvUGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBsYXlDYXJvdXNlbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCDCtG5nT25Jbml0wrQgdG8gaW5pdCBjb25maWd1cmF0aW9uLlxuICAgKiBUaGlzIGlzIGFuIEFuZ3VsYXIncyBsaWZlY3ljbGUgaG9vaywgc28gaXRzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IEFuZ3VsYXIgaXRzZWxmLlxuICAgKiBJbiBwYXJ0aWN1bGFyLCBpdCdzIGNhbGxlZCBvbmx5IG9uZSB0aW1lISEhXG4gICAqL1xuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCBsaWJDb25maWc6IExpYkNvbmZpZyB8IHVuZGVmaW5lZCA9IHRoaXMuY29uZmlnU2VydmljZS5nZXRDb25maWcodGhpcy5pZCk7XG4gICAgaWYgKCFsaWJDb25maWcgfHwgIWxpYkNvbmZpZy5idXR0b25zQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBsaWJDb25maWcgYW5kIGJ1dHRvbnNDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHRoaXMuc2xpZGVDb25maWcgPSBsaWJDb25maWcuc2xpZGVDb25maWc7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5Q29uZmlnID0gbGliQ29uZmlnLmFjY2Vzc2liaWxpdHlDb25maWc7XG4gICAgdGhpcy5jdXJyZW50SW1hZ2VDb25maWcgPSBsaWJDb25maWcuY3VycmVudEltYWdlQ29uZmlnO1xuICAgIHRoaXMua2V5Ym9hcmRDb25maWcgPSBsaWJDb25maWcua2V5Ym9hcmRDb25maWc7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIMK0bmdPbkNoYW5nZXPCtCB0byB1cGRhdGUgYGxvYWRpbmdgIHN0YXR1cyBhbmQgZW1pdCBldmVudHMuXG4gICAqIElmIHRoZSBnYWxsZXJ5IGlzIG9wZW4sIHRoZW4gaXQgd2lsbCBhbHNvIG1hbmFnZSBib3VuZGFyeSBhcnJvd3MgYW5kIHNsaWRpbmcuXG4gICAqIFRoaXMgaXMgYW4gQW5ndWxhcidzIGxpZmVjeWNsZSBob29rLCBzbyBpdHMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgQW5ndWxhciBpdHNlbGYuXG4gICAqIEluIHBhcnRpY3VsYXIsIGl0J3MgY2FsbGVkIHdoZW4gYW55IGRhdGEtYm91bmQgcHJvcGVydHkgb2YgYSBkaXJlY3RpdmUgY2hhbmdlcyEhIVxuICAgKi9cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IGxpYkNvbmZpZzogTGliQ29uZmlnIHwgdW5kZWZpbmVkID0gdGhpcy5jb25maWdTZXJ2aWNlLmdldENvbmZpZyh0aGlzLmlkKTtcbiAgICBpZiAoIWxpYkNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gbGliQ29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBpbWFnZXM6IFNpbXBsZUNoYW5nZSA9IGNoYW5nZXMuaW1hZ2VzO1xuICAgIGNvbnN0IGN1cnJlbnRJbWFnZTogU2ltcGxlQ2hhbmdlID0gY2hhbmdlcy5jdXJyZW50SW1hZ2U7XG5cbiAgICBpZiAoY3VycmVudEltYWdlICYmIGN1cnJlbnRJbWFnZS5wcmV2aW91c1ZhbHVlICE9PSBjdXJyZW50SW1hZ2UuY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUluZGV4ZXMoKTtcbiAgICB9IGVsc2UgaWYgKGltYWdlcyAmJiBpbWFnZXMucHJldmlvdXNWYWx1ZSAhPT0gaW1hZ2VzLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVJbmRleGVzKCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2xpZGVDb25maWc6IFNpbXBsZUNoYW5nZSA9IGNoYW5nZXMuc2xpZGVDb25maWc7XG4gICAgaWYgKHNsaWRlQ29uZmlnICYmIHNsaWRlQ29uZmlnLnByZXZpb3VzVmFsdWUgIT09IHNsaWRlQ29uZmlnLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy5zbGlkZUNvbmZpZyA9IGxpYkNvbmZpZy5zbGlkZUNvbmZpZztcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgLy8gaW50ZXJ2YWwgZG9lc24ndCBwbGF5IHdlbGwgd2l0aCBTU1IgYW5kIHByb3RyYWN0b3IsXG4gICAgLy8gc28gd2Ugc2hvdWxkIHJ1biBpdCBpbiB0aGUgYnJvd3NlciBhbmQgb3V0c2lkZSBBbmd1bGFyXG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgdGhpcy5zdGFydCRcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIG1hcCgoKSA9PiB0aGlzLnNsaWRlQ29uZmlnICYmIHRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZyAmJiB0aGlzLnNsaWRlQ29uZmlnLnBsYXlDb25maWcuYXV0b1BsYXkgJiYgdGhpcy5zbGlkZUNvbmZpZy5wbGF5Q29uZmlnLmludGVydmFsKSxcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgICAgIGZpbHRlcigoaW50ZXJ2YWw6IGFueSkgPT4gaW50ZXJ2YWwgPiAwKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcChpbnRlcnZhbCA9PiB0aW1lcihpbnRlcnZhbCkucGlwZSh0YWtlVW50aWwodGhpcy5zdG9wJCkpKVxuICAgICAgICAgIClcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNMYXN0SW1hZ2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5leHRJbWFnZShBY3Rpb24uQVVUT1BMQVkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuc3RhcnQkLm5leHQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gaGFuZGxlIGtleXByZXNzIGJhc2VkIG9uIHRoZSBga2V5Ym9hcmRDb25maWdgIGlucHV0LiBJdCBnZXRzIHRoZSBrZXlDb2RlIG9mXG4gICAqIHRoZSBrZXkgdGhhdCB0cmlnZ2VyZWQgdGhlIGtleXByZXNzIGV2ZW50IHRvIG5hdmlnYXRlIGJldHdlZW4gaW1hZ2VzIG9yIHRvIGNsb3NlIHRoZSBtb2RhbCBnYWxsZXJ5LlxuICAgKiBAcGFyYW0gbnVtYmVyIGtleUNvZGUgb2YgdGhlIGtleSB0aGF0IHRyaWdnZXJlZCB0aGUga2V5cHJlc3MgZXZlbnRcbiAgICovXG4gIG9uS2V5UHJlc3Moa2V5Q29kZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZXNjOiBudW1iZXIgPSB0aGlzLmtleWJvYXJkQ29uZmlnICYmIHRoaXMua2V5Ym9hcmRDb25maWcuZXNjID8gdGhpcy5rZXlib2FyZENvbmZpZy5lc2MgOiBLZXlib2FyZC5FU0M7XG4gICAgY29uc3QgcmlnaHQ6IG51bWJlciA9IHRoaXMua2V5Ym9hcmRDb25maWcgJiYgdGhpcy5rZXlib2FyZENvbmZpZy5yaWdodCA/IHRoaXMua2V5Ym9hcmRDb25maWcucmlnaHQgOiBLZXlib2FyZC5SSUdIVF9BUlJPVztcbiAgICBjb25zdCBsZWZ0OiBudW1iZXIgPSB0aGlzLmtleWJvYXJkQ29uZmlnICYmIHRoaXMua2V5Ym9hcmRDb25maWcubGVmdCA/IHRoaXMua2V5Ym9hcmRDb25maWcubGVmdCA6IEtleWJvYXJkLkxFRlRfQVJST1c7XG5cbiAgICBzd2l0Y2ggKGtleUNvZGUpIHtcbiAgICAgIGNhc2UgZXNjOlxuICAgICAgICB0aGlzLmNsb3NlR2FsbGVyeS5lbWl0KG5ldyBJbWFnZU1vZGFsRXZlbnQodGhpcy5pZCwgQWN0aW9uLktFWUJPQVJELCB0cnVlKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSByaWdodDpcbiAgICAgICAgdGhpcy5uZXh0SW1hZ2UoQWN0aW9uLktFWUJPQVJEKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGxlZnQ6XG4gICAgICAgIHRoaXMucHJldkltYWdlKEFjdGlvbi5LRVlCT0FSRCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IHRoZSBpbWFnZSBkZXNjcmlwdGlvbiBiYXNlZCBvbiBpbnB1dCBwYXJhbXMuXG4gICAqIElmIHlvdSBwcm92aWRlIGEgZnVsbCBkZXNjcmlwdGlvbiB0aGlzIHdpbGwgYmUgdGhlIHZpc2libGUgZGVzY3JpcHRpb24sIG90aGVyd2lzZSxcbiAgICogaXQgd2lsbCBiZSBidWlsdCB1c2luZyB0aGUgYERlc2NyaXB0aW9uYCBvYmplY3QsIGNvbmNhdGVuYXRpbmcgaXRzIGZpZWxkcy5cbiAgICogQHBhcmFtIEltYWdlIGltYWdlIHRvIGdldCBpdHMgZGVzY3JpcHRpb24uIElmIG5vdCBwcm92aWRlZCBpdCB3aWxsIGJlIHRoZSBjdXJyZW50IGltYWdlXG4gICAqIEByZXR1cm5zIFN0cmluZyBkZXNjcmlwdGlvbiBvZiB0aGUgaW1hZ2UgKG9yIHRoZSBjdXJyZW50IGltYWdlIGlmIG5vdCBwcm92aWRlZClcbiAgICogQHRocm93cyBhbiBFcnJvciBpZiBkZXNjcmlwdGlvbiBpc24ndCBhdmFpbGFibGVcbiAgICovXG4gIGdldERlc2NyaXB0aW9uVG9EaXNwbGF5KGltYWdlOiBJbWFnZSA9IHRoaXMuY3VycmVudEltYWdlKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEltYWdlQ29uZmlnIHx8ICF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXNjcmlwdGlvbiBpbnB1dCBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0IGltcGxlbWVudGluZyB0aGUgRGVzY3JpcHRpb24gaW50ZXJmYWNlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb246IGJvb2xlYW4gPSAhaW1hZ2UubW9kYWwgfHwgIWltYWdlLm1vZGFsLmRlc2NyaXB0aW9uIHx8IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uID09PSAnJztcblxuICAgIHN3aXRjaCAodGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uc3RyYXRlZ3kpIHtcbiAgICAgIGNhc2UgRGVzY3JpcHRpb25TdHJhdGVneS5ISURFX0lGX0VNUFRZOlxuICAgICAgICByZXR1cm4gaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24gPyAnJyA6IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uICsgJyc7XG4gICAgICBjYXNlIERlc2NyaXB0aW9uU3RyYXRlZ3kuQUxXQVlTX0hJRERFTjpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0gRGVzY3JpcHRpb25TdHJhdGVneS5BTFdBWVNfVklTSUJMRSAtLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZFRleHREZXNjcmlwdGlvbihpbWFnZSwgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IGBhbHQgYXR0cmlidXRlYC5cbiAgICogYGFsdGAgc3BlY2lmaWVzIGFuIGFsdGVybmF0ZSB0ZXh0IGZvciBhbiBpbWFnZSwgaWYgdGhlIGltYWdlIGNhbm5vdCBiZSBkaXNwbGF5ZWQuXG4gICAqIEBwYXJhbSBJbWFnZSBpbWFnZSB0byBnZXQgaXRzIGFsdCBkZXNjcmlwdGlvbi4gSWYgbm90IHByb3ZpZGVkIGl0IHdpbGwgYmUgdGhlIGN1cnJlbnQgaW1hZ2VcbiAgICogQHJldHVybnMgU3RyaW5nIGFsdCBkZXNjcmlwdGlvbiBvZiB0aGUgaW1hZ2UgKG9yIHRoZSBjdXJyZW50IGltYWdlIGlmIG5vdCBwcm92aWRlZClcbiAgICovXG4gIGdldEFsdERlc2NyaXB0aW9uQnlJbWFnZShpbWFnZTogSW1hZ2UgPSB0aGlzLmN1cnJlbnRJbWFnZSk6IHN0cmluZyB7XG4gICAgaWYgKCFpbWFnZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gaW1hZ2UubW9kYWwgJiYgaW1hZ2UubW9kYWwuZGVzY3JpcHRpb24gPyBpbWFnZS5tb2RhbC5kZXNjcmlwdGlvbiA6IGBJbWFnZSAke2dldEluZGV4KGltYWdlLCB0aGlzLmltYWdlcykgKyAxfWA7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCB0aGUgdGl0bGUgYXR0cmlidXRlcyBiYXNlZCBvbiBkZXNjcmlwdGlvbnMuXG4gICAqIFRoaXMgaXMgdXNlZnVsIHRvIHByZXZlbnQgYWNjZXNzaWJpbGl0eSBpc3N1ZXMsIGJlY2F1c2UgaWYgRGVzY3JpcHRpb25TdHJhdGVneSBpcyBBTFdBWVNfSElEREVOLFxuICAgKiBpdCBwcmV2ZW50cyBhbiBlbXB0eSBzdHJpbmcgYXMgdGl0bGUuXG4gICAqIEBwYXJhbSBJbWFnZSBpbWFnZSB0byBnZXQgaXRzIGRlc2NyaXB0aW9uLiBJZiBub3QgcHJvdmlkZWQgaXQgd2lsbCBiZSB0aGUgY3VycmVudCBpbWFnZVxuICAgKiBAcmV0dXJucyBTdHJpbmcgdGl0bGUgb2YgdGhlIGltYWdlIGJhc2VkIG9uIGRlc2NyaXB0aW9uc1xuICAgKiBAdGhyb3dzIGFuIEVycm9yIGlmIGRlc2NyaXB0aW9uIGlzbid0IGF2YWlsYWJsZVxuICAgKi9cbiAgZ2V0VGl0bGVUb0Rpc3BsYXkoaW1hZ2U6IEltYWdlID0gdGhpcy5jdXJyZW50SW1hZ2UpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jdXJyZW50SW1hZ2VDb25maWcgfHwgIXRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Rlc2NyaXB0aW9uIGlucHV0IG11c3QgYmUgYSB2YWxpZCBvYmplY3QgaW1wbGVtZW50aW5nIHRoZSBEZXNjcmlwdGlvbiBpbnRlcmZhY2UnKTtcbiAgICB9XG4gICAgY29uc3QgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb246IGJvb2xlYW4gPSAhaW1hZ2UubW9kYWwgfHwgIWltYWdlLm1vZGFsLmRlc2NyaXB0aW9uIHx8IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uID09PSAnJztcbiAgICBjb25zdCBkZXNjcmlwdGlvbjogc3RyaW5nID0gdGhpcy5idWlsZFRleHREZXNjcmlwdGlvbihpbWFnZSwgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24pO1xuICAgIHJldHVybiBkZXNjcmlwdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IHRoZSBsZWZ0IHNpZGUgcHJldmlldyBpbWFnZS5cbiAgICogQHJldHVybnMgSW1hZ2UgdGhlIGltYWdlIHRvIHNob3cgYXMgc2l6ZSBwcmV2aWV3IG9uIHRoZSBsZWZ0XG4gICAqL1xuICBnZXRMZWZ0UHJldmlld0ltYWdlKCk6IEltYWdlIHtcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIHNsaWRlQ29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBjdXJyZW50SW5kZXg6IG51bWJlciA9IGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gMCAmJiB0aGlzLnNsaWRlQ29uZmlnLmluZmluaXRlKSB7XG4gICAgICAvLyB0aGUgY3VycmVudCBpbWFnZSBpcyB0aGUgZmlyc3Qgb25lLFxuICAgICAgLy8gc28gdGhlIHByZXZpb3VzIG9uZSBpcyB0aGUgbGFzdCBpbWFnZVxuICAgICAgLy8gYmVjYXVzZSBpbmZpbml0ZSBpcyB0cnVlXG4gICAgICByZXR1cm4gdGhpcy5pbWFnZXNbdGhpcy5pbWFnZXMubGVuZ3RoIC0gMV07XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlQm91bmRhcmllcyhjdXJyZW50SW5kZXgpO1xuICAgIHJldHVybiB0aGlzLmltYWdlc1tNYXRoLm1heChjdXJyZW50SW5kZXggLSAxLCAwKV07XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCB0aGUgcmlnaHQgc2lkZSBwcmV2aWV3IGltYWdlLlxuICAgKiBAcmV0dXJucyBJbWFnZSB0aGUgaW1hZ2UgdG8gc2hvdyBhcyBzaXplIHByZXZpZXcgb24gdGhlIHJpZ2h0XG4gICAqL1xuICBnZXRSaWdodFByZXZpZXdJbWFnZSgpOiBJbWFnZSB7XG4gICAgaWYgKCF0aGlzLnNsaWRlQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBzbGlkZUNvbmZpZyBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudEluZGV4OiBudW1iZXIgPSBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpO1xuICAgIGlmIChjdXJyZW50SW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEgJiYgdGhpcy5zbGlkZUNvbmZpZy5pbmZpbml0ZSkge1xuICAgICAgLy8gdGhlIGN1cnJlbnQgaW1hZ2UgaXMgdGhlIGxhc3Qgb25lLFxuICAgICAgLy8gc28gdGhlIG5leHQgb25lIGlzIHRoZSBmaXJzdCBpbWFnZVxuICAgICAgLy8gYmVjYXVzZSBpbmZpbml0ZSBpcyB0cnVlXG4gICAgICByZXR1cm4gdGhpcy5pbWFnZXNbMF07XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlQm91bmRhcmllcyhjdXJyZW50SW5kZXgpO1xuICAgIHJldHVybiB0aGlzLmltYWdlc1tNYXRoLm1pbihjdXJyZW50SW5kZXggKyAxLCB0aGlzLmltYWdlcy5sZW5ndGggLSAxKV07XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGNhbGxlZCBieSBldmVudHMgZnJvbSBib3RoIGtleWJvYXJkIGFuZCBtb3VzZSBvbiBhbiBpbWFnZS5cbiAgICogVGhpcyB3aWxsIGludm9rZSB0aGUgbmV4dEltYWdlIG1ldGhvZC5cbiAgICogQHBhcmFtIEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50IGV2ZW50IHBheWxvYWRcbiAgICogQHBhcmFtIEFjdGlvbiBhY3Rpb24gdGhhdCB0cmlnZ2VyZWQgdGhlIGV2ZW50IG9yIGBBY3Rpb24uTk9STUFMYCBpZiBub3QgcHJvdmlkZWRcbiAgICovXG4gIG9uSW1hZ2VFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQsIGFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jdXJyZW50SW1hZ2VDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIGN1cnJlbnRJbWFnZUNvbmZpZyBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG4gICAgLy8gY2hlY2sgaWYgdHJpZ2dlcmVkIGJ5IGEgbW91c2UgY2xpY2tcbiAgICAvLyBJZiB5ZXMsIEl0IHNob3VsZCBibG9jayBuYXZpZ2F0aW9uIHdoZW4gbmF2aWdhdGVPbkNsaWNrIGlzIGZhbHNlXG4gICAgaWYgKGFjdGlvbiA9PT0gQWN0aW9uLkNMSUNLICYmICF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5uYXZpZ2F0ZU9uQ2xpY2spIHtcbiAgICAgIC8vIGEgdXNlciBoYXMgcmVxdWVzdGVkIHRvIGJsb2NrIG5hdmlnYXRpb24gdmlhIGNvbmZpZ0N1cnJlbnRJbWFnZS5uYXZpZ2F0ZU9uQ2xpY2sgcHJvcGVydHlcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZUltYWdlRXZlbnQoZXZlbnQpO1xuICAgIGlmIChyZXN1bHQgPT09IE5FWFQpIHtcbiAgICAgIHRoaXMubmV4dEltYWdlKGFjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBjYWxsZWQgYnkgZXZlbnRzIGZyb20gYm90aCBrZXlib2FyZCBhbmQgbW91c2Ugb24gYSBuYXZpZ2F0aW9uIGFycm93LlxuICAgKiBAcGFyYW0gc3RyaW5nIGRpcmVjdGlvbiBvZiB0aGUgbmF2aWdhdGlvbiB0aGF0IGNhbiBiZSBlaXRoZXIgJ25leHQnIG9yICdwcmV2J1xuICAgKiBAcGFyYW0gS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQgZXZlbnQgcGF5bG9hZFxuICAgKiBAcGFyYW0gQWN0aW9uIGFjdGlvbiB0aGF0IHRyaWdnZXJlZCB0aGUgZXZlbnQgb3IgYEFjdGlvbi5OT1JNQUxgIGlmIG5vdCBwcm92aWRlZFxuICAgKiBAcGFyYW0gYm9vbGVhbiBkaXNhYmxlIHRvIGRpc2FibGUgbmF2aWdhdGlvblxuICAgKi9cbiAgb25OYXZpZ2F0aW9uRXZlbnQoZGlyZWN0aW9uOiBzdHJpbmcsIGV2ZW50OiBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCwgYWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMLCBkaXNhYmxlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAoZGlzYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZU5hdmlnYXRpb25FdmVudChkaXJlY3Rpb24sIGV2ZW50KTtcbiAgICBpZiAocmVzdWx0ID09PSBORVhUKSB7XG4gICAgICB0aGlzLm5leHRJbWFnZShhY3Rpb24pO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSBQUkVWKSB7XG4gICAgICB0aGlzLnByZXZJbWFnZShhY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ28gYmFjayB0byB0aGUgcHJldmlvdXMgaW1hZ2UuXG4gICAqIEBwYXJhbSBhY3Rpb24gRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyB0aGUgc291cmNlXG4gICAqICBhY3Rpb24gdGhhdCBtb3ZlZCBiYWNrIHRvIHRoZSBwcmV2aW91cyBpbWFnZS4gYEFjdGlvbi5OT1JNQUxgIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBwcmV2SW1hZ2UoYWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMKTogdm9pZCB7XG4gICAgLy8gY2hlY2sgaWYgcHJldkltYWdlIHNob3VsZCBiZSBibG9ja2VkXG4gICAgaWYgKHRoaXMuaXNQcmV2ZW50U2xpZGluZygwKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwcmV2SW1hZ2U6IEludGVybmFsTGliSW1hZ2UgPSB0aGlzLmdldFByZXZJbWFnZSgpO1xuICAgIHRoaXMubG9hZGluZyA9ICFwcmV2SW1hZ2UucHJldmlvdXNseUxvYWRlZDtcbiAgICB0aGlzLmNoYW5nZUltYWdlLmVtaXQobmV3IEltYWdlTW9kYWxFdmVudCh0aGlzLmlkLCBhY3Rpb24sIGdldEluZGV4KHByZXZJbWFnZSwgdGhpcy5pbWFnZXMpKSk7XG5cbiAgICB0aGlzLnN0YXJ0JC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdvIGJhY2sgdG8gdGhlIHByZXZpb3VzIGltYWdlLlxuICAgKiBAcGFyYW0gYWN0aW9uIEVudW0gb2YgdHlwZSBgQWN0aW9uYCB0aGF0IHJlcHJlc2VudHMgdGhlIHNvdXJjZVxuICAgKiAgYWN0aW9uIHRoYXQgbW92ZWQgdG8gdGhlIG5leHQgaW1hZ2UuIGBBY3Rpb24uTk9STUFMYCBieSBkZWZhdWx0LlxuICAgKi9cbiAgbmV4dEltYWdlKGFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTCk6IHZvaWQge1xuICAgIC8vIGNoZWNrIGlmIG5leHRJbWFnZSBzaG91bGQgYmUgYmxvY2tlZFxuICAgIGlmICh0aGlzLmlzUHJldmVudFNsaWRpbmcodGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbmV4dEltYWdlOiBJbnRlcm5hbExpYkltYWdlID0gdGhpcy5nZXROZXh0SW1hZ2UoKTtcbiAgICB0aGlzLmxvYWRpbmcgPSAhbmV4dEltYWdlLnByZXZpb3VzbHlMb2FkZWQ7XG4gICAgdGhpcy5jaGFuZ2VJbWFnZS5lbWl0KG5ldyBJbWFnZU1vZGFsRXZlbnQodGhpcy5pZCwgYWN0aW9uLCBnZXRJbmRleChuZXh0SW1hZ2UsIHRoaXMuaW1hZ2VzKSkpO1xuXG4gICAgdGhpcy5zdGFydCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBlbWl0IGFuIGV2ZW50IGFzIGxvYWRJbWFnZSBvdXRwdXQgdG8gc2F5IHRoYXQgdGhlIHJlcXVlc3RlZCBpbWFnZSBpZiBsb2FkZWQuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgYnkgdGhlIGphdmFzY3JpcHQncyAnbG9hZCcgZXZlbnQgb24gYW4gaW1nIHRhZy5cbiAgICogQHBhcmFtIEV2ZW50IGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBsb2FkXG4gICAqL1xuICBvbkltYWdlTG9hZChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBsb2FkSW1hZ2VEYXRhOiBJbWFnZUxvYWRFdmVudCA9IHtcbiAgICAgIHN0YXR1czogdHJ1ZSxcbiAgICAgIGluZGV4OiBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpLFxuICAgICAgaWQ6IHRoaXMuY3VycmVudEltYWdlLmlkXG4gICAgfTtcblxuICAgIHRoaXMubG9hZEltYWdlLmVtaXQobG9hZEltYWdlRGF0YSk7XG5cbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdXNlZCBieSBIYW1tZXJqcyB0byBzdXBwb3J0IHRvdWNoIGdlc3R1cmVzICh5b3UgY2FuIGFsc28gaW52ZXJ0IHRoZSBzd2lwZSBkaXJlY3Rpb24gd2l0aCBjb25maWdDdXJyZW50SW1hZ2UuaW52ZXJ0U3dpcGUpLlxuICAgKiBAcGFyYW0gYWN0aW9uIFN0cmluZyB0aGF0IHJlcHJlc2VudCB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzd2lwZSBhY3Rpb24uICdzd2lwZXJpZ2h0JyBieSBkZWZhdWx0LlxuICAgKi9cbiAgc3dpcGUoYWN0aW9uID0gdGhpcy5TV0lQRV9BQ1RJT04uUklHSFQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEltYWdlQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBjdXJyZW50SW1hZ2VDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHN3aXRjaCAoYWN0aW9uKSB7XG4gICAgICBjYXNlIHRoaXMuU1dJUEVfQUNUSU9OLlJJR0hUOlxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SW1hZ2VDb25maWcuaW52ZXJ0U3dpcGUpIHtcbiAgICAgICAgICB0aGlzLnByZXZJbWFnZShBY3Rpb24uU1dJUEUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubmV4dEltYWdlKEFjdGlvbi5TV0lQRSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHRoaXMuU1dJUEVfQUNUSU9OLkxFRlQ6XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5pbnZlcnRTd2lwZSkge1xuICAgICAgICAgIHRoaXMubmV4dEltYWdlKEFjdGlvbi5TV0lQRSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wcmV2SW1hZ2UoQWN0aW9uLlNXSVBFKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIC8vIGNhc2UgdGhpcy5TV0lQRV9BQ1RJT04uVVA6XG4gICAgICAvLyAgIGJyZWFrO1xuICAgICAgLy8gY2FzZSB0aGlzLlNXSVBFX0FDVElPTi5ET1dOOlxuICAgICAgLy8gICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHVzZWQgaW4gYG1vZGFsLWdhbGxlcnkuY29tcG9uZW50YCB0byBnZXQgdGhlIGluZGV4IG9mIGFuIGltYWdlIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIEltYWdlIGltYWdlIHRvIGdldCB0aGUgaW5kZXgsIG9yIHRoZSB2aXNpYmxlIGltYWdlLCBpZiBub3QgcGFzc2VkXG4gICAqIEByZXR1cm5zIG51bWJlciB0aGUgaW5kZXggb2YgdGhlIGltYWdlXG4gICAqL1xuICBnZXRJbmRleFRvRGVsZXRlKGltYWdlOiBJbWFnZSA9IHRoaXMuY3VycmVudEltYWdlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZ2V0SW5kZXgoaW1hZ2UsIHRoaXMuaW1hZ2VzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gcGxheSBtb2RhbCBnYWxsZXJ5LlxuICAgKi9cbiAgcGxheUNhcm91c2VsKCk6IHZvaWQge1xuICAgIHRoaXMuc3RhcnQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBtb2RhbCBnYWxsZXJ5IGZyb20gY3ljbGluZyB0aHJvdWdoIGl0ZW1zLlxuICAgKi9cbiAgc3RvcENhcm91c2VsKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBjbGVhbnVwIHJlc291cmNlcy4gSW4gZmFjdCwgdGhpcyB3aWxsIHN0b3AgdGhlIG1vZGFsIGdhbGxlcnkuXG4gICAqIFRoaXMgaXMgYW4gQW5ndWxhcidzIGxpZmVjeWNsZSBob29rIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhpcyBjb21wb25lbnQgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wQ2Fyb3VzZWwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byB1cGRhdGUgYm90aCBgaXNGaXJzdEltYWdlYCBhbmQgYGlzTGFzdEltYWdlYCBiYXNlZCBvblxuICAgKiB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqIEBwYXJhbSBudW1iZXIgY3VycmVudEluZGV4IGlzIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBpbWFnZVxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVCb3VuZGFyaWVzKGN1cnJlbnRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW1hZ2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSB0cnVlO1xuICAgICAgdGhpcy5pc0xhc3RJbWFnZSA9IHRydWU7XG4gICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNsaWRlQ29uZmlnIHx8IHRoaXMuc2xpZGVDb25maWcuaW5maW5pdGUgPT09IHRydWUpIHtcbiAgICAgIC8vIGluZmluaXRlIHNsaWRpbmcgZW5hYmxlZFxuICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSBmYWxzZTtcbiAgICAgIHRoaXMuaXNMYXN0SW1hZ2UgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBleGVjdXRlIHRoaXMgb25seSBpZiBpbmZpbml0ZSBzbGlkaW5nIGlzIGRpc2FibGVkXG4gICAgICBzd2l0Y2ggKGN1cnJlbnRJbmRleCkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuaXNMYXN0SW1hZ2UgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSB0aGlzLmltYWdlcy5sZW5ndGggLSAxOlxuICAgICAgICAgIHRoaXMuaXNGaXJzdEltYWdlID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5pc0xhc3RJbWFnZSA9IHRydWU7XG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLmlzTGFzdEltYWdlID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIGNoZWNrIGlmIG5leHQvcHJldiBhY3Rpb25zIHNob3VsZCBiZSBibG9ja2VkLlxuICAgKiBJdCBjaGVja3MgaWYgc2xpZGVDb25maWcuaW5maW5pdGUgPT09IGZhbHNlIGFuZCBpZiB0aGUgaW1hZ2UgaW5kZXggaXMgZXF1YWxzIHRvIHRoZSBpbnB1dCBwYXJhbWV0ZXIuXG4gICAqIElmIHllcywgaXQgcmV0dXJucyB0cnVlIHRvIHNheSB0aGF0IHNsaWRpbmcgc2hvdWxkIGJlIGJsb2NrZWQsIG90aGVyd2lzZSBub3QuXG4gICAqIEBwYXJhbSBudW1iZXIgYm91bmRhcnlJbmRleCB0aGF0IGNvdWxkIGJlIGVpdGhlciB0aGUgYmVnaW5uaW5nIGluZGV4ICgwKSBvciB0aGUgbGFzdCBpbmRleFxuICAgKiAgb2YgaW1hZ2VzICh0aGlzLmltYWdlcy5sZW5ndGggLSAxKS5cbiAgICogQHJldHVybnMgYm9vbGVhbiB0cnVlIGlmIHNsaWRlQ29uZmlnLmluZmluaXRlID09PSBmYWxzZSBhbmQgdGhlIGN1cnJlbnQgaW5kZXggaXNcbiAgICogIGVpdGhlciB0aGUgZmlyc3Qgb3IgdGhlIGxhc3Qgb25lLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1ByZXZlbnRTbGlkaW5nKGJvdW5kYXJ5SW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuc2xpZGVDb25maWcgJiYgdGhpcy5zbGlkZUNvbmZpZy5pbmZpbml0ZSA9PT0gZmFsc2UgJiYgZ2V0SW5kZXgodGhpcy5jdXJyZW50SW1hZ2UsIHRoaXMuaW1hZ2VzKSA9PT0gYm91bmRhcnlJbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBnZXQgdGhlIG5leHQgaW5kZXguXG4gICAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgYXQgdGhlIGVuZCwgd2hlbiB5b3UgY2FsbCBuZXh0IGFnYWluLCB5b3UnbGwgZ28gdG8gdGhlIGZpcnN0IGltYWdlLlxuICAgKiBUaGF0IGhhcHBlbnMgYmVjYXVzZSBhbGwgbW9kYWwgaW1hZ2VzIGFyZSBzaG93biBsaWtlIGluIGEgY2lyY2xlLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXROZXh0SW1hZ2UoKTogSW50ZXJuYWxMaWJJbWFnZSB7XG4gICAgY29uc3QgY3VycmVudEluZGV4OiBudW1iZXIgPSBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpO1xuICAgIGxldCBuZXdJbmRleCA9IDA7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA+PSAwICYmIGN1cnJlbnRJbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpIHtcbiAgICAgIG5ld0luZGV4ID0gY3VycmVudEluZGV4ICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3SW5kZXggPSAwOyAvLyBzdGFydCBmcm9tIHRoZSBmaXJzdCBpbmRleFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pbWFnZXNbbmV3SW5kZXhdO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIGdldCB0aGUgcHJldmlvdXMgaW5kZXguXG4gICAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgYXQgaW5kZXggMCwgd2hlbiB5b3UgY2FsbCBwcmV2IGFnYWluLCB5b3UnbGwgZ28gdG8gdGhlIGxhc3QgaW1hZ2UuXG4gICAqIFRoYXQgaGFwcGVucyBiZWNhdXNlIGFsbCBtb2RhbCBpbWFnZXMgYXJlIHNob3duIGxpa2UgaW4gYSBjaXJjbGUuXG4gICAqL1xuICBwcml2YXRlIGdldFByZXZJbWFnZSgpOiBJbnRlcm5hbExpYkltYWdlIHtcbiAgICBjb25zdCBjdXJyZW50SW5kZXg6IG51bWJlciA9IGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG4gICAgbGV0IG5ld0luZGV4ID0gMDtcbiAgICBpZiAoY3VycmVudEluZGV4ID4gMCAmJiBjdXJyZW50SW5kZXggPD0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkge1xuICAgICAgbmV3SW5kZXggPSBjdXJyZW50SW5kZXggLSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdJbmRleCA9IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDE7IC8vIHN0YXJ0IGZyb20gdGhlIGxhc3QgaW5kZXhcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VzW25ld0luZGV4XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBidWlsZCBhIHRleHQgZGVzY3JpcHRpb24uXG4gICAqIFRoaXMgaXMgdXNlZCBhbHNvIHRvIGNyZWF0ZSB0aXRsZXMuXG4gICAqIEBwYXJhbSBJbWFnZSBpbWFnZSB0byBnZXQgaXRzIGRlc2NyaXB0aW9uLiBJZiBub3QgcHJvdmlkZWQgaXQgd2lsbCBiZSB0aGUgY3VycmVudCBpbWFnZS5cbiAgICogQHBhcmFtIGJvb2xlYW4gaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24gaXMgYSBib29sZWFuIHRoYXQgaXQncyB0cnVlIGlmIHRoZSBpbWFnZSBoYXNuJ3QgYSAnbW9kYWwnIGRlc2NyaXB0aW9uLlxuICAgKiBAcmV0dXJucyBTdHJpbmcgZGVzY3JpcHRpb24gYnVpbHQgY29uY2F0ZW5hdGluZyBpbWFnZSBmaWVsZHMgd2l0aCBhIHNwZWNpZmljIGxvZ2ljLlxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFRleHREZXNjcmlwdGlvbihpbWFnZTogSW1hZ2UsIGltYWdlV2l0aG91dERlc2NyaXB0aW9uOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEltYWdlQ29uZmlnIHx8ICF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXNjcmlwdGlvbiBpbnB1dCBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0IGltcGxlbWVudGluZyB0aGUgRGVzY3JpcHRpb24gaW50ZXJmYWNlJyk7XG4gICAgfVxuXG4gICAgLy8gSWYgY3VzdG9tRnVsbERlc2NyaXB0aW9uIHVzZSBpdCwgb3RoZXJ3aXNlIHByb2NlZWQgdG8gYnVpbGQgYSBkZXNjcmlwdGlvblxuICAgIGlmICh0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5jdXN0b21GdWxsRGVzY3JpcHRpb24gJiYgdGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uY3VzdG9tRnVsbERlc2NyaXB0aW9uICE9PSAnJykge1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uLmN1c3RvbUZ1bGxEZXNjcmlwdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50SW5kZXg6IG51bWJlciA9IGdldEluZGV4KGltYWdlLCB0aGlzLmltYWdlcyk7XG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgaW1hZ2UgaGFzbid0IGEgZGVzY3JpcHRpb24sXG4gICAgLy8gcHJldmVudCB0byB3cml0ZSB0aGUgJyAtICcgKG9yIHRoaXMuZGVzY3JpcHRpb24uYmVmb3JlVGV4dERlc2NyaXB0aW9uKVxuXG4gICAgY29uc3QgcHJldkRlc2NyaXB0aW9uOiBzdHJpbmcgPSB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5pbWFnZVRleHQgPyB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5pbWFnZVRleHQgOiAnJztcbiAgICBjb25zdCBtaWRTZXBhcmF0b3I6IHN0cmluZyA9IHRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uLm51bWJlclNlcGFyYXRvciA/IHRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uLm51bWJlclNlcGFyYXRvciA6ICcnO1xuICAgIGNvbnN0IG1pZGRsZURlc2NyaXB0aW9uOiBzdHJpbmcgPSBjdXJyZW50SW5kZXggKyAxICsgbWlkU2VwYXJhdG9yICsgdGhpcy5pbWFnZXMubGVuZ3RoO1xuXG4gICAgaWYgKGltYWdlV2l0aG91dERlc2NyaXB0aW9uKSB7XG4gICAgICByZXR1cm4gcHJldkRlc2NyaXB0aW9uICsgbWlkZGxlRGVzY3JpcHRpb247XG4gICAgfVxuXG4gICAgY29uc3QgY3VyckltZ0Rlc2NyaXB0aW9uOiBzdHJpbmcgPSBpbWFnZS5tb2RhbCAmJiBpbWFnZS5tb2RhbC5kZXNjcmlwdGlvbiA/IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uIDogJyc7XG4gICAgY29uc3QgZW5kRGVzY3JpcHRpb246IHN0cmluZyA9IHRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uLmJlZm9yZVRleHREZXNjcmlwdGlvbiArIGN1cnJJbWdEZXNjcmlwdGlvbjtcbiAgICByZXR1cm4gcHJldkRlc2NyaXB0aW9uICsgbWlkZGxlRGVzY3JpcHRpb24gKyBlbmREZXNjcmlwdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBjYWxsIGhhbmRsZUJvdW5kYXJpZXMgd2hlbiBuZ09uQ2hhbmdlcyBpcyBjYWxsZWQuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUluZGV4ZXMoKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgICBjb25zdCBpbmRleDogbnVtYmVyID0gZ2V0SW5kZXgodGhpcy5jdXJyZW50SW1hZ2UsIHRoaXMuaW1hZ2VzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVCb3VuZGFyaWVzKGluZGV4KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBnZXQgdGhlIGN1cnJlbnQgaW1hZ2UgaW5kZXggaW4gY3VycmVudC1pbWFnZScpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxufVxuIiwiPG1haW4gY2xhc3M9XCJtYWluLWltYWdlLWNvbnRhaW5lclwiXG4gICAgICBrc0tleWJvYXJkTmF2aWdhdGlvbiBbaXNPcGVuXT1cImlzT3BlblwiIChrZXlib2FyZE5hdmlnYXRpb24pPVwib25LZXlQcmVzcygkZXZlbnQpXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8ubWFpbkNvbnRhaW5lckFyaWFMYWJlbFwiXG4gICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8ubWFpbkNvbnRhaW5lclRpdGxlXCI+XG5cbiAgPGRpdiBjbGFzcz1cImxlZnQtc3ViLWNvbnRhaW5lclwiPlxuICAgIDxhIGNsYXNzPVwibmF2LWxlZnQge3tpc0ZpcnN0SW1hZ2UgPyAnbm8tcG9pbnRlcicgOiAnJ319XCJcbiAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjY2Vzc2liaWxpdHlDb25maWc/Lm1haW5QcmV2SW1hZ2VBcmlhTGFiZWxcIlxuICAgICAgIFt0YWJJbmRleF09XCJpc0ZpcnN0SW1hZ2UgPyAtMSA6IDBcIiByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAoY2xpY2spPVwib25OYXZpZ2F0aW9uRXZlbnQoJ2xlZnQnLCAkZXZlbnQpXCIgKGtleXVwKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdsZWZ0JywgJGV2ZW50KVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImluc2lkZSB7e2lzRmlyc3RJbWFnZSA/ICdlbXB0eS1hcnJvdy1pbWFnZScgOiAnbGVmdC1hcnJvdy1pbWFnZSd9fVwiXG4gICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgIFt0aXRsZV09XCJpc0ZpcnN0SW1hZ2UgPyAnJyA6IGFjY2Vzc2liaWxpdHlDb25maWc/Lm1haW5QcmV2SW1hZ2VUaXRsZVwiPjwvZGl2PlxuICAgIDwvYT5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzbGlkZUNvbmZpZz8uc2lkZVByZXZpZXdzPy5zaG93XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0TGVmdFByZXZpZXdJbWFnZSgpIGFzIGxlZnRQcmV2aWV3XCI+XG4gICAgICAgIDxpbWcgKm5nSWY9XCIhaXNGaXJzdEltYWdlOyBlbHNlIGZpcnN0SW1hZ2VcIlxuICAgICAgICAgICAgIGNsYXNzPVwiaW5zaWRlIGN1cnJlbnQtaW1hZ2UtcHJldmlvdXNcIlxuICAgICAgICAgICAgIFtzcmNdPVwibGVmdFByZXZpZXcucGxhaW4/LmltZyA/IGxlZnRQcmV2aWV3LnBsYWluPy5pbWcgOiBsZWZ0UHJldmlldy5tb2RhbC5pbWdcIlxuICAgICAgICAgICAgIGtzRmFsbGJhY2tJbWFnZSBbZmFsbGJhY2tJbWddPVwibGVmdFByZXZpZXcucGxhaW4/LmZhbGxiYWNrSW1nID8gbGVmdFByZXZpZXcucGxhaW4/LmZhbGxiYWNrSW1nIDogbGVmdFByZXZpZXcubW9kYWwuZmFsbGJhY2tJbWdcIlxuICAgICAgICAgICAgIFtoaWRkZW5dPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAga3NTaXplIFtzaXplQ29uZmlnXT1cInt3aWR0aDogc2xpZGVDb25maWc/LnNpZGVQcmV2aWV3cz8uc2l6ZS53aWR0aCwgaGVpZ2h0OiBzbGlkZUNvbmZpZz8uc2lkZVByZXZpZXdzPy5zaXplLmhlaWdodH1cIlxuICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwibGVmdFByZXZpZXcubW9kYWwuYXJpYUxhYmVsXCJcbiAgICAgICAgICAgICBbdGl0bGVdPVwiKGxlZnRQcmV2aWV3Lm1vZGFsLnRpdGxlIHx8IGxlZnRQcmV2aWV3Lm1vZGFsLnRpdGxlID09PSAnJykgPyBsZWZ0UHJldmlldy5tb2RhbC50aXRsZSA6IGdldERlc2NyaXB0aW9uVG9EaXNwbGF5KGxlZnRQcmV2aWV3KVwiXG4gICAgICAgICAgICAgYWx0PVwie3tsZWZ0UHJldmlldy5tb2RhbC5hbHQgPyBsZWZ0UHJldmlldy5tb2RhbC5hbHQgOiBnZXRBbHREZXNjcmlwdGlvbkJ5SW1hZ2UobGVmdFByZXZpZXcpfX1cIlxuICAgICAgICAgICAgIFt0YWJJbmRleF09XCIwXCIgcm9sZT1cImltZ1wiXG4gICAgICAgICAgICAgKGNsaWNrKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdsZWZ0JywgJGV2ZW50LCBjbGlja0FjdGlvbilcIiAoa2V5dXApPVwib25OYXZpZ2F0aW9uRXZlbnQoJ2xlZnQnLCAkZXZlbnQsIGtleWJvYXJkQWN0aW9uKVwiLz5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNmaXJzdEltYWdlPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJyZW50LWltYWdlLXByZXZpb3VzIGhpZGRlblwiXG4gICAgICAgICAgICAgICBrc1NpemUgW3NpemVDb25maWddPVwie3dpZHRoOiBzbGlkZUNvbmZpZz8uc2lkZVByZXZpZXdzPy5zaXplLndpZHRoLCBoZWlnaHQ6IHNsaWRlQ29uZmlnPy5zaWRlUHJldmlld3M/LnNpemUuaGVpZ2h0fVwiPjwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG5cbiAgPGZpZ3VyZSBpZD1cImN1cnJlbnQtZmlndXJlXCIgW3N0eWxlLmRpc3BsYXldPVwibG9hZGluZyA/ICdub25lJyA6ICcnXCI+XG4gICAgPGltZyBpZD1cImN1cnJlbnQtaW1hZ2VcIlxuICAgICAgICAgY2xhc3M9XCJpbnNpZGVcIlxuICAgICAgICAgW25nQ2xhc3NdPVwiY3VycmVudEltYWdlQ29uZmlnPy5uYXZpZ2F0ZU9uQ2xpY2sgPyAnJyA6ICd1bmNsaWNrYWJsZSdcIlxuICAgICAgICAgW3NyY109XCJjdXJyZW50SW1hZ2UubW9kYWwuaW1nXCJcbiAgICAgICAgIGtzRmFsbGJhY2tJbWFnZSBbZmFsbGJhY2tJbWddPVwiY3VycmVudEltYWdlLm1vZGFsLmZhbGxiYWNrSW1nXCJcbiAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiY3VycmVudEltYWdlLm1vZGFsLmFyaWFMYWJlbFwiXG4gICAgICAgICBbdGl0bGVdPVwiKGN1cnJlbnRJbWFnZS5tb2RhbC50aXRsZSB8fCBjdXJyZW50SW1hZ2UubW9kYWwudGl0bGUgPT09ICcnKSA/IGN1cnJlbnRJbWFnZS5tb2RhbC50aXRsZSA6IGdldFRpdGxlVG9EaXNwbGF5KClcIlxuICAgICAgICAgYWx0PVwie3tjdXJyZW50SW1hZ2UubW9kYWwuYWx0ID8gY3VycmVudEltYWdlLm1vZGFsLmFsdCA6IGdldEFsdERlc2NyaXB0aW9uQnlJbWFnZSgpfX1cIlxuICAgICAgICAgW3RhYkluZGV4XT1cIjBcIiByb2xlPVwiaW1nXCJcbiAgICAgICAgIChsb2FkKT1cIm9uSW1hZ2VMb2FkKCRldmVudClcIlxuICAgICAgICAgKGNsaWNrKT1cIm9uSW1hZ2VFdmVudCgkZXZlbnQsIGNsaWNrQWN0aW9uKVwiIChrZXl1cCk9XCJvbkltYWdlRXZlbnQoJGV2ZW50LCBrZXlib2FyZEFjdGlvbilcIlxuICAgICAgICAgKHN3aXBlbGVmdCk9XCJzd2lwZSgkZXZlbnQudHlwZSlcIlxuICAgICAgICAgKHN3aXBlcmlnaHQpPVwic3dpcGUoJGV2ZW50LnR5cGUpXCIvPlxuICAgIDxmaWdjYXB0aW9uICpuZ0lmPVwiZ2V0RGVzY3JpcHRpb25Ub0Rpc3BsYXkoKSAhPT0gJydcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5zaWRlIGRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICBrc0Rlc2NyaXB0aW9uIFtkZXNjcmlwdGlvbl09XCJjdXJyZW50SW1hZ2VDb25maWc/LmRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImdldERlc2NyaXB0aW9uVG9EaXNwbGF5KClcIj5cbiAgICA8L2ZpZ2NhcHRpb24+XG4gIDwvZmlndXJlPlxuXG4gIDxkaXYgY2xhc3M9XCJyaWdodC1zdWItY29udGFpbmVyXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNsaWRlQ29uZmlnPy5zaWRlUHJldmlld3M/LnNob3dcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRSaWdodFByZXZpZXdJbWFnZSgpIGFzIHJpZ2h0UHJldmlld1wiPlxuICAgICAgICA8aW1nICpuZ0lmPVwiIWlzTGFzdEltYWdlOyBlbHNlIGxhc3RJbWFnZVwiXG4gICAgICAgICAgICAgY2xhc3M9XCJpbnNpZGUgY3VycmVudC1pbWFnZS1uZXh0XCJcbiAgICAgICAgICAgICBbc3JjXT1cInJpZ2h0UHJldmlldy5wbGFpbj8uaW1nID8gcmlnaHRQcmV2aWV3LnBsYWluPy5pbWcgOiByaWdodFByZXZpZXcubW9kYWwuaW1nXCJcbiAgICAgICAgICAgICBrc0ZhbGxiYWNrSW1hZ2UgW2ZhbGxiYWNrSW1nXT1cInJpZ2h0UHJldmlldy5wbGFpbj8uZmFsbGJhY2tJbWcgPyByaWdodFByZXZpZXcucGxhaW4/LmZhbGxiYWNrSW1nIDogcmlnaHRQcmV2aWV3Lm1vZGFsLmZhbGxiYWNrSW1nXCJcbiAgICAgICAgICAgICBbaGlkZGVuXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgIGtzU2l6ZSBbc2l6ZUNvbmZpZ109XCJ7d2lkdGg6IHNsaWRlQ29uZmlnPy5zaWRlUHJldmlld3M/LnNpemUud2lkdGgsIGhlaWdodDogc2xpZGVDb25maWc/LnNpZGVQcmV2aWV3cz8uc2l6ZS5oZWlnaHR9XCJcbiAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInJpZ2h0UHJldmlldy5tb2RhbC5hcmlhTGFiZWxcIlxuICAgICAgICAgICAgIFt0aXRsZV09XCIocmlnaHRQcmV2aWV3Lm1vZGFsLnRpdGxlIHx8IHJpZ2h0UHJldmlldy5tb2RhbC50aXRsZSA9PT0gJycpID8gcmlnaHRQcmV2aWV3Lm1vZGFsLnRpdGxlIDogZ2V0RGVzY3JpcHRpb25Ub0Rpc3BsYXkocmlnaHRQcmV2aWV3KVwiXG4gICAgICAgICAgICAgYWx0PVwie3tyaWdodFByZXZpZXcubW9kYWwuYWx0ID8gcmlnaHRQcmV2aWV3Lm1vZGFsLmFsdCA6IGdldEFsdERlc2NyaXB0aW9uQnlJbWFnZShyaWdodFByZXZpZXcpfX1cIlxuICAgICAgICAgICAgIFt0YWJJbmRleF09XCIwXCIgcm9sZT1cImltZ1wiXG4gICAgICAgICAgICAgKGNsaWNrKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdyaWdodCcsICRldmVudCwgY2xpY2tBY3Rpb24pXCIgKGtleXVwKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdyaWdodCcsICRldmVudCwga2V5Ym9hcmRBY3Rpb24pXCIvPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2xhc3RJbWFnZT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3VycmVudC1pbWFnZS1uZXh0IGhpZGRlblwiXG4gICAgICAgICAgICAgICBrc1NpemUgW3NpemVDb25maWddPVwie3dpZHRoOiBzbGlkZUNvbmZpZz8uc2lkZVByZXZpZXdzPy5zaXplLndpZHRoLCBoZWlnaHQ6IHNsaWRlQ29uZmlnPy5zaWRlUHJldmlld3M/LnNpemUuaGVpZ2h0fVwiPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZyAmJiBjdXJyZW50SW1hZ2VDb25maWc/LmxvYWRpbmdDb25maWc/LmVuYWJsZVwiPlxuICAgICAgPGtzLWxvYWRpbmctc3Bpbm5lciBbbG9hZGluZ0NvbmZpZ109XCJjdXJyZW50SW1hZ2VDb25maWc/LmxvYWRpbmdDb25maWdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbYWNjZXNzaWJpbGl0eUNvbmZpZ109XCJhY2Nlc3NpYmlsaXR5Q29uZmlnXCI+PC9rcy1sb2FkaW5nLXNwaW5uZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8YSBjbGFzcz1cIm5hdi1yaWdodCB7e2lzRmlyc3RJbWFnZSA/ICduby1wb2ludGVyJyA6ICcnfX1cIlxuICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8ubWFpbk5leHRJbWFnZUFyaWFMYWJlbFwiXG4gICAgICAgW3RhYkluZGV4XT1cImlzTGFzdEltYWdlID8gLTEgOiAwXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgKGNsaWNrKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdyaWdodCcsICRldmVudClcIiAoa2V5dXApPVwib25OYXZpZ2F0aW9uRXZlbnQoJ3JpZ2h0JywgJGV2ZW50KVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImluc2lkZSB7e2lzTGFzdEltYWdlID8gJ2VtcHR5LWFycm93LWltYWdlJyA6ICdyaWdodC1hcnJvdy1pbWFnZSd9fVwiXG4gICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgIFt0aXRsZV09XCJpc0xhc3RJbWFnZSA/ICcnIDogYWNjZXNzaWJpbGl0eUNvbmZpZz8ubWFpbk5leHRJbWFnZVRpdGxlXCI+PC9kaXY+XG4gICAgPC9hPlxuICA8L2Rpdj5cbjwvbWFpbj5cbiJdfQ==
|