@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.
Files changed (113) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/CONTRIBUTING.md +3 -3
  3. package/README.md +26 -34
  4. package/{esm2015/ks89-angular-modal-gallery.js → esm2020/ks89-angular-modal-gallery.mjs} +0 -0
  5. package/{esm2015/lib/components/accessibility-default.js → esm2020/lib/components/accessibility-default.mjs} +0 -0
  6. package/{esm2015/lib/components/accessible.component.js → esm2020/lib/components/accessible.component.mjs} +6 -6
  7. package/esm2020/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +462 -0
  8. package/esm2020/lib/components/carousel/carousel.component.mjs +747 -0
  9. package/{esm2015/lib/components/components.js → esm2020/lib/components/components.mjs} +0 -0
  10. package/esm2020/lib/components/current-image/current-image.component.mjs +616 -0
  11. package/esm2020/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +80 -0
  12. package/esm2020/lib/components/dots/dots.component.mjs +127 -0
  13. package/esm2020/lib/components/modal-gallery/modal-gallery-ref.mjs +103 -0
  14. package/esm2020/lib/components/modal-gallery/modal-gallery.component.mjs +523 -0
  15. package/esm2020/lib/components/modal-gallery/modal-gallery.service.mjs +187 -0
  16. package/esm2020/lib/components/modal-gallery/modal-gallery.tokens.mjs +26 -0
  17. package/esm2020/lib/components/plain-gallery/plain-gallery.component.mjs +249 -0
  18. package/esm2020/lib/components/previews/previews.component.mjs +332 -0
  19. package/{esm2015/lib/components/upper-buttons/upper-buttons-default.js → esm2020/lib/components/upper-buttons/upper-buttons-default.mjs} +0 -0
  20. package/esm2020/lib/components/upper-buttons/upper-buttons.component.mjs +249 -0
  21. package/{esm2015/lib/directives/a-tag-bg-image.directive.js → esm2020/lib/directives/a-tag-bg-image.directive.mjs} +3 -3
  22. package/{esm2015/lib/directives/click-outside.directive.js → esm2020/lib/directives/click-outside.directive.mjs} +3 -3
  23. package/{esm2015/lib/directives/description.directive.js → esm2020/lib/directives/description.directive.mjs} +3 -3
  24. package/{esm2015/lib/directives/direction.directive.js → esm2020/lib/directives/direction.directive.mjs} +3 -3
  25. package/{esm2015/lib/directives/directives.js → esm2020/lib/directives/directives.mjs} +0 -0
  26. package/esm2020/lib/directives/fallback-image.directive.mjs +59 -0
  27. package/{esm2015/lib/directives/keyboard-navigation.directive.js → esm2020/lib/directives/keyboard-navigation.directive.mjs} +5 -5
  28. package/{esm2015/lib/directives/margin.directive.js → esm2020/lib/directives/margin.directive.mjs} +3 -3
  29. package/{esm2015/lib/directives/max-size.directive.js → esm2020/lib/directives/max-size.directive.mjs} +3 -3
  30. package/{esm2015/lib/directives/size.directive.js → esm2020/lib/directives/size.directive.mjs} +3 -3
  31. package/{esm2015/lib/directives/wrap.directive.js → esm2020/lib/directives/wrap.directive.mjs} +6 -6
  32. package/{esm2015/lib/modal-gallery.module.js → esm2020/lib/modal-gallery.module.mjs} +10 -13
  33. package/{esm2015/lib/model/accessibility.interface.js → esm2020/lib/model/accessibility.interface.mjs} +0 -0
  34. package/{esm2015/lib/model/action.enum.js → esm2020/lib/model/action.enum.mjs} +0 -0
  35. package/esm2020/lib/model/buttons-config.interface.mjs +62 -0
  36. package/{esm2015/lib/model/carousel-config.interface.js → esm2020/lib/model/carousel-config.interface.mjs} +1 -1
  37. package/{esm2015/lib/model/carousel-image-config.interface.js → esm2020/lib/model/carousel-image-config.interface.mjs} +0 -0
  38. package/{esm2015/lib/model/carousel-preview-config.interface.js → esm2020/lib/model/carousel-preview-config.interface.mjs} +0 -0
  39. package/{esm2015/lib/model/current-image-config.interface.js → esm2020/lib/model/current-image-config.interface.mjs} +0 -0
  40. package/{esm2015/lib/model/description.interface.js → esm2020/lib/model/description.interface.mjs} +0 -0
  41. package/{esm2015/lib/model/dots-config.interface.js → esm2020/lib/model/dots-config.interface.mjs} +0 -0
  42. package/{esm2015/lib/model/image-internal.class.js → esm2020/lib/model/image-internal.class.mjs} +0 -0
  43. package/{esm2015/lib/model/image.class.js → esm2020/lib/model/image.class.mjs} +0 -0
  44. package/{esm2015/lib/model/interaction-event.interface.js → esm2020/lib/model/interaction-event.interface.mjs} +0 -0
  45. package/{esm2015/lib/model/keyboard-config.interface.js → esm2020/lib/model/keyboard-config.interface.mjs} +1 -1
  46. package/{esm2015/lib/model/keyboard-service-config.interface.js → esm2020/lib/model/keyboard-service-config.interface.mjs} +0 -0
  47. package/esm2020/lib/model/keyboard.enum.mjs +35 -0
  48. package/{esm2015/lib/model/lib-config.interface.js → esm2020/lib/model/lib-config.interface.mjs} +1 -1
  49. package/{esm2015/lib/model/loading-config.interface.js → esm2020/lib/model/loading-config.interface.mjs} +0 -0
  50. package/{esm2015/lib/model/max-size.interface.js → esm2020/lib/model/max-size.interface.mjs} +0 -0
  51. package/{esm2015/lib/model/modal-gallery-config.interface.js → esm2020/lib/model/modal-gallery-config.interface.mjs} +1 -1
  52. package/esm2020/lib/model/plain-gallery-config.interface.mjs +55 -0
  53. package/{esm2015/lib/model/play-config.interface.js → esm2020/lib/model/play-config.interface.mjs} +0 -0
  54. package/{esm2015/lib/model/preview-config.interface.js → esm2020/lib/model/preview-config.interface.mjs} +0 -0
  55. package/{esm2015/lib/model/size.interface.js → esm2020/lib/model/size.interface.mjs} +0 -0
  56. package/{esm2015/lib/model/slide-config.interface.js → esm2020/lib/model/slide-config.interface.mjs} +0 -0
  57. package/esm2020/lib/services/config.service.mjs +396 -0
  58. package/esm2020/lib/services/id-validator.service.mjs +71 -0
  59. package/{esm2015/lib/services/keyboard.service.js → esm2020/lib/services/keyboard.service.mjs} +3 -3
  60. package/{esm2015/lib/utils/image.util.js → esm2020/lib/utils/image.util.mjs} +0 -0
  61. package/esm2020/lib/utils/user-input.util.mjs +104 -0
  62. package/esm2020/public-api.mjs +42 -0
  63. package/fesm2015/ks89-angular-modal-gallery.mjs +5782 -0
  64. package/fesm2015/ks89-angular-modal-gallery.mjs.map +1 -0
  65. package/{fesm2015/ks89-angular-modal-gallery.js → fesm2020/ks89-angular-modal-gallery.mjs} +521 -544
  66. package/fesm2020/ks89-angular-modal-gallery.mjs.map +1 -0
  67. package/lib/components/accessible.component.d.ts +2 -2
  68. package/lib/components/carousel/carousel-previews/carousel-previews.component.d.ts +0 -7
  69. package/lib/components/carousel/carousel.component.d.ts +25 -67
  70. package/lib/components/current-image/current-image.component.d.ts +6 -3
  71. package/lib/components/dots/dots.component.d.ts +4 -0
  72. package/lib/components/modal-gallery/modal-gallery-ref.d.ts +35 -0
  73. package/lib/components/modal-gallery/modal-gallery.component.d.ts +53 -49
  74. package/lib/components/modal-gallery/modal-gallery.service.d.ts +57 -1
  75. package/lib/components/plain-gallery/plain-gallery.component.d.ts +16 -10
  76. package/lib/components/previews/previews.component.d.ts +6 -0
  77. package/lib/components/upper-buttons/upper-buttons.component.d.ts +5 -1
  78. package/lib/directives/fallback-image.directive.d.ts +3 -0
  79. package/lib/directives/keyboard-navigation.directive.d.ts +1 -1
  80. package/lib/directives/wrap.directive.d.ts +1 -1
  81. package/lib/model/carousel-config.interface.d.ts +0 -1
  82. package/lib/model/keyboard-config.interface.d.ts +4 -4
  83. package/lib/model/keyboard.enum.d.ts +11 -8
  84. package/lib/model/lib-config.interface.d.ts +20 -7
  85. package/lib/model/modal-gallery-config.interface.d.ts +2 -2
  86. package/lib/model/plain-gallery-config.interface.d.ts +1 -9
  87. package/lib/services/id-validator.service.d.ts +2 -1
  88. package/lib/utils/user-input.util.d.ts +35 -26
  89. package/package.json +27 -14
  90. package/public-api.d.ts +2 -2
  91. package/bundles/ks89-angular-modal-gallery.umd.js +0 -6067
  92. package/bundles/ks89-angular-modal-gallery.umd.js.map +0 -1
  93. package/esm2015/lib/components/carousel/carousel-previews/carousel-previews.component.js +0 -480
  94. package/esm2015/lib/components/carousel/carousel.component.js +0 -800
  95. package/esm2015/lib/components/current-image/current-image.component.js +0 -618
  96. package/esm2015/lib/components/current-image/loading-spinner/loading-spinner.component.js +0 -93
  97. package/esm2015/lib/components/dots/dots.component.js +0 -132
  98. package/esm2015/lib/components/modal-gallery/modal-gallery-ref.js +0 -45
  99. package/esm2015/lib/components/modal-gallery/modal-gallery.component.js +0 -558
  100. package/esm2015/lib/components/modal-gallery/modal-gallery.service.js +0 -131
  101. package/esm2015/lib/components/modal-gallery/modal-gallery.tokens.js +0 -3
  102. package/esm2015/lib/components/plain-gallery/plain-gallery.component.js +0 -253
  103. package/esm2015/lib/components/previews/previews.component.js +0 -338
  104. package/esm2015/lib/components/upper-buttons/upper-buttons.component.js +0 -266
  105. package/esm2015/lib/directives/fallback-image.directive.js +0 -56
  106. package/esm2015/lib/model/buttons-config.interface.js +0 -66
  107. package/esm2015/lib/model/keyboard.enum.js +0 -35
  108. package/esm2015/lib/model/plain-gallery-config.interface.js +0 -64
  109. package/esm2015/lib/services/config.service.js +0 -395
  110. package/esm2015/lib/services/id-validator.service.js +0 -73
  111. package/esm2015/lib/utils/user-input.util.js +0 -95
  112. package/esm2015/public-api.js +0 -46
  113. package/fesm2015/ks89-angular-modal-gallery.js.map +0 -1
