@asoftwareworld/form-builder-pro
Version:
ASW Form Builder Pro helps you with rapid development and designed web forms which includes several controls. The key feature of Form Builder is to make your content attractive and effective. We can customize our control at run time and preview the same b
175 lines • 28 kB
JavaScript
/**
* @license
* Copyright ASW (A Software World) All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file
*/
import { Injectable } from '@angular/core';
import { getTransformationsFromExifData, supportsAutomaticRotation } from '@asoftwareworld/form-builder-pro/utils';
import * as i0 from "@angular/core";
export class LoadImageService {
autoRotateSupported = supportsAutomaticRotation();
loadImageFile(file, cropperSettings) {
return file.arrayBuffer().then((arrayBuffer) => this.checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, file.type, cropperSettings));
}
checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, imageType, cropperSettings) {
if (!this.isValidImageType(imageType)) {
return Promise.reject(new Error('Invalid image type'));
}
return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings);
}
isValidImageType(type) {
return /image\/(png|jpg|jpeg|bmp|gif|tiff|webp|x-icon|vnd.microsoft.icon)/.test(type);
}
loadImageFromURL(url, cropperSettings) {
return fetch(url)
.then((res) => res.arrayBuffer())
.then((buffer) => this.loadImageFromArrayBuffer(buffer, cropperSettings));
}
loadBase64Image(imageBase64, cropperSettings) {
const arrayBuffer = this.base64ToArrayBuffer(imageBase64);
return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings);
}
base64ToArrayBuffer(imageBase64) {
imageBase64 = imageBase64.replace(/^data\:([^\;]+)\;base64,/gim, '');
const binaryString = atob(imageBase64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
loadImageFromArrayBuffer(arrayBuffer, cropperSettings) {
return new Promise((resolve, reject) => {
const blob = new Blob([arrayBuffer]);
const objectUrl = URL.createObjectURL(blob);
const originalImage = new Image();
originalImage.onload = () => resolve({
originalImage,
originalObjectUrl: objectUrl,
originalArrayBuffer: arrayBuffer
});
originalImage.onerror = reject;
originalImage.src = objectUrl;
}).then((res) => this.transformImageFromArrayBuffer(res, cropperSettings));
}
async transformImageFromArrayBuffer(res, cropperSettings) {
const autoRotate = await this.autoRotateSupported;
const exifTransform = await getTransformationsFromExifData(autoRotate ? -1 : res.originalArrayBuffer);
if (!res.originalImage || !res.originalImage.complete) {
return Promise.reject(new Error('No image loaded'));
}
const loadedImage = {
original: {
objectUrl: res.originalObjectUrl,
image: res.originalImage,
size: {
width: res.originalImage.naturalWidth,
height: res.originalImage.naturalHeight
}
},
exifTransform
};
return this.transformLoadedImage(loadedImage, cropperSettings);
}
async transformLoadedImage(loadedImage, cropperSettings) {
const canvasRotation = cropperSettings.canvasRotation + loadedImage.exifTransform.rotate;
const originalSize = {
width: loadedImage.original.image.naturalWidth,
height: loadedImage.original.image.naturalHeight
};
if (canvasRotation === 0 && !loadedImage.exifTransform.flip && !cropperSettings.containWithinAspectRatio) {
return {
original: {
objectUrl: loadedImage.original.objectUrl,
image: loadedImage.original.image,
size: { ...originalSize }
},
transformed: {
objectUrl: loadedImage.original.objectUrl,
image: loadedImage.original.image,
size: { ...originalSize }
},
exifTransform: loadedImage.exifTransform
};
}
const transformedSize = this.getTransformedSize(originalSize, loadedImage.exifTransform, cropperSettings);
const canvas = document.createElement('canvas');
canvas.width = transformedSize.width;
canvas.height = transformedSize.height;
const ctx = canvas.getContext('2d');
ctx?.setTransform(loadedImage.exifTransform.flip ? -1 : 1, 0, 0, 1, canvas.width / 2, canvas.height / 2);
ctx?.rotate(Math.PI * (canvasRotation / 2));
ctx?.drawImage(loadedImage.original.image, -originalSize.width / 2, -originalSize.height / 2);
const blob = await new Promise((resolve) => canvas.toBlob(resolve, cropperSettings.format));
if (!blob) {
throw new Error('Failed to get Blob for transformed image.');
}
const objectUrl = URL.createObjectURL(blob);
const transformedImage = await this.loadImageFromObjectUrl(objectUrl);
return {
original: {
objectUrl: loadedImage.original.objectUrl,
image: loadedImage.original.image,
size: { ...originalSize }
},
transformed: {
objectUrl: objectUrl,
image: transformedImage,
size: {
width: transformedImage.width,
height: transformedImage.height
}
},
exifTransform: loadedImage.exifTransform
};
}
loadImageFromObjectUrl(objectUrl) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = reject;
image.src = objectUrl;
});
}
getTransformedSize(originalSize, exifTransform, cropperSettings) {
const canvasRotation = cropperSettings.canvasRotation + exifTransform.rotate;
if (cropperSettings.containWithinAspectRatio) {
if (canvasRotation % 2) {
const minWidthToContain = originalSize.width * cropperSettings.aspectRatio;
const minHeightToContain = originalSize.height / cropperSettings.aspectRatio;
return {
width: Math.max(originalSize.height, minWidthToContain),
height: Math.max(originalSize.width, minHeightToContain)
};
}
else {
const minWidthToContain = originalSize.height * cropperSettings.aspectRatio;
const minHeightToContain = originalSize.width / cropperSettings.aspectRatio;
return {
width: Math.max(originalSize.width, minWidthToContain),
height: Math.max(originalSize.height, minHeightToContain)
};
}
}
if (canvasRotation % 2) {
return {
height: originalSize.width,
width: originalSize.height
};
}
return {
width: originalSize.width,
height: originalSize.height
};
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: LoadImageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: LoadImageService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: LoadImageService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC1pbWFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvaW1hZ2UtY3JvcC9zZXJ2aWNlcy9sb2FkLWltYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsOEJBQThCLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7QUFTbkgsTUFBTSxPQUFPLGdCQUFnQjtJQUNqQixtQkFBbUIsR0FBcUIseUJBQXlCLEVBQUUsQ0FBQztJQUU1RSxhQUFhLENBQUMsSUFBVSxFQUFFLGVBQWdDO1FBQ3RELE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDN0ksQ0FBQztJQUVPLHlDQUF5QyxDQUFDLFdBQTRCLEVBQUUsU0FBaUIsRUFBRSxlQUFnQztRQUMvSCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDcEMsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxJQUFZO1FBQ2pDLE9BQU8sbUVBQW1FLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxHQUFXLEVBQUUsZUFBZ0M7UUFDMUQsT0FBTyxL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QWhCLGdCQUFnQixjQURILE1BQU07OzJGQUNuQixnQkFBZ0I7a0JBRDVCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFTVyAoQSBTb2Z0d2FyZSBXb3JsZCkgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENyb3BwZXJTZXR0aW5ncywgRGltZW5zaW9ucywgRXhpZlRyYW5zZm9ybSwgTG9hZGVkSW1hZ2UgfSBmcm9tICdAYXNvZnR3YXJld29ybGQvZm9ybS1idWlsZGVyLXByby9hcGknO1xuaW1wb3J0IHsgZ2V0VHJhbnNmb3JtYXRpb25zRnJvbUV4aWZEYXRhLCBzdXBwb3J0c0F1dG9tYXRpY1JvdGF0aW9uIH0gZnJvbSAnQGFzb2Z0d2FyZXdvcmxkL2Zvcm0tYnVpbGRlci1wcm8vdXRpbHMnO1xuXG5pbnRlcmZhY2UgTG9hZEltYWdlQXJyYXlCdWZmZXIge1xuICAgIG9yaWdpbmFsSW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQ7XG4gICAgb3JpZ2luYWxBcnJheUJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlO1xuICAgIG9yaWdpbmFsT2JqZWN0VXJsOiBzdHJpbmc7XG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgTG9hZEltYWdlU2VydmljZSB7XG4gICAgcHJpdmF0ZSBhdXRvUm90YXRlU3VwcG9ydGVkOiBQcm9taXNlPGJvb2xlYW4+ID0gc3VwcG9ydHNBdXRvbWF0aWNSb3RhdGlvbigpO1xuXG4gICAgbG9hZEltYWdlRmlsZShmaWxlOiBGaWxlLCBjcm9wcGVyU2V0dGluZ3M6IENyb3BwZXJTZXR0aW5ncyk6IFByb21pc2U8TG9hZGVkSW1hZ2U+IHtcbiAgICAgICAgcmV0dXJuIGZpbGUuYXJyYXlCdWZmZXIoKS50aGVuKChhcnJheUJ1ZmZlcikgPT4gdGhpcy5jaGVja0ltYWdlVHlwZUFuZExvYWRJbWFnZUZyb21BcnJheUJ1ZmZlcihhcnJheUJ1ZmZlciwgZmlsZS50eXBlLCBjcm9wcGVyU2V0dGluZ3MpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrSW1hZ2VUeXBlQW5kTG9hZEltYWdlRnJvbUFycmF5QnVmZmVyKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIGltYWdlVHlwZTogc3RyaW5nLCBjcm9wcGVyU2V0dGluZ3M6IENyb3BwZXJTZXR0aW5ncyk6IFByb21pc2U8TG9hZGVkSW1hZ2U+IHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWRJbWFnZVR5cGUoaW1hZ2VUeXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignSW52YWxpZCBpbWFnZSB0eXBlJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmxvYWRJbWFnZUZyb21BcnJheUJ1ZmZlcihhcnJheUJ1ZmZlciwgY3JvcHBlclNldHRpbmdzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzVmFsaWRJbWFnZVR5cGUodHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAvaW1hZ2VcXC8ocG5nfGpwZ3xqcGVnfGJtcHxnaWZ8dGlmZnx3ZWJwfHgtaWNvbnx2bmQubWljcm9zb2Z0Lmljb24pLy50ZXN0KHR5cGUpO1xuICAgIH1cblxuICAgIGxvYWRJbWFnZUZyb21VUkwodXJsOiBzdHJpbmcsIGNyb3BwZXJTZXR0aW5nczogQ3JvcHBlclNldHRpbmdzKTogUHJvbWlzZTxMb2FkZWRJbWFnZT4ge1xuICAgICAgICByZXR1cm4gZmV0Y2godXJsKVxuICAgICAgICAgICAgLnRoZW4oKHJlcykgPT4gcmVzLmFycmF5QnVmZmVyKCkpXG4gICAgICAgICAgICAudGhlbigoYnVmZmVyKSA9PiB0aGlzLmxvYWRJbWFnZUZyb21BcnJheUJ1ZmZlcihidWZmZXIsIGNyb3BwZXJTZXR0aW5ncykpO1xuICAgIH1cblxuICAgIGxvYWRCYXNlNjRJbWFnZShpbWFnZUJhc2U2NDogc3RyaW5nLCBjcm9wcGVyU2V0dGluZ3M6IENyb3BwZXJTZXR0aW5ncyk6IFByb21pc2U8TG9hZGVkSW1hZ2U+IHtcbiAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB0aGlzLmJhc2U2NFRvQXJyYXlCdWZmZXIoaW1hZ2VCYXNlNjQpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2FkSW1hZ2VGcm9tQXJyYXlCdWZmZXIoYXJyYXlCdWZmZXIsIGNyb3BwZXJTZXR0aW5ncyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBiYXNlNjRUb0FycmF5QnVmZmVyKGltYWdlQmFzZTY0OiBzdHJpbmcpOiBBcnJheUJ1ZmZlckxpa2Uge1xuICAgICAgICBpbWFnZUJhc2U2NCA9IGltYWdlQmFzZTY0LnJlcGxhY2UoL15kYXRhXFw6KFteXFw7XSspXFw7YmFzZTY0LC9naW0sICcnKTtcbiAgICAgICAgY29uc3QgYmluYXJ5U3RyaW5nID0gYXRvYihpbWFnZUJhc2U2NCk7XG4gICAgICAgIGNvbnN0IGxlbiA9IGJpbmFyeVN0cmluZy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgYnl0ZXNbaV0gPSBiaW5hcnlTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYnl0ZXMuYnVmZmVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZEltYWdlRnJvbUFycmF5QnVmZmVyKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIGNyb3BwZXJTZXR0aW5nczogQ3JvcHBlclNldHRpbmdzKTogUHJvbWlzZTxMb2FkZWRJbWFnZT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8TG9hZEltYWdlQXJyYXlCdWZmZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYXJyYXlCdWZmZXJdKTtcbiAgICAgICAgICAgIGNvbnN0IG9iamVjdFVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbEltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICAgICAgICBvcmlnaW5hbEltYWdlLm9ubG9hZCA9ICgpID0+XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsSW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsT2JqZWN0VXJsOiBvYmplY3RVcmwsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsQXJyYXlCdWZmZXI6IGFycmF5QnVmZmVyXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBvcmlnaW5hbEltYWdlLm9uZXJyb3IgPSByZWplY3Q7XG4gICAgICAgICAgICBvcmlnaW5hbEltYWdlLnNyYyA9IG9iamVjdFVybDtcbiAgICAgICAgfSkudGhlbigocmVzOiBMb2FkSW1hZ2VBcnJheUJ1ZmZlcikgPT4gdGhpcy50cmFuc2Zvcm1JbWFnZUZyb21BcnJheUJ1ZmZlcihyZXMsIGNyb3BwZXJTZXR0aW5ncykpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgdHJhbnNmb3JtSW1hZ2VGcm9tQXJyYXlCdWZmZXIocmVzOiBMb2FkSW1hZ2VBcnJheUJ1ZmZlciwgY3JvcHBlclNldHRpbmdzOiBDcm9wcGVyU2V0dGluZ3MpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgICAgIGNvbnN0IGF1dG9Sb3RhdGUgPSBhd2FpdCB0aGlzLmF1dG9Sb3RhdGVTdXBwb3J0ZWQ7XG4gICAgICAgIGNvbnN0IGV4aWZUcmFuc2Zvcm0gPSBhd2FpdCBnZXRUcmFuc2Zvcm1hdGlvbnNGcm9tRXhpZkRhdGEoYXV0b1JvdGF0ZSA/IC0xIDogcmVzLm9yaWdpbmFsQXJyYXlCdWZmZXIpO1xuICAgICAgICBpZiAoIXJlcy5vcmlnaW5hbEltYWdlIHx8ICFyZXMub3JpZ2luYWxJbWFnZS5jb21wbGV0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignTm8gaW1hZ2UgbG9hZGVkJykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxvYWRlZEltYWdlID0ge1xuICAgICAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICAgICAgICBvYmplY3RVcmw6IHJlcy5vcmlnaW5hbE9iamVjdFVybCxcbiAgICAgICAgICAgICAgICBpbWFnZTogcmVzLm9yaWdpbmFsSW1hZ2UsXG4gICAgICAgICAgICAgICAgc2l6ZToge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogcmVzLm9yaWdpbmFsSW1hZ2UubmF0dXJhbFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHJlcy5vcmlnaW5hbEltYWdlLm5hdHVyYWxIZWlnaHRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXhpZlRyYW5zZm9ybVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1Mb2FkZWRJbWFnZShsb2FkZWRJbWFnZSwgY3JvcHBlclNldHRpbmdzKTtcbiAgICB9XG5cbiAgICBhc3luYyB0cmFuc2Zvcm1Mb2FkZWRJbWFnZShsb2FkZWRJbWFnZTogUGFydGlhbDxMb2FkZWRJbWFnZT4sIGNyb3BwZXJTZXR0aW5nczogQ3JvcHBlclNldHRpbmdzKTogUHJvbWlzZTxMb2FkZWRJbWFnZT4ge1xuICAgICAgICBjb25zdCBjYW52YXNSb3RhdGlvbiA9IGNyb3BwZXJTZXR0aW5ncy5jYW52YXNSb3RhdGlvbiArIGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLnJvdGF0ZTtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxTaXplID0ge1xuICAgICAgICAgICAgd2lkdGg6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5pbWFnZS5uYXR1cmFsV2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5pbWFnZS5uYXR1cmFsSGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGlmIChjYW52YXNSb3RhdGlvbiA9PT0gMCAmJiAhbG9hZGVkSW1hZ2UuZXhpZlRyYW5zZm9ybSEuZmxpcCAmJiAhY3JvcHBlclNldHRpbmdzLmNvbnRhaW5XaXRoaW5Bc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbDoge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3RVcmw6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5vYmplY3RVcmwsXG4gICAgICAgICAgICAgICAgICAgIGltYWdlOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuaW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgIHNpemU6IHsgLi4ub3JpZ2luYWxTaXplIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkOiB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdFVybDogbG9hZGVkSW1hZ2Uub3JpZ2luYWwhLm9iamVjdFVybCxcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2U6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5pbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgc2l6ZTogeyAuLi5vcmlnaW5hbFNpemUgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXhpZlRyYW5zZm9ybTogbG9hZGVkSW1hZ2UuZXhpZlRyYW5zZm9ybSFcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZFNpemUgPSB0aGlzLmdldFRyYW5zZm9ybWVkU2l6ZShvcmlnaW5hbFNpemUsIGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLCBjcm9wcGVyU2V0dGluZ3MpO1xuICAgICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgY2FudmFzLndpZHRoID0gdHJhbnNmb3JtZWRTaXplLndpZHRoO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gdHJhbnNmb3JtZWRTaXplLmhlaWdodDtcbiAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGN0eD8uc2V0VHJhbnNmb3JtKGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLmZsaXAgPyAtMSA6IDEsIDAsIDAsIDEsIGNhbnZhcy53aWR0aCAvIDIsIGNhbnZhcy5oZWlnaHQgLyAyKTtcbiAgICAgICAgY3R4Py5yb3RhdGUoTWF0aC5QSSAqIChjYW52YXNSb3RhdGlvbiAvIDIpKTtcbiAgICAgICAgY3R4Py5kcmF3SW1hZ2UobG9hZGVkSW1hZ2Uub3JpZ2luYWwhLmltYWdlLCAtb3JpZ2luYWxTaXplLndpZHRoIC8gMiwgLW9yaWdpbmFsU2l6ZS5oZWlnaHQgLyAyKTtcbiAgICAgICAgY29uc3QgYmxvYiA9IGF3YWl0IG5ldyBQcm9taXNlPEJsb2IgfCBudWxsPigocmVzb2x2ZSkgPT4gY2FudmFzLnRvQmxvYihyZXNvbHZlLCBjcm9wcGVyU2V0dGluZ3MuZm9ybWF0KSk7XG4gICAgICAgIGlmICghYmxvYikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZ2V0IEJsb2IgZm9yIHRyYW5zZm9ybWVkIGltYWdlLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9iamVjdFVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkSW1hZ2UgPSBhd2FpdCB0aGlzLmxvYWRJbWFnZUZyb21PYmplY3RVcmwob2JqZWN0VXJsKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgICAgICAgICAgb2JqZWN0VXJsOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEub2JqZWN0VXJsLFxuICAgICAgICAgICAgICAgIGltYWdlOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuaW1hZ2UsXG4gICAgICAgICAgICAgICAgc2l6ZTogeyAuLi5vcmlnaW5hbFNpemUgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyYW5zZm9ybWVkOiB7XG4gICAgICAgICAgICAgICAgb2JqZWN0VXJsOiBvYmplY3RVcmwsXG4gICAgICAgICAgICAgICAgaW1hZ2U6IHRyYW5zZm9ybWVkSW1hZ2UsXG4gICAgICAgICAgICAgICAgc2l6ZToge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdHJhbnNmb3JtZWRJbWFnZS53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0cmFuc2Zvcm1lZEltYWdlLmhlaWdodFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBleGlmVHJhbnNmb3JtOiBsb2FkZWRJbWFnZS5leGlmVHJhbnNmb3JtIVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZEltYWdlRnJvbU9iamVjdFVybChvYmplY3RVcmw6IHN0cmluZyk6IFByb21pc2U8SFRNTEltYWdlRWxlbWVudD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8SFRNTEltYWdlRWxlbWVudD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgICAgIGltYWdlLm9ubG9hZCA9ICgpID0+IHJlc29sdmUoaW1hZ2UpO1xuICAgICAgICAgICAgaW1hZ2Uub25lcnJvciA9IHJlamVjdDtcbiAgICAgICAgICAgIGltYWdlLnNyYyA9IG9iamVjdFVybDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRUcmFuc2Zvcm1lZFNpemUob3JpZ2luYWxTaXplOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0sIGV4aWZUcmFuc2Zvcm06IEV4aWZUcmFuc2Zvcm0sIGNyb3BwZXJTZXR0aW5nczogQ3JvcHBlclNldHRpbmdzKTogRGltZW5zaW9ucyB7XG4gICAgICAgIGNvbnN0IGNhbnZhc1JvdGF0aW9uID0gY3JvcHBlclNldHRpbmdzLmNhbnZhc1JvdGF0aW9uICsgZXhpZlRyYW5zZm9ybS5yb3RhdGU7XG4gICAgICAgIGlmIChjcm9wcGVyU2V0dGluZ3MuY29udGFpbldpdGhpbkFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICBpZiAoY2FudmFzUm90YXRpb24gJSAyKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWluV2lkdGhUb0NvbnRhaW4gPSBvcmlnaW5hbFNpemUud2lkdGggKiBjcm9wcGVyU2V0dGluZ3MuYXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgICAgY29uc3QgbWluSGVpZ2h0VG9Db250YWluID0gb3JpZ2luYWxTaXplLmhlaWdodCAvIGNyb3BwZXJTZXR0aW5ncy5hc3BlY3RSYXRpbztcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogTWF0aC5tYXgob3JpZ2luYWxTaXplLmhlaWdodCwgbWluV2lkdGhUb0NvbnRhaW4pLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IE1hdGgubWF4KG9yaWdpbmFsU2l6ZS53aWR0aCwgbWluSGVpZ2h0VG9Db250YWluKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbldpZHRoVG9Db250YWluID0gb3JpZ2luYWxTaXplLmhlaWdodCAqIGNyb3BwZXJTZXR0aW5ncy5hc3BlY3RSYXRpbztcbiAgICAgICAgICAgICAgICBjb25zdCBtaW5IZWlnaHRUb0NvbnRhaW4gPSBvcmlnaW5hbFNpemUud2lkdGggLyBjcm9wcGVyU2V0dGluZ3MuYXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IE1hdGgubWF4KG9yaWdpbmFsU2l6ZS53aWR0aCwgbWluV2lkdGhUb0NvbnRhaW4pLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IE1hdGgubWF4KG9yaWdpbmFsU2l6ZS5oZWlnaHQsIG1pbkhlaWdodFRvQ29udGFpbilcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNhbnZhc1JvdGF0aW9uICUgMikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IG9yaWdpbmFsU2l6ZS53aWR0aCxcbiAgICAgICAgICAgICAgICB3aWR0aDogb3JpZ2luYWxTaXplLmhlaWdodFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2lkdGg6IG9yaWdpbmFsU2l6ZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogb3JpZ2luYWxTaXplLmhlaWdodFxuICAgICAgICB9O1xuICAgIH1cbn1cbiJdfQ==