@libs-ui/components-image-editor 0.2.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/defines/image-editor.define.d.ts +16 -0
- package/esm2022/defines/image-editor.define.mjs +89 -0
- package/esm2022/image-editor.component.mjs +784 -0
- package/esm2022/index.mjs +5 -0
- package/esm2022/interfaces/function-control-event.interface.mjs +2 -0
- package/esm2022/interfaces/image-editor.interface.mjs +2 -0
- package/esm2022/libs-ui-components-image-editor.mjs +5 -0
- package/esm2022/resize/resize.component.mjs +125 -0
- package/fesm2022/libs-ui-components-image-editor.mjs +994 -0
- package/fesm2022/libs-ui-components-image-editor.mjs.map +1 -0
- package/image-editor.component.d.ts +117 -0
- package/index.d.ts +4 -0
- package/interfaces/function-control-event.interface.d.ts +4 -0
- package/interfaces/image-editor.interface.d.ts +55 -0
- package/package.json +25 -0
- package/resize/resize.component.d.ts +32 -0
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
3
|
+
import { ChangeDetectionStrategy, Component, Inject, inject, input, model, Optional, output, signal, viewChild } from '@angular/core';
|
|
4
|
+
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
|
+
import { LibsUiComponentsInputsValidComponent } from '@libs-ui/components-inputs-valid';
|
|
6
|
+
import { LibsUiComponentsModalComponent } from '@libs-ui/components-modal';
|
|
7
|
+
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
8
|
+
import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
|
|
9
|
+
import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
|
|
10
|
+
import { convertBase64ToBlob, get, isNil, LINK_IMAGE_ERROR_TOKEN_INJECT } from '@libs-ui/utils';
|
|
11
|
+
import { TranslateModule } from '@ngx-translate/core';
|
|
12
|
+
import { fromEvent, Subject } from 'rxjs';
|
|
13
|
+
import { mergeMap, takeUntil, tap } from 'rxjs/operators';
|
|
14
|
+
import { cropRationItems, getCropRectImage, getDataUrl, getStylesOfElement, getWidthHeightResizeCropFollow } from './defines/image-editor.define';
|
|
15
|
+
import { LibsUiComponentsImageEditorResizeComponent } from './resize/resize.component';
|
|
16
|
+
import * as i0 from "@angular/core";
|
|
17
|
+
import * as i1 from "@ngx-translate/core";
|
|
18
|
+
export class LibsUiComponentsImageEditorComponent {
|
|
19
|
+
linkImageError;
|
|
20
|
+
loading = signal(false);
|
|
21
|
+
loadingImage = signal(true);
|
|
22
|
+
changed = signal(false);
|
|
23
|
+
originWidth = signal(0);
|
|
24
|
+
originHeight = signal(0);
|
|
25
|
+
cropRatioItems = signal(cropRationItems());
|
|
26
|
+
cropRatioItemSelected = signal('');
|
|
27
|
+
cropSize = signal({ width: 20, height: 20 });
|
|
28
|
+
resizeData = signal({ ratio: 100, width: 600, height: 800 });
|
|
29
|
+
dragGridCrop = signal(false);
|
|
30
|
+
image = new Image();
|
|
31
|
+
canvas = document.createElement('canvas');
|
|
32
|
+
containerHeight = signal(800);
|
|
33
|
+
containerWidth = signal(1200);
|
|
34
|
+
imgContainerRect = signal({ top: 0, left: 0, width: 0, height: 0 });
|
|
35
|
+
rectClip = signal({ top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 });
|
|
36
|
+
resizeState = signal('none');
|
|
37
|
+
moveState = signal('none');
|
|
38
|
+
startMouseDim = signal({ clientX: 0, clientY: 0, width: 0, height: 0, top: 0, left: 0, imageTop: 0, imageLeft: 0, imageWidth: 0, imageHeight: 0 });
|
|
39
|
+
dataUrlOrigin = signal('');
|
|
40
|
+
ratioValue = signal(0);
|
|
41
|
+
minHeight = 20;
|
|
42
|
+
minWidth = 20;
|
|
43
|
+
onDestroy = new Subject();
|
|
44
|
+
resizeComponentRef;
|
|
45
|
+
modeShowButton = input('save-file');
|
|
46
|
+
mimetype = input();
|
|
47
|
+
zIndex = input(1200);
|
|
48
|
+
imgSrc = model.required();
|
|
49
|
+
originUrl = input();
|
|
50
|
+
nameFile = input();
|
|
51
|
+
hasZoom = input(false);
|
|
52
|
+
aspectRatio = model();
|
|
53
|
+
requiredCropFollowRatio = input(false);
|
|
54
|
+
imageOrigin = viewChild.required('imageOrigin');
|
|
55
|
+
imageClip = viewChild.required('imageClip');
|
|
56
|
+
imageEditorContainer = viewChild.required('imageEditorContainer');
|
|
57
|
+
imageContainer = viewChild.required('imageContainer');
|
|
58
|
+
cropArea = viewChild.required('cropArea');
|
|
59
|
+
cropTL = viewChild.required('cropTL');
|
|
60
|
+
cropBL = viewChild.required('cropBL');
|
|
61
|
+
cropBR = viewChild.required('cropBR');
|
|
62
|
+
cropTR = viewChild.required('cropTR');
|
|
63
|
+
cropLineVL = viewChild.required('cropLineVL');
|
|
64
|
+
cropLineVR = viewChild.required('cropLineVR');
|
|
65
|
+
cropLineHT = viewChild.required('cropLineHT');
|
|
66
|
+
cropLineHB = viewChild.required('cropLineHB');
|
|
67
|
+
circleTL = viewChild.required('circleTL');
|
|
68
|
+
circleTR = viewChild.required('circleTR');
|
|
69
|
+
circleBL = viewChild.required('circleBL');
|
|
70
|
+
circleBR = viewChild.required('circleBR');
|
|
71
|
+
outClose = output();
|
|
72
|
+
outSaveFile = output();
|
|
73
|
+
outFunctionsControl = output();
|
|
74
|
+
dynamicComponentService = inject(LibsUiDynamicComponentService);
|
|
75
|
+
constructor(linkImageError) {
|
|
76
|
+
this.linkImageError = linkImageError;
|
|
77
|
+
}
|
|
78
|
+
ngAfterViewInit() {
|
|
79
|
+
if (this.aspectRatio()) {
|
|
80
|
+
this.dragGridCrop.set(true);
|
|
81
|
+
const aspectRatioFound = this.cropRatioItems().find(item => item.key === this.aspectRatio()?.key);
|
|
82
|
+
this.cropRatioItemSelected.set(aspectRatioFound?.key || this.cropRatioItems()[0].key);
|
|
83
|
+
this.updateOriginImageSize();
|
|
84
|
+
this.changedImage(true);
|
|
85
|
+
}
|
|
86
|
+
this.updateModalSize();
|
|
87
|
+
this.initData();
|
|
88
|
+
this.initMouseEvent();
|
|
89
|
+
this.outFunctionsControl.emit({
|
|
90
|
+
cropImage: this.cropImage.bind(this),
|
|
91
|
+
setLoadingState: (loading) => this.loading.set(loading)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
handlerImageLoaded() {
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
this.updateModalSize();
|
|
97
|
+
this.loadingImage.set(false);
|
|
98
|
+
}, 500);
|
|
99
|
+
}
|
|
100
|
+
handlerImageError(e) {
|
|
101
|
+
console.log('e', e);
|
|
102
|
+
e.target.src = this.linkImageError;
|
|
103
|
+
}
|
|
104
|
+
updateModalSize() {
|
|
105
|
+
const maxHeight = window.innerHeight - 100;
|
|
106
|
+
const maxWidth = window.innerWidth - 400;
|
|
107
|
+
this.containerHeight.set(maxHeight - 124);
|
|
108
|
+
this.containerWidth.set(maxWidth - 384);
|
|
109
|
+
this.updateOriginImageSize();
|
|
110
|
+
}
|
|
111
|
+
initData() {
|
|
112
|
+
this.imgContainerRect.set(this.imageContainer().nativeElement.getBoundingClientRect());
|
|
113
|
+
this.image.setAttribute('crossorigin', 'anonymous');
|
|
114
|
+
this.image.onload = () => {
|
|
115
|
+
this.imgContainerRect.set(this.imageContainer().nativeElement.getBoundingClientRect());
|
|
116
|
+
this.canvas.height = this.image.height;
|
|
117
|
+
this.canvas.width = this.image.width;
|
|
118
|
+
this.originHeight.set(this.image.height);
|
|
119
|
+
this.originWidth.set(this.image.width);
|
|
120
|
+
this.updateOriginImageSize();
|
|
121
|
+
this.canvas.getContext('2d')?.drawImage(this.image, 0, 0, this.canvas.width, this.canvas.height);
|
|
122
|
+
this.dataUrlOrigin.set(getDataUrl(this.canvas, this.mimetype(), this.image.src));
|
|
123
|
+
this.imgSrc.set(this.dataUrlOrigin());
|
|
124
|
+
};
|
|
125
|
+
this.image.src = this.imgSrc();
|
|
126
|
+
}
|
|
127
|
+
initMouseEvent() {
|
|
128
|
+
const mouseUp = this.initEvent({ nativeElement: document }, 'mouseup', { callStopPropagation: true, callPreventDefault: true }, undefined, () => this.handlerMouseup());
|
|
129
|
+
const mouseMove = this.initEvent({ nativeElement: document }, 'mousemove', { callStopPropagation: true, callPreventDefault: true }).pipe(takeUntil(mouseUp));
|
|
130
|
+
this.initEvent({ nativeElement: document }, 'wheel', { callStopPropagation: true }, undefined, (e) => this.handlerMousewheel(e)).subscribe();
|
|
131
|
+
this.initEvent({ nativeElement: window }, 'resize', {}, undefined, () => this.updateModalSize()).subscribe();
|
|
132
|
+
this.initEvent(this.imageContainer(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => this.handlerImageContainerMousedown(e)).subscribe((e) => this.handlerMousemove(e));
|
|
133
|
+
this.initEvent(this.cropTL(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'TL'); }).subscribe((e) => this.handlerMousemove(e));
|
|
134
|
+
this.initEvent(this.cropBL(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'BL'); }).subscribe((e) => this.handlerMousemove(e));
|
|
135
|
+
this.initEvent(this.cropBR(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'BR'); }).subscribe((e) => this.handlerMousemove(e));
|
|
136
|
+
this.initEvent(this.cropTR(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'TR'); }).subscribe((e) => this.handlerMousemove(e));
|
|
137
|
+
this.initEvent(this.cropLineVL(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'VL'); }).subscribe((e) => this.handlerMousemove(e));
|
|
138
|
+
this.initEvent(this.cropLineVR(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'VR'); }).subscribe((e) => this.handlerMousemove(e));
|
|
139
|
+
this.initEvent(this.cropLineHT(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'HT'); }).subscribe((e) => this.handlerMousemove(e));
|
|
140
|
+
this.initEvent(this.cropLineHB(), 'mousedown', { callStopPropagation: true, callPreventDefault: true }, mouseMove, (e) => { this.handlerCropResize(e, 'HB'); }).subscribe((e) => this.handlerMousemove(e));
|
|
141
|
+
this.initEvent(this.cropArea(), 'mousedown', {}, undefined, (e) => this.handlerMousedownCropArea(e)).subscribe((e) => this.handlerMousemove(e));
|
|
142
|
+
}
|
|
143
|
+
initEvent(element, eventName, flag, obsMerge, callback) {
|
|
144
|
+
const obs = fromEvent(element.nativeElement, eventName).pipe(tap((e) => {
|
|
145
|
+
if (flag.callStopPropagation && e?.stopPropagation) {
|
|
146
|
+
e.stopPropagation();
|
|
147
|
+
}
|
|
148
|
+
if (flag.callPreventDefault && e?.preventDefault) {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
}
|
|
151
|
+
if (callback) {
|
|
152
|
+
callback(e);
|
|
153
|
+
}
|
|
154
|
+
}), takeUntil(this.onDestroy));
|
|
155
|
+
if (obsMerge) {
|
|
156
|
+
return obs.pipe(mergeMap(() => obsMerge), (takeUntil(this.onDestroy)));
|
|
157
|
+
}
|
|
158
|
+
return obs;
|
|
159
|
+
}
|
|
160
|
+
;
|
|
161
|
+
updateOriginImageSize() {
|
|
162
|
+
let width = this.originWidth();
|
|
163
|
+
let height = this.originHeight();
|
|
164
|
+
const ratio = width / height;
|
|
165
|
+
if (width >= height) {
|
|
166
|
+
width = Math.min(this.containerWidth(), width);
|
|
167
|
+
height = Math.min(width / ratio, this.containerHeight());
|
|
168
|
+
width = height * ratio;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
height = Math.min(this.containerHeight(), height);
|
|
172
|
+
width = height * ratio;
|
|
173
|
+
}
|
|
174
|
+
this.setImagePosition(width, height);
|
|
175
|
+
this.updateCropAreaPos();
|
|
176
|
+
this.updateRectClipPos();
|
|
177
|
+
}
|
|
178
|
+
setImagePosition(width, height) {
|
|
179
|
+
const left = this.containerWidth() / 2 - width / 2;
|
|
180
|
+
const top = this.containerHeight() / 2 - height / 2;
|
|
181
|
+
const styles = { width, height, top, left, display: 'block' };
|
|
182
|
+
this.setStylesElements(this.imageOrigin(), styles);
|
|
183
|
+
this.setStylesElements(this.imageClip(), styles);
|
|
184
|
+
this.setCirclePosition(styles);
|
|
185
|
+
}
|
|
186
|
+
setCirclePosition(styles) {
|
|
187
|
+
this.setStylesElements(this.circleTL(), { top: (styles.top || 0) - 5, left: (styles.left || 0) - 5 });
|
|
188
|
+
this.setStylesElements(this.circleTR(), { top: (styles.top || 0) - 5, left: (styles.left || 0) + (styles.width || 0) - 10 });
|
|
189
|
+
this.setStylesElements(this.circleBL(), { top: (styles.top || 0) + (styles.height || 0) - 10, left: (styles.left || 0) - 5 });
|
|
190
|
+
this.setStylesElements(this.circleBR(), { top: (styles.top || 0) + (styles.height || 0) - 10, left: (styles.left || 0) + (styles.width || 0) - 10 });
|
|
191
|
+
}
|
|
192
|
+
updateCropAreaPos() {
|
|
193
|
+
const [imgTop, imgLeft, imgWidth, imgHeight] = getStylesOfElement(this.imageClip().nativeElement, ['style.top', 'style.left', 'offsetWidth', 'offsetHeight']);
|
|
194
|
+
const rectImg = {
|
|
195
|
+
top: Math.max(0, imgTop),
|
|
196
|
+
left: Math.max(0, imgLeft),
|
|
197
|
+
width: imgWidth,
|
|
198
|
+
height: imgHeight
|
|
199
|
+
};
|
|
200
|
+
rectImg.width = Math.min(imgWidth, this.containerWidth() - imgLeft);
|
|
201
|
+
if (imgLeft < 0) {
|
|
202
|
+
rectImg.width = Math.min(imgWidth + imgLeft, this.containerWidth());
|
|
203
|
+
}
|
|
204
|
+
rectImg.height = Math.min(imgHeight, this.containerHeight() - imgTop);
|
|
205
|
+
if (imgTop < 0) {
|
|
206
|
+
rectImg.height = Math.min(imgTop + imgHeight, this.containerHeight());
|
|
207
|
+
}
|
|
208
|
+
this.ratioValue.set(this.getCropRatioValue());
|
|
209
|
+
if (!this.ratioValue()) {
|
|
210
|
+
this.setStylesElements(this.cropArea(), rectImg);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
let width = rectImg.width;
|
|
214
|
+
let height = width / this.ratioValue();
|
|
215
|
+
width = Math.min(rectImg.width, width);
|
|
216
|
+
height = width / this.ratioValue();
|
|
217
|
+
height = Math.min(rectImg.height, height);
|
|
218
|
+
width = height * this.ratioValue();
|
|
219
|
+
const top = rectImg.top + (rectImg.height - height) / 2;
|
|
220
|
+
const left = rectImg.left + (rectImg.width - width) / 2;
|
|
221
|
+
this.setStylesElements(this.cropArea(), { width, height, top, left });
|
|
222
|
+
}
|
|
223
|
+
getCropRatioValue() {
|
|
224
|
+
const cropRatio = this.aspectRatio() || this.cropRatioItems().find(item => item.key === this.cropRatioItemSelected());
|
|
225
|
+
if (!cropRatio) {
|
|
226
|
+
return this.originWidth() / this.originHeight();
|
|
227
|
+
}
|
|
228
|
+
return cropRatio.value ?? 0;
|
|
229
|
+
}
|
|
230
|
+
updateRectClipPos() {
|
|
231
|
+
const reactClip = this.getRectClipImage();
|
|
232
|
+
this.imageClip().nativeElement.style.clip = `rect(${reactClip.top}px, ${reactClip.right}px, ${reactClip.bottom}px, ${reactClip.left}px)`;
|
|
233
|
+
}
|
|
234
|
+
getRectClipImage() {
|
|
235
|
+
const imageRect = this.imageClip().nativeElement.getBoundingClientRect();
|
|
236
|
+
if (!imageRect.width) {
|
|
237
|
+
return this.rectClip();
|
|
238
|
+
}
|
|
239
|
+
const cropRect = this.cropArea().nativeElement.getBoundingClientRect();
|
|
240
|
+
const width = Math.round(cropRect.width);
|
|
241
|
+
const height = Math.round(cropRect.height);
|
|
242
|
+
const left = cropRect.left - imageRect.left;
|
|
243
|
+
const top = cropRect.top - imageRect.top;
|
|
244
|
+
const right = Math.round(left + width);
|
|
245
|
+
const bottom = Math.round(top + height);
|
|
246
|
+
const ratio = this.originWidth() / imageRect.width;
|
|
247
|
+
this.rectClip.set({ left, top, right, bottom, width, height });
|
|
248
|
+
this.cropSize.set({
|
|
249
|
+
height: top >= 0 ? (Math.round((bottom - top) * ratio)) : (Math.floor((bottom - top) * ratio)),
|
|
250
|
+
width: top >= 0 ? (Math.round(((right - left) * (this.ratioValue() ?? 1)) * ratio)) : (Math.floor(((right - left) * (this.ratioValue() ?? 1)) * ratio))
|
|
251
|
+
});
|
|
252
|
+
return this.rectClip();
|
|
253
|
+
}
|
|
254
|
+
handlerMousemove(e) {
|
|
255
|
+
const typeState = ['BL', 'TL', 'TR', 'BR', 'VL', 'VR', 'HT', 'HB'];
|
|
256
|
+
const methodName = `resizeCropFollow${this.resizeState()}Dir`; // resizeCropFollowBLDir, resizeCropFollowTLDir, resizeCropFollowTRDir, resizeCropFollowBRDir, resizeCropFollowVLDir, resizeCropFollowVRDir, resizeCropFollowHTDir, resizeCropFollowHBDir
|
|
257
|
+
if (typeState.includes(this.resizeState())) {
|
|
258
|
+
this[methodName](e);
|
|
259
|
+
}
|
|
260
|
+
switch (this.moveState()) {
|
|
261
|
+
case 'clip':
|
|
262
|
+
this.moveClipArea(e);
|
|
263
|
+
break;
|
|
264
|
+
case 'image':
|
|
265
|
+
this.moveImage(e);
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
this.changedImage(true);
|
|
269
|
+
}
|
|
270
|
+
resizeCropFollowBLDir = (e) => {
|
|
271
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
272
|
+
const momentX = this.ratioValue() ? -momentY * this.ratioValue() : e.clientX - this.startMouseDim().clientX;
|
|
273
|
+
const maxHeight = this.startMouseDim().imageTop + this.startMouseDim().imageHeight - this.startMouseDim().top;
|
|
274
|
+
const maxWidth = this.startMouseDim().left + this.startMouseDim().width - this.startMouseDim().imageLeft;
|
|
275
|
+
let { width, height, left } = this.getRectResizeCropFollow({ width: -1, height: 1, left: 1, top: 0 }, momentX, momentY);
|
|
276
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
277
|
+
left = this.startMouseDim().left + this.startMouseDim().width - width;
|
|
278
|
+
this.setStylesElements(this.cropArea(), { left, height, width }, true);
|
|
279
|
+
};
|
|
280
|
+
resizeCropFollowTLDir = (e) => {
|
|
281
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
282
|
+
const momentX = this.ratioValue() ? this.ratioValue() * momentY : e.clientX - this.startMouseDim().clientX;
|
|
283
|
+
const maxHeight = this.startMouseDim().top + this.startMouseDim().height - this.startMouseDim().imageTop;
|
|
284
|
+
const maxWidth = this.startMouseDim().left + this.startMouseDim().width - this.startMouseDim().imageLeft;
|
|
285
|
+
let { width, height, top, left } = this.getRectResizeCropFollow({ width: -1, height: -1, left: 1, top: 1 }, momentX, momentY);
|
|
286
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
287
|
+
left = this.startMouseDim().left + this.startMouseDim().width - width;
|
|
288
|
+
top = this.startMouseDim().top + this.startMouseDim().height - height;
|
|
289
|
+
this.setStylesElements(this.cropArea(), { top, left, height, width }, true);
|
|
290
|
+
};
|
|
291
|
+
resizeCropFollowTRDir = (e) => {
|
|
292
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
293
|
+
const momentX = this.ratioValue() ? -momentY * this.ratioValue() : e.clientX - this.startMouseDim().clientX;
|
|
294
|
+
const maxHeight = this.startMouseDim().top + this.startMouseDim().height - this.startMouseDim().imageTop;
|
|
295
|
+
const maxWidth = this.startMouseDim().imageLeft + this.startMouseDim().imageWidth - this.startMouseDim().left;
|
|
296
|
+
let { width, height, top } = this.getRectResizeCropFollow({ width: 1, height: -1, left: 0, top: 1 }, momentX, momentY);
|
|
297
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
298
|
+
top = this.startMouseDim().top + this.startMouseDim().height - height;
|
|
299
|
+
this.setStylesElements(this.cropArea(), { top, height, width }, true);
|
|
300
|
+
};
|
|
301
|
+
resizeCropFollowBRDir(e) {
|
|
302
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
303
|
+
const momentX = this.ratioValue() ? momentY * this.ratioValue() : e.clientX - this.startMouseDim().clientX;
|
|
304
|
+
const maxHeight = this.startMouseDim().imageTop + this.startMouseDim().imageHeight - this.startMouseDim().top;
|
|
305
|
+
const maxWidth = this.startMouseDim().imageLeft + this.startMouseDim().imageWidth - this.startMouseDim().left;
|
|
306
|
+
let { width, height } = this.getRectResizeCropFollow({ width: 1, height: 1, left: 0, top: 0 }, momentX, momentY);
|
|
307
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
308
|
+
this.setStylesElements(this.cropArea(), { height, width }, true);
|
|
309
|
+
}
|
|
310
|
+
resizeCropFollowVLDir = (e) => {
|
|
311
|
+
const momentX = e.clientX - this.startMouseDim().clientX;
|
|
312
|
+
const momentY = this.ratioValue() ? momentX / this.ratioValue() : 0;
|
|
313
|
+
const maxHeight = this.startMouseDim().top + this.startMouseDim().height - this.startMouseDim().imageTop;
|
|
314
|
+
const maxWidth = this.startMouseDim().left + this.startMouseDim().width - this.startMouseDim().imageLeft;
|
|
315
|
+
let { width, height, top, left } = this.getRectResizeCropFollow({ width: -1, height: -1, left: 1, top: 1 }, momentX, momentY);
|
|
316
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
317
|
+
left = this.startMouseDim().left + this.startMouseDim().width - width;
|
|
318
|
+
top = this.startMouseDim().top + this.startMouseDim().height - height;
|
|
319
|
+
this.setStylesElements(this.cropArea(), { top, left, height, width }, true);
|
|
320
|
+
};
|
|
321
|
+
resizeCropFollowVRDir = (e) => {
|
|
322
|
+
const momentX = e.clientX - this.startMouseDim().clientX;
|
|
323
|
+
const momentY = this.ratioValue() ? -momentX / this.ratioValue() : 0;
|
|
324
|
+
const maxHeight = this.startMouseDim().top + this.startMouseDim().height - this.startMouseDim().imageTop;
|
|
325
|
+
const maxWidth = this.startMouseDim().imageLeft + this.startMouseDim().imageWidth - this.startMouseDim().left;
|
|
326
|
+
let { width, height, top } = this.getRectResizeCropFollow({ width: 1, height: -1, left: 0, top: 1 }, momentX, momentY);
|
|
327
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
328
|
+
top = this.startMouseDim().top + this.startMouseDim().height - height;
|
|
329
|
+
this.setStylesElements(this.cropArea(), { top, height, width }, true);
|
|
330
|
+
};
|
|
331
|
+
resizeCropFollowHTDir = (e) => {
|
|
332
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
333
|
+
const momentX = this.ratioValue() ? momentY * this.ratioValue() : 0;
|
|
334
|
+
const maxWidth = this.startMouseDim().width + this.startMouseDim().left - this.startMouseDim().imageLeft;
|
|
335
|
+
const maxHeight = this.startMouseDim().top + this.startMouseDim().height - this.startMouseDim().imageTop;
|
|
336
|
+
let { width, height, top, left } = this.getRectResizeCropFollow({ width: -1, height: -1, left: 1, top: 1 }, momentX, momentY);
|
|
337
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
338
|
+
top = this.startMouseDim().top + this.startMouseDim().height - height;
|
|
339
|
+
left = this.startMouseDim().left + this.startMouseDim().width - width;
|
|
340
|
+
this.setStylesElements(this.cropArea(), { top, left, height, width }, true);
|
|
341
|
+
};
|
|
342
|
+
resizeCropFollowHBDir = (e) => {
|
|
343
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
344
|
+
const momentX = this.ratioValue() ? momentY * this.ratioValue() : 0;
|
|
345
|
+
const maxHeight = this.startMouseDim().imageTop + this.startMouseDim().imageHeight - this.startMouseDim().top;
|
|
346
|
+
const maxWidth = this.startMouseDim().width + this.startMouseDim().left - this.startMouseDim().imageLeft;
|
|
347
|
+
let { width, height, left } = this.getRectResizeCropFollow({ width: 1, height: 1, left: -1, top: 0 }, momentX, momentY);
|
|
348
|
+
[width, height] = getWidthHeightResizeCropFollow(this.ratioValue(), width, height, maxWidth, maxHeight, this.minWidth, this.minHeight);
|
|
349
|
+
left = this.startMouseDim().left + this.startMouseDim().width - width;
|
|
350
|
+
this.setStylesElements(this.cropArea(), { height, left, width }, true);
|
|
351
|
+
};
|
|
352
|
+
getRectResizeCropFollow(ratio, momentX, momentY) {
|
|
353
|
+
const width = this.startMouseDim().width + momentX * ratio.width;
|
|
354
|
+
const height = this.startMouseDim().height + momentY * ratio.height;
|
|
355
|
+
const top = this.startMouseDim().top + momentY * ratio.top;
|
|
356
|
+
const left = this.startMouseDim().left + momentX * ratio.left;
|
|
357
|
+
return { width, height, left, top };
|
|
358
|
+
}
|
|
359
|
+
handlerMouseup() {
|
|
360
|
+
this.imageContainer().nativeElement.classList.remove('cursor-move');
|
|
361
|
+
this.cropArea().nativeElement.classList.remove('cursor-move');
|
|
362
|
+
this.resizeState.set('none');
|
|
363
|
+
this.moveState.set('none');
|
|
364
|
+
}
|
|
365
|
+
handlerMousewheel(event) {
|
|
366
|
+
if (!this.hasZoom()) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (event.deltaY < 0) {
|
|
370
|
+
this.zoomImage(1 / 1.1);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
this.zoomImage(1.1);
|
|
374
|
+
}
|
|
375
|
+
handlerImageContainerMousedown(e) {
|
|
376
|
+
if (this.resizeState() === 'none' && this.moveState() === 'none') {
|
|
377
|
+
this.moveState.set('image');
|
|
378
|
+
this.handlerMousedown(e);
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
handlerCropResize(e, resizeType) {
|
|
383
|
+
this.resizeState.set(resizeType);
|
|
384
|
+
this.dragGridCrop.set(true);
|
|
385
|
+
this.handlerMousedown(e);
|
|
386
|
+
}
|
|
387
|
+
handlerMousedownCropArea(e) {
|
|
388
|
+
this.moveState.set('clip');
|
|
389
|
+
this.handlerMousedown(e);
|
|
390
|
+
}
|
|
391
|
+
handlerMousedown(e) {
|
|
392
|
+
const [width, height, top, left] = getStylesOfElement(this.cropArea().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
393
|
+
const [imageWidth, imageHeight, imageTop, imageLeft] = getStylesOfElement(this.imageOrigin().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
394
|
+
switch (this.moveState()) {
|
|
395
|
+
case 'image':
|
|
396
|
+
this.imageContainer().nativeElement.classList.add('cursor-move');
|
|
397
|
+
break;
|
|
398
|
+
case 'clip':
|
|
399
|
+
if (width === imageWidth && height === imageHeight) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
this.cropArea().nativeElement.classList.add('cursor-move');
|
|
403
|
+
break;
|
|
404
|
+
default:
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
this.startMouseDim.set({
|
|
408
|
+
clientX: e.clientX,
|
|
409
|
+
clientY: e.clientY,
|
|
410
|
+
width: width,
|
|
411
|
+
height: height,
|
|
412
|
+
top: top,
|
|
413
|
+
left: left,
|
|
414
|
+
imageTop: imageTop,
|
|
415
|
+
imageLeft: imageLeft,
|
|
416
|
+
imageWidth: imageWidth,
|
|
417
|
+
imageHeight: imageHeight
|
|
418
|
+
});
|
|
419
|
+
this.ratioValue.set(this.getCropRatioValue());
|
|
420
|
+
}
|
|
421
|
+
moveImage(e) {
|
|
422
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
423
|
+
const momentX = e.clientX - this.startMouseDim().clientX;
|
|
424
|
+
const imgTop = this.startMouseDim().imageTop + momentY;
|
|
425
|
+
const imgLeft = this.startMouseDim().imageLeft + momentX;
|
|
426
|
+
const top = this.startMouseDim().top + momentY;
|
|
427
|
+
const left = this.startMouseDim().left + momentX;
|
|
428
|
+
this.setStylesElements(this.imageOrigin(), { top: imgTop, left: imgLeft });
|
|
429
|
+
this.setStylesElements(this.imageClip(), { top: imgTop, left: imgLeft });
|
|
430
|
+
this.setStylesElements(this.cropArea(), { top, left });
|
|
431
|
+
this.setCirclePosition({ top: imgTop, left: imgLeft, width: this.startMouseDim().imageWidth, height: this.startMouseDim().imageHeight });
|
|
432
|
+
}
|
|
433
|
+
moveClipArea(e) {
|
|
434
|
+
const [imgWidth, imgHeight, imgTop, imgLeft] = getStylesOfElement(this.imageClip().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
435
|
+
const [cropWidth, cropHeight] = getStylesOfElement(this.cropArea().nativeElement, ['offsetWidth', 'offsetHeight']);
|
|
436
|
+
const momentY = e.clientY - this.startMouseDim().clientY;
|
|
437
|
+
const momentX = e.clientX - this.startMouseDim().clientX;
|
|
438
|
+
let top = Math.max(imgTop, this.startMouseDim().top + momentY);
|
|
439
|
+
let left = Math.max(imgLeft, this.startMouseDim().left + momentX);
|
|
440
|
+
top = Math.min(top, imgTop + imgHeight - cropHeight);
|
|
441
|
+
left = Math.min(left, imgLeft + imgWidth - cropWidth);
|
|
442
|
+
this.setStylesElements(this.cropArea(), { top, left }, true);
|
|
443
|
+
}
|
|
444
|
+
zoomImage(scale) {
|
|
445
|
+
const [currWidth, currHeight, currTop, currLeft] = getStylesOfElement(this.imageOrigin().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
446
|
+
const width = Math.max(currWidth * scale, 50);
|
|
447
|
+
const height = this.imageOrigin().nativeElement.offsetHeight * width / this.imageOrigin().nativeElement.offsetWidth;
|
|
448
|
+
const top = currTop + (currHeight - height) / 2;
|
|
449
|
+
const left = currLeft + (currWidth - width) / 2;
|
|
450
|
+
let [cropWidth, cropHeight] = getStylesOfElement(this.cropArea().nativeElement, ['offsetWidth', 'offsetHeight']);
|
|
451
|
+
const [cropTop, cropLeft] = getStylesOfElement(this.cropArea().nativeElement, ['style.top', 'style.left']);
|
|
452
|
+
const maxCropWidth = width + left - cropLeft;
|
|
453
|
+
const maxCropHeight = height + top - cropTop;
|
|
454
|
+
const minWidth = 20;
|
|
455
|
+
const minHeight = 20;
|
|
456
|
+
cropWidth = Math.min(cropWidth, maxCropWidth);
|
|
457
|
+
cropHeight = Math.min(cropHeight, maxCropHeight);
|
|
458
|
+
cropWidth = Math.max(cropWidth, minWidth);
|
|
459
|
+
cropHeight = Math.max(cropHeight, minHeight);
|
|
460
|
+
this.ratioValue.set(this.getCropRatioValue());
|
|
461
|
+
if (this.ratioValue()) {
|
|
462
|
+
cropHeight = cropWidth / this.ratioValue();
|
|
463
|
+
cropHeight = Math.min(cropHeight, maxCropHeight);
|
|
464
|
+
cropHeight = Math.max(cropHeight, minHeight);
|
|
465
|
+
cropWidth = cropHeight * this.ratioValue();
|
|
466
|
+
}
|
|
467
|
+
this.rectClip.update(rect => {
|
|
468
|
+
const rectTop = cropTop - top;
|
|
469
|
+
const rectLeft = cropLeft - left;
|
|
470
|
+
return {
|
|
471
|
+
...rect,
|
|
472
|
+
top: rectTop,
|
|
473
|
+
left: rectLeft,
|
|
474
|
+
right: rectLeft + cropWidth,
|
|
475
|
+
bottom: rectTop + cropHeight
|
|
476
|
+
};
|
|
477
|
+
});
|
|
478
|
+
const clip = `rect(${this.rectClip().top}px, ${this.rectClip().right}px, ${this.rectClip().bottom}px, ${this.rectClip().left}px)`;
|
|
479
|
+
this.setStylesElements(this.cropArea(), { top: cropTop, left: cropLeft, width: cropWidth, height: cropHeight });
|
|
480
|
+
this.setStylesElements(this.imageOrigin(), { top, left, width, height });
|
|
481
|
+
this.setCirclePosition({ top, left, width, height });
|
|
482
|
+
this.setStylesElements(this.imageClip(), { clip, top, left, width, height });
|
|
483
|
+
this.getRectClipImage();
|
|
484
|
+
}
|
|
485
|
+
handlerRotateImage(event) {
|
|
486
|
+
event.stopPropagation();
|
|
487
|
+
this.image.src = this.imgSrc();
|
|
488
|
+
this.image.onload = () => {
|
|
489
|
+
const canvas = document.createElement('canvas');
|
|
490
|
+
const ctx = canvas.getContext("2d");
|
|
491
|
+
const [width, height] = getStylesOfElement(this.imageOrigin().nativeElement, ['offsetWidth', 'offsetHeight']);
|
|
492
|
+
const originWidth = this.image.width;
|
|
493
|
+
const originHeight = this.image.height;
|
|
494
|
+
let top = parseInt(this.imageOrigin().nativeElement.style.top);
|
|
495
|
+
let left = parseInt(this.imageOrigin().nativeElement.style.left);
|
|
496
|
+
let newHeight = width;
|
|
497
|
+
let newWidth = height;
|
|
498
|
+
const ratio = newWidth / newHeight;
|
|
499
|
+
canvas.height = originWidth;
|
|
500
|
+
canvas.width = originHeight;
|
|
501
|
+
ctx?.translate(originHeight / 2, originWidth / 2);
|
|
502
|
+
ctx?.rotate(Math.PI / 2);
|
|
503
|
+
ctx?.drawImage(this.image, -originWidth / 2, -originHeight / 2);
|
|
504
|
+
const src = getDataUrl(canvas, this.mimetype(), this.image.src);
|
|
505
|
+
this.imgSrc.set(src);
|
|
506
|
+
newWidth = Math.max(newWidth, originHeight);
|
|
507
|
+
newWidth = Math.min(newWidth, this.containerWidth());
|
|
508
|
+
newHeight = newWidth / ratio;
|
|
509
|
+
newHeight = Math.max(newHeight, originWidth);
|
|
510
|
+
newHeight = Math.min(newHeight, this.containerHeight());
|
|
511
|
+
newWidth = newHeight * ratio;
|
|
512
|
+
top = top - (newHeight / 2 - height / 2);
|
|
513
|
+
left = left - (newWidth / 2 - width / 2);
|
|
514
|
+
this.setStylesElements(this.imageOrigin(), { src, top, left, width: newWidth, height: newHeight });
|
|
515
|
+
this.setCirclePosition({ top, left, width: newWidth, height: newHeight });
|
|
516
|
+
this.setStylesElements(this.imageClip(), { src, top, left, width: newWidth, height: newHeight });
|
|
517
|
+
this.getOriginalImageSize(() => {
|
|
518
|
+
this.cropSize.set({ width: this.originWidth(), height: this.originHeight() });
|
|
519
|
+
this.updateOriginImageSize();
|
|
520
|
+
});
|
|
521
|
+
this.changedImage(true);
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
getOriginalImageSize(callback) {
|
|
525
|
+
this.image.src = this.imgSrc();
|
|
526
|
+
this.image.onload = () => {
|
|
527
|
+
this.originWidth.set(this.image.width);
|
|
528
|
+
this.originHeight.set(this.image.height);
|
|
529
|
+
if (callback) {
|
|
530
|
+
return callback();
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
changedImage(status) {
|
|
535
|
+
this.changed.set(status);
|
|
536
|
+
}
|
|
537
|
+
handlerFlipImage(event, mode) {
|
|
538
|
+
event.stopPropagation();
|
|
539
|
+
this.image.src = this.imgSrc();
|
|
540
|
+
this.image.onload = () => {
|
|
541
|
+
const canvas = document.createElement('canvas');
|
|
542
|
+
const ctx = canvas.getContext("2d");
|
|
543
|
+
const width = this.image.width;
|
|
544
|
+
const height = this.image.height;
|
|
545
|
+
canvas.height = height;
|
|
546
|
+
canvas.width = width;
|
|
547
|
+
if (ctx) {
|
|
548
|
+
ctx.drawImage(this.image, 0, 0, width, height);
|
|
549
|
+
if (mode === 'horizontal') {
|
|
550
|
+
ctx.translate(width, 0);
|
|
551
|
+
ctx.scale(-1, 1);
|
|
552
|
+
}
|
|
553
|
+
if (mode === 'vertical') {
|
|
554
|
+
ctx.translate(0, height);
|
|
555
|
+
ctx.scale(1, -1);
|
|
556
|
+
}
|
|
557
|
+
ctx.clearRect(0, 0, width, height);
|
|
558
|
+
ctx.drawImage(this.image, 0, 0);
|
|
559
|
+
}
|
|
560
|
+
const dataUrl = getDataUrl(canvas, this.mimetype(), this.image.src);
|
|
561
|
+
this.imgSrc.set(dataUrl);
|
|
562
|
+
this.imageOrigin().nativeElement.src = dataUrl;
|
|
563
|
+
this.imageClip().nativeElement.src = dataUrl;
|
|
564
|
+
this.updateCropAreaPos();
|
|
565
|
+
this.updateRectClipPos();
|
|
566
|
+
this.changedImage(true);
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
handlerRestoreImage(event) {
|
|
570
|
+
event.stopPropagation();
|
|
571
|
+
this.imgSrc.set(this.dataUrlOrigin());
|
|
572
|
+
this.dragGridCrop.set(false);
|
|
573
|
+
this.getOriginalImageSize(() => {
|
|
574
|
+
this.updateOriginImageSize();
|
|
575
|
+
this.changedImage(false);
|
|
576
|
+
this.cropRatioItemSelected.set('');
|
|
577
|
+
this.updateCropAreaPos();
|
|
578
|
+
this.updateRectClipPos();
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
cropImage() {
|
|
582
|
+
return new Promise((resolve) => {
|
|
583
|
+
this.image.src = this.imgSrc();
|
|
584
|
+
this.image.onload = () => {
|
|
585
|
+
const canvas = document.createElement('canvas');
|
|
586
|
+
const originWidth = this.image.width;
|
|
587
|
+
const width = parseInt(this.imageClip().nativeElement.offsetWidth);
|
|
588
|
+
const height = parseInt(this.imageClip().nativeElement.offsetHeight);
|
|
589
|
+
const scale = originWidth / width;
|
|
590
|
+
const rectClip = this.getRectClipImage();
|
|
591
|
+
const cropRect = getCropRectImage(rectClip, width, height, scale);
|
|
592
|
+
canvas.height = cropRect.height;
|
|
593
|
+
canvas.width = cropRect.width;
|
|
594
|
+
this.originHeight.set(canvas.height);
|
|
595
|
+
this.originWidth.set(canvas.width);
|
|
596
|
+
const ctx = canvas.getContext("2d");
|
|
597
|
+
if (ctx) {
|
|
598
|
+
ctx.drawImage(this.image, cropRect.left, cropRect.top, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height);
|
|
599
|
+
}
|
|
600
|
+
const dataUrl = getDataUrl(canvas, this.mimetype(), this.image.src);
|
|
601
|
+
this.changedImage(true);
|
|
602
|
+
resolve(dataUrl);
|
|
603
|
+
};
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
async handlerSaveFile(event, modeSave) {
|
|
607
|
+
event.stopPropagation();
|
|
608
|
+
const dataUrl = await this.cropImage();
|
|
609
|
+
const file = convertBase64ToBlob(dataUrl);
|
|
610
|
+
this.outSaveFile.emit({ file: file, url: dataUrl, mode: modeSave });
|
|
611
|
+
}
|
|
612
|
+
async handlerClose(event) {
|
|
613
|
+
event.stopPropagation();
|
|
614
|
+
this.outClose.emit({ isClickButtonClose: true });
|
|
615
|
+
}
|
|
616
|
+
handlerSelectCropRatioItem(event, key) {
|
|
617
|
+
event.stopPropagation();
|
|
618
|
+
this.cropRatioItemSelected.set(key);
|
|
619
|
+
this.aspectRatio.set(undefined);
|
|
620
|
+
this.changed.set(true);
|
|
621
|
+
this.dragGridCrop.set(true);
|
|
622
|
+
this.updateOriginImageSize();
|
|
623
|
+
}
|
|
624
|
+
handlerResize(event) {
|
|
625
|
+
event.stopPropagation();
|
|
626
|
+
if (this.resizeComponentRef) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
this.resizeComponentRef = this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsImageEditorResizeComponent);
|
|
630
|
+
const instance = this.resizeComponentRef.instance;
|
|
631
|
+
const subs = instance.outClose.pipe(takeUntil(this.onDestroy)).subscribe(() => {
|
|
632
|
+
this.dynamicComponentService.remove(this.resizeComponentRef);
|
|
633
|
+
this.resizeComponentRef = undefined;
|
|
634
|
+
subs.unsubscribe();
|
|
635
|
+
});
|
|
636
|
+
instance.src = this.imgSrc();
|
|
637
|
+
instance.mimetype = this.mimetype();
|
|
638
|
+
instance.zIndex = this.zIndex();
|
|
639
|
+
subs.add(instance.outSave.pipe(takeUntil(this.onDestroy)).subscribe(event => {
|
|
640
|
+
this.resizeData.set(event);
|
|
641
|
+
this.saveResize();
|
|
642
|
+
}));
|
|
643
|
+
instance.resizeData = { ratio: 100, width: this.originWidth(), height: this.originHeight() };
|
|
644
|
+
instance.originWidth = this.originWidth();
|
|
645
|
+
instance.originHeight = this.originHeight();
|
|
646
|
+
this.dynamicComponentService.addToBody(this.resizeComponentRef);
|
|
647
|
+
}
|
|
648
|
+
saveResize() {
|
|
649
|
+
this.image.src = this.imgSrc();
|
|
650
|
+
this.image.onload = () => {
|
|
651
|
+
const canvas = document.createElement('canvas');
|
|
652
|
+
canvas.width = this.resizeData().width;
|
|
653
|
+
canvas.height = this.resizeData().height;
|
|
654
|
+
const ctx = canvas.getContext('2d');
|
|
655
|
+
if (ctx) {
|
|
656
|
+
ctx.drawImage(this.image, 0, 0, canvas.width, canvas.height);
|
|
657
|
+
}
|
|
658
|
+
const src = getDataUrl(canvas, this.mimetype(), this.image.src);
|
|
659
|
+
const [currWidth, currHeight, currTop, currLeft] = getStylesOfElement(this.imageOrigin().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
660
|
+
const ratio = currWidth / currHeight;
|
|
661
|
+
let newWidth = Math.min(this.resizeData().width, this.containerWidth());
|
|
662
|
+
let newHeight = newWidth / ratio;
|
|
663
|
+
newHeight = Math.min(this.resizeData().height, this.containerHeight());
|
|
664
|
+
newWidth = newHeight * ratio;
|
|
665
|
+
Math.min(this.resizeData().height, this.containerHeight());
|
|
666
|
+
const top = currTop + (currHeight - newHeight) / 2;
|
|
667
|
+
const left = currLeft + (currWidth - newWidth) / 2;
|
|
668
|
+
const movementY = currTop - top;
|
|
669
|
+
const movementX = currLeft - left;
|
|
670
|
+
this.rectClip.update(rect => {
|
|
671
|
+
const rectTop = rect.top + movementY;
|
|
672
|
+
const rectLeft = rect.left + movementX;
|
|
673
|
+
return {
|
|
674
|
+
...rect,
|
|
675
|
+
top: rectTop,
|
|
676
|
+
left: rectLeft,
|
|
677
|
+
right: rectLeft + newWidth,
|
|
678
|
+
bottom: rectTop + newHeight
|
|
679
|
+
};
|
|
680
|
+
});
|
|
681
|
+
const clip = `rect(${this.rectClip().top}px, ${this.rectClip().right}px, ${this.rectClip().bottom}px, ${this.rectClip().left}px)`;
|
|
682
|
+
this.setStylesElements(this.imageOrigin(), { src, top, left, width: newWidth, height: newHeight });
|
|
683
|
+
this.setCirclePosition({ top, left, width: newWidth, height: newHeight });
|
|
684
|
+
this.setStylesElements(this.imageClip(), { src, clip, top, left, width: newWidth, height: newHeight });
|
|
685
|
+
this.imgSrc.set(src);
|
|
686
|
+
this.originWidth.set(this.resizeData().width);
|
|
687
|
+
this.originHeight.set(this.resizeData().height);
|
|
688
|
+
this.updateCropAreaPos();
|
|
689
|
+
this.updateRectClipPos();
|
|
690
|
+
this.changedImage(true);
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
handlerCropWidth() {
|
|
694
|
+
this.processCropWidthOrHeight('width');
|
|
695
|
+
}
|
|
696
|
+
handlerCropHeight() {
|
|
697
|
+
this.processCropWidthOrHeight('height');
|
|
698
|
+
}
|
|
699
|
+
processCropWidthOrHeight(cropBy) {
|
|
700
|
+
this.ratioValue.set(this.getCropRatioValue());
|
|
701
|
+
const [currImgWidth, currImgHeight, currImgTop, currImgLeft] = getStylesOfElement(this.imageOrigin().nativeElement, ['offsetWidth', 'offsetHeight', 'style.top', 'style.left']);
|
|
702
|
+
let [cropWidth, cropHeight] = getStylesOfElement(this.cropArea().nativeElement, ['offsetWidth', 'offsetHeight']);
|
|
703
|
+
const [cropTop, cropLeft] = getStylesOfElement(this.cropArea().nativeElement, ['style.top', 'style.left']);
|
|
704
|
+
const maxCropWidth = currImgLeft + currImgWidth - cropLeft;
|
|
705
|
+
const maxCropHeight = currImgHeight + currImgTop - cropTop;
|
|
706
|
+
const ratio = this.originWidth() / currImgWidth;
|
|
707
|
+
let cropValue = get(this.cropSize, cropBy) / ratio;
|
|
708
|
+
cropValue = Math.min(cropValue, cropBy === 'width' ? maxCropWidth : maxCropHeight);
|
|
709
|
+
cropValue = Math.max(1, cropValue);
|
|
710
|
+
if (this.ratioValue()) {
|
|
711
|
+
if (cropBy === 'width') {
|
|
712
|
+
cropHeight = cropValue / this.ratioValue();
|
|
713
|
+
cropHeight = Math.min(cropHeight, maxCropHeight);
|
|
714
|
+
cropValue = cropHeight * this.ratioValue();
|
|
715
|
+
this.cropSize.update(cropSize => ({ ...cropSize, height: Math.round(cropHeight * ratio) }));
|
|
716
|
+
this.cropArea().nativeElement.style.height = `${cropHeight}px`;
|
|
717
|
+
}
|
|
718
|
+
if (cropBy === 'height') {
|
|
719
|
+
cropWidth = cropValue * this.ratioValue();
|
|
720
|
+
cropWidth = Math.min(cropWidth, maxCropWidth);
|
|
721
|
+
cropValue = cropWidth / this.ratioValue();
|
|
722
|
+
this.cropSize.update(cropSize => ({ ...cropSize, width: Math.round(cropWidth * ratio) }));
|
|
723
|
+
this.cropArea().nativeElement.style.width = `${cropWidth}px`;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
this.cropSize.update(cropSize => ({ ...cropSize, [cropBy]: Math.round(cropValue * ratio) }));
|
|
727
|
+
this.cropArea().nativeElement.style[cropBy] = `${cropValue}px`;
|
|
728
|
+
const imageRect = this.imageClip().nativeElement.getBoundingClientRect();
|
|
729
|
+
const cropRect = this.cropArea().nativeElement.getBoundingClientRect();
|
|
730
|
+
const { width, height } = cropRect;
|
|
731
|
+
const left = cropRect.left - imageRect.left;
|
|
732
|
+
const top = cropRect.top - imageRect.top;
|
|
733
|
+
const right = left + width;
|
|
734
|
+
const bottom = top + height;
|
|
735
|
+
this.imageClip().nativeElement.style.clip = `rect(${top}px, ${right}px, ${bottom}px, ${left}px)`;
|
|
736
|
+
}
|
|
737
|
+
setStylesElements(element, styles, isUpdateRectClipPos) {
|
|
738
|
+
if (!isNil(styles.top)) {
|
|
739
|
+
element.nativeElement.style.top = `${styles.top}px`;
|
|
740
|
+
}
|
|
741
|
+
if (!isNil(styles.left)) {
|
|
742
|
+
element.nativeElement.style.left = `${styles.left}px`;
|
|
743
|
+
}
|
|
744
|
+
if (!isNil(styles.width)) {
|
|
745
|
+
element.nativeElement.style.width = `${styles.width}px`;
|
|
746
|
+
}
|
|
747
|
+
if (!isNil(styles.height)) {
|
|
748
|
+
element.nativeElement.style.height = `${styles.height}px`;
|
|
749
|
+
}
|
|
750
|
+
if (!isNil(styles.display)) {
|
|
751
|
+
element.nativeElement.style.display = styles.display;
|
|
752
|
+
}
|
|
753
|
+
if (!isNil(styles.src)) {
|
|
754
|
+
element.nativeElement.src = styles.src;
|
|
755
|
+
}
|
|
756
|
+
if (!isNil(styles.clip)) {
|
|
757
|
+
element.nativeElement.style.clip = styles.clip;
|
|
758
|
+
}
|
|
759
|
+
if (isUpdateRectClipPos) {
|
|
760
|
+
this.updateRectClipPos();
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
ngOnDestroy() {
|
|
764
|
+
this.onDestroy.next();
|
|
765
|
+
this.onDestroy.complete();
|
|
766
|
+
this.dynamicComponentService.remove(this.resizeComponentRef);
|
|
767
|
+
// this.dynamicComponentService.remove(this.forwardComponentRef);
|
|
768
|
+
}
|
|
769
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsImageEditorComponent, deps: [{ token: LINK_IMAGE_ERROR_TOKEN_INJECT, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
770
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsImageEditorComponent, isStandalone: true, selector: "libs_ui-components-image_editor", inputs: { modeShowButton: { classPropertyName: "modeShowButton", publicName: "modeShowButton", isSignal: true, isRequired: false, transformFunction: null }, mimetype: { classPropertyName: "mimetype", publicName: "mimetype", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, imgSrc: { classPropertyName: "imgSrc", publicName: "imgSrc", isSignal: true, isRequired: true, transformFunction: null }, originUrl: { classPropertyName: "originUrl", publicName: "originUrl", isSignal: true, isRequired: false, transformFunction: null }, nameFile: { classPropertyName: "nameFile", publicName: "nameFile", isSignal: true, isRequired: false, transformFunction: null }, hasZoom: { classPropertyName: "hasZoom", publicName: "hasZoom", isSignal: true, isRequired: false, transformFunction: null }, aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null }, requiredCropFollowRatio: { classPropertyName: "requiredCropFollowRatio", publicName: "requiredCropFollowRatio", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imgSrc: "imgSrcChange", aspectRatio: "aspectRatioChange", outClose: "outClose", outSaveFile: "outSaveFile", outFunctionsControl: "outFunctionsControl" }, viewQueries: [{ propertyName: "imageOrigin", first: true, predicate: ["imageOrigin"], descendants: true, isSignal: true }, { propertyName: "imageClip", first: true, predicate: ["imageClip"], descendants: true, isSignal: true }, { propertyName: "imageEditorContainer", first: true, predicate: ["imageEditorContainer"], descendants: true, isSignal: true }, { propertyName: "imageContainer", first: true, predicate: ["imageContainer"], descendants: true, isSignal: true }, { propertyName: "cropArea", first: true, predicate: ["cropArea"], descendants: true, isSignal: true }, { propertyName: "cropTL", first: true, predicate: ["cropTL"], descendants: true, isSignal: true }, { propertyName: "cropBL", first: true, predicate: ["cropBL"], descendants: true, isSignal: true }, { propertyName: "cropBR", first: true, predicate: ["cropBR"], descendants: true, isSignal: true }, { propertyName: "cropTR", first: true, predicate: ["cropTR"], descendants: true, isSignal: true }, { propertyName: "cropLineVL", first: true, predicate: ["cropLineVL"], descendants: true, isSignal: true }, { propertyName: "cropLineVR", first: true, predicate: ["cropLineVR"], descendants: true, isSignal: true }, { propertyName: "cropLineHT", first: true, predicate: ["cropLineHT"], descendants: true, isSignal: true }, { propertyName: "cropLineHB", first: true, predicate: ["cropLineHB"], descendants: true, isSignal: true }, { propertyName: "circleTL", first: true, predicate: ["circleTL"], descendants: true, isSignal: true }, { propertyName: "circleTR", first: true, predicate: ["circleTR"], descendants: true, isSignal: true }, { propertyName: "circleBL", first: true, predicate: ["circleBL"], descendants: true, isSignal: true }, { propertyName: "circleBR", first: true, predicate: ["circleBR"], descendants: true, isSignal: true }], ngImport: i0, template: "<libs_ui-components-modal [width]=\"'calc(100vw - 400px)'\"\n [height]=\"'calc(100vh - 100px)'\"\n [minWidth]=\"'1200px'\"\n [headerConfig]=\"{ignoreHeaderTheme: true, removeButtonClose: true}\"\n [bodyConfig]=\"{classInclude: '!p-0', scrollOverlayOptions: {scrollX: 'hidden', scrollY: 'hidden'}}\"\n [footerConfig]=\"{hidden: true}\"\n [zIndex]=\"zIndex()\"\n [buttonsFooter]=\"[]\"\n [mode]=\"'center'\">\n <div class=\"libs-ui-modal-header-custom w-full flex items-center justify-between\">\n <div class=\"w-full relative mx-[24px] h-[16px]\">\n <div class=\"flex w-full libs-ui-font-h4s absolute\">\n <libs_ui-components-popover [type]=\"'text'\"\n [config]=\"{zIndex: zIndex()}\">\n {{ 'i18n_edit_file_name' | translate:{file_name: nameFile()} }}\n </libs_ui-components-popover>\n </div>\n </div>\n <div class=\"flex items-center\">\n @if (modeShowButton() === 'save-file') {\n <libs_ui-components-buttons-button [type]=\"'button-third'\"\n [label]=\"'i18n_cancel'\"\n [disable]=\"loading() || loadingImage()\"\n [classInclude]=\"'py-[6px] px-[12px] mr-[16px]'\"\n (outClick)=\"handlerClose($event)\" />\n\n <libs_ui-components-buttons-button class=\"mr-[24px]\"\n [label]=\"'i18n_save'\"\n [disable]=\"loading() || loadingImage()\"\n [classInclude]=\"'py-[6px] px-[12px]'\"\n (outClick)=\"handlerSaveFile($event,'save-file')\" />\n }\n @else {\n <libs_ui-components-buttons-button [label]=\"'i18n_save_to_new_file'\"\n [type]=\"'button-outline'\"\n [classInclude]=\"'mx-[16px] py-[6px] px-[12px]'\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerSaveFile($event,'save-api-as-new-file')\" />\n <libs_ui-components-buttons-button [type]=\"'button-secondary'\"\n [label]=\"'i18n_save'\"\n [classInclude]=\"'py-[6px] px-[12px]'\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerSaveFile($event,'save-api')\" />\n <div class=\"h-[12px] libs-ui-border-left-general mx-[16px]\"></div>\n <libs_ui-components-buttons-button class=\"mr-[24px]\"\n [classInclude]=\"'p-[6px]'\"\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [disable]=\"loading()\"\n [popover]=\"{config: {content: 'i18n_exit_edit_mode', zIndex: zIndex()}}\"\n [classIconLeft]=\"'libs-ui-icon-close'\"\n (outClick)=\"handlerClose($event)\" />\n }\n </div>\n </div>\n <div class=\"libs-ui-modal-body-custom h-full w-full flex\">\n <div #imageEditorContainer\n class=\"relative w-full h-full bg-[#e6e7ea] border-radius-bottom-left-8px p-[32px]\">\n @if (loadingImage()) {\n <div class=\"absolute h-full w-full bg-[#e6e7ea] top-0 left-0 z-[5]\">\n <libs_ui-components-spinner [size]=\"'medium'\" />\n </div>\n }\n <div class=\"absolute h-[32px] w-[calc(100%-64px)] bg-[#e6e7eab8] top-0 left-[32px] z-[1]\">\n </div>\n <div class=\"absolute w-[32px] h-full bg-[#e6e7eab8] left-0 top-0 z-[1] rounded-bl-[8px]\">\n </div>\n <div class=\"absolute w-[32px] h-full bg-[#e6e7eab8] right-0 top-0 z-[1]\">\n </div>\n <div class=\"absolute h-[32px] w-[calc(100%-64px)] bg-[#e6e7eab8] bottom-0 left-[32px] z-[1]\">\n </div>\n <div #imageContainer\n class=\"relative w-full h-full rounded-bl-[8px] min-h-0\">\n <div #circleTL\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleTR\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleBL\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleBR\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <img #imageOrigin\n class=\"absolute border-[4px] border-[#8e61ee] rounded-[4px] w-0 h-0\"\n loading=\"lazy\"\n [src]=\"imgSrc()\"\n (load)=\"handlerImageLoaded()\"\n (error)=\"handlerImageError($event)\" />\n <img #imageClip\n class=\"absolute z-[1] w-0 h-0\"\n loading=\"lazy\"\n [src]=\"imgSrc()\"\n (error)=\"handlerImageError($event)\" />\n <div class=\"absolute top-0 left-0 right-0 bottom-0 bg-[#e6e7eab8]\">\n </div>\n <div #cropArea\n class=\"absolute z-[2] border-[4px] border-[#8e61ee] rounded-[4px]\">\n <div class=\"relative w-full h-full\">\n <div #cropTL\n class=\"absolute z-[2] left-[-18px] top-[-17px] libs-ui-image-editor-edit-cursor-nwse-resize\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropBL\n class=\"absolute z-[2] left-[-17px] bottom-[-18px] libs-ui-image-editor-edit-cursor-nesw-resize rotate-[270deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropTR\n class=\"absolute z-[2] right-[-17px] top-[-17px] libs-ui-image-editor-edit-cursor-nesw-resize rotate-[90deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropBR\n class=\"absolute z-[2] right-[-18px] bottom-[-17px] libs-ui-image-editor-edit-cursor-nwse-resize rotate-[180deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropLineVL\n class=\"absolute z-[1] w-[12px] left-[-6px] top-0 bottom-0 libs-ui-image-editor-edit-cursor-ew-resize\">\n </div>\n <div #cropLineVR\n class=\"absolute z-[1] w-[12px] right-[-6px] top-0 bottom-0 libs-ui-image-editor-edit-cursor-ew-resize\">\n </div>\n <div #cropLineHT\n class=\"absolute z-[1] h-[12px] left-0 top-[-6px] right-0 libs-ui-image-editor-edit-cursor-ns-resize\">\n </div>\n <div #cropLineHB\n class=\"absolute z-[1] h-[12px] left-0 right-0 bottom-[-6px] libs-ui-image-editor-edit-cursor-ns-resize\">\n </div>\n <div class=\"absolute z-[1] h-[1px] top-0 left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] h-[1px] bottom-0 left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] w-[1px] top-0 left-0 bottom-0\">\n </div>\n <div class=\"absolute z-[1] w-[1px] top-0 right-0 bottom-0\">\n </div>\n <div class=\"absolute z-[1] h-[2px] top-[33px] left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] h-[2px] top-[66px] left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] w-[2px] top-0 bottom-0 left-[33px]\">\n </div>\n <div class=\"absolute z-[1] w-[2px] top-0 bottom-0 left-[66px]\">\n </div>\n </div>\n </div>\n </div>\n @if (loading()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n <div class=\"w-[320px] shrink-0 p-[16px] bg-[#ffffff] rounded-br-[8px] z-[2]\">\n <div class=\"flex items-center justify-between mb-[16px]\">\n <div class=\"libs-ui-font-h4m\">{{ 'i18n_cutting_ratio' | translate }}</div>\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [type]=\"'button-third'\"\n [classIconLeft]=\"'libs-ui-icon-refresh'\"\n [classInclude]=\"'p-[6px] mr-[8px]'\"\n [popover]=\"{config: {content: 'i18n_restore_the_original_state', zIndex: zIndex()}}\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerRestoreImage($event)\" />\n </div>\n <div class=\"mb-[16px] libs-ui-image-editor-edit-display-grid-gap-16\">\n @for (item of cropRatioItems(); track item.key) {\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage() || requiredCropFollowRatio()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"item.icon+' !text-[20px]'\"\n (outClick)=\"handlerSelectCropRatioItem($event, item.key)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ (item.key === 'free' ? 'i18n_custom' : item.key) | translate }}\n </div>\n </div>\n }\n </div>\n <div class=\"mb-[16px] flex\">\n <libs_ui-components-inputs-valid class=\"mr-[16px]\"\n [dataType]=\"'int'\"\n [labelConfig]=\"{labelLeft: 'i18n_width', classInclude: 'mb-[4px]', labelLeftClass: 'libs-ui-font-h7r'}\"\n [fieldNameBind]=\"'width'\"\n [(item)]=\"cropSize\"\n [unitsRight]=\"[{id: 'px', label: 'px'}]\"\n [keySelectedUnitRight]=\"'px'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"originWidth()\"\n [disable]=\"loading() || loadingImage()\"\n (outValueChange)=\"handlerCropWidth()\" />\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [labelConfig]=\"{labelLeft: 'i18n_length', classInclude: 'mb-[4px]', labelLeftClass: 'libs-ui-font-h7r'}\"\n [fieldNameBind]=\"'height'\"\n [(item)]=\"cropSize\"\n [unitsRight]=\"[{id: 'px', label: 'px'}]\"\n [keySelectedUnitRight]=\"'px'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"originHeight()\"\n [disable]=\"loading() || loadingImage()\"\n (outValueChange)=\"handlerCropHeight()\" />\n </div>\n <div class=\"libs-ui-font-h4m mb-[16px]\">{{ 'i18n_rotate_photos' | translate }}</div>\n <div class=\"flex libs-ui-image-editor-edit-display-grid-gap-16\">\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-rotate-image-outline !text-[20px]'\"\n (outClick)=\"handlerRotateImage($event)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_rotate_ninety_degrees' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-flip-vertical !text-[20px]'\"\n (outClick)=\"handlerFlipImage($event, 'vertical')\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_vertical_flip' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-flip-horizontal !text-[20px]'\"\n (outClick)=\"handlerFlipImage($event, 'horizontal')\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_horizontal_flip' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-scale !text-[20px]'\"\n (outClick)=\"handlerResize($event)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_resize' | translate }}\n </div>\n </div>\n </div>\n </div>\n </div>\n</libs_ui-components-modal>\n\n<ng-template #svgArrow>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 40 40\"\n fill=\"none\">\n <path d=\"M33.6987 14.6969L18.3309 14.6969C16.516 14.6969 15.0311 16.1818 15.0311 17.9967L15.0311 33.3645\"\n stroke=\"white\"\n stroke-width=\"5.83333\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n</ng-template>\n\n<ng-template #svgCircle>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\">\n <circle cx=\"7.5\"\n cy=\"7.5\"\n r=\"7.5\"\n fill=\"white\" />\n </svg>\n</ng-template>\n", styles: [".libs-ui-image-editor-edit-display-grid-gap-16{display:grid;gap:16px;grid-template-columns:1fr 1fr 1fr 1fr}.libs-ui-image-editor-edit-top-33{top:33.33%}.libs-ui-image-editor-edit-top-66{top:66.66%}.libs-ui-image-editor-edit-left-33{left:33.33%}.libs-ui-image-editor-edit-left-66{left:66.66%}.libs-ui-image-editor-edit-cursor-ew-resize{cursor:ew-resize!important}.libs-ui-image-editor-edit-cursor-ns-resize{cursor:ns-resize!important}.libs-ui-image-editor-edit-cursor-nwse-resize{cursor:nwse-resize!important}.libs-ui-image-editor-edit-cursor-nesw-resize{cursor:nesw-resize!important}.libs-ui-image-editor-edit-action-item{display:flex;flex-direction:column;align-items:center;width:60px;cursor:pointer}.libs-ui-image-editor-edit-action-item-icon{padding:12px;border-radius:8px;width:max-content;border:1px solid #e6e7ea}.libs-ui-image-editor-edit-action-item-icon:before{font-size:20px}.libs-ui-image-editor-edit-action-item:hover .libs-ui-image-editor-edit-action-item-icon{border:1px solid var(--mo-global-color-primary-border-hover)}.libs-ui-image-editor-edit-action-item:hover .libs-ui-image-editor-edit-action-item-icon:before{color:var(--mo-global-color-primary-text-bright-20)!important}.libs-ui-image-editor-edit-action-item[active=true] .libs-ui-image-editor-edit-action-item-icon{border:1px solid var(--mo-global-color-primary-border-active)!important;background-color:var(--mo-global-color-primary-background-95)!important}.libs-ui-image-editor-edit-action-item[active=true] .libs-ui-image-editor-edit-action-item-icon:before{color:var(--mo-global-color-primary-text-active)!important}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsModalComponent, selector: "libs_ui-components-modal", inputs: ["show", "mode", "isBackdropTransparent", "isBackgroundTransparentModal", "isSizeBackdropByWidthHeightInput", "hasShadowBoxWhenHiddenBackDropTransparent", "classIncludeModalWrapper", "zIndex", "width", "height", "maxWidth", "maxHeight", "minWidth", "isFullScreen", "disable", "ignoreCommunicateMicroEvent", "headerConfig", "bodyConfig", "footerConfig", "buttonsFooter", "title", "titleUseXssFilter", "titleUseTooltip", "titleUseInnerText"], outputs: ["showChange", "widthChange", "heightChange", "maxWidthChange", "maxHeightChange", "minWidthChange", "disableChange", "buttonsFooterChange", "outScrollContent", "outEvent", "outFunctionControl"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "typeInput", "modeInput", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "ignoreWidthInput100", "classIncludeInput", "classContainerInput", "readonly", "disable", "noBorder", "backgroundNone", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "classContainerBottomInput", "autoRemoveEmoji", "defaultHeight", "maxHeightTextArea", "minHeightTextArea", "ignoreShowError", "borderError", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "zIndexPopoverContent", "unitsLeft", "configUnitLeft", "keySelectedUnitLeft", "unitsRight", "configUnitRight", "keySelectedUnitRight", "maxValueNumber", "minValueNumber", "ignoreContentLeft", "ignoreContentRight", "isBaselineStyle", "valuePatternShowError", "validPattern", "validRequired", "validMinLength", "validMinValue", "validMaxValue", "validMaxLength", "functionValid", "maxLength", "positionMessageErrorStartInput", "classInclude", "resize", "templateLeftBottomInput", "templateRightBottomInput", "onlyAcceptNegativeValue", "autoAddZeroLessThan10InTypeInt", "maxLengthNumberCount", "classMessageErrorInclude", "ignoreStopPropagationEvent", "ignoreUnitRightClassReadOnly", "paddingRightCustomSpecific", "focusTimeOut"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsSpinnerComponent, selector: "libs_ui-components-spinner", inputs: ["type", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
771
|
+
}
|
|
772
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsImageEditorComponent, decorators: [{
|
|
773
|
+
type: Component,
|
|
774
|
+
args: [{ selector: 'libs_ui-components-image_editor', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
775
|
+
NgTemplateOutlet, TranslateModule, LibsUiComponentsPopoverComponent, LibsUiComponentsModalComponent,
|
|
776
|
+
LibsUiComponentsInputsValidComponent, LibsUiComponentsButtonsButtonComponent, LibsUiComponentsSpinnerComponent,
|
|
777
|
+
], template: "<libs_ui-components-modal [width]=\"'calc(100vw - 400px)'\"\n [height]=\"'calc(100vh - 100px)'\"\n [minWidth]=\"'1200px'\"\n [headerConfig]=\"{ignoreHeaderTheme: true, removeButtonClose: true}\"\n [bodyConfig]=\"{classInclude: '!p-0', scrollOverlayOptions: {scrollX: 'hidden', scrollY: 'hidden'}}\"\n [footerConfig]=\"{hidden: true}\"\n [zIndex]=\"zIndex()\"\n [buttonsFooter]=\"[]\"\n [mode]=\"'center'\">\n <div class=\"libs-ui-modal-header-custom w-full flex items-center justify-between\">\n <div class=\"w-full relative mx-[24px] h-[16px]\">\n <div class=\"flex w-full libs-ui-font-h4s absolute\">\n <libs_ui-components-popover [type]=\"'text'\"\n [config]=\"{zIndex: zIndex()}\">\n {{ 'i18n_edit_file_name' | translate:{file_name: nameFile()} }}\n </libs_ui-components-popover>\n </div>\n </div>\n <div class=\"flex items-center\">\n @if (modeShowButton() === 'save-file') {\n <libs_ui-components-buttons-button [type]=\"'button-third'\"\n [label]=\"'i18n_cancel'\"\n [disable]=\"loading() || loadingImage()\"\n [classInclude]=\"'py-[6px] px-[12px] mr-[16px]'\"\n (outClick)=\"handlerClose($event)\" />\n\n <libs_ui-components-buttons-button class=\"mr-[24px]\"\n [label]=\"'i18n_save'\"\n [disable]=\"loading() || loadingImage()\"\n [classInclude]=\"'py-[6px] px-[12px]'\"\n (outClick)=\"handlerSaveFile($event,'save-file')\" />\n }\n @else {\n <libs_ui-components-buttons-button [label]=\"'i18n_save_to_new_file'\"\n [type]=\"'button-outline'\"\n [classInclude]=\"'mx-[16px] py-[6px] px-[12px]'\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerSaveFile($event,'save-api-as-new-file')\" />\n <libs_ui-components-buttons-button [type]=\"'button-secondary'\"\n [label]=\"'i18n_save'\"\n [classInclude]=\"'py-[6px] px-[12px]'\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerSaveFile($event,'save-api')\" />\n <div class=\"h-[12px] libs-ui-border-left-general mx-[16px]\"></div>\n <libs_ui-components-buttons-button class=\"mr-[24px]\"\n [classInclude]=\"'p-[6px]'\"\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [disable]=\"loading()\"\n [popover]=\"{config: {content: 'i18n_exit_edit_mode', zIndex: zIndex()}}\"\n [classIconLeft]=\"'libs-ui-icon-close'\"\n (outClick)=\"handlerClose($event)\" />\n }\n </div>\n </div>\n <div class=\"libs-ui-modal-body-custom h-full w-full flex\">\n <div #imageEditorContainer\n class=\"relative w-full h-full bg-[#e6e7ea] border-radius-bottom-left-8px p-[32px]\">\n @if (loadingImage()) {\n <div class=\"absolute h-full w-full bg-[#e6e7ea] top-0 left-0 z-[5]\">\n <libs_ui-components-spinner [size]=\"'medium'\" />\n </div>\n }\n <div class=\"absolute h-[32px] w-[calc(100%-64px)] bg-[#e6e7eab8] top-0 left-[32px] z-[1]\">\n </div>\n <div class=\"absolute w-[32px] h-full bg-[#e6e7eab8] left-0 top-0 z-[1] rounded-bl-[8px]\">\n </div>\n <div class=\"absolute w-[32px] h-full bg-[#e6e7eab8] right-0 top-0 z-[1]\">\n </div>\n <div class=\"absolute h-[32px] w-[calc(100%-64px)] bg-[#e6e7eab8] bottom-0 left-[32px] z-[1]\">\n </div>\n <div #imageContainer\n class=\"relative w-full h-full rounded-bl-[8px] min-h-0\">\n <div #circleTL\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleTR\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleBL\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <div #circleBR\n class=\"absolute z-[5]\"\n [class.hidden]=\"!dragGridCrop()\"\n [class.flex]=\"dragGridCrop()\">\n <ng-template *ngTemplateOutlet=\"svgCircle\" />\n </div>\n <img #imageOrigin\n class=\"absolute border-[4px] border-[#8e61ee] rounded-[4px] w-0 h-0\"\n loading=\"lazy\"\n [src]=\"imgSrc()\"\n (load)=\"handlerImageLoaded()\"\n (error)=\"handlerImageError($event)\" />\n <img #imageClip\n class=\"absolute z-[1] w-0 h-0\"\n loading=\"lazy\"\n [src]=\"imgSrc()\"\n (error)=\"handlerImageError($event)\" />\n <div class=\"absolute top-0 left-0 right-0 bottom-0 bg-[#e6e7eab8]\">\n </div>\n <div #cropArea\n class=\"absolute z-[2] border-[4px] border-[#8e61ee] rounded-[4px]\">\n <div class=\"relative w-full h-full\">\n <div #cropTL\n class=\"absolute z-[2] left-[-18px] top-[-17px] libs-ui-image-editor-edit-cursor-nwse-resize\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropBL\n class=\"absolute z-[2] left-[-17px] bottom-[-18px] libs-ui-image-editor-edit-cursor-nesw-resize rotate-[270deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropTR\n class=\"absolute z-[2] right-[-17px] top-[-17px] libs-ui-image-editor-edit-cursor-nesw-resize rotate-[90deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropBR\n class=\"absolute z-[2] right-[-18px] bottom-[-17px] libs-ui-image-editor-edit-cursor-nwse-resize rotate-[180deg]\">\n <ng-template *ngTemplateOutlet=\"svgArrow\" />\n </div>\n <div #cropLineVL\n class=\"absolute z-[1] w-[12px] left-[-6px] top-0 bottom-0 libs-ui-image-editor-edit-cursor-ew-resize\">\n </div>\n <div #cropLineVR\n class=\"absolute z-[1] w-[12px] right-[-6px] top-0 bottom-0 libs-ui-image-editor-edit-cursor-ew-resize\">\n </div>\n <div #cropLineHT\n class=\"absolute z-[1] h-[12px] left-0 top-[-6px] right-0 libs-ui-image-editor-edit-cursor-ns-resize\">\n </div>\n <div #cropLineHB\n class=\"absolute z-[1] h-[12px] left-0 right-0 bottom-[-6px] libs-ui-image-editor-edit-cursor-ns-resize\">\n </div>\n <div class=\"absolute z-[1] h-[1px] top-0 left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] h-[1px] bottom-0 left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] w-[1px] top-0 left-0 bottom-0\">\n </div>\n <div class=\"absolute z-[1] w-[1px] top-0 right-0 bottom-0\">\n </div>\n <div class=\"absolute z-[1] h-[2px] top-[33px] left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] h-[2px] top-[66px] left-0 right-0\">\n </div>\n <div class=\"absolute z-[1] w-[2px] top-0 bottom-0 left-[33px]\">\n </div>\n <div class=\"absolute z-[1] w-[2px] top-0 bottom-0 left-[66px]\">\n </div>\n </div>\n </div>\n </div>\n @if (loading()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n <div class=\"w-[320px] shrink-0 p-[16px] bg-[#ffffff] rounded-br-[8px] z-[2]\">\n <div class=\"flex items-center justify-between mb-[16px]\">\n <div class=\"libs-ui-font-h4m\">{{ 'i18n_cutting_ratio' | translate }}</div>\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [type]=\"'button-third'\"\n [classIconLeft]=\"'libs-ui-icon-refresh'\"\n [classInclude]=\"'p-[6px] mr-[8px]'\"\n [popover]=\"{config: {content: 'i18n_restore_the_original_state', zIndex: zIndex()}}\"\n [disable]=\"loading() || loadingImage() || !changed()\"\n (outClick)=\"handlerRestoreImage($event)\" />\n </div>\n <div class=\"mb-[16px] libs-ui-image-editor-edit-display-grid-gap-16\">\n @for (item of cropRatioItems(); track item.key) {\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage() || requiredCropFollowRatio()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"item.icon+' !text-[20px]'\"\n (outClick)=\"handlerSelectCropRatioItem($event, item.key)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ (item.key === 'free' ? 'i18n_custom' : item.key) | translate }}\n </div>\n </div>\n }\n </div>\n <div class=\"mb-[16px] flex\">\n <libs_ui-components-inputs-valid class=\"mr-[16px]\"\n [dataType]=\"'int'\"\n [labelConfig]=\"{labelLeft: 'i18n_width', classInclude: 'mb-[4px]', labelLeftClass: 'libs-ui-font-h7r'}\"\n [fieldNameBind]=\"'width'\"\n [(item)]=\"cropSize\"\n [unitsRight]=\"[{id: 'px', label: 'px'}]\"\n [keySelectedUnitRight]=\"'px'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"originWidth()\"\n [disable]=\"loading() || loadingImage()\"\n (outValueChange)=\"handlerCropWidth()\" />\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [labelConfig]=\"{labelLeft: 'i18n_length', classInclude: 'mb-[4px]', labelLeftClass: 'libs-ui-font-h7r'}\"\n [fieldNameBind]=\"'height'\"\n [(item)]=\"cropSize\"\n [unitsRight]=\"[{id: 'px', label: 'px'}]\"\n [keySelectedUnitRight]=\"'px'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"originHeight()\"\n [disable]=\"loading() || loadingImage()\"\n (outValueChange)=\"handlerCropHeight()\" />\n </div>\n <div class=\"libs-ui-font-h4m mb-[16px]\">{{ 'i18n_rotate_photos' | translate }}</div>\n <div class=\"flex libs-ui-image-editor-edit-display-grid-gap-16\">\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-rotate-image-outline !text-[20px]'\"\n (outClick)=\"handlerRotateImage($event)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_rotate_ninety_degrees' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-flip-vertical !text-[20px]'\"\n (outClick)=\"handlerFlipImage($event, 'vertical')\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_vertical_flip' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-flip-horizontal !text-[20px]'\"\n (outClick)=\"handlerFlipImage($event, 'horizontal')\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_horizontal_flip' | translate }}\n </div>\n </div>\n\n <div class=\"flex flex-col items-center\">\n <libs_ui-components-buttons-button [iconOnlyType]=\"true\"\n [sizeButton]=\"'large'\"\n [disable]=\"loading() || loadingImage()\"\n [type]=\"'button-outline'\"\n [classIconLeft]=\"'libs-ui-icon-scale !text-[20px]'\"\n (outClick)=\"handlerResize($event)\" />\n <div class=\"libs-ui-font-h6r text-[#6a7383] mt-[4px]\">\n {{ 'i18n_resize' | translate }}\n </div>\n </div>\n </div>\n </div>\n </div>\n</libs_ui-components-modal>\n\n<ng-template #svgArrow>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 40 40\"\n fill=\"none\">\n <path d=\"M33.6987 14.6969L18.3309 14.6969C16.516 14.6969 15.0311 16.1818 15.0311 17.9967L15.0311 33.3645\"\n stroke=\"white\"\n stroke-width=\"5.83333\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n</ng-template>\n\n<ng-template #svgCircle>\n <svg xmlns=\"http://www.w3.org/2000/svg\"\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\">\n <circle cx=\"7.5\"\n cy=\"7.5\"\n r=\"7.5\"\n fill=\"white\" />\n </svg>\n</ng-template>\n", styles: [".libs-ui-image-editor-edit-display-grid-gap-16{display:grid;gap:16px;grid-template-columns:1fr 1fr 1fr 1fr}.libs-ui-image-editor-edit-top-33{top:33.33%}.libs-ui-image-editor-edit-top-66{top:66.66%}.libs-ui-image-editor-edit-left-33{left:33.33%}.libs-ui-image-editor-edit-left-66{left:66.66%}.libs-ui-image-editor-edit-cursor-ew-resize{cursor:ew-resize!important}.libs-ui-image-editor-edit-cursor-ns-resize{cursor:ns-resize!important}.libs-ui-image-editor-edit-cursor-nwse-resize{cursor:nwse-resize!important}.libs-ui-image-editor-edit-cursor-nesw-resize{cursor:nesw-resize!important}.libs-ui-image-editor-edit-action-item{display:flex;flex-direction:column;align-items:center;width:60px;cursor:pointer}.libs-ui-image-editor-edit-action-item-icon{padding:12px;border-radius:8px;width:max-content;border:1px solid #e6e7ea}.libs-ui-image-editor-edit-action-item-icon:before{font-size:20px}.libs-ui-image-editor-edit-action-item:hover .libs-ui-image-editor-edit-action-item-icon{border:1px solid var(--mo-global-color-primary-border-hover)}.libs-ui-image-editor-edit-action-item:hover .libs-ui-image-editor-edit-action-item-icon:before{color:var(--mo-global-color-primary-text-bright-20)!important}.libs-ui-image-editor-edit-action-item[active=true] .libs-ui-image-editor-edit-action-item-icon{border:1px solid var(--mo-global-color-primary-border-active)!important;background-color:var(--mo-global-color-primary-background-95)!important}.libs-ui-image-editor-edit-action-item[active=true] .libs-ui-image-editor-edit-action-item-icon:before{color:var(--mo-global-color-primary-text-active)!important}\n"] }]
|
|
778
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
779
|
+
type: Optional
|
|
780
|
+
}, {
|
|
781
|
+
type: Inject,
|
|
782
|
+
args: [LINK_IMAGE_ERROR_TOKEN_INJECT]
|
|
783
|
+
}] }] });
|
|
784
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9pbWFnZS1lZGl0b3Ivc3JjL2ltYWdlLWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW1hZ2UtZWRpdG9yL3NyYy9pbWFnZS1lZGl0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUE0QixNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQWEsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFMLE9BQU8sRUFBRSxzQ0FBc0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3hGLE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzNFLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9FLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRS9FLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9B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SUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9OLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxD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QUFNLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVPLGlCQUFpQixDQUFDLE1BQWU7UUFDdkMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3SCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM5SCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksRUFB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QUFDLENBQUM7UUFDM0MsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBQzVDLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQztRQUN6QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQztRQUN2QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQztRQUN4QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUduRCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztZQUNoQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztZQUM5RixLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtB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by1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgQ29tcG9uZW50UmVmLCBFbGVtZW50UmVmLCBJbmplY3QsIGluamVjdCwgaW5wdXQsIG1vZGVsLCBPbkRlc3Ryb3ksIE9wdGlvbmFsLCBvdXRwdXQsIHNpZ25hbCwgdmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1idXR0b24nO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0lucHV0c1ZhbGlkQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtdmFsaWQnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c01vZGFsQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1tb2RhbCc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtcG9wb3Zlcic7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzU3Bpbm5lckNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtc3Bpbm5lcic7XG5pbXBvcnQgeyBJQm91bmRpbmdDbGllbnRSZWN0LCBJRXZlbnQgfSBmcm9tICdAbGlicy11aS9pbnRlcmZhY2VzLXR5cGVzJztcbmltcG9ydCB7IExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlIH0gZnJvbSAnQGxpYnMtdWkvc2VydmljZXMtZHluYW1pYy1jb21wb25lbnQnO1xuaW1wb3J0IHsgY29udmVydEJhc2U2NFRvQmxvYiwgZ2V0LCBpc05pbCwgTElOS19JTUFHRV9FUlJPUl9UT0tFTl9JTkpFQ1QgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWVyZ2VNYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgY3JvcFJhdGlvbkl0ZW1zLCBnZXRDcm9wUmVjdEltYWdlLCBnZXREYXRhVXJsLCBnZXRTdHlsZXNPZkVsZW1lbnQsIGdldFdpZHRoSGVpZ2h0UmVzaXplQ3JvcEZvbGxvdyB9IGZyb20gJy4vZGVmaW5lcy9pbWFnZS1lZGl0b3IuZGVmaW5lJztcbmltcG9ydCB7IElJbWFnZUVkaXRvckZ1bmN0aW9uQ29udHJvbEV2ZW50IH0gZnJvbSAnLi9pbnRlcmZhY2VzL2Z1bmN0aW9uLWNvbnRyb2wtZXZlbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IElBc3BlY3RSYXRpbywgSUNyb3BSYXRpb0l0ZW0sIElDcm9wU2l6ZSwgSVNhdmVGaWxlLCBJUmVjdENsaXAsIElSZXNpemVEYXRhLCBJU3RhcnRNb3VzZURpbSwgSVN0eWxlcywgTU9ERV9FRElULCBUWVBFX1JFU0laRV9TVEFURSwgVFlQRV9NT0RFX1NBVkUgfSBmcm9tICcuL2ludGVyZmFjZXMvaW1hZ2UtZWRpdG9yLmludGVyZmFjZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzSW1hZ2VFZGl0b3JSZXNpemVDb21wb25lbnQgfSBmcm9tICcuL3Jlc2l6ZS9yZXNpemUuY29tcG9uZW50JztcbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2xpYnNfdWktY29tcG9uZW50cy1pbWFnZV9lZGl0b3InLFxuICB0ZW1wbGF0ZVVybDogJy4vaW1hZ2UtZWRpdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vaW1hZ2UtZWRpdG9yLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgTmdUZW1wbGF0ZU91dGxldCwgVHJhbnNsYXRlTW9kdWxlLCBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCwgTGlic1VpQ29tcG9uZW50c01vZGFsQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNWYWxpZENvbXBvbmVudCwgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNCdXR0b25Db21wb25lbnQsIExpYnNVaUNvbXBvbmVudHNTcGlubmVyQ29tcG9uZW50LFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaUNvbXBvbmVudHNJbWFnZUVkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBsb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJvdGVjdGVkIGxvYWRpbmdJbWFnZSA9IHNpZ25hbCh0cnVlKTtcbiAgcHJvdGVjdGVkIGNoYW5nZWQgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgb3JpZ2luV2lkdGggPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJvdGVjdGVkIG9yaWdpbkhlaWdodCA9IHNpZ25hbDxudW1iZXI+KDApO1xuICBwcm90ZWN0ZWQgY3JvcFJhdGlvSXRlbXMgPSBzaWduYWw8QXJyYXk8SUNyb3BSYXRpb0l0ZW0+Pihjcm9wUmF0aW9uSXRlbXMoKSk7XG4gIHByb3RlY3RlZCBjcm9wUmF0aW9JdGVtU2VsZWN0ZWQgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHByb3RlY3RlZCBjcm9wU2l6ZSA9IHNpZ25hbDxJQ3JvcFNpemU+KHsgd2lkdGg6IDIwLCBoZWlnaHQ6IDIwIH0pO1xuICBwcm90ZWN0ZWQgcmVzaXplRGF0YSA9IHNpZ25hbDxJUmVzaXplRGF0YT4oeyByYXRpbzogMTAwLCB3aWR0aDogNjAwLCBoZWlnaHQ6IDgwMCB9KTtcbiAgcHJvdGVjdGVkIGRyYWdHcmlkQ3JvcCA9IHNpZ25hbChmYWxzZSk7XG5cbiAgcHJpdmF0ZSBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICBwcml2YXRlIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBwcml2YXRlIGNvbnRhaW5lckhlaWdodCA9IHNpZ25hbCg4MDApO1xuICBwcml2YXRlIGNvbnRhaW5lcldpZHRoID0gc2lnbmFsKDEyMDApO1xuICBwcml2YXRlIGltZ0NvbnRhaW5lclJlY3QgPSBzaWduYWw8SUJvdW5kaW5nQ2xpZW50UmVjdD4oeyB0b3A6IDAsIGxlZnQ6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSk7XG4gIHByaXZhdGUgcmVjdENsaXAgPSBzaWduYWw8SVJlY3RDbGlwPih7IHRvcDogMCwgbGVmdDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCB9KTtcbiAgcHJpdmF0ZSByZXNpemVTdGF0ZSA9IHNpZ25hbDxUWVBFX1JFU0laRV9TVEFURT4oJ25vbmUnKTtcbiAgcHJpdmF0ZSBtb3ZlU3RhdGUgPSBzaWduYWw8J2NsaXAnIHwgJ2ltYWdlJyB8ICdub25lJz4oJ25vbmUnKTtcbiAgcHJpdmF0ZSBzdGFydE1vdXNlRGltID0gc2lnbmFsPElTdGFydE1vdXNlRGltPih7IGNsaWVudFg6IDAsIGNsaWVudFk6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDAsIHRvcDogMCwgbGVmdDogMCwgaW1hZ2VUb3A6IDAsIGltYWdlTGVmdDogMCwgaW1hZ2VXaWR0aDogMCwgaW1hZ2VIZWlnaHQ6IDAgfSk7XG4gIHByaXZhdGUgZGF0YVVybE9yaWdpbiA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcHJpdmF0ZSByYXRpb1ZhbHVlID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWluSGVpZ2h0ID0gMjA7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWluV2lkdGggPSAyMDtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlc2l6ZUNvbXBvbmVudFJlZj86IENvbXBvbmVudFJlZjxMaWJzVWlDb21wb25lbnRzSW1hZ2VFZGl0b3JSZXNpemVDb21wb25lbnQ+O1xuXG5cbiAgcmVhZG9ubHkgbW9kZVNob3dCdXR0b24gPSBpbnB1dDxNT0RFX0VESVQ+KCdzYXZlLWZpbGUnKTtcbiAgcmVhZG9ubHkgbWltZXR5cGUgPSBpbnB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IHpJbmRleCA9IGlucHV0PG51bWJlcj4oMTIwMCk7XG4gIHJlYWRvbmx5IGltZ1NyYyA9IG1vZGVsLnJlcXVpcmVkPHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgb3JpZ2luVXJsID0gaW5wdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBuYW1lRmlsZSA9IGlucHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgaGFzWm9vbSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgYXNwZWN0UmF0aW8gPSBtb2RlbDxJQXNwZWN0UmF0aW8+KCk7XG4gIHJlYWRvbmx5IHJlcXVpcmVkQ3JvcEZvbGxvd1JhdGlvID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIHJlYWRvbmx5IGltYWdlT3JpZ2luID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdpbWFnZU9yaWdpbicpO1xuICByZWFkb25seSBpbWFnZUNsaXAgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2ltYWdlQ2xpcCcpO1xuICByZWFkb25seSBpbWFnZUVkaXRvckNvbnRhaW5lciA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPignaW1hZ2VFZGl0b3JDb250YWluZXInKTtcbiAgcmVhZG9ubHkgaW1hZ2VDb250YWluZXIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2ltYWdlQ29udGFpbmVyJyk7XG4gIHJlYWRvbmx5IGNyb3BBcmVhID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdjcm9wQXJlYScpO1xuICByZWFkb25seSBjcm9wVEwgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2Nyb3BUTCcpO1xuICByZWFkb25seSBjcm9wQkwgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2Nyb3BCTCcpO1xuICByZWFkb25seSBjcm9wQlIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2Nyb3BCUicpO1xuICByZWFkb25seSBjcm9wVFIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2Nyb3BUUicpO1xuICByZWFkb25seSBjcm9wTGluZVZMID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdjcm9wTGluZVZMJyk7XG4gIHJlYWRvbmx5IGNyb3BMaW5lVlIgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2Nyb3BMaW5lVlInKTtcbiAgcmVhZG9ubHkgY3JvcExpbmVIVCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPignY3JvcExpbmVIVCcpO1xuICByZWFkb25seSBjcm9wTGluZUhCID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdjcm9wTGluZUhCJyk7XG4gIHJlYWRvbmx5IGNpcmNsZVRMID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdjaXJjbGVUTCcpO1xuICByZWFkb25seSBjaXJjbGVUUiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPignY2lyY2xlVFInKTtcbiAgcmVhZG9ubHkgY2lyY2xlQkwgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2NpcmNsZUJMJyk7XG4gIHJlYWRvbmx5IGNpcmNsZUJSID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY+KCdjaXJjbGVCUicpO1xuXG4gIHJlYWRvbmx5IG91dENsb3NlID0gb3V0cHV0PHsgaXNDbGlja0J1dHRvbkNsb3NlOiBib29sZWFuIH0+KCk7XG4gIHJlYWRvbmx5IG91dFNhdmVGaWxlID0gb3V0cHV0PElTYXZlRmlsZT4oKTtcbiAgcmVhZG9ubHkgb3V0RnVuY3Rpb25zQ29udHJvbCA9IG91dHB1dDxJSW1hZ2VFZGl0b3JGdW5jdGlvbkNvbnRyb2xFdmVudD4oKTtcblxuICBwcml2YXRlIGR5bmFtaWNDb21wb25lbnRTZXJ2aWNlID0gaW5qZWN0KExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlKTtcblxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KExJTktfSU1BR0VfRVJST1JfVE9LRU5fSU5KRUNUKSBwcml2YXRlIGxpbmtJbWFnZUVycm9yOiBzdHJpbmcpIHtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5hc3BlY3RSYXRpbygpKSB7XG4gICAgICB0aGlzLmRyYWdHcmlkQ3JvcC5zZXQodHJ1ZSk7XG4gICAgICBjb25zdCBhc3BlY3RSYXRpb0ZvdW5kID0gdGhpcy5jcm9wUmF0aW9JdGVtcygpLmZpbmQoaXRlbSA9PiBpdGVtLmtleSA9PT0gdGhpcy5hc3BlY3RSYXRpbygpPy5rZXkpO1xuXG4gICAgICB0aGlzLmNyb3BSYXRpb0l0ZW1TZWxlY3RlZC5zZXQoYXNwZWN0UmF0aW9Gb3VuZD8ua2V5IHx8IHRoaXMuY3JvcFJhdGlvSXRlbXMoKVswXS5rZXkpO1xuICAgICAgdGhpcy51cGRhdGVPcmlnaW5JbWFnZVNpemUoKTtcbiAgICAgIHRoaXMuY2hhbmdlZEltYWdlKHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlTW9kYWxTaXplKCk7XG4gICAgdGhpcy5pbml0RGF0YSgpO1xuICAgIHRoaXMuaW5pdE1vdXNlRXZlbnQoKTtcbiAgICB0aGlzLm91dEZ1bmN0aW9uc0NvbnRyb2wuZW1pdCh7XG4gICAgICBjcm9wSW1hZ2U6IHRoaXMuY3JvcEltYWdlLmJpbmQodGhpcyksXG4gICAgICBzZXRMb2FkaW5nU3RhdGU6IChsb2FkaW5nOiBib29sZWFuKSA9PiB0aGlzLmxvYWRpbmcuc2V0KGxvYWRpbmcpXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckltYWdlTG9hZGVkKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVNb2RhbFNpemUoKTtcbiAgICAgIHRoaXMubG9hZGluZ0ltYWdlLnNldChmYWxzZSk7XG4gICAgfSwgNTAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVySW1hZ2VFcnJvcihlOiBFcnJvckV2ZW50KSB7XG4gICAgY29uc29sZS5sb2coJ2UnLCBlKTtcbiAgICAoZSBhcyBJRXZlbnQpLnRhcmdldC5zcmMgPSB0aGlzLmxpbmtJbWFnZUVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVNb2RhbFNpemUoKSB7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0IC0gMTAwO1xuICAgIGNvbnN0IG1heFdpZHRoID0gd2luZG93LmlubmVyV2lkdGggLSA0MDA7XG5cbiAgICB0aGlzLmNvbnRhaW5lckhlaWdodC5zZXQobWF4SGVpZ2h0IC0gMTI0KTtcbiAgICB0aGlzLmNvbnRhaW5lcldpZHRoLnNldChtYXhXaWR0aCAtIDM4NCk7XG4gICAgdGhpcy51cGRhdGVPcmlnaW5JbWFnZVNpemUoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdERhdGEoKSB7XG4gICAgdGhpcy5pbWdDb250YWluZXJSZWN0LnNldCh0aGlzLmltYWdlQ29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG4gICAgdGhpcy5pbWFnZS5zZXRBdHRyaWJ1dGUoJ2Nyb3Nzb3JpZ2luJywgJ2Fub255bW91cycpO1xuICAgIHRoaXMuaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgdGhpcy5pbWdDb250YWluZXJSZWN0LnNldCh0aGlzLmltYWdlQ29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG4gICAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSB0aGlzLmltYWdlLmhlaWdodDtcbiAgICAgIHRoaXMuY2FudmFzLndpZHRoID0gdGhpcy5pbWFnZS53aWR0aDtcbiAgICAgIHRoaXMub3JpZ2luSGVpZ2h0LnNldCh0aGlzLmltYWdlLmhlaWdodCk7XG4gICAgICB0aGlzLm9yaWdpbldpZHRoLnNldCh0aGlzLmltYWdlLndpZHRoKTtcblxuICAgICAgdGhpcy51cGRhdGVPcmlnaW5JbWFnZVNpemUoKTtcbiAgICAgIHRoaXMuY2FudmFzLmdldENvbnRleHQoJzJkJyk/LmRyYXdJbWFnZSh0aGlzLmltYWdlLCAwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcbiAgICAgIHRoaXMuZGF0YVVybE9yaWdpbi5zZXQoZ2V0RGF0YVVybCh0aGlzLmNhbnZhcywgdGhpcy5taW1ldHlwZSgpLCB0aGlzLmltYWdlLnNyYykpO1xuICAgICAgdGhpcy5pbWdTcmMuc2V0KHRoaXMuZGF0YVVybE9yaWdpbigpKTtcbiAgICB9O1xuICAgIHRoaXMuaW1hZ2Uuc3JjID0gdGhpcy5pbWdTcmMoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdE1vdXNlRXZlbnQoKSB7XG4gICAgY29uc3QgbW91c2VVcCA9IHRoaXMuaW5pdEV2ZW50KHsgbmF0aXZlRWxlbWVudDogZG9jdW1lbnQgfSwgJ21vdXNldXAnLCB7IGNhbGxTdG9wUHJvcGFnYXRpb246IHRydWUsIGNhbGxQcmV2ZW50RGVmYXVsdDogdHJ1ZSB9LCB1bmRlZmluZWQsICgpID0+IHRoaXMuaGFuZGxlck1vdXNldXAoKSk7XG4gICAgY29uc3QgbW91c2VNb3ZlID0gdGhpcy5pbml0RXZlbnQoeyBuYXRpdmVFbGVtZW50OiBkb2N1bWVudCB9LCAnbW91c2Vtb3ZlJywgeyBjYWxsU3RvcFByb3BhZ2F0aW9uOiB0cnVlLCBjYWxsUHJldmVudERlZmF1bHQ6IHRydWUgfSkucGlwZSh0YWtlVW50aWwobW91c2VVcCkpO1xuXG4gICAgdGhpcy5pbml0RXZlbnQoeyBuYXRpdmVFbGVtZW50OiBkb2N1bWVudCB9LCAnd2hlZWwnLCB7IGNhbGxTdG9wUHJvcGFnYXRpb246IHRydWUgfSwgdW5kZWZpbmVkLCAoZTogRXZlbnQpID0+IHRoaXMuaGFuZGxlck1vdXNld2hlZWwoZSkpLnN1YnNjcmliZSgpO1xuICAgIHRoaXMuaW5pdEV2ZW50KHsgbmF0aXZlRWxlbWVudDogd2luZG93IH0sICdyZXNpemUnLCB7fSwgdW5kZWZpbmVkLCAoKSA9PiB0aGlzLnVwZGF0ZU1vZGFsU2l6ZSgpKS5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmltYWdlQ29udGFpbmVyKCksICdtb3VzZWRvd24nLCB7IGNhbGxTdG9wUHJvcGFnYXRpb246IHRydWUsIGNhbGxQcmV2ZW50RGVmYXVsdDogdHJ1ZSB9LCBtb3VzZU1vdmUsIChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVySW1hZ2VDb250YWluZXJNb3VzZWRvd24oZSkpLnN1YnNjcmliZSgoZTogRXZlbnQpID0+IHRoaXMuaGFuZGxlck1vdXNlbW92ZShlKSk7XG4gICAgdGhpcy5pbml0RXZlbnQodGhpcy5jcm9wVEwoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ1RMJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BCTCgpLCAnbW91c2Vkb3duJywgeyBjYWxsU3RvcFByb3BhZ2F0aW9uOiB0cnVlLCBjYWxsUHJldmVudERlZmF1bHQ6IHRydWUgfSwgbW91c2VNb3ZlLCAoZTogRXZlbnQpID0+IHsgdGhpcy5oYW5kbGVyQ3JvcFJlc2l6ZShlLCAnQkwnKSB9KS5zdWJzY3JpYmUoKGU6IEV2ZW50KSA9PiB0aGlzLmhhbmRsZXJNb3VzZW1vdmUoZSkpO1xuICAgIHRoaXMuaW5pdEV2ZW50KHRoaXMuY3JvcEJSKCksICdtb3VzZWRvd24nLCB7IGNhbGxTdG9wUHJvcGFnYXRpb246IHRydWUsIGNhbGxQcmV2ZW50RGVmYXVsdDogdHJ1ZSB9LCBtb3VzZU1vdmUsIChlOiBFdmVudCkgPT4geyB0aGlzLmhhbmRsZXJDcm9wUmVzaXplKGUsICdCUicpIH0pLnN1YnNjcmliZSgoZTogRXZlbnQpID0+IHRoaXMuaGFuZGxlck1vdXNlbW92ZShlKSk7XG4gICAgdGhpcy5pbml0RXZlbnQodGhpcy5jcm9wVFIoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ1RSJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BMaW5lVkwoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ1ZMJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BMaW5lVlIoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ1ZSJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BMaW5lSFQoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ0hUJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BMaW5lSEIoKSwgJ21vdXNlZG93bicsIHsgY2FsbFN0b3BQcm9wYWdhdGlvbjogdHJ1ZSwgY2FsbFByZXZlbnREZWZhdWx0OiB0cnVlIH0sIG1vdXNlTW92ZSwgKGU6IEV2ZW50KSA9PiB7IHRoaXMuaGFuZGxlckNyb3BSZXNpemUoZSwgJ0hCJykgfSkuc3Vic2NyaWJlKChlOiBFdmVudCkgPT4gdGhpcy5oYW5kbGVyTW91c2Vtb3ZlKGUpKTtcbiAgICB0aGlzLmluaXRFdmVudCh0aGlzLmNyb3BBcmVhKCksICdtb3VzZWRvd24nLCB7fSwgdW5kZWZpbmVkLCAoZTogRXZlbnQpID0+IHRoaXMuaGFuZGxlck1vdXNlZG93bkNyb3BBcmVhKGUpKS5zdWJzY3JpYmUoKGU6IEV2ZW50KSA9PiB0aGlzLmhhbmRsZXJNb3VzZW1vdmUoZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0RXZlbnQoZWxlbWVudDogRWxlbWVudFJlZiwgZXZlbnROYW1lOiBzdHJpbmcsIGZsYWc6IHsgY2FsbFN0b3BQcm9wYWdhdGlvbj86IGJvb2xlYW4sIGNhbGxQcmV2ZW50RGVmYXVsdD86IGJvb2xlYW4gfSwgb2JzTWVyZ2U/OiBPYnNlcnZhYmxlPEV2ZW50PiwgY2FsbGJhY2s/OiAoZTogRXZlbnQpID0+IHZvaWQpOiBPYnNlcnZhYmxlPEV2ZW50PiB7XG4gICAgY29uc3Qgb2JzID0gZnJvbUV2ZW50PEV2ZW50PihlbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIGV2ZW50TmFtZSkucGlwZShcbiAgICAgIHRhcCgoZTogRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGZsYWcuY2FsbFN0b3BQcm9wYWdhdGlvbiAmJiBlPy5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFnLmNhbGxQcmV2ZW50RGVmYXVsdCAmJiBlPy5wcmV2ZW50RGVmYXVsdCkge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICBjYWxsYmFjayhlKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpKTtcblxuICAgIGlmIChvYnNNZXJnZSkge1xuICAgICAgcmV0dXJuIG9icy5waXBlKG1lcmdlTWFwKCgpID0+IG9ic01lcmdlKSwgKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JzO1xuICB9O1xuXG4gIHByaXZhdGUgdXBkYXRlT3JpZ2luSW1hZ2VTaXplKCkge1xuICAgIGxldCB3aWR0aCA9IHRoaXMub3JpZ2luV2lkdGgoKTtcbiAgICBsZXQgaGVpZ2h0ID0gdGhpcy5vcmlnaW5IZWlnaHQoKTtcbiAgICBjb25zdCByYXRpbyA9IHdpZHRoIC8gaGVpZ2h0O1xuXG4gICAgaWYgKHdpZHRoID49IGhlaWdodCkge1xuICAgICAgd2lkdGggPSBNYXRoLm1pbih0aGlzLmNvbnRhaW5lcldpZHRoKCksIHdpZHRoKTtcbiAgICAgIGhlaWdodCA9IE1hdGgubWluKHdpZHRoIC8gcmF0aW8sIHRoaXMuY29udGFpbmVySGVpZ2h0KCkpO1xuICAgICAgd2lkdGggPSBoZWlnaHQgKiByYXRpbztcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gTWF0aC5taW4odGhpcy5jb250YWluZXJIZWlnaHQoKSwgaGVpZ2h0KTtcbiAgICAgIHdpZHRoID0gaGVpZ2h0ICogcmF0aW87XG4gICAgfVxuICAgIHRoaXMuc2V0SW1hZ2VQb3NpdGlvbih3aWR0aCwgaGVpZ2h0KTtcbiAgICB0aGlzLnVwZGF0ZUNyb3BBcmVhUG9zKCk7XG4gICAgdGhpcy51cGRhdGVSZWN0Q2xpcFBvcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRJbWFnZVBvc2l0aW9uKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgY29uc3QgbGVmdCA9IHRoaXMuY29udGFpbmVyV2lkdGgoKSAvIDIgLSB3aWR0aCAvIDI7XG4gICAgY29uc3QgdG9wID0gdGhpcy5jb250YWluZXJIZWlnaHQoKSAvIDIgLSBoZWlnaHQgLyAyO1xuICAgIGNvbnN0IHN0eWxlcyA9IHsgd2lkdGgsIGhlaWdodCwgdG9wLCBsZWZ0LCBkaXNwbGF5OiAnYmxvY2snIH07XG5cbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VPcmlnaW4oKSwgc3R5bGVzKTtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VDbGlwKCksIHN0eWxlcyk7XG4gICAgdGhpcy5zZXRDaXJjbGVQb3NpdGlvbihzdHlsZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRDaXJjbGVQb3NpdGlvbihzdHlsZXM6IElTdHlsZXMpIHtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuY2lyY2xlVEwoKSwgeyB0b3A6IChzdHlsZXMudG9wIHx8IDApIC0gNSwgbGVmdDogKHN0eWxlcy5sZWZ0IHx8IDApIC0gNSB9KTtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuY2lyY2xlVFIoKSwgeyB0b3A6IChzdHlsZXMudG9wIHx8IDApIC0gNSwgbGVmdDogKHN0eWxlcy5sZWZ0IHx8IDApICsgKHN0eWxlcy53aWR0aCB8fCAwKSAtIDEwIH0pO1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jaXJjbGVCTCgpLCB7IHRvcDogKHN0eWxlcy50b3AgfHwgMCkgKyAoc3R5bGVzLmhlaWdodCB8fCAwKSAtIDEwLCBsZWZ0OiAoc3R5bGVzLmxlZnQgfHwgMCkgLSA1IH0pO1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jaXJjbGVCUigpLCB7IHRvcDogKHN0eWxlcy50b3AgfHwgMCkgKyAoc3R5bGVzLmhlaWdodCB8fCAwKSAtIDEwLCBsZWZ0OiAoc3R5bGVzLmxlZnQgfHwgMCkgKyAoc3R5bGVzLndpZHRoIHx8IDApIC0gMTAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUNyb3BBcmVhUG9zKCkge1xuICAgIGNvbnN0IFtpbWdUb3AsIGltZ0xlZnQsIGltZ1dpZHRoLCBpbWdIZWlnaHRdID0gZ2V0U3R5bGVzT2ZFbGVtZW50PG51bWJlcj4odGhpcy5pbWFnZUNsaXAoKS5uYXRpdmVFbGVtZW50LCBbJ3N0eWxlLnRvcCcsICdzdHlsZS5sZWZ0JywgJ29mZnNldFdpZHRoJywgJ29mZnNldEhlaWdodCddKTtcblxuICAgIGNvbnN0IHJlY3RJbWc6IElCb3VuZGluZ0NsaWVudFJlY3QgPSB7XG4gICAgICB0b3A6IE1hdGgubWF4KDAsIGltZ1RvcCksXG4gICAgICBsZWZ0OiBNYXRoLm1heCgwLCBpbWdMZWZ0KSxcbiAgICAgIHdpZHRoOiBpbWdXaWR0aCxcbiAgICAgIGhlaWdodDogaW1nSGVpZ2h0XG4gICAgfTtcblxuICAgIHJlY3RJbWcud2lkdGggPSBNYXRoLm1pbihpbWdXaWR0aCwgdGhpcy5jb250YWluZXJXaWR0aCgpIC0gaW1nTGVmdCk7XG4gICAgaWYgKGltZ0xlZnQgPCAwKSB7XG4gICAgICByZWN0SW1nLndpZHRoID0gTWF0aC5taW4oaW1nV2lkdGggKyBpbWdMZWZ0LCB0aGlzLmNvbnRhaW5lcldpZHRoKCkpO1xuICAgIH1cbiAgICByZWN0SW1nLmhlaWdodCA9IE1hdGgubWluKGltZ0hlaWdodCwgdGhpcy5jb250YWluZXJIZWlnaHQoKSAtIGltZ1RvcCk7XG4gICAgaWYgKGltZ1RvcCA8IDApIHtcbiAgICAgIHJlY3RJbWcuaGVpZ2h0ID0gTWF0aC5taW4oaW1nVG9wICsgaW1nSGVpZ2h0LCB0aGlzLmNvbnRhaW5lckhlaWdodCgpKTtcbiAgICB9XG4gICAgdGhpcy5yYXRpb1ZhbHVlLnNldCh0aGlzLmdldENyb3BSYXRpb1ZhbHVlKCkpO1xuICAgIGlmICghdGhpcy5yYXRpb1ZhbHVlKCkpIHtcbiAgICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCByZWN0SW1nKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgd2lkdGggPSByZWN0SW1nLndpZHRoO1xuICAgIGxldCBoZWlnaHQgPSB3aWR0aCAvIHRoaXMucmF0aW9WYWx1ZSgpO1xuXG4gICAgd2lkdGggPSBNYXRoLm1pbihyZWN0SW1nLndpZHRoLCB3aWR0aCk7XG4gICAgaGVpZ2h0ID0gd2lkdGggLyB0aGlzLnJhdGlvVmFsdWUoKTtcbiAgICBoZWlnaHQgPSBNYXRoLm1pbihyZWN0SW1nLmhlaWdodCwgaGVpZ2h0KTtcbiAgICB3aWR0aCA9IGhlaWdodCAqIHRoaXMucmF0aW9WYWx1ZSgpO1xuICAgIGNvbnN0IHRvcCA9IHJlY3RJbWcudG9wICsgKHJlY3RJbWcuaGVpZ2h0IC0gaGVpZ2h0KSAvIDI7XG4gICAgY29uc3QgbGVmdCA9IHJlY3RJbWcubGVmdCArIChyZWN0SW1nLndpZHRoIC0gd2lkdGgpIC8gMjtcblxuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IHdpZHRoLCBoZWlnaHQsIHRvcCwgbGVmdCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q3JvcFJhdGlvVmFsdWUoKSB7XG4gICAgY29uc3QgY3JvcFJhdGlvID0gdGhpcy5hc3BlY3RSYXRpbygpIHx8IHRoaXMuY3JvcFJhdGlvSXRlbXMoKS5maW5kKGl0ZW0gPT4gaXRlbS5rZXkgPT09IHRoaXMuY3JvcFJhdGlvSXRlbVNlbGVjdGVkKCkpO1xuXG4gICAgaWYgKCFjcm9wUmF0aW8pIHtcbiAgICAgIHJldHVybiB0aGlzLm9yaWdpbldpZHRoKCkgLyB0aGlzLm9yaWdpbkhlaWdodCgpO1xuICAgIH1cblxuICAgIHJldHVybiBjcm9wUmF0aW8udmFsdWUgPz8gMDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUmVjdENsaXBQb3MoKSB7XG4gICAgY29uc3QgcmVhY3RDbGlwID0gdGhpcy5nZXRSZWN0Q2xpcEltYWdlKCk7XG5cbiAgICB0aGlzLmltYWdlQ2xpcCgpLm5hdGl2ZUVsZW1lbnQuc3R5bGUuY2xpcCA9IGByZWN0KCR7cmVhY3RDbGlwLnRvcH1weCwgJHtyZWFjdENsaXAucmlnaHR9cHgsICR7cmVhY3RDbGlwLmJvdHRvbX1weCwgJHtyZWFjdENsaXAubGVmdH1weClgO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRSZWN0Q2xpcEltYWdlKCkge1xuXG4gICAgY29uc3QgaW1hZ2VSZWN0ID0gdGhpcy5pbWFnZUNsaXAoKS5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmICghaW1hZ2VSZWN0LndpZHRoKSB7XG5cbiAgICAgIHJldHVybiB0aGlzLnJlY3RDbGlwKCk7XG4gICAgfVxuICAgIGNvbnN0IGNyb3BSZWN0ID0gdGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3Qgd2lkdGggPSBNYXRoLnJvdW5kKGNyb3BSZWN0LndpZHRoKTtcbiAgICBjb25zdCBoZWlnaHQgPSBNYXRoLnJvdW5kKGNyb3BSZWN0LmhlaWdodCk7XG4gICAgY29uc3QgbGVmdCA9IGNyb3BSZWN0LmxlZnQgLSBpbWFnZVJlY3QubGVmdDtcbiAgICBjb25zdCB0b3AgPSBjcm9wUmVjdC50b3AgLSBpbWFnZVJlY3QudG9wO1xuICAgIGNvbnN0IHJpZ2h0ID0gTWF0aC5yb3VuZChsZWZ0ICsgd2lkdGgpO1xuICAgIGNvbnN0IGJvdHRvbSA9IE1hdGgucm91bmQodG9wICsgaGVpZ2h0KTtcbiAgICBjb25zdCByYXRpbyA9IHRoaXMub3JpZ2luV2lkdGgoKSAvIGltYWdlUmVjdC53aWR0aDtcblxuXG4gICAgdGhpcy5yZWN0Q2xpcC5zZXQoeyBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20sIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgdGhpcy5jcm9wU2l6ZS5zZXQoe1xuICAgICAgaGVpZ2h0OiB0b3AgPj0gMCA/IChNYXRoLnJvdW5kKChib3R0b20gLSB0b3ApICogcmF0aW8pKSA6IChNYXRoLmZsb29yKChib3R0b20gLSB0b3ApICogcmF0aW8pKSxcbiAgICAgIHdpZHRoOiB0b3AgPj0gMCA/IChNYXRoLnJvdW5kKCgocmlnaHQgLSBsZWZ0KSAqICh0aGlzLnJhdGlvVmFsdWUoKSA/PyAxKSkgKiByYXRpbykpIDogKE1hdGguZmxvb3IoKChyaWdodCAtIGxlZnQpICogKHRoaXMucmF0aW9WYWx1ZSgpID8/IDEpKSAqIHJhdGlvKSlcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLnJlY3RDbGlwKCk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJNb3VzZW1vdmUoZTogYW55KSB7XG4gICAgY29uc3QgdHlwZVN0YXRlID0gWydCTCcsICdUTCcsICdUUicsICdCUicsICdWTCcsICdWUicsICdIVCcsICdIQiddO1xuICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBgcmVzaXplQ3JvcEZvbGxvdyR7dGhpcy5yZXNpemVTdGF0ZSgpfURpcmA7IC8vIHJlc2l6ZUNyb3BGb2xsb3dCTERpciwgcmVzaXplQ3JvcEZvbGxvd1RMRGlyLCByZXNpemVDcm9wRm9sbG93VFJEaXIsIHJlc2l6ZUNyb3BGb2xsb3dCUkRpciwgcmVzaXplQ3JvcEZvbGxvd1ZMRGlyLCByZXNpemVDcm9wRm9sbG93VlJEaXIsIHJlc2l6ZUNyb3BGb2xsb3dIVERpciwgcmVzaXplQ3JvcEZvbGxvd0hCRGlyXG5cbiAgICBpZiAodHlwZVN0YXRlLmluY2x1ZGVzKHRoaXMucmVzaXplU3RhdGUoKSkpIHtcbiAgICAgICh0aGlzIGFzIGFueSlbbWV0aG9kTmFtZV0oZSk7XG4gICAgfVxuICAgIHN3aXRjaCAodGhpcy5tb3ZlU3RhdGUoKSkge1xuICAgICAgY2FzZSAnY2xpcCc6XG4gICAgICAgIHRoaXMubW92ZUNsaXBBcmVhKGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaW1hZ2UnOlxuICAgICAgICB0aGlzLm1vdmVJbWFnZShlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuY2hhbmdlZEltYWdlKHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlc2l6ZUNyb3BGb2xsb3dCTERpciA9IChlOiBJRXZlbnQpID0+IHtcbiAgICBjb25zdCBtb21lbnRZID0gZS5jbGllbnRZIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WTtcbiAgICBjb25zdCBtb21lbnRYID0gdGhpcy5yYXRpb1ZhbHVlKCkgPyAtbW9tZW50WSAqIHRoaXMucmF0aW9WYWx1ZSgpIDogZS5jbGllbnRYIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZVRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlSGVpZ2h0IC0gdGhpcy5zdGFydE1vdXNlRGltKCkudG9wO1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5zdGFydE1vdXNlRGltKCkubGVmdCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLndpZHRoIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0O1xuICAgIGxldCB7IHdpZHRoLCBoZWlnaHQsIGxlZnQgfSA9IHRoaXMuZ2V0UmVjdFJlc2l6ZUNyb3BGb2xsb3coeyB3aWR0aDogLTEsIGhlaWdodDogMSwgbGVmdDogMSwgdG9wOiAwIH0sIG1vbWVudFgsIG1vbWVudFkpO1xuXG4gICAgW3dpZHRoLCBoZWlnaHRdID0gZ2V0V2lkdGhIZWlnaHRSZXNpemVDcm9wRm9sbG93KHRoaXMucmF0aW9WYWx1ZSgpLCB3aWR0aCwgaGVpZ2h0LCBtYXhXaWR0aCwgbWF4SGVpZ2h0LCB0aGlzLm1pbldpZHRoLCB0aGlzLm1pbkhlaWdodCk7XG4gICAgbGVmdCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQgKyB0aGlzLnN0YXJ0TW91c2VEaW0oKS53aWR0aCAtIHdpZHRoO1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IGxlZnQsIGhlaWdodCwgd2lkdGggfSwgdHJ1ZSk7XG4gIH07XG5cbiAgcHJvdGVjdGVkIHJlc2l6ZUNyb3BGb2xsb3dUTERpciA9IChlOiBJRXZlbnQpID0+IHtcbiAgICBjb25zdCBtb21lbnRZID0gZS5jbGllbnRZIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WTtcbiAgICBjb25zdCBtb21lbnRYID0gdGhpcy5yYXRpb1ZhbHVlKCkgPyB0aGlzLnJhdGlvVmFsdWUoKSAqIG1vbWVudFkgOiBlLmNsaWVudFggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRYO1xuICAgIGNvbnN0IG1heEhlaWdodCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmhlaWdodCAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlVG9wO1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5zdGFydE1vdXNlRGltKCkubGVmdCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLndpZHRoIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0O1xuICAgIGxldCB7IHdpZHRoLCBoZWlnaHQsIHRvcCwgbGVmdCB9ID0gdGhpcy5nZXRSZWN0UmVzaXplQ3JvcEZvbGxvdyh7IHdpZHRoOiAtMSwgaGVpZ2h0OiAtMSwgbGVmdDogMSwgdG9wOiAxIH0sIG1vbWVudFgsIG1vbWVudFkpO1xuXG4gICAgW3dpZHRoLCBoZWlnaHRdID0gZ2V0V2lkdGhIZWlnaHRSZXNpemVDcm9wRm9sbG93KHRoaXMucmF0aW9WYWx1ZSgpLCB3aWR0aCwgaGVpZ2h0LCBtYXhXaWR0aCwgbWF4SGVpZ2h0LCB0aGlzLm1pbldpZHRoLCB0aGlzLm1pbkhlaWdodCk7XG4gICAgbGVmdCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQgKyB0aGlzLnN0YXJ0TW91c2VEaW0oKS53aWR0aCAtIHdpZHRoO1xuICAgIHRvcCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmhlaWdodCAtIGhlaWdodDtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuY3JvcEFyZWEoKSwgeyB0b3AsIGxlZnQsIGhlaWdodCwgd2lkdGggfSwgdHJ1ZSk7XG4gIH07XG5cbiAgcHJvdGVjdGVkIHJlc2l6ZUNyb3BGb2xsb3dUUkRpciA9IChlOiBJRXZlbnQpID0+IHtcbiAgICBjb25zdCBtb21lbnRZID0gZS5jbGllbnRZIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WTtcbiAgICBjb25zdCBtb21lbnRYID0gdGhpcy5yYXRpb1ZhbHVlKCkgPyAtbW9tZW50WSAqIHRoaXMucmF0aW9WYWx1ZSgpIDogZS5jbGllbnRYIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS50b3AgKyB0aGlzLnN0YXJ0TW91c2VEaW0oKS5oZWlnaHQgLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZVRvcDtcbiAgICBjb25zdCBtYXhXaWR0aCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlTGVmdCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlV2lkdGggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5sZWZ0O1xuICAgIGxldCB7IHdpZHRoLCBoZWlnaHQsIHRvcCB9ID0gdGhpcy5nZXRSZWN0UmVzaXplQ3JvcEZvbGxvdyh7IHdpZHRoOiAxLCBoZWlnaHQ6IC0xLCBsZWZ0OiAwLCB0b3A6IDEgfSwgbW9tZW50WCwgbW9tZW50WSk7XG5cbiAgICBbd2lkdGgsIGhlaWdodF0gPSBnZXRXaWR0aEhlaWdodFJlc2l6ZUNyb3BGb2xsb3codGhpcy5yYXRpb1ZhbHVlKCksIHdpZHRoLCBoZWlnaHQsIG1heFdpZHRoLCBtYXhIZWlnaHQsIHRoaXMubWluV2lkdGgsIHRoaXMubWluSGVpZ2h0KTtcbiAgICB0b3AgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS50b3AgKyB0aGlzLnN0YXJ0TW91c2VEaW0oKS5oZWlnaHQgLSBoZWlnaHQ7XG4gICAgdGhpcy5zZXRTdHlsZXNFbGVtZW50cyh0aGlzLmNyb3BBcmVhKCksIHsgdG9wLCBoZWlnaHQsIHdpZHRoIH0sIHRydWUpO1xuICB9O1xuXG4gIHByb3RlY3RlZCByZXNpemVDcm9wRm9sbG93QlJEaXIoZTogSUV2ZW50KSB7XG4gICAgY29uc3QgbW9tZW50WSA9IGUuY2xpZW50WSAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmNsaWVudFk7XG4gICAgY29uc3QgbW9tZW50WCA9IHRoaXMucmF0aW9WYWx1ZSgpID8gbW9tZW50WSAqIHRoaXMucmF0aW9WYWx1ZSgpIDogZS5jbGllbnRYIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZVRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlSGVpZ2h0IC0gdGhpcy5zdGFydE1vdXNlRGltKCkudG9wO1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0ICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VXaWR0aCAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQ7XG4gICAgbGV0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5nZXRSZWN0UmVzaXplQ3JvcEZvbGxvdyh7IHdpZHRoOiAxLCBoZWlnaHQ6IDEsIGxlZnQ6IDAsIHRvcDogMCB9LCBtb21lbnRYLCBtb21lbnRZKTtcblxuICAgIFt3aWR0aCwgaGVpZ2h0XSA9IGdldFdpZHRoSGVpZ2h0UmVzaXplQ3JvcEZvbGxvdyh0aGlzLnJhdGlvVmFsdWUoKSwgd2lkdGgsIGhlaWdodCwgbWF4V2lkdGgsIG1heEhlaWdodCwgdGhpcy5taW5XaWR0aCwgdGhpcy5taW5IZWlnaHQpO1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IGhlaWdodCwgd2lkdGggfSwgdHJ1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVzaXplQ3JvcEZvbGxvd1ZMRGlyID0gKGU6IElFdmVudCkgPT4ge1xuICAgIGNvbnN0IG1vbWVudFggPSBlLmNsaWVudFggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRYO1xuICAgIGNvbnN0IG1vbWVudFkgPSB0aGlzLnJhdGlvVmFsdWUoKSA/IG1vbWVudFggLyB0aGlzLnJhdGlvVmFsdWUoKSA6IDA7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5zdGFydE1vdXNlRGltKCkudG9wICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaGVpZ2h0IC0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VUb3A7XG4gICAgY29uc3QgbWF4V2lkdGggPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5sZWZ0ICsgdGhpcy5zdGFydE1vdXNlRGltKCkud2lkdGggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZUxlZnQ7XG4gICAgbGV0IHsgd2lkdGgsIGhlaWdodCwgdG9wLCBsZWZ0IH0gPSB0aGlzLmdldFJlY3RSZXNpemVDcm9wRm9sbG93KHsgd2lkdGg6IC0xLCBoZWlnaHQ6IC0xLCBsZWZ0OiAxLCB0b3A6IDEgfSwgbW9tZW50WCwgbW9tZW50WSk7XG5cbiAgICBbd2lkdGgsIGhlaWdodF0gPSBnZXRXaWR0aEhlaWdodFJlc2l6ZUNyb3BGb2xsb3codGhpcy5yYXRpb1ZhbHVlKCksIHdpZHRoLCBoZWlnaHQsIG1heFdpZHRoLCBtYXhIZWlnaHQsIHRoaXMubWluV2lkdGgsIHRoaXMubWluSGVpZ2h0KTtcbiAgICBsZWZ0ID0gdGhpcy5zdGFydE1vdXNlRGltKCkubGVmdCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLndpZHRoIC0gd2lkdGg7XG4gICAgdG9wID0gdGhpcy5zdGFydE1vdXNlRGltKCkudG9wICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaGVpZ2h0IC0gaGVpZ2h0O1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IHRvcCwgbGVmdCwgaGVpZ2h0LCB3aWR0aCB9LCB0cnVlKTtcbiAgfTtcblxuICBwcm90ZWN0ZWQgcmVzaXplQ3JvcEZvbGxvd1ZSRGlyID0gKGU6IElFdmVudCkgPT4ge1xuICAgIGNvbnN0IG1vbWVudFggPSBlLmNsaWVudFggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRYO1xuICAgIGNvbnN0IG1vbWVudFkgPSB0aGlzLnJhdGlvVmFsdWUoKSA/IC1tb21lbnRYIC8gdGhpcy5yYXRpb1ZhbHVlKCkgOiAwO1xuICAgIGNvbnN0IG1heEhlaWdodCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmhlaWdodCAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlVG9wO1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0ICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VXaWR0aCAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQ7XG4gICAgbGV0IHsgd2lkdGgsIGhlaWdodCwgdG9wIH0gPSB0aGlzLmdldFJlY3RSZXNpemVDcm9wRm9sbG93KHsgd2lkdGg6IDEsIGhlaWdodDogLTEsIGxlZnQ6IDAsIHRvcDogMSB9LCBtb21lbnRYLCBtb21lbnRZKTtcblxuICAgIFt3aWR0aCwgaGVpZ2h0XSA9IGdldFdpZHRoSGVpZ2h0UmVzaXplQ3JvcEZvbGxvdyh0aGlzLnJhdGlvVmFsdWUoKSwgd2lkdGgsIGhlaWdodCwgbWF4V2lkdGgsIG1heEhlaWdodCwgdGhpcy5taW5XaWR0aCwgdGhpcy5taW5IZWlnaHQpO1xuICAgIHRvcCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmhlaWdodCAtIGhlaWdodDtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuY3JvcEFyZWEoKSwgeyB0b3AsIGhlaWdodCwgd2lkdGggfSwgdHJ1ZSk7XG4gIH07XG5cbiAgcHJvdGVjdGVkIHJlc2l6ZUNyb3BGb2xsb3dIVERpciA9IChlOiBJRXZlbnQpID0+IHtcbiAgICBjb25zdCBtb21lbnRZID0gZS5jbGllbnRZIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WTtcbiAgICBjb25zdCBtb21lbnRYID0gdGhpcy5yYXRpb1ZhbHVlKCkgPyBtb21lbnRZICogdGhpcy5yYXRpb1ZhbHVlKCkgOiAwO1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5zdGFydE1vdXNlRGltKCkud2lkdGggKyB0aGlzLnN0YXJ0TW91c2VEaW0oKS5sZWZ0IC0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0O1xuICAgIGNvbnN0IG1heEhlaWdodCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmhlaWdodCAtIHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlVG9wO1xuICAgIGxldCB7IHdpZHRoLCBoZWlnaHQsIHRvcCwgbGVmdCB9ID0gdGhpcy5nZXRSZWN0UmVzaXplQ3JvcEZvbGxvdyh7IHdpZHRoOiAtMSwgaGVpZ2h0OiAtMSwgbGVmdDogMSwgdG9wOiAxIH0sIG1vbWVudFgsIG1vbWVudFkpO1xuXG4gICAgW3dpZHRoLCBoZWlnaHRdID0gZ2V0V2lkdGhIZWlnaHRSZXNpemVDcm9wRm9sbG93KHRoaXMucmF0aW9WYWx1ZSgpLCB3aWR0aCwgaGVpZ2h0LCBtYXhXaWR0aCwgbWF4SGVpZ2h0LCB0aGlzLm1pbldpZHRoLCB0aGlzLm1pbkhlaWdodCk7XG4gICAgdG9wID0gdGhpcy5zdGFydE1vdXNlRGltKCkudG9wICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaGVpZ2h0IC0gaGVpZ2h0O1xuICAgIGxlZnQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5sZWZ0ICsgdGhpcy5zdGFydE1vdXNlRGltKCkud2lkdGggLSB3aWR0aDtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuY3JvcEFyZWEoKSwgeyB0b3AsIGxlZnQsIGhlaWdodCwgd2lkdGggfSwgdHJ1ZSk7XG4gIH07XG5cbiAgcHJvdGVjdGVkIHJlc2l6ZUNyb3BGb2xsb3dIQkRpciA9IChlOiBJRXZlbnQpID0+IHtcbiAgICBjb25zdCBtb21lbnRZID0gZS5jbGllbnRZIC0gdGhpcy5zdGFydE1vdXNlRGltKCkuY2xpZW50WTtcbiAgICBjb25zdCBtb21lbnRYID0gdGhpcy5yYXRpb1ZhbHVlKCkgPyBtb21lbnRZICogdGhpcy5yYXRpb1ZhbHVlKCkgOiAwO1xuICAgIGNvbnN0IG1heEhlaWdodCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlVG9wICsgdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VIZWlnaHQgLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS50b3A7XG4gICAgY29uc3QgbWF4V2lkdGggPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS53aWR0aCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQgLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZUxlZnQ7XG4gICAgbGV0IHsgd2lkdGgsIGhlaWdodCwgbGVmdCB9ID0gdGhpcy5nZXRSZWN0UmVzaXplQ3JvcEZvbGxvdyh7IHdpZHRoOiAxLCBoZWlnaHQ6IDEsIGxlZnQ6IC0xLCB0b3A6IDAgfSwgbW9tZW50WCwgbW9tZW50WSk7XG5cbiAgICBbd2lkdGgsIGhlaWdodF0gPSBnZXRXaWR0aEhlaWdodFJlc2l6ZUNyb3BGb2xsb3codGhpcy5yYXRpb1ZhbHVlKCksIHdpZHRoLCBoZWlnaHQsIG1heFdpZHRoLCBtYXhIZWlnaHQsIHRoaXMubWluV2lkdGgsIHRoaXMubWluSGVpZ2h0KTtcbiAgICBsZWZ0ID0gdGhpcy5zdGFydE1vdXNlRGltKCkubGVmdCArIHRoaXMuc3RhcnRNb3VzZURpbSgpLndpZHRoIC0gd2lkdGg7XG4gICAgdGhpcy5zZXRTdHlsZXNFbGVtZW50cyh0aGlzLmNyb3BBcmVhKCksIHsgaGVpZ2h0LCBsZWZ0LCB3aWR0aCB9LCB0cnVlKTtcbiAgfTtcblxuICBwcml2YXRlIGdldFJlY3RSZXNpemVDcm9wRm9sbG93KHJhdGlvOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyOyB0b3A6IG51bWJlcjsgbGVmdDogbnVtYmVyIH0sIG1vbWVudFg6IG51bWJlciwgbW9tZW50WTogbnVtYmVyKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS53aWR0aCArIG1vbWVudFggKiByYXRpby53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5oZWlnaHQgKyBtb21lbnRZICogcmF0aW8uaGVpZ2h0O1xuICAgIGNvbnN0IHRvcCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIG1vbWVudFkgKiByYXRpby50b3A7XG4gICAgY29uc3QgbGVmdCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmxlZnQgKyBtb21lbnRYICogcmF0aW8ubGVmdDtcblxuICAgIHJldHVybiB7IHdpZHRoLCBoZWlnaHQsIGxlZnQsIHRvcCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyTW91c2V1cCgpIHtcbiAgICB0aGlzLmltYWdlQ29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdjdXJzb3ItbW92ZScpO1xuICAgIHRoaXMuY3JvcEFyZWEoKS5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2N1cnNvci1tb3ZlJyk7XG4gICAgdGhpcy5yZXNpemVTdGF0ZS5zZXQoJ25vbmUnKTtcbiAgICB0aGlzLm1vdmVTdGF0ZS5zZXQoJ25vbmUnKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlck1vdXNld2hlZWwoZXZlbnQ6IGFueSkge1xuICAgIGlmICghdGhpcy5oYXNab29tKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGV2ZW50LmRlbHRhWSA8IDApIHtcbiAgICAgIHRoaXMuem9vbUltYWdlKDEgLyAxLjEpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuem9vbUltYWdlKDEuMSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJJbWFnZUNvbnRhaW5lck1vdXNlZG93bihlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5yZXNpemVTdGF0ZSgpID09PSAnbm9uZScgJiYgdGhpcy5tb3ZlU3RhdGUoKSA9PT0gJ25vbmUnKSB7XG4gICAgICB0aGlzLm1vdmVTdGF0ZS5zZXQoJ2ltYWdlJyk7XG4gICAgICB0aGlzLmhhbmRsZXJNb3VzZWRvd24oZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyQ3JvcFJlc2l6ZShlOiBhbnksIHJlc2l6ZVR5cGU6IFRZUEVfUkVTSVpFX1NUQVRFKSB7XG4gICAgdGhpcy5yZXNpemVTdGF0ZS5zZXQocmVzaXplVHlwZSk7XG4gICAgdGhpcy5kcmFnR3JpZENyb3Auc2V0KHRydWUpO1xuICAgIHRoaXMuaGFuZGxlck1vdXNlZG93bihlKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlck1vdXNlZG93bkNyb3BBcmVhKGU6IGFueSkge1xuICAgIHRoaXMubW92ZVN0YXRlLnNldCgnY2xpcCcpO1xuICAgIHRoaXMuaGFuZGxlck1vdXNlZG93bihlKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlck1vdXNlZG93bihlOiBJRXZlbnQpIHtcbiAgICBjb25zdCBbd2lkdGgsIGhlaWdodCwgdG9wLCBsZWZ0XSA9IGdldFN0eWxlc09mRWxlbWVudDxudW1iZXI+KHRoaXMuY3JvcEFyZWEoKS5uYXRpdmVFbGVtZW50LCBbJ29mZnNldFdpZHRoJywgJ29mZnNldEhlaWdodCcsICdzdHlsZS50b3AnLCAnc3R5bGUubGVmdCddKTtcbiAgICBjb25zdCBbaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQsIGltYWdlVG9wLCBpbWFnZUxlZnRdID0gZ2V0U3R5bGVzT2ZFbGVtZW50PG51bWJlcj4odGhpcy5pbWFnZU9yaWdpbigpLm5hdGl2ZUVsZW1lbnQsIFsnb2Zmc2V0V2lkdGgnLCAnb2Zmc2V0SGVpZ2h0JywgJ3N0eWxlLnRvcCcsICdzdHlsZS5sZWZ0J10pO1xuICAgIHN3aXRjaCAodGhpcy5tb3ZlU3RhdGUoKSkge1xuICAgICAgY2FzZSAnaW1hZ2UnOlxuICAgICAgICB0aGlzLmltYWdlQ29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjdXJzb3ItbW92ZScpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NsaXAnOlxuICAgICAgICBpZiAod2lkdGggPT09IGltYWdlV2lkdGggJiYgaGVpZ2h0ID09PSBpbWFnZUhlaWdodCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNyb3BBcmVhKCkubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjdXJzb3ItbW92ZScpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydE1vdXNlRGltLnNldCh7XG4gICAgICBjbGllbnRYOiBlLmNsaWVudFgsXG4gICAgICBjbGllbnRZOiBlLmNsaWVudFksXG4gICAgICB3aWR0aDogd2lkdGgsXG4gICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgIHRvcDogdG9wLFxuICAgICAgbGVmdDogbGVmdCxcbiAgICAgIGltYWdlVG9wOiBpbWFnZVRvcCxcbiAgICAgIGltYWdlTGVmdDogaW1hZ2VMZWZ0LFxuICAgICAgaW1hZ2VXaWR0aDogaW1hZ2VXaWR0aCxcbiAgICAgIGltYWdlSGVpZ2h0OiBpbWFnZUhlaWdodFxuICAgIH0pO1xuICAgIHRoaXMucmF0aW9WYWx1ZS5zZXQodGhpcy5nZXRDcm9wUmF0aW9WYWx1ZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZUltYWdlKGU6IElFdmVudCkge1xuICAgIGNvbnN0IG1vbWVudFkgPSBlLmNsaWVudFkgLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRZO1xuICAgIGNvbnN0IG1vbWVudFggPSBlLmNsaWVudFggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRYO1xuICAgIGNvbnN0IGltZ1RvcCA9IHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlVG9wICsgbW9tZW50WTtcbiAgICBjb25zdCBpbWdMZWZ0ID0gdGhpcy5zdGFydE1vdXNlRGltKCkuaW1hZ2VMZWZ0ICsgbW9tZW50WDtcbiAgICBjb25zdCB0b3AgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS50b3AgKyBtb21lbnRZO1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5sZWZ0ICsgbW9tZW50WDtcblxuXG4gICAgdGhpcy5zZXRTdHlsZXNFbGVtZW50cyh0aGlzLmltYWdlT3JpZ2luKCksIHsgdG9wOiBpbWdUb3AsIGxlZnQ6IGltZ0xlZnQgfSk7XG4gICAgdGhpcy5zZXRTdHlsZXNFbGVtZW50cyh0aGlzLmltYWdlQ2xpcCgpLCB7IHRvcDogaW1nVG9wLCBsZWZ0OiBpbWdMZWZ0IH0pO1xuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IHRvcCwgbGVmdCB9KTtcbiAgICB0aGlzLnNldENpcmNsZVBvc2l0aW9uKHsgdG9wOiBpbWdUb3AsIGxlZnQ6IGltZ0xlZnQsIHdpZHRoOiB0aGlzLnN0YXJ0TW91c2VEaW0oKS5pbWFnZVdpZHRoLCBoZWlnaHQ6IHRoaXMuc3RhcnRNb3VzZURpbSgpLmltYWdlSGVpZ2h0IH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlQ2xpcEFyZWEoZTogSUV2ZW50KSB7XG4gICAgY29uc3QgW2ltZ1dpZHRoLCBpbWdIZWlnaHQsIGltZ1RvcCwgaW1nTGVmdF0gPSBnZXRTdHlsZXNPZkVsZW1lbnQ8bnVtYmVyPih0aGlzLmltYWdlQ2xpcCgpLm5hdGl2ZUVsZW1lbnQsIFsnb2Zmc2V0V2lkdGgnLCAnb2Zmc2V0SGVpZ2h0JywgJ3N0eWxlLnRvcCcsICdzdHlsZS5sZWZ0J10pO1xuICAgIGNvbnN0IFtjcm9wV2lkdGgsIGNyb3BIZWlnaHRdID0gZ2V0U3R5bGVzT2ZFbGVtZW50PG51bWJlcj4odGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQsIFsnb2Zmc2V0V2lkdGgnLCAnb2Zmc2V0SGVpZ2h0J10pO1xuICAgIGNvbnN0IG1vbWVudFkgPSBlLmNsaWVudFkgLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRZO1xuICAgIGNvbnN0IG1vbWVudFggPSBlLmNsaWVudFggLSB0aGlzLnN0YXJ0TW91c2VEaW0oKS5jbGllbnRYO1xuICAgIGxldCB0b3AgPSBNYXRoLm1heChpbWdUb3AsIHRoaXMuc3RhcnRNb3VzZURpbSgpLnRvcCArIG1vbWVudFkpO1xuICAgIGxldCBsZWZ0ID0gTWF0aC5tYXgoaW1nTGVmdCwgdGhpcy5zdGFydE1vdXNlRGltKCkubGVmdCArIG1vbWVudFgpO1xuXG4gICAgdG9wID0gTWF0aC5taW4odG9wLCBpbWdUb3AgKyBpbWdIZWlnaHQgLSBjcm9wSGVpZ2h0KTtcbiAgICBsZWZ0ID0gTWF0aC5taW4obGVmdCwgaW1nTGVmdCArIGltZ1dpZHRoIC0gY3JvcFdpZHRoKTtcblxuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IHRvcCwgbGVmdCB9LCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgem9vbUltYWdlKHNjYWxlOiBudW1iZXIpIHtcbiAgICBjb25zdCBbY3VycldpZHRoLCBjdXJySGVpZ2h0LCBjdXJyVG9wLCBjdXJyTGVmdF0gPSBnZXRTdHlsZXNPZkVsZW1lbnQ8bnVtYmVyPih0aGlzLmltYWdlT3JpZ2luKCkubmF0aXZlRWxlbWVudCwgWydvZmZzZXRXaWR0aCcsICdvZmZzZXRIZWlnaHQnLCAnc3R5bGUudG9wJywgJ3N0eWxlLmxlZnQnXSk7XG4gICAgY29uc3Qgd2lkdGggPSBNYXRoLm1heChjdXJyV2lkdGggKiBzY2FsZSwgNTApO1xuICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodCAqIHdpZHRoIC8gdGhpcy5pbWFnZU9yaWdpbigpLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgY29uc3QgdG9wID0gY3VyclRvcCArIChjdXJySGVpZ2h0IC0gaGVpZ2h0KSAvIDI7XG4gICAgY29uc3QgbGVmdCA9IGN1cnJMZWZ0ICsgKGN1cnJXaWR0aCAtIHdpZHRoKSAvIDI7XG4gICAgbGV0IFtjcm9wV2lkdGgsIGNyb3BIZWlnaHRdID0gZ2V0U3R5bGVzT2ZFbGVtZW50PG51bWJlcj4odGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQsIFsnb2Zmc2V0V2lkdGgnLCAnb2Zmc2V0SGVpZ2h0J10pO1xuICAgIGNvbnN0IFtjcm9wVG9wLCBjcm9wTGVmdF0gPSBnZXRTdHlsZXNPZkVsZW1lbnQ8bnVtYmVyPih0aGlzLmNyb3BBcmVhKCkubmF0aXZlRWxlbWVudCwgWydzdHlsZS50b3AnLCAnc3R5bGUubGVmdCddKTtcbiAgICBjb25zdCBtYXhDcm9wV2lkdGggPSB3aWR0aCArIGxlZnQgLSBjcm9wTGVmdDtcbiAgICBjb25zdCBtYXhDcm9wSGVpZ2h0ID0gaGVpZ2h0ICsgdG9wIC0gY3JvcFRvcDtcbiAgICBjb25zdCBtaW5XaWR0aCA9IDIwO1xuICAgIGNvbnN0IG1pbkhlaWdodCA9IDIwO1xuXG4gICAgY3JvcFdpZHRoID0gTWF0aC5taW4oY3JvcFdpZHRoLCBtYXhDcm9wV2lkdGgpO1xuICAgIGNyb3BIZWlnaHQgPSBNYXRoLm1pbihjcm9wSGVpZ2h0LCBtYXhDcm9wSGVpZ2h0KTtcbiAgICBjcm9wV2lkdGggPSBNYXRoLm1heChjcm9wV2lkdGgsIG1pbldpZHRoKTtcbiAgICBjcm9wSGVpZ2h0ID0gTWF0aC5tYXgoY3JvcEhlaWdodCwgbWluSGVpZ2h0KTtcbiAgICB0aGlzLnJhdGlvVmFsdWUuc2V0KHRoaXMuZ2V0Q3JvcFJhdGlvVmFsdWUoKSk7XG4gICAgaWYgKHRoaXMucmF0aW9WYWx1ZSgpKSB7XG4gICAgICBjcm9wSGVpZ2h0ID0gY3JvcFdpZHRoIC8gdGhpcy5yYXRpb1ZhbHVlKCk7XG4gICAgICBjcm9wSGVpZ2h0ID0gTWF0aC5taW4oY3JvcEhlaWdodCwgbWF4Q3JvcEhlaWdodCk7XG4gICAgICBjcm9wSGVpZ2h0ID0gTWF0aC5tYXgoY3JvcEhlaWdodCwgbWluSGVpZ2h0KTtcbiAgICAgIGNyb3BXaWR0aCA9IGNyb3BIZWlnaHQgKiB0aGlzLnJhdGlvVmFsdWUoKTtcbiAgICB9XG4gICAgdGhpcy5yZWN0Q2xpcC51cGRhdGUocmVjdCA9PiB7XG4gICAgICBjb25zdCByZWN0VG9wID0gY3JvcFRvcCAtIHRvcDtcbiAgICAgIGNvbnN0IHJlY3RMZWZ0ID0gY3JvcExlZnQgLSBsZWZ0O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVjdCxcbiAgICAgICAgdG9wOiByZWN0VG9wLFxuICAgICAgICBsZWZ0OiByZWN0TGVmdCxcbiAgICAgICAgcmlnaHQ6IHJlY3RMZWZ0ICsgY3JvcFdpZHRoLFxuICAgICAgICBib3R0b206IHJlY3RUb3AgKyBjcm9wSGVpZ2h0XG4gICAgICB9O1xuICAgIH0pO1xuICAgIGNvbnN0IGNsaXAgPSBgcmVjdCgke3RoaXMucmVjdENsaXAoKS50b3B9cHgsICR7dGhpcy5yZWN0Q2xpcCgpLnJpZ2h0fXB4LCAke3RoaXMucmVjdENsaXAoKS5ib3R0b219cHgsICR7dGhpcy5yZWN0Q2xpcCgpLmxlZnR9cHgpYDtcblxuICAgIHRoaXMuc2V0U3R5bGVzRWxlbWVudHModGhpcy5jcm9wQXJlYSgpLCB7IHRvcDogY3JvcFRvcCwgbGVmdDogY3JvcExlZnQsIHdpZHRoOiBjcm9wV2lkdGgsIGhlaWdodDogY3JvcEhlaWdodCB9KTtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VPcmlnaW4oKSwgeyB0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgdGhpcy5zZXRDaXJjbGVQb3NpdGlvbih7IHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VDbGlwKCksIHsgY2xpcCwgdG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgIHRoaXMuZ2V0UmVjdENsaXBJbWFnZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJSb3RhdGVJbWFnZShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmltYWdlLnNyYyA9IHRoaXMuaW1nU3JjKCk7XG4gICAgdGhpcy5pbWFnZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgICAgIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IGdldFN0eWxlc09mRWxlbWVudDxudW1iZXI+KHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LCBbJ29mZnNldFdpZHRoJywgJ29mZnNldEhlaWdodCddKTtcbiAgICAgIGNvbnN0IG9yaWdpbldpZHRoID0gdGhpcy5pbWFnZS53aWR0aDtcbiAgICAgIGNvbnN0IG9yaWdpbkhlaWdodCA9IHRoaXMuaW1hZ2UuaGVpZ2h0O1xuICAgICAgbGV0IHRvcCA9IHBhcnNlSW50KHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCk7XG4gICAgICBsZXQgbGVmdCA9IHBhcnNlSW50KHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LnN0eWxlLmxlZnQpO1xuICAgICAgbGV0IG5ld0hlaWdodCA9IHdpZHRoO1xuICAgICAgbGV0IG5ld1dpZHRoID0gaGVpZ2h0O1xuICAgICAgY29uc3QgcmF0aW8gPSBuZXdXaWR0aCAvIG5ld0hlaWdodDtcblxuICAgICAgY2FudmFzLmhlaWdodCA9IG9yaWdpbldpZHRoO1xuICAgICAgY2FudmFzLndpZHRoID0gb3JpZ2luSGVpZ2h0O1xuICAgICAgY3R4Py50cmFuc2xhdGUob3JpZ2luSGVpZ2h0IC8gMiwgb3JpZ2luV2lkdGggLyAyKTtcbiAgICAgIGN0eD8ucm90YXRlKE1hdGguUEkgLyAyKTtcbiAgICAgIGN0eD8uZHJhd0ltYWdlKHRoaXMuaW1hZ2UsIC1vcmlnaW5XaWR0aCAvIDIsIC1vcmlnaW5IZWlnaHQgLyAyKTtcbiAgICAgIGNvbnN0IHNyYyA9IGdldERhdGFVcmwoY2FudmFzLCB0aGlzLm1pbWV0eXBlKCksIHRoaXMuaW1hZ2Uuc3JjKTtcblxuICAgICAgdGhpcy5pbWdTcmMuc2V0KHNyYyk7XG4gICAgICBuZXdXaWR0aCA9IE1hdGgubWF4KG5ld1dpZHRoLCBvcmlnaW5IZWlnaHQpO1xuICAgICAgbmV3V2lkdGggPSBNYXRoLm1pbihuZXdXaWR0aCwgdGhpcy5jb250YWluZXJXaWR0aCgpKTtcbiAgICAgIG5ld0hlaWdodCA9IG5ld1dpZHRoIC8gcmF0aW87XG4gICAgICBuZXdIZWlnaHQgPSBNYXRoLm1heChuZXdIZWlnaHQsIG9yaWdpbldpZHRoKTtcbiAgICAgIG5ld0hlaWdodCA9IE1hdGgubWluKG5ld0hlaWdodCwgdGhpcy5jb250YWluZXJIZWlnaHQoKSk7XG4gICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCAqIHJhdGlvO1xuICAgICAgdG9wID0gdG9wIC0gKG5ld0hlaWdodCAvIDIgLSBoZWlnaHQgLyAyKTtcbiAgICAgIGxlZnQgPSBsZWZ0IC0gKG5ld1dpZHRoIC8gMiAtIHdpZHRoIC8gMik7XG4gICAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VPcmlnaW4oKSwgeyBzcmMsIHRvcCwgbGVmdCwgd2lkdGg6IG5ld1dpZHRoLCBoZWlnaHQ6IG5ld0hlaWdodCB9KTtcbiAgICAgIHRoaXMuc2V0Q2lyY2xlUG9zaXRpb24oeyB0b3AsIGxlZnQsIHdpZHRoOiBuZXdXaWR0aCwgaGVpZ2h0OiBuZXdIZWlnaHQgfSk7XG4gICAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VDbGlwKCksIHsgc3JjLCB0b3AsIGxlZnQsIHdpZHRoOiBuZXdXaWR0aCwgaGVpZ2h0OiBuZXdIZWlnaHQgfSk7XG4gICAgICB0aGlzLmdldE9yaWdpbmFsSW1hZ2VTaXplKCgpID0+IHtcbiAgICAgICAgdGhpcy5jcm9wU2l6ZS5zZXQoeyB3aWR0aDogdGhpcy5vcmlnaW5XaWR0aCgpLCBoZWlnaHQ6IHRoaXMub3JpZ2luSGVpZ2h0KCkgfSk7XG4gICAgICAgIHRoaXMudXBkYXRlT3JpZ2luSW1hZ2VTaXplKCk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2hhbmdlZEltYWdlKHRydWUpO1xuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0T3JpZ2luYWxJbWFnZVNpemUoY2FsbGJhY2s/OiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5pbWFnZS5zcmMgPSB0aGlzLmltZ1NyYygpO1xuICAgIHRoaXMuaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgdGhpcy5vcmlnaW5XaWR0aC5zZXQodGhpcy5pbWFnZS53aWR0aCk7XG4gICAgICB0aGlzLm9yaWdpbkhlaWdodC5zZXQodGhpcy5pbWFnZS5oZWlnaHQpO1xuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgY2hhbmdlZEltYWdlKHN0YXR1czogYm9vbGVhbikge1xuICAgIHRoaXMuY2hhbmdlZC5zZXQoc3RhdHVzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyRmxpcEltYWdlKGV2ZW50OiBFdmVudCwgbW9kZTogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJykge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuaW1hZ2Uuc3JjID0gdGhpcy5pbWdTcmMoKTtcbiAgICB0aGlzLmltYWdlLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy5pbWFnZS53aWR0aDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuaW1hZ2UuaGVpZ2h0O1xuXG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcy5pbWFnZSwgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGlmIChtb2RlID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICBjdHgudHJhbnNsYXRlKHdpZHRoLCAwKTtcbiAgICAgICAgICBjdHguc2NhbGUoLTEsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtb2RlID09PSAndmVydGljYWwnKSB7XG4gICAgICAgICAgY3R4LnRyYW5zbGF0ZSgwLCBoZWlnaHQpO1xuICAgICAgICAgIGN0eC5zY2FsZSgxLCAtMSk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLmltYWdlLCAwLCAwKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRhdGFVcmwgPSBnZXREYXRhVXJsKGNhbnZhcywgdGhpcy5taW1ldHlwZSgpLCB0aGlzLmltYWdlLnNyYyk7XG5cbiAgICAgIHRoaXMuaW1nU3JjLnNldChkYXRhVXJsKTtcbiAgICAgIHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LnNyYyA9IGRhdGFVcmw7XG4gICAgICB0aGlzLmltYWdlQ2xpcCgpLm5hdGl2ZUVsZW1lbnQuc3JjID0gZGF0YVVybDtcbiAgICAgIHRoaXMudXBkYXRlQ3JvcEFyZWFQb3MoKTtcbiAgICAgIHRoaXMudXBkYXRlUmVjdENsaXBQb3MoKTtcbiAgICAgIHRoaXMuY2hhbmdlZEltYWdlKHRydWUpO1xuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclJlc3RvcmVJbWFnZShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmltZ1NyYy5zZXQodGhpcy5kYXRhVXJsT3JpZ2luKCkpO1xuICAgIHRoaXMuZHJhZ0dyaWRDcm9wLnNldChmYWxzZSk7XG4gICAgdGhpcy5nZXRPcmlnaW5hbEltYWdlU2l6ZSgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZU9yaWdpbkltYWdlU2l6ZSgpO1xuICAgICAgdGhpcy5jaGFuZ2VkSW1hZ2UoZmFsc2UpO1xuICAgICAgdGhpcy5jcm9wUmF0aW9JdGVtU2VsZWN0ZWQuc2V0KCcnKTtcbiAgICAgIHRoaXMudXBkYXRlQ3JvcEFyZWFQb3MoKTtcbiAgICAgIHRoaXMudXBkYXRlUmVjdENsaXBQb3MoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JvcEltYWdlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICB0aGlzLmltYWdlLnNyYyA9IHRoaXMuaW1nU3JjKCk7XG4gICAgICB0aGlzLmltYWdlLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgIGNvbnN0IG9yaWdpbldpZHRoID0gdGhpcy5pbWFnZS53aWR0aDtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBwYXJzZUludCh0aGlzLmltYWdlQ2xpcCgpLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGgpO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBwYXJzZUludCh0aGlzLmltYWdlQ2xpcCgpLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0KTtcbiAgICAgICAgY29uc3Qgc2NhbGUgPSBvcmlnaW5XaWR0aCAvIHdpZHRoO1xuICAgICAgICBjb25zdCByZWN0Q2xpcCA9IHRoaXMuZ2V0UmVjdENsaXBJbWFnZSgpO1xuICAgICAgICBjb25zdCBjcm9wUmVjdCA9IGdldENyb3BSZWN0SW1hZ2UocmVjdENsaXAsIHdpZHRoLCBoZWlnaHQsIHNjYWxlKTtcblxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gY3JvcFJlY3QuaGVpZ2h0O1xuICAgICAgICBjYW52YXMud2lkdGggPSBjcm9wUmVjdC53aWR0aDtcbiAgICAgICAgdGhpcy5vcmlnaW5IZWlnaHQuc2V0KGNhbnZhcy5oZWlnaHQpO1xuICAgICAgICB0aGlzLm9yaWdpbldpZHRoLnNldChjYW52YXMud2lkdGgpO1xuICAgICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICBpZiAoY3R4KSB7XG4gICAgICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLmltYWdlLCBjcm9wUmVjdC5sZWZ0LCBjcm9wUmVjdC50b3AsIGNyb3BSZWN0LndpZHRoLCBjcm9wUmVjdC5oZWlnaHQsIDAsIDAsIGNyb3BSZWN0LndpZHRoLCBjcm9wUmVjdC5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRhdGFVcmwgPSBnZXREYXRhVXJsKGNhbnZhcywgdGhpcy5taW1ldHlwZSgpLCB0aGlzLmltYWdlLnNyYyk7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VkSW1hZ2UodHJ1ZSk7XG4gICAgICAgIHJlc29sdmUoZGF0YVVybCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJTYXZlRmlsZShldmVudDogRXZlbnQsIG1vZGVTYXZlOiBUWVBFX01PREVfU0FWRSkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGRhdGFVcmwgPSBhd2FpdCB0aGlzLmNyb3BJbWFnZSgpO1xuICAgIGNvbnN0IGZpbGUgPSBjb252ZXJ0QmFzZTY0VG9CbG9iKGRhdGFVcmwpO1xuXG4gICAgdGhpcy5vdXRTYXZlRmlsZS5lbWl0KHsgZmlsZTogZmlsZSwgdXJsOiBkYXRhVXJsLCBtb2RlOiBtb2RlU2F2ZSB9KTtcbiAgfVxuXG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDbG9zZShldmVudDogRXZlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm91dENsb3NlLmVtaXQoeyBpc0NsaWNrQnV0dG9uQ2xvc2U6IHRydWUgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclNlbGVjdENyb3BSYXRpb0l0ZW0oZXZlbnQ6IEV2ZW50LCBrZXk6IHN0cmluZykge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuY3JvcFJhdGlvSXRlbVNlbGVjdGVkLnNldChrZXkpO1xuICAgIHRoaXMuYXNwZWN0UmF0aW8uc2V0KHVuZGVmaW5lZCk7XG4gICAgdGhpcy5jaGFuZ2VkLnNldCh0cnVlKTtcbiAgICB0aGlzLmRyYWdHcmlkQ3JvcC5zZXQodHJ1ZSk7XG4gICAgdGhpcy51cGRhdGVPcmlnaW5JbWFnZVNpemUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyUmVzaXplKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICh0aGlzLnJlc2l6ZUNvbXBvbmVudFJlZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlc2l6ZUNvbXBvbmVudFJlZiA9IHRoaXMuZHluYW1pY0NvbXBvbmVudFNlcnZpY2UucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoTGlic1VpQ29tcG9uZW50c0ltYWdlRWRpdG9yUmVzaXplQ29tcG9uZW50KTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMucmVzaXplQ29tcG9uZW50UmVmLmluc3RhbmNlO1xuICAgIGNvbnN0IHN1YnMgPSBpbnN0YW5jZS5vdXRDbG9zZS5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLnJlc2l6ZUNvbXBvbmVudFJlZik7XG4gICAgICB0aGlzLnJlc2l6ZUNvbXBvbmVudFJlZiA9IHVuZGVmaW5lZDtcbiAgICAgIHN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcblxuICAgIGluc3RhbmNlLnNyYyA9IHRoaXMuaW1nU3JjKCk7XG4gICAgaW5zdGFuY2UubWltZXR5cGUgPSB0aGlzLm1pbWV0eXBlKCk7XG4gICAgaW5zdGFuY2UuekluZGV4ID0gdGhpcy56SW5kZXgoKTtcbiAgICBzdWJzLmFkZChpbnN0YW5jZS5vdXRTYXZlLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgIHRoaXMucmVzaXplRGF0YS5zZXQoZXZlbnQpO1xuICAgICAgdGhpcy5zYXZlUmVzaXplKCk7XG4gICAgfSkpO1xuICAgIGluc3RhbmNlLnJlc2l6ZURhdGEgPSB7IHJhdGlvOiAxMDAsIHdpZHRoOiB0aGlzLm9yaWdpbldpZHRoKCksIGhlaWdodDogdGhpcy5vcmlnaW5IZWlnaHQoKSB9O1xuICAgIGluc3RhbmNlLm9yaWdpbldpZHRoID0gdGhpcy5vcmlnaW5XaWR0aCgpO1xuICAgIGluc3RhbmNlLm9yaWdpbkhlaWdodCA9IHRoaXMub3JpZ2luSGVpZ2h0KCk7XG4gICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5hZGRUb0JvZHkodGhpcy5yZXNpemVDb21wb25lbnRSZWYpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNhdmVSZXNpemUoKSB7XG4gICAgdGhpcy5pbWFnZS5zcmMgPSB0aGlzLmltZ1NyYygpO1xuICAgIHRoaXMuaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG5cbiAgICAgIGNhbnZhcy53aWR0aCA9IHRoaXMucmVzaXplRGF0YSgpLndpZHRoO1xuICAgICAgY2FudmFzLmhlaWdodCA9IHRoaXMucmVzaXplRGF0YSgpLmhlaWdodDtcbiAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcy5pbWFnZSwgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNyYyA9IGdldERhdGFVcmwoY2FudmFzLCB0aGlzLm1pbWV0eXBlKCksIHRoaXMuaW1hZ2Uuc3JjKTtcbiAgICAgIGNvbnN0IFtjdXJyV2lkdGgsIGN1cnJIZWlnaHQsIGN1cnJUb3AsIGN1cnJMZWZ0XSA9IGdldFN0eWxlc09mRWxlbWVudDxudW1iZXI+KHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LCBbJ29mZnNldFdpZHRoJywgJ29mZnNldEhlaWdodCcsICdzdHlsZS50b3AnLCAnc3R5bGUubGVmdCddKTtcbiAgICAgIGNvbnN0IHJhdGlvID0gY3VycldpZHRoIC8gY3VyckhlaWdodDtcbiAgICAgIGxldCBuZXdXaWR0aCA9IE1hdGgubWluKHRoaXMucmVzaXplRGF0YSgpLndpZHRoLCB0aGlzLmNvbnRhaW5lcldpZHRoKCkpO1xuICAgICAgbGV0IG5ld0hlaWdodCA9IG5ld1dpZHRoIC8gcmF0aW87XG5cbiAgICAgIG5ld0hlaWdodCA9IE1hdGgubWluKHRoaXMucmVzaXplRGF0YSgpLmhlaWdodCwgdGhpcy5jb250YWluZXJIZWlnaHQoKSk7XG4gICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCAqIHJhdGlvO1xuICAgICAgTWF0aC5taW4odGhpcy5yZXNpemVEYXRhKCkuaGVpZ2h0LCB0aGlzLmNvbnRhaW5lckhlaWdodCgpKTtcbiAgICAgIGNvbnN0IHRvcCA9IGN1cnJUb3AgKyAoY3VyckhlaWdodCAtIG5ld0hlaWdodCkgLyAyO1xuICAgICAgY29uc3QgbGVmdCA9IGN1cnJMZWZ0ICsgKGN1cnJXaWR0aCAtIG5ld1dpZHRoKSAvIDI7XG4gICAgICBjb25zdCBtb3ZlbWVudFkgPSBjdXJyVG9wIC0gdG9wO1xuICAgICAgY29uc3QgbW92ZW1lbnRYID0gY3VyckxlZnQgLSBsZWZ0O1xuXG4gICAgICB0aGlzLnJlY3RDbGlwLnVwZGF0ZShyZWN0ID0+IHtcbiAgICAgICAgY29uc3QgcmVjdFRvcCA9IHJlY3QudG9wICsgbW92ZW1lbnRZO1xuICAgICAgICBjb25zdCByZWN0TGVmdCA9IHJlY3QubGVmdCArIG1vdmVtZW50WDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5yZWN0LFxuICAgICAgICAgIHRvcDogcmVjdFRvcCxcbiAgICAgICAgICBsZWZ0OiByZWN0TGVmdCxcbiAgICAgICAgICByaWdodDogcmVjdExlZnQgKyBuZXdXaWR0aCxcbiAgICAgICAgICBib3R0b206IHJlY3RUb3AgKyBuZXdIZWlnaHRcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgY2xpcCA9IGByZWN0KCR7dGhpcy5yZWN0Q2xpcCgpLnRvcH1weCwgJHt0aGlzLnJlY3RDbGlwKCkucmlnaHR9cHgsICR7dGhpcy5yZWN0Q2xpcCgpLmJvdHRvbX1weCwgJHt0aGlzLnJlY3RDbGlwKCkubGVmdH1weClgO1xuXG4gICAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VPcmlnaW4oKSwgeyBzcmMsIHRvcCwgbGVmdCwgd2lkdGg6IG5ld1dpZHRoLCBoZWlnaHQ6IG5ld0hlaWdodCB9KTtcbiAgICAgIHRoaXMuc2V0Q2lyY2xlUG9zaXRpb24oeyB0b3AsIGxlZnQsIHdpZHRoOiBuZXdXaWR0aCwgaGVpZ2h0OiBuZXdIZWlnaHQgfSk7XG4gICAgICB0aGlzLnNldFN0eWxlc0VsZW1lbnRzKHRoaXMuaW1hZ2VDbGlwKCksIHsgc3JjLCBjbGlwLCB0b3AsIGxlZnQsIHdpZHRoOiBuZXdXaWR0aCwgaGVpZ2h0OiBuZXdIZWlnaHQgfSk7XG4gICAgICB0aGlzLmltZ1NyYy5zZXQoc3JjKTtcbiAgICAgIHRoaXMub3JpZ2luV2lkdGguc2V0KHRoaXMucmVzaXplRGF0YSgpLndpZHRoKTtcbiAgICAgIHRoaXMub3JpZ2luSGVpZ2h0LnNldCh0aGlzLnJlc2l6ZURhdGEoKS5oZWlnaHQpO1xuICAgICAgdGhpcy51cGRhdGVDcm9wQXJlYVBvcygpO1xuICAgICAgdGhpcy51cGRhdGVSZWN0Q2xpcFBvcygpO1xuICAgICAgdGhpcy5jaGFuZ2VkSW1hZ2UodHJ1ZSk7XG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ3JvcFdpZHRoKCkge1xuICAgIHRoaXMucHJvY2Vzc0Nyb3BXaWR0aE9ySGVpZ2h0KCd3aWR0aCcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJDcm9wSGVpZ2h0KCkge1xuICAgIHRoaXMucHJvY2Vzc0Nyb3BXaWR0aE9ySGVpZ2h0KCdoZWlnaHQnKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc0Nyb3BXaWR0aE9ySGVpZ2h0KGNyb3BCeTogJ3dpZHRoJyB8ICdoZWlnaHQnKSB7XG4gICAgdGhpcy5yYXRpb1ZhbHVlLnNldCh0aGlzLmdldENyb3BSYXRpb1ZhbHVlKCkpO1xuICAgIGNvbnN0IFtjdXJySW1nV2lkdGgsIGN1cnJJbWdIZWlnaHQsIGN1cnJJbWdUb3AsIGN1cnJJbWdMZWZ0XSA9IGdldFN0eWxlc09mRWxlbWVudDxudW1iZXI+KHRoaXMuaW1hZ2VPcmlnaW4oKS5uYXRpdmVFbGVtZW50LCBbJ29mZnNldFdpZHRoJywgJ29mZnNldEhlaWdodCcsICdzdHlsZS50b3AnLCAnc3R5bGUubGVmdCddKTtcbiAgICBsZXQgW2Nyb3BXaWR0aCwgY3JvcEhlaWdodF0gPSBnZXRTdHlsZXNPZkVsZW1lbnQ8bnVtYmVyPih0aGlzLmNyb3BBcmVhKCkubmF0aXZlRWxlbWVudCwgWydvZmZzZXRXaWR0aCcsICdvZmZzZXRIZWlnaHQnXSk7XG4gICAgY29uc3QgW2Nyb3BUb3AsIGNyb3BMZWZ0XSA9IGdldFN0eWxlc09mRWxlbWVudDxudW1iZXI+KHRoaXMuY3JvcEFyZWEoKS5uYXRpdmVFbGVtZW50LCBbJ3N0eWxlLnRvcCcsICdzdHlsZS5sZWZ0J10pO1xuICAgIGNvbnN0IG1heENyb3BXaWR0aCA9IGN1cnJJbWdMZWZ0ICsgY3VyckltZ1dpZHRoIC0gY3JvcExlZnQ7XG4gICAgY29uc3QgbWF4Q3JvcEhlaWdodCA9IGN1cnJJbWdIZWlnaHQgKyBjdXJySW1nVG9wIC0gY3JvcFRvcDtcbiAgICBjb25zdCByYXRpbyA9IHRoaXMub3JpZ2luV2lkdGgoKSAvIGN1cnJJbWdXaWR0aDtcbiAgICBsZXQgY3JvcFZhbHVlID0gZ2V0KHRoaXMuY3JvcFNpemUsIGNyb3BCeSkgLyByYXRpbztcblxuICAgIGNyb3BWYWx1ZSA9IE1hdGgubWluKGNyb3BWYWx1ZSwgY3JvcEJ5ID09PSAnd2lkdGgnID8gbWF4Q3JvcFdpZHRoIDogbWF4Q3JvcEhlaWdodCk7XG4gICAgY3JvcFZhbHVlID0gTWF0aC5tYXgoMSwgY3JvcFZhbHVlKTtcbiAgICBpZiAodGhpcy5yYXRpb1ZhbHVlKCkpIHtcbiAgICAgIGlmIChjcm9wQnkgPT09ICd3aWR0aCcpIHtcbiAgICAgICAgY3JvcEhlaWdodCA9IGNyb3BWYWx1ZSAvIHRoaXMucmF0aW9WYWx1ZSgpO1xuICAgICAgICBjcm9wSGVpZ2h0ID0gTWF0aC5taW4oY3JvcEhlaWdodCwgbWF4Q3JvcEhlaWdodCk7XG4gICAgICAgIGNyb3BWYWx1ZSA9IGNyb3BIZWlnaHQgKiB0aGlzLnJhdGlvVmFsdWUoKTtcbiAgICAgICAgdGhpcy5jcm9wU2l6ZS51cGRhdGUoY3JvcFNpemUgPT4gKHsgLi4uY3JvcFNpemUsIGhlaWdodDogTWF0aC5yb3VuZChjcm9wSGVpZ2h0ICogcmF0aW8pIH0pKTtcbiAgICAgICAgdGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7Y3JvcEhlaWdodH1weGA7XG4gICAgICB9XG4gICAgICBpZiAoY3JvcEJ5ID09PSAnaGVpZ2h0Jykge1xuICAgICAgICBjcm9wV2lkdGggPSBjcm9wVmFsdWUgKiB0aGlzLnJhdGlvVmFsdWUoKTtcbiAgICAgICAgY3JvcFdpZHRoID0gTWF0aC5taW4oY3JvcFdpZHRoLCBtYXhDcm9wV2lkdGgpO1xuICAgICAgICBjcm9wVmFsdWUgPSBjcm9wV2lkdGggLyB0aGlzLnJhdGlvVmFsdWUoKTtcbiAgICAgICAgdGhpcy5jcm9wU2l6ZS51cGRhdGUoY3JvcFNpemUgPT4gKHsgLi4uY3JvcFNpemUsIHdpZHRoOiBNYXRoLnJvdW5kKGNyb3BXaWR0aCAqIHJhdGlvKSB9KSk7XG4gICAgICAgIHRoaXMuY3JvcEFyZWEoKS5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gYCR7Y3JvcFdpZHRofXB4YDtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jcm9wU2l6ZS51cGRhdGUoY3JvcFNpemUgPT4gKHsgLi4uY3JvcFNpemUsIFtjcm9wQnldOiBNYXRoLnJvdW5kKGNyb3BWYWx1ZSAqIHJhdGlvKSB9KSk7XG4gICAgdGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQuc3R5bGVbY3JvcEJ5XSA9IGAke2Nyb3BWYWx1ZX1weGA7XG4gICAgY29uc3QgaW1hZ2VSZWN0ID0gdGhpcy5pbWFnZUNsaXAoKS5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGNyb3BSZWN0ID0gdGhpcy5jcm9wQXJlYSgpLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjcm9wUmVjdDtcbiAgICBjb25zdCBsZWZ0ID0gY3JvcFJlY3QubGVmdCAtIGltYWdlUmVjdC5sZWZ0O1xuICAgIGNvbnN0IHRvcCA9IGNyb3BSZWN0LnRvcCAtIGltYWdlUmVjdC50b3A7XG4gICAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgd2lkdGg7XG4gICAgY29uc3QgYm90dG9tID0gdG9wICsgaGVpZ2h0O1xuXG4gICAgdGhpcy5pbWFnZUNsaXAoKS5uYXRpdmVFbGVtZW50LnN0eWxlLmNsaXAgPSBgcmVjdCgke3RvcH1weCwgJHtyaWdodH1weCwgJHtib3R0b219cHgsICR7bGVmdH1weClgO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTdHlsZXNFbGVtZW50cyhlbGVtZW50OiBFbGVtZW50UmVmLCBzdHlsZXM6IElTdHlsZXMsIGlzVXBkYXRlUmVjdENsaXBQb3M/OiBib29sZWFuKSB7XG4gICAgaWYgKCFpc05pbChzdHlsZXMudG9wKSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCA9IGAke3N0eWxlcy50b3B9cHhgO1xuICAgIH1cbiAgICBpZiAoIWlzTmlsKHN0eWxlcy5sZWZ0KSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtzdHlsZXMubGVmdH1weGA7XG4gICAgfVxuICAgIGlmICghaXNOaWwoc3R5bGVzLndpZHRoKSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gYCR7c3R5bGVzLndpZHRofXB4YDtcbiAgICB9XG4gICAgaWYgKCFpc05pbChzdHlsZXMuaGVpZ2h0KSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3N0eWxlcy5oZWlnaHR9cHhgO1xuICAgIH1cbiAgICBpZiAoIWlzTmlsKHN0eWxlcy5kaXNwbGF5KSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBzdHlsZXMuZGlzcGxheTtcbiAgICB9XG4gICAgaWYgKCFpc05pbChzdHlsZXMuc3JjKSkge1xuICAgICAgZWxlbWVudC5uYXRpdmVFbGVtZW50LnNyYyA9IHN0eWxlcy5zcmM7XG4gICAgfVxuICAgIGlmICghaXNOaWwoc3R5bGVzLmNsaXApKSB7XG4gICAgICBlbGVtZW50Lm5hdGl2ZUVsZW1lbnQuc3R5bGUuY2xpcCA9IHN0eWxlcy5jbGlwO1xuICAgIH1cbiAgICBpZiAoaXNVcGRhdGVSZWN0Q2xpcFBvcykge1xuICAgICAgdGhpcy51cGRhdGVSZWN0Q2xpcFBvcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub25EZXN0cm95Lm5leHQoKTtcbiAgICB0aGlzLm9uRGVzdHJveS5jb21wbGV0ZSgpO1xuICAgIHRoaXMuZHluYW1pY0NvbXBvbmVudFNlcnZpY2UucmVtb3ZlKHRoaXMucmVzaXplQ29tcG9uZW50UmVmKTtcbiAgICAvLyB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLmZvcndhcmRDb21wb25lbnRSZWYpO1xuICB9XG59XG4iLCI8bGlic191aS1jb21wb25lbnRzLW1vZGFsIFt3aWR0aF09XCInY2FsYygxMDB2dyAtIDQwMHB4KSdcIlxuICBbaGVpZ2h0XT1cIidjYWxjKDEwMHZoIC0gMTAwcHgpJ1wiXG4gIFttaW5XaWR0aF09XCInMTIwMHB4J1wiXG4gIFtoZWFkZXJDb25maWddPVwie2lnbm9yZUhlYWRlclRoZW1lOiB0cnVlLCByZW1vdmVCdXR0b25DbG9zZTogdHJ1ZX1cIlxuICBbYm9keUNvbmZpZ109XCJ7Y2xhc3NJbmNsdWRlOiAnIXAtMCcsIHNjcm9sbE92ZXJsYXlPcHRpb25zOiB7c2Nyb2xsWDogJ2hpZGRlbicsIHNjcm9sbFk6ICdoaWRkZW4nfX1cIlxuICBbZm9vdGVyQ29uZmlnXT1cIntoaWRkZW46IHRydWV9XCJcbiAgW3pJbmRleF09XCJ6SW5kZXgoKVwiXG4gIFtidXR0b25zRm9vdGVyXT1cIltdXCJcbiAgW21vZGVdPVwiJ2NlbnRlcidcIj5cbiAgPGRpdiBjbGFzcz1cImxpYnMtdWktbW9kYWwtaGVhZGVyLWN1c3RvbSB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuXCI+XG4gICAgPGRpdiBjbGFzcz1cInctZnVsbCByZWxhdGl2ZSBteC1bMjRweF0gaC1bMTZweF1cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IHctZnVsbCBsaWJzLXVpLWZvbnQtaDRzIGFic29sdXRlXCI+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbdHlwZV09XCIndGV4dCdcIlxuICAgICAgICAgIFtjb25maWddPVwie3pJbmRleDogekluZGV4KCl9XCI+XG4gICAgICAgICAge3sgJ2kxOG5fZWRpdF9maWxlX25hbWUnIHwgdHJhbnNsYXRlOntmaWxlX25hbWU6IG5hbWVGaWxlKCl9IH19XG4gICAgICAgIDwvbGlic191aS1jb21wb25lbnRzLXBvcG92ZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgIEBpZiAobW9kZVNob3dCdXR0b24oKSA9PT0gJ3NhdmUtZmlsZScpIHtcbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBbdHlwZV09XCInYnV0dG9uLXRoaXJkJ1wiXG4gICAgICAgICAgW2xhYmVsXT1cIidpMThuX2NhbmNlbCdcIlxuICAgICAgICAgIFtkaXNhYmxlXT1cImxvYWRpbmcoKSB8fCBsb2FkaW5nSW1hZ2UoKVwiXG4gICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCIncHktWzZweF0gcHgtWzEycHhdIG1yLVsxNnB4XSdcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyQ2xvc2UoJGV2ZW50KVwiIC8+XG5cbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBjbGFzcz1cIm1yLVsyNHB4XVwiXG4gICAgICAgICAgW2xhYmVsXT1cIidpMThuX3NhdmUnXCJcbiAgICAgICAgICBbZGlzYWJsZV09XCJsb2FkaW5nKCkgfHwgbG9hZGluZ0ltYWdlKClcIlxuICAgICAgICAgIFtjbGFzc0luY2x1ZGVdPVwiJ3B5LVs2cHhdIHB4LVsxMnB4XSdcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyU2F2ZUZpbGUoJGV2ZW50LCdzYXZlLWZpbGUnKVwiIC8+XG4gICAgICB9XG4gICAgICBAZWxzZSB7XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1idXR0b24gW2xhYmVsXT1cIidpMThuX3NhdmVfdG9fbmV3X2ZpbGUnXCJcbiAgICAgICAgICBbdHlwZV09XCInYnV0dG9uLW91dGxpbmUnXCJcbiAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cIidteC1bMTZweF0gcHktWzZweF0gcHgtWzEycHhdJ1wiXG4gICAgICAgICAgW2Rpc2FibGVdPVwibG9hZGluZygpIHx8IGxvYWRpbmdJbWFnZSgpIHx8ICFjaGFuZ2VkKClcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyU2F2ZUZpbGUoJGV2ZW50LCdzYXZlLWFwaS1hcy1uZXctZmlsZScpXCIgLz5cbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBbdHlwZV09XCInYnV0dG9uLXNlY29uZGFyeSdcIlxuICAgICAgICAgIFtsYWJlbF09XCInaTE4bl9zYXZlJ1wiXG4gICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCIncHktWzZweF0gcHgtWzEycHhdJ1wiXG4gICAgICAgICAgW2Rpc2FibGVdPVwibG9hZGluZygpIHx8IGxvYWRpbmdJbWFnZSgpIHx8ICFjaGFuZ2VkKClcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyU2F2ZUZpbGUoJGV2ZW50LCdzYXZlLWFwaScpXCIgLz5cbiAgICAgICAgPGRpdiBjbGFzcz1cImgtWzEycHhdIGxpYnMtdWktYm9yZGVyLWxlZnQtZ2VuZXJhbCBteC1bMTZweF1cIj48L2Rpdj5cbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBjbGFzcz1cIm1yLVsyNHB4XVwiXG4gICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCIncC1bNnB4XSdcIlxuICAgICAgICAgIFt0eXBlXT1cIididXR0b24tdGhpcmQtaG92ZXItZGFuZ2VyJ1wiXG4gICAgICAgICAgW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgICBbZGlzYWJsZV09XCJsb2FkaW5nKClcIlxuICAgICAgICAgIFtwb3BvdmVyXT1cIntjb25maWc6IHtjb250ZW50OiAnaTE4bl9leGl0X2VkaXRfbW9kZScsIHpJbmRleDogekluZGV4KCl9fVwiXG4gICAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1jbG9zZSdcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyQ2xvc2UoJGV2ZW50KVwiIC8+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwibGlicy11aS1tb2RhbC1ib2R5LWN1c3RvbSBoLWZ1bGwgdy1mdWxsIGZsZXhcIj5cbiAgICA8ZGl2ICNpbWFnZUVkaXRvckNvbnRhaW5lclxuICAgICAgY2xhc3M9XCJyZWxhdGl2ZSB3LWZ1bGwgaC1mdWxsIGJnLVsjZTZlN2VhXSBib3JkZXItcmFkaXVzLWJvdHRvbS1sZWZ0LThweCBwLVszMnB4XVwiPlxuICAgICAgQGlmIChsb2FkaW5nSW1hZ2UoKSkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgaC1mdWxsIHctZnVsbCBiZy1bI2U2ZTdlYV0gdG9wLTAgbGVmdC0wIHotWzVdXCI+XG4gICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1zcGlubmVyIFtzaXplXT1cIidtZWRpdW0nXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgaC1bMzJweF0gdy1bY2FsYygxMDAlLTY0cHgpXSBiZy1bI2U2ZTdlYWI4XSB0b3AtMCBsZWZ0LVszMnB4XSB6LVsxXVwiPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgdy1bMzJweF0gaC1mdWxsIGJnLVsjZTZlN2VhYjhdIGxlZnQtMCB0b3AtMCB6LVsxXSByb3VuZGVkLWJsLVs4cHhdXCI+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhYnNvbHV0ZSB3LVszMnB4XSBoLWZ1bGwgYmctWyNlNmU3ZWFiOF0gcmlnaHQtMCB0b3AtMCB6LVsxXVwiPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgaC1bMzJweF0gdy1bY2FsYygxMDAlLTY0cHgpXSBiZy1bI2U2ZTdlYWI4XSBib3R0b20tMCBsZWZ0LVszMnB4XSB6LVsxXVwiPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICNpbWFnZUNvbnRhaW5lclxuICAgICAgICBjbGFzcz1cInJlbGF0aXZlIHctZnVsbCBoLWZ1bGwgcm91bmRlZC1ibC1bOHB4XSBtaW4taC0wXCI+XG4gICAgICAgIDxkaXYgI2NpcmNsZVRMXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVs1XVwiXG4gICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCIhZHJhZ0dyaWRDcm9wKClcIlxuICAgICAgICAgIFtjbGFzcy5mbGV4XT1cImRyYWdHcmlkQ3JvcCgpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwic3ZnQ2lyY2xlXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgI2NpcmNsZVRSXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVs1XVwiXG4gICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCIhZHJhZ0dyaWRDcm9wKClcIlxuICAgICAgICAgIFtjbGFzcy5mbGV4XT1cImRyYWdHcmlkQ3JvcCgpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwic3ZnQ2lyY2xlXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgI2NpcmNsZUJMXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVs1XVwiXG4gICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCIhZHJhZ0dyaWRDcm9wKClcIlxuICAgICAgICAgIFtjbGFzcy5mbGV4XT1cImRyYWdHcmlkQ3JvcCgpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwic3ZnQ2lyY2xlXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgI2NpcmNsZUJSXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVs1XVwiXG4gICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCIhZHJhZ0dyaWRDcm9wKClcIlxuICAgICAgICAgIFtjbGFzcy5mbGV4XT1cImRyYWdHcmlkQ3JvcCgpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwic3ZnQ2lyY2xlXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxpbWcgI2ltYWdlT3JpZ2luXG4gICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSBib3JkZXItWzRweF0gYm9yZGVyLVsjOGU2MWVlXSByb3VuZGVkLVs0cHhdIHctMCBoLTBcIlxuICAgICAgICAgIGxvYWRpbmc9XCJsYXp5XCJcbiAgICAgICAgICBbc3JjXT1cImltZ1NyYygpXCJcbiAgICAgICAgICAobG9hZCk9XCJoYW5kbGVySW1hZ2VMb2FkZWQoKVwiXG4gICAgICAgICAgKGVycm9yKT1cImhhbmRsZXJJbWFnZUVycm9yKCRldmVudClcIiAvPlxuICAgICAgICA8aW1nICNpbWFnZUNsaXBcbiAgICAgICAgICBjbGFzcz1cImFic29sdXRlIHotWzFdIHctMCBoLTBcIlxuICAgICAgICAgIGxvYWRpbmc9XCJsYXp5XCJcbiAgICAgICAgICBbc3JjXT1cImltZ1NyYygpXCJcbiAgICAgICAgICAoZXJyb3IpPVwiaGFuZGxlckltYWdlRXJyb3IoJGV2ZW50KVwiIC8+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhYnNvbHV0ZSB0b3AtMCBsZWZ0LTAgcmlnaHQtMCBib3R0b20tMCBiZy1bI2U2ZTdlYWI4XVwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAjY3JvcEFyZWFcbiAgICAgICAgICBjbGFzcz1cImFic29sdXRlIHotWzJdIGJvcmRlci1bNHB4XSBib3JkZXItWyM4ZTYxZWVdIHJvdW5kZWQtWzRweF1cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgdy1mdWxsIGgtZnVsbFwiPlxuICAgICAgICAgICAgPGRpdiAjY3JvcFRMXG4gICAgICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgei1bMl0gbGVmdC1bLTE4cHhdIHRvcC1bLTE3cHhdIGxpYnMtdWktaW1hZ2UtZWRpdG9yLWVkaXQtY3Vyc29yLW53c2UtcmVzaXplXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdUZW1wbGF0ZU91dGxldD1cInN2Z0Fycm93XCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAjY3JvcEJMXG4gICAgICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgei1bMl0gbGVmdC1bLTE3cHhdIGJvdHRvbS1bLTE4cHhdIGxpYnMtdWktaW1hZ2UtZWRpdG9yLWVkaXQtY3Vyc29yLW5lc3ctcmVzaXplIHJvdGF0ZS1bMjcwZGVnXVwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdmdBcnJvd1wiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgI2Nyb3BUUlxuICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIHotWzJdIHJpZ2h0LVstMTdweF0gdG9wLVstMTdweF0gbGlicy11aS1pbWFnZS1lZGl0b3ItZWRpdC1jdXJzb3ItbmVzdy1yZXNpemUgcm90YXRlLVs5MGRlZ11cIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwic3ZnQXJyb3dcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICNjcm9wQlJcbiAgICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVsyXSByaWdodC1bLTE4cHhdIGJvdHRvbS1bLTE3cHhdIGxpYnMtdWktaW1hZ2UtZWRpdG9yLWVkaXQtY3Vyc29yLW53c2UtcmVzaXplIHJvdGF0ZS1bMTgwZGVnXVwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdmdBcnJvd1wiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgI2Nyb3BMaW5lVkxcbiAgICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVsxXSB3LVsxMnB4XSBsZWZ0LVstNnB4XSB0b3AtMCBib3R0b20tMCBsaWJzLXVpLWltYWdlLWVkaXRvci1lZGl0LWN1cnNvci1ldy1yZXNpemVcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAjY3JvcExpbmVWUlxuICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIHotWzFdIHctWzEycHhdIHJpZ2h0LVstNnB4XSB0b3AtMCBib3R0b20tMCBsaWJzLXVpLWltYWdlLWVkaXRvci1lZGl0LWN1cnNvci1ldy1yZXNpemVcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAjY3JvcExpbmVIVFxuICAgICAgICAgICAgICBjbGFzcz1cImFic29sdXRlIHotWzFdIGgtWzEycHhdIGxlZnQtMCB0b3AtWy02cHhdIHJpZ2h0LTAgbGlicy11aS1pbWFnZS1lZGl0b3ItZWRpdC1jdXJzb3ItbnMtcmVzaXplXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgI2Nyb3BMaW5lSEJcbiAgICAgICAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB6LVsxXSBoLVsxMnB4XSBsZWZ0LTAgcmlnaHQtMCBib3R0b20tWy02cHhdIGxpYnMtdWktaW1hZ2UtZWRpdG9yLWVkaXQtY3Vyc29yLW5zLXJlc2l6ZVwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgei1bMV0gaC1bMXB4XSB0b3AtMCBsZWZ0LTAgcmlnaHQtMFwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgei1bMV0gaC1bMXB4XSBib3R0b20tMCBsZWZ0LTAgcmlnaHQtMFwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgei1bMV0gdy1bMXB4XSB0b3AtMCBsZWZ0LTAgYm90dG9tLTBcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFic29sdXRlIHotWzFdIHctWzFweF0gdG9wLTAgcmlnaHQtMCBib3R0b20tMFwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgei1bMV0gaC1bMnB4XSB0b3AtWzMzcHhdIGxlZnQtMCByaWdodC0wXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhYnNvbHV0ZSB6LVsxXSBoLVsycHhdIHRvcC1bNjZweF0gbGVmdC0wIHJpZ2h0LTBcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFic29sdXRlIHotWzFdIHctWzJweF0gdG9wLTAgYm90dG9tLTAgbGVmdC1bMzNweF1cIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFic29sdXRlIHotWzFdIHctWzJweF0gdG9wLTAgYm90dG9tLTAgbGVmdC1bNjZweF1cIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgQGlmIChsb2FkaW5nKCkpIHtcbiAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1zcGlubmVyIFtzaXplXT1cIidtZWRpdW0nXCIgLz5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidy1bMzIwcHhdIHNocmluay0wIHAtWzE2cHhdIGJnLVsjZmZmZmZmXSByb3VuZGVkLWJyLVs4cHhdIHotWzJdXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIG1iLVsxNnB4XVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGlicy11aS1mb250LWg0bVwiPnt7ICdpMThuX2N1dHRpbmdfcmF0aW8nIHwgdHJhbnNsYXRlIH19PC9kaXY+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYnV0dG9ucy1idXR0b24gW2ljb25Pbmx5VHlwZV09XCJ0cnVlXCJcbiAgICAgICAgICBbdHlwZV09XCInYnV0dG9uLXRoaXJkJ1wiXG4gICAgICAgICAgW2NsYXNzSWNvbkxlZnRdPVwiJ2xpYnMtdWktaWNvbi1yZWZyZXNoJ1wiXG4gICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCIncC1bNnB4XSBtci1bOHB4XSdcIlxuICAgICAgICAgIFtwb3BvdmVyXT1cIntjb25maWc6IHtjb250ZW50OiAnaTE4bl9yZXN0b3JlX3RoZV9vcmlnaW5hbF9zdGF0ZScsIHpJbmRleDogekluZGV4KCl9fVwiXG4gICAgICAgICAgW2Rpc2FibGVdPVwibG9hZGluZygpIHx8IGxvYWRpbmdJbWFnZSgpIHx8ICFjaGFuZ2VkKClcIlxuICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyUmVzdG9yZUltYWdlKCRldmVudClcIiAvPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWItWzE2cHhdIGxpYnMtdWktaW1hZ2UtZWRpdG9yLWVkaXQtZGlzcGxheS1ncmlkLWdhcC0xNlwiPlxuICAgICAgICBAZm9yIChpdGVtIG9mIGNyb3BSYXRpb0l0ZW1zKCk7IHRyYWNrIGl0ZW0ua2V5KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgIFtzaXplQnV0dG9uXT1cIidsYXJnZSdcIlxuICAgICAgICAgICAgICBbZGlzYWJsZV09XCJsb2FkaW5nKCkgfHwgbG9hZGluZ0ltYWdlKCkgfHwgcmVxdWlyZWRDcm9wRm9sbG93UmF0aW8oKVwiXG4gICAgICAgICAgICAgIFt0eXBlXT1cIididXR0b24tb3V0bGluZSdcIlxuICAgICAgICAgICAgICBbY2xhc3NJY29uTGVmdF09XCJpdGVtLmljb24rJyAhdGV4dC1bMjBweF0nXCJcbiAgICAgICAgICAgICAgKG91dENsaWNrKT1cImhhbmRsZXJTZWxlY3RDcm9wUmF0aW9JdGVtKCRldmVudCwgaXRlbS5rZXkpXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWJzLXVpLWZvbnQtaDZyIHRleHQtWyM2YTczODNdIG10LVs0cHhdXCI+XG4gICAgICAgICAgICAgIHt7IChpdGVtLmtleSA9PT0gJ2ZyZWUnID8gJ2kxOG5fY3VzdG9tJyA6IGl0ZW0ua2V5KSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1iLVsxNnB4XSBmbGV4XCI+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXZhbGlkIGNsYXNzPVwibXItWzE2cHhdXCJcbiAgICAgICAgICBbZGF0YVR5cGVdPVwiJ2ludCdcIlxuICAgICAgICAgIFtsYWJlbENvbmZpZ109XCJ7bGFiZWxMZWZ0OiAnaTE4bl93aWR0aCcsIGNsYXNzSW5jbHVkZTogJ21iLVs0cHhdJywgbGFiZWxMZWZ0Q2xhc3M6ICdsaWJzLXVpLWZvbnQtaDdyJ31cIlxuICAgICAgICAgIFtmaWVsZE5hbWVCaW5kXT1cIid3aWR0aCdcIlxuICAgICAgICAgIFsoaXRlbSldPVwiY3JvcFNpemVcIlxuICAgICAgICAgIFt1bml0c1JpZ2h0XT1cIlt7aWQ6ICdweCcsIGxhYmVsOiAncHgnfV1cIlxuICAgICAgICAgIFtrZXlTZWxlY3RlZFVuaXRSaWdodF09XCIncHgnXCJcbiAgICAgICAgICBbdmFsdWVVcERvd25OdW1iZXJdPVwiMVwiXG4gICAgICAgICAgW21heFZhbHVlTnVtYmVyXT1cIm9yaWdpbldpZHRoKClcIlxuICAgICAgICAgIFtkaXNhYmxlXT1cImxvYWRpbmcoKSB8fCBsb2FkaW5nSW1hZ2UoKVwiXG4gICAgICAgICAgKG91dFZhbHVlQ2hhbmdlKT1cImhhbmRsZXJDcm9wV2lkdGgoKVwiIC8+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXZhbGlkIFtkYXRhVHlwZV09XCInaW50J1wiXG4gICAgICAgICAgW2xhYmVsQ29uZmlnXT1cIntsYWJlbExlZnQ6ICdpMThuX2xlbmd0aCcsIGNsYXNzSW5jbHVkZTogJ21iLVs0cHhdJywgbGFiZWxMZWZ0Q2xhc3M6ICdsaWJzLXVpLWZvbnQtaDdyJ31cIlxuICAgICAgICAgIFtmaWVsZE5hbWVCaW5kXT1cIidoZWlnaHQnXCJcbiAgICAgICAgICBbKGl0ZW0pXT1cImNyb3BTaXplXCJcbiAgICAgICAgICBbdW5pdHNSaWdodF09XCJbe2lkOiAncHgnLCBsYWJlbDogJ3B4J31dXCJcbiAgICAgICAgICBba2V5U2VsZWN0ZWRVbml0UmlnaHRdPVwiJ3B4J1wiXG4gICAgICAgICAgW3ZhbHVlVXBEb3duTnVtYmVyXT1cIjFcIlxuICAgICAgICAgIFttYXhWYWx1ZU51bWJlcl09XCJvcmlnaW5IZWlnaHQoKVwiXG4gICAgICAgICAgW2Rpc2FibGVdPVwibG9hZGluZygpIHx8IGxvYWRpbmdJbWFnZSgpXCJcbiAgICAgICAgICAob3V0VmFsdWVDaGFuZ2UpPVwiaGFuZGxlckNyb3BIZWlnaHQoKVwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJsaWJzLXVpLWZvbnQtaDRtIG1iLVsxNnB4XVwiPnt7ICdpMThuX3JvdGF0ZV9waG90b3MnIHwgdHJhbnNsYXRlIH19PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleCBsaWJzLXVpLWltYWdlLWVkaXRvci1lZGl0LWRpc3BsYXktZ3JpZC1nYXAtMTZcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBbaWNvbk9ubHlUeXBlXT1cInRydWVcIlxuICAgICAgICAgICAgW3NpemVCdXR0b25dPVwiJ2xhcmdlJ1wiXG4gICAgICAgICAgICBbZGlzYWJsZV09XCJsb2FkaW5nKCkgfHwgbG9hZGluZ0ltYWdlKClcIlxuICAgICAgICAgICAgW3R5cGVdPVwiJ2J1dHRvbi1vdXRsaW5lJ1wiXG4gICAgICAgICAgICBbY2xhc3NJY29uTGVmdF09XCInbGlicy11aS1pY29uLXJvdGF0ZS1pbWFnZS1vdXRsaW5lICF0ZXh0LVsyMHB4XSdcIlxuICAgICAgICAgICAgKG91dENsaWNrKT1cImhhbmRsZXJSb3RhdGVJbWFnZSgkZXZlbnQpXCIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlicy11aS1mb250LWg2ciB0ZXh0LVsjNmE3MzgzXSBtdC1bNHB4XVwiPlxuICAgICAgICAgICAge3sgJ2kxOG5fcm90YXRlX25pbmV0eV9kZWdyZWVzJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbc2l6ZUJ1dHRvbl09XCInbGFyZ2UnXCJcbiAgICAgICAgICAgIFtkaXNhYmxlXT1cImxvYWRpbmcoKSB8fCBsb2FkaW5nSW1hZ2UoKVwiXG4gICAgICAgICAgICBbdHlwZV09XCInYnV0dG9uLW91dGxpbmUnXCJcbiAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cIidsaWJzLXVpLWljb24tZmxpcC12ZXJ0aWNhbCAhdGV4dC1bMjBweF0nXCJcbiAgICAgICAgICAgIChvdXRDbGljayk9XCJoYW5kbGVyRmxpcEltYWdlKCRldmVudCwgJ3ZlcnRpY2FsJylcIiAvPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWJzLXVpLWZvbnQtaDZyIHRleHQtWyM2YTczODNdIG10LVs0cHhdXCI+XG4gICAgICAgICAgICB7eyAnaTE4bl92ZXJ0aWNhbF9mbGlwJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbc2l6ZUJ1dHRvbl09XCInbGFyZ2UnXCJcbiAgICAgICAgICAgIFtkaXNhYmxlXT1cImxvYWRpbmcoKSB8fCBsb2FkaW5nSW1hZ2UoKVwiXG4gICAgICAgICAgICBbdHlwZV09XCInYnV0dG9uLW91dGxpbmUnXCJcbiAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cIidsaWJzLXVpLWljb24tZmxpcC1ob3Jpem9udGFsICF0ZXh0LVsyMHB4XSdcIlxuICAgICAgICAgICAgKG91dENsaWNrKT1cImhhbmRsZXJGbGlwSW1hZ2UoJGV2ZW50LCAnaG9yaXpvbnRhbCcpXCIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlicy11aS1mb250LWg2ciB0ZXh0LVsjNmE3MzgzXSBtdC1bNHB4XVwiPlxuICAgICAgICAgICAge3sgJ2kxOG5faG9yaXpvbnRhbF9mbGlwJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uIFtpY29uT25seVR5cGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbc2l6ZUJ1dHRvbl09XCInbGFyZ2UnXCJcbiAgICAgICAgICAgIFtkaXNhYmxlXT1cImxvYWRpbmcoKSB8fCBsb2FkaW5nSW1hZ2UoKVwiXG4gICAgICAgICAgICBbdHlwZV09XCInYnV0dG9uLW91dGxpbmUnXCJcbiAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cIidsaWJzLXVpLWljb24tc2NhbGUgIXRleHQtWzIwcHhdJ1wiXG4gICAgICAgICAgICAob3V0Q2xpY2spPVwiaGFuZGxlclJlc2l6ZSgkZXZlbnQpXCIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlicy11aS1mb250LWg2ciB0ZXh0LVsjNmE3MzgzXSBtdC1bNHB4XVwiPlxuICAgICAgICAgICAge3sgJ2kxOG5fcmVzaXplJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbGlic191aS1jb21wb25lbnRzLW1vZGFsPlxuXG48bmctdGVtcGxhdGUgI3N2Z0Fycm93PlxuICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgIHdpZHRoPVwiNDBcIlxuICAgIGhlaWdodD1cIjQwXCJcbiAgICB2aWV3Qm94PVwiMCAwIDQwIDQwXCJcbiAgICBmaWxsPVwibm9uZVwiPlxuICAgIDxwYXRoIGQ9XCJNMzMuNjk4NyAxNC42OTY5TDE4LjMzMDkgMTQuNjk2OUMxNi41MTYgMTQuNjk2OSAxNS4wMzExIDE2LjE4MTggMTUuMDMxMSAxNy45OTY3TDE1LjAzMTEgMzMuMzY0NVwiXG4gICAgICBzdHJva2U9XCJ3aGl0ZVwiXG4gICAgICBzdHJva2Utd2lkdGg9XCI1LjgzMzMzXCJcbiAgICAgIHN0cm9rZS1taXRlcmxpbWl0PVwiMTBcIlxuICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gIDwvc3ZnPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNzdmdDaXJjbGU+XG4gIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgd2lkdGg9XCIxNVwiXG4gICAgaGVpZ2h0PVwiMTVcIlxuICAgIHZpZXdCb3g9XCIwIDAgMTUgMTVcIlxuICAgIGZpbGw9XCJub25lXCI+XG4gICAgPGNpcmNsZSBjeD1cIjcuNVwiXG4gICAgICBjeT1cIjcuNVwiXG4gICAgICByPVwiNy41XCJcbiAgICAgIGZpbGw9XCJ3aGl0ZVwiIC8+XG4gIDwvc3ZnPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|