@@ -1,480 +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, HostBinding, Input, Output } from '@angular/core';
25
- import { Breakpoints } from '@angular/cdk/layout';
26
- import { AccessibleComponent } from '../../accessible.component';
27
- import { NEXT, PREV } from '../../../utils/user-input.util';
28
- import { getIndex } from '../../../utils/image.util';
29
- import { Action } from '../../../model/action.enum';
30
- import * as i0 from "@angular/core";
31
- import * as i1 from "@angular/cdk/layout";
32
- import * as i2 from "@angular/platform-browser";
33
- import * as i3 from "../../../services/config.service";
34
- import * as i4 from "@angular/common";
35
- import * as i5 from "../../../directives/fallback-image.directive";
36
- import * as i6 from "../../../directives/size.directive";
37
- /**
38
- * Default max height of previews.
39
- */
40
- const DEFAULT_MAX_HEIGHT = '200px';
41
- /**
42
- * Component with image previews for carousel
43
- */
44
- export class CarouselPreviewsComponent extends AccessibleComponent {
45
- constructor(ref, breakpointObserver,
46
- // sanitizer is used only to sanitize style before add it to background property when legacyIE11Mode is enabled
47
- sanitizer, configService) {
48
- super();
49
- this.ref = ref;
50
- this.breakpointObserver = breakpointObserver;
51
- this.sanitizer = sanitizer;
52
- this.configService = configService;
53
- /**
54
- * Variable to change the max-width of the host component
55
- */
56
- this.hostMaxWidth = '100%';
57
- /**
58
- * Variable to set aria-label of the host component
59
- */
60
- this.ariaLabel = `Carousel previews`;
61
- /**
62
- * Output to emit the clicked preview. The payload contains the `InternalLibImage` associated to the clicked preview.
63
- */
64
- this.clickPreview = new EventEmitter();
65
- /**
66
- * Enum of type `Action` that represents a mouse click on a button.
67
- * Declared here to be used inside the template.
68
- */
69
- this.clickAction = Action.CLICK;
70
- /**
71
- * Enum of type `Action` that represents a keyboard action.
72
- * Declared here to be used inside the template.
73
- */
74
- this.keyboardAction = Action.KEYBOARD;
75
- /**
76
- * Array of `InternalLibImage` exposed to the template. This field is initialized
77
- * applying transformations, default values and so on to the input of the same type.
78
- */
79
- this.previews = [];
80
- /**
81
- * Variable with the preview's maxHeight
82
- */
83
- this.previewMaxHeight = DEFAULT_MAX_HEIGHT;
84
- // listen for width changes and update preview heights accordingly
85
- this.breakpointSubscription = breakpointObserver
86
- .observe([Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge])
87
- .subscribe((result) => {
88
- if (!this.previewConfig || !this.previewConfig.breakpoints) {
89
- return;
90
- }
91
- if (result.breakpoints[Breakpoints.XSmall]) {
92
- this.updateHeight(this.previewConfig.breakpoints.xSmall);
93
- }
94
- else if (result.breakpoints[Breakpoints.Small]) {
95
- this.updateHeight(this.previewConfig.breakpoints.small);
96
- }
97
- else if (result.breakpoints[Breakpoints.Medium]) {
98
- this.updateHeight(this.previewConfig.breakpoints.medium);
99
- }
100
- else if (result.breakpoints[Breakpoints.Large]) {
101
- this.updateHeight(this.previewConfig.breakpoints.large);
102
- }
103
- else if (result.breakpoints[Breakpoints.XLarge]) {
104
- this.updateHeight(this.previewConfig.breakpoints.xLarge);
105
- }
106
- });
107
- }
108
- /**
109
- * Method to update the height of previews, passing the desired height as input.
110
- * @param configBreakpointHeight is a number that represent the desired height to set.
111
- */
112
- updateHeight(configBreakpointHeight) {
113
- if (this.previewConfig && this.previewConfig.maxHeight) {
114
- const heightNum = +this.previewConfig.maxHeight.replace('px', '').replace('%', '');
115
- this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px';
116
- }
117
- else {
118
- const heightNum = +DEFAULT_MAX_HEIGHT.replace('px', '').replace('%', '');
119
- this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px';
120
- }
121
- this.ref.markForCheck();
122
- }
123
- /**
124
- * Method ´ngOnInit´ to build `configPreview` applying a default value and also to
125
- * init the `previews` array.
126
- * This is an Angular's lifecycle hook, so its called automatically by Angular itself.
127
- * In particular, it's called only one time!!!
128
- */
129
- ngOnInit() {
130
- const libConfig = this.configService.getConfig(this.id);
131
- if (!libConfig) {
132
- throw new Error('Internal library error - libConfig must be defined');
133
- }
134
- this.carouselConfig = libConfig.carouselConfig;
135
- this.previewConfig = libConfig.carouselPreviewsConfig;
136
- this.accessibilityConfig = libConfig.accessibilityConfig;
137
- if (!this.previewConfig || !this.previewConfig.maxHeight || !this.previewConfig.breakpoints) {
138
- throw new Error('Internal library error - previewConfig must be defined');
139
- }
140
- // change the max-width of this component if there is a specified width !== 100% in carouselConfig
141
- if (this.carouselConfig && this.carouselConfig.maxWidth !== '100%') {
142
- this.hostMaxWidth = this.carouselConfig.maxWidth;
143
- }
144
- this.previewMaxHeight = this.previewConfig.maxHeight;
145
- // init previews based on currentImage and the full array of images
146
- this.initPreviews(this.currentImage, this.images);
147
- // apply custom height based on responsive breakpoints
148
- // This is required, because the breakpointSubscription is not triggered at creation,
149
- // but only when the width changes
150
- const isXsmallScreen = this.breakpointObserver.isMatched(Breakpoints.XSmall);
151
- const isSmallScreen = this.breakpointObserver.isMatched(Breakpoints.Small);
152
- const isMediumScreen = this.breakpointObserver.isMatched(Breakpoints.Medium);
153
- const isLargeScreen = this.breakpointObserver.isMatched(Breakpoints.Large);
154
- const isxLargeScreen = this.breakpointObserver.isMatched(Breakpoints.XLarge);
155
- if (isXsmallScreen) {
156
- this.updateHeight(this.previewConfig.breakpoints.xSmall);
157
- }
158
- else if (isSmallScreen) {
159
- this.updateHeight(this.previewConfig.breakpoints.small);
160
- }
161
- else if (isMediumScreen) {
162
- this.updateHeight(this.previewConfig.breakpoints.medium);
163
- }
164
- else if (isLargeScreen) {
165
- this.updateHeight(this.previewConfig.breakpoints.large);
166
- }
167
- else if (isxLargeScreen) {
168
- this.updateHeight(this.previewConfig.breakpoints.xLarge);
169
- }
170
- }
171
- /**
172
- * Method to check if an image is active (i.e. a preview image).
173
- * @param InternalLibImage preview is an image to check if it's active or not
174
- * @returns boolean true if is active, false otherwise
175
- */
176
- isActive(preview) {
177
- if (!preview || !this.currentImage) {
178
- return false;
179
- }
180
- return preview.id === this.currentImage.id;
181
- }
182
- /**
183
- * Method ´ngOnChanges´ to update `previews` array.
184
- * Also, both `start` and `end` local variables will be updated accordingly.
185
- * This is an Angular's lifecycle hook, so its called automatically by Angular itself.
186
- * In particular, it's called when any data-bound property of a directive changes!!!
187
- */
188
- ngOnChanges(changes) {
189
- const simpleChange = changes.currentImage;
190
- if (!simpleChange) {
191
- return;
192
- }
193
- const prev = simpleChange.previousValue;
194
- const current = simpleChange.currentValue;
195
- if (current && changes.images && changes.images.previousValue && changes.images.currentValue) {
196
- // I'm in this if statement, if input images are changed (for instance, because I removed one of them with the 'delete button',
197
- // or because users changed the images array while modal gallery is still open).
198
- // In this case, I have to re-init previews, because the input array of images is changed.
199
- this.initPreviews(current, changes.images.currentValue);
200
- }
201
- if (prev && current && prev.id !== current.id) {
202
- // to manage infinite sliding I have to reset both `start` and `end` at the beginning
203
- // to show again previews from the first image.
204
- // This happens when you navigate over the last image to return to the first one
205
- let prevIndex;
206
- let currentIndex;
207
- try {
208
- prevIndex = getIndex(prev, this.images);
209
- currentIndex = getIndex(current, this.images);
210
- }
211
- catch (err) {
212
- console.error('Cannot get previous and current image indexes in previews');
213
- throw err;
214
- }
215
- // apply a formula to get a values to be used to decide if go next, return back or stay without doing anything
216
- const calc = Math.floor((this.end - this.start) / 2) + this.start;
217
- if (prevIndex === this.images.length - 1 && currentIndex === 0) {
218
- // first image
219
- this.setBeginningIndexesPreviews();
220
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
221
- return;
222
- }
223
- // the same for the opposite case, when you navigate back from the fist image to go to the last one.
224
- if (prevIndex === 0 && currentIndex === this.images.length - 1) {
225
- // last image
226
- this.setEndIndexesPreviews();
227
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
228
- return;
229
- }
230
- if (this.previewConfig && this.previewConfig.number % 2 === 0) {
231
- if (calc > currentIndex) {
232
- this.previous();
233
- }
234
- else {
235
- this.next();
236
- }
237
- }
238
- else {
239
- if (calc > currentIndex) {
240
- this.previous();
241
- }
242
- if (calc < currentIndex) {
243
- this.next();
244
- }
245
- }
246
- }
247
- }
248
- /**
249
- * Method called by events from both keyboard and mouse on a preview.
250
- * This will trigger the `clickpreview` output with the input preview as its payload.
251
- * @param InternalLibImage preview that triggered this method
252
- * @param KeyboardEvent | MouseEvent event payload
253
- * @param Action that triggered this event (Action.NORMAL by default)
254
- */
255
- onImageEvent(preview, event, action = Action.NORMAL) {
256
- if (!this.previewConfig || !this.previewConfig.clickable) {
257
- return;
258
- }
259
- const clickedImageIndex = this.images.indexOf(preview);
260
- const result = super.handleImageEvent(event);
261
- if (result === NEXT) {
262
- this.clickPreview.emit({ action, result: clickedImageIndex });
263
- }
264
- else if (result === PREV) {
265
- this.clickPreview.emit({ action, result: clickedImageIndex });
266
- }
267
- }
268
- /**
269
- * Method called by events from both keyboard and mouse on a navigation arrow.
270
- * @param string direction of the navigation that can be either 'next' or 'prev'
271
- * @param KeyboardEvent | MouseEvent event payload
272
- */
273
- onNavigationEvent(direction, event) {
274
- const result = super.handleNavigationEvent(direction, event);
275
- if (result === NEXT) {
276
- this.next();
277
- }
278
- else if (result === PREV) {
279
- this.previous();
280
- }
281
- }
282
- /**
283
- * Method to get aria-label text for a preview image.
284
- * @param Image is the preview
285
- */
286
- getAriaLabel(preview) {
287
- if (!preview.plain) {
288
- return preview.modal.ariaLabel || '';
289
- }
290
- return preview.plain.ariaLabel || preview.modal.ariaLabel || '';
291
- }
292
- /**
293
- * Method to get title text for a preview image.
294
- * @param Image is the preview
295
- */
296
- getTitle(preview) {
297
- if (!preview.plain) {
298
- return preview.modal.title || '';
299
- }
300
- return preview.plain.title || preview.modal.title || '';
301
- }
302
- /**
303
- * Method to get alt text for a preview image.
304
- * @param Image is the preview
305
- */
306
- getAlt(preview) {
307
- if (!preview.plain) {
308
- return preview.modal.alt || '';
309
- }
310
- return preview.plain.alt || preview.modal.alt || '';
311
- }
312
- /**
313
- * Method used in the template to track ids in ngFor.
314
- * @param number index of the array
315
- * @param Image item of the array
316
- * @returns number the id of the item
317
- */
318
- trackById(index, item) {
319
- return item.id;
320
- }
321
- /**
322
- * Method used in template to sanitize an url when you need legacyIE11Mode.
323
- * In this way you can set an url as background of a div.
324
- * @param unsafeStyle is a string or a SafeResourceUrl that represents the url to sanitize.
325
- * @param unsafeStyleFallback is a string or a SafeResourceUrl that represents the fallback url to sanitize.
326
- * @returns a SafeStyle object that can be used in template without problems.
327
- */
328
- sanitizeUrlBgStyle(unsafeStyle, unsafeStyleFallback) {
329
- // Method used only to sanitize background-image style before add it to background property when legacyIE11Mode is enabled
330
- let bg = 'url(' + unsafeStyle + ')';
331
- if (!!unsafeStyleFallback) {
332
- // if a fallback image is defined, append it. In this way, it will be used by the browser as fallback.
333
- bg += ', ' + 'url(' + unsafeStyleFallback + ')';
334
- }
335
- return this.sanitizer.bypassSecurityTrustStyle(bg);
336
- }
337
- /**
338
- * Method to get the background-size value when IE11LegacyMode is enabled.
339
- * This prevent weired behaviour on IE11 when previews are really small, but original images (.png/.jgp/...) are big.
340
- * Using 'cover' it's not enough, because it's causing empty background in some cases.
341
- * After some experiments, I decided to use the double of the height and auto as width.
342
- */
343
- getIE11LegacyBgSize() {
344
- if (this.previewConfig && this.previewConfig.maxHeight) {
345
- const bgHeight = +this.previewConfig.maxHeight.replace('px', '');
346
- return '100% ' + bgHeight * 2 + 'px';
347
- }
348
- return 'cover';
349
- }
350
- /**
351
- * Method to cleanup resources. In fact, it cleans breakpointSubscription.
352
- * This is an Angular's lifecycle hook that is called when this component is destroyed.
353
- */
354
- ngOnDestroy() {
355
- if (this.breakpointSubscription) {
356
- this.breakpointSubscription.unsubscribe();
357
- }
358
- }
359
- /**
360
- * Private method to init previews based on the currentImage and the full array of images.
361
- * The current image in mandatory to show always the current preview (as highlighted).
362
- * @param InternalLibImage currentImage to decide how to show previews, because I always want to see the current image as highlighted
363
- * @param InternalLibImage[] images is the array of all images.
364
- */
365
- initPreviews(currentImage, images) {
366
- let index;
367
- try {
368
- index = getIndex(currentImage, images);
369
- }
370
- catch (err) {
371
- throw err;
372
- }
373
- switch (index) {
374
- case 0:
375
- // first image
376
- this.setBeginningIndexesPreviews();
377
- break;
378
- case images.length - 1:
379
- // last image
380
- this.setEndIndexesPreviews();
381
- break;
382
- // default:
383
- // // other images
384
- // // TODO unused because it starts always at image 0
385
- // this.setIndexesPreviews();
386
- // break;
387
- }
388
- this.previews = images.filter((img, i) => i >= this.start && i < this.end);
389
- }
390
- /**
391
- * Private method to init both `start` and `end` to the beginning.
392
- */
393
- setBeginningIndexesPreviews() {
394
- if (!this.previewConfig || this.previewConfig.number === undefined) {
395
- throw new Error('Internal library error - previewConfig and number must be defined');
396
- }
397
- this.start = 0;
398
- this.end = Math.min(this.previewConfig.number, this.images.length);
399
- }
400
- /**
401
- * Private method to init both `start` and `end` to the end.
402
- */
403
- setEndIndexesPreviews() {
404
- if (!this.previewConfig || this.previewConfig.number === undefined) {
405
- throw new Error('Internal library error - previewConfig and number must be defined');
406
- }
407
- this.start = this.images.length - 1 - (this.previewConfig.number - 1);
408
- this.end = this.images.length;
409
- }
410
- /**
411
- * Private method to update the visible previews navigating to the right (next).
412
- */
413
- next() {
414
- // check if nextImage should be blocked
415
- if (this.isPreventSliding(this.images.length - 1)) {
416
- return;
417
- }
418
- if (this.end === this.images.length) {
419
- return;
420
- }
421
- this.start++;
422
- this.end = Math.min(this.end + 1, this.images.length);
423
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
424
- }
425
- /**
426
- * Private method to update the visible previews navigating to the left (previous).
427
- */
428
- previous() {
429
- // check if prevImage should be blocked
430
- if (this.isPreventSliding(0)) {
431
- return;
432
- }
433
- if (this.start === 0) {
434
- return;
435
- }
436
- this.start = Math.max(this.start - 1, 0);
437
- this.end = Math.min(this.end - 1, this.images.length);
438
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
439
- }
440
- /**
441
- * Private method to block/permit sliding between previews.
442
- * @param number boundaryIndex is the first or the last index of `images` input array
443
- * @returns boolean if true block sliding, otherwise not
444
- */
445
- isPreventSliding(boundaryIndex) {
446
- return getIndex(this.currentImage, this.images) === boundaryIndex;
447
- }
448
- }
449
- CarouselPreviewsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: CarouselPreviewsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.BreakpointObserver }, { token: i2.DomSanitizer }, { token: i3.ConfigService }], target: i0.ɵɵFactoryTarget.Component });
450
- CarouselPreviewsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.3", type: CarouselPreviewsComponent, selector: "ks-carousel-previews", inputs: { id: "id", currentImage: "currentImage", images: "images" }, outputs: { clickPreview: "clickPreview" }, host: { properties: { "style.max-width": "this.hostMaxWidth", "attr.aria-label": "this.ariaLabel" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<nav *ngIf=\"previewConfig?.visible\"\n class=\"previews-container\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewsContainerAriaLabel\"\n [title]=\"accessibilityConfig?.carouselPreviewsContainerTitle\">\n\n <a class=\"nav-left\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollPrevAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && start > 0 ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('left', $event)\" (keyup)=\"onNavigationEvent('left', $event)\">\n <div class=\"inside {{previewConfig?.arrows && start > 0 ? 'left-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollPrevTitle\"></div>\n </a>\n\n <div class=\"preview-inner-container\">\n <ng-container *ngFor=\"let preview of previews; trackBy: trackById; let index = index\">\n <ng-container *ngIf=\"!carouselConfig?.legacyIE11Mode; else legacyMode\">\n <img *ngIf=\"preview?.modal?.img\"\n class=\"inside preview-image{{isActive(preview) ? ' active' : ''}}{{!previewConfig?.clickable ? ' unclickable' : ''}}\"\n [src]=\"preview.plain?.img ? preview.plain?.img : preview.modal.img\"\n ksFallbackImage [fallbackImg]=\"preview.plain?.fallbackImg ? preview.plain?.fallbackImg : preview.modal.fallbackImg\"\n ksSize [sizeConfig]=\"{width: previewConfig?.width!,\n height: previewMaxHeight}\"\n [attr.aria-label]=\"getAriaLabel(preview)\"\n [title]=\"getTitle(preview)\"\n alt=\"{{getAlt(preview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onImageEvent(preview, $event, clickAction)\" (keyup)=\"onImageEvent(preview, $event, keyboardAction)\"/>\n </ng-container>\n <ng-template #legacyMode>\n <div *ngIf=\"preview?.modal?.img\"\n class=\"inside preview-ie11-image{{isActive(preview) ? ' active' : ''}}{{!previewConfig?.clickable ? ' unclickable' : ''}}\"\n [style.background-color]=\"'transparent'\"\n [style.background-image]=\"sanitizeUrlBgStyle(\n preview.plain?.img ? preview.plain?.img : preview.modal.img,\n preview.plain?.fallbackImg ? preview.plain?.fallbackImg : preview.modal.fallbackImg)\"\n [style.background-position]=\"'center center'\"\n [style.background-size]=\"getIE11LegacyBgSize()\"\n [style.background-repeat]=\"'no-repeat'\"\n [style.background-attachment]=\"'scroll'\"\n ksSize [sizeConfig]=\"{width: previewConfig?.width!,\n height: previewMaxHeight}\"\n [attr.aria-label]=\"getAriaLabel(preview)\"\n [title]=\"getTitle(preview)\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onImageEvent(preview, $event, clickAction)\" (keyup)=\"onImageEvent(preview, $event, keyboardAction)\"></div>\n </ng-template>\n </ng-container>\n </div>\n\n <a class=\"nav-right\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollNextAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && end < images.length ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('right', $event)\" (keyup)=\"onNavigationEvent('right', $event)\">\n <div class=\"inside {{previewConfig?.arrows && end < images.length ? 'right-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollNextTitle\"></div>\n </a>\n\n</nav>\n", styles: [":host{position:relative;margin-top:3px;margin-bottom:3px;width:100%}.previews-container{animation:fadein-semi-visible08 .8s;margin-bottom:0}.previews-container,.previews-container>.preview-inner-container{align-items:center;display:flex;flex-direction:row;justify-content:center}.previews-container>.preview-inner-container{flex-wrap:nowrap;width:100%}.previews-container>.preview-inner-container>.preview-image{cursor:pointer;object-fit:cover}.previews-container>.preview-inner-container>.preview-image.unclickable{cursor:not-allowed}.previews-container>.preview-inner-container>.preview-ie11-image{cursor:pointer}.previews-container>.preview-inner-container>.preview-ie11-image.unclickable{cursor:not-allowed}.previews-container .nav,.previews-container>.nav-left,.previews-container>.nav-right{position:absolute;top:calc(50% - 7px);color:#919191;z-index:1000;cursor:pointer;transition:all .5s}.previews-container .nav:hover,.previews-container>.nav-left:hover,.previews-container>.nav-right:hover{transform:scale(1.1)}.previews-container>.nav-left{margin-right:10px;left:10px}.previews-container>.nav-left>.left-arrow-preview-image{opacity:1}.previews-container>.nav-right{margin-left:10px;right:10px}.previews-container>.nav-right>.right-arrow-preview-image{opacity:1}", ".arrow-preview-image,.empty-arrow-preview-image,.left-arrow-preview-image,.right-arrow-preview-image{width:15px;height:15px;opacity:.5}.empty-arrow-preview-image{background:#000;opacity:0}.left-arrow-preview-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");background-size:15px;transition:all .5s}.left-arrow-preview-image:hover{transform:scale(1.2)}.right-arrow-preview-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");background-size:15px;transition:all .5s}.right-arrow-preview-image:hover{transform:scale(1.2)}"], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.FallbackImageDirective, selector: "[ksFallbackImage]", inputs: ["fallbackImg"], outputs: ["fallbackApplied"] }, { type: i6.SizeDirective, selector: "[ksSize]", inputs: ["sizeConfig"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
451
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.3", ngImport: i0, type: CarouselPreviewsComponent, decorators: [{
452
- type: Component,
453
- args: [{
454
- selector: 'ks-carousel-previews',
455
- styleUrls: ['carousel-previews.scss', '../../previews-arrows.scss'],
456
- templateUrl: 'carousel-previews.html',
457
- changeDetection: ChangeDetectionStrategy.OnPush
458
- }]
459
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.BreakpointObserver }, { type: i2.DomSanitizer }, { type: i3.ConfigService }]; }, propDecorators: { hostMaxWidth: [{
460
- type: HostBinding,
461
- args: ['style.max-width']
462
- }], ariaLabel: [{
463
- type: HostBinding,
464
- args: ['attr.aria-label']
465
- }],
466
- // @ts-ignore
467
- id: [{
468
- type: Input
469
- }],
470
- // @ts-ignore
471
- currentImage: [{
472
- type: Input
473
- }],
474
- // @ts-ignore
475
- images: [{
476
- type: Input
477
- }], clickPreview: [{
478
- type: Output
479
- }] } });
480
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwtcHJldmlld3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3M4OS9hbmd1bGFyLW1vZGFsLWdhbGxlcnkvc3JjL2xpYi9jb21wb25lbnRzL2Nhcm91c2VsL2Nhcm91c2VsLXByZXZpZXdzL2Nhcm91c2VsLXByZXZpZXdzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tzODkvYW5ndWxhci1tb2RhbC1nYWxsZXJ5L3NyYy9saWIvY29tcG9uZW50cy9jYXJvdXNlbC9jYXJvdXNlbC1wcmV2aWV3cy9jYXJvdXNlbC1wcmV2aWV3cy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBSUwsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBc0IsV0FBVyxFQUFtQixNQUFNLHFCQUFxQixDQUFDO0FBSXZGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBUWpFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7QUFJcEQ7O0dBRUc7QUFDSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUVuQzs7R0FFRztBQU9ILE1BQU0sT0FBTyx5QkFBMEIsU0FBUSxtQkFBbUI7SUFzRmhFLFlBQ1UsR0FBc0IsRUFDdEIsa0JBQXNDO0lBQzlDLCtHQUErRztJQUN2RyxTQUF1QixFQUN2QixhQUE0QjtRQUVwQyxL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VClcblxuIENvcHlyaWdodCAoQykgMjAxNy0yMDIxIFN0ZWZhbm8gQ2FwcGEgKEtzODkpXG5cbiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cbiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTiBJTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZSxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsLCBTYWZlU3R5bGUgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IEJyZWFrcG9pbnRPYnNlcnZlciwgQnJlYWtwb2ludHMsIEJyZWFrcG9pbnRTdGF0ZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9sYXlvdXQnO1xuXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQWNjZXNzaWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2FjY2Vzc2libGUuY29tcG9uZW50JztcblxuaW1wb3J0IHsgQWNjZXNzaWJpbGl0eUNvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2FjY2Vzc2liaWxpdHkuaW50ZXJmYWNlJztcbmltcG9ydCB7IEltYWdlLCBJbWFnZUV2ZW50IH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvaW1hZ2UuY2xhc3MnO1xuaW1wb3J0IHsgSW50ZXJuYWxMaWJJbWFnZSB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2ltYWdlLWludGVybmFsLmNsYXNzJztcbmltcG9ydCB7IENhcm91c2VsUHJldmlld0NvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2Nhcm91c2VsLXByZXZpZXctY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDYXJvdXNlbENvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2Nhcm91c2VsLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5pbXBvcnQgeyBORVhULCBQUkVWIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvdXNlci1pbnB1dC51dGlsJztcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvaW1hZ2UudXRpbCc7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9tb2RlbC9hY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGliQ29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvbGliLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIERlZmF1bHQgbWF4IGhlaWdodCBvZiBwcmV2aWV3cy5cbiAqL1xuY29uc3QgREVGQVVMVF9NQVhfSEVJR0hUID0gJzIwMHB4JztcblxuLyoqXG4gKiBDb21wb25lbnQgd2l0aCBpbWFnZSBwcmV2aWV3cyBmb3IgY2Fyb3VzZWxcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAna3MtY2Fyb3VzZWwtcHJldmlld3MnLFxuICBzdHlsZVVybHM6IFsnY2Fyb3VzZWwtcHJldmlld3Muc2NzcycsICcuLi8uLi9wcmV2aWV3cy1hcnJvd3Muc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJ2Nhcm91c2VsLXByZXZpZXdzLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBDYXJvdXNlbFByZXZpZXdzQ29tcG9uZW50IGV4dGVuZHMgQWNjZXNzaWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogVmFyaWFibGUgdG8gY2hhbmdlIHRoZSBtYXgtd2lkdGggb2YgdGhlIGhvc3QgY29tcG9uZW50XG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ3N0eWxlLm1heC13aWR0aCcpXG4gIGhvc3RNYXhXaWR0aCA9ICcxMDAlJztcblxuICAvKipcbiAgICogVmFyaWFibGUgdG8gc2V0IGFyaWEtbGFiZWwgb2YgdGhlIGhvc3QgY29tcG9uZW50XG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1sYWJlbCcpXG4gIGFyaWFMYWJlbCA9IGBDYXJvdXNlbCBwcmV2aWV3c2A7XG5cbiAgLyoqXG4gICAqIFRPRE8gd3JpdGUgZG9jXG4gICAqL1xuICBASW5wdXQoKVxuICAvLyBAdHMtaWdub3JlXG4gIGlkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgSW50ZXJuYWxMaWJJbWFnZWAgdGhhdCByZXByZXNlbnQgdGhlIHZpc2libGUgaW1hZ2UuXG4gICAqL1xuICBASW5wdXQoKVxuICAvLyBAdHMtaWdub3JlXG4gIGN1cnJlbnRJbWFnZTogSW50ZXJuYWxMaWJJbWFnZTtcbiAgLyoqXG4gICAqIEFycmF5IG9mIGBJbnRlcm5hbExpYkltYWdlYCB0aGF0IHJlcHJlc2VudCB0aGUgbW9kZWwgb2YgdGhpcyBsaWJyYXJ5IHdpdGggYWxsIGltYWdlcyxcbiAgICogdGh1bWJzIGFuZCBzbyBvbi5cbiAgICovXG4gIEBJbnB1dCgpXG4gIC8vIEB0cy1pZ25vcmVcbiAgaW1hZ2VzOiBJbnRlcm5hbExpYkltYWdlW107XG5cbiAgLyoqXG4gICAqIE91dHB1dCB0byBlbWl0IHRoZSBjbGlja2VkIHByZXZpZXcuIFRoZSBwYXlsb2FkIGNvbnRhaW5zIHRoZSBgSW50ZXJuYWxMaWJJbWFnZWAgYXNzb2NpYXRlZCB0byB0aGUgY2xpY2tlZCBwcmV2aWV3LlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGNsaWNrUHJldmlldzogRXZlbnRFbWl0dGVyPEltYWdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWFnZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgQ2Fyb3VzZWxDb25maWdgIHRvIGluaXQgQ2Fyb3VzZWxDb21wb25lbnQncyBmZWF0dXJlcy5cbiAgICogRm9yIGluc3RhbmNlLCBpdCBjb250YWlucyBwYXJhbWV0ZXJzIHRvIGNoYW5nZSB0aGUgc3R5bGUsIGhvdyBpdCBuYXZpZ2F0ZXMgYW5kIHNvIG9uLlxuICAgKi9cbiAgY2Fyb3VzZWxDb25maWc6IENhcm91c2VsQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYENhcm91c2VsUHJldmlld0NvbmZpZ2AgdG8gaW5pdCBQcmV2aWV3c0NvbXBvbmVudCdzIGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIGEgcGFyYW0gdG8gc2hvdy9oaWRlIHRoaXMgY29tcG9uZW50LCBzaXplcy5cbiAgICovXG4gIHByZXZpZXdDb25maWc6IENhcm91c2VsUHJldmlld0NvbmZpZyB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBBY2Nlc3NpYmlsaXR5Q29uZmlnYCB0byBpbml0IGN1c3RvbSBhY2Nlc3NpYmlsaXR5IGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIHRpdGxlcywgYWx0IHRleHRzLCBhcmlhLWxhYmVscyBhbmQgc28gb24uXG4gICAqL1xuICBhY2Nlc3NpYmlsaXR5Q29uZmlnOiBBY2Nlc3NpYmlsaXR5Q29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyBhIG1vdXNlIGNsaWNrIG9uIGEgYnV0dG9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGNsaWNrQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uQ0xJQ0s7XG4gIC8qKlxuICAgKiBFbnVtIG9mIHR5cGUgYEFjdGlvbmAgdGhhdCByZXByZXNlbnRzIGEga2V5Ym9hcmQgYWN0aW9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGtleWJvYXJkQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uS0VZQk9BUkQ7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBgSW50ZXJuYWxMaWJJbWFnZWAgZXhwb3NlZCB0byB0aGUgdGVtcGxhdGUuIFRoaXMgZmllbGQgaXMgaW5pdGlhbGl6ZWRcbiAgICogYXBwbHlpbmcgdHJhbnNmb3JtYXRpb25zLCBkZWZhdWx0IHZhbHVlcyBhbmQgc28gb24gdG8gdGhlIGlucHV0IG9mIHRoZSBzYW1lIHR5cGUuXG4gICAqL1xuICBwcmV2aWV3czogSW50ZXJuYWxMaWJJbWFnZVtdID0gW107XG4gIC8qKlxuICAgKiBWYXJpYWJsZSB3aXRoIHRoZSBwcmV2aWV3J3MgbWF4SGVpZ2h0XG4gICAqL1xuICBwcmV2aWV3TWF4SGVpZ2h0OiBzdHJpbmcgPSBERUZBVUxUX01BWF9IRUlHSFQ7XG4gIC8qKlxuICAgKiBTdGFydCBpbmRleCAoaW5jbHVzaXZlKSBvZiB0aGUgaW5wdXQgaW1hZ2VzIHVzZWQgdG8gZGlzcGxheSBwcmV2aWV3cy5cbiAgICovXG4gIC8vIEB0cy1pZ25vcmVcbiAgc3RhcnQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIEVuZCBpbmRleCAobm9uIGluY2x1c2l2ZSkgb2YgdGhlIGlucHV0IGltYWdlcyB1c2VkIHRvIGRpc3BsYXkgcHJldmlld3MuXG4gICAqL1xuICAvLyBAdHMtaWdub3JlXG4gIGVuZDogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYnJlYWtwb2ludFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIGJyZWFrcG9pbnRPYnNlcnZlcjogQnJlYWtwb2ludE9ic2VydmVyLFxuICAgIC8vIHNhbml0aXplciBpcyB1c2VkIG9ubHkgdG8gc2FuaXRpemUgc3R5bGUgYmVmb3JlIGFkZCBpdCB0byBiYWNrZ3JvdW5kIHByb3BlcnR5IHdoZW4gbGVnYWN5SUUxMU1vZGUgaXMgZW5hYmxlZFxuICAgIHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXG4gICAgcHJpdmF0ZSBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvLyBsaXN0ZW4gZm9yIHdpZHRoIGNoYW5nZXMgYW5kIHVwZGF0ZSBwcmV2aWV3IGhlaWdodHMgYWNjb3JkaW5nbHlcbiAgICB0aGlzLmJyZWFrcG9pbnRTdWJzY3JpcHRpb24gPSBicmVha3BvaW50T2JzZXJ2ZXJcbiAgICAgIC5vYnNlcnZlKFtCcmVha3BvaW50cy5YU21hbGwsIEJyZWFrcG9pbnRzLlNtYWxsLCBCcmVha3BvaW50cy5NZWRpdW0sIEJyZWFrcG9pbnRzLkxhcmdlLCBCcmVha3BvaW50cy5YTGFyZ2VdKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0OiBCcmVha3BvaW50U3RhdGUpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnByZXZpZXdDb25maWcgfHwgIXRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LmJyZWFrcG9pbnRzW0JyZWFrcG9pbnRzLlhTbWFsbF0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMueFNtYWxsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuYnJlYWtwb2ludHNbQnJlYWtwb2ludHMuU21hbGxdKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnNtYWxsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuYnJlYWtwb2ludHNbQnJlYWtwb2ludHMuTWVkaXVtXSkge1xuICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5tZWRpdW0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5MYXJnZV0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMubGFyZ2UpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5YTGFyZ2VdKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnhMYXJnZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byB1cGRhdGUgdGhlIGhlaWdodCBvZiBwcmV2aWV3cywgcGFzc2luZyB0aGUgZGVzaXJlZCBoZWlnaHQgYXMgaW5wdXQuXG4gICAqIEBwYXJhbSBjb25maWdCcmVha3BvaW50SGVpZ2h0IGlzIGEgbnVtYmVyIHRoYXQgcmVwcmVzZW50IHRoZSBkZXNpcmVkIGhlaWdodCB0byBzZXQuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUhlaWdodChjb25maWdCcmVha3BvaW50SGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wcmV2aWV3Q29uZmlnICYmIHRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQpIHtcbiAgICAgIGNvbnN0IGhlaWdodE51bTogbnVtYmVyID0gK3RoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQucmVwbGFjZSgncHgnLCAnJykucmVwbGFjZSgnJScsICcnKTtcbiAgICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IE1hdGgubWluKGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQsIGhlaWdodE51bSkgKyAncHgnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoZWlnaHROdW06IG51bWJlciA9ICtERUZBVUxUX01BWF9IRUlHSFQucmVwbGFjZSgncHgnLCAnJykucmVwbGFjZSgnJScsICcnKTtcbiAgICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IE1hdGgubWluKGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQsIGhlaWdodE51bSkgKyAncHgnO1xuICAgIH1cbiAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgwrRuZ09uSW5pdMK0IHRvIGJ1aWxkIGBjb25maWdQcmV2aWV3YCBhcHBseWluZyBhIGRlZmF1bHQgdmFsdWUgYW5kIGFsc28gdG9cbiAgICogaW5pdCB0aGUgYHByZXZpZXdzYCBhcnJheS5cbiAgICogVGhpcyBpcyBhbiBBbmd1bGFyJ3MgbGlmZWN5Y2xlIGhvb2ssIHNvIGl0cyBjYWxsZWQgYXV0b21hdGljYWxseSBieSBBbmd1bGFyIGl0c2VsZi5cbiAgICogSW4gcGFydGljdWxhciwgaXQncyBjYWxsZWQgb25seSBvbmUgdGltZSEhIVxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3QgbGliQ29uZmlnOiBMaWJDb25maWcgfCB1bmRlZmluZWQgPSB0aGlzLmNvbmZpZ1NlcnZpY2UuZ2V0Q29uZmlnKHRoaXMuaWQpO1xuICAgIGlmICghbGliQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBsaWJDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHRoaXMuY2Fyb3VzZWxDb25maWcgPSBsaWJDb25maWcuY2Fyb3VzZWxDb25maWc7XG4gICAgdGhpcy5wcmV2aWV3Q29uZmlnID0gbGliQ29uZmlnLmNhcm91c2VsUHJldmlld3NDb25maWc7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5Q29uZmlnID0gbGliQ29uZmlnLmFjY2Vzc2liaWxpdHlDb25maWc7XG5cbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLm1heEhlaWdodCB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBwcmV2aWV3Q29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICAvLyBjaGFuZ2UgdGhlIG1heC13aWR0aCBvZiB0aGlzIGNvbXBvbmVudCBpZiB0aGVyZSBpcyBhIHNwZWNpZmllZCB3aWR0aCAhPT0gMTAwJSBpbiBjYXJvdXNlbENvbmZpZ1xuICAgIGlmICh0aGlzLmNhcm91c2VsQ29uZmlnICYmIHRoaXMuY2Fyb3VzZWxDb25maWcubWF4V2lkdGggIT09ICcxMDAlJykge1xuICAgICAgdGhpcy5ob3N0TWF4V2lkdGggPSB0aGlzLmNhcm91c2VsQ29uZmlnLm1heFdpZHRoO1xuICAgIH1cblxuICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IHRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQ7XG4gICAgLy8gaW5pdCBwcmV2aWV3cyBiYXNlZCBvbiBjdXJyZW50SW1hZ2UgYW5kIHRoZSBmdWxsIGFycmF5IG9mIGltYWdlc1xuICAgIHRoaXMuaW5pdFByZXZpZXdzKHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG5cbiAgICAvLyBhcHBseSBjdXN0b20gaGVpZ2h0IGJhc2VkIG9uIHJlc3BvbnNpdmUgYnJlYWtwb2ludHNcbiAgICAvLyBUaGlzIGlzIHJlcXVpcmVkLCBiZWNhdXNlIHRoZSBicmVha3BvaW50U3Vic2NyaXB0aW9uIGlzIG5vdCB0cmlnZ2VyZWQgYXQgY3JlYXRpb24sXG4gICAgLy8gYnV0IG9ubHkgd2hlbiB0aGUgd2lkdGggY2hhbmdlc1xuICAgIGNvbnN0IGlzWHNtYWxsU2NyZWVuID0gdGhpcy5icmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLlhTbWFsbCk7XG4gICAgY29uc3QgaXNTbWFsbFNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5TbWFsbCk7XG4gICAgY29uc3QgaXNNZWRpdW1TY3JlZW4gPSB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlci5pc01hdGNoZWQoQnJlYWtwb2ludHMuTWVkaXVtKTtcbiAgICBjb25zdCBpc0xhcmdlU2NyZWVuID0gdGhpcy5icmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLkxhcmdlKTtcbiAgICBjb25zdCBpc3hMYXJnZVNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5YTGFyZ2UpO1xuICAgIGlmIChpc1hzbWFsbFNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnhTbWFsbCk7XG4gICAgfSBlbHNlIGlmIChpc1NtYWxsU2NyZWVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMuc21hbGwpO1xuICAgIH0gZWxzZSBpZiAoaXNNZWRpdW1TY3JlZW4pIHtcbiAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5tZWRpdW0pO1xuICAgIH0gZWxzZSBpZiAoaXNMYXJnZVNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLmxhcmdlKTtcbiAgICB9IGVsc2UgaWYgKGlzeExhcmdlU2NyZWVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMueExhcmdlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGNoZWNrIGlmIGFuIGltYWdlIGlzIGFjdGl2ZSAoaS5lLiBhIHByZXZpZXcgaW1hZ2UpLlxuICAgKiBAcGFyYW0gSW50ZXJuYWxMaWJJbWFnZSBwcmV2aWV3IGlzIGFuIGltYWdlIHRvIGNoZWNrIGlmIGl0J3MgYWN0aXZlIG9yIG5vdFxuICAgKiBAcmV0dXJucyBib29sZWFuIHRydWUgaWYgaXMgYWN0aXZlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIGlzQWN0aXZlKHByZXZpZXc6IEludGVybmFsTGliSW1hZ2UpOiBib29sZWFuIHtcbiAgICBpZiAoIXByZXZpZXcgfHwgIXRoaXMuY3VycmVudEltYWdlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBwcmV2aWV3LmlkID09PSB0aGlzLmN1cnJlbnRJbWFnZS5pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgwrRuZ09uQ2hhbmdlc8K0IHRvIHVwZGF0ZSBgcHJldmlld3NgIGFycmF5LlxuICAgKiBBbHNvLCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIGxvY2FsIHZhcmlhYmxlcyB3aWxsIGJlIHVwZGF0ZWQgYWNjb3JkaW5nbHkuXG4gICAqIFRoaXMgaXMgYW4gQW5ndWxhcidzIGxpZmVjeWNsZSBob29rLCBzbyBpdHMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgQW5ndWxhciBpdHNlbGYuXG4gICAqIEluIHBhcnRpY3VsYXIsIGl0J3MgY2FsbGVkIHdoZW4gYW55IGRhdGEtYm91bmQgcHJvcGVydHkgb2YgYSBkaXJlY3RpdmUgY2hhbmdlcyEhIVxuICAgKi9cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHNpbXBsZUNoYW5nZTogU2ltcGxlQ2hhbmdlID0gY2hhbmdlcy5jdXJyZW50SW1hZ2U7XG4gICAgaWYgKCFzaW1wbGVDaGFuZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2OiBJbnRlcm5hbExpYkltYWdlID0gc2ltcGxlQ2hhbmdlLnByZXZpb3VzVmFsdWU7XG4gICAgY29uc3QgY3VycmVudDogSW50ZXJuYWxMaWJJbWFnZSA9IHNpbXBsZUNoYW5nZS5jdXJyZW50VmFsdWU7XG5cbiAgICBpZiAoY3VycmVudCAmJiBjaGFuZ2VzLmltYWdlcyAmJiBjaGFuZ2VzLmltYWdlcy5wcmV2aW91c1ZhbHVlICYmIGNoYW5nZXMuaW1hZ2VzLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgLy8gSSdtIGluIHRoaXMgaWYgc3RhdGVtZW50LCBpZiBpbnB1dCBpbWFnZXMgYXJlIGNoYW5nZWQgKGZvciBpbnN0YW5jZSwgYmVjYXVzZSBJIHJlbW92ZWQgb25lIG9mIHRoZW0gd2l0aCB0aGUgJ2RlbGV0ZSBidXR0b24nLFxuICAgICAgLy8gb3IgYmVjYXVzZSB1c2VycyBjaGFuZ2VkIHRoZSBpbWFnZXMgYXJyYXkgd2hpbGUgbW9kYWwgZ2FsbGVyeSBpcyBzdGlsbCBvcGVuKS5cbiAgICAgIC8vIEluIHRoaXMgY2FzZSwgSSBoYXZlIHRvIHJlLWluaXQgcHJldmlld3MsIGJlY2F1c2UgdGhlIGlucHV0IGFycmF5IG9mIGltYWdlcyBpcyBjaGFuZ2VkLlxuICAgICAgdGhpcy5pbml0UHJldmlld3MoY3VycmVudCwgY2hhbmdlcy5pbWFnZXMuY3VycmVudFZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAocHJldiAmJiBjdXJyZW50ICYmIHByZXYuaWQgIT09IGN1cnJlbnQuaWQpIHtcbiAgICAgIC8vIHRvIG1hbmFnZSBpbmZpbml0ZSBzbGlkaW5nIEkgaGF2ZSB0byByZXNldCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIGF0IHRoZSBiZWdpbm5pbmdcbiAgICAgIC8vIHRvIHNob3cgYWdhaW4gcHJldmlld3MgZnJvbSB0aGUgZmlyc3QgaW1hZ2UuXG4gICAgICAvLyBUaGlzIGhhcHBlbnMgd2hlbiB5b3UgbmF2aWdhdGUgb3ZlciB0aGUgbGFzdCBpbWFnZSB0byByZXR1cm4gdG8gdGhlIGZpcnN0IG9uZVxuICAgICAgbGV0IHByZXZJbmRleDogbnVtYmVyO1xuICAgICAgbGV0IGN1cnJlbnRJbmRleDogbnVtYmVyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcHJldkluZGV4ID0gZ2V0SW5kZXgocHJldiwgdGhpcy5pbWFnZXMpO1xuICAgICAgICBjdXJyZW50SW5kZXggPSBnZXRJbmRleChjdXJyZW50LCB0aGlzLmltYWdlcyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IGdldCBwcmV2aW91cyBhbmQgY3VycmVudCBpbWFnZSBpbmRleGVzIGluIHByZXZpZXdzJyk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cblxuICAgICAgLy8gYXBwbHkgYSBmb3JtdWxhIHRvIGdldCBhIHZhbHVlcyB0byBiZSB1c2VkIHRvIGRlY2lkZSBpZiBnbyBuZXh0LCByZXR1cm4gYmFjayBvciBzdGF5IHdpdGhvdXQgZG9pbmcgYW55dGhpbmdcbiAgICAgIGNvbnN0IGNhbGMgPSBNYXRoLmZsb29yKCh0aGlzLmVuZCAtIHRoaXMuc3RhcnQpIC8gMikgKyB0aGlzLnN0YXJ0O1xuXG4gICAgICBpZiAocHJldkluZGV4ID09PSB0aGlzLmltYWdlcy5sZW5ndGggLSAxICYmIGN1cnJlbnRJbmRleCA9PT0gMCkge1xuICAgICAgICAvLyBmaXJzdCBpbWFnZVxuICAgICAgICB0aGlzLnNldEJlZ2lubmluZ0luZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgICB0aGlzLnByZXZpZXdzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIHRoZSBzYW1lIGZvciB0aGUgb3Bwb3NpdGUgY2FzZSwgd2hlbiB5b3UgbmF2aWdhdGUgYmFjayBmcm9tIHRoZSBmaXN0IGltYWdlIHRvIGdvIHRvIHRoZSBsYXN0IG9uZS5cbiAgICAgIGlmIChwcmV2SW5kZXggPT09IDAgJiYgY3VycmVudEluZGV4ID09PSB0aGlzLmltYWdlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIC8vIGxhc3QgaW1hZ2VcbiAgICAgICAgdGhpcy5zZXRFbmRJbmRleGVzUHJldmlld3MoKTtcbiAgICAgICAgdGhpcy5wcmV2aWV3cyA9IHRoaXMuaW1hZ2VzLmZpbHRlcigoaW1nOiBJbnRlcm5hbExpYkltYWdlLCBpOiBudW1iZXIpID0+IGkgPj0gdGhpcy5zdGFydCAmJiBpIDwgdGhpcy5lbmQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnByZXZpZXdDb25maWcgJiYgKHRoaXMucHJldmlld0NvbmZpZy5udW1iZXIgYXMgbnVtYmVyKSAlIDIgPT09IDApIHtcbiAgICAgICAgaWYgKGNhbGMgPiBjdXJyZW50SW5kZXgpIHtcbiAgICAgICAgICB0aGlzLnByZXZpb3VzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5uZXh0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjYWxjID4gY3VycmVudEluZGV4KSB7XG4gICAgICAgICAgdGhpcy5wcmV2aW91cygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjYWxjIDwgY3VycmVudEluZGV4KSB7XG4gICAgICAgICAgdGhpcy5uZXh0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGNhbGxlZCBieSBldmVudHMgZnJvbSBib3RoIGtleWJvYXJkIGFuZCBtb3VzZSBvbiBhIHByZXZpZXcuXG4gICAqIFRoaXMgd2lsbCB0cmlnZ2VyIHRoZSBgY2xpY2twcmV2aWV3YCBvdXRwdXQgd2l0aCB0aGUgaW5wdXQgcHJldmlldyBhcyBpdHMgcGF5bG9hZC5cbiAgICogQHBhcmFtIEludGVybmFsTGliSW1hZ2UgcHJldmlldyB0aGF0IHRyaWdnZXJlZCB0aGlzIG1ldGhvZFxuICAgKiBAcGFyYW0gS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQgZXZlbnQgcGF5bG9hZFxuICAgKiBAcGFyYW0gQWN0aW9uIHRoYXQgdHJpZ2dlcmVkIHRoaXMgZXZlbnQgKEFjdGlvbi5OT1JNQUwgYnkgZGVmYXVsdClcbiAgICovXG4gIG9uSW1hZ2VFdmVudChwcmV2aWV3OiBJbnRlcm5hbExpYkltYWdlLCBldmVudDogS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQsIGFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2aWV3Q29uZmlnIHx8ICF0aGlzLnByZXZpZXdDb25maWcuY2xpY2thYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNsaWNrZWRJbWFnZUluZGV4OiBudW1iZXIgPSB0aGlzLmltYWdlcy5pbmRleE9mKHByZXZpZXcpO1xuICAgIGNvbnN0IHJlc3VsdDogbnVtYmVyID0gc3VwZXIuaGFuZGxlSW1hZ2VFdmVudChldmVudCk7XG4gICAgaWYgKHJlc3VsdCA9PT0gTkVYVCkge1xuICAgICAgdGhpcy5jbGlja1ByZXZpZXcuZW1pdCh7IGFjdGlvbiwgcmVzdWx0OiBjbGlja2VkSW1hZ2VJbmRleCB9IGFzIEltYWdlRXZlbnQpO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSBQUkVWKSB7XG4gICAgICB0aGlzLmNsaWNrUHJldmlldy5lbWl0KHsgYWN0aW9uLCByZXN1bHQ6IGNsaWNrZWRJbWFnZUluZGV4IH0gYXMgSW1hZ2VFdmVudCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBjYWxsZWQgYnkgZXZlbnRzIGZyb20gYm90aCBrZXlib2FyZCBhbmQgbW91c2Ugb24gYSBuYXZpZ2F0aW9uIGFycm93LlxuICAgKiBAcGFyYW0gc3RyaW5nIGRpcmVjdGlvbiBvZiB0aGUgbmF2aWdhdGlvbiB0aGF0IGNhbiBiZSBlaXRoZXIgJ25leHQnIG9yICdwcmV2J1xuICAgKiBAcGFyYW0gS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQgZXZlbnQgcGF5bG9hZFxuICAgKi9cbiAgb25OYXZpZ2F0aW9uRXZlbnQoZGlyZWN0aW9uOiBzdHJpbmcsIGV2ZW50OiBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHJlc3VsdDogbnVtYmVyID0gc3VwZXIuaGFuZGxlTmF2aWdhdGlvbkV2ZW50KGRpcmVjdGlvbiwgZXZlbnQpO1xuICAgIGlmIChyZXN1bHQgPT09IE5FWFQpIHtcbiAgICAgIHRoaXMubmV4dCgpO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSBQUkVWKSB7XG4gICAgICB0aGlzLnByZXZpb3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBnZXQgYXJpYS1sYWJlbCB0ZXh0IGZvciBhIHByZXZpZXcgaW1hZ2UuXG4gICAqIEBwYXJhbSBJbWFnZSBpcyB0aGUgcHJldmlld1xuICAgKi9cbiAgZ2V0QXJpYUxhYmVsKHByZXZpZXc6IEltYWdlKTogc3RyaW5nIHtcbiAgICBpZiAoIXByZXZpZXcucGxhaW4pIHtcbiAgICAgIHJldHVybiBwcmV2aWV3Lm1vZGFsLmFyaWFMYWJlbCB8fCAnJztcbiAgICB9XG4gICAgcmV0dXJuIHByZXZpZXcucGxhaW4uYXJpYUxhYmVsIHx8IHByZXZpZXcubW9kYWwuYXJpYUxhYmVsIHx8ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBnZXQgdGl0bGUgdGV4dCBmb3IgYSBwcmV2aWV3IGltYWdlLlxuICAgKiBAcGFyYW0gSW1hZ2UgaXMgdGhlIHByZXZpZXdcbiAgICovXG4gIGdldFRpdGxlKHByZXZpZXc6IEltYWdlKTogc3RyaW5nIHtcbiAgICBpZiAoIXByZXZpZXcucGxhaW4pIHtcbiAgICAgIHJldHVybiBwcmV2aWV3Lm1vZGFsLnRpdGxlIHx8ICcnO1xuICAgIH1cbiAgICByZXR1cm4gcHJldmlldy5wbGFpbi50aXRsZSB8fCBwcmV2aWV3Lm1vZGFsLnRpdGxlIHx8ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBnZXQgYWx0IHRleHQgZm9yIGEgcHJldmlldyBpbWFnZS5cbiAgICogQHBhcmFtIEltYWdlIGlzIHRoZSBwcmV2aWV3XG4gICAqL1xuICBnZXRBbHQocHJldmlldzogSW1hZ2UpOiBzdHJpbmcge1xuICAgIGlmICghcHJldmlldy5wbGFpbikge1xuICAgICAgcmV0dXJuIHByZXZpZXcubW9kYWwuYWx0IHx8ICcnO1xuICAgIH1cbiAgICByZXR1cm4gcHJldmlldy5wbGFpbi5hbHQgfHwgcHJldmlldy5tb2RhbC5hbHQgfHwgJyc7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHVzZWQgaW4gdGhlIHRlbXBsYXRlIHRvIHRyYWNrIGlkcyBpbiBuZ0Zvci5cbiAgICogQHBhcmFtIG51bWJlciBpbmRleCBvZiB0aGUgYXJyYXlcbiAgICogQHBhcmFtIEltYWdlIGl0ZW0gb2YgdGhlIGFycmF5XG4gICAqIEByZXR1cm5zIG51bWJlciB0aGUgaWQgb2YgdGhlIGl0ZW1cbiAgICovXG4gIHRyYWNrQnlJZChpbmRleDogbnVtYmVyLCBpdGVtOiBJbWFnZSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGl0ZW0uaWQ7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHVzZWQgaW4gdGVtcGxhdGUgdG8gc2FuaXRpemUgYW4gdXJsIHdoZW4geW91IG5lZWQgbGVnYWN5SUUxMU1vZGUuXG4gICAqIEluIHRoaXMgd2F5IHlvdSBjYW4gc2V0IGFuIHVybCBhcyBiYWNrZ3JvdW5kIG9mIGEgZGl2LlxuICAgKiBAcGFyYW0gdW5zYWZlU3R5bGUgaXMgYSBzdHJpbmcgb3IgYSBTYWZlUmVzb3VyY2VVcmwgdGhhdCByZXByZXNlbnRzIHRoZSB1cmwgdG8gc2FuaXRpemUuXG4gICAqIEBwYXJhbSB1bnNhZmVTdHlsZUZhbGxiYWNrIGlzIGEgc3RyaW5nIG9yIGEgU2FmZVJlc291cmNlVXJsIHRoYXQgcmVwcmVzZW50cyB0aGUgZmFsbGJhY2sgdXJsIHRvIHNhbml0aXplLlxuICAgKiBAcmV0dXJucyBhIFNhZmVTdHlsZSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBpbiB0ZW1wbGF0ZSB3aXRob3V0IHByb2JsZW1zLlxuICAgKi9cbiAgc2FuaXRpemVVcmxCZ1N0eWxlKHVuc2FmZVN0eWxlOiBzdHJpbmcgfCBTYWZlUmVzb3VyY2VVcmwsIHVuc2FmZVN0eWxlRmFsbGJhY2s6IHN0cmluZyB8IFNhZmVSZXNvdXJjZVVybCk6IFNhZmVTdHlsZSB7XG4gICAgLy8gTWV0aG9kIHVzZWQgb25seSB0byBzYW5pdGl6ZSBiYWNrZ3JvdW5kLWltYWdlIHN0eWxlIGJlZm9yZSBhZGQgaXQgdG8gYmFja2dyb3VuZCBwcm9wZXJ0eSB3aGVuIGxlZ2FjeUlFMTFNb2RlIGlzIGVuYWJsZWRcbiAgICBsZXQgYmc6IHN0cmluZyA9ICd1cmwoJyArIHVuc2FmZVN0eWxlICsgJyknO1xuICAgIGlmICghIXVuc2FmZVN0eWxlRmFsbGJhY2spIHtcbiAgICAgIC8vIGlmIGEgZmFsbGJhY2sgaW1hZ2UgaXMgZGVmaW5lZCwgYXBwZW5kIGl0LiBJbiB0aGlzIHdheSwgaXQgd2lsbCBiZSB1c2VkIGJ5IHRoZSBicm93c2VyIGFzIGZhbGxiYWNrLlxuICAgICAgYmcgKz0gJywgJyArICd1cmwoJyArIHVuc2FmZVN0eWxlRmFsbGJhY2sgKyAnKSc7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0U3R5bGUoYmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBnZXQgdGhlIGJhY2tncm91bmQtc2l6ZSB2YWx1ZSB3aGVuIElFMTFMZWdhY3lNb2RlIGlzIGVuYWJsZWQuXG4gICAqIFRoaXMgcHJldmVudCB3ZWlyZWQgYmVoYXZpb3VyIG9uIElFMTEgd2hlbiBwcmV2aWV3cyBhcmUgcmVhbGx5IHNtYWxsLCBidXQgb3JpZ2luYWwgaW1hZ2VzICgucG5nLy5qZ3AvLi4uKSBhcmUgYmlnLlxuICAgKiBVc2luZyAnY292ZXInIGl0J3Mgbm90IGVub3VnaCwgYmVjYXVzZSBpdCdzIGNhdXNpbmcgZW1wdHkgYmFja2dyb3VuZCBpbiBzb21lIGNhc2VzLlxuICAgKiBBZnRlciBzb21lIGV4cGVyaW1lbnRzLCBJIGRlY2lkZWQgdG8gdXNlIHRoZSBkb3VibGUgb2YgdGhlIGhlaWdodCBhbmQgYXV0byBhcyB3aWR0aC5cbiAgICovXG4gIGdldElFMTFMZWdhY3lCZ1NpemUoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5wcmV2aWV3Q29uZmlnICYmIHRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQpIHtcbiAgICAgIGNvbnN0IGJnSGVpZ2h0OiBudW1iZXIgPSArdGhpcy5wcmV2aWV3Q29uZmlnLm1heEhlaWdodC5yZXBsYWNlKCdweCcsICcnKTtcbiAgICAgIHJldHVybiAnMTAwJSAnICsgYmdIZWlnaHQgKiAyICsgJ3B4JztcbiAgICB9XG4gICAgcmV0dXJuICdjb3Zlcic7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGNsZWFudXAgcmVzb3VyY2VzLiBJbiBmYWN0LCBpdCBjbGVhbnMgYnJlYWtwb2ludFN1YnNjcmlwdGlvbi5cbiAgICogVGhpcyBpcyBhbiBBbmd1bGFyJ3MgbGlmZWN5Y2xlIGhvb2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGlzIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5icmVha3BvaW50U3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gaW5pdCBwcmV2aWV3cyBiYXNlZCBvbiB0aGUgY3VycmVudEltYWdlIGFuZCB0aGUgZnVsbCBhcnJheSBvZiBpbWFnZXMuXG4gICAqIFRoZSBjdXJyZW50IGltYWdlIGluIG1hbmRhdG9yeSB0byBzaG93IGFsd2F5cyB0aGUgY3VycmVudCBwcmV2aWV3IChhcyBoaWdobGlnaHRlZCkuXG4gICAqIEBwYXJhbSBJbnRlcm5hbExpYkltYWdlIGN1cnJlbnRJbWFnZSB0byBkZWNpZGUgaG93IHRvIHNob3cgcHJldmlld3MsIGJlY2F1c2UgSSBhbHdheXMgd2FudCB0byBzZWUgdGhlIGN1cnJlbnQgaW1hZ2UgYXMgaGlnaGxpZ2h0ZWRcbiAgICogQHBhcmFtIEludGVybmFsTGliSW1hZ2VbXSBpbWFnZXMgaXMgdGhlIGFycmF5IG9mIGFsbCBpbWFnZXMuXG4gICAqL1xuICBwcml2YXRlIGluaXRQcmV2aWV3cyhjdXJyZW50SW1hZ2U6IEludGVybmFsTGliSW1hZ2UsIGltYWdlczogSW50ZXJuYWxMaWJJbWFnZVtdKTogdm9pZCB7XG4gICAgbGV0IGluZGV4OiBudW1iZXI7XG4gICAgdHJ5IHtcbiAgICAgIGluZGV4ID0gZ2V0SW5kZXgoY3VycmVudEltYWdlLCBpbWFnZXMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIC8vIGZpcnN0IGltYWdlXG4gICAgICAgIHRoaXMuc2V0QmVnaW5uaW5nSW5kZXhlc1ByZXZpZXdzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBpbWFnZXMubGVuZ3RoIC0gMTpcbiAgICAgICAgLy8gbGFzdCBpbWFnZVxuICAgICAgICB0aGlzLnNldEVuZEluZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIGRlZmF1bHQ6XG4gICAgICAvLyAgIC8vIG90aGVyIGltYWdlc1xuICAgICAgLy8gICAvLyBUT0RPIHVudXNlZCBiZWNhdXNlIGl0IHN0YXJ0cyBhbHdheXMgYXQgaW1hZ2UgMFxuICAgICAgLy8gICB0aGlzLnNldEluZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgLy8gICBicmVhaztcbiAgICB9XG4gICAgdGhpcy5wcmV2aWV3cyA9IGltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBpbml0IGJvdGggYHN0YXJ0YCBhbmQgYGVuZGAgdG8gdGhlIGJlZ2lubmluZy5cbiAgICovXG4gIHByaXZhdGUgc2V0QmVnaW5uaW5nSW5kZXhlc1ByZXZpZXdzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2aWV3Q29uZmlnIHx8IHRoaXMucHJldmlld0NvbmZpZy5udW1iZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gcHJldmlld0NvbmZpZyBhbmQgbnVtYmVyIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnQgPSAwO1xuICAgIHRoaXMuZW5kID0gTWF0aC5taW4odGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciBhcyBudW1iZXIsIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gaW5pdCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIHRvIHRoZSBlbmQuXG4gICAqL1xuICBwcml2YXRlIHNldEVuZEluZGV4ZXNQcmV2aWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCB0aGlzLnByZXZpZXdDb25maWcubnVtYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIHByZXZpZXdDb25maWcgYW5kIG51bWJlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXJ0ID0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSAtICgodGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciBhcyBudW1iZXIpIC0gMSk7XG4gICAgdGhpcy5lbmQgPSB0aGlzLmltYWdlcy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIHRoZSB2aXNpYmxlIHByZXZpZXdzIG5hdmlnYXRpbmcgdG8gdGhlIHJpZ2h0IChuZXh0KS5cbiAgICovXG4gIHByaXZhdGUgbmV4dCgpOiB2b2lkIHtcbiAgICAvLyBjaGVjayBpZiBuZXh0SW1hZ2Ugc2hvdWxkIGJlIGJsb2NrZWRcbiAgICBpZiAodGhpcy5pc1ByZXZlbnRTbGlkaW5nKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZW5kID09PSB0aGlzLmltYWdlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXJ0Kys7XG4gICAgdGhpcy5lbmQgPSBNYXRoLm1pbih0aGlzLmVuZCArIDEsIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG5cbiAgICB0aGlzLnByZXZpZXdzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIHRoZSB2aXNpYmxlIHByZXZpZXdzIG5hdmlnYXRpbmcgdG8gdGhlIGxlZnQgKHByZXZpb3VzKS5cbiAgICovXG4gIHByaXZhdGUgcHJldmlvdXMoKTogdm9pZCB7XG4gICAgLy8gY2hlY2sgaWYgcHJldkltYWdlIHNob3VsZCBiZSBibG9ja2VkXG4gICAgaWYgKHRoaXMuaXNQcmV2ZW50U2xpZGluZygwKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXJ0ID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydCA9IE1hdGgubWF4KHRoaXMuc3RhcnQgLSAxLCAwKTtcbiAgICB0aGlzLmVuZCA9IE1hdGgubWluKHRoaXMuZW5kIC0gMSwgdGhpcy5pbWFnZXMubGVuZ3RoKTtcblxuICAgIHRoaXMucHJldmlld3MgPSB0aGlzLmltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBibG9jay9wZXJtaXQgc2xpZGluZyBiZXR3ZWVuIHByZXZpZXdzLlxuICAgKiBAcGFyYW0gbnVtYmVyIGJvdW5kYXJ5SW5kZXggaXMgdGhlIGZpcnN0IG9yIHRoZSBsYXN0IGluZGV4IG9mIGBpbWFnZXNgIGlucHV0IGFycmF5XG4gICAqIEByZXR1cm5zIGJvb2xlYW4gaWYgdHJ1ZSBibG9jayBzbGlkaW5nLCBvdGhlcndpc2Ugbm90XG4gICAqL1xuICBwcml2YXRlIGlzUHJldmVudFNsaWRpbmcoYm91bmRhcnlJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcykgPT09IGJvdW5kYXJ5SW5kZXg7XG4gIH1cbn1cbiIsIjxuYXYgKm5nSWY9XCJwcmV2aWV3Q29uZmlnPy52aXNpYmxlXCJcbiAgICAgY2xhc3M9XCJwcmV2aWV3cy1jb250YWluZXJcIlxuICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld3NDb250YWluZXJBcmlhTGFiZWxcIlxuICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3c0NvbnRhaW5lclRpdGxlXCI+XG5cbiAgPGEgY2xhc3M9XCJuYXYtbGVmdFwiXG4gICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsUHJldkFyaWFMYWJlbFwiXG4gICAgIFt0YWJJbmRleF09XCJwcmV2aWV3Q29uZmlnPy5hcnJvd3MgJiYgc3RhcnQgPiAwID8gMCA6IC0xXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgIChjbGljayk9XCJvbk5hdmlnYXRpb25FdmVudCgnbGVmdCcsICRldmVudClcIiAoa2V5dXApPVwib25OYXZpZ2F0aW9uRXZlbnQoJ2xlZnQnLCAkZXZlbnQpXCI+XG4gICAgPGRpdiBjbGFzcz1cImluc2lkZSB7e3ByZXZpZXdDb25maWc/LmFycm93cyAmJiBzdGFydCA+IDAgPyAnbGVmdC1hcnJvdy1wcmV2aWV3LWltYWdlJyA6ICdlbXB0eS1hcnJvdy1wcmV2aWV3LWltYWdlJ319XCJcbiAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsUHJldlRpdGxlXCI+PC9kaXY+XG4gIDwvYT5cblxuICA8ZGl2IGNsYXNzPVwicHJldmlldy1pbm5lci1jb250YWluZXJcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcmV2aWV3IG9mIHByZXZpZXdzOyB0cmFja0J5OiB0cmFja0J5SWQ7IGxldCBpbmRleCA9IGluZGV4XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNhcm91c2VsQ29uZmlnPy5sZWdhY3lJRTExTW9kZTsgZWxzZSBsZWdhY3lNb2RlXCI+XG4gICAgICAgIDxpbWcgKm5nSWY9XCJwcmV2aWV3Py5tb2RhbD8uaW1nXCJcbiAgICAgICAgICAgICBjbGFzcz1cImluc2lkZSBwcmV2aWV3LWltYWdle3tpc0FjdGl2ZShwcmV2aWV3KSA/ICcgYWN0aXZlJyA6ICcnfX17eyFwcmV2aWV3Q29uZmlnPy5jbGlja2FibGUgPyAnIHVuY2xpY2thYmxlJyA6ICcnfX1cIlxuICAgICAgICAgICAgIFtzcmNdPVwicHJldmlldy5wbGFpbj8uaW1nID8gcHJldmlldy5wbGFpbj8uaW1nIDogcHJldmlldy5tb2RhbC5pbWdcIlxuICAgICAgICAgICAgIGtzRmFsbGJhY2tJbWFnZSBbZmFsbGJhY2tJbWddPVwicHJldmlldy5wbGFpbj8uZmFsbGJhY2tJbWcgPyBwcmV2aWV3LnBsYWluPy5mYWxsYmFja0ltZyA6IHByZXZpZXcubW9kYWwuZmFsbGJhY2tJbWdcIlxuICAgICAgICAgICAgIGtzU2l6ZSBbc2l6ZUNvbmZpZ109XCJ7d2lkdGg6IHByZXZpZXdDb25maWc/LndpZHRoISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBwcmV2aWV3TWF4SGVpZ2h0fVwiXG4gICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJnZXRBcmlhTGFiZWwocHJldmlldylcIlxuICAgICAgICAgICAgIFt0aXRsZV09XCJnZXRUaXRsZShwcmV2aWV3KVwiXG4gICAgICAgICAgICAgYWx0PVwie3tnZXRBbHQocHJldmlldyl9fVwiXG4gICAgICAgICAgICAgW3RhYkluZGV4XT1cIjBcIiByb2xlPVwiaW1nXCJcbiAgICAgICAgICAgICAoY2xpY2spPVwib25JbWFnZUV2ZW50KHByZXZpZXcsICRldmVudCwgY2xpY2tBY3Rpb24pXCIgKGtleXVwKT1cIm9uSW1hZ2VFdmVudChwcmV2aWV3LCAkZXZlbnQsIGtleWJvYXJkQWN0aW9uKVwiLz5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLXRlbXBsYXRlICNsZWdhY3lNb2RlPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwicHJldmlldz8ubW9kYWw/LmltZ1wiXG4gICAgICAgICAgICAgY2xhc3M9XCJpbnNpZGUgcHJldmlldy1pZTExLWltYWdle3tpc0FjdGl2ZShwcmV2aWV3KSA/ICcgYWN0aXZlJyA6ICcnfX17eyFwcmV2aWV3Q29uZmlnPy5jbGlja2FibGUgPyAnIHVuY2xpY2thYmxlJyA6ICcnfX1cIlxuICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cIid0cmFuc3BhcmVudCdcIlxuICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXT1cInNhbml0aXplVXJsQmdTdHlsZShcbiAgICAgICAgICAgICAgcHJldmlldy5wbGFpbj8uaW1nID8gcHJldmlldy5wbGFpbj8uaW1nIDogcHJldmlldy5tb2RhbC5pbWcsXG4gICAgICAgICAgICAgIHByZXZpZXcucGxhaW4/LmZhbGxiYWNrSW1nID8gcHJldmlldy5wbGFpbj8uZmFsbGJhY2tJbWcgOiBwcmV2aWV3Lm1vZGFsLmZhbGxiYWNrSW1nKVwiXG4gICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtcG9zaXRpb25dPVwiJ2NlbnRlciBjZW50ZXInXCJcbiAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1zaXplXT1cImdldElFMTFMZWdhY3lCZ1NpemUoKVwiXG4gICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtcmVwZWF0XT1cIiduby1yZXBlYXQnXCJcbiAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1hdHRhY2htZW50XT1cIidzY3JvbGwnXCJcbiAgICAgICAgICAgICBrc1NpemUgW3NpemVDb25maWddPVwie3dpZHRoOiBwcmV2aWV3Q29uZmlnPy53aWR0aCEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHByZXZpZXdNYXhIZWlnaHR9XCJcbiAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImdldEFyaWFMYWJlbChwcmV2aWV3KVwiXG4gICAgICAgICAgICAgW3RpdGxlXT1cImdldFRpdGxlKHByZXZpZXcpXCJcbiAgICAgICAgICAgICBbdGFiSW5kZXhdPVwiMFwiIHJvbGU9XCJpbWdcIlxuICAgICAgICAgICAgIChjbGljayk9XCJvbkltYWdlRXZlbnQocHJldmlldywgJGV2ZW50LCBjbGlja0FjdGlvbilcIiAoa2V5dXApPVwib25JbWFnZUV2ZW50KHByZXZpZXcsICRldmVudCwga2V5Ym9hcmRBY3Rpb24pXCI+PC9kaXY+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cblxuICA8YSBjbGFzcz1cIm5hdi1yaWdodFwiXG4gICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsTmV4dEFyaWFMYWJlbFwiXG4gICAgIFt0YWJJbmRleF09XCJwcmV2aWV3Q29uZmlnPy5hcnJvd3MgJiYgZW5kIDwgaW1hZ2VzLmxlbmd0aCA/IDAgOiAtMVwiIHJvbGU9XCJidXR0b25cIlxuICAgICAoY2xpY2spPVwib25OYXZpZ2F0aW9uRXZlbnQoJ3JpZ2h0JywgJGV2ZW50KVwiIChrZXl1cCk9XCJvbk5hdmlnYXRpb25FdmVudCgncmlnaHQnLCAkZXZlbnQpXCI+XG4gICAgPGRpdiBjbGFzcz1cImluc2lkZSB7e3ByZXZpZXdDb25maWc/LmFycm93cyAmJiBlbmQgPCBpbWFnZXMubGVuZ3RoID8gJ3JpZ2h0LWFycm93LXByZXZpZXctaW1hZ2UnIDogJ2VtcHR5LWFycm93LXByZXZpZXctaW1hZ2UnfX1cIlxuICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgIFt0aXRsZV09XCJhY2Nlc3NpYmlsaXR5Q29uZmlnPy5jYXJvdXNlbFByZXZpZXdTY3JvbGxOZXh0VGl0bGVcIj48L2Rpdj5cbiAgPC9hPlxuXG48L25hdj5cbiJdfQ==