UNPKG

138 kBJavaScriptView Raw
1import { Injectable, Component, Input, Output, EventEmitter, ViewChild, NgModule } from '@angular/core';
2import { fabric } from 'fabric';
3import { ActionSheetController, IonicModule } from 'ionic-angular';
4import { Gesture } from 'ionic-angular/gestures/gesture';
5import { TranslateService } from '@ngx-translate/core';
6import { CommonModule } from '@angular/common';
7
8/**
9 * @fileoverview added by tsickle
10 * @suppress {checkTypes} checked by tsc
11 */
12/** @enum {number} */
13const AvailableGeometricShape = {
14 "Rectangle": 0,
15 "Circle": 1,
16 "Triangle": 2,
17 "Line": 3,
18 "Cross": 4,
19};
20AvailableGeometricShape[AvailableGeometricShape["Rectangle"]] = "Rectangle";
21AvailableGeometricShape[AvailableGeometricShape["Circle"]] = "Circle";
22AvailableGeometricShape[AvailableGeometricShape["Triangle"]] = "Triangle";
23AvailableGeometricShape[AvailableGeometricShape["Line"]] = "Line";
24AvailableGeometricShape[AvailableGeometricShape["Cross"]] = "Cross";
25
26/**
27 * @fileoverview added by tsickle
28 * @suppress {checkTypes} checked by tsc
29 */
30const /** @type {?} */ SHAPE_DATA = {
31 width: 200,
32 height: 200,
33 left: 50,
34 top: 50,
35 radius: 100,
36 stroke: 10,
37 freeDrawingBrushWidth: 10,
38 cornerSize: 20
39};
40
41/**
42 * @fileoverview added by tsickle
43 * @suppress {checkTypes} checked by tsc
44 */
45class CanvasManagerService {
46 constructor() {
47 this.emptyCanvas();
48 this.mousePosition = { x: 0, y: 0 };
49 this.cropStartingPosition = { x: 0, y: 0 };
50 }
51 /**
52 * @return {?}
53 */
54 get backgroundImage() {
55 return this.canvas;
56 }
57 /**
58 * @return {?}
59 */
60 get canvasObjects() {
61 return this.canvas.getObjects();
62 }
63 /**
64 * @return {?}
65 */
66 get canvasBackgroundImage() {
67 return this.canvas.backgroundImage;
68 }
69 /**
70 * @return {?}
71 */
72 get activeObject() {
73 return this.canvas.getActiveObject();
74 }
75 /**
76 * @return {?}
77 */
78 get activeGroup() {
79 return this.canvas.getActiveObjects();
80 }
81 /**
82 * @return {?}
83 */
84 emptyCanvas() {
85 if (this.canvas) {
86 this.canvas.dispose();
87 }
88 this.canvas = new fabric.Canvas('canvas');
89 this.canvas.clear();
90 this.canvas.remove(this.canvas.getObjects());
91 }
92 /**
93 * @param {?=} backgroundImageURL
94 * @return {?}
95 */
96 loadNewImage(backgroundImageURL) {
97 this.emptyCanvas();
98 if (backgroundImageURL) {
99 this.setBackgroundFromURL(backgroundImageURL);
100 }
101 }
102 /**
103 * @return {?}
104 */
105 renderCanvas() {
106 this.markSelectedObjectsDirty();
107 this.canvas.renderAll();
108 }
109 /**
110 * @param {?} strokeColor
111 * @param {?} fillColor
112 * @param {?} shape
113 * @return {?}
114 */
115 addGeometricShape(strokeColor, fillColor, shape) {
116 switch (shape) {
117 case AvailableGeometricShape.Rectangle:
118 this.addRectangle(strokeColor, fillColor);
119 break;
120 case AvailableGeometricShape.Circle:
121 this.addCircle(strokeColor, fillColor);
122 break;
123 case AvailableGeometricShape.Triangle:
124 this.addTriangle(strokeColor, fillColor);
125 break;
126 case AvailableGeometricShape.Line:
127 this.addHorizontalLine(strokeColor, fillColor);
128 break;
129 case AvailableGeometricShape.Cross:
130 this.addCross(strokeColor, fillColor);
131 break;
132 }
133 }
134 /**
135 * @param {?} strokeColor
136 * @param {?} fillColor
137 * @return {?}
138 */
139 addRectangle(strokeColor, fillColor) {
140 this.canvas.add(new fabric.Rect({
141 width: SHAPE_DATA.width,
142 height: SHAPE_DATA.height,
143 left: SHAPE_DATA.left,
144 top: SHAPE_DATA.top,
145 fill: fillColor,
146 stroke: strokeColor,
147 strokeWidth: SHAPE_DATA.stroke,
148 cornerSize: SHAPE_DATA.cornerSize
149 }));
150 }
151 /**
152 * @param {?} strokeColor
153 * @param {?} fillColor
154 * @return {?}
155 */
156 addCircle(strokeColor, fillColor) {
157 this.canvas.add(new fabric.Circle({
158 left: SHAPE_DATA.left,
159 top: SHAPE_DATA.top,
160 radius: SHAPE_DATA.radius,
161 stroke: strokeColor,
162 strokeWidth: SHAPE_DATA.stroke,
163 fill: fillColor,
164 cornerSize: SHAPE_DATA.cornerSize
165 }));
166 }
167 /**
168 * @param {?} strokeColor
169 * @param {?} fillColor
170 * @return {?}
171 */
172 addTriangle(strokeColor, fillColor) {
173 this.canvas.add(new fabric.Triangle({
174 width: SHAPE_DATA.width,
175 height: SHAPE_DATA.height,
176 left: SHAPE_DATA.left,
177 top: SHAPE_DATA.top,
178 fill: fillColor,
179 stroke: strokeColor,
180 strokeWidth: SHAPE_DATA.stroke,
181 cornerSize: SHAPE_DATA.cornerSize
182 }));
183 }
184 /**
185 * @param {?} strokeColor
186 * @param {?} fillColor
187 * @return {?}
188 */
189 addHorizontalLine(strokeColor, fillColor) {
190 this.canvas.add(this.createHorizontalLine(strokeColor));
191 }
192 /**
193 * @param {?} strokeColor
194 * @return {?}
195 */
196 createHorizontalLine(strokeColor) {
197 const /** @type {?} */ line = new fabric.Line([100, 150, 200, 150], {
198 left: 50,
199 top: 100,
200 stroke: strokeColor,
201 strokeWidth: 5,
202 cornerSize: SHAPE_DATA.cornerSize
203 });
204 line.setControlsVisibility({
205 bl: false,
206 br: false,
207 tl: false,
208 tr: false,
209 mt: false,
210 mb: false
211 });
212 return line;
213 }
214 /**
215 * @param {?} strokeColor
216 * @return {?}
217 */
218 createVerticalLine(strokeColor) {
219 const /** @type {?} */ line = new fabric.Line([150, 100, 150, 200], {
220 left: 100,
221 top: 50,
222 stroke: strokeColor,
223 strokeWidth: 5,
224 cornerSize: SHAPE_DATA.cornerSize
225 });
226 line.setControlsVisibility({
227 bl: false,
228 br: false,
229 tl: false,
230 tr: false,
231 ml: false,
232 mr: false
233 });
234 return line;
235 }
236 /**
237 * @param {?} strokeColor
238 * @param {?} fillColor
239 * @return {?}
240 */
241 addCross(strokeColor, fillColor) {
242 const /** @type {?} */ horizontalLine = this.createHorizontalLine(strokeColor);
243 const /** @type {?} */ verticalLine = this.createVerticalLine(strokeColor);
244 this.canvas.add(horizontalLine);
245 this.canvas.add(verticalLine);
246 }
247 /**
248 * @return {?}
249 */
250 toggleFreeDrawing() {
251 this.canvas.isDrawingMode = !this.canvas.isDrawingMode;
252 }
253 /**
254 * @param {?} color
255 * @return {?}
256 */
257 setFreeDrawingBrushColor(color) {
258 this.canvas.freeDrawingBrush.color = color;
259 this.setFreeDrawingBrushWidthFromZoom(this.canvas.getZoom());
260 }
261 /**
262 * @param {?} zoom
263 * @return {?}
264 */
265 setFreeDrawingBrushWidthFromZoom(zoom) {
266 this.canvas.freeDrawingBrush.width = SHAPE_DATA.freeDrawingBrushWidth * (1 / zoom);
267 }
268 /**
269 * @param {?} color
270 * @param {?} inputText
271 * @return {?}
272 */
273 addText(color, inputText) {
274 const /** @type {?} */ text = new fabric.IText('text', {
275 fontFamily: 'arial black',
276 fontStyle: 'bold',
277 left: SHAPE_DATA.left,
278 top: SHAPE_DATA.top,
279 cornerSize: SHAPE_DATA.cornerSize
280 });
281 text.setColor(color);
282 this.canvas.add(text);
283 }
284 /**
285 * @param {?} imageURL
286 * @return {?}
287 */
288 addImage(imageURL) {
289 return new Promise((resolve, reject) => {
290 const /** @type {?} */ canvas = this.canvas;
291 const /** @type {?} */ image = new Image();
292 image.onload = function (img) {
293 const /** @type {?} */ fabricImage = new fabric.Image(image, {
294 angle: 0,
295 width: image.width,
296 height: image.height,
297 left: SHAPE_DATA.left,
298 top: SHAPE_DATA.top,
299 scaleX: 1,
300 scaleY: 1,
301 cornerSize: SHAPE_DATA.cornerSize
302 });
303 canvas.add(fabricImage);
304 resolve();
305 };
306 image.src = imageURL;
307 });
308 }
309 /**
310 * @param {?} backgroundImageURL
311 * @return {?}
312 */
313 setBackgroundFromURL(backgroundImageURL) {
314 const /** @type {?} */ canvas = this.canvas;
315 const /** @type {?} */ resize = this.resizeCanvasAndComputeScaleFactor;
316 return new Promise((resolve, reject) => {
317 if (backgroundImageURL == null) {
318 return reject();
319 }
320 const /** @type {?} */ image = new Image();
321 image.onload = function () {
322 const /** @type {?} */ f_img = new fabric.Image(image, {});
323 const /** @type {?} */ scaleData = resize(f_img, canvas);
324 canvas.setBackgroundImage(f_img, canvas.renderAll.bind(canvas), {
325 scaleX: scaleData.scaleFactor,
326 scaleY: scaleData.scaleFactor
327 });
328 canvas.renderAll();
329 resolve();
330 };
331 image.src = backgroundImageURL;
332 });
333 }
334 /**
335 * @param {?} f_img
336 * @param {?} canvas
337 * @return {?}
338 */
339 resizeCanvasAndComputeScaleFactor(f_img, canvas) {
340 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
341 canvas.setWidth(container.clientWidth);
342 canvas.setHeight(container.clientHeight);
343 const /** @type {?} */ canvasWidth = canvas.getWidth();
344 const /** @type {?} */ canvasHeight = canvas.getHeight();
345 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
346 const /** @type {?} */ imgAspect = f_img.width / f_img.height;
347 let /** @type {?} */ left, /** @type {?} */ top, /** @type {?} */ scaleFactor;
348 if (canvasAspect <= imgAspect) {
349 scaleFactor = canvasWidth / f_img.width;
350 left = 0;
351 top = -(f_img.height * scaleFactor - canvasHeight) / 2;
352 }
353 else {
354 scaleFactor = canvasHeight / f_img.height;
355 top = 0;
356 left = -(f_img.width * scaleFactor - canvasWidth) / 2;
357 }
358 return { scaleFactor: scaleFactor, left: left, top: top };
359 }
360 /**
361 * @return {?}
362 */
363 onOrientationChange() {
364 this.mousePosition = { x: this.canvas.getWidth, y: this.canvas.getHeight };
365 this.cropImage();
366 }
367 /**
368 * @param {?} color
369 * @return {?}
370 */
371 changeSelectedObjectsFillColor(color) {
372 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
373 if (activeObjects) {
374 for (const /** @type {?} */ object of activeObjects) {
375 object.setColor(color);
376 this.canvas.renderAll();
377 }
378 }
379 }
380 /**
381 * @param {?} color
382 * @return {?}
383 */
384 changeSelectedObjectsStrokeColor(color) {
385 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
386 if (activeObjects) {
387 for (const /** @type {?} */ object of activeObjects) {
388 if (object.type === 'i-text') {
389 object.setColor(color);
390 }
391 else {
392 object.stroke = color;
393 object.set('dirty', true);
394 }
395 }
396 this.canvas.renderAll();
397 }
398 }
399 /**
400 * @return {?}
401 */
402 deleteSelectedObjects() {
403 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
404 if (activeObjects) {
405 for (const /** @type {?} */ object of activeObjects) {
406 this.canvas.remove(object);
407 }
408 this.canvas.discardActiveObject();
409 this.canvas.renderAll();
410 }
411 }
412 /**
413 * @return {?}
414 */
415 bringSelectedObjectsToFront() {
416 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
417 if (activeObjects) {
418 for (const /** @type {?} */ object of activeObjects) {
419 this.canvas.bringToFront(object);
420 }
421 }
422 }
423 /**
424 * @return {?}
425 */
426 sendSelectedObjectsToBack() {
427 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
428 if (activeObjects) {
429 for (const /** @type {?} */ object of activeObjects) {
430 this.canvas.sendToBack(object);
431 }
432 }
433 }
434 /**
435 * @return {?}
436 */
437 jsonFromCanvas() {
438 return this.canvas.toJSON();
439 }
440 /**
441 * @param {?} json
442 * @return {?}
443 */
444 loadfromJson(json) {
445 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
446 this.canvas.setWidth(container.clientWidth);
447 this.canvas.setHeight(container.clientHeight);
448 return new Promise((resolve, reject) => {
449 this.adjustCanvas(json);
450 this.canvas.loadFromJSON(json, this.canvas.renderAll.bind(this.canvas));
451 resolve();
452 });
453 }
454 /**
455 * @param {?} json
456 * @return {?}
457 */
458 adjustCanvas(json) {
459 const /** @type {?} */ backgroundImage = json['backgroundImage'];
460 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
461 const /** @type {?} */ width = backgroundImage['width'];
462 const /** @type {?} */ height = backgroundImage['height'];
463 const /** @type {?} */ canvasWidth = container.clientWidth;
464 const /** @type {?} */ canvasHeight = container.clientHeight;
465 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
466 const /** @type {?} */ imgAspect = width / height;
467 let /** @type {?} */ scaleFactor;
468 if (canvasAspect <= imgAspect) {
469 scaleFactor = canvasWidth / width;
470 }
471 else {
472 scaleFactor = canvasHeight / height;
473 }
474 const /** @type {?} */ objectScale = scaleFactor / backgroundImage['scaleX'];
475 backgroundImage['scaleX'] = scaleFactor;
476 backgroundImage['scaleY'] = scaleFactor;
477 this.canvas.setWidth(width * scaleFactor);
478 this.canvas.setHeight(height * scaleFactor);
479 const /** @type {?} */ objects = json['objects'];
480 for (let /** @type {?} */ i = 0; i < objects.length; i++) {
481 objects[i]['left'] *= objectScale;
482 objects[i]['top'] *= objectScale;
483 objects[i]['scaleX'] *= objectScale;
484 objects[i]['scaleY'] *= objectScale;
485 }
486 this.canvas.selectable = true;
487 this.canvas.selection = true;
488 this.canvas.renderAll();
489 }
490 /**
491 * @return {?}
492 */
493 exportImageAsDataURL() {
494 return this.canvas.toDataURL('image/png');
495 }
496 /**
497 * @param {?} itemNumber
498 * @return {?}
499 */
500 selectItem(itemNumber) {
501 this.canvas.setActiveObject(this.canvas.item(itemNumber));
502 }
503 /**
504 * @param {?} activeObject
505 * @return {?}
506 */
507 getIndexOf(activeObject) {
508 return this.canvas.getObjects().indexOf(activeObject);
509 }
510 /**
511 * @return {?}
512 */
513 selectLastObject() {
514 const /** @type {?} */ itemNumber = this.canvas.getObjects().length - 1;
515 const /** @type {?} */ object = this.canvas.item(itemNumber);
516 this.canvas.setActiveObject(object);
517 object.enterEditing();
518 }
519 /**
520 * @return {?}
521 */
522 markSelectedObjectsDirty() {
523 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
524 if (activeObjects) {
525 for (const /** @type {?} */ object of activeObjects) {
526 object.set('dirty', true);
527 }
528 }
529 }
530 /**
531 * @return {?}
532 */
533 addSelectionRectangle() {
534 this.cropRectangle = new fabric.Rect({
535 fill: 'transparent',
536 originX: 'left',
537 originY: 'top',
538 stroke: '#ccc',
539 strokeDashArray: [2, 2],
540 opacity: 1,
541 width: 1,
542 height: 1
543 });
544 this.cropRectangle.visible = false;
545 this.canvas.add(this.cropRectangle);
546 }
547 /**
548 * @param {?} event
549 * @return {?}
550 */
551 ajustCropRectangleFromMouse(event) {
552 const /** @type {?} */ x = Math.min(event.layerX, this.mousePosition.x), /** @type {?} */
553 y = Math.min(event.layerY, this.mousePosition.y), /** @type {?} */
554 w = Math.abs(event.layerX - this.mousePosition.x), /** @type {?} */
555 h = Math.abs(event.layerY - this.mousePosition.y);
556 if (!w || !h) {
557 return false;
558 }
559 this.cropRectangle
560 .set('top', y)
561 .set('left', x)
562 .set('width', w)
563 .set('height', h);
564 this.canvas.renderAll();
565 return true;
566 }
567 /**
568 * @param {?} event
569 * @return {?}
570 */
571 startSelectingCropRectangleFromMouse(event) {
572 this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
573 this.cropRectangle.left = event.layerX;
574 this.cropRectangle.top = event.layerY;
575 this.cropRectangle.setCoords();
576 this.mousePosition = { x: event.layerX, y: event.layerY };
577 this.canvas.renderAll();
578 this.cropRectangle.visible = true;
579 this.canvas.bringToFront(this.cropRectangle);
580 }
581 /**
582 * @return {?}
583 */
584 cropImage() {
585 const /** @type {?} */ left = this.cropRectangle.left;
586 const /** @type {?} */ top = this.cropRectangle.top;
587 const /** @type {?} */ width = this.cropRectangle.width;
588 const /** @type {?} */ height = this.cropRectangle.height;
589 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
590 const /** @type {?} */ canvasWidth = container.clientWidth;
591 const /** @type {?} */ canvasHeight = container.clientHeight;
592 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
593 const /** @type {?} */ imgAspect = width / height;
594 let /** @type {?} */ scaleFactor;
595 if (canvasAspect <= imgAspect) {
596 scaleFactor = canvasWidth / width;
597 }
598 else {
599 scaleFactor = canvasHeight / height;
600 }
601 this.canvas.setWidth(width * scaleFactor);
602 this.canvas.setHeight(height * scaleFactor);
603 this.canvas.backgroundImage.scaleX *= scaleFactor;
604 this.canvas.backgroundImage.scaleY *= scaleFactor;
605 this.canvas.backgroundImage.left -= left;
606 this.canvas.backgroundImage.left *= scaleFactor;
607 this.canvas.backgroundImage.top -= top - scaleFactor;
608 this.canvas.backgroundImage.top *= scaleFactor;
609 this.moveAllObjectsInCanvas(-1 * left, -1 * top, scaleFactor);
610 this.enableSlection();
611 this.cropRectangle.visible = false;
612 this.canvas.remove(this.cropRectangle);
613 this.canvas.renderAll();
614 }
615 /**
616 * @return {?}
617 */
618 enableSlection() {
619 this.canvas.selectable = true;
620 this.canvas.selection = true;
621 }
622 /**
623 * @param {?} event
624 * @return {?}
625 */
626 ajustCropRectangle(event) {
627 const /** @type {?} */ touch = event.touches[0];
628 const /** @type {?} */ rect = event.target.getBoundingClientRect();
629 const /** @type {?} */ x = Math.min(touch.clientX - rect.left, this.mousePosition.x), /** @type {?} */
630 y = Math.min(touch.clientY - rect.top, this.mousePosition.y), /** @type {?} */
631 w = Math.abs(touch.clientX - rect.left - this.mousePosition.x), /** @type {?} */
632 h = Math.abs(touch.clientY - rect.top - this.mousePosition.y);
633 if (!w || !h) {
634 return false;
635 }
636 this.cropRectangle
637 .set('left', x)
638 .set('top', y)
639 .set('width', w)
640 .set('height', h);
641 this.canvas.renderAll();
642 return true;
643 }
644 /**
645 * @param {?} event
646 * @return {?}
647 */
648 startSelectingCropRectangle(event) {
649 this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
650 const /** @type {?} */ touch = event.touches[0];
651 const /** @type {?} */ rect = event.target.getBoundingClientRect();
652 this.cropRectangle.left = touch.clientX - rect.left;
653 this.cropRectangle.top = touch.clientY - rect.top;
654 this.cropRectangle.setCoords();
655 this.mousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
656 this.canvas.renderAll();
657 this.cropRectangle.visible = true;
658 this.canvas.bringToFront(this.cropRectangle);
659 }
660 /**
661 * @return {?}
662 */
663 disableSelection() {
664 this.canvas.selection = false;
665 }
666 /**
667 * @param {?} x
668 * @param {?} y
669 * @param {?} scaleFactor
670 * @return {?}
671 */
672 moveAllObjectsInCanvas(x, y, scaleFactor) {
673 const /** @type {?} */ objects = this.canvas.getObjects();
674 for (const /** @type {?} */ obj of objects) {
675 obj.left += x;
676 obj.left *= scaleFactor;
677 obj.scaleX *= scaleFactor;
678 obj.top += y;
679 obj.scaleY *= scaleFactor;
680 obj.top *= scaleFactor;
681 obj.setCoords();
682 }
683 }
684 /**
685 * @return {?}
686 */
687 groupSelectedObjects() {
688 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
689 if (activeObjects) {
690 const /** @type {?} */ objects = [];
691 for (const /** @type {?} */ object of activeObjects) {
692 objects.push(object);
693 }
694 this.deleteSelectedObjects();
695 const /** @type {?} */ group = new fabric.Group(objects);
696 this.canvas.add(group);
697 group.setCoords();
698 this.canvas.setActiveObject(group);
699 this.canvas.renderAll();
700 }
701 }
702 /**
703 * @param {?} event
704 * @return {?}
705 */
706 setLastPanPosition(event) {
707 this.lastPanPosition = new fabric.Point(event.touches[0].clientX, event.touches[0].clientY);
708 }
709 /**
710 * @param {?} event
711 * @return {?}
712 */
713 panCanvas(event) {
714 const /** @type {?} */ delta = new fabric.Point(event.touches[0].clientX - this.lastPanPosition.x, event.touches[0].clientY - this.lastPanPosition.y);
715 this.canvas.relativePan(delta);
716 this.preventPanOutsideCanvas();
717 this.canvas.renderAll();
718 this.setLastPanPosition(event);
719 }
720 /**
721 * @return {?}
722 */
723 preventPanOutsideCanvas() {
724 const /** @type {?} */ canvasViewPort = this.canvas.viewportTransform;
725 const /** @type {?} */ bottomEndPoint = this.canvas.height * (canvasViewPort[0] - 1);
726 if (canvasViewPort[5] >= 0 || -bottomEndPoint > canvasViewPort[5]) {
727 canvasViewPort[5] = (canvasViewPort[5] >= 0) ? 0 : -bottomEndPoint;
728 }
729 const /** @type {?} */ rightEndPoint = this.canvas.width * (canvasViewPort[0] - 1);
730 if (canvasViewPort[4] >= 0 || -rightEndPoint > canvasViewPort[4]) {
731 canvasViewPort[4] = (canvasViewPort[4] >= 0) ? 0 : -rightEndPoint;
732 }
733 }
734 /**
735 * @param {?} event
736 * @return {?}
737 */
738 zoom(event) {
739 if (Math.abs(event.overallVelocity) > 0.005) {
740 const /** @type {?} */ point = new fabric.Point(event.center.x, event.center.y);
741 let /** @type {?} */ zoom = this.canvas.getZoom();
742 zoom = zoom + (event.scale - zoom) / 20;
743 if (zoom < 1) {
744 zoom = 1;
745 this.canvas.zoomToPoint(new fabric.Point(0, 0), zoom);
746 this.canvas.absolutePan(new fabric.Point(0, 0));
747 }
748 else {
749 if (zoom > 10) {
750 zoom = 10;
751 }
752 this.canvas.zoomToPoint(point, zoom);
753 }
754 this.setFreeDrawingBrushWidthFromZoom(zoom);
755 this.canvas.renderAll();
756 }
757 }
758 /**
759 * @return {?}
760 */
761 resetZoom() {
762 this.canvas.zoomToPoint(new fabric.Point(0, 0), 1);
763 this.canvas.absolutePan(new fabric.Point(0, 0));
764 }
765}
766CanvasManagerService.decorators = [
767 { type: Injectable },
768];
769/** @nocollapse */
770CanvasManagerService.ctorParameters = () => [];
771
772/**
773 * @fileoverview added by tsickle
774 * @suppress {checkTypes} checked by tsc
775 */
776const /** @type {?} */ Black = '#000000';
777const /** @type {?} */ Transparent = 'transparent';
778class MobileSketchToolComponent {
779 /**
780 * @param {?} actionSheetCtrl
781 * @param {?} canvasManagerService
782 * @param {?} translate
783 */
784 constructor(actionSheetCtrl, canvasManagerService, translate) {
785 this.actionSheetCtrl = actionSheetCtrl;
786 this.canvasManagerService = canvasManagerService;
787 this.translate = translate;
788 this.canvas = new EventEmitter();
789 this.strokeColor = Black;
790 this.fillColor = Transparent;
791 this.isCropping = false;
792 this.isPanning = false;
793 this.isLoaded = false;
794 this.isUndoAvailable = false;
795 this.isSelectingColor = false;
796 }
797 /**
798 * @return {?}
799 */
800 ngOnInit() {
801 if (this.imageData) {
802 this.canvasManagerService.emptyCanvas();
803 if (this.loadedJson == null || this.loadedJson.length < 10) {
804 this.canvasManagerService.setBackgroundFromURL(this.imageData);
805 }
806 else {
807 this.previousJson = JSON.parse(this.loadedJson);
808 this.currentJson = this.previousJson;
809 this.canvasManagerService
810 .loadfromJson(JSON.parse(this.loadedJson));
811 }
812 this.isLoaded = true;
813 this.previousImageData = this.imageData;
814 }
815 this.emitCanvas();
816 }
817 /**
818 * @return {?}
819 */
820 ngOnChanges() {
821 if (this.isLoaded) {
822 if (this.loadedJson === null || this.loadedJson.length < 10 || this.imageData !== this.previousImageData) {
823 this.canvasManagerService.emptyCanvas();
824 this.canvasManagerService.setBackgroundFromURL(this.imageData);
825 this.previousImageData = this.imageData;
826 this.currentJson = null;
827 }
828 else if (this.loadedJson !== JSON.stringify(this.currentJson)) {
829 this.previousJson = JSON.parse(this.loadedJson);
830 this.currentJson = this.previousJson;
831 this.canvasManagerService
832 .loadfromJson(JSON.parse(this.loadedJson));
833 }
834 }
835 this.emitCanvas();
836 }
837 /**
838 * @return {?}
839 */
840 ngAfterViewInit() {
841 this.gesture = new Gesture(this.element.nativeElement);
842 this.gesture.listen();
843 this.gesture.on('pinch', $event => this.pinch($event));
844 }
845 /**
846 * @return {?}
847 */
848 ngOnDestroy() {
849 this.gesture.destroy();
850 }
851 /**
852 * @return {?}
853 */
854 get hasPictograms() {
855 return !(!this.icons);
856 }
857 /**
858 * @return {?}
859 */
860 addText() {
861 this.canvasManagerService.addText(this.strokeColor, 'text ');
862 this.emitCanvas();
863 }
864 /**
865 * @param {?} shape
866 * @return {?}
867 */
868 addShape(shape) {
869 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape[shape]);
870 this.emitCanvas();
871 }
872 /**
873 * @param {?} source
874 * @return {?}
875 */
876 addImage(source) {
877 this.canvasManagerService.addImage(this.iconsPath + source);
878 this.emitCanvas();
879 }
880 /**
881 * @return {?}
882 */
883 changeStrokeColor() {
884 this.canvasManagerService.changeSelectedObjectsStrokeColor(this.strokeColor);
885 this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
886 this.emitCanvas();
887 }
888 /**
889 * @return {?}
890 */
891 bringFoward() {
892 this.canvasManagerService.bringSelectedObjectsToFront();
893 this.emitCanvas();
894 }
895 /**
896 * @return {?}
897 */
898 sendToBack() {
899 this.canvasManagerService.sendSelectedObjectsToBack();
900 this.emitCanvas();
901 }
902 /**
903 * @return {?}
904 */
905 crop() {
906 this.isCropping = true;
907 this.canvasManagerService.resetZoom();
908 this.canvasManagerService.disableSelection();
909 this.canvasManagerService.addSelectionRectangle();
910 this.isUndoAvailable = true;
911 this.previousJson = this.canvasManagerService.jsonFromCanvas();
912 this.emitCanvas();
913 }
914 /**
915 * @return {?}
916 */
917 deleteSelection() {
918 this.canvasManagerService.deleteSelectedObjects();
919 this.emitCanvas();
920 }
921 /**
922 * @param {?} event
923 * @return {?}
924 */
925 mouseUp(event) {
926 if (this.isCropping) {
927 this.isCropping = false;
928 this.canvasManagerService.cropImage();
929 this.isUndoAvailable = true;
930 this.emitCanvas();
931 }
932 }
933 /**
934 * @param {?} event
935 * @return {?}
936 */
937 mouseMove(event) {
938 if (this.isCropping) {
939 this.canvasManagerService.ajustCropRectangle(event);
940 }
941 else if (this.isPanning) {
942 this.canvasManagerService.panCanvas(event);
943 }
944 }
945 /**
946 * @param {?} event
947 * @return {?}
948 */
949 mouseDown(event) {
950 if (this.isCropping) {
951 this.canvasManagerService.startSelectingCropRectangle(event);
952 }
953 else if (this.isPanning) {
954 this.canvasManagerService.setLastPanPosition(event);
955 }
956 }
957 /**
958 * @param {?} event
959 * @return {?}
960 */
961 pinch(event) {
962 event.preventDefault();
963 this.disableDrawing();
964 this.canvasManagerService.zoom(event);
965 }
966 /**
967 * @return {?}
968 */
969 group() {
970 this.canvasManagerService.groupSelectedObjects();
971 this.emitCanvas();
972 }
973 /**
974 * @return {?}
975 */
976 undo() {
977 this.canvasManagerService.loadfromJson(this.previousJson);
978 this.isUndoAvailable = false;
979 this.emitCanvas();
980 }
981 /**
982 * @return {?}
983 */
984 onColorClicked() {
985 this.isSelectingColor = true;
986 this.stopPanning();
987 }
988 /**
989 * @return {?}
990 */
991 onMoveClicked() {
992 this.isPanning = !this.isPanning;
993 (this.isPanning) ? this.canvasManagerService.disableSelection() : this.canvasManagerService.enableSlection();
994 }
995 /**
996 * @return {?}
997 */
998 stopPanning() {
999 if (this.isPanning) {
1000 this.isPanning = false;
1001 this.canvasManagerService.enableSlection();
1002 }
1003 }
1004 /**
1005 * @param {?} color
1006 * @return {?}
1007 */
1008 setColor(color) {
1009 this.strokeColor = color;
1010 this.changeStrokeColor();
1011 this.isSelectingColor = false;
1012 this.emitCanvas();
1013 }
1014 /**
1015 * @return {?}
1016 */
1017 draw() {
1018 this.isDrawing = !this.isDrawing;
1019 this.canvasManagerService.toggleFreeDrawing();
1020 this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
1021 }
1022 /**
1023 * @return {?}
1024 */
1025 disableDrawing() {
1026 if (this.isDrawing) {
1027 this.isDrawing = false;
1028 this.canvasManagerService.toggleFreeDrawing();
1029 }
1030 }
1031 /**
1032 * @return {?}
1033 */
1034 translateShapeButtonsText() {
1035 const /** @type {?} */ translationArray = [];
1036 translationArray.push(this.translate.instant('rectangle'));
1037 translationArray.push(this.translate.instant('triangle'));
1038 translationArray.push(this.translate.instant('circle'));
1039 translationArray.push(this.translate.instant('line'));
1040 translationArray.push(this.translate.instant('cross'));
1041 translationArray.push(this.translate.instant('text'));
1042 return translationArray;
1043 }
1044 /**
1045 * @return {?}
1046 */
1047 presentShapeActionSheet() {
1048 this.disableDrawing();
1049 const /** @type {?} */ titleText = this.translate.instant('addGeometricShape');
1050 const /** @type {?} */ buttonsText = this.translateShapeButtonsText();
1051 let /** @type {?} */ i = 0;
1052 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1053 title: titleText,
1054 buttons: [
1055 {
1056 text: '\uf0c8 ' + buttonsText[i++],
1057 handler: () => {
1058 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Rectangle);
1059 }
1060 },
1061 {
1062 text: '\uf0d8 ' + buttonsText[i++],
1063 handler: () => {
1064 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Triangle);
1065 }
1066 },
1067 {
1068 text: '\uf111 ' + buttonsText[i++],
1069 handler: () => {
1070 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Circle);
1071 }
1072 },
1073 {
1074 text: '\uf068 ' + buttonsText[i++],
1075 handler: () => {
1076 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Line);
1077 }
1078 },
1079 {
1080 text: '\uf067 ' + buttonsText[i++],
1081 handler: () => {
1082 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Cross);
1083 }
1084 },
1085 {
1086 text: '\uf031 ' + buttonsText[i++],
1087 handler: () => {
1088 this.canvasManagerService.addText(this.strokeColor, '');
1089 }
1090 }
1091 ]
1092 });
1093 actionSheet.present();
1094 }
1095 /**
1096 * @return {?}
1097 */
1098 translateEditButtonsText() {
1099 const /** @type {?} */ translationArray = [];
1100 translationArray.push(this.translate.instant('crop'));
1101 translationArray.push(this.translate.instant('group'));
1102 translationArray.push(this.translate.instant('bringToFront'));
1103 translationArray.push(this.translate.instant('sendToBack'));
1104 translationArray.push(this.translate.instant('delete'));
1105 return translationArray;
1106 }
1107 /**
1108 * @return {?}
1109 */
1110 presentEditActionSheet() {
1111 this.disableDrawing();
1112 const /** @type {?} */ titleText = this.translate.instant('edition');
1113 const /** @type {?} */ buttonsText = this.translateEditButtonsText();
1114 let /** @type {?} */ i = 0;
1115 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1116 title: titleText,
1117 buttons: [
1118 {
1119 text: '\uf125 ' + buttonsText[i++],
1120 handler: () => {
1121 this.crop();
1122 }
1123 },
1124 {
1125 text: '\uf247 ' + buttonsText[i++],
1126 handler: () => {
1127 this.group();
1128 }
1129 },
1130 {
1131 text: '\uf0de ' + buttonsText[i++],
1132 handler: () => {
1133 this.bringFoward();
1134 }
1135 },
1136 {
1137 text: '\uf0dd ' + buttonsText[i++],
1138 handler: () => {
1139 this.sendToBack();
1140 }
1141 },
1142 {
1143 text: '\uf1f8 ' + buttonsText[i++],
1144 handler: () => {
1145 this.deleteSelection();
1146 }
1147 }
1148 ]
1149 });
1150 actionSheet.present();
1151 }
1152 /**
1153 * @return {?}
1154 */
1155 presentPictogramsActionSheet() {
1156 this.disableDrawing();
1157 const /** @type {?} */ buttons = [];
1158 const /** @type {?} */ actionSheetStyles = [];
1159 const /** @type {?} */ images = this.icons;
1160 for (let /** @type {?} */ i = 0; i < images.length; i++) {
1161 const /** @type {?} */ style = document.createElement('style');
1162 style.type = 'text/css';
1163 style.innerHTML =
1164 '.customCSSClass' +
1165 i +
1166 '{background: url(' +
1167 "'" +
1168 this.iconsPath +
1169 images[i] +
1170 "'" +
1171 ') no-repeat !important;padding-left:50px !important;height:80px; background-position: left center !important;}';
1172 document.getElementsByTagName('head')[0].appendChild(style);
1173 actionSheetStyles.push(style);
1174 buttons.push({
1175 role: 'destructive',
1176 text: images[i],
1177 cssClass: 'customCSSClass' + i,
1178 handler: () => {
1179 this.addImage(images[i]);
1180 }
1181 });
1182 }
1183 const /** @type {?} */ titleText = this.translate.instant('addPictogram');
1184 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1185 title: titleText,
1186 buttons: buttons
1187 });
1188 actionSheet.onDidDismiss(() => {
1189 for (let /** @type {?} */ i = 0; i < actionSheetStyles.length; i++) {
1190 if (actionSheetStyles[i].parentNode != null) {
1191 actionSheetStyles[i].parentNode.removeChild(actionSheetStyles[i]);
1192 }
1193 }
1194 });
1195 actionSheet.present();
1196 }
1197 /**
1198 * @return {?}
1199 */
1200 emitCanvas() {
1201 this.canvas.emit(this.canvasManagerService.canvas);
1202 }
1203}
1204MobileSketchToolComponent.decorators = [
1205 { type: Component, args: [{
1206 selector: 'lib-mobile-sketch-tool',
1207 template: `<ion-content>
1208 <div class="div-canvas-container" (touchstart)="mouseDown($event)" (touchmove)="mouseMove($event)" (touchend)="mouseUp($event)"
1209 #pinchElement>
1210 <canvas id="canvas"></canvas>
1211
1212 <div class="color-picker" *ngIf="isSelectingColor">
1213 <ion-grid fixed>
1214 <ion-row>
1215 <ion-col style="background:#660000" (tap)="setColor('#660000')">
1216 </ion-col>
1217 <ion-col style="background:#663300" (tap)="setColor('#663300')">
1218 </ion-col>
1219 <ion-col style="background:#666600" (tap)="setColor('#666600')">
1220 </ion-col>
1221 <ion-col style="background:#006600" (tap)="setColor('#006600')">
1222 </ion-col>
1223 <ion-col style="background:#000066" (tap)="setColor('#000066')">
1224 </ion-col>
1225 <ion-col style="background:#660066" (tap)="setColor('#660066')">
1226 </ion-col>
1227
1228 </ion-row>
1229 <ion-row>
1230 <ion-col style="background:#CC0000" (tap)="setColor('#CC0000')">
1231 </ion-col>
1232 <ion-col style="background:#CC6600" (tap)="setColor('#CC6600')">
1233 </ion-col>
1234 <ion-col style="background:#CCCC00" (tap)="setColor('#CCCC00')">
1235 </ion-col>
1236 <ion-col style="background:#00CC00" (tap)="setColor('#00CC00')">
1237 </ion-col>
1238 <ion-col style="background:#0000CC" (tap)="setColor('#0000CC')">
1239 </ion-col>
1240 <ion-col style="background:#CC00CC" (tap)="setColor('#CC00CC')">
1241 </ion-col>
1242
1243 </ion-row>
1244 <ion-row>
1245 <ion-col style="background:#FF0000" (tap)="setColor('#FF0000')">
1246 </ion-col>
1247 <ion-col style="background:#FF8000" (tap)="setColor('#FF8000')">
1248 </ion-col>
1249 <ion-col style="background:#FFFF00" (tap)="setColor('#FFFF00')">
1250 </ion-col>
1251 <ion-col style="background:#00FF00" (tap)="setColor('#00FF00')">
1252 </ion-col>
1253 <ion-col style="background:#0000FF" (tap)="setColor('#0000FF')">
1254 </ion-col>
1255 <ion-col style="background:#FF00FF" (tap)="setColor('#FF00FF')">
1256 </ion-col>
1257
1258 </ion-row>
1259 <ion-row>
1260 <ion-col style="background:#FF6666" (tap)="setColor('#FF6666')">
1261 </ion-col>
1262 <ion-col style="background:#FFB266" (tap)="setColor('#FFB266')">
1263 </ion-col>
1264 <ion-col style="background:#FFFF66" (tap)="setColor('#FFFF66')">
1265 </ion-col>
1266 <ion-col style="background:#66FF66" (tap)="setColor('#66FF66')">
1267 </ion-col>
1268 <ion-col style="background:#6666FF" (tap)="setColor('#6666FF')">
1269 </ion-col>
1270 <ion-col style="background:#FF66FF" (tap)="setColor('#FF66FF')">
1271 </ion-col>
1272
1273 </ion-row>
1274 <ion-row>
1275 <ion-col style="background:#FF9999" (tap)="setColor('#FF9999')">
1276 </ion-col>
1277 <ion-col style="background:#FFCC99" (tap)="setColor('#FFCC99')">
1278 </ion-col>
1279 <ion-col style="background:#FFFF99" (tap)="setColor('#FFFF99')">
1280 </ion-col>
1281 <ion-col style="background:#99FF99" (tap)="setColor('#99FF99')">
1282 </ion-col>
1283 <ion-col style="background:#9999FF" (tap)="setColor('#9999FF')">
1284 </ion-col>
1285 <ion-col style="background:#FF99FF" (tap)="setColor('#FF99FF')">
1286 </ion-col>
1287
1288 </ion-row>
1289 <ion-row>
1290 <ion-col style="background:#FFFFFF" (tap)="setColor('#FFFFFF')">
1291 </ion-col>
1292 <ion-col style="background:#C0C0C0" (tap)="setColor('#C0C0C0')">
1293 </ion-col>
1294 <ion-col style="background:#808080" (tap)="setColor('#808080')">
1295 </ion-col>
1296 <ion-col style="background:#606060" (tap)="setColor('#606060')">
1297 </ion-col>
1298 <ion-col style="background:#303030" (tap)="setColor('#606060')">
1299 </ion-col>
1300 <ion-col style="background:#000000" (tap)="setColor('#000000')">
1301 </ion-col>
1302 </ion-row>
1303 </ion-grid>
1304 </div>
1305 </div>
1306</ion-content>
1307
1308<ion-footer>
1309 <ion-toolbar>
1310 <div class="div-edit-toolbar">
1311 <button class="button-edit-toolbar" ion-button large [clear]="true" (click)="presentShapeActionSheet()">
1312 <i class="fas fa-shapes" id="icon"></i>
1313 </button>
1314
1315 <button class="button-edit-toolbar" ion-button large [clear]="true" (click)="presentPictogramsActionSheet()" *ngIf="hasPictograms">
1316 <i class="fas fa-images" id="icon"></i>
1317 </button>
1318
1319 <button class="button-edit-toolbar" ion-button large [clear]="true" (click)="presentEditActionSheet()">
1320 <i class="fas fa-edit" id="icon"></i>
1321 </button>
1322
1323 <button class="button-edit-toolbar" ion-button large [clear]="!isDrawing" (click)="draw()">
1324 <i class="fas fa-pencil-alt" id="icon"></i>
1325 </button>
1326
1327 <button class="button-edit-toolbar" ion-button large [clear]="true" (click)="onColorClicked()">
1328 <i class="fas fa-palette" id="icon"></i>
1329 </button>
1330
1331 <button class="button-edit-toolbar" ion-button large [clear]="!isPanning" (click)="onMoveClicked()">
1332 <i class="fas fa-arrows-alt" id="icon"></i>
1333 </button>
1334
1335 <button class="button-edit-toolbar" ion-button large [clear]="true" (click)="undo()" *ngIf="isUndoAvailable">
1336 <i class="fas fa-undo" id="icon"></i>
1337 </button>
1338
1339 </div>
1340 </ion-toolbar>
1341</ion-footer>
1342`,
1343 styles: [`.div-canvas-container{height:100%;width:100%;-o-object-fit:contain;object-fit:contain;text-align:center;margin:0 auto;padding:0 auto}.scroll-content{padding:0!important;overflow-y:hidden}.div-edit-toolbar{text-align:center}.button-edit-toolbar{padding:4%!important;margin:0!important}.action-sheet-button{font-family:FontAwesome,Arial}.color-picker{position:absolute;width:100%;height:auto;bottom:0;left:0}#icon{color:#b32017}.col{padding:10px}`],
1344 providers: [CanvasManagerService]
1345 },] },
1346];
1347/** @nocollapse */
1348MobileSketchToolComponent.ctorParameters = () => [
1349 { type: ActionSheetController, },
1350 { type: CanvasManagerService, },
1351 { type: TranslateService, },
1352];
1353MobileSketchToolComponent.propDecorators = {
1354 "element": [{ type: ViewChild, args: ['pinchElement',] },],
1355 "imageData": [{ type: Input },],
1356 "loadedJson": [{ type: Input },],
1357 "iconsPath": [{ type: Input },],
1358 "icons": [{ type: Input },],
1359 "canvas": [{ type: Output },],
1360};
1361
1362/**
1363 * @fileoverview added by tsickle
1364 * @suppress {checkTypes} checked by tsc
1365 */
1366class SketchToolModule {
1367}
1368SketchToolModule.decorators = [
1369 { type: NgModule, args: [{
1370 imports: [CommonModule, IonicModule],
1371 declarations: [
1372 MobileSketchToolComponent,
1373 ],
1374 exports: [MobileSketchToolComponent]
1375 },] },
1376];
1377
1378/**
1379 * @fileoverview added by tsickle
1380 * @suppress {checkTypes} checked by tsc
1381 */
1382
1383/**
1384 * @fileoverview added by tsickle
1385 * @suppress {checkTypes} checked by tsc
1386 */
1387
1388export { MobileSketchToolComponent, CanvasManagerService, SketchToolModule };
1389
1390//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliLXNrZXRjaC10b29sLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC9jb25zdGFudHMvc2hhcGUtZGF0YS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvbW9iaWxlLWNvbXBvbmVudC9tb2JpbGUtc2tldGNoLXRvb2wuY29tcG9uZW50LnRzIiwibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC9za2V0Y2gtdG9vbC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IFNIQVBFX0RBVEEgPSB7XG4gIHdpZHRoOiAyMDAsXG4gIGhlaWdodDogMjAwLFxuICBsZWZ0OiA1MCxcbiAgdG9wOiA1MCxcbiAgcmFkaXVzOiAxMDAsXG4gIHN0cm9rZTogMTAsXG4gIGZyZWVEcmF3aW5nQnJ1c2hXaWR0aDogMTAsXG4gIGNvcm5lclNpemU6IDIwXG59O1xuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcblxuaW1wb3J0IHsgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUgfSBmcm9tICcuLy4uL2NvbnN0YW50cy9hdmFpbGFibGUtZ2VvbWV0cmljLXNoYXBlcyc7XG5pbXBvcnQgeyBTSEFQRV9EQVRBIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvc2hhcGUtZGF0YSc7XG5cbmludGVyZmFjZSBTY2FsZURhdGEge1xuICBzY2FsZUZhY3RvcjogbnVtYmVyO1xuICBsZWZ0OiBudW1iZXI7XG4gIHRvcDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUG9zaXRpb24ge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENhbnZhc01hbmFnZXJTZXJ2aWNlIHtcbiAgcHVibGljIGNhbnZhcztcblxuICBwcml2YXRlIGNyb3BSZWN0YW5nbGU6IGZhYnJpYy5SZWN0O1xuICBwcml2YXRlIG1vdXNlUG9zaXRpb246IFBvc2l0aW9uO1xuICBwcml2YXRlIGNyb3BTdGFydGluZ1Bvc2l0aW9uOiBQb3NpdGlvbjtcbiAgcHJpdmF0ZSBsYXN0UGFuUG9zaXRpb246IGZhYnJpYy5Qb2ludDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmVtcHR5Q2FudmFzKCk7XG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IDAsIHk6IDB9O1xuICAgIHRoaXMuY3JvcFN0YXJ0aW5nUG9zaXRpb24gPSB7eDogMCwgeTogMH07XG4gIH1cblxuICBnZXQgYmFja2dyb3VuZEltYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcztcbiAgfVxuXG4gIGdldCBjYW52YXNPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCk7XG4gIH1cblxuICBnZXQgY2FudmFzQmFja2dyb3VuZEltYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2U7XG4gIH1cblxuICBnZXQgYWN0aXZlT2JqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3QoKTtcbiAgfVxuXG4gIGdldCBhY3RpdmVHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuICB9XG5cbiAgcHVibGljIGVtcHR5Q2FudmFzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgdGhpcy5jYW52YXMuZGlzcG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBmYWJyaWMuQ2FudmFzKCdjYW52YXMnKTtcbiAgICB0aGlzLmNhbnZhcy5jbGVhcigpO1xuICAgIHRoaXMuY2FudmFzLnJlbW92ZSh0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkpO1xuICB9XG5cbiAgcHVibGljIGxvYWROZXdJbWFnZShiYWNrZ3JvdW5kSW1hZ2VVUkw/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtcHR5Q2FudmFzKCk7XG4gICAgaWYgKGJhY2tncm91bmRJbWFnZVVSTCkge1xuICAgICAgdGhpcy5zZXRCYWNrZ3JvdW5kRnJvbVVSTChiYWNrZ3JvdW5kSW1hZ2VVUkwpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZW5kZXJDYW52YXMoKTogdm9pZCB7XG4gICAgdGhpcy5tYXJrU2VsZWN0ZWRPYmplY3RzRGlydHkoKTtcbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRHZW9tZXRyaWNTaGFwZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZywgc2hhcGU6IEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlKTogdm9pZCB7XG4gICAgc3dpdGNoIChzaGFwZSkge1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5SZWN0YW5nbGU6XG4gICAgICAgIHRoaXMuYWRkUmVjdGFuZ2xlKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuQ2lyY2xlOlxuICAgICAgICB0aGlzLmFkZENpcmNsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLlRyaWFuZ2xlOlxuICAgICAgICB0aGlzLmFkZFRyaWFuZ2xlKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuTGluZTpcbiAgICAgICAgdGhpcy5hZGRIb3Jpem9udGFsTGluZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkNyb3NzOlxuICAgICAgICB0aGlzLmFkZENyb3NzKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZFJlY3RhbmdsZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZChcbiAgICAgIG5ldyBmYWJyaWMuUmVjdCh7XG4gICAgICAgIHdpZHRoOiBTSEFQRV9EQVRBLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IFNIQVBFX0RBVEEuaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IFNIQVBFX0RBVEEuc3Ryb2tlLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2lyY2xlKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXMuYWRkKFxuICAgICAgbmV3IGZhYnJpYy5DaXJjbGUoe1xuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIHJhZGl1czogU0hBUEVfREFUQS5yYWRpdXMsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBTSEFQRV9EQVRBLnN0cm9rZSxcbiAgICAgICAgZmlsbDogZmlsbENvbG9yLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVHJpYW5nbGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQoXG4gICAgICBuZXcgZmFicmljLlRyaWFuZ2xlKHtcbiAgICAgICAgd2lkdGg6IFNIQVBFX0RBVEEud2lkdGgsXG4gICAgICAgIGhlaWdodDogU0hBUEVfREFUQS5oZWlnaHQsXG4gICAgICAgIGxlZnQ6IFNIQVBFX0RBVEEubGVmdCxcbiAgICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgICAgZmlsbDogZmlsbENvbG9yLFxuICAgICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogU0hBUEVfREFUQS5zdHJva2UsXG4gICAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZCh0aGlzLmNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yKSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yOiBzdHJpbmcpOiBmYWJyaWMuTGluZSB7XG4gICAgY29uc3QgbGluZSA9IG5ldyBmYWJyaWMuTGluZShbMTAwLCAxNTAsIDIwMCwgMTUwXSwge1xuICAgICAgbGVmdDogNTAsXG4gICAgICB0b3A6IDEwMCxcbiAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICBzdHJva2VXaWR0aDogNSxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgbGluZS5zZXRDb250cm9sc1Zpc2liaWxpdHkoe1xuICAgICAgYmw6IGZhbHNlLFxuICAgICAgYnI6IGZhbHNlLFxuICAgICAgdGw6IGZhbHNlLFxuICAgICAgdHI6IGZhbHNlLFxuICAgICAgbXQ6IGZhbHNlLFxuICAgICAgbWI6IGZhbHNlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmVydGljYWxMaW5lKHN0cm9rZUNvbG9yOiBzdHJpbmcpOiBmYWJyaWMuTGluZSB7XG4gICAgY29uc3QgbGluZSA9IG5ldyBmYWJyaWMuTGluZShbMTUwLCAxMDAsIDE1MCwgMjAwXSwge1xuICAgICAgbGVmdDogMTAwLFxuICAgICAgdG9wOiA1MCxcbiAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICBzdHJva2VXaWR0aDogNSxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgbGluZS5zZXRDb250cm9sc1Zpc2liaWxpdHkoe1xuICAgICAgYmw6IGZhbHNlLFxuICAgICAgYnI6IGZhbHNlLFxuICAgICAgdGw6IGZhbHNlLFxuICAgICAgdHI6IGZhbHNlLFxuICAgICAgbWw6IGZhbHNlLFxuICAgICAgbXI6IGZhbHNlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ3Jvc3Moc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBob3Jpem9udGFsTGluZSA9IHRoaXMuY3JlYXRlSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3IpO1xuICAgIGNvbnN0IHZlcnRpY2FsTGluZSA9IHRoaXMuY3JlYXRlVmVydGljYWxMaW5lKHN0cm9rZUNvbG9yKTtcbiAgICB0aGlzLmNhbnZhcy5hZGQoaG9yaXpvbnRhbExpbmUpO1xuICAgIHRoaXMuY2FudmFzLmFkZCh2ZXJ0aWNhbExpbmUpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZyZWVEcmF3aW5nKCk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmlzRHJhd2luZ01vZGUgPSAhdGhpcy5jYW52YXMuaXNEcmF3aW5nTW9kZTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGcmVlRHJhd2luZ0JydXNoQ29sb3IoY29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmZyZWVEcmF3aW5nQnJ1c2guY29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLnNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHRoaXMuY2FudmFzLmdldFpvb20oKSk7XG4gIH1cblxuICBwcml2YXRlIHNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHpvb206IG51bWJlcikge1xuICAgIHRoaXMuY2FudmFzLmZyZWVEcmF3aW5nQnJ1c2gud2lkdGggPSBTSEFQRV9EQVRBLmZyZWVEcmF3aW5nQnJ1c2hXaWR0aCAqICgxIC8gem9vbSk7XG4gIH1cblxuICBwdWJsaWMgYWRkVGV4dChjb2xvcjogc3RyaW5nLCBpbnB1dFRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgZmFicmljLklUZXh0KCd0ZXh0Jywge1xuICAgICAgZm9udEZhbWlseTogJ2FyaWFsIGJsYWNrJyxcbiAgICAgIGZvbnRTdHlsZTogJ2JvbGQnLFxuICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgdGV4dC5zZXRDb2xvcihjb2xvcik7XG5cbiAgICB0aGlzLmNhbnZhcy5hZGQodGV4dCk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW1hZ2UoaW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShcbiAgICAgIChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXM7XG5cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oaW1nKSB7XG4gICAgICAgICAgY29uc3QgZmFicmljSW1hZ2UgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7XG4gICAgICAgICAgICBhbmdsZTogMCxcbiAgICAgICAgICAgIHdpZHRoOiBpbWFnZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaW1hZ2UuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgICAgICAgIHNjYWxlWDogMSxcbiAgICAgICAgICAgIHNjYWxlWTogMSxcbiAgICAgICAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNhbnZhcy5hZGQoZmFicmljSW1hZ2UpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gaW1hZ2VVUkw7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRCYWNrZ3JvdW5kRnJvbVVSTChiYWNrZ3JvdW5kSW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzO1xuICAgIGNvbnN0IHJlc2l6ZSA9IHRoaXMucmVzaXplQ2FudmFzQW5kQ29tcHV0ZVNjYWxlRmFjdG9yO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgICAgKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoYmFja2dyb3VuZEltYWdlVVJMID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgZl9pbWcgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7fSk7XG5cbiAgICAgICAgICBjb25zdCBzY2FsZURhdGEgPSByZXNpemUoZl9pbWcsIGNhbnZhcyk7XG5cbiAgICAgICAgICBjYW52YXMuc2V0QmFja2dyb3VuZEltYWdlKGZfaW1nLCBjYW52YXMucmVuZGVyQWxsLmJpbmQoY2FudmFzKSwge1xuICAgICAgICAgICAgc2NhbGVYOiBzY2FsZURhdGEuc2NhbGVGYWN0b3IsXG4gICAgICAgICAgICBzY2FsZVk6IHNjYWxlRGF0YS5zY2FsZUZhY3RvclxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2FudmFzLnJlbmRlckFsbCgpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gYmFja2dyb3VuZEltYWdlVVJMO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlc2l6ZUNhbnZhc0FuZENvbXB1dGVTY2FsZUZhY3RvcihmX2ltZzogZmFicmljLkltYWdlLCBjYW52YXM6IGZhYnJpYy5DYW52YXMpOiBTY2FsZURhdGEge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIGNhbnZhcy5zZXRXaWR0aChjb250YWluZXIuY2xpZW50V2lkdGgpO1xuICAgIGNhbnZhcy5zZXRIZWlnaHQoY29udGFpbmVyLmNsaWVudEhlaWdodCk7XG5cbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhcy5nZXRXaWR0aCgpO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNhbnZhcy5nZXRIZWlnaHQoKTtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IGZfaW1nLndpZHRoIC8gZl9pbWcuaGVpZ2h0O1xuICAgIGxldCBsZWZ0LCB0b3AsIHNjYWxlRmFjdG9yO1xuXG4gICAgaWYgKGNhbnZhc0FzcGVjdCA8PSBpbWdBc3BlY3QpIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzV2lkdGggLyBmX2ltZy53aWR0aDtcbiAgICAgIGxlZnQgPSAwO1xuICAgICAgdG9wID0gLShmX2ltZy5oZWlnaHQgKiBzY2FsZUZhY3RvciAtIGNhbnZhc0hlaWdodCkgLyAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc0hlaWdodCAvIGZfaW1nLmhlaWdodDtcbiAgICAgIHRvcCA9IDA7XG4gICAgICBsZWZ0ID0gLShmX2ltZy53aWR0aCAqIHNjYWxlRmFjdG9yIC0gY2FudmFzV2lkdGgpIC8gMjtcbiAgICB9XG4gICAgcmV0dXJuIHsgc2NhbGVGYWN0b3I6IHNjYWxlRmFjdG9yLCBsZWZ0OiBsZWZ0LCB0b3A6IHRvcCB9O1xuICB9XG5cbiAgcHVibGljIG9uT3JpZW50YXRpb25DaGFuZ2UoKSB7XG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IHRoaXMuY2FudmFzLmdldFdpZHRoLCB5OiB0aGlzLmNhbnZhcy5nZXRIZWlnaHQgfTtcbiAgICB0aGlzLmNyb3BJbWFnZSgpO1xuICB9XG5cbiAgcHVibGljIGNoYW5nZVNlbGVjdGVkT2JqZWN0c0ZpbGxDb2xvcihjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIG9iamVjdC5zZXRDb2xvcihjb2xvcik7XG4gICAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjaGFuZ2VTZWxlY3RlZE9iamVjdHNTdHJva2VDb2xvcihjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIGlmIChvYmplY3QudHlwZSA9PT0gJ2ktdGV4dCcpIHtcbiAgICAgICAgICBvYmplY3Quc2V0Q29sb3IoY29sb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9iamVjdC5zdHJva2UgPSBjb2xvcjtcbiAgICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlU2VsZWN0ZWRPYmplY3RzKCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICB0aGlzLmNhbnZhcy5yZW1vdmUob2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FudmFzLmRpc2NhcmRBY3RpdmVPYmplY3QoKTtcbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBicmluZ1NlbGVjdGVkT2JqZWN0c1RvRnJvbnQoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLmJyaW5nVG9Gcm9udChvYmplY3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZW5kU2VsZWN0ZWRPYmplY3RzVG9CYWNrKCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICB0aGlzLmNhbnZhcy5zZW5kVG9CYWNrKG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGpzb25Gcm9tQ2FudmFzKCk6IEpTT04ge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy50b0pTT04oKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkZnJvbUpzb24oanNvbjogSlNPTik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIHRoaXMuY2FudmFzLnNldFdpZHRoKGNvbnRhaW5lci5jbGllbnRXaWR0aCk7XG4gICAgdGhpcy5jYW52YXMuc2V0SGVpZ2h0KGNvbnRhaW5lci5jbGllbnRIZWlnaHQpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgICAgKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmFkanVzdENhbnZhcyhqc29uKTtcbiAgICAgICAgdGhpcy5jYW52YXMubG9hZEZyb21KU09OKGpzb24sIHRoaXMuY2FudmFzLnJlbmRlckFsbC5iaW5kKHRoaXMuY2FudmFzKSk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFkanVzdENhbnZhcyhqc29uOiBKU09OKTogdm9pZCB7XG4gICAgY29uc3QgYmFja2dyb3VuZEltYWdlID0ganNvblsnYmFja2dyb3VuZEltYWdlJ107XG5cbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFxuICAgICAgJ2Rpdi1jYW52YXMtY29udGFpbmVyJ1xuICAgIClbMF07XG5cbiAgICBjb25zdCB3aWR0aCA9IGJhY2tncm91bmRJbWFnZVsnd2lkdGgnXTtcbiAgICBjb25zdCBoZWlnaHQgPSBiYWNrZ3JvdW5kSW1hZ2VbJ2hlaWdodCddO1xuXG4gICAgY29uc3QgY2FudmFzV2lkdGggPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY29udGFpbmVyLmNsaWVudEhlaWdodDtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IHdpZHRoIC8gaGVpZ2h0O1xuICAgIGxldCBzY2FsZUZhY3RvcjtcblxuICAgIGlmIChjYW52YXNBc3BlY3QgPD0gaW1nQXNwZWN0KSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc1dpZHRoIC8gd2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzSGVpZ2h0IC8gaGVpZ2h0O1xuICAgIH1cblxuICAgIGNvbnN0IG9iamVjdFNjYWxlID0gc2NhbGVGYWN0b3IgLyBiYWNrZ3JvdW5kSW1hZ2VbJ3NjYWxlWCddO1xuXG4gICAgYmFja2dyb3VuZEltYWdlWydzY2FsZVgnXSA9IHNjYWxlRmFjdG9yO1xuICAgIGJhY2tncm91bmRJbWFnZVsnc2NhbGVZJ10gPSBzY2FsZUZhY3RvcjtcblxuICAgIHRoaXMuY2FudmFzLnNldFdpZHRoKHdpZHRoICogc2NhbGVGYWN0b3IpO1xuICAgIHRoaXMuY2FudmFzLnNldEhlaWdodChoZWlnaHQgKiBzY2FsZUZhY3Rvcik7XG5cbiAgICBjb25zdCBvYmplY3RzID0ganNvblsnb2JqZWN0cyddO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzW2ldWydsZWZ0J10gKj0gb2JqZWN0U2NhbGU7XG4gICAgICBvYmplY3RzW2ldWyd0b3AnXSAqPSBvYmplY3RTY2FsZTtcbiAgICAgIG9iamVjdHNbaV1bJ3NjYWxlWCddICo9IG9iamVjdFNjYWxlO1xuICAgICAgb2JqZWN0c1tpXVsnc2NhbGVZJ10gKj0gb2JqZWN0U2NhbGU7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuc2VsZWN0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICB9XG5cbiAgcHVibGljIGV4cG9ydEltYWdlQXNEYXRhVVJMKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0SXRlbShpdGVtTnVtYmVyOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5zZXRBY3RpdmVPYmplY3QodGhpcy5jYW52YXMuaXRlbShpdGVtTnVtYmVyKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0SW5kZXhPZihhY3RpdmVPYmplY3QpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkuaW5kZXhPZihhY3RpdmVPYmplY3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3RMYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW1OdW1iZXIgPSB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBvYmplY3QgPSB0aGlzLmNhbnZhcy5pdGVtKGl0ZW1OdW1iZXIpO1xuICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChvYmplY3QpO1xuICAgIG9iamVjdC5lbnRlckVkaXRpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRTZWxlY3Rpb25SZWN0YW5nbGUoKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlID0gbmV3IGZhYnJpYy5SZWN0KHtcbiAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICBvcmlnaW5YOiAnbGVmdCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIHN0cm9rZTogJyNjY2MnLFxuICAgICAgc3Ryb2tlRGFzaEFycmF5OiBbMiwgMl0sXG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgd2lkdGg6IDEsXG4gICAgICBoZWlnaHQ6IDFcbiAgICB9KTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5jYW52YXMuYWRkKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgYWp1c3RDcm9wUmVjdGFuZ2xlRnJvbU1vdXNlKGV2ZW50OiBNb3VzZUV2ZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3QgeCA9IE1hdGgubWluKGV2ZW50LmxheWVyWCwgdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgeSA9IE1hdGgubWluKGV2ZW50LmxheWVyWSwgdGhpcy5tb3VzZVBvc2l0aW9uLnkpLFxuICAgICAgdyA9IE1hdGguYWJzKGV2ZW50LmxheWVyWCAtIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIGggPSBNYXRoLmFicyhldmVudC5sYXllclkgLSB0aGlzLm1vdXNlUG9zaXRpb24ueSk7XG5cbiAgICBpZiAoIXcgfHwgIWgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGVcbiAgICAgIC5zZXQoJ3RvcCcsIHkpXG4gICAgICAuc2V0KCdsZWZ0JywgeClcbiAgICAgIC5zZXQoJ3dpZHRoJywgdylcbiAgICAgIC5zZXQoJ2hlaWdodCcsIGgpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGVGcm9tTW91c2UoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNyb3BTdGFydGluZ1Bvc2l0aW9uID0geyB4OiB0aGlzLmNhbnZhcy5sZWZ0LCB5OiB0aGlzLmNhbnZhcy50b3AgfTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS5sZWZ0ID0gZXZlbnQubGF5ZXJYO1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS50b3AgPSBldmVudC5sYXllclk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnNldENvb3JkcygpO1xuXG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IGV2ZW50LmxheWVyWCwgeTogZXZlbnQubGF5ZXJZIH07XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUudmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuYnJpbmdUb0Zyb250KHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgY3JvcEltYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdDtcbiAgICBjb25zdCB0b3AgPSB0aGlzLmNyb3BSZWN0YW5nbGUudG9wO1xuXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmNyb3BSZWN0YW5nbGUud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5jcm9wUmVjdGFuZ2xlLmhlaWdodDtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XG5cbiAgICBjb25zdCBjYW52YXNBc3BlY3QgPSBjYW52YXNXaWR0aCAvIGNhbnZhc0hlaWdodDtcbiAgICBjb25zdCBpbWdBc3BlY3QgPSB3aWR0aCAvIGhlaWdodDtcbiAgICBsZXQgc2NhbGVGYWN0b3I7XG5cbiAgICBpZiAoY2FudmFzQXNwZWN0IDw9IGltZ0FzcGVjdCkge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjYW52YXNXaWR0aCAvIHdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc0hlaWdodCAvIGhlaWdodDtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5zZXRXaWR0aCh3aWR0aCAqIHNjYWxlRmFjdG9yKTtcbiAgICB0aGlzLmNhbnZhcy5zZXRIZWlnaHQoaGVpZ2h0ICogc2NhbGVGYWN0b3IpO1xuXG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLnNjYWxlWCAqPSBzY2FsZUZhY3RvcjtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2Uuc2NhbGVZICo9IHNjYWxlRmFjdG9yO1xuXG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLmxlZnQgLT0gbGVmdDtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UubGVmdCAqPSBzY2FsZUZhY3RvcjtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UudG9wIC09IHRvcCAtIHNjYWxlRmFjdG9yO1xuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS50b3AgKj0gc2NhbGVGYWN0b3I7XG5cbiAgICB0aGlzLm1vdmVBbGxPYmplY3RzSW5DYW52YXMoLTEgKiBsZWZ0LCAtMSAqIHRvcCwgc2NhbGVGYWN0b3IpO1xuXG4gICAgdGhpcy5lbmFibGVTbGVjdGlvbigpO1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gZmFsc2U7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW1vdmUodGhpcy5jcm9wUmVjdGFuZ2xlKTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICB9XG5cbiAgcHVibGljIGVuYWJsZVNsZWN0aW9uKCkge1xuICAgIHRoaXMuY2FudmFzLnNlbGVjdGFibGUgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzLnNlbGVjdGlvbiA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgYWp1c3RDcm9wUmVjdGFuZ2xlKGV2ZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3QgdG91Y2ggPSBldmVudC50b3VjaGVzWzBdO1xuXG4gICAgY29uc3QgcmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGNvbnN0IHggPSBNYXRoLm1pbih0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0LCB0aGlzLm1vdXNlUG9zaXRpb24ueCksXG4gICAgICB5ID0gTWF0aC5taW4odG91Y2guY2xpZW50WSAtIHJlY3QudG9wLCB0aGlzLm1vdXNlUG9zaXRpb24ueSksXG4gICAgICB3ID0gTWF0aC5hYnModG91Y2guY2xpZW50WCAtIHJlY3QubGVmdCAtIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIGggPSBNYXRoLmFicyh0b3VjaC5jbGllbnRZIC0gcmVjdC50b3AgLSB0aGlzLm1vdXNlUG9zaXRpb24ueSk7XG5cbiAgICBpZiAoIXcgfHwgIWgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGVcbiAgICAgIC5zZXQoJ2xlZnQnLCB4KVxuICAgICAgLnNldCgndG9wJywgeSlcbiAgICAgIC5zZXQoJ3dpZHRoJywgdylcbiAgICAgIC5zZXQoJ2hlaWdodCcsIGgpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGUoZXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNyb3BTdGFydGluZ1Bvc2l0aW9uID0geyB4OiB0aGlzLmNhbnZhcy5sZWZ0LCB5OiB0aGlzLmNhbnZhcy50b3AgfTtcblxuICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTtcbiAgICBjb25zdCByZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLmxlZnQgPSB0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS50b3AgPSB0b3VjaC5jbGllbnRZIC0gcmVjdC50b3A7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnNldENvb3JkcygpO1xuXG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0geyB4OiB0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0LCB5OiB0b3VjaC5jbGllbnRZIC0gcmVjdC50b3AgfTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLmNhbnZhcy5icmluZ1RvRnJvbnQodGhpcy5jcm9wUmVjdGFuZ2xlKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNhYmxlU2VsZWN0aW9uKCkge1xuICAgIHRoaXMuY2FudmFzLnNlbGVjdGlvbiA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlQWxsT2JqZWN0c0luQ2FudmFzKHg6IG51bWJlciwgeTogbnVtYmVyLCBzY2FsZUZhY3RvcjogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgb2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldE9iamVjdHMoKTtcbiAgICBmb3IgKGNvbnN0IG9iaiBvZiBvYmplY3RzKSB7XG4gICAgICBvYmoubGVmdCArPSB4O1xuICAgICAgb2JqLmxlZnQgKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmouc2NhbGVYICo9IHNjYWxlRmFjdG9yO1xuICAgICAgb2JqLnRvcCArPSB5O1xuICAgICAgb2JqLnNjYWxlWSAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai50b3AgKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmouc2V0Q29vcmRzKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdyb3VwU2VsZWN0ZWRPYmplY3RzKCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgY29uc3Qgb2JqZWN0cyA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIG9iamVjdHMucHVzaChvYmplY3QpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWxldGVTZWxlY3RlZE9iamVjdHMoKTtcblxuICAgICAgY29uc3QgZ3JvdXAgPSBuZXcgZmFicmljLkdyb3VwKG9iamVjdHMpO1xuICAgICAgdGhpcy5jYW52YXMuYWRkKGdyb3VwKTtcbiAgICAgIGdyb3VwLnNldENvb3JkcygpO1xuXG4gICAgICB0aGlzLmNhbnZhcy5zZXRBY3RpdmVPYmplY3QoZ3JvdXApO1xuXG4gICAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0TGFzdFBhblBvc2l0aW9uKGV2ZW50KSB7XG4gICAgdGhpcy5sYXN0UGFuUG9zaXRpb24gPSBuZXcgZmFicmljLlBvaW50KGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCwgZXZlbnQudG91Y2hlc1swXS5jbGllbnRZKTtcbiAgfVxuXG4gIHB1YmxpYyBwYW5DYW52YXMoZXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBkZWx0YSA9IG5ldyBmYWJyaWMuUG9pbnQoXG4gICAgICBldmVudC50b3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLmxhc3RQYW5Qb3NpdGlvbi54LFxuICAgICAgZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIC0gdGhpcy5sYXN0UGFuUG9zaXRpb24ueVxuICAgICk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZWxhdGl2ZVBhbihkZWx0YSk7XG4gICAgdGhpcy5wcmV2ZW50UGFuT3V0c2lkZUNhbnZhcygpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgdGhpcy5zZXRMYXN0UGFuUG9zaXRpb24oZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmV2ZW50UGFuT3V0c2lkZUNhbnZhcygpIHtcbiAgICBjb25zdCBjYW52YXNWaWV3UG9ydCA9IHRoaXMuY2FudmFzLnZpZXdwb3J0VHJhbnNmb3JtO1xuXG4gICAgY29uc3QgYm90dG9tRW5kUG9pbnQgPSB0aGlzLmNhbnZhcy5oZWlnaHQgKiAoY2FudmFzVmlld1BvcnRbMF0gLSAxKTtcbiAgICBpZiAoY2FudmFzVmlld1BvcnRbNV0gPj0gMCB8fCAtYm90dG9tRW5kUG9pbnQgPiBjYW52YXNWaWV3UG9ydFs1XSkge1xuICAgICAgICBjYW52YXNWaWV3UG9ydFs1XSA9IChjYW52YXNWaWV3UG9ydFs1XSA+PSAwKSA/IDAgOiAtYm90dG9tRW5kUG9pbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgcmlnaHRFbmRQb2ludCA9IHRoaXMuY2FudmFzLndpZHRoICogKGNhbnZhc1ZpZXdQb3J0WzBdIC0gMSk7XG4gICAgaWYgKGNhbnZhc1ZpZXdQb3J0WzRdID49IDAgfHwgLXJpZ2h0RW5kUG9pbnQgPiBjYW52YXNWaWV3UG9ydFs0XSkge1xuICAgICAgICBjYW52YXNWaWV3UG9ydFs0XSA9IChjYW52YXNWaWV3UG9ydFs0XSA+PSAwKSA/IDAgOiAtcmlnaHRFbmRQb2ludDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgem9vbShldmVudCk6IHZvaWQge1xuICAgIGlmIChNYXRoLmFicyhldmVudC5vdmVyYWxsVmVsb2NpdHkpID4gMC4wMDUpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gbmV3IGZhYnJpYy5Qb2ludChldmVudC5jZW50ZXIueCwgZXZlbnQuY2VudGVyLnkpO1xuXG4gICAgICBsZXQgem9vbSA9IHRoaXMuY2FudmFzLmdldFpvb20oKTtcbiAgICAgIHpvb20gPSB6b29tICsgKGV2ZW50LnNjYWxlIC0gem9vbSkgLyAyMDtcblxuXG4gICAgICBpZiAoem9vbSA8IDEpIHtcbiAgICAgICAgem9vbSA9IDE7XG4gICAgICAgIHRoaXMuY2FudmFzLnpvb21Ub1BvaW50KG5ldyBmYWJyaWMuUG9pbnQoMCwgMCksIHpvb20pO1xuICAgICAgICB0aGlzLmNhbnZhcy5hYnNvbHV0ZVBhbihuZXcgZmFicmljLlBvaW50KDAsIDApKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh6b29tID4gMTApIHtcbiAgICAgICAgICB6b29tID0gMTA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jYW52YXMuem9vbVRvUG9pbnQocG9pbnQsIHpvb20pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHpvb20pO1xuICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlc2V0Wm9vbSgpIHtcbiAgICB0aGlzLmNhbnZhcy56b29tVG9Qb2ludChuZXcgZmFicmljLlBvaW50KDAsIDApLCAxKTtcbiAgICB0aGlzLmNhbnZhcy5hYnNvbHV0ZVBhbihuZXcgZmFicmljLlBvaW50KDAsIDApKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgRXZlbnRFbWl0dGVyLCB0cmFuc2l0aW9uLCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aW9uU2hlZXRDb250cm9sbGVyIH0gZnJvbSAnaW9uaWMtYW5ndWxhcic7XG5pbXBvcnQgeyBHZXN0dXJlIH0gZnJvbSAnaW9uaWMtYW5ndWxhci9nZXN0dXJlcy9nZXN0dXJlJztcbmltcG9ydCB7IEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvYXZhaWxhYmxlLWdlb21ldHJpYy1zaGFwZXMnO1xuaW1wb3J0IHsgQ2FudmFzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLy4uL3NlcnZpY2VzL2NhbnZhcy1tYW5hZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcblxuY29uc3QgQmxhY2sgPSAnIzAwMDAwMCc7XG5jb25zdCBUcmFuc3BhcmVudCA9ICd0cmFuc3BhcmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1tb2JpbGUtc2tldGNoLXRvb2wnLFxuICB0ZW1wbGF0ZTogYDxpb24tY29udGVudD5cbiAgPGRpdiBjbGFzcz1cImRpdi1jYW52YXMtY29udGFpbmVyXCIgKHRvdWNoc3RhcnQpPVwibW91c2VEb3duKCRldmVudClcIiAodG91Y2htb3ZlKT1cIm1vdXNlTW92ZSgkZXZlbnQpXCIgKHRvdWNoZW5kKT1cIm1vdXNlVXAoJGV2ZW50KVwiXG4gICAgI3BpbmNoRWxlbWVudD5cbiAgICA8Y2FudmFzIGlkPVwiY2FudmFzXCI+PC9jYW52YXM+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY29sb3ItcGlja2VyXCIgKm5nSWY9XCJpc1NlbGVjdGluZ0NvbG9yXCI+XG4gICAgICA8aW9uLWdyaWQgZml4ZWQ+XG4gICAgICAgIDxpb24tcm93PlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjYwMDAwXCIgKHRhcCk9XCJzZXRDb2xvcignIzY2MDAwMCcpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjYzMzAwXCIgKHRhcCk9XCJzZXRDb2xvcignIzY2MzMwMCcpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjY2NjAwXCIgKHRhcCk9XCJzZXRDb2xvcignIzY2NjYwMCcpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojMDA2NjAwXCIgKHRhcCk9XCJzZXRDb2xvcignIzAwNjYwMCcpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojMDAwMDY2XCIgKHRhcCk9XCJzZXRDb2xvcignIzAwMDA2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjYwMDY2XCIgKHRhcCk9XCJzZXRDb2xvcignIzY2MDA2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgPGlvbi1yb3c+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzAwMDBcIiAodGFwKT1cInNldENvbG9yKCcjQ0MwMDAwJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzY2MDBcIiAodGFwKT1cInNldENvbG9yKCcjQ0M2NjAwJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQ0NDMDBcIiAodGFwKT1cInNldENvbG9yKCcjQ0NDQzAwJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMENDMDBcIiAodGFwKT1cInNldENvbG9yKCcjMDBDQzAwJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDAwQ0NcIiAodGFwKT1cInNldENvbG9yKCcjMDAwMENDJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzAwQ0NcIiAodGFwKT1cInNldENvbG9yKCcjQ0MwMENDJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgICA8aW9uLXJvdz5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0ZGMDAwMFwiICh0YXApPVwic2V0Q29sb3IoJyNGRjAwMDAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0ZGODAwMFwiICh0YXApPVwic2V0Q29sb3IoJyNGRjgwMDAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0ZGRkYwMFwiICh0YXApPVwic2V0Q29sb3IoJyNGRkZGMDAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzAwRkYwMFwiICh0YXApPVwic2V0Q29sb3IoJyMwMEZGMDAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzAwMDBGRlwiICh0YXApPVwic2V0Q29sb3IoJyMwMDAwRkYnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0ZGMDBGRlwiICh0YXApPVwic2V0Q29sb3IoJyNGRjAwRkYnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8L2lvbi1yb3c+XG4gICAgICAgIDxpb24tcm93PlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojRkY2NjY2XCIgKHRhcCk9XCJzZXRDb2xvcignI0ZGNjY2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojRkZCMjY2XCIgKHRhcCk9XCJzZXRDb2xvcignI0ZGQjI2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojRkZGRjY2XCIgKHRhcCk9XCJzZXRDb2xvcignI0ZGRkY2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjZGRjY2XCIgKHRhcCk9XCJzZXRDb2xvcignIzY2RkY2NicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojNjY2NkZGXCIgKHRhcCk9XCJzZXRDb2xvcignIzY2NjZGRicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDxpb24tY29sIHN0eWxlPVwiYmFja2dyb3VuZDojRkY2NkZGXCIgKHRhcCk9XCJzZXRDb2xvcignI0ZGNjZGRicpXCI+XG4gICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgPGlvbi1yb3c+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjk5OTlcIiAodGFwKT1cInNldENvbG9yKCcjRkY5OTk5JylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkNDOTlcIiAodGFwKT1cInNldENvbG9yKCcjRkZDQzk5JylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkZGOTlcIiAodGFwKT1cInNldENvbG9yKCcjRkZGRjk5JylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiM5OUZGOTlcIiAodGFwKT1cInNldENvbG9yKCcjOTlGRjk5JylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiM5OTk5RkZcIiAodGFwKT1cInNldENvbG9yKCcjOTk5OUZGJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjk5RkZcIiAodGFwKT1cInNldENvbG9yKCcjRkY5OUZGJylcIj5cbiAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgICA8aW9uLXJvdz5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0ZGRkZGRlwiICh0YXApPVwic2V0Q29sb3IoJyNGRkZGRkYnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6I0MwQzBDMFwiICh0YXApPVwic2V0Q29sb3IoJyNDMEMwQzAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzgwODA4MFwiICh0YXApPVwic2V0Q29sb3IoJyM4MDgwODAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzYwNjA2MFwiICh0YXApPVwic2V0Q29sb3IoJyM2MDYwNjAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzMwMzAzMFwiICh0YXApPVwic2V0Q29sb3IoJyM2MDYwNjAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cImJhY2tncm91bmQ6IzAwMDAwMFwiICh0YXApPVwic2V0Q29sb3IoJyMwMDAwMDAnKVwiPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgPC9pb24tZ3JpZD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2lvbi1jb250ZW50PlxuXG48aW9uLWZvb3Rlcj5cbiAgPGlvbi10b29sYmFyPlxuICAgIDxkaXYgY2xhc3M9XCJkaXYtZWRpdC10b29sYmFyXCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnV0dG9uLWVkaXQtdG9vbGJhclwiIGlvbi1idXR0b24gbGFyZ2UgW2NsZWFyXT1cInRydWVcIiAoY2xpY2spPVwicHJlc2VudFNoYXBlQWN0aW9uU2hlZXQoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zaGFwZXNcIiBpZD1cImljb25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ1dHRvbi1lZGl0LXRvb2xiYXJcIiBpb24tYnV0dG9uIGxhcmdlIFtjbGVhcl09XCJ0cnVlXCIgKGNsaWNrKT1cInByZXNlbnRQaWN0b2dyYW1zQWN0aW9uU2hlZXQoKVwiICpuZ0lmPVwiaGFzUGljdG9ncmFtc1wiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1pbWFnZXNcIiBpZD1cImljb25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ1dHRvbi1lZGl0LXRvb2xiYXJcIiBpb24tYnV0dG9uIGxhcmdlIFtjbGVhcl09XCJ0cnVlXCIgKGNsaWNrKT1cInByZXNlbnRFZGl0QWN0aW9uU2hlZXQoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1lZGl0XCIgaWQ9XCJpY29uXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidXR0b24tZWRpdC10b29sYmFyXCIgaW9uLWJ1dHRvbiBsYXJnZSBbY2xlYXJdPVwiIWlzRHJhd2luZ1wiIChjbGljayk9XCJkcmF3KClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtcGVuY2lsLWFsdFwiIGlkPVwiaWNvblwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnV0dG9uLWVkaXQtdG9vbGJhclwiIGlvbi1idXR0b24gbGFyZ2UgW2NsZWFyXT1cInRydWVcIiAoY2xpY2spPVwib25Db2xvckNsaWNrZWQoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1wYWxldHRlXCIgaWQ9XCJpY29uXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidXR0b24tZWRpdC10b29sYmFyXCIgaW9uLWJ1dHRvbiBsYXJnZSBbY2xlYXJdPVwiIWlzUGFubmluZ1wiIChjbGljayk9XCJvbk1vdmVDbGlja2VkKClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtYXJyb3dzLWFsdFwiIGlkPVwiaWNvblwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnV0dG9uLWVkaXQtdG9vbGJhclwiIGlvbi1idXR0b24gbGFyZ2UgW2NsZWFyXT1cInRydWVcIiAoY2xpY2spPVwidW5kbygpXCIgKm5nSWY9XCJpc1VuZG9BdmFpbGFibGVcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtdW5kb1wiIGlkPVwiaWNvblwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgPC9kaXY+XG4gIDwvaW9uLXRvb2xiYXI+XG48L2lvbi1mb290ZXI+XG5gLFxuICBzdHlsZXM6IFtgLmRpdi1jYW52YXMtY29udGFpbmVye2hlaWdodDoxMDAlO3dpZHRoOjEwMCU7LW8tb2JqZWN0LWZpdDpjb250YWluO29iamVjdC1maXQ6Y29udGFpbjt0ZXh0LWFsaWduOmNlbnRlcjttYXJnaW46MCBhdXRvO3BhZGRpbmc6MCBhdXRvfS5zY3JvbGwtY29udGVudHtwYWRkaW5nOjAhaW1wb3J0YW50O292ZXJmbG93LXk6aGlkZGVufS5kaXYtZWRpdC10b29sYmFye3RleHQtYWxpZ246Y2VudGVyfS5idXR0b24tZWRpdC10b29sYmFye3BhZGRpbmc6NCUhaW1wb3J0YW50O21hcmdpbjowIWltcG9ydGFudH0uYWN0aW9uLXNoZWV0LWJ1dHRvbntmb250LWZhbWlseTpGb250QXdlc29tZSxBcmlhbH0uY29sb3ItcGlja2Vye3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjEwMCU7aGVpZ2h0OmF1dG87Ym90dG9tOjA7bGVmdDowfSNpY29ue2NvbG9yOiNiMzIwMTd9LmNvbHtwYWRkaW5nOjEwcHh9YF0sXG4gIHByb3ZpZGVyczogW0NhbnZhc01hbmFnZXJTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBNb2JpbGVTa2V0Y2hUb29sQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgZ2VzdHVyZTogR2VzdHVyZTtcbiAgQFZpZXdDaGlsZCgncGluY2hFbGVtZW50JykgZWxlbWVudDtcblxuICBwdWJsaWMgZmlsbENvbG9yOiBzdHJpbmc7XG4gIHB1YmxpYyBzdHJva2VDb2xvcjogc3RyaW5nO1xuICBwdWJsaWMgaXNDcm9wcGluZzogYm9vbGVhbjtcbiAgcHVibGljIGlzVW5kb0F2YWlsYWJsZTogYm9vbGVhbjtcbiAgcHVibGljIGlzU2VsZWN0aW5nQ29sb3I6IGJvb2xlYW47XG4gIHB1YmxpYyBpc0RyYXdpbmc6IGJvb2xlYW47XG4gIHB1YmxpYyBpc1Bhbm5pbmc6IGJvb2xlYW47XG5cbiAgQElucHV0KCkgcHVibGljIGltYWdlRGF0YTogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgbG9hZGVkSnNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgaWNvbnNQYXRoOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBpY29uczogW3N0cmluZ107XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBjYW52YXMgPSBuZXcgRXZlbnRFbWl0dGVyPGZhYnJpYy5DYW52YXM+KCk7XG5cbiAgcHJpdmF0ZSBpc0xvYWRlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwcmV2aW91c0ltYWdlRGF0YTogc3RyaW5nO1xuICBwcml2YXRlIGN1cnJlbnRKc29uOiBKU09OO1xuICBwcml2YXRlIHByZXZpb3VzSnNvbjogSlNPTjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aW9uU2hlZXRDdHJsOiBBY3Rpb25TaGVldENvbnRyb2xsZXIsXG4gICAgcHJpdmF0ZSBjYW52YXNNYW5hZ2VyU2VydmljZTogQ2FudmFzTWFuYWdlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5zdHJva2VDb2xvciA9IEJsYWNrO1xuICAgIHRoaXMuZmlsbENvbG9yID0gVHJhbnNwYXJlbnQ7XG4gICAgdGhpcy5pc0Nyb3BwaW5nID0gZmFsc2U7XG4gICAgdGhpcy5pc1Bhbm5pbmcgPSBmYWxzZTtcbiAgICB0aGlzLmlzTG9hZGVkID0gZmFsc2U7XG4gICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLmlzU2VsZWN0aW5nQ29sb3IgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLmltYWdlRGF0YSkge1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5lbXB0eUNhbnZhcygpO1xuICAgICAgaWYgKHRoaXMubG9hZGVkSnNvbiA9PSBudWxsIHx8IHRoaXMubG9hZGVkSnNvbi5sZW5ndGggPCAxMCkge1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEJhY2tncm91bmRGcm9tVVJMKHRoaXMuaW1hZ2VEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucHJldmlvdXNKc29uID0gSlNPTi5wYXJzZSh0aGlzLmxvYWRlZEpzb24pO1xuICAgICAgICB0aGlzLmN1cnJlbnRKc29uID0gdGhpcy5wcmV2aW91c0pzb247XG4gICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2VcbiAgICAgICAgICAubG9hZGZyb21Kc29uKEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMucHJldmlvdXNJbWFnZURhdGEgPSB0aGlzLmltYWdlRGF0YTtcbiAgICB9XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgaWYgKHRoaXMubG9hZGVkSnNvbiA9PT0gbnVsbCB8fCB0aGlzLmxvYWRlZEpzb24ubGVuZ3RoIDwgMTAgfHwgdGhpcy5pbWFnZURhdGEgIT09IHRoaXMucHJldmlvdXNJbWFnZURhdGEpIHtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5lbXB0eUNhbnZhcygpO1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEJhY2tncm91bmRGcm9tVVJMKHRoaXMuaW1hZ2VEYXRhKTtcbiAgICAgICAgdGhpcy5wcmV2aW91c0ltYWdlRGF0YSA9IHRoaXMuaW1hZ2VEYXRhO1xuICAgICAgICB0aGlzLmN1cnJlbnRKc29uID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5sb2FkZWRKc29uICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLmN1cnJlbnRKc29uKSkge1xuICAgICAgICAgIHRoaXMucHJldmlvdXNKc29uID0gSlNPTi5wYXJzZSh0aGlzLmxvYWRlZEpzb24pO1xuICAgICAgICAgIHRoaXMuY3VycmVudEpzb24gPSB0aGlzLnByZXZpb3VzSnNvbjtcbiAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlXG4gICAgICAgICAgICAubG9hZGZyb21Kc29uKEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuZ2VzdHVyZSA9IG5ldyBHZXN0dXJlKHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KTtcbiAgICB0aGlzLmdlc3R1cmUubGlzdGVuKCk7XG4gICAgdGhpcy5nZXN0dXJlLm9uKCdwaW5jaCcsICRldmVudCA9PiB0aGlzLnBpbmNoKCRldmVudCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5nZXN0dXJlLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGdldCBoYXNQaWN0b2dyYW1zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKCF0aGlzLmljb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUZXh0KCkge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkVGV4dCh0aGlzLnN0cm9rZUNvbG9yLCAndGV4dCAnKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRTaGFwZShzaGFwZTogc3RyaW5nKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRHZW9tZXRyaWNTaGFwZShcbiAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlW3NoYXBlXVxuICAgICk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW1hZ2Uoc291cmNlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEltYWdlKHRoaXMuaWNvbnNQYXRoICsgc291cmNlKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBjaGFuZ2VTdHJva2VDb2xvcigpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmNoYW5nZVNlbGVjdGVkT2JqZWN0c1N0cm9rZUNvbG9yKFxuICAgICAgdGhpcy5zdHJva2VDb2xvclxuICAgICk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5zZXRGcmVlRHJhd2luZ0JydXNoQ29sb3IodGhpcy5zdHJva2VDb2xvcik7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgYnJpbmdGb3dhcmQoKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5icmluZ1NlbGVjdGVkT2JqZWN0c1RvRnJvbnQoKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZW5kVG9CYWNrKCkge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2VuZFNlbGVjdGVkT2JqZWN0c1RvQmFjaygpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGNyb3AoKSB7XG4gICAgdGhpcy5pc0Nyb3BwaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnJlc2V0Wm9vbSgpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZGlzYWJsZVNlbGVjdGlvbigpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkU2VsZWN0aW9uUmVjdGFuZ2xlKCk7XG4gICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSB0cnVlO1xuICAgIHRoaXMucHJldmlvdXNKc29uID0gdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5qc29uRnJvbUNhbnZhcygpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGRlbGV0ZVNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmRlbGV0ZVNlbGVjdGVkT2JqZWN0cygpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIG1vdXNlVXAoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmlzQ3JvcHBpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuY3JvcEltYWdlKCk7XG4gICAgICB0aGlzLmlzVW5kb0F2YWlsYWJsZSA9IHRydWU7XG4gICAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNDcm9wcGluZykge1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hanVzdENyb3BSZWN0YW5nbGUoZXZlbnQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc1Bhbm5pbmcpIHtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5wYW5DYW52YXMoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBtb3VzZURvd24oZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnN0YXJ0U2VsZWN0aW5nQ3JvcFJlY3RhbmdsZShldmVudCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzUGFubmluZykge1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldExhc3RQYW5Qb3NpdGlvbihldmVudCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBpbmNoKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS56b29tKGV2ZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBncm91cCgpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmdyb3VwU2VsZWN0ZWRPYmplY3RzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgdW5kbygpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmxvYWRmcm9tSnNvbih0aGlzLnByZXZpb3VzSnNvbik7XG4gICAgdGhpcy5pc1VuZG9BdmFpbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbG9yQ2xpY2tlZCgpIHtcbiAgICB0aGlzLmlzU2VsZWN0aW5nQ29sb3IgPSB0cnVlO1xuICAgIHRoaXMuc3RvcFBhbm5pbmcoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbk1vdmVDbGlja2VkKCkge1xuICAgIHRoaXMuaXNQYW5uaW5nID0gIXRoaXMuaXNQYW5uaW5nO1xuICAgICh0aGlzLmlzUGFubmluZykgPyB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmRpc2FibGVTZWxlY3Rpb24oKSA6IHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW5hYmxlU2xlY3Rpb24oKTtcbiAgfVxuXG4gIHB1YmxpYyBzdG9wUGFubmluZygpIHtcbiAgICBpZiAodGhpcy5pc1Bhbm5pbmcpIHtcbiAgICAgIHRoaXMuaXNQYW5uaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmVuYWJsZVNsZWN0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNldENvbG9yKGNvbG9yOiBzdHJpbmcpIHtcbiAgICB0aGlzLnN0cm9rZUNvbG9yID0gY29sb3I7XG4gICAgdGhpcy5jaGFuZ2VTdHJva2VDb2xvcigpO1xuICAgIHRoaXMuaXNTZWxlY3RpbmdDb2xvciA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGRyYXcoKSB7XG4gICAgdGhpcy5pc0RyYXdpbmcgPSAhdGhpcy5pc0RyYXdpbmc7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS50b2dnbGVGcmVlRHJhd2luZygpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKHRoaXMuc3Ryb2tlQ29sb3IpO1xuICB9XG5cbiAgcHJpdmF0ZSBkaXNhYmxlRHJhd2luZygpIHtcbiAgICBpZiAodGhpcy5pc0RyYXdpbmcpIHtcbiAgICAgIHRoaXMuaXNEcmF3aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnRvZ2dsZUZyZWVEcmF3aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2xhdGVTaGFwZUJ1dHRvbnNUZXh0KCk6IEFycmF5PFN0cmluZz4ge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uQXJyYXkgPSBbXTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgncmVjdGFuZ2xlJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCd0cmlhbmdsZScpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnY2lyY2xlJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdsaW5lJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjcm9zcycpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgndGV4dCcpKTtcbiAgICByZXR1cm4gdHJhbnNsYXRpb25BcnJheTtcbiAgfVxuXG4gIHB1YmxpYyBwcmVzZW50U2hhcGVBY3Rpb25TaGVldCgpIHtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG5cbiAgICBjb25zdCB0aXRsZVRleHQgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdhZGRHZW9tZXRyaWNTaGFwZScpO1xuICAgIGNvbnN0IGJ1dHRvbnNUZXh0ID0gdGhpcy50cmFuc2xhdGVTaGFwZUJ1dHRvbnNUZXh0KCk7XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgY29uc3QgYWN0aW9uU2hlZXQgPSB0aGlzLmFjdGlvblNoZWV0Q3RybC5jcmVhdGUoe1xuICAgICAgdGl0bGU6IHRpdGxlVGV4dCxcbiAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMGM4ICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRHZW9tZXRyaWNTaGFwZShcbiAgICAgICAgICAgICAgdGhpcy5zdHJva2VDb2xvcixcbiAgICAgICAgICAgICAgdGhpcy5maWxsQ29sb3IsXG4gICAgICAgICAgICAgIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLlJlY3RhbmdsZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjBkOCAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICAgICAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgICAgICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5UcmlhbmdsZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjExMSAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICAgICAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgICAgICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5DaXJjbGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYwNjggICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgICAgICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgICAgICAgICAgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuTGluZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjA2NyAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICAgICAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgICAgICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5Dcm9zc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjAzMSAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkVGV4dCh0aGlzLnN0cm9rZUNvbG9yLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSk7XG4gICAgYWN0aW9uU2hlZXQucHJlc2VudCgpO1xuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2xhdGVFZGl0QnV0dG9uc1RleHQoKTogQXJyYXk8U3RyaW5nPiB7XG4gICAgY29uc3QgdHJhbnNsYXRpb25BcnJheSA9IFtdO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjcm9wJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdncm91cCcpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnYnJpbmdUb0Zyb250JykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdzZW5kVG9CYWNrJykpO1xuICAgIHRyYW5zbGF0aW9uQXJyYXkucHVzaCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdkZWxldGUnKSk7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uQXJyYXk7XG4gIH1cblxuICBwdWJsaWMgcHJlc2VudEVkaXRBY3Rpb25TaGVldCgpIHtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG5cbiAgICBjb25zdCB0aXRsZVRleHQgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdlZGl0aW9uJyk7XG5cbiAgICBjb25zdCBidXR0b25zVGV4dCA9IHRoaXMudHJhbnNsYXRlRWRpdEJ1dHRvbnNUZXh0KCk7XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgY29uc3QgYWN0aW9uU2hlZXQgPSB0aGlzLmFjdGlvblNoZWV0Q3RybC5jcmVhdGUoe1xuICAgICAgdGl0bGU6IHRpdGxlVGV4dCxcbiAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMTI1ICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3JvcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMjQ3ICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ncm91cCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMGRlICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5icmluZ0Zvd2FyZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMGRkICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZW5kVG9CYWNrKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYxZjggICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRlbGV0ZVNlbGVjdGlvbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuICAgIGFjdGlvblNoZWV0LnByZXNlbnQoKTtcbiAgfVxuXG4gIHB1YmxpYyBwcmVzZW50UGljdG9ncmFtc0FjdGlvblNoZWV0KCkge1xuICAgIHRoaXMuZGlzYWJsZURyYXdpbmcoKTtcblxuICAgIGNvbnN0IGJ1dHRvbnMgPSBbXTtcbiAgICBjb25zdCBhY3Rpb25TaGVldFN0eWxlcyA9IFtdO1xuICAgIGNvbnN0IGltYWdlcyA9IHRoaXMuaWNvbnM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbWFnZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgIHN0eWxlLnR5cGUgPSAndGV4dC9jc3MnO1xuICAgICAgc3R5bGUuaW5uZXJIVE1MID1cbiAgICAgICAgJy5jdXN0b21DU1NDbGFzcycgK1xuICAgICAgICBpICtcbiAgICAgICAgJ3tiYWNrZ3JvdW5kOiB1cmwoJyArXG4gICAgICAgIFwiJ1wiICtcbiAgICAgICAgdGhpcy5pY29uc1BhdGggK1xuICAgICAgICBpbWFnZXNbaV0gK1xuICAgICAgICBcIidcIiArXG4gICAgICAgICcpIG5vLXJlcGVhdCAhaW1wb3J0YW50O3BhZGRpbmctbGVmdDo1MHB4ICFpbXBvcnRhbnQ7aGVpZ2h0OjgwcHg7IGJhY2tncm91bmQtcG9zaXRpb246IGxlZnQgY2VudGVyICFpbXBvcnRhbnQ7fSc7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgICAgIGFjdGlvblNoZWV0U3R5bGVzLnB1c2goc3R5bGUpO1xuICAgICAgYnV0dG9ucy5wdXNoKHtcbiAgICAgICAgcm9sZTogJ2Rlc3RydWN0aXZlJyxcbiAgICAgICAgdGV4dDogaW1hZ2VzW2ldLFxuICAgICAgICBjc3NDbGFzczogJ2N1c3RvbUNTU0NsYXNzJyArIGksXG4gICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZEltYWdlKGltYWdlc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHRpdGxlVGV4dCA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2FkZFBpY3RvZ3JhbScpO1xuXG4gICAgY29uc3QgYWN0aW9uU2hlZXQgPSB0aGlzLmFjdGlvblNoZWV0Q3RybC5jcmVhdGUoe1xuICAgICAgdGl0bGU6IHRpdGxlVGV4dCxcbiAgICAgIGJ1dHRvbnM6IGJ1dHRvbnNcbiAgICB9KTtcbiAgICBhY3Rpb25TaGVldC5vbkRpZERpc21pc3MoKCkgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhY3Rpb25TaGVldFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYWN0aW9uU2hlZXRTdHlsZXNbaV0ucGFyZW50Tm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgYWN0aW9uU2hlZXRTdHlsZXNbaV0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChhY3Rpb25TaGVldFN0eWxlc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGFjdGlvblNoZWV0LnByZXNlbnQoKTtcbiAgfVxuXG4gIHB1YmxpYyBlbWl0Q2FudmFzKCkge1xuICAgIHRoaXMuY2FudmFzLmVtaXQodGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5jYW52YXMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IElvbmljTW9kdWxlIH0gZnJvbSAnaW9uaWMtYW5ndWxhcic7XG5cbmltcG9ydCB7IE1vYmlsZVNrZXRjaFRvb2xDb21wb25lbnQgfSBmcm9tICcuL21vYmlsZS1jb21wb25lbnQvbW9iaWxlLXNrZXRjaC10b29sLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDYW52YXNNYW5hZ2VyU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIElvbmljTW9kdWxlXSxcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgTW9iaWxlU2tldGNoVG9vbENvbXBvbmVudCxcbiAgXSxcbiAgZXhwb3J0czogW01vYmlsZVNrZXRjaFRvb2xDb21wb25lbnRdXG59KVxuZXhwb3J0IGNsYXNzIFNrZXRjaFRvb2xNb2R1bGUge31cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLEFBQU8sdUJBQU0sVUFBVSxHQUFHO0lBQ3hCLEtBQUssRUFBRSxHQUFHO0lBQ1YsTUFBTSxFQUFFLEdBQUc7SUFDWCxJQUFJLEVBQUUsRUFBRTtJQUNSLEdBQUcsRUFBRSxFQUFFO0lBQ1AsTUFBTSxFQUFFLEdBQUc7SUFDWCxNQUFNLEVBQUUsRUFBRTtJQUNWLHFCQUFxQixFQUFFLEVBQUU7SUFDekIsVUFBVSxFQUFFLEVBQUU7Q0FDZixDQUFDOzs7Ozs7QUNURjtJQTBCRTtRQUNFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUM7S0FDMUM7Ozs7SUFFRCxJQUFJLGVBQWU7UUFDakIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0tBQ3BCOzs7O0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO0tBQ2pDOzs7O0lBRUQsSUFBSSxxQkFBcUI7UUFDdkIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQztLQUNwQzs7OztJQUVELElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztLQUN0Qzs7OztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0tBQ3ZDOzs7O0lBRU0sV0FBVztRQUNoQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDZixJQUFJLENBQUMs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
\No newline at end of file