UNPKG

@rangertechnologies/ngnxt

Version:

This library was used for creating dymanic UI based on the input JSON/data

194 lines 31.3 kB
import { getTransformationsFromExifData, supportsAutomaticRotation } from '../utils/exif.utils'; export class LoadImageService { autoRotateSupported = supportsAutomaticRotation(); async loadImageFile(file, cropperSettings) { const arrayBuffer = await file.arrayBuffer(); if (cropperSettings.options.checkImageType) { return await this.checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, file.type, cropperSettings); } return await this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings); } checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, imageType, cropperSettings) { if (!this.isValidImageType(imageType)) { return Promise.reject(new Error('Invalid image type')); } return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings, imageType); } isValidImageType(type) { return /image\/(png|jpg|jpeg|heic|bmp|gif|tiff|svg|webp|x-icon|vnd.microsoft.icon)/.test(type); } async loadImageFromURL(url, cropperSettings) { const res = await fetch(url); const blob = await res.blob(); const buffer = await blob.arrayBuffer(); return await this.loadImageFromArrayBuffer(buffer, cropperSettings, blob.type); } loadBase64Image(imageBase64, cropperSettings) { const arrayBuffer = this.base64ToArrayBuffer(imageBase64); return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings); } base64ToArrayBuffer(imageBase64) { imageBase64 = imageBase64.replace(/^data:([^;]+);base64,/gmi, ''); 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; } async loadImageFromArrayBuffer(arrayBuffer, cropperState, imageType) { const res = await new Promise(async (resolve, reject) => { try { const blob = new Blob([arrayBuffer], imageType ? { type: imageType } : undefined); const objectUrl = URL.createObjectURL(blob); const originalImage = new Image(); const isSvg = imageType === 'image/svg+xml'; const originalImageSize = isSvg ? await this.getSvgImageSize(blob) : undefined; originalImage.onload = () => resolve({ originalImage, originalImageSize, originalObjectUrl: objectUrl, originalArrayBuffer: arrayBuffer }); originalImage.onerror = reject; originalImage.src = objectUrl; } catch (e) { reject(e); } }); return await this.transformImageFromArrayBuffer(res, cropperState, res.originalImageSize != null); } async getSvgImageSize(blob) { const parser = new DOMParser(); const doc = parser.parseFromString(await blob.text(), 'image/svg+xml'); const svgElement = doc.querySelector('svg'); if (!svgElement) { throw Error('Failed to parse SVG image'); } const widthAttr = svgElement.getAttribute('width'); const heightAttr = svgElement.getAttribute('height'); if (widthAttr && heightAttr) { return null; } const viewBoxAttr = svgElement.getAttribute('viewBox') || svgElement.getAttribute('viewbox'); if (viewBoxAttr) { const viewBox = viewBoxAttr.split(' '); return { width: +viewBox[2], height: +viewBox[3] }; } throw Error('Failed to load SVG image. SVG must have width + height or viewBox definition.'); } async transformImageFromArrayBuffer(res, cropperSettings, forceTransform = false) { const autoRotate = await this.autoRotateSupported; const exifTransform = 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: res.originalImageSize ?? { width: res.originalImage.naturalWidth, height: res.originalImage.naturalHeight } }, exifTransform }; return this.transformLoadedImage(loadedImage, cropperSettings, forceTransform); } async transformLoadedImage(loadedImage, cropperState, forceTransform = false) { const canvasRotation = cropperState.options.canvasRotation + loadedImage.exifTransform.rotate; const originalSize = loadedImage.original.size; if (!forceTransform && canvasRotation === 0 && !loadedImage.exifTransform.flip && !cropperState.options.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, cropperState); 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, cropperState.options.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, cropperState) { const canvasRotation = cropperState.options.canvasRotation + exifTransform.rotate; if (cropperState.options.containWithinAspectRatio) { if (canvasRotation % 2) { const minWidthToContain = originalSize.width * cropperState.options.aspectRatio; const minHeightToContain = originalSize.height / cropperState.options.aspectRatio; return { width: Math.max(originalSize.height, minWidthToContain), height: Math.max(originalSize.width, minHeightToContain) }; } else { const minWidthToContain = originalSize.height * cropperState.options.aspectRatio; const minHeightToContain = originalSize.width / cropperState.options.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 }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC1pbWFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvaW1hZ2UtY3JvcHBlci9zZXJ2aWNlcy9sb2FkLWltYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLDhCQUE4QixFQUFFLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFTaEcsTUFBTSxPQUFPLGdCQUFnQjtJQUVuQixtQkFBbUIsR0FBcUIseUJBQXlCLEVBQUUsQ0FBQztJQUU1RSxLQUFLLENBQUMsYUFBYSxDQUFDLElBQVUsRUFBRSxlQUE2QjtRQUMzRCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDM0MsT0FBTyxNQUFNLElBQUksQ0FBQyx5Q0FBeUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN2RyxDQUFDO1FBQ0QsT0FBTyxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVPLHlDQUF5QyxDQUFDLFdBQTRCLEVBQUUsU0FBaUIsRUFBRSxlQUE2QjtRQUM5SCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNoRixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsSUFB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QUcsWUFBWSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztnQkFDakYsTUFBTSxrQkFBa0IsR0FBRyxZQUFZLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO2dCQUNqRixPQUFPO29CQUNMLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUM7b0JBQ3RELE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUM7aUJBQzFELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE9BQU87Z0JBQ0wsTUFBTSxFQUFFLFlBQVksQ0FBQyxLQUFLO2dCQUMxQixLQUFLLEVBQUUsWUFBWSxDQUFDLE1BQU07YUFDM0IsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPO1lBQ0wsS0FBSyxFQUFFLFlBQVksQ0FBQyxLQUFLO1lBQ3pCLE1BQU0sRUFBRSxZQUFZLENBQUMsTUFBTTtTQUM1QixDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGltZW5zaW9ucywgTG9hZGVkSW1hZ2UgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IENyb3BwZXJTdGF0ZSB9IGZyb20gJy4uL2NvbXBvbmVudC9jcm9wcGVyLnN0YXRlJztcbmltcG9ydCB7IEV4aWZUcmFuc2Zvcm0gfSBmcm9tICcuLi9pbnRlcmZhY2VzL2V4aWYtdHJhbnNmb3JtLmludGVyZmFjZSc7XG5pbXBvcnQgeyBnZXRUcmFuc2Zvcm1hdGlvbnNGcm9tRXhpZkRhdGEsIHN1cHBvcnRzQXV0b21hdGljUm90YXRpb24gfSBmcm9tICcuLi91dGlscy9leGlmLnV0aWxzJztcblxuaW50ZXJmYWNlIExvYWRJbWFnZUFycmF5QnVmZmVyIHtcbiAgb3JpZ2luYWxJbWFnZTogSFRNTEltYWdlRWxlbWVudDtcbiAgb3JpZ2luYWxBcnJheUJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlO1xuICBvcmlnaW5hbE9iamVjdFVybDogc3RyaW5nO1xuICBvcmlnaW5hbEltYWdlU2l6ZT86IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXI7IH0gfCBudWxsO1xufVxuXG5leHBvcnQgY2xhc3MgTG9hZEltYWdlU2VydmljZSB7XG5cbiAgcHJpdmF0ZSBhdXRvUm90YXRlU3VwcG9ydGVkOiBQcm9taXNlPGJvb2xlYW4+ID0gc3VwcG9ydHNBdXRvbWF0aWNSb3RhdGlvbigpO1xuXG4gIGFzeW5jIGxvYWRJbWFnZUZpbGUoZmlsZTogRmlsZSwgY3JvcHBlclNldHRpbmdzOiBDcm9wcGVyU3RhdGUpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCBmaWxlLmFycmF5QnVmZmVyKCk7XG4gICAgaWYgKGNyb3BwZXJTZXR0aW5ncy5vcHRpb25zLmNoZWNrSW1hZ2VUeXBlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5jaGVja0ltYWdlVHlwZUFuZExvYWRJbWFnZUZyb21BcnJheUJ1ZmZlcihhcnJheUJ1ZmZlciwgZmlsZS50eXBlLCBjcm9wcGVyU2V0dGluZ3MpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5sb2FkSW1hZ2VGcm9tQXJyYXlCdWZmZXIoYXJyYXlCdWZmZXIsIGNyb3BwZXJTZXR0aW5ncyk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSW1hZ2VUeXBlQW5kTG9hZEltYWdlRnJvbUFycmF5QnVmZmVyKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIGltYWdlVHlwZTogc3RyaW5nLCBjcm9wcGVyU2V0dGluZ3M6IENyb3BwZXJTdGF0ZSk6IFByb21pc2U8TG9hZGVkSW1hZ2U+IHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZEltYWdlVHlwZShpbWFnZVR5cGUpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdJbnZhbGlkIGltYWdlIHR5cGUnKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmxvYWRJbWFnZUZyb21BcnJheUJ1ZmZlcihhcnJheUJ1ZmZlciwgY3JvcHBlclNldHRpbmdzLCBpbWFnZVR5cGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkSW1hZ2VUeXBlKHR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvaW1hZ2VcXC8ocG5nfGpwZ3xqcGVnfGhlaWN8Ym1wfGdpZnx0aWZmfHN2Z3x3ZWJwfHgtaWNvbnx2bmQubWljcm9zb2Z0Lmljb24pLy50ZXN0KHR5cGUpO1xuICB9XG5cbiAgYXN5bmMgbG9hZEltYWdlRnJvbVVSTCh1cmw6IHN0cmluZywgY3JvcHBlclNldHRpbmdzOiBDcm9wcGVyU3RhdGUpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBjb25zdCBibG9iID0gYXdhaXQgcmVzLmJsb2IoKTtcbiAgICBjb25zdCBidWZmZXIgPSBhd2FpdCBibG9iLmFycmF5QnVmZmVyKCk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMubG9hZEltYWdlRnJvbUFycmF5QnVmZmVyKGJ1ZmZlciwgY3JvcHBlclNldHRpbmdzLCBibG9iLnR5cGUpO1xuICB9XG5cbiAgbG9hZEJhc2U2NEltYWdlKGltYWdlQmFzZTY0OiBzdHJpbmcsIGNyb3BwZXJTZXR0aW5nczogQ3JvcHBlclN0YXRlKTogUHJvbWlzZTxMb2FkZWRJbWFnZT4ge1xuICAgIGNvbnN0IGFycmF5QnVmZmVyID0gdGhpcy5iYXNlNjRUb0FycmF5QnVmZmVyKGltYWdlQmFzZTY0KTtcbiAgICByZXR1cm4gdGhpcy5sb2FkSW1hZ2VGcm9tQXJyYXlCdWZmZXIoYXJyYXlCdWZmZXIsIGNyb3BwZXJTZXR0aW5ncyk7XG4gIH1cblxuICBwcml2YXRlIGJhc2U2NFRvQXJyYXlCdWZmZXIoaW1hZ2VCYXNlNjQ6IHN0cmluZyk6IEFycmF5QnVmZmVyTGlrZSB7XG4gICAgaW1hZ2VCYXNlNjQgPSBpbWFnZUJhc2U2NC5yZXBsYWNlKC9eZGF0YTooW147XSspO2Jhc2U2NCwvZ21pLCAnJyk7XG4gICAgY29uc3QgYmluYXJ5U3RyaW5nID0gYXRvYihpbWFnZUJhc2U2NCk7XG4gICAgY29uc3QgbGVuID0gYmluYXJ5U3RyaW5nLmxlbmd0aDtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGxlbik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgYnl0ZXNbaV0gPSBiaW5hcnlTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ5dGVzLmJ1ZmZlcjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZEltYWdlRnJvbUFycmF5QnVmZmVyKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIGNyb3BwZXJTdGF0ZTogQ3JvcHBlclN0YXRlLCBpbWFnZVR5cGU/OiBzdHJpbmcpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgbmV3IFByb21pc2U8TG9hZEltYWdlQXJyYXlCdWZmZXI+KGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYXJyYXlCdWZmZXJdLCBpbWFnZVR5cGUgPyB7dHlwZTogaW1hZ2VUeXBlfSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IG9iamVjdFVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgY29uc3QgaXNTdmcgPSBpbWFnZVR5cGUgPT09ICdpbWFnZS9zdmcreG1sJztcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxJbWFnZVNpemUgPSBpc1N2ZyA/IGF3YWl0IHRoaXMuZ2V0U3ZnSW1hZ2VTaXplKGJsb2IpIDogdW5kZWZpbmVkO1xuICAgICAgICBvcmlnaW5hbEltYWdlLm9ubG9hZCA9ICgpID0+IHJlc29sdmUoe1xuICAgICAgICAgIG9yaWdpbmFsSW1hZ2UsXG4gICAgICAgICAgb3JpZ2luYWxJbWFnZVNpemUsXG4gICAgICAgICAgb3JpZ2luYWxPYmplY3RVcmw6IG9iamVjdFVybCxcbiAgICAgICAgICBvcmlnaW5hbEFycmF5QnVmZmVyOiBhcnJheUJ1ZmZlclxuICAgICAgICB9KTtcbiAgICAgICAgb3JpZ2luYWxJbWFnZS5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgICBvcmlnaW5hbEltYWdlLnNyYyA9IG9iamVjdFVybDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnRyYW5zZm9ybUltYWdlRnJvbUFycmF5QnVmZmVyKHJlcywgY3JvcHBlclN0YXRlLCByZXMub3JpZ2luYWxJbWFnZVNpemUgIT0gbnVsbCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFN2Z0ltYWdlU2l6ZShibG9iOiBCbG9iKTogUHJvbWlzZTx7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyOyB9IHwgbnVsbD4ge1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICBjb25zdCBkb2MgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKGF3YWl0IGJsb2IudGV4dCgpLCAnaW1hZ2Uvc3ZnK3htbCcpO1xuICAgIGNvbnN0IHN2Z0VsZW1lbnQgPSBkb2MucXVlcnlTZWxlY3Rvcignc3ZnJyk7XG4gICAgaWYgKCFzdmdFbGVtZW50KSB7XG4gICAgICB0aHJvdyBFcnJvcignRmFpbGVkIHRvIHBhcnNlIFNWRyBpbWFnZScpO1xuICAgIH1cbiAgICBjb25zdCB3aWR0aEF0dHIgPSBzdmdFbGVtZW50LmdldEF0dHJpYnV0ZSgnd2lkdGgnKTtcbiAgICBjb25zdCBoZWlnaHRBdHRyID0gc3ZnRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hlaWdodCcpO1xuICAgIGlmICh3aWR0aEF0dHIgJiYgaGVpZ2h0QXR0cikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHZpZXdCb3hBdHRyID0gc3ZnRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnKVxuICAgICAgfHwgc3ZnRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3ZpZXdib3gnKTtcbiAgICBpZiAodmlld0JveEF0dHIpIHtcbiAgICAgIGNvbnN0IHZpZXdCb3ggPSB2aWV3Qm94QXR0ci5zcGxpdCgnICcpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGg6ICt2aWV3Qm94WzJdLFxuICAgICAgICBoZWlnaHQ6ICt2aWV3Qm94WzNdXG4gICAgICB9O1xuICAgIH1cbiAgICB0aHJvdyBFcnJvcignRmFpbGVkIHRvIGxvYWQgU1ZHIGltYWdlLiBTVkcgbXVzdCBoYXZlIHdpZHRoICsgaGVpZ2h0IG9yIHZpZXdCb3ggZGVmaW5pdGlvbi4nKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdHJhbnNmb3JtSW1hZ2VGcm9tQXJyYXlCdWZmZXIocmVzOiBMb2FkSW1hZ2VBcnJheUJ1ZmZlciwgY3JvcHBlclNldHRpbmdzOiBDcm9wcGVyU3RhdGUsIGZvcmNlVHJhbnNmb3JtID0gZmFsc2UpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgY29uc3QgYXV0b1JvdGF0ZSA9IGF3YWl0IHRoaXMuYXV0b1JvdGF0ZVN1cHBvcnRlZDtcbiAgICBjb25zdCBleGlmVHJhbnNmb3JtID0gZ2V0VHJhbnNmb3JtYXRpb25zRnJvbUV4aWZEYXRhKGF1dG9Sb3RhdGUgPyAtMSA6IHJlcy5vcmlnaW5hbEFycmF5QnVmZmVyKTtcbiAgICBpZiAoIXJlcy5vcmlnaW5hbEltYWdlIHx8ICFyZXMub3JpZ2luYWxJbWFnZS5jb21wbGV0ZSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignTm8gaW1hZ2UgbG9hZGVkJykpO1xuICAgIH1cbiAgICBjb25zdCBsb2FkZWRJbWFnZSA9IHtcbiAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgIG9iamVjdFVybDogcmVzLm9yaWdpbmFsT2JqZWN0VXJsLFxuICAgICAgICBpbWFnZTogcmVzLm9yaWdpbmFsSW1hZ2UsXG4gICAgICAgIHNpemU6IHJlcy5vcmlnaW5hbEltYWdlU2l6ZSA/PyB7XG4gICAgICAgICAgd2lkdGg6IHJlcy5vcmlnaW5hbEltYWdlLm5hdHVyYWxXaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IHJlcy5vcmlnaW5hbEltYWdlLm5hdHVyYWxIZWlnaHRcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGV4aWZUcmFuc2Zvcm1cbiAgICB9O1xuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybUxvYWRlZEltYWdlKGxvYWRlZEltYWdlLCBjcm9wcGVyU2V0dGluZ3MsIGZvcmNlVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGFzeW5jIHRyYW5zZm9ybUxvYWRlZEltYWdlKGxvYWRlZEltYWdlOiBQYXJ0aWFsPExvYWRlZEltYWdlPiwgY3JvcHBlclN0YXRlOiBDcm9wcGVyU3RhdGUsIGZvcmNlVHJhbnNmb3JtID0gZmFsc2UpOiBQcm9taXNlPExvYWRlZEltYWdlPiB7XG4gICAgY29uc3QgY2FudmFzUm90YXRpb24gPSBjcm9wcGVyU3RhdGUub3B0aW9ucy5jYW52YXNSb3RhdGlvbiArIGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLnJvdGF0ZTtcbiAgICBjb25zdCBvcmlnaW5hbFNpemUgPSBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuc2l6ZTtcbiAgICBpZiAoIWZvcmNlVHJhbnNmb3JtICYmIGNhbnZhc1JvdGF0aW9uID09PSAwICYmICFsb2FkZWRJbWFnZS5leGlmVHJhbnNmb3JtIS5mbGlwICYmICFjcm9wcGVyU3RhdGUub3B0aW9ucy5jb250YWluV2l0aGluQXNwZWN0UmF0aW8pIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgICAgb2JqZWN0VXJsOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEub2JqZWN0VXJsLFxuICAgICAgICAgIGltYWdlOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuaW1hZ2UsXG4gICAgICAgICAgc2l6ZTogey4uLm9yaWdpbmFsU2l6ZX1cbiAgICAgICAgfSxcbiAgICAgICAgdHJhbnNmb3JtZWQ6IHtcbiAgICAgICAgICBvYmplY3RVcmw6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5vYmplY3RVcmwsXG4gICAgICAgICAgaW1hZ2U6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5pbWFnZSxcbiAgICAgICAgICBzaXplOiB7Li4ub3JpZ2luYWxTaXplfVxuICAgICAgICB9LFxuICAgICAgICBleGlmVHJhbnNmb3JtOiBsb2FkZWRJbWFnZS5leGlmVHJhbnNmb3JtIVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2Zvcm1lZFNpemUgPSB0aGlzLmdldFRyYW5zZm9ybWVkU2l6ZShvcmlnaW5hbFNpemUsIGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLCBjcm9wcGVyU3RhdGUpO1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHRyYW5zZm9ybWVkU2l6ZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gdHJhbnNmb3JtZWRTaXplLmhlaWdodDtcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjdHg/LnNldFRyYW5zZm9ybShcbiAgICAgIGxvYWRlZEltYWdlLmV4aWZUcmFuc2Zvcm0hLmZsaXAgPyAtMSA6IDEsXG4gICAgICAwLFxuICAgICAgMCxcbiAgICAgIDEsXG4gICAgICBjYW52YXMud2lkdGggLyAyLFxuICAgICAgY2FudmFzLmhlaWdodCAvIDJcbiAgICApO1xuICAgIGN0eD8ucm90YXRlKE1hdGguUEkgKiAoY2FudmFzUm90YXRpb24gLyAyKSk7XG4gICAgY3R4Py5kcmF3SW1hZ2UoXG4gICAgICBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuaW1hZ2UsXG4gICAgICAtb3JpZ2luYWxTaXplLndpZHRoIC8gMixcbiAgICAgIC1vcmlnaW5hbFNpemUuaGVpZ2h0IC8gMlxuICAgICk7XG4gICAgY29uc3QgYmxvYiA9IGF3YWl0IG5ldyBQcm9taXNlPEJsb2IgfCBudWxsPihyZXNvbHZlID0+IGNhbnZhcy50b0Jsb2IocmVzb2x2ZSwgY3JvcHBlclN0YXRlLm9wdGlvbnMuZm9ybWF0KSk7XG4gICAgaWYgKCFibG9iKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgQmxvYiBmb3IgdHJhbnNmb3JtZWQgaW1hZ2UuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iamVjdFVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgdHJhbnNmb3JtZWRJbWFnZSA9IGF3YWl0IHRoaXMubG9hZEltYWdlRnJvbU9iamVjdFVybChvYmplY3RVcmwpO1xuICAgIHJldHVybiB7XG4gICAgICBvcmlnaW5hbDoge1xuICAgICAgICBvYmplY3RVcmw6IGxvYWRlZEltYWdlLm9yaWdpbmFsIS5vYmplY3RVcmwsXG4gICAgICAgIGltYWdlOiBsb2FkZWRJbWFnZS5vcmlnaW5hbCEuaW1hZ2UsXG4gICAgICAgIHNpemU6IHsuLi5vcmlnaW5hbFNpemV9XG4gICAgICB9LFxuICAgICAgdHJhbnNmb3JtZWQ6IHtcbiAgICAgICAgb2JqZWN0VXJsOiBvYmplY3RVcmwsXG4gICAgICAgIGltYWdlOiB0cmFuc2Zvcm1lZEltYWdlLFxuICAgICAgICBzaXplOiB7XG4gICAgICAgICAgd2lkdGg6IHRyYW5zZm9ybWVkSW1hZ2Uud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiB0cmFuc2Zvcm1lZEltYWdlLmhlaWdodFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXhpZlRyYW5zZm9ybTogbG9hZGVkSW1hZ2UuZXhpZlRyYW5zZm9ybSFcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkSW1hZ2VGcm9tT2JqZWN0VXJsKG9iamVjdFVybDogc3RyaW5nKTogUHJvbWlzZTxIVE1MSW1hZ2VFbGVtZW50PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPEhUTUxJbWFnZUVsZW1lbnQ+KCgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgICAgaW1hZ2Uub25sb2FkID0gKCkgPT4gcmVzb2x2ZShpbWFnZSk7XG4gICAgICBpbWFnZS5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgaW1hZ2Uuc3JjID0gb2JqZWN0VXJsO1xuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VHJhbnNmb3JtZWRTaXplKFxuICAgIG9yaWdpbmFsU2l6ZTogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9LFxuICAgIGV4aWZUcmFuc2Zvcm06IEV4aWZUcmFuc2Zvcm0sXG4gICAgY3JvcHBlclN0YXRlOiBDcm9wcGVyU3RhdGVcbiAgKTogRGltZW5zaW9ucyB7XG4gICAgY29uc3QgY2FudmFzUm90YXRpb24gPSBjcm9wcGVyU3RhdGUub3B0aW9ucy5jYW52YXNSb3RhdGlvbiArIGV4aWZUcmFuc2Zvcm0ucm90YXRlO1xuICAgIGlmIChjcm9wcGVyU3RhdGUub3B0aW9ucy5jb250YWluV2l0aGluQXNwZWN0UmF0aW8pIHtcbiAgICAgIGlmIChjYW52YXNSb3RhdGlvbiAlIDIpIHtcbiAgICAgICAgY29uc3QgbWluV2lkdGhUb0NvbnRhaW4gPSBvcmlnaW5hbFNpemUud2lkdGggKiBjcm9wcGVyU3RhdGUub3B0aW9ucy5hc3BlY3RSYXRpbztcbiAgICAgICAgY29uc3QgbWluSGVpZ2h0VG9Db250YWluID0gb3JpZ2luYWxTaXplLmhlaWdodCAvIGNyb3BwZXJTdGF0ZS5vcHRpb25zLmFzcGVjdFJhdGlvO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHdpZHRoOiBNYXRoLm1heChvcmlnaW5hbFNpemUuaGVpZ2h0LCBtaW5XaWR0aFRvQ29udGFpbiksXG4gICAgICAgICAgaGVpZ2h0OiBNYXRoLm1heChvcmlnaW5hbFNpemUud2lkdGgsIG1pbkhlaWdodFRvQ29udGFpbilcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG1pbldpZHRoVG9Db250YWluID0gb3JpZ2luYWxTaXplLmhlaWdodCAqIGNyb3BwZXJTdGF0ZS5vcHRpb25zLmFzcGVjdFJhdGlvO1xuICAgICAgICBjb25zdCBtaW5IZWlnaHRUb0NvbnRhaW4gPSBvcmlnaW5hbFNpemUud2lkdGggLyBjcm9wcGVyU3RhdGUub3B0aW9ucy5hc3BlY3RSYXRpbztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB3aWR0aDogTWF0aC5tYXgob3JpZ2luYWxTaXplLndpZHRoLCBtaW5XaWR0aFRvQ29udGFpbiksXG4gICAgICAgICAgaGVpZ2h0OiBNYXRoLm1heChvcmlnaW5hbFNpemUuaGVpZ2h0LCBtaW5IZWlnaHRUb0NvbnRhaW4pXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNhbnZhc1JvdGF0aW9uICUgMikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGVpZ2h0OiBvcmlnaW5hbFNpemUud2lkdGgsXG4gICAgICAgIHdpZHRoOiBvcmlnaW5hbFNpemUuaGVpZ2h0XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGg6IG9yaWdpbmFsU2l6ZS53aWR0aCxcbiAgICAgIGhlaWdodDogb3JpZ2luYWxTaXplLmhlaWdodFxuICAgIH07XG4gIH1cbn1cbiJdfQ==