keevo-components 1.8.340 → 1.8.341
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/esm2022/lib/api/services/image.cutter.service.mjs +564 -0
- package/esm2022/lib/components/kv-avatar/kv-avatar.component.mjs +54 -231
- package/esm2022/lib/components/kv-avatar/kv-avatar.module.mjs +7 -3
- package/esm2022/lib/components/kv-home-card/kv-home-card.module.mjs +1 -1
- package/esm2022/lib/components/kv-image-upload/kv-image-upload.component.mjs +46 -16
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/keevo-components.mjs +816 -413
- package/fesm2022/keevo-components.mjs.map +1 -1
- package/lib/api/services/image.cutter.service.d.ts +15 -0
- package/lib/components/kv-avatar/kv-avatar.component.d.ts +12 -37
- package/lib/components/kv-avatar/kv-avatar.module.d.ts +2 -1
- package/lib/components/kv-image-upload/kv-image-upload.component.d.ts +10 -3
- package/lib/components/kv-table/kv-table.component.d.ts +1 -1
- package/lib/components/kv-table-expandable/kv-table-expandable.component.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
import { Component, computed, HostListener, Injectable, signal, ViewChild } from '@angular/core';
|
|
2
|
+
import { DialogModule } from 'primeng/dialog';
|
|
3
|
+
// ? Componente de modal usado no cutter
|
|
4
|
+
import { SliderModule } from 'primeng/slider';
|
|
5
|
+
import { CommonModule } from '@angular/common';
|
|
6
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
7
|
+
import { ButtonModule } from 'primeng/button';
|
|
8
|
+
import { FileUploadModule } from 'primeng/fileupload';
|
|
9
|
+
import { KvLabelModule } from '../../components/kv-label/kv-label.module';
|
|
10
|
+
import { FormService } from './form.service';
|
|
11
|
+
import { KvModalModule } from '../../components/kv-modal/kv-modal.module';
|
|
12
|
+
import { KvButtonModule } from '../../components/kv-button/kv-button.module';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "primeng/dynamicdialog";
|
|
15
|
+
import * as i2 from "primeng/slider";
|
|
16
|
+
import * as i3 from "@angular/forms";
|
|
17
|
+
import * as i4 from "../../components/kv-button/kv-button.component";
|
|
18
|
+
import * as i5 from "../../components/kv-label/kv-label.component";
|
|
19
|
+
export class ImageCutterService {
|
|
20
|
+
constructor(dialogservice) {
|
|
21
|
+
this.dialogservice = dialogservice;
|
|
22
|
+
}
|
|
23
|
+
cut(imageBase64, width, height, indCircle = false) {
|
|
24
|
+
const cutConfig = { imageBase64, width, height, indCircle };
|
|
25
|
+
this.abrirModal(cutConfig);
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
window.addEventListener('cropImage', (event) => {
|
|
28
|
+
if (event.detail.status == true) {
|
|
29
|
+
resolve(event.detail.result);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
reject('Operacao cancelada.');
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
abrirModal(cutConfig) {
|
|
38
|
+
const params = {
|
|
39
|
+
closable: true,
|
|
40
|
+
maximizable: false,
|
|
41
|
+
popup: true,
|
|
42
|
+
width: '75vw',
|
|
43
|
+
header: `Cortar`,
|
|
44
|
+
id: { imagem: cutConfig.imageBase64, width: cutConfig.width, height: cutConfig.height, indCircle: cutConfig.indCircle },
|
|
45
|
+
styleClass: 'modal'
|
|
46
|
+
};
|
|
47
|
+
const dialogRef = FormService.openDialog(this.dialogservice, SimpleComponent, () => { }, params);
|
|
48
|
+
}
|
|
49
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: ImageCutterService, deps: [{ token: i1.DialogService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
50
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: ImageCutterService, providedIn: 'root' }); }
|
|
51
|
+
}
|
|
52
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: ImageCutterService, decorators: [{
|
|
53
|
+
type: Injectable,
|
|
54
|
+
args: [{
|
|
55
|
+
providedIn: 'root'
|
|
56
|
+
}]
|
|
57
|
+
}], ctorParameters: () => [{ type: i1.DialogService }] });
|
|
58
|
+
class SimpleComponent {
|
|
59
|
+
constructor(dynamicDialogRef, dialogService) {
|
|
60
|
+
this.dynamicDialogRef = dynamicDialogRef;
|
|
61
|
+
this.dialogService = dialogService;
|
|
62
|
+
// ? Variavies que recebem os valores do dialog
|
|
63
|
+
this._variaviesDialog = signal(null);
|
|
64
|
+
//? Referências para o contexto e canvas
|
|
65
|
+
this.canvas = signal(null);
|
|
66
|
+
this.ctx = signal(null);
|
|
67
|
+
this._Image = signal(new Image());
|
|
68
|
+
//? Coordenadas iniciais e finais do desenho
|
|
69
|
+
this.startX = 0;
|
|
70
|
+
this.startY = 0;
|
|
71
|
+
//? Fator de escala da imagem e zoom
|
|
72
|
+
this.scaleFactorReadOnly = computed(() => {
|
|
73
|
+
return Math.min(this.scaleFactor(), 3);
|
|
74
|
+
});
|
|
75
|
+
this.scaleFactor = signal(null);
|
|
76
|
+
this.scaleFactorModel = 0;
|
|
77
|
+
this.imageX = 0;
|
|
78
|
+
this.imageY = 0;
|
|
79
|
+
//#region Propriedades computadas de tamanho do canvas e da imagem
|
|
80
|
+
//? Largura e altura do canvas baseado na tamanho da tela
|
|
81
|
+
this.canvasWidth = computed(() => this.widthTela() * 0.5);
|
|
82
|
+
this.canvasHeight = computed(() => this.heigthTela() * 0.5);
|
|
83
|
+
//? Largura e altura da área de corte
|
|
84
|
+
this.cutWidth = computed(() => {
|
|
85
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
86
|
+
return this.radius() * 2;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const canvasWidth = this.canvasWidth();
|
|
90
|
+
const maxWidth = canvasWidth * 0.8;
|
|
91
|
+
const proportionalHeight = maxWidth * this.proporcaoImagem();
|
|
92
|
+
return proportionalHeight > this.canvasHeight() * 0.8 ? this.canvasHeight() * 0.8 / this.proporcaoImagem() : maxWidth;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
this.cutHeight = computed(() => {
|
|
96
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
97
|
+
return this.radius() * 2;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const canvasHeight = this.canvasHeight();
|
|
101
|
+
const maxHeight = canvasHeight * 0.8;
|
|
102
|
+
const proportionalWidth = maxHeight / this.proporcaoImagem();
|
|
103
|
+
return proportionalWidth > this.canvasWidth() * 0.8 ? this.canvasWidth() * 0.8 * this.proporcaoImagem() : maxHeight;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
//? Largura e altura da imagem no canvas (baseado na escala) - tamanho real da imagem
|
|
107
|
+
this.canvaImageWidth = computed(() => {
|
|
108
|
+
return this._Image().width * this.scaleFactorReadOnly();
|
|
109
|
+
});
|
|
110
|
+
this.canvaImageHeight = computed(() => {
|
|
111
|
+
return this._Image().height * this.scaleFactorReadOnly();
|
|
112
|
+
});
|
|
113
|
+
this.proporcaoImagem = computed(() => {
|
|
114
|
+
return this._variaviesDialog()?.height / this._variaviesDialog()?.width;
|
|
115
|
+
});
|
|
116
|
+
this.radius = computed(() => {
|
|
117
|
+
const minSize = Math.min(this.canvasHeight() * 0.8, this.canvasWidth() * 0.8);
|
|
118
|
+
return minSize / 2;
|
|
119
|
+
});
|
|
120
|
+
//#endregion
|
|
121
|
+
// #region Limites de movimentação da imagem
|
|
122
|
+
//? Limites de movimentação da imagem
|
|
123
|
+
this.indCircle = computed(() => {
|
|
124
|
+
return this._variaviesDialog()?.indCircle;
|
|
125
|
+
});
|
|
126
|
+
this.xMin = computed(() => {
|
|
127
|
+
return !this._variaviesDialog()?.indCircle ? (this.canvasWidth() - this.cutWidth()) / 2 : (this.canvasWidth() - (this.radius() * 2)) / 2;
|
|
128
|
+
});
|
|
129
|
+
this.yMin = computed(() => {
|
|
130
|
+
return !this._variaviesDialog()?.indCircle ? (this.canvasHeight() - this.cutHeight()) / 2 : (this.canvasHeight() - (this.radius() * 2)) / 2;
|
|
131
|
+
});
|
|
132
|
+
this.xMax = computed(() => {
|
|
133
|
+
return !this._variaviesDialog()?.indCircle ? -(this.canvaImageWidth() - (this.xMin()) - this.cutWidth()) : -(this.canvaImageWidth() - (this.xMin()) - (this.radius() * 2));
|
|
134
|
+
});
|
|
135
|
+
this.yMax = computed(() => {
|
|
136
|
+
return !this._variaviesDialog()?.indCircle ? -(this.canvaImageHeight() - (this.yMin()) - this.cutHeight()) : -(this.canvaImageHeight() - (this.yMin()) - (this.radius() * 2));
|
|
137
|
+
});
|
|
138
|
+
// #endregion
|
|
139
|
+
//? Proporção da imagem
|
|
140
|
+
this.widthTela = signal(0);
|
|
141
|
+
this.heigthTela = signal(0);
|
|
142
|
+
this.atualizaTamanhoTela();
|
|
143
|
+
}
|
|
144
|
+
setScaleFactorModel(valor) {
|
|
145
|
+
this.scaleFactorModel = valor;
|
|
146
|
+
this.scaleFactor.set(this.scaleFactorModel);
|
|
147
|
+
}
|
|
148
|
+
onWindowResize() {
|
|
149
|
+
this.atualizaTamanhoTela();
|
|
150
|
+
this.updateCanvasSize();
|
|
151
|
+
this.atualizaCutBorder();
|
|
152
|
+
}
|
|
153
|
+
atualizaTamanhoTela() {
|
|
154
|
+
this.widthTela.set(window.innerWidth);
|
|
155
|
+
this.heigthTela.set(window.innerHeight);
|
|
156
|
+
}
|
|
157
|
+
ngAfterViewInit() {
|
|
158
|
+
this.recuperarVariaviesDialog();
|
|
159
|
+
this.inciarReferencias();
|
|
160
|
+
this.iniciarCanvas();
|
|
161
|
+
}
|
|
162
|
+
inciarReferencias() {
|
|
163
|
+
this.canvas.set(this.cropCanvas.nativeElement);
|
|
164
|
+
this.ctx.set(this.canvas().getContext('2d'));
|
|
165
|
+
this._Image().src = this._variaviesDialog()?.imagem;
|
|
166
|
+
}
|
|
167
|
+
iniciarCanvas() {
|
|
168
|
+
this._Image().onload = () => {
|
|
169
|
+
//? Define o tamanho do canvas
|
|
170
|
+
this.canvas().height = this.canvasHeight();
|
|
171
|
+
this.canvas().width = this.canvasWidth();
|
|
172
|
+
this.ajustarZommEPosicaoInicial();
|
|
173
|
+
this.initializeImageMove(this.canvas(), this.ctx(), this._Image());
|
|
174
|
+
this.initializeMouseWheel(this.canvas(), this.ctx(), this._Image());
|
|
175
|
+
this.redrawCanvas(this.ctx(), this._Image());
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
ajustarZommEPosicaoInicial() {
|
|
179
|
+
const cutWidth = this.cutWidth();
|
|
180
|
+
const cutHeight = this.cutHeight();
|
|
181
|
+
const imageWidth = this._Image().width;
|
|
182
|
+
const imageHeight = this._Image().height;
|
|
183
|
+
//? Ajusta possição e zoom inicial
|
|
184
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
185
|
+
const scaleFactor = (this.radius() * 2) / Math.min(imageWidth, imageHeight);
|
|
186
|
+
this.setScaleFactorModel(scaleFactor);
|
|
187
|
+
this.scaleFactor.set(scaleFactor);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const scaleFactor = this.cutHeight() === this.cutWidth()
|
|
191
|
+
? this._Image().width > this._Image().height
|
|
192
|
+
? this.cutHeight() / imageHeight
|
|
193
|
+
: this.cutWidth() / imageWidth
|
|
194
|
+
: this.cutHeight() > this.cutWidth()
|
|
195
|
+
? this.cutHeight() / imageHeight
|
|
196
|
+
: this.cutWidth() / imageWidth;
|
|
197
|
+
this.setScaleFactorModel(scaleFactor);
|
|
198
|
+
this.scaleFactor.set(scaleFactor);
|
|
199
|
+
}
|
|
200
|
+
this.imageX = Math.max((this.canvas().width - imageWidth * this.scaleFactorReadOnly()) / 2, this.xMin());
|
|
201
|
+
this.imageY = Math.max((this.canvasHeight() - imageHeight * this.scaleFactorReadOnly()) / 2, this.yMin());
|
|
202
|
+
}
|
|
203
|
+
//#region Métodos de recuperação de dados
|
|
204
|
+
recuperaInstanciaDialog() {
|
|
205
|
+
const arr = this.dialogService.dialogComponentRefMap;
|
|
206
|
+
const entries = arr.entries();
|
|
207
|
+
const firstEntry = entries.next().value;
|
|
208
|
+
const [firstKey, firstValue] = firstEntry;
|
|
209
|
+
const instance = this.dialogService.getInstance(firstKey);
|
|
210
|
+
this.dialogInstance = instance;
|
|
211
|
+
return instance;
|
|
212
|
+
}
|
|
213
|
+
recuperarVariaviesDialog() {
|
|
214
|
+
this._variaviesDialog.set(this.recuperaInstanciaDialog().data.id);
|
|
215
|
+
}
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region Métodos de atualizacao do canvas
|
|
218
|
+
//? Atualiza o tamanho do canvas
|
|
219
|
+
updateCanvasSize() {
|
|
220
|
+
this.imageX = (this.canvas().width - this._Image().width * this.scaleFactorReadOnly()) / 2;
|
|
221
|
+
this.imageY = (this.canvasHeight() / 2) - (this._Image().height * this.scaleFactorReadOnly()) / 2;
|
|
222
|
+
this.canvas().height = this.canvasHeight();
|
|
223
|
+
this.canvas().width = this.canvasWidth();
|
|
224
|
+
this.redrawCanvas(this.ctx(), this._Image());
|
|
225
|
+
}
|
|
226
|
+
redrawCanvas(ctx, img) {
|
|
227
|
+
if (!ctx)
|
|
228
|
+
return;
|
|
229
|
+
this.drawCropArea(ctx);
|
|
230
|
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
231
|
+
ctx.filter = 'blur(5px) opacity(0.9)';
|
|
232
|
+
ctx.drawImage(img, this.imageX, this.imageY, img.width * this.scaleFactorReadOnly(), img.height * this.scaleFactorReadOnly());
|
|
233
|
+
ctx.filter = 'none';
|
|
234
|
+
this.drawImageInCropArea(ctx, img);
|
|
235
|
+
}
|
|
236
|
+
//? Desenha a área de corte
|
|
237
|
+
drawCropArea(ctx) {
|
|
238
|
+
if (!ctx)
|
|
239
|
+
return;
|
|
240
|
+
this.atualizaCutBorder();
|
|
241
|
+
const cropX = ctx.canvas.width / 2 - this.cutWidth() / 2;
|
|
242
|
+
const cropY = ctx.canvas.height / 2 - this.cutHeight() / 2;
|
|
243
|
+
const cropXCircle = ctx.canvas.width / 2 - this.radius() / 2;
|
|
244
|
+
const cropYCircle = ctx.canvas.height / 2 - this.radius() / 2;
|
|
245
|
+
ctx.beginPath();
|
|
246
|
+
ctx.strokeStyle = 'transparent';
|
|
247
|
+
ctx.lineWidth = 2;
|
|
248
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
249
|
+
ctx.arc(cropXCircle, cropYCircle, this.radius(), 0, Math.PI * 2, true);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
ctx.rect(cropX, cropY, this.cutWidth(), this.cutHeight());
|
|
253
|
+
}
|
|
254
|
+
ctx.stroke();
|
|
255
|
+
}
|
|
256
|
+
//? Desenha a imagem na área de corte
|
|
257
|
+
drawImageInCropArea(ctx, img) {
|
|
258
|
+
if (!ctx)
|
|
259
|
+
return;
|
|
260
|
+
const cropX = (ctx.canvas.width - this.cutWidth()) / 2;
|
|
261
|
+
const cropY = (ctx.canvas.height - this.cutHeight()) / 2;
|
|
262
|
+
ctx.save();
|
|
263
|
+
ctx.beginPath();
|
|
264
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
265
|
+
ctx.arc(ctx.canvas.width / 2, ctx.canvas.height / 2, this.radius(), 0, Math.PI * 2, true);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
ctx.rect(cropX, cropY, this.cutWidth(), this.cutHeight());
|
|
269
|
+
}
|
|
270
|
+
ctx.clip();
|
|
271
|
+
ctx.drawImage(img, this.imageX, this.imageY, img.width * this.scaleFactorReadOnly(), img.height * this.scaleFactorReadOnly());
|
|
272
|
+
ctx.restore();
|
|
273
|
+
}
|
|
274
|
+
atualizaCutBorder() {
|
|
275
|
+
if (this.cropBorder && this.cropBorder.nativeElement) {
|
|
276
|
+
const cropBorderElement = this.cropBorder.nativeElement;
|
|
277
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
278
|
+
cropBorderElement.style.borderRadius = this.radius() * 2 + 'px';
|
|
279
|
+
cropBorderElement.style.width = this.radius() * 2 + 'px';
|
|
280
|
+
cropBorderElement.style.height = this.radius() * 2 + 'px';
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
cropBorderElement.style.width = this.cutWidth() + 'px';
|
|
284
|
+
cropBorderElement.style.height = this.cutHeight() + 'px';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region handlers de eventos
|
|
290
|
+
onZoomChange(e) {
|
|
291
|
+
const prevZoom = this.scaleFactorReadOnly();
|
|
292
|
+
const zoomValue = e.value;
|
|
293
|
+
const direction = prevZoom < zoomValue ? 'up' : 'down';
|
|
294
|
+
this.ajustarZoom(direction);
|
|
295
|
+
}
|
|
296
|
+
initializeMouseWheel(canvas, ctx, img) {
|
|
297
|
+
canvas.onwheel = (e) => {
|
|
298
|
+
e.preventDefault();
|
|
299
|
+
//? Recuperando os valores de zoom e delta atuais
|
|
300
|
+
const direction = e.deltaY > 0 ? 'down' : 'up';
|
|
301
|
+
this.ajustarZoom(direction);
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
ajustarZoom(direction) {
|
|
305
|
+
const prevScaleFactor = this.scaleFactorReadOnly();
|
|
306
|
+
const delta = direction == 'down' ? -0.01 : 0.01;
|
|
307
|
+
let scaleFactor = Math.min((prevScaleFactor + (delta * 1.2)), 3);
|
|
308
|
+
const newHeight = this._Image().height * scaleFactor;
|
|
309
|
+
const newWidth = this._Image().width * scaleFactor;
|
|
310
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
311
|
+
if (newHeight < this.radius() * 2 || newWidth < this.radius() * 2) {
|
|
312
|
+
scaleFactor = prevScaleFactor;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
this.scaleFactor.set(scaleFactor);
|
|
316
|
+
this.setScaleFactorModel(scaleFactor);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
if (newHeight < this.cutHeight() || newWidth < this.cutWidth()) {
|
|
321
|
+
scaleFactor = prevScaleFactor;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
this.scaleFactor.set(scaleFactor);
|
|
325
|
+
this.setScaleFactorModel(scaleFactor);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
this.scaleFactor.set(scaleFactor);
|
|
329
|
+
this.setScaleFactorModel(scaleFactor);
|
|
330
|
+
const canvas = this.cropCanvas.nativeElement;
|
|
331
|
+
const canvasWidth = canvas.offsetWidth;
|
|
332
|
+
const canvasHeight = canvas.offsetHeight;
|
|
333
|
+
const centerX = canvasWidth / 2;
|
|
334
|
+
const centerY = canvasHeight / 2;
|
|
335
|
+
const newCanvasX = centerX - (centerX - this.imageX) * (scaleFactor / prevScaleFactor);
|
|
336
|
+
const newCanvasY = centerY - (centerY - this.imageY) * (scaleFactor / prevScaleFactor);
|
|
337
|
+
this.imageX = newCanvasX;
|
|
338
|
+
this.imageY = newCanvasY;
|
|
339
|
+
if (!this.verificaImagemdentroDosLimiteXmin()) {
|
|
340
|
+
const diffXmin = this.retornaDiffXmax();
|
|
341
|
+
this.moveImage(this.imageX - diffXmin);
|
|
342
|
+
}
|
|
343
|
+
if (!this.verificaImagemdentroDosLimiteXmax()) {
|
|
344
|
+
const diffXmax = this.retornaDiffXmin();
|
|
345
|
+
this.moveImage(this.imageX + diffXmax);
|
|
346
|
+
}
|
|
347
|
+
if (!this.verificaImagemdentroDosLimiteYmax()) {
|
|
348
|
+
const diffYmax = this.retornaDiffYmin();
|
|
349
|
+
this.moveImage(undefined, this.imageY + diffYmax);
|
|
350
|
+
}
|
|
351
|
+
if (!this.verificaImagemdentroDosLimiteYmin()) {
|
|
352
|
+
const diffYmin = this.retornaDiffYmax();
|
|
353
|
+
this.moveImage(undefined, this.imageY - diffYmin);
|
|
354
|
+
}
|
|
355
|
+
this.redrawCanvas(this.ctx(), this._Image());
|
|
356
|
+
}
|
|
357
|
+
verificaImagemdentroDosLimiteXmin() {
|
|
358
|
+
const newImageX = this.imageX;
|
|
359
|
+
return newImageX < this.xMin();
|
|
360
|
+
}
|
|
361
|
+
verificaImagemdentroDosLimiteXmax() {
|
|
362
|
+
const newImageX = this.imageX;
|
|
363
|
+
return newImageX > this.xMax();
|
|
364
|
+
}
|
|
365
|
+
verificaImagemdentroDosLimiteYmin() {
|
|
366
|
+
const newImageY = this.imageY;
|
|
367
|
+
return newImageY < this.yMin();
|
|
368
|
+
}
|
|
369
|
+
verificaImagemdentroDosLimiteYmax() {
|
|
370
|
+
const newImageY = this.imageY;
|
|
371
|
+
return newImageY > this.yMax();
|
|
372
|
+
}
|
|
373
|
+
retornaDiffXmin() {
|
|
374
|
+
const newImageX = this.imageX;
|
|
375
|
+
return this.xMin() - newImageX;
|
|
376
|
+
}
|
|
377
|
+
retornaDiffXmax() {
|
|
378
|
+
const newImageX = this.imageX;
|
|
379
|
+
return newImageX - this.xMax();
|
|
380
|
+
}
|
|
381
|
+
retornaDiffYmin() {
|
|
382
|
+
const newImageY = this.imageY;
|
|
383
|
+
return this.yMin() - newImageY;
|
|
384
|
+
}
|
|
385
|
+
retornaDiffYmax() {
|
|
386
|
+
const newImageY = this.imageY;
|
|
387
|
+
return newImageY - this.yMax();
|
|
388
|
+
}
|
|
389
|
+
initializeImageMove(canvas, ctx, img) {
|
|
390
|
+
let isDragging = false;
|
|
391
|
+
canvas.style.cursor = 'grab';
|
|
392
|
+
canvas.onmousedown = (e) => {
|
|
393
|
+
isDragging = true;
|
|
394
|
+
canvas.style.cursor = 'grabbing';
|
|
395
|
+
this.startX = e.offsetX - this.imageX;
|
|
396
|
+
this.startY = e.offsetY - this.imageY;
|
|
397
|
+
};
|
|
398
|
+
canvas.onmouseup = () => {
|
|
399
|
+
isDragging = false;
|
|
400
|
+
canvas.style.cursor = 'grab';
|
|
401
|
+
};
|
|
402
|
+
canvas.onmouseout = () => {
|
|
403
|
+
isDragging = false;
|
|
404
|
+
canvas.style.cursor = 'grab';
|
|
405
|
+
};
|
|
406
|
+
canvas.onmousemove = (e) => {
|
|
407
|
+
if (isDragging) {
|
|
408
|
+
// Calcula o novo posicionamento da imagem
|
|
409
|
+
let newImageX = e.offsetX - this.startX;
|
|
410
|
+
let newImageY = e.offsetY - this.startY;
|
|
411
|
+
if (newImageX < this.xMin() && newImageX > this.xMax()) {
|
|
412
|
+
this.moveImage(newImageX);
|
|
413
|
+
}
|
|
414
|
+
if (newImageY < this.yMin() && newImageY > this.yMax()) {
|
|
415
|
+
this.moveImage(undefined, newImageY);
|
|
416
|
+
}
|
|
417
|
+
this.redrawCanvas(ctx, img);
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
moveImage(dx, dy) {
|
|
422
|
+
this.imageX = (dx ?? this.imageX);
|
|
423
|
+
this.imageY = (dy ?? this.imageY);
|
|
424
|
+
}
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region Métodos de corte e fechamento do modal
|
|
427
|
+
cropImage() {
|
|
428
|
+
const ctx = this.ctx();
|
|
429
|
+
if (ctx) {
|
|
430
|
+
const X = ((this.canvas().width - this._Image().width * this.scaleFactorReadOnly()) / 2);
|
|
431
|
+
const Y = ((this.canvasHeight() / 2) - (this._Image().height * this.scaleFactorReadOnly()) / 2);
|
|
432
|
+
// Recuperar o imageData da imagem que está na área de corte
|
|
433
|
+
let imageData;
|
|
434
|
+
const cropX = (ctx.canvas.width - this.cutWidth()) / 2;
|
|
435
|
+
const cropY = (ctx.canvas.height - this.cutHeight()) / 2;
|
|
436
|
+
if (this._variaviesDialog()?.indCircle) {
|
|
437
|
+
// Create a new canvas with the same dimensions as the circle
|
|
438
|
+
const circleCanvas = document.createElement('canvas');
|
|
439
|
+
const circleCtx = circleCanvas.getContext('2d');
|
|
440
|
+
circleCanvas.width = this.radius() * 2;
|
|
441
|
+
circleCanvas.height = this.radius() * 2;
|
|
442
|
+
// Draw the circle on the new canvas
|
|
443
|
+
circleCtx.beginPath();
|
|
444
|
+
circleCtx.arc(this.radius(), this.radius(), this.radius(), 0, 2 * Math.PI);
|
|
445
|
+
circleCtx.fill();
|
|
446
|
+
// Set the composite operation to 'destination-in' to cut out the circle
|
|
447
|
+
ctx.globalCompositeOperation = 'destination-in';
|
|
448
|
+
// Draw the image on the main canvas using the circle as a mask
|
|
449
|
+
ctx.drawImage(circleCanvas, cropX, cropY);
|
|
450
|
+
// Reset the composite operation to the default value
|
|
451
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
452
|
+
// Get the image data of the cropped circle
|
|
453
|
+
imageData = ctx.getImageData(cropX, cropY, this.radius() * 2, this.radius() * 2);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
imageData = ctx.getImageData(cropX, cropY, this.cutWidth(), this.cutHeight());
|
|
457
|
+
}
|
|
458
|
+
// Obter os valores de width e height da variável _variaviesDialog
|
|
459
|
+
const variaveisDialog = this._variaviesDialog();
|
|
460
|
+
if (variaveisDialog) {
|
|
461
|
+
const { width, height } = variaveisDialog;
|
|
462
|
+
// Criar um novo canvas e contexto com os valores de width e height
|
|
463
|
+
const newCanvas = document.createElement('canvas');
|
|
464
|
+
const newCtx = newCanvas.getContext('2d');
|
|
465
|
+
newCanvas.width = width;
|
|
466
|
+
newCanvas.height = height;
|
|
467
|
+
if (newCtx) {
|
|
468
|
+
// Redimensionar a imagem para o tamanho especificado
|
|
469
|
+
const tempCanvas = document.createElement('canvas');
|
|
470
|
+
const tempCtx = tempCanvas.getContext('2d');
|
|
471
|
+
tempCanvas.width = this.cutWidth();
|
|
472
|
+
tempCanvas.height = this.cutHeight();
|
|
473
|
+
tempCtx.putImageData(imageData, 0, 0);
|
|
474
|
+
newCtx.drawImage(tempCanvas, 0, 0, width, height);
|
|
475
|
+
window.dispatchEvent(new CustomEvent('cropImage', { detail: {
|
|
476
|
+
result: Promise.resolve(newCanvas.toDataURL()),
|
|
477
|
+
status: true
|
|
478
|
+
} }));
|
|
479
|
+
this.closeCropModal();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
closeCropModal() {
|
|
485
|
+
this.dialogInstance.close();
|
|
486
|
+
}
|
|
487
|
+
cancel() {
|
|
488
|
+
window.dispatchEvent(new CustomEvent('cropImage', { detail: {
|
|
489
|
+
result: Promise.resolve('cancel'),
|
|
490
|
+
status: false
|
|
491
|
+
} }));
|
|
492
|
+
this.closeCropModal();
|
|
493
|
+
}
|
|
494
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: SimpleComponent, deps: [{ token: i1.DynamicDialogRef }, { token: i1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
495
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.8", type: SimpleComponent, isStandalone: true, selector: "app-simple-component", host: { listeners: { "window:resize": "onWindowResize($event)" } }, viewQueries: [{ propertyName: "cropCanvas", first: true, predicate: ["cropCanvas"], descendants: true }, { propertyName: "cropBorder", first: true, predicate: ["cropBorder"], descendants: true }], ngImport: i0, template: `
|
|
496
|
+
<div class="modal-content">
|
|
497
|
+
<div class="crop-container">
|
|
498
|
+
<canvas #cropCanvas class="crop-canvas"></canvas>
|
|
499
|
+
<div #cropBorder class="crop-border"></div>
|
|
500
|
+
</div>
|
|
501
|
+
|
|
502
|
+
<div class="w-full mt-2">
|
|
503
|
+
<kv-label label="Zoom" style="text-align: left;" />
|
|
504
|
+
<p-slider [(ngModel)]="this.scaleFactorModel" [step]="0.000001" [max]="3" (onChange)="onZoomChange($event)"></p-slider>
|
|
505
|
+
</div>
|
|
506
|
+
|
|
507
|
+
<div class="button-container">
|
|
508
|
+
<kv-button label="Cancelar" severity="tertiary" icon="close" (click)="cancel()"></kv-button>
|
|
509
|
+
<kv-button label="Recortar" severity="primary" icon="crop" (click)="cropImage()" class="ml-2"></kv-button>
|
|
510
|
+
</div>
|
|
511
|
+
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
`, isInline: true, styles: ["img{border-style:solid;border-width:2px;border-radius:50%;object-fit:cover}i{font-size:22px}.botao-alterar-foto{border-style:none;width:max-content;background-color:#002542;color:#000;font-weight:700;cursor:pointer;padding:7px 9px}.botao-alterar-foto i{color:#fff}.botao-excluir-foto{border-style:none;width:max-content;background-color:#002542;color:#000;font-weight:700;cursor:pointer;padding:7px 9px}.botao-excluir-foto i{color:#fff}.btn{position:absolute;top:87%;left:87%;transform:translate(-50%,-50%)}.image-container{display:inline-block;position:relative}.modal-content{position:relative;background-color:#fefefe;margin:1% auto;padding:20px;width:80%;max-width:fit-content;text-align:center;border-radius:12px}.crop-container{display:flex;justify-content:center;align-items:center}.crop-canvas{border:1px solid #d1d5db;border-radius:12px;width:100%;height:auto}.crop-border{position:absolute;border:2px dashed #9ca3af;pointer-events:none}.zoom-container{padding-top:20px;padding-bottom:20px}.button-container{display:flex;align-items:center;justify-content:flex-end;flex-direction:row;margin-top:24px}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: KvModalModule }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i2.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: KvButtonModule }, { kind: "component", type: i4.KvButtonComponent, selector: "kv-button", inputs: ["label", "icon", "loading", "disabled", "severity", "size", "fullWidth"], outputs: ["onClick"] }, { kind: "ngmodule", type: KvLabelModule }, { kind: "component", type: i5.KvLabelComponent, selector: "kv-label", inputs: ["componentId", "label"] }] }); }
|
|
517
|
+
}
|
|
518
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: SimpleComponent, decorators: [{
|
|
519
|
+
type: Component,
|
|
520
|
+
args: [{ selector: 'app-simple-component', template: `
|
|
521
|
+
<div class="modal-content">
|
|
522
|
+
<div class="crop-container">
|
|
523
|
+
<canvas #cropCanvas class="crop-canvas"></canvas>
|
|
524
|
+
<div #cropBorder class="crop-border"></div>
|
|
525
|
+
</div>
|
|
526
|
+
|
|
527
|
+
<div class="w-full mt-2">
|
|
528
|
+
<kv-label label="Zoom" style="text-align: left;" />
|
|
529
|
+
<p-slider [(ngModel)]="this.scaleFactorModel" [step]="0.000001" [max]="3" (onChange)="onZoomChange($event)"></p-slider>
|
|
530
|
+
</div>
|
|
531
|
+
|
|
532
|
+
<div class="button-container">
|
|
533
|
+
<kv-button label="Cancelar" severity="tertiary" icon="close" (click)="cancel()"></kv-button>
|
|
534
|
+
<kv-button label="Recortar" severity="primary" icon="crop" (click)="cropImage()" class="ml-2"></kv-button>
|
|
535
|
+
</div>
|
|
536
|
+
|
|
537
|
+
</div>
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
`, standalone: true, imports: [
|
|
542
|
+
DialogModule,
|
|
543
|
+
KvModalModule,
|
|
544
|
+
SliderModule,
|
|
545
|
+
CommonModule,
|
|
546
|
+
ButtonModule,
|
|
547
|
+
FileUploadModule,
|
|
548
|
+
SliderModule,
|
|
549
|
+
FormsModule,
|
|
550
|
+
ReactiveFormsModule,
|
|
551
|
+
KvButtonModule,
|
|
552
|
+
KvLabelModule,
|
|
553
|
+
], styles: ["img{border-style:solid;border-width:2px;border-radius:50%;object-fit:cover}i{font-size:22px}.botao-alterar-foto{border-style:none;width:max-content;background-color:#002542;color:#000;font-weight:700;cursor:pointer;padding:7px 9px}.botao-alterar-foto i{color:#fff}.botao-excluir-foto{border-style:none;width:max-content;background-color:#002542;color:#000;font-weight:700;cursor:pointer;padding:7px 9px}.botao-excluir-foto i{color:#fff}.btn{position:absolute;top:87%;left:87%;transform:translate(-50%,-50%)}.image-container{display:inline-block;position:relative}.modal-content{position:relative;background-color:#fefefe;margin:1% auto;padding:20px;width:80%;max-width:fit-content;text-align:center;border-radius:12px}.crop-container{display:flex;justify-content:center;align-items:center}.crop-canvas{border:1px solid #d1d5db;border-radius:12px;width:100%;height:auto}.crop-border{position:absolute;border:2px dashed #9ca3af;pointer-events:none}.zoom-container{padding-top:20px;padding-bottom:20px}.button-container{display:flex;align-items:center;justify-content:flex-end;flex-direction:row;margin-top:24px}\n"] }]
|
|
554
|
+
}], ctorParameters: () => [{ type: i1.DynamicDialogRef }, { type: i1.DialogService }], propDecorators: { cropCanvas: [{
|
|
555
|
+
type: ViewChild,
|
|
556
|
+
args: ['cropCanvas']
|
|
557
|
+
}], cropBorder: [{
|
|
558
|
+
type: ViewChild,
|
|
559
|
+
args: ['cropBorder']
|
|
560
|
+
}], onWindowResize: [{
|
|
561
|
+
type: HostListener,
|
|
562
|
+
args: ['window:resize', ['$event']]
|
|
563
|
+
}] } });
|
|
564
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UuY3V0dGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rZWV2by1jb21wb25lbnRzL3NyYy9saWIvYXBpL3NlcnZpY2VzL2ltYWdlLmN1dHRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWdCLFFBQVEsRUFBYyxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0gsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBMEM5Qyx3Q0FBd0M7QUFDeEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7Ozs7OztBQTlDN0UsTUFBTSxPQUFPLGtCQUFrQjtJQUU3QixZQUNtQixhQUE0QjtRQUE1QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtJQUMzQyxDQUFDO0lBRUwsR0FBRyxDQUFDLFdBQW1CLEVBQUUsS0FBYSxFQUFFLE1BQWMsRUFBRSxZQUFxQixLQUFLO1FBQ2hGLE1BQU0sU0FBUyxHQUFH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Q0FBQTtJQUN2QixDQUFDOzhHQTdpQkcsZUFBZTtrR0FBZixlQUFlLHlWQTFJVDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJULGdxQ0FzR0MsWUFBWSw4QkFDWixhQUFhLDhCQUNiLFlBQVksK1JBQ1osWUFBWSw4QkFDWixZQUFZLDhCQUNaLGdCQUFnQiw4QkFFaEIsV0FBVyw4VkFDWCxtQkFBbUIsOEJBQ25CLGNBQWMsaU5BQ2QsYUFBYTs7MkZBS1gsZUFBZTtrQkE1SXBCLFNBQVM7K0JBQ0Usc0JBQXNCLFlBQ3RCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQlQsY0FvR1csSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osYUFBYTt3QkFDYixZQUFZO3dCQUNaLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixnQkFBZ0I7d0JBQ2hCLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxtQkFBbUI7d0JBQ25CLGNBQWM7d0JBQ2QsYUFBYTtxQkFFZDtpSEFnQjBCLFVBQVU7c0JBQWxDLFNBQVM7dUJBQUMsWUFBWTtnQkFDRSxVQUFVO3NCQUFsQyxTQUFTO3VCQUFDLFlBQVk7Z0JBMkd6QixjQUFjO3NCQURiLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBDb21wb25lbnRSZWYsIGNvbXB1dGVkLCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIEluamVjdGFibGUsIHNpZ25hbCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UsIER5bmFtaWNEaWFsb2dDb21wb25lbnQsIER5bmFtaWNEaWFsb2dSZWYgfSBmcm9tICdwcmltZW5nL2R5bmFtaWNkaWFsb2cnO1xyXG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBJbWFnZUN1dHRlclNlcnZpY2Uge1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGlhbG9nc2VydmljZTogRGlhbG9nU2VydmljZVxyXG4gICkgeyB9XHJcblxyXG4gIGN1dChpbWFnZUJhc2U2NDogc3RyaW5nLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgaW5kQ2lyY2xlOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgY29uc3QgY3V0Q29uZmlnID0geyBpbWFnZUJhc2U2NCwgd2lkdGgsIGhlaWdodCwgaW5kQ2lyY2xlIH07XHJcbiAgICB0aGlzLmFicmlyTW9kYWwoY3V0Q29uZmlnKTtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjcm9wSW1hZ2UnLCAoZXZlbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmKGV2ZW50LmRldGFpbC5zdGF0dXMgPT0gdHJ1ZSApIHtcclxuICAgICAgICAgIHJlc29sdmUoZXZlbnQuZGV0YWlsLnJlc3VsdCk7XHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICByZWplY3QoJ09wZXJhY2FvIGNhbmNlbGFkYS4nKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgYWJyaXJNb2RhbChjdXRDb25maWc6IHsgaW1hZ2VCYXNlNjQ6IHN0cmluZywgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGluZENpcmNsZTogYm9vbGVhbiB9KSB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSAgICAgICB7XHJcbiAgICAgIGNsb3NhYmxlOiB0cnVlLFxyXG4gICAgICBtYXhpbWl6YWJsZTogZmFsc2UsXHJcbiAgICAgIHBvcHVwOiB0cnVlLFxyXG4gICAgICB3aWR0aDogJzc1dncnLFxyXG4gICAgICBoZWFkZXI6IGBDb3J0YXJgICxcclxuICAgICAgaWQ6IHsgaW1hZ2VtOiBjdXRDb25maWcuaW1hZ2VCYXNlNjQsIHdpZHRoOiBjdXRDb25maWcud2lkdGgsIGhlaWdodDogY3V0Q29uZmlnLmhlaWdodCwgaW5kQ2lyY2xlOiBjdXRDb25maWcuaW5kQ2lyY2xlIH0sXHJcbiAgICAgIHN0eWxlQ2xhc3M6ICdtb2RhbCdcclxuICAgIH1cclxuICAgIGNvbnN0IGRpYWxvZ1JlZjogRHluYW1pY0RpYWxvZ1JlZiA9IEZvcm1TZXJ2aWNlLm9wZW5EaWFsb2codGhpcy5kaWFsb2dzZXJ2aWNlLCBTaW1wbGVDb21wb25lbnQsICgpPT57fSwgcGFyYW1zKTtcclxuICB9XHJcbn1cclxuXHJcblxyXG4vLyA/IENvbXBvbmVudGUgZGUgbW9kYWwgdXNhZG8gbm8gY3V0dGVyXHJcbmltcG9ydCB7IFNsaWRlck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvc2xpZGVyJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcclxuaW1wb3J0IHsgRmlsZVVwbG9hZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZmlsZXVwbG9hZCc7XHJcbmltcG9ydCB7IEt2TGFiZWxNb2R1bGUgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2t2LWxhYmVsL2t2LWxhYmVsLm1vZHVsZSc7XHJcbmltcG9ydCB7IEZvcm1TZXJ2aWNlIH0gZnJvbSAnLi9mb3JtLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBLdk1vZGFsTW9kdWxlIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9rdi1tb2RhbC9rdi1tb2RhbC5tb2R1bGUnO1xyXG5pbXBvcnQgeyBLdkJ1dHRvbk1vZHVsZSB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMva3YtYnV0dG9uL2t2LWJ1dHRvbi5tb2R1bGUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdhcHAtc2ltcGxlLWNvbXBvbmVudCcsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3JvcC1jb250YWluZXJcIj5cclxuICAgICAgICAgIDxjYW52YXMgI2Nyb3BDYW52YXMgY2xhc3M9XCJjcm9wLWNhbnZhc1wiPjwvY2FudmFzPlxyXG4gICAgICAgICAgPGRpdiAjY3JvcEJvcmRlciBjbGFzcz1cImNyb3AtYm9yZGVyXCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgbXQtMlwiPlxyXG4gICAgICAgICAgPGt2LWxhYmVsIGxhYmVsPVwiWm9vbVwiIHN0eWxlPVwidGV4dC1hbGlnbjogbGVmdDtcIiAvPlxyXG4gICAgICAgICAgPHAtc2xpZGVyIFsobmdNb2RlbCldPVwidGhpcy5zY2FsZUZhY3Rvck1vZGVsXCIgW3N0ZXBdPVwiMC4wMDAwMDFcIiAgW21heF09XCIzXCIgIChvbkNoYW5nZSk9XCJvblpvb21DaGFuZ2UoJGV2ZW50KVwiPjwvcC1zbGlkZXI+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvbi1jb250YWluZXJcIj5cclxuICAgICAgICAgIDxrdi1idXR0b24gbGFiZWw9XCJDYW5jZWxhclwiIHNldmVyaXR5PVwidGVydGlhcnlcIiBpY29uPVwiY2xvc2VcIiAoY2xpY2spPVwiY2FuY2VsKClcIj48L2t2LWJ1dHRvbj5cclxuICAgICAgICAgIDxrdi1idXR0b24gbGFiZWw9XCJSZWNvcnRhclwiIHNldmVyaXR5PVwicHJpbWFyeVwiIGljb249XCJjcm9wXCIgKGNsaWNrKT1cImNyb3BJbWFnZSgpXCIgY2xhc3M9XCJtbC0yXCI+PC9rdi1idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8L2Rpdj5cclxuXHJcblxyXG5cclxuICBgLFxyXG4gIHN0eWxlczogW2BcclxuXHJcbmltZyB7XHJcbiAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcclxuICBib3JkZXItd2lkdGg6IDJweDtcclxuICBib3JkZXItcmFkaXVzOiA1MCU7XHJcbiAgb2JqZWN0LWZpdDogY292ZXI7XHJcbn1cclxuXHJcbmkge1xyXG4gIGZvbnQtc2l6ZTogMjJweDtcclxufVxyXG5cclxuLmJvdGFvLWFsdGVyYXItZm90byB7XHJcbiAgYm9yZGVyLXN0eWxlOiBub25lO1xyXG4gIHdpZHRoOiBtYXgtY29udGVudDtcclxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAyNTQyO1xyXG4gIGNvbG9yOiBibGFjaztcclxuICBmb250LXdlaWdodDogYm9sZDtcclxuICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgcGFkZGluZzogN3B4IDlweDtcclxufVxyXG5cclxuLmJvdGFvLWFsdGVyYXItZm90byBpIHtcclxuICBjb2xvcjogI2ZmZjtcclxufVxyXG5cclxuLmJvdGFvLWV4Y2x1aXItZm90byB7XHJcbiAgYm9yZGVyLXN0eWxlOiBub25lO1xyXG4gIHdpZHRoOiBtYXgtY29udGVudDtcclxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAyNTQyO1xyXG4gIGNvbG9yOiBibGFjaztcclxuICBmb250LXdlaWdodDogYm9sZDtcclxuICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgcGFkZGluZzogN3B4IDlweDtcclxufVxyXG5cclxuLmJvdGFvLWV4Y2x1aXItZm90byBpIHtcclxuICBjb2xvcjogI2ZmZjtcclxufVxyXG5cclxuLmJ0biB7XHJcbiAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gIHRvcDogODclO1xyXG4gIGxlZnQ6IDg3JTtcclxuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTtcclxufVxyXG5cclxuLmltYWdlLWNvbnRhaW5lciB7XHJcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xyXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcclxufVxyXG5cclxuLm1vZGFsLWNvbnRlbnQge1xyXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcclxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmVmZWZlO1xyXG4gIG1hcmdpbjogMSUgYXV0bztcclxuICBwYWRkaW5nOiAyMHB4O1xyXG4gIHdpZHRoOiA4MCU7XHJcbiAgbWF4LXdpZHRoOiBmaXQtY29udGVudDtcclxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgYm9yZGVyLXJhZGl1czogMTJweDtcclxufVxyXG5cclxuLmNyb3AtY29udGFpbmVyIHtcclxuICBkaXNwbGF5OiBmbGV4O1xyXG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xyXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbn1cclxuXHJcbi5jcm9wLWNhbnZhcyB7XHJcbiAgYm9yZGVyOiAxcHggc29saWQgI2QxZDVkYjtcclxuICBib3JkZXItcmFkaXVzOiAxMnB4O1xyXG4gIHdpZHRoOiAxMDAlO1xyXG4gIGhlaWdodDogYXV0bztcclxufVxyXG5cclxuLmNyb3AtYm9yZGVyIHtcclxuICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgYm9yZGVyOiAycHggZGFzaGVkICM5Y2EzYWY7XHJcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XHJcbn1cclxuXHJcbi56b29tLWNvbnRhaW5lciB7XHJcbiAgcGFkZGluZy10b3A6IDIwcHg7XHJcbiAgcGFkZGluZy1ib3R0b206IDIwcHg7XHJcbn1cclxuXHJcbi5idXR0b24tY29udGFpbmVyIHtcclxuICBkaXNwbGF5OiBmbGV4O1xyXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcclxuICBmbGV4LWRpcmVjdGlvbjogcm93O1xyXG4gIG1hcmdpbi10b3A6IDI0cHg7XHJcbn1cclxuXHJcblxyXG5cclxuICBgXSxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIERpYWxvZ01vZHVsZSxcclxuICAgIEt2TW9kYWxNb2R1bGUsXHJcbiAgICBTbGlkZXJNb2R1bGUsXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBCdXR0b25Nb2R1bGUsXHJcbiAgICBGaWxlVXBsb2FkTW9kdWxlLFxyXG4gICAgU2xpZGVyTW9kdWxlLFxyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxyXG4gICAgS3ZCdXR0b25Nb2R1bGUsXHJcbiAgICBLdkxhYmVsTW9kdWxlLFxyXG5cclxuICBdXHJcbn0pXHJcblxyXG5jbGFzcyBTaW1wbGVDb21wb25lbnQge1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGR5bmFtaWNEaWFsb2dSZWY6IER5bmFtaWNEaWFsb2dSZWYsIHByaXZhdGUgcmVhZG9ubHkgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSkge1xyXG4gICAgdGhpcy5hdHVhbGl6YVRhbWFuaG9UZWxhKClcclxuICB9XHJcblxyXG5cclxuICAvLyA/IFZhcmlhdmllcyBxdWUgcmVjZWJlbSBvcyB2YWxvcmVzIGRvIGRpYWxvZ1xyXG4gIF92YXJpYXZpZXNEaWFsb2cgPSBzaWduYWw8eyBpbWFnZW06IHN0cmluZywgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGluZENpcmNsZTogYm9vbGVhbiB9fG51bGw+KG51bGwpXHJcblxyXG5cclxuXHJcbiAgICAvLz8gUmVmZXLDqm5jaWEgcGFyYSBvIGVsZW1lbnRvIHF1ZSBjb250w6ltIGEgaW1hZ2VtIGUgY2FudmFzXHJcbiAgICBAVmlld0NoaWxkKCdjcm9wQ2FudmFzJykgY3JvcENhbnZhcyE6IEVsZW1lbnRSZWY8SFRNTENhbnZhc0VsZW1lbnQ+O1xyXG4gICAgQFZpZXdDaGlsZCgnY3JvcEJvcmRlcicpIGNyb3BCb3JkZXIhOiBFbGVtZW50UmVmO1xyXG5cclxuICAgIC8vPyBSZWZlcsOqbmNpYXMgcGFyYSBvIGNvbnRleHRvIGUgY2FudmFzXHJcbiAgICBwcml2YXRlIGNhbnZhcyA9IHNpZ25hbDxIVE1MQ2FudmFzRWxlbWVudHxudWxsPihudWxsKTtcclxuICAgIHByaXZhdGUgY3R4ID0gIHNpZ25hbDxDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR8bnVsbD4obnVsbCk7XHJcbiAgICBwcml2YXRlIF9JbWFnZSA9IHNpZ25hbDxIVE1MSW1hZ2VFbGVtZW50PihuZXcgSW1hZ2UoKSk7XHJcblxyXG4gICAgLy8/IENvb3JkZW5hZGFzIGluaWNpYWlzIGUgZmluYWlzIGRvIGRlc2VuaG9cclxuICAgIHByaXZhdGUgc3RhcnRYID0gMDtcclxuICAgIHByaXZhdGUgc3RhcnRZID0gMDtcclxuXHJcbiAgICAvLz8gUmVmZXLDqm5jaWEgcGFyYSBvIG1vZGFsXHJcbiAgICBwcml2YXRlIGRpYWxvZ0luc3RhbmNlITpEeW5hbWljRGlhbG9nQ29tcG9uZW50O1xyXG5cclxuICAgIC8vPyBGYXRvciBkZSBlc2NhbGEgZGEgaW1hZ2VtIGUgem9vbVxyXG4gICAgc2NhbGVGYWN0b3JSZWFkT25seSA9IGNvbXB1dGVkPG51bWJlcj4oKCk9PiB7XHJcbiAgICAgIHJldHVybiBNYXRoLm1pbih0aGlzLnNjYWxlRmFjdG9yKCkhLCAzKTtcclxuICAgIH0pXHJcbiAgICBwcml2YXRlIHNjYWxlRmFjdG9yID0gc2lnbmFsPG51bWJlcnxudWxsPihudWxsKTtcclxuICAgIHNldFNjYWxlRmFjdG9yTW9kZWwodmFsb3I6bnVtYmVyKXtcclxuICAgICAgdGhpcy5zY2FsZUZhY3Rvck1vZGVsID0gdmFsb3JcclxuICAgICAgdGhpcy5zY2FsZUZhY3Rvci5zZXQodGhpcy5zY2FsZUZhY3Rvck1vZGVsKVxyXG4gICAgfVxyXG4gICAgc2NhbGVGYWN0b3JNb2RlbCA9IDA7XHJcblxyXG4gICAgcHJpdmF0ZSBpbWFnZVg6IG51bWJlciA9IDA7XHJcbiAgICBwcml2YXRlIGltYWdlWTogbnVtYmVyID0gMDtcclxuXHJcblxyXG4gICAgLy8jcmVnaW9uIFByb3ByaWVkYWRlcyBjb21wdXRhZGFzIGRlIHRhbWFuaG8gZG8gY2FudmFzIGUgZGEgaW1hZ2VtXHJcbiAgICAgIC8vPyBMYXJndXJhIGUgYWx0dXJhIGRvIGNhbnZhcyBiYXNlYWRvIG5hIHRhbWFuaG8gZGEgdGVsYVxyXG4gICAgICBjYW52YXNXaWR0aCA9IGNvbXB1dGVkPG51bWJlciB8IG51bGw+KCgpID0+IHRoaXMud2lkdGhUZWxhKCkqMC41KTtcclxuICAgICAgY2FudmFzSGVpZ2h0ID0gY29tcHV0ZWQ8bnVtYmVyIHwgbnVsbD4oKCkgPT4gdGhpcy5oZWlndGhUZWxhKCkqMC41KTtcclxuXHJcbiAgICAgIC8vPyBMYXJndXJhIGUgYWx0dXJhIGRhIMOhcmVhIGRlIGNvcnRlXHJcbiAgICAgIGN1dFdpZHRoID0gY29tcHV0ZWQ8bnVtYmVyIHwgbnVsbD4oKCkgPT4ge1xyXG4gICAgICAgIGlmKHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUpe1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmFkaXVzKCkhICogMjtcclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gdGhpcy5jYW52YXNXaWR0aCgpITtcclxuICAgICAgICAgIGNvbnN0IG1heFdpZHRoID0gY2FudmFzV2lkdGggKiAwLjg7XHJcbiAgICAgICAgICBjb25zdCBwcm9wb3J0aW9uYWxIZWlnaHQgPSBtYXhXaWR0aCAqIHRoaXMucHJvcG9yY2FvSW1hZ2VtKCkhO1xyXG4gICAgICAgICAgcmV0dXJuIHByb3BvcnRpb25hbEhlaWdodCA+IHRoaXMuY2FudmFzSGVpZ2h0KCkhICogMC44ID8gdGhpcy5jYW52YXNIZWlnaHQoKSEgKiAwLjggLyB0aGlzLnByb3BvcmNhb0ltYWdlbSgpISA6IG1heFdpZHRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH0pO1xyXG4gICAgICBjdXRIZWlnaHQgPSBjb21wdXRlZDxudW1iZXIgfCBudWxsPigoKSA9PiB7XHJcbiAgICAgICAgaWYodGhpcy5fdmFyaWF2aWVzRGlhbG9nKCk/LmluZENpcmNsZSl7XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5yYWRpdXMoKSEgKiAyO1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gdGhpcy5jYW52YXNIZWlnaHQoKSE7XHJcbiAgICAgICAgICBjb25zdCBtYXhIZWlnaHQgPSBjYW52YXNIZWlnaHQgKiAwLjg7XHJcbiAgICAgICAgICBjb25zdCBwcm9wb3J0aW9uYWxXaWR0aCA9IG1heEhlaWdodCAvIHRoaXMucHJvcG9yY2FvSW1hZ2VtKCkhO1xyXG4gICAgICAgICAgcmV0dXJuIHByb3BvcnRpb25hbFdpZHRoID4gdGhpcy5jYW52YXNXaWR0aCgpISAqIDAuOCA/IHRoaXMuY2FudmFzV2lkdGgoKSEgKiAwLjggKiB0aGlzLnByb3BvcmNhb0ltYWdlbSgpISA6IG1heEhlaWdodDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vPyBMYXJndXJhIGUgYWx0dXJhIGRhIGltYWdlbSBubyBjYW52YXMgKGJhc2VhZG8gbmEgZXNjYWxhKSAtIHRhbWFuaG8gcmVhbCBkYSBpbWFnZW1cclxuICAgICAgY2FudmFJbWFnZVdpZHRoID0gY29tcHV0ZWQ8bnVtYmVyPigoKT0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fSW1hZ2UoKS53aWR0aCAqIHRoaXMuc2NhbGVGYWN0b3JSZWFkT25seSgpIVxyXG4gICAgICB9KVxyXG4gICAgICBjYW52YUltYWdlSGVpZ2h0ID0gY29tcHV0ZWQ8bnVtYmVyPigoKT0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fSW1hZ2UoKS5oZWlnaHQgKiB0aGlzLnNjYWxlRmFjdG9yUmVhZE9ubHkoKSFcclxuICAgICAgfSlcclxuICAgICAgcHJvcG9yY2FvSW1hZ2VtID0gY29tcHV0ZWQ8bnVtYmVyIHwgbnVsbD4oKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YXJpYXZpZXNEaWFsb2coKT8uaGVpZ2h0ISAvIHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy53aWR0aCE7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmFkaXVzID0gY29tcHV0ZWQ8bnVtYmVyIHwgbnVsbD4oKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IG1pblNpemUgPSAgIE1hdGgubWluKHRoaXMuY2FudmFzSGVpZ2h0KCkhKjAuOCwgdGhpcy5jYW52YXNXaWR0aCgpISowLjggKTtcclxuICAgICAgICByZXR1cm4gbWluU2l6ZS8yO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAvLyNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIExpbWl0ZXMgZGUgbW92aW1lbnRhw6fDo28gZGEgaW1hZ2VtXHJcbiAgICAvLz8gTGltaXRlcyBkZSBtb3ZpbWVudGHDp8OjbyBkYSBpbWFnZW1cclxuICAgICAgaW5kQ2lyY2xlID0gY29tcHV0ZWQ8Ym9vbGVhbj4oKCk9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUhXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICB4TWluID0gY29tcHV0ZWQ8bnVtYmVyPigoKT0+IHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUhID8gKHRoaXMuY2FudmFzV2lkdGgoKSEgLSAgdGhpcy5jdXRXaWR0aCgpISkvMiA6ICh0aGlzLmNhbnZhc1dpZHRoKCkhIC0gICh0aGlzLnJhZGl1cygpISoyKSkvMlxyXG4gICAgICB9KVxyXG4gICAgICB5TWluID0gY29tcHV0ZWQ8bnVtYmVyPigoKT0+IHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUhID8gKHRoaXMuY2FudmFzSGVpZ2h0KCkhIC0gIHRoaXMuY3V0SGVpZ2h0KCkhKS8yIDogKHRoaXMuY2FudmFzSGVpZ2h0KCkhIC0gICh0aGlzLnJhZGl1cygpISoyKSkvMlxyXG4gICAgICB9KVxyXG5cclxuICAgICAgeE1heCA9IGNvbXB1dGVkPG51bWJlcj4oKCk9PiB7XHJcbiAgICAgICAgcmV0dXJuICF0aGlzLl92YXJpYXZpZXNEaWFsb2coKT8uaW5kQ2lyY2xlISA/IC0oIHRoaXMuY2FudmFJbWFnZVdpZHRoKCkhIC0gKHRoaXMueE1pbigpISkgLSB0aGlzLmN1dFdpZHRoKCkhKSA6IC0oIHRoaXMuY2FudmFJbWFnZVdpZHRoKCkhIC0gKHRoaXMueE1pbigpISkgLSAodGhpcy5yYWRpdXMoKSEqMikpXHJcbiAgICAgIH0pXHJcbiAgICAgIHlNYXggPSBjb21wdXRlZDxudW1iZXI+KCgpPT4ge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5fdmFyaWF2aWVzRGlhbG9nKCk/LmluZENpcmNsZSEgPyAtKCB0aGlzLmNhbnZhSW1hZ2VIZWlnaHQoKSEgLSAodGhpcy55TWluKCkhKSAtIHRoaXMuY3V0SGVpZ2h0KCkhKSA6IC0oIHRoaXMuY2FudmFJbWFnZUhlaWdodCgpISAtICh0aGlzLnlNaW4oKSEpIC0gKHRoaXMucmFkaXVzKCkhKjIpKVxyXG4gICAgICB9KVxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuXHJcblxyXG4gICAgLy8/IFByb3BvcsOnw6NvIGRhIGltYWdlbVxyXG5cclxuICAgIHdpZHRoVGVsYSA9IHNpZ25hbDxudW1iZXI+KDApXHJcbiAgICBoZWlndGhUZWxhID0gc2lnbmFsPG51bWJlcj4oMClcclxuXHJcblxyXG5cclxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcclxuICBvbldpbmRvd1Jlc2l6ZSgpIHtcclxuICAgIHRoaXMuYXR1YWxpemFUYW1hbmhvVGVsYSgpXHJcbiAgICB0aGlzLnVwZGF0ZUNhbnZhc1NpemUoKTtcclxuICAgIHRoaXMuYXR1YWxpemFDdXRCb3JkZXIoKTtcclxuICB9XHJcblxyXG4gIGF0dWFsaXphVGFtYW5ob1RlbGEoKXtcclxuICAgIHRoaXMud2lkdGhUZWxhLnNldCh3aW5kb3cuaW5uZXJXaWR0aCk7XHJcbiAgICB0aGlzLmhlaWd0aFRlbGEuc2V0KHdpbmRvdy5pbm5lckhlaWdodCk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLnJlY3VwZXJhclZhcmlhdmllc0RpYWxvZygpXHJcbiAgICB0aGlzLmluY2lhclJlZmVyZW5jaWFzKClcclxuICAgIHRoaXMuaW5pY2lhckNhbnZhcygpXHJcbiAgfVxyXG4gIGluY2lhclJlZmVyZW5jaWFzKCl7XHJcbiAgICB0aGlzLmNhbnZhcy5zZXQodGhpcy5jcm9wQ2FudmFzLm5hdGl2ZUVsZW1lbnQpO1xyXG4gICAgdGhpcy5jdHguc2V0KHRoaXMuY2FudmFzKCkhLmdldENvbnRleHQoJzJkJykpXHJcbiAgICB0aGlzLl9JbWFnZSgpLnNyYyA9IHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbWFnZW0hXHJcbiAgfVxyXG4gIGluaWNpYXJDYW52YXMoKXtcclxuICAgICAgdGhpcy5fSW1hZ2UoKS5vbmxvYWQgPSAoKSA9PiB7XHJcblxyXG4gICAgICAvLz8gRGVmaW5lIG8gdGFtYW5obyBkbyBjYW52YXNcclxuICAgICAgdGhpcy5jYW52YXMoKSEuaGVpZ2h0ID0gdGhpcy5jYW52YXNIZWlnaHQoKSE7XHJcbiAgICAgIHRoaXMuY2FudmFzKCkhLndpZHRoID0gdGhpcy5jYW52YXNXaWR0aCgpITtcclxuXHJcblxyXG4gICAgICB0aGlzLmFqdXN0YXJab21tRVBvc2ljYW9JbmljaWFsKClcclxuXHJcblxyXG4gICAgICB0aGlzLmluaXRpYWxpemVJbWFnZU1vdmUodGhpcy5jYW52YXMoKSEsIHRoaXMuY3R4KCksIHRoaXMuX0ltYWdlKCkpO1xyXG4gICAgICB0aGlzLmluaXRpYWxpemVNb3VzZVdoZWVsKHRoaXMuY2FudmFzKCkhLCB0aGlzLmN0eCgpLCB0aGlzLl9JbWFnZSgpKTtcclxuXHJcbiAgICAgIHRoaXMucmVkcmF3Q2FudmFzKHRoaXMuY3R4KCksIHRoaXMuX0ltYWdlKCkpO1xyXG5cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhanVzdGFyWm9tbUVQb3NpY2FvSW5pY2lhbCgpe1xyXG4gICAgY29uc3QgY3V0V2lkdGggPSB0aGlzLmN1dFdpZHRoKCkhO1xyXG4gICAgY29uc3QgY3V0SGVpZ2h0ID0gdGhpcy5jdXRIZWlnaHQoKSE7XHJcbiAgICBjb25zdCBpbWFnZVdpZHRoID0gdGhpcy5fSW1hZ2UoKS53aWR0aDtcclxuICAgIGNvbnN0IGltYWdlSGVpZ2h0ID0gdGhpcy5fSW1hZ2UoKS5oZWlnaHQ7XHJcblxyXG4gICAgLy8/IEFqdXN0YSBwb3NzacOnw6NvIGUgem9vbSBpbmljaWFsXHJcblxyXG4gICAgaWYgKHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUpIHtcclxuICAgICAgY29uc3Qgc2NhbGVGYWN0b3IgPSAodGhpcy5yYWRpdXMoKSEgKiAyKSAvIE1hdGgubWluKGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0KTtcclxuICAgICAgdGhpcy5zZXRTY2FsZUZhY3Rvck1vZGVsKHNjYWxlRmFjdG9yKTtcclxuICAgICAgdGhpcy5zY2FsZUZhY3Rvci5zZXQoc2NhbGVGYWN0b3IpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3Qgc2NhbGVGYWN0b3IgPSB0aGlzLmN1dEhlaWdodCgpISA9PT0gdGhpcy5jdXRXaWR0aCgpIVxyXG4gICAgICAgID8gdGhpcy5fSW1hZ2UoKS53aWR0aCA+IHRoaXMuX0ltYWdlKCkuaGVpZ2h0XHJcbiAgICAgICAgICA/IHRoaXMuY3V0SGVpZ2h0KCkhIC8gaW1hZ2VIZWlnaHRcclxuICAgICAgICAgIDogdGhpcy5jdXRXaWR0aCgpISAvIGltYWdlV2lkdGhcclxuICAgICAgICA6IHRoaXMuY3V0SGVpZ2h0KCkhID4gdGhpcy5jdXRXaWR0aCgpIVxyXG4gICAgICAgICAgPyB0aGlzLmN1dEhlaWdodCgpISAvIGltYWdlSGVpZ2h0XHJcbiAgICAgICAgICA6IHRoaXMuY3V0V2lkdGgoKSEgLyBpbWFnZVdpZHRoO1xyXG4gICAgICB0aGlzLnNldFNjYWxlRmFjdG9yTW9kZWwoc2NhbGVGYWN0b3IpO1xyXG4gICAgICB0aGlzLnNjYWxlRmFjdG9yLnNldChzY2FsZUZhY3Rvcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5pbWFnZVggPSBNYXRoLm1heCgodGhpcy5jYW52YXMoKSEud2lkdGggLSBpbWFnZVdpZHRoICogdGhpcy5zY2FsZUZhY3RvclJlYWRPbmx5KCkhKSAvIDIsIHRoaXMueE1pbigpISk7XHJcbiAgICB0aGlzLmltYWdlWSA9IE1hdGgubWF4KCh0aGlzLmNhbnZhc0hlaWdodCgpISAtIGltYWdlSGVpZ2h0ICogdGhpcy5zY2FsZUZhY3RvclJlYWRPbmx5KCkhKSAvIDIsIHRoaXMueU1pbigpISk7XHJcblxyXG4gIH1cclxuXHJcbiAgLy8jcmVnaW9uIE3DqXRvZG9zIGRlIHJlY3VwZXJhw6fDo28gZGUgZGFkb3NcclxuICByZWN1cGVyYUluc3RhbmNpYURpYWxvZygpOiBEeW5hbWljRGlhbG9nQ29tcG9uZW50IHtcclxuICAgIGNvbnN0IGFycjogTWFwPER5bmFtaWNEaWFsb2dSZWY8YW55PiwgQ29tcG9uZW50UmVmPGFueT4+ID0gdGhpcy5kaWFsb2dTZXJ2aWNlLmRpYWxvZ0NvbXBvbmVudFJlZk1hcFxyXG4gICAgY29uc3QgZW50cmllcyA9IGFyci5lbnRyaWVzKCk7XHJcbiAgICBjb25zdCBmaXJzdEVudHJ5ID0gZW50cmllcy5uZXh0KCkudmFsdWU7XHJcbiAgICBjb25zdCBbZmlyc3RLZXksIGZpcnN0VmFsdWVdID0gZmlyc3RFbnRyeTtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5kaWFsb2dTZXJ2aWNlLmdldEluc3RhbmNlKGZpcnN0S2V5KVxyXG4gICAgdGhpcy5kaWFsb2dJbnN0YW5jZSA9IGluc3RhbmNlXHJcbiAgICByZXR1cm4gaW5zdGFuY2VcclxuICB9XHJcblxyXG4gIHJlY3VwZXJhclZhcmlhdmllc0RpYWxvZygpOiB2b2lke1xyXG4gICAgdGhpcy5fdmFyaWF2aWVzRGlhbG9nLnNldCh0aGlzLnJlY3VwZXJhSW5zdGFuY2lhRGlhbG9nKCkuZGF0YS5pZClcclxuICB9XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG5cclxuICAvLyNyZWdpb24gTcOpdG9kb3MgZGUgYXR1YWxpemFjYW8gZG8gY2FudmFzXHJcbiAgLy8/IEF0dWFsaXphIG8gdGFtYW5obyBkbyBjYW52YXNcclxuICB1cGRhdGVDYW52YXNTaXplKCkge1xyXG5cclxuICAgIHRoaXMuaW1hZ2VYID0gKHRoaXMuY2FudmFzKCkhLndpZHRoIC0gdGhpcy5fSW1hZ2UoKS53aWR0aCAqIHRoaXMuc2NhbGVGYWN0b3JSZWFkT25seSgpISkgLyAyO1xyXG4gICAgdGhpcy5pbWFnZVkgPSAodGhpcy5jYW52YXNIZWlnaHQoKSEgLyAyKSAtICh0aGlzLl9JbWFnZSgpLmhlaWdodCAqIHRoaXMuc2NhbGVGYWN0b3JSZWFkT25seSgpISkgLyAyO1xyXG5cclxuXHJcblxyXG4gICAgdGhpcy5jYW52YXMoKSEuaGVpZ2h0ID0gdGhpcy5jYW52YXNIZWlnaHQoKSE7XHJcbiAgICB0aGlzLmNhbnZhcygpIS53aWR0aCA9IHRoaXMuY2FudmFzV2lkdGgoKSE7XHJcblxyXG4gICAgdGhpcy5yZWRyYXdDYW52YXModGhpcy5jdHgoKSwgdGhpcy5fSW1hZ2UoKSk7XHJcbiAgfVxyXG5cclxuICByZWRyYXdDYW52YXMoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgfCBudWxsLCBpbWc6IEhUTUxJbWFnZUVsZW1lbnQpIHtcclxuICAgIGlmICghY3R4KSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5kcmF3Q3JvcEFyZWEoY3R4KTtcclxuXHJcbiAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGN0eC5jYW52YXMud2lkdGgsIGN0eC5jYW52YXMuaGVpZ2h0KTtcclxuICAgIGN0eC5maWx0ZXIgPSAnYmx1cig1cHgpIG9wYWNpdHkoMC45KSc7XHJcbiAgICBjdHguZHJhd0ltYWdlKGltZywgdGhpcy5pbWFnZVgsIHRoaXMuaW1hZ2VZLCBpbWcud2lkdGggKiB0aGlzLnNjYWxlRmFjdG9yUmVhZE9ubHkoKSEsIGltZy5oZWlnaHQgKiB0aGlzLnNjYWxlRmFjdG9yUmVhZE9ubHkoKSEpO1xyXG4gICAgY3R4LmZpbHRlciA9ICdub25lJztcclxuXHJcbiAgICB0aGlzLmRyYXdJbWFnZUluQ3JvcEFyZWEoY3R4LCBpbWcpO1xyXG4gIH1cclxuXHJcbiAgLy8/IERlc2VuaGEgYSDDoXJlYSBkZSBjb3J0ZVxyXG4gIGRyYXdDcm9wQXJlYShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCB8IG51bGwpIHtcclxuICAgIGlmICghY3R4KSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5hdHVhbGl6YUN1dEJvcmRlcigpXHJcblxyXG4gICAgY29uc3QgY3JvcFggPSBjdHguY2FudmFzLndpZHRoIC8gMiAtIHRoaXMuY3V0V2lkdGgoKSEgLyAyO1xyXG4gICAgY29uc3QgY3JvcFkgPSBjdHguY2FudmFzLmhlaWdodCAvIDIgLSB0aGlzLmN1dEhlaWdodCgpISAvIDI7XHJcblxyXG5cclxuICAgIGNvbnN0IGNyb3BYQ2lyY2xlID0gY3R4LmNhbnZhcy53aWR0aCAvIDIgLSB0aGlzLnJhZGl1cygpISAvIDI7XHJcbiAgICBjb25zdCBjcm9wWUNpcmNsZSA9IGN0eC5jYW52YXMuaGVpZ2h0IC8gMiAtIHRoaXMucmFkaXVzKCkhIC8gMjtcclxuXHJcbiAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSAndHJhbnNwYXJlbnQnO1xyXG4gICAgY3R4LmxpbmVXaWR0aCA9IDI7XHJcblxyXG4gICAgaWYodGhpcy5fdmFyaWF2aWVzRGlhbG9nKCk/LmluZENpcmNsZSkge1xyXG4gICAgICBjdHguYXJjKGNyb3BYQ2lyY2xlLCBjcm9wWUNpcmNsZSwgdGhpcy5yYWRpdXMoKSEsIDAsIE1hdGguUEkgKiAyLCB0cnVlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGN0eC5yZWN0KGNyb3BYLCBjcm9wWSAsIHRoaXMuY3V0V2lkdGgoKSEsIHRoaXMuY3V0SGVpZ2h0KCkhKTtcclxuICAgIH1cclxuXHJcbiAgICBjdHguc3Ryb2tlKCk7XHJcblxyXG5cclxuICB9XHJcbiAgLy8/IERlc2VuaGEgYSBpbWFnZW0gbmEgw6FyZWEgZGUgY29ydGVcclxuICBkcmF3SW1hZ2VJbkNyb3BBcmVhKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCwgaW1nOiBIVE1MSW1hZ2VFbGVtZW50KSB7XHJcbiAgICAgIGlmICghY3R4KSByZXR1cm47XHJcblxyXG4gICAgICBjb25zdCBjcm9wWCA9IChjdHguY2FudmFzLndpZHRoIC0gdGhpcy5jdXRXaWR0aCgpISkgLyAyO1xyXG4gICAgICBjb25zdCBjcm9wWSA9IChjdHguY2FudmFzLmhlaWdodCAtIHRoaXMuY3V0SGVpZ2h0KCkhKSAvIDI7XHJcblxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcblxyXG4gICAgICBpZih0aGlzLl92YXJpYXZpZXNEaWFsb2coKT8uaW5kQ2lyY2xlKSB7XHJcbiAgICAgICAgY3R4LmFyYyhjdHguY2FudmFzLndpZHRoLzIsIGN0eC5jYW52YXMuaGVpZ2h0LzIsIHRoaXMucmFkaXVzKCkhLCAwLCBNYXRoLlBJICogMiwgdHJ1ZSk7XHJcblxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGN0eC5yZWN0KGNyb3BYLCBjcm9wWSAsIHRoaXMuY3V0V2lkdGgoKSEsIHRoaXMuY3V0SGVpZ2h0KCkhKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY3R4LmNsaXAoKTtcclxuICAgICAgY3R4LmRyYXdJbWFnZShpbWcsIHRoaXMuaW1hZ2VYLCB0aGlzLmltYWdlWSwgaW1nLndpZHRoICogdGhpcy5zY2FsZUZhY3RvclJlYWRPbmx5KCkhLCBpbWcuaGVpZ2h0ICogdGhpcy5zY2FsZUZhY3RvclJlYWRPbmx5KCkhKTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICB9XHJcbiAgYXR1YWxpemFDdXRCb3JkZXIoKSB7XHJcbiAgICBpZiAodGhpcy5jcm9wQm9yZGVyICYmIHRoaXMuY3JvcEJvcmRlci5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgIGNvbnN0IGNyb3BCb3JkZXJFbGVtZW50ID0gdGhpcy5jcm9wQm9yZGVyLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgIGlmKHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpPy5pbmRDaXJjbGUpe1xyXG5cclxuICAgICAgICBjcm9wQm9yZGVyRWxlbWVudC5zdHlsZS5ib3JkZXJSYWRpdXMgPSB0aGlzLnJhZGl1cygpISoyKydweCc7XHJcbiAgICAgICAgY3JvcEJvcmRlckVsZW1lbnQuc3R5bGUud2lkdGggPSB0aGlzLnJhZGl1cygpISoyKydweCc7XHJcbiAgICAgICAgY3JvcEJvcmRlckVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5yYWRpdXMoKSEqMisncHgnO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICBjcm9wQm9yZGVyRWxlbWVudC5zdHlsZS53aWR0aCA9IHRoaXMuY3V0V2lkdGgoKSErJ3B4JztcclxuICAgICAgICBjcm9wQm9yZGVyRWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmN1dEhlaWdodCgpISsncHgnO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuXHJcbiAgLy8jcmVnaW9uIGhhbmRsZXJzIGRlIGV2ZW50b3NcclxuXHJcbiAgb25ab29tQ2hhbmdlKGU6IGFueSkge1xyXG4gICAgY29uc3QgcHJldlpvb20gPSB0aGlzLnNjYWxlRmFjdG9yUmVhZE9ubHkoKSE7XHJcbiAgICBjb25zdCB6b29tVmFsdWUgPSBlLnZhbHVlO1xyXG4gICAgY29uc3QgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nID0gcHJldlpvb20gPCB6b29tVmFsdWUgPyAndXAnIDogJ2Rvd24nO1xyXG4gICAgdGhpcy5hanVzdGFyWm9vbShkaXJlY3Rpb24pXHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIGluaXRpYWxpemVNb3VzZVdoZWVsKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCwgaW1nOiBIVE1MSW1hZ2VFbGVtZW50KSB7XHJcbiAgICBjYW52YXMub253aGVlbCA9IChlKSA9PiB7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgLy8/IFJlY3VwZXJhbmRvIG9zIHZhbG9yZXMgZGUgem9vbSBlIGRlbHRhIGF0dWFpc1xyXG4gICAgICBjb25zdCBkaXJlY3Rpb246ICd1cCcgfCAnZG93bicgPSBlLmRlbHRhWSA+IDAgPyAnZG93bicgOiAndXAnO1xyXG5cclxuICAgICAgdGhpcy5hanVzdGFyWm9vbShkaXJlY3Rpb24pXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcblxyXG4gIGFqdXN0YXJab29tKGRpcmVjdGlvbjogJ3VwJyB8ICdkb3duJykge1xyXG4gICAgY29uc3QgcHJldlNjYWxlRmFjdG9yID0gdGhpcy5zY2FsZUZhY3RvclJlYWRPbmx5KCkhO1xyXG4gICAgY29uc3QgZGVsdGEgPSBkaXJlY3Rpb24gPT0gJ2Rvd24nID8gLTAuMDEgOiAwLjAxO1xyXG5cclxuICAgIGxldCBzY2FsZUZhY3RvciA9IE1hdGgubWluKChwcmV2U2NhbGVGYWN0b3IgKyAoZGVsdGEqMS4yKSksIDMpO1xyXG5cclxuICAgIGNvbnN0IG5ld0hlaWdodCA9IHRoaXMuX0ltYWdlKCkuaGVpZ2h0ICogc2NhbGVGYWN0b3I7XHJcbiAgICBjb25zdCBuZXdXaWR0aCA9IHRoaXMuX0ltYWdlKCkud2lkdGggKiBzY2FsZUZhY3RvcjtcclxuXHJcbiAgICBpZiAodGhpcy5fdmFyaWF2aWVzRGlhbG9nKCk/LmluZENpcmNsZSkge1xyXG4gICAgICBpZiAobmV3SGVpZ2h0IDwgdGhpcy5yYWRpdXMoKSEgKiAyIHx8IG5ld1dpZHRoIDwgdGhpcy5yYWRpdXMoKSEgKiAyKSB7XHJcbiAgICAgICAgc2NhbGVGYWN0b3IgPSBwcmV2U2NhbGVGYWN0b3I7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zY2FsZUZhY3Rvci5zZXQoc2NhbGVGYWN0b3IpO1xyXG4gICAgICAgIHRoaXMuc2V0U2NhbGVGYWN0b3JNb2RlbChzY2FsZUZhY3Rvcik7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChuZXdIZWlnaHQgPCB0aGlzLmN1dEhlaWdodCgpISB8fCBuZXdXaWR0aCA8IHRoaXMuY3V0V2lkdGgoKSEpIHtcclxuICAgICAgICBzY2FsZUZhY3RvciA9IHByZXZTY2FsZUZhY3RvcjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnNjYWxlRmFjdG9yLnNldChzY2FsZUZhY3Rvcik7XHJcbiAgICAgICAgdGhpcy5zZXRTY2FsZUZhY3Rvck1vZGVsKHNjYWxlRmFjdG9yKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc2NhbGVGYWN0b3Iuc2V0KHNjYWxlRmFjdG9yKTtcclxuICAgIHRoaXMuc2V0U2NhbGVGYWN0b3JNb2RlbChzY2FsZUZhY3Rvcik7XHJcblxyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jcm9wQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhcy5vZmZzZXRXaWR0aDtcclxuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNhbnZhcy5vZmZzZXRIZWlnaHQ7XHJcbiAgICBjb25zdCBjZW50ZXJYID0gY2FudmFzV2lkdGggLyAyO1xyXG4gICAgY29uc3QgY2VudGVyWSA9IGNhbnZhc0hlaWdodCAvIDI7XHJcbiAgICBjb25zdCBuZXdDYW52YXNYID0gY2VudGVyWCAtIChjZW50ZXJYIC0gdGhpcy5pbWFnZVgpICogKHNjYWxlRmFjdG9yIC8gcHJldlNjYWxlRmFjdG9yKTtcclxuICAgIGNvbnN0IG5ld0NhbnZhc1kgPSBjZW50ZXJZIC0gKGNlbnRlclkgLSB0aGlzLmltYWdlWSkgKiAoc2NhbGVGYWN0b3IgLyBwcmV2U2NhbGVGYWN0b3IpO1xyXG4gICAgdGhpcy5pbWFnZVggPSBuZXdDYW52YXNYO1xyXG4gICAgdGhpcy5pbWFnZVkgPSBuZXdDYW52YXNZO1xyXG5cclxuICAgIGlmICghdGhpcy52ZXJpZmljYUltYWdlbWRlbnRyb0Rvc0xpbWl0ZVhtaW4oKSkge1xyXG4gICAgICBjb25zdCBkaWZmWG1pbiA9IHRoaXMucmV0b3JuYURpZmZYbWF4KCk7XHJcbiAgICAgIHRoaXMubW92ZUltYWdlKHRoaXMuaW1hZ2VYIC0gZGlmZlhtaW4pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy52ZXJpZmljYUltYWdlbWRlbnRyb0Rvc0xpbWl0ZVhtYXgoKSkge1xyXG4gICAgICBjb25zdCBkaWZmWG1heCA9IHRoaXMucmV0b3JuYURpZmZYbWluKCk7XHJcbiAgICAgIHRoaXMubW92ZUltYWdlKHRoaXMuaW1hZ2VYICsgZGlmZlhtYXgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy52ZXJpZmljYUltYWdlbWRlbnRyb0Rvc0xpbWl0ZVltYXgoKSkge1xyXG4gICAgICBjb25zdCBkaWZmWW1heCA9IHRoaXMucmV0b3JuYURpZmZZbWluKCk7XHJcbiAgICAgIHRoaXMubW92ZUltYWdlKHVuZGVmaW5lZCwgdGhpcy5pbWFnZVkgKyBkaWZmWW1heCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLnZlcmlmaWNhSW1hZ2VtZGVudHJvRG9zTGltaXRlWW1pbigpKSB7XHJcbiAgICAgIGNvbnN0IGRpZmZZbWluID0gdGhpcy5yZXRvcm5hRGlmZlltYXgoKTtcclxuICAgICAgdGhpcy5tb3ZlSW1hZ2UodW5kZWZpbmVkLCB0aGlzLmltYWdlWSAtIGRpZmZZbWluKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcyh0aGlzLmN0eCgpISwgdGhpcy5fSW1hZ2UoKSEpO1xyXG4gIH1cclxuXHJcblxyXG5cclxuXHJcbiAgdmVyaWZpY2FJbWFnZW1kZW50cm9Eb3NMaW1pdGVYbWluKCk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgbmV3SW1hZ2VYID0gdGhpcy5pbWFnZVg7XHJcbiAgICByZXR1cm4gbmV3SW1hZ2VYIDwgdGhpcy54TWluKCkhXHJcbiAgfVxyXG4gIHZlcmlmaWNhSW1hZ2VtZGVudHJvRG9zTGltaXRlWG1heCgpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IG5ld0ltYWdlWCA9IHRoaXMuaW1hZ2VYO1xyXG4gICAgcmV0dXJuIG5ld0ltYWdlWCA+IHRoaXMueE1heCgpIVxyXG4gIH1cclxuICB2ZXJpZmljYUltYWdlbWRlbnRyb0Rvc0xpbWl0ZVltaW4oKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBuZXdJbWFnZVkgPSB0aGlzLmltYWdlWTtcclxuICAgIHJldHVybiBuZXdJbWFnZVkgPCB0aGlzLnlNaW4oKSFcclxuICB9XHJcbiAgdmVyaWZpY2FJbWFnZW1kZW50cm9Eb3NMaW1pdGVZbWF4KCk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgbmV3SW1hZ2VZID0gdGhpcy5pbWFnZVk7XHJcbiAgICByZXR1cm4gbmV3SW1hZ2VZID4gdGhpcy55TWF4KCkhXHJcbiAgfVxyXG5cclxuICByZXRvcm5hRGlmZlhtaW4oKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IG5ld0ltYWdlWCA9IHRoaXMuaW1hZ2VYO1xyXG4gICAgcmV0dXJuIHRoaXMueE1pbigpISAtIG5ld0ltYWdlWDtcclxuICB9XHJcbiAgcmV0b3JuYURpZmZYbWF4KCk6IG51bWJlciB7XHJcbiAgICBjb25zdCBuZXdJbWFnZVggPSB0aGlzLmltYWdlWDtcclxuICAgIHJldHVybiBuZXdJbWFnZVggLSB0aGlzLnhNYXgoKSE7XHJcbiAgfVxyXG4gIHJldG9ybmFEaWZmWW1pbigpOiBudW1iZXIge1xyXG4gICAgY29uc3QgbmV3SW1hZ2VZID0gdGhpcy5pbWFnZVk7XHJcbiAgICByZXR1cm4gdGhpcy55TWluKCkhIC0gbmV3SW1hZ2VZO1xyXG4gIH1cclxuICByZXRvcm5hRGlmZlltYXgoKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IG5ld0ltYWdlWSA9IHRoaXMuaW1hZ2VZO1xyXG4gICAgcmV0dXJuIG5ld0ltYWdlWSAtIHRoaXMueU1heCgpITtcclxuICB9XHJcblxyXG5cclxuICBpbml0aWFsaXplSW1hZ2VNb3ZlKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCwgaW1nOiBIVE1MSW1hZ2VFbGVtZW50KSB7XHJcbiAgICBsZXQgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG5cclxuICAgIGNhbnZhcy5zdHlsZS5jdXJzb3IgPSAnZ3JhYic7XHJcblxyXG4gICAgY2FudmFzLm9ubW91c2Vkb3duID0gKGUpID0+IHtcclxuICAgICAgaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgIGNhbnZhcy5zdHlsZS5jdXJzb3IgPSAnZ3JhYmJpbmcnO1xyXG4gICAgICB0aGlzLnN0YXJ0WCA9IGUub2Zmc2V0WCAtIHRoaXMuaW1hZ2VYO1xyXG4gICAgICB0aGlzLnN0YXJ0WSA9IGUub2Zmc2V0WSAtIHRoaXMuaW1hZ2VZO1xyXG4gICAgfTtcclxuXHJcbiAgICBjYW52YXMub25tb3VzZXVwID0gKCkgPT4ge1xyXG4gICAgICBpc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgIGNhbnZhcy5zdHlsZS5jdXJzb3IgPSAnZ3JhYic7XHJcbiAgICB9O1xyXG5cclxuICAgIGNhbnZhcy5vbm1vdXNlb3V0ID0gKCkgPT4ge1xyXG4gICAgICBpc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgIGNhbnZhcy5zdHlsZS5jdXJzb3IgPSAnZ3JhYic7XHJcbiAgICB9O1xyXG5cclxuICAgIGNhbnZhcy5vbm1vdXNlbW92ZSA9IChlKSA9PiB7XHJcbiAgICAgIGlmIChpc0RyYWdnaW5nKSB7XHJcblxyXG4gICAgICAgICAgLy8gQ2FsY3VsYSBvIG5vdm8gcG9zaWNpb25hbWVudG8gZGEgaW1hZ2VtXHJcbiAgICAgICAgICBsZXQgbmV3SW1hZ2VYID0gZS5vZmZzZXRYIC0gdGhpcy5zdGFydFg7XHJcbiAgICAgICAgICBsZXQgbmV3SW1hZ2VZID0gZS5vZmZzZXRZIC0gdGhpcy5zdGFydFk7XHJcblxyXG4gICAgICAgICAgaWYgKG5ld0ltYWdlWCA8ICB0aGlzLnhNaW4oKSEgJiYgbmV3SW1hZ2VYID4gdGhpcy54TWF4KCkhKSB7XHJcbiAgICAgICAgICAgIHRoaXMubW92ZUltYWdlKG5ld0ltYWdlWClcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmKG5ld0ltYWdlWSA8IHRoaXMueU1pbigpISAmJiBuZXdJbWFnZVkgPiB0aGlzLnlNYXgoKSEpe1xyXG4gICAgICAgICAgICB0aGlzLm1vdmVJbWFnZSh1bmRlZmluZWQsIG5ld0ltYWdlWSlcclxuICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgdGhpcy5yZWRyYXdDYW52YXMoY3R4LCBpbWcpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgfVxyXG5cclxuICBtb3ZlSW1hZ2UoZHg/OiBudW1iZXIsIGR5PzogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmltYWdlWCA9IChkeD8/dGhpcy5pbWFnZVgpO1xyXG4gICAgdGhpcy5pbWFnZVkgPSAoZHk/P3RoaXMuaW1hZ2VZKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG5cclxuICAvLyNyZWdpb24gTcOpdG9kb3MgZGUgY29ydGUgZSBmZWNoYW1lbnRvIGRvIG1vZGFsXHJcbiAgY3JvcEltYWdlKCkge1xyXG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHgoKTtcclxuXHJcbiAgICBpZiAoY3R4KSB7XHJcbiAgICAgIGNvbnN0IFggPSAoKHRoaXMuY2FudmFzKCkhLndpZHRoIC0gdGhpcy5fSW1hZ2UoKS53aWR0aCAqIHRoaXMuc2NhbGVGYWN0b3JSZWFkT25seSgpISkgLyAyKTtcclxuICAgICAgY29uc3QgWSA9ICgodGhpcy5jYW52YXNIZWlnaHQoKSEgLyAyKSAtICh0aGlzLl9JbWFnZSgpLmhlaWdodCAqIHRoaXMuc2NhbGVGYWN0b3JSZWFkT25seSgpISkgLyAyKTtcclxuXHJcbiAgICAgIC8vIFJlY3VwZXJhciBvIGltYWdlRGF0YSBkYSBpbWFnZW0gcXVlIGVzdMOhIG5hIMOhcmVhIGRlIGNvcnRlXHJcbiAgICAgIGxldCBpbWFnZURhdGFcclxuICAgICAgY29uc3QgY3JvcFggPSAoY3R4LmNhbnZhcy53aWR0aCAtIHRoaXMuY3V0V2lkdGgoKSEpIC8gMjtcclxuICAgICAgY29uc3QgY3JvcFkgPSAoY3R4LmNhbnZhcy5oZWlnaHQgLSB0aGlzLmN1dEhlaWdodCgpISkgLyAyO1xyXG4gICAgICBpZih0aGlzLl92YXJpYXZpZXNEaWFsb2coKT8uaW5kQ2lyY2xlKXtcclxuICAgICAgICAvLyBDcmVhdGUgYSBuZXcgY2FudmFzIHdpdGggdGhlIHNhbWUgZGltZW5zaW9ucyBhcyB0aGUgY2lyY2xlXHJcbiAgICAgICAgY29uc3QgY2lyY2xlQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XHJcbiAgICAgICAgY29uc3QgY2lyY2xlQ3R4ID0gY2lyY2xlQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcbiAgICAgICAgY2lyY2xlQ2FudmFzLndpZHRoID0gdGhpcy5yYWRpdXMoKSEgKiAyO1xyXG4gICAgICAgIGNpcmNsZUNhbnZhcy5oZWlnaHQgPSB0aGlzLnJhZGl1cygpISAqIDI7XHJcblxyXG4gICAgICAgIC8vIERyYXcgdGhlIGNpcmNsZSBvbiB0aGUgbmV3IGNhbnZhc1xyXG4gICAgICAgIGNpcmNsZUN0eCEuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgY2lyY2xlQ3R4IS5hcmModGhpcy5yYWRpdXMoKSEsIHRoaXMucmFkaXVzKCkhLCB0aGlzLnJhZGl1cygpISwgMCwgMiAqIE1hdGguUEkpO1xyXG4gICAgICAgIGNpcmNsZUN0eCEuZmlsbCgpO1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gdG8gJ2Rlc3RpbmF0aW9uLWluJyB0byBjdXQgb3V0IHRoZSBjaXJjbGVcclxuICAgICAgICBjdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2Rlc3RpbmF0aW9uLWluJztcclxuXHJcbiAgICAgICAgLy8gRHJhdyB0aGUgaW1hZ2Ugb24gdGhlIG1haW4gY2FudmFzIHVzaW5nIHRoZSBjaXJjbGUgYXMgYSBtYXNrXHJcbiAgICAgICAgY3R4LmRyYXdJbWFnZShjaXJjbGVDYW52YXMsIGNyb3BYLCBjcm9wWSk7XHJcblxyXG4gICAgICAgIC8vIFJlc2V0IHRoZSBjb21wb3NpdGUgb3BlcmF0aW9uIHRvIHRoZSBkZWZhdWx0IHZhbHVlXHJcbiAgICAgICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdzb3VyY2Utb3Zlcic7XHJcblxyXG4gICAgICAgIC8vIEdldCB0aGUgaW1hZ2UgZGF0YSBvZiB0aGUgY3JvcHBlZCBjaXJjbGVcclxuICAgICAgICBpbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKGNyb3BYLCBjcm9wWSwgdGhpcy5yYWRpdXMoKSEgKiAyLCB0aGlzLnJhZGl1cygpISAqIDIpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGltYWdlRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoY3JvcFgsIGNyb3BZLCB0aGlzLmN1dFdpZHRoKCkhLCB0aGlzLmN1dEhlaWdodCgpISk7XHJcbiAgICAgIH1cclxuXHJcblxyXG4gICAgICAvLyBPYnRlciBvcyB2YWxvcmVzIGRlIHdpZHRoIGUgaGVpZ2h0IGRhIHZhcmnDoXZlbCBfdmFyaWF2aWVzRGlhbG9nXHJcbiAgICAgIGNvbnN0IHZhcmlhdmVpc0RpYWxvZyA9IHRoaXMuX3Zhcmlhdmllc0RpYWxvZygpO1xyXG4gICAgICBpZiAodmFyaWF2ZWlzRGlhbG9nKSB7XHJcbiAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB2YXJpYXZlaXNEaWFsb2c7XHJcblxyXG4gICAgICAgIC8vIENyaWFyIHVtIG5vdm8gY2FudmFzIGUgY29udGV4dG8gY29tIG9zIHZhbG9yZXMgZGUgd2lkdGggZSBoZWlnaHRcclxuICAgICAgICBjb25zdCBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcclxuICAgICAgICBjb25zdCBuZXdDdHggPSBuZXdDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgICAgICBuZXdDYW52YXMud2lkdGggPSB3aWR0aDtcclxuICAgICAgICBuZXdDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG5cclxuICAgICAgICBpZiAobmV3Q3R4KSB7XHJcbiAgICAgICAgICAvLyBSZWRpbWVuc2lvbmFyIGEgaW1hZ2VtIHBhcmEgbyB0YW1hbmhvIGVzcGVjaWZpY2Fkb1xyXG4gICAgICAgICAgY29uc3QgdGVtcENhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgICAgICAgY29uc3QgdGVtcEN0eCA9IHRlbXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgICAgICAgIHRlbXBDYW52YXMud2lkdGggPSB0aGlzLmN1dFdpZHRoKCkhO1xyXG4gICAgICAgICAgdGVtcENhbnZhcy5oZWlnaHQgPSB0aGlzLmN1dEhlaWdodCgpITtcclxuICAgICAgICAgIHRlbXBDdHghLnB1dEltYWdlRGF0YShpbWFnZURhdGEsIDAsIDApO1xyXG5cclxuICAgICAgICAgIG5ld0N0eC5kcmF3SW1hZ2UodGVtcENhbnZhcywgMCwgMCwgd2lkdGgsIGhlaWdodCk7XHJcblxyXG4gICAgICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjcm9wSW1hZ2UnLCB7IGRldGFpbDp7XHJcbiAgICAgICAgICAgIHJlc3VsdDogUHJvbWlzZS5yZXNvbHZlKG5ld0NhbnZhcy50b0RhdGFVUkwoKSksXHJcbiAgICAgICAgICAgIHN0YXR1czogdHJ1ZVxyXG4gICAgICAgICAgfSB9KSk7XHJcbiAgICAgICAgICB0aGlzLmNsb3NlQ3JvcE1vZGFsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjbG9zZUNyb3BNb2RhbCgpIHtcclxuICAgIHRoaXMuZGlhbG9nSW5zdGFuY2UuY2xvc2UoKTtcclxuICB9XHJcblxyXG4gIGNhbmNlbCgpe1xyXG4gICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KCdjcm9wSW1hZ2UnLCB7IGRldGFpbDp7XHJcbiAgICAgIHJlc3VsdDogUHJvbWlzZS5yZXNvbHZlKCdjYW5jZWwnKSxcclxuICAgICAgc3RhdHVzOiBmYWxzZVxyXG4gICAgfSB9KSk7XHJcblxyXG4gICAgdGhpcy5jbG9zZUNyb3BNb2RhbCgpXHJcbiAgfVxyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxufVxyXG4iXX0=
|