keevo-components 2.0.269 → 2.0.271

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,140 @@
1
+ import { ImageCutterService } from './../../api/services/image.cutter.service';
2
+ import { Component, inject, model, viewChild, input, output } from '@angular/core';
3
+ import { NotificationService } from '../../api/services/notification.service';
4
+ import { CommonModule } from '@angular/common';
5
+ import { ButtonModule } from 'primeng/button';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "primeng/button";
8
+ export class KvImageUploadComponentNew {
9
+ constructor() {
10
+ this.notificationService = inject(NotificationService);
11
+ this.imageCutterService = inject(ImageCutterService);
12
+ this.file = null;
13
+ this.fileSrc = model(null);
14
+ this.widthComponent = input('auto');
15
+ this.heightComponent = input('auto');
16
+ this.maxHeightImage = input('400px');
17
+ this.description = input();
18
+ this.cutImage = input(false);
19
+ this.cutWidth = input(0);
20
+ this.cutHeight = input(0);
21
+ this.cutCircle = input(false);
22
+ this.maintainAspectRatio = input(true);
23
+ this.fileEmit = output();
24
+ this.deleteEmit = output();
25
+ this.fileInput = viewChild('fileInput');
26
+ }
27
+ onDragOver(event) {
28
+ event.preventDefault();
29
+ event.stopPropagation();
30
+ this.addDragOverClass(event);
31
+ }
32
+ onDragLeave(event) {
33
+ event.preventDefault();
34
+ event.stopPropagation();
35
+ this.removeDragOverClass(event);
36
+ }
37
+ onDrop(event) {
38
+ event.preventDefault();
39
+ event.stopPropagation();
40
+ this.removeDragOverClass(event);
41
+ if (event.dataTransfer && event.dataTransfer.files.length > 0) {
42
+ this.handleFile(event.dataTransfer.files[0]);
43
+ }
44
+ }
45
+ onFileSelected(event) {
46
+ const inputElement = event.target;
47
+ if (inputElement.files && inputElement.files.length > 0) {
48
+ this.handleFile(inputElement.files[0]);
49
+ }
50
+ }
51
+ triggerClick() {
52
+ if (!this.fileSrc()) {
53
+ this.fileInput()?.nativeElement.click();
54
+ }
55
+ }
56
+ handleFile(file) {
57
+ if (file.type.startsWith('image/')) {
58
+ if (this.cutImage() == true) {
59
+ const reader = new FileReader();
60
+ reader.onload = async () => {
61
+ try {
62
+ const result = await this.imageCutterService.cut(reader.result?.toString() ?? '', this.cutWidth(), this.cutHeight(), this.cutCircle(), false, this.maintainAspectRatio());
63
+ if (result) {
64
+ this.file = file;
65
+ this.fileSrc.set(result);
66
+ const processedFile = this.base64ToFile(this.fileSrc(), this.file?.name ?? 'file.png');
67
+ this.fileEmit.emit(processedFile);
68
+ }
69
+ else {
70
+ const inputEl = this.fileInput();
71
+ if (inputEl) {
72
+ inputEl.nativeElement.value = '';
73
+ }
74
+ }
75
+ }
76
+ catch (error) {
77
+ console.error('Erro ao cortar a imagem:', error);
78
+ this.notificationService.toastError('Erro ao cortar a imagem');
79
+ }
80
+ };
81
+ reader.readAsDataURL(file);
82
+ }
83
+ else {
84
+ this.file = file;
85
+ const reader = new FileReader();
86
+ reader.onload = () => {
87
+ this.fileSrc.set(reader.result);
88
+ };
89
+ reader.readAsDataURL(file);
90
+ this.fileEmit.emit(file);
91
+ }
92
+ }
93
+ else {
94
+ this.notificationService.toastError('Apenas arquivos de imagem são permitidos.');
95
+ }
96
+ }
97
+ base64ToFile(base64String, fileName) {
98
+ // Extrair o tipo MIME da string base64
99
+ const arr = base64String.split(',');
100
+ const mime = arr[0].match(/:(.*?);/)[1];
101
+ // Converter Base64 para Binário
102
+ const binaryString = atob(arr[1]);
103
+ const len = binaryString.length;
104
+ const uint8Array = new Uint8Array(len);
105
+ for (let i = 0; i < len; i++) {
106
+ uint8Array[i] = binaryString.charCodeAt(i);
107
+ }
108
+ // Criar um Blob e, em seguida, um objeto File
109
+ const blob = new Blob([uint8Array], { type: mime });
110
+ const file = new File([blob], fileName, { type: mime });
111
+ return file;
112
+ }
113
+ addDragOverClass(event) {
114
+ const container = event.target;
115
+ container.classList.add('dragover');
116
+ }
117
+ removeDragOverClass(event) {
118
+ const container = event.target;
119
+ container.classList.remove('dragover');
120
+ }
121
+ deleteImage() {
122
+ this.file = null;
123
+ this.fileSrc.set(null);
124
+ const inputEl = this.fileInput();
125
+ if (inputEl) {
126
+ inputEl.nativeElement.value = '';
127
+ }
128
+ this.deleteEmit.emit();
129
+ }
130
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: KvImageUploadComponentNew, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
131
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.8", type: KvImageUploadComponentNew, isStandalone: true, selector: "kv-image-upload-new", inputs: { fileSrc: { classPropertyName: "fileSrc", publicName: "fileSrc", isSignal: true, isRequired: false, transformFunction: null }, widthComponent: { classPropertyName: "widthComponent", publicName: "widthComponent", isSignal: true, isRequired: false, transformFunction: null }, heightComponent: { classPropertyName: "heightComponent", publicName: "heightComponent", isSignal: true, isRequired: false, transformFunction: null }, maxHeightImage: { classPropertyName: "maxHeightImage", publicName: "maxHeightImage", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, cutImage: { classPropertyName: "cutImage", publicName: "cutImage", isSignal: true, isRequired: false, transformFunction: null }, cutWidth: { classPropertyName: "cutWidth", publicName: "cutWidth", isSignal: true, isRequired: false, transformFunction: null }, cutHeight: { classPropertyName: "cutHeight", publicName: "cutHeight", isSignal: true, isRequired: false, transformFunction: null }, cutCircle: { classPropertyName: "cutCircle", publicName: "cutCircle", isSignal: true, isRequired: false, transformFunction: null }, maintainAspectRatio: { classPropertyName: "maintainAspectRatio", publicName: "maintainAspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSrc: "fileSrcChange", fileEmit: "fileEmit", deleteEmit: "deleteEmit" }, host: { properties: { "style.width": "widthComponent()", "style.height": "heightComponent()" } }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"file-upload-container\"\r\n [class.has-file]=\"fileSrc()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n (click)=\"triggerClick()\"\r\n>\r\n <input\r\n type=\"file\"\r\n #fileInput\r\n (change)=\"onFileSelected($event)\"\r\n accept=\"image/*\"\r\n hidden\r\n />\r\n\r\n @if (!fileSrc()) {\r\n <div class=\"dropzone-content\">\r\n <div class=\"cloud-icon-wrapper\">\r\n <span class=\"material-symbols-outlined\">cloud_upload</span>\r\n </div>\r\n <div class=\"text-content\">\r\n @if (description()) {\r\n <p class=\"main-text description-text\">{{ description() }}</p>\r\n } @else {\r\n <p class=\"main-text\">\r\n <span class=\"blue-text\">Clique para selecionar</span> ou arraste uma\r\n imagem aqui\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (fileSrc() || file) {\r\n <div class=\"preview-wrapper\">\r\n <img\r\n [src]=\"fileSrc()\"\r\n [alt]=\"file?.name\"\r\n class=\"preview-image\"\r\n [style.maxHeight]=\"maxHeightImage()\"\r\n />\r\n\r\n <button\r\n pButton\r\n (click)=\"deleteImage(); $event.stopPropagation()\"\r\n class=\"delete-button\"\r\n [text]=\"true\"\r\n [icon]=\"'pi pi-trash'\"\r\n ></button>\r\n </div>\r\n }\r\n</div>", styles: [":host{display:block}.file-upload-container{width:100%;border:1px dashed #cbd5e1;border-radius:.75rem;background-color:#f8fafc;min-height:160px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease-in-out;position:relative;padding:1.5rem;box-sizing:border-box;height:100%;overflow:hidden}.file-upload-container:hover,.file-upload-container.dragover{border-color:#3b82f6!important;background-color:#eff6ff}.file-upload-container.has-file{cursor:default;border-color:#cbd5e1;padding:0;border-style:solid;overflow:hidden;min-height:160px}.file-upload-container.has-file:hover{border-color:#3b82f6!important}.dropzone-content{display:flex;flex-direction:column;align-items:center;pointer-events:none;width:100%}.cloud-icon-wrapper{background-color:#e0f2fe;color:#3b82f6;width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto .75rem}.cloud-icon-wrapper span{font-size:24px}.text-content{text-align:center}.main-text{font-size:.875rem;color:#4b5563;margin:0}.main-text.description-text{font-weight:600}.main-text .blue-text{color:#2563eb;font-weight:600}.sub-text{font-size:.75rem;color:#9ca3af;margin:.25rem 0 0}.preview-wrapper{width:100%;height:100%;min-height:160px;background-color:#f1f5f9;position:relative;display:flex;align-items:center;justify-content:center}.preview-image{width:auto;height:auto;max-width:100%;display:block;object-fit:contain}.image-preview-container{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.delete-button{position:absolute;top:0;right:0;width:2rem;height:2rem;background-color:transparent!important;color:#b91c1c!important;transition:color .5s ease;border:none}.delete-button:hover{color:#ef4444!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }] }); }
132
+ }
133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: KvImageUploadComponentNew, decorators: [{
134
+ type: Component,
135
+ args: [{ selector: 'kv-image-upload-new', standalone: true, imports: [CommonModule, ButtonModule], host: {
136
+ '[style.width]': 'widthComponent()',
137
+ '[style.height]': 'heightComponent()',
138
+ }, template: "<div\r\n class=\"file-upload-container\"\r\n [class.has-file]=\"fileSrc()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n (click)=\"triggerClick()\"\r\n>\r\n <input\r\n type=\"file\"\r\n #fileInput\r\n (change)=\"onFileSelected($event)\"\r\n accept=\"image/*\"\r\n hidden\r\n />\r\n\r\n @if (!fileSrc()) {\r\n <div class=\"dropzone-content\">\r\n <div class=\"cloud-icon-wrapper\">\r\n <span class=\"material-symbols-outlined\">cloud_upload</span>\r\n </div>\r\n <div class=\"text-content\">\r\n @if (description()) {\r\n <p class=\"main-text description-text\">{{ description() }}</p>\r\n } @else {\r\n <p class=\"main-text\">\r\n <span class=\"blue-text\">Clique para selecionar</span> ou arraste uma\r\n imagem aqui\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (fileSrc() || file) {\r\n <div class=\"preview-wrapper\">\r\n <img\r\n [src]=\"fileSrc()\"\r\n [alt]=\"file?.name\"\r\n class=\"preview-image\"\r\n [style.maxHeight]=\"maxHeightImage()\"\r\n />\r\n\r\n <button\r\n pButton\r\n (click)=\"deleteImage(); $event.stopPropagation()\"\r\n class=\"delete-button\"\r\n [text]=\"true\"\r\n [icon]=\"'pi pi-trash'\"\r\n ></button>\r\n </div>\r\n }\r\n</div>", styles: [":host{display:block}.file-upload-container{width:100%;border:1px dashed #cbd5e1;border-radius:.75rem;background-color:#f8fafc;min-height:160px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;transition:all .2s ease-in-out;position:relative;padding:1.5rem;box-sizing:border-box;height:100%;overflow:hidden}.file-upload-container:hover,.file-upload-container.dragover{border-color:#3b82f6!important;background-color:#eff6ff}.file-upload-container.has-file{cursor:default;border-color:#cbd5e1;padding:0;border-style:solid;overflow:hidden;min-height:160px}.file-upload-container.has-file:hover{border-color:#3b82f6!important}.dropzone-content{display:flex;flex-direction:column;align-items:center;pointer-events:none;width:100%}.cloud-icon-wrapper{background-color:#e0f2fe;color:#3b82f6;width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto .75rem}.cloud-icon-wrapper span{font-size:24px}.text-content{text-align:center}.main-text{font-size:.875rem;color:#4b5563;margin:0}.main-text.description-text{font-weight:600}.main-text .blue-text{color:#2563eb;font-weight:600}.sub-text{font-size:.75rem;color:#9ca3af;margin:.25rem 0 0}.preview-wrapper{width:100%;height:100%;min-height:160px;background-color:#f1f5f9;position:relative;display:flex;align-items:center;justify-content:center}.preview-image{width:auto;height:auto;max-width:100%;display:block;object-fit:contain}.image-preview-container{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.delete-button{position:absolute;top:0;right:0;width:2rem;height:2rem;background-color:transparent!important;color:#b91c1c!important;transition:color .5s ease;border:none}.delete-button:hover{color:#ef4444!important}\n"] }]
139
+ }] });
140
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3YtaW1hZ2UtdXBsb2FkLW5ldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rZWV2by1jb21wb25lbnRzL3NyYy9saWIvY29tcG9uZW50cy9rdi1pbWFnZS11cGxvYWQtbmV3L2t2LWltYWdlLXVwbG9hZC1uZXcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva2Vldm8tY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMva3YtaW1hZ2UtdXBsb2FkLW5ldy9rdi1pbWFnZS11cGxvYWQtbmV3LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxTQUFTLEVBQWMsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFjOUMsTUFBTSxPQUFPLHlCQUF5QjtJQVp0QztRQWNVLHdCQUFtQixHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2xELHVCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRXhELFNBQUksR0FBZ0IsSUFBSSxDQUFDO1FBRXpCLFlBQU8sR0FBRyxLQUFLLENBQThCLElBQUksQ0FBQyxDQUFDO1FBRW5ELG1CQUFjLEdBQUcsS0FBSyxDQUFTLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLG9CQUFlLEdBQUcsS0FBSyxDQUFTLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLG1CQUFjLEdBQUcs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QWdCLENBQUMsS0FBZ0I7UUFDL0IsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7UUFDOUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELG1CQUFtQixDQUFDLEtBQWdCO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFxQixDQUFDO1FBQzlDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pDLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDekIsQ0FBQzs4R0ExSlUseUJBQXlCO2tHQUF6Qix5QkFBeUIsNHZEQ2xCdEMsaTdDQW9ETSxrekREekNNLFlBQVksOEJBQUUsWUFBWTs7MkZBT3pCLHlCQUF5QjtrQkFackMsU0FBUzsrQkFDRSxxQkFBcUIsY0FHbkIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxRQUMvQjt3QkFDSixlQUFlLEVBQUUsa0JBQWtCO3dCQUNuQyxnQkFBZ0IsRUFBRSxtQkFBbUI7cUJBQ3RDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW1hZ2VDdXR0ZXJTZXJ2aWNlIH0gZnJvbSAnLi8uLi8uLi9hcGkvc2VydmljZXMvaW1hZ2UuY3V0dGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIGluamVjdCwgbW9kZWwsIHZpZXdDaGlsZCwgaW5wdXQsIG91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYXBpL3NlcnZpY2VzL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdrdi1pbWFnZS11cGxvYWQtbmV3JyxcclxuICB0ZW1wbGF0ZVVybDogJy4va3YtaW1hZ2UtdXBsb2FkLW5ldy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2t2LWltYWdlLXVwbG9hZC1uZXcuY29tcG9uZW50LnNjc3MnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgQnV0dG9uTW9kdWxlXSxcclxuICBob3N0OiB7XHJcbiAgICAnW3N0eWxlLndpZHRoXSc6ICd3aWR0aENvbXBvbmVudCgpJyxcclxuICAgICdbc3R5bGUuaGVpZ2h0XSc6ICdoZWlnaHRDb21wb25lbnQoKScsXHJcbiAgfSxcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBLdkltYWdlVXBsb2FkQ29tcG9uZW50TmV3IHtcclxuXHJcbiAgcHJpdmF0ZSBub3RpZmljYXRpb25TZXJ2aWNlID0gaW5qZWN0KE5vdGlmaWNhdGlvblNlcnZpY2UpO1xyXG4gIHByaXZhdGUgaW1hZ2VDdXR0ZXJTZXJ2aWNlID0gaW5qZWN0KEltYWdlQ3V0dGVyU2VydmljZSk7XHJcblxyXG4gIGZpbGU6IEZpbGUgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgZmlsZVNyYyA9IG1vZGVsPHN0cmluZyB8IEFycmF5QnVmZmVyIHwgbnVsbD4obnVsbCk7XHJcblxyXG4gIHdpZHRoQ29tcG9uZW50ID0gaW5wdXQ8c3RyaW5nPignYXV0bycpO1xyXG4gIGhlaWdodENvbXBvbmVudCA9IGlucHV0PHN0cmluZz4oJ2F1dG8nKTtcclxuICBtYXhIZWlnaHRJbWFnZSA9IGlucHV0PHN0cmluZz4oJzQwMHB4Jyk7XHJcbiAgZGVzY3JpcHRpb24gPSBpbnB1dDxzdHJpbmcgfCB1bmRlZmluZWQ+KCk7XHJcbiAgY3V0SW1hZ2UgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcbiAgY3V0V2lkdGggPSBpbnB1dDxudW1iZXI+KDApO1xyXG4gIGN1dEhlaWdodCA9IGlucHV0PG51bWJlcj4oMCk7XHJcbiAgY3V0Q2lyY2xlID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIG1haW50YWluQXNwZWN0UmF0aW8gPSBpbnB1dDxib29sZWFuPih0cnVlKTtcclxuXHJcbiAgZmlsZUVtaXQgPSBvdXRwdXQ8RmlsZT4oKTtcclxuICBkZWxldGVFbWl0ID0gb3V0cHV0PHZvaWQ+KCk7XHJcblxyXG4gIGZpbGVJbnB1dCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+PignZmlsZUlucHV0Jyk7XHJcblxyXG4gIG9uRHJhZ092ZXIoZXZlbnQ6IERyYWdFdmVudCkge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgdGhpcy5hZGREcmFnT3ZlckNsYXNzKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIG9uRHJhZ0xlYXZlKGV2ZW50OiBEcmFnRXZlbnQpIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMucmVtb3ZlRHJhZ092ZXJDbGFzcyhldmVudCk7XHJcbiAgfVxyXG5cclxuICBvbkRyb3AoZXZlbnQ6IERyYWdFdmVudCkge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgdGhpcy5yZW1vdmVEcmFnT3ZlckNsYXNzKGV2ZW50KTtcclxuXHJcbiAgICBpZiAoZXZlbnQuZGF0YVRyYW5zZmVyICYmIGV2ZW50LmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlRmlsZShldmVudC5kYXRhVHJhbnNmZXIuZmlsZXNbMF0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25GaWxlU2VsZWN0ZWQoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBjb25zdCBpbnB1dEVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcclxuXHJcbiAgICBpZiAoaW5wdXRFbGVtZW50LmZpbGVzICYmIGlucHV0RWxlbWVudC5maWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlRmlsZShpbnB1dEVsZW1lbnQuZmlsZXNbMF0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdHJpZ2dlckNsaWNrKCkge1xyXG4gICAgaWYgKCF0aGlzLmZpbGVTcmMoKSkge1xyXG4gICAgICB0aGlzLmZpbGVJbnB1dCgpPy5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBoYW5kbGVGaWxlKGZpbGU6IEZpbGUpIHtcclxuICAgIGlmIChmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHtcclxuICAgICAgaWYgKHRoaXMuY3V0SW1hZ2UoKSA9PSB0cnVlKSB7XHJcblxyXG4gICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGFzeW5jICgpID0+IHtcclxuICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuaW1hZ2VDdXR0ZXJTZXJ2aWNlLmN1dChcclxuICAgICAgICAgICAgICByZWFkZXIucmVzdWx0Py50b1N0cmluZygpID8/ICcnLFxyXG4gICAgICAgICAgICAgIHRoaXMuY3V0V2lkdGgoKSxcclxuICAgICAgICAgICAgICB0aGlzLmN1dEhlaWdodCgpLFxyXG4gICAgICAgICAgICAgIHRoaXMuY3V0Q2lyY2xlKCksXHJcbiAgICAgICAgICAgICAgZmFsc2UsXHJcbiAgICAgICAgICAgICAgdGhpcy5tYWludGFpbkFzcGVjdFJhdGlvKCksXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgdGhpcy5maWxlID0gZmlsZTtcclxuICAgICAgICAgICAgICB0aGlzLmZpbGVTcmMuc2V0KHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkRmlsZSA9IHRoaXMuYmFzZTY0VG9GaWxlKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5maWxlU3JjKCkgYXMgc3RyaW5nLFxyXG4gICAgICAgICAgICAgICAgdGhpcy5maWxlPy5uYW1lID8/ICdmaWxlLnBuZycsXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICB0aGlzLmZpbGVFbWl0LmVtaXQocHJvY2Vzc2VkRmlsZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgaW5wdXRFbCA9IHRoaXMuZmlsZUlucHV0KCk7XHJcbiAgICAgICAgICAgICAgaWYgKGlucHV0RWwpIHtcclxuICAgICAgICAgICAgICAgIGlucHV0RWwubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJybyBhbyBjb3J0YXIgYSBpbWFnZW06JywgZXJyb3IpO1xyXG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UudG9hc3RFcnJvcignRXJybyBhbyBjb3J0YXIgYSBpbWFnZW0nKTsgXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmZpbGUgPSBmaWxlO1xyXG4gICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgIHRoaXMuZmlsZVNyYy5zZXQocmVhZGVyLnJlc3VsdCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgICAgICB0aGlzLmZpbGVFbWl0LmVtaXQoZmlsZSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS50b2FzdEVycm9yKFxyXG4gICAgICAgICdBcGVuYXMgYXJxdWl2b3MgZGUgaW1hZ2VtIHPDo28gcGVybWl0aWRvcy4nLFxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYmFzZTY0VG9GaWxlKGJhc2U2NFN0cmluZzogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nKSB7XHJcbiAgICAvLyBFeHRyYWlyIG8gdGlwbyBNSU1FIGRhIHN0cmluZyBiYXNlNjRcclxuICAgIGNvbnN0IGFyciA9IGJhc2U2NFN0cmluZy5zcGxpdCgnLCcpO1xyXG4gICAgY29uc3QgbWltZSA9IGFyclswXS5tYXRjaCgvOiguKj8pOy8pIVsxXTtcclxuXHJcbiAgICAvLyBDb252ZXJ0ZXIgQmFzZTY0IHBhcmEgQmluw6FyaW9cclxuICAgIGNvbnN0IGJpbmFyeVN0cmluZyA9IGF0b2IoYXJyWzFdKTtcclxuICAgIGNvbnN0IGxlbiA9IGJpbmFyeVN0cmluZy5sZW5ndGg7XHJcbiAgICBjb25zdCB1aW50OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgIHVpbnQ4QXJyYXlbaV0gPSBiaW5hcnlTdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDcmlhciB1bSBCbG9iIGUsIGVtIHNlZ3VpZGEsIHVtIG9iamV0byBGaWxlXHJcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3VpbnQ4QXJyYXldLCB7IHR5cGU6IG1pbWUgfSk7XHJcbiAgICBjb25zdCBmaWxlID0gbmV3IEZpbGUoW2Jsb2JdLCBmaWxlTmFtZSwgeyB0eXBlOiBtaW1lIH0pO1xyXG5cclxuICAgIHJldHVybiBmaWxlO1xyXG4gIH1cclxuXHJcbiAgYWRkRHJhZ092ZXJDbGFzcyhldmVudDogRHJhZ0V2ZW50KSB7XHJcbiAgICBjb25zdCBjb250YWluZXIgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb250YWluZXIuY2xhc3NMaXN0LmFkZCgnZHJhZ292ZXInKTtcclxuICB9XHJcblxyXG4gIHJlbW92ZURyYWdPdmVyQ2xhc3MoZXZlbnQ6IERyYWdFdmVudCkge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ2RyYWdvdmVyJyk7XHJcbiAgfVxyXG5cclxuICBkZWxldGVJbWFnZSgpIHtcclxuICAgIHRoaXMuZmlsZSA9IG51bGw7XHJcbiAgICB0aGlzLmZpbGVTcmMuc2V0KG51bGwpO1xyXG5cclxuICAgIGNvbnN0IGlucHV0RWwgPSB0aGlzLmZpbGVJbnB1dCgpO1xyXG4gICAgaWYgKGlucHV0RWwpIHtcclxuICAgICAgaW5wdXRFbC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XHJcbiAgICB9XHJcbiAgICB0aGlzLmRlbGV0ZUVtaXQuZW1pdCgpO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2XHJcbiAgY2xhc3M9XCJmaWxlLXVwbG9hZC1jb250YWluZXJcIlxyXG4gIFtjbGFzcy5oYXMtZmlsZV09XCJmaWxlU3JjKClcIlxyXG4gIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudClcIlxyXG4gIChkcmFnbGVhdmUpPVwib25EcmFnTGVhdmUoJGV2ZW50KVwiXHJcbiAgKGRyb3ApPVwib25Ecm9wKCRldmVudClcIlxyXG4gIChjbGljayk9XCJ0cmlnZ2VyQ2xpY2soKVwiXHJcbj5cclxuICA8aW5wdXRcclxuICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICNmaWxlSW5wdXRcclxuICAgIChjaGFuZ2UpPVwib25GaWxlU2VsZWN0ZWQoJGV2ZW50KVwiXHJcbiAgICBhY2NlcHQ9XCJpbWFnZS8qXCJcclxuICAgIGhpZGRlblxyXG4gIC8+XHJcblxyXG4gIEBpZiAoIWZpbGVTcmMoKSkge1xyXG4gICAgPGRpdiBjbGFzcz1cImRyb3B6b25lLWNvbnRlbnRcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNsb3VkLWljb24td3JhcHBlclwiPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPmNsb3VkX3VwbG9hZDwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj5cclxuICAgICAgICBAaWYgKGRlc2NyaXB0aW9uKCkpIHtcclxuICAgICAgICAgIDxwIGNsYXNzPVwibWFpbi10ZXh0IGRlc2NyaXB0aW9uLXRleHRcIj57eyBkZXNjcmlwdGlvbigpIH19PC9wPlxyXG4gICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgPHAgY2xhc3M9XCJtYWluLXRleHRcIj5cclxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJibHVlLXRleHRcIj5DbGlxdWUgcGFyYSBzZWxlY2lvbmFyPC9zcGFuPiBvdSBhcnJhc3RlIHVtYVxyXG4gICAgICAgICAgICBpbWFnZW0gYXF1aVxyXG4gICAgICAgICAgPC9wPlxyXG4gICAgICAgIH1cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcblxyXG4gIEBpZiAoZmlsZVNyYygpIHx8IGZpbGUpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJwcmV2aWV3LXdyYXBwZXJcIj5cclxuICAgICAgPGltZ1xyXG4gICAgICAgIFtzcmNdPVwiZmlsZVNyYygpXCJcclxuICAgICAgICBbYWx0XT1cImZpbGU/Lm5hbWVcIlxyXG4gICAgICAgIGNsYXNzPVwicHJldmlldy1pbWFnZVwiXHJcbiAgICAgICAgW3N0eWxlLm1heEhlaWdodF09XCJtYXhIZWlnaHRJbWFnZSgpXCJcclxuICAgICAgLz5cclxuXHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBwQnV0dG9uXHJcbiAgICAgICAgKGNsaWNrKT1cImRlbGV0ZUltYWdlKCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgY2xhc3M9XCJkZWxldGUtYnV0dG9uXCJcclxuICAgICAgICBbdGV4dF09XCJ0cnVlXCJcclxuICAgICAgICBbaWNvbl09XCIncGkgcGktdHJhc2gnXCJcclxuICAgICAgPjwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcbiAgfVxyXG48L2Rpdj4iXX0=