UNPKG

ng-cornerstone

Version:

[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.git

183 lines 27.7 kB
import { Injectable } from '@angular/core'; import { metaData, utilities } from '@cornerstonejs/core'; import { api } from 'dicomweb-client'; import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'; import dcmjs from 'dcmjs'; import getPixelSpacingInformation from './getPixelSpacingInformation'; import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv'; import { RequestSchema } from '../config/types'; import { getPTImageIdInstanceMetadata } from './getPTImageIdInstanceMetadata'; import ptScalingMetaDataProvider from './ptScalingMetaDataProvider'; import * as i0 from "@angular/core"; const { DicomMetaDictionary } = dcmjs.data; export class ImageIdService { constructor() { } async wadoRsCreateImageIdsAndCacheMetaData(imageInfo) { const MODALITY = '00080060'; const SOP_INSTANCE_UID = '00080018'; const { urlRoot, studyInstanceUID, seriesInstanceUID } = imageInfo; const client = new api.DICOMwebClient({ url: urlRoot }); const instances = await client.retrieveSeriesMetadata({ studyInstanceUID, seriesInstanceUID, }); const modality = instances[0][MODALITY].Value[0]; let sopInstanceUIDSet; if (imageInfo?.sopInstanceUIDs && imageInfo?.sopInstanceUIDs.length >= 0) { sopInstanceUIDSet = new Set(imageInfo?.sopInstanceUIDs); } else { const instanceUIDs = instances.map((instanceMetaData) => { return instanceMetaData[SOP_INSTANCE_UID].Value[0]; }); sopInstanceUIDSet = new Set(instanceUIDs); imageInfo.sopInstanceUIDs = instanceUIDs; } let imageIds = []; instances.forEach((instanceMetaData) => { const sopInstanceUID = instanceMetaData[SOP_INSTANCE_UID].Value[0]; if (sopInstanceUIDSet.has(sopInstanceUID)) { const imageId = ImageIdService.wadoRsCreateImageIds({ ...imageInfo, sopInstanceUIDs: [sopInstanceUID], }); imageIds.push(...imageId); // only one image id cornerstoneDICOMImageLoader.wadors.metaDataManager.add(imageId[0], instanceMetaData); } }); imageIds = this.convertMultiframeImageIds(imageIds); this.pixelSpacingProvider(imageIds); if (modality === 'PT') { this.ptProvider(imageIds); } return imageIds; } static createImageIds(imageInfo) { if (imageInfo?.schema === RequestSchema.wadoRs) { return ImageIdService.wadoRsCreateImageIds(imageInfo); } else if (imageInfo?.schema === RequestSchema.wadoUri) { return ImageIdService.wadoURICreateImageIds(imageInfo); } return []; } static wadoURICreateImageIds(imageInfo) { if (!imageInfo.sopInstanceUIDs || imageInfo.sopInstanceUIDs.length === 0) { console.error('Invalid image info', imageInfo); return []; } const { urlRoot, studyInstanceUID, seriesInstanceUID, sopInstanceUIDs } = imageInfo; const wadoURIRoot = `${RequestSchema.wadoUri}${urlRoot}?requestType=WADO&studyUID=${studyInstanceUID}&seriesUID=${seriesInstanceUID}&contentType=application%2Fdicom`; return sopInstanceUIDs.map((uid) => { return `${wadoURIRoot}&objectUID=${uid}`; }); } static wadoRsCreateImageIds(imageInfo) { if (!imageInfo.sopInstanceUIDs || imageInfo.sopInstanceUIDs.length === 0) { console.error('Invalid image info', imageInfo); return []; } const { urlRoot, studyInstanceUID, seriesInstanceUID, sopInstanceUIDs } = imageInfo; const wadoURIRoot = `${RequestSchema.wadoRs}${urlRoot}/studies/${studyInstanceUID}/series/${seriesInstanceUID}`; return sopInstanceUIDs.map((uid) => { return `${wadoURIRoot}/instances/${uid}/frames/1`; }); } convertMultiframeImageIds(imageIds) { const newImageIds = []; imageIds.forEach((imageId) => { const { imageIdFrameless } = this.getFrameInformation(imageId); const instanceMetaData = metaData.get('multiframeModule', imageId); if (instanceMetaData && instanceMetaData.NumberOfFrames && instanceMetaData.NumberOfFrames > 1) { const NumberOfFrames = instanceMetaData.NumberOfFrames; for (let i = 0; i < NumberOfFrames; i++) { const newImageId = imageIdFrameless + (i + 1); newImageIds.push(newImageId); } } else newImageIds.push(imageId); }); return newImageIds; } getFrameInformation(imageId) { if (imageId.includes('wadors:')) { const frameIndex = imageId.indexOf('/frames/'); const imageIdFrameless = frameIndex > 0 ? imageId.slice(0, frameIndex + 8) : imageId; return { frameIndex, imageIdFrameless, }; } else { const frameIndex = imageId.indexOf('&frame='); let imageIdFrameless = frameIndex > 0 ? imageId.slice(0, frameIndex + 7) : imageId; if (!imageIdFrameless.includes('&frame=')) { imageIdFrameless = imageIdFrameless + '&frame='; } return { frameIndex, imageIdFrameless, }; } } pixelSpacingProvider(imageIds) { imageIds.forEach((imageId) => { let instanceMetaData = cornerstoneDICOMImageLoader.wadors.metaDataManager.get(imageId); // It was using JSON.parse(JSON.stringify(...)) before but it is 8x slower instanceMetaData = this.removeInvalidTags(instanceMetaData); if (instanceMetaData) { // Add calibrated pixel spacing const metadata = DicomMetaDictionary.naturalizeDataset(instanceMetaData); const pixelSpacing = getPixelSpacingInformation(metadata); if (pixelSpacing) { utilities.calibratedPixelSpacingMetadataProvider.add(imageId, pixelSpacing.map((s) => parseFloat(s))); } } }); } ptProvider(imageIds) { const instanceMetadataArray = []; imageIds.forEach((imageId) => { const instanceMetadata = getPTImageIdInstanceMetadata(imageId); // TODO: Temporary fix because static-wado is producing a string, not an array of values // (or maybe dcmjs isn't parsing it correctly?) // It's showing up like 'DECY\\ATTN\\SCAT\\DTIM\\RAN\\RADL\\DCAL\\SLSENS\\NORM' // but calculate-suv expects ['DECY', 'ATTN', ...] if (typeof instanceMetadata.CorrectedImage === 'string') { instanceMetadata.CorrectedImage = instanceMetadata.CorrectedImage.split('\\'); } if (instanceMetadata) { instanceMetadataArray.push(instanceMetadata); } }); if (instanceMetadataArray.length) { const suvScalingFactors = calculateSUVScalingFactors(instanceMetadataArray); instanceMetadataArray.forEach((instanceMetadata, index) => { ptScalingMetaDataProvider.addInstance(imageIds[index], suvScalingFactors[index]); }); } } removeInvalidTags(srcMetadata) { // Object.create(null) make it ~9% faster const dstMetadata = Object.create(null); const tagIds = Object.keys(srcMetadata); let tagValue; tagIds.forEach((tagId) => { tagValue = srcMetadata[tagId]; if (tagValue !== undefined && tagValue !== null) { dstMetadata[tagId] = tagValue; } }); return dstMetadata; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageIdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageIdService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImageIdService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtaWQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNvcm5lcnN0b25lL3NyYy9saWIvY29yZS9wcm92aWRlci9pbWFnZS1pZC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTywyQkFBMkIsTUFBTSxtQ0FBbUMsQ0FBQztBQUM1RSxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTywwQkFBMEIsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsMEJBQTBCLEVBQW9CLE1BQU0sOEJBQThCLENBQUM7QUFDNUYsT0FBTyxFQUFhLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzlFLE9BQU8seUJBQXlCLE1BQU0sNkJBQTZCLENBQUM7O0FBRXBFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7QUFJM0MsTUFBTSxPQUFPLGNBQWM7SUFDekIsZ0JBQWUsQ0FBQztJQUVoQixLQUFLLENBQUMsb0NBQW9DLENBQUMsU0FBb0I7UUFDN0QsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDO1FBQzVCLE1BQU0sZ0JBQWdCLEdBQUcsVUFBVSxDQUFDO1FBQ3BDLE1BQU0sRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxTQUFTLENBQUM7UUFDbkUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRyxFQUFF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QztRQUViLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUN2QixRQUFRLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTlCLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ2hELFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDaEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQzsrR0FuTFUsY0FBYzttSEFBZCxjQUFjLGNBRmIsTUFBTTs7NEZBRVAsY0FBYztrQkFIMUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBtZXRhRGF0YSwgdXRpbGl0aWVzIH0gZnJvbSAnQGNvcm5lcnN0b25lanMvY29yZSc7XG5pbXBvcnQgeyBhcGkgfSBmcm9tICdkaWNvbXdlYi1jbGllbnQnO1xuaW1wb3J0IGNvcm5lcnN0b25lRElDT01JbWFnZUxvYWRlciBmcm9tICdAY29ybmVyc3RvbmVqcy9kaWNvbS1pbWFnZS1sb2FkZXInO1xuaW1wb3J0IGRjbWpzIGZyb20gJ2RjbWpzJztcbmltcG9ydCBnZXRQaXhlbFNwYWNpbmdJbmZvcm1hdGlvbiBmcm9tICcuL2dldFBpeGVsU3BhY2luZ0luZm9ybWF0aW9uJztcbmltcG9ydCB7IGNhbGN1bGF0ZVNVVlNjYWxpbmdGYWN0b3JzLCBJbnN0YW5jZU1ldGFkYXRhIH0gZnJvbSAnQGNvcm5lcnN0b25lanMvY2FsY3VsYXRlLXN1dic7XG5pbXBvcnQgeyBJbWFnZUluZm8sIFJlcXVlc3RTY2hlbWEgfSBmcm9tICcuLi9jb25maWcvdHlwZXMnO1xuaW1wb3J0IHsgZ2V0UFRJbWFnZUlkSW5zdGFuY2VNZXRhZGF0YSB9IGZyb20gJy4vZ2V0UFRJbWFnZUlkSW5zdGFuY2VNZXRhZGF0YSc7XG5pbXBvcnQgcHRTY2FsaW5nTWV0YURhdGFQcm92aWRlciBmcm9tICcuL3B0U2NhbGluZ01ldGFEYXRhUHJvdmlkZXInO1xuXG5jb25zdCB7IERpY29tTWV0YURpY3Rpb25hcnkgfSA9IGRjbWpzLmRhdGE7XG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgSW1hZ2VJZFNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgYXN5bmMgd2Fkb1JzQ3JlYXRlSW1hZ2VJZHNBbmRDYWNoZU1ldGFEYXRhKGltYWdlSW5mbzogSW1hZ2VJbmZvKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IE1PREFMSVRZID0gJzAwMDgwMDYwJztcbiAgICBjb25zdCBTT1BfSU5TVEFOQ0VfVUlEID0gJzAwMDgwMDE4JztcbiAgICBjb25zdCB7IHVybFJvb3QsIHN0dWR5SW5zdGFuY2VVSUQsIHNlcmllc0luc3RhbmNlVUlEIH0gPSBpbWFnZUluZm87XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IGFwaS5ESUNPTXdlYkNsaWVudCh7IHVybDogdXJsUm9vdCB9KTtcbiAgICBjb25zdCBpbnN0YW5jZXMgPSBhd2FpdCBjbGllbnQucmV0cmlldmVTZXJpZXNNZXRhZGF0YSh7XG4gICAgICBzdHVkeUluc3RhbmNlVUlELFxuICAgICAgc2VyaWVzSW5zdGFuY2VVSUQsXG4gICAgfSk7XG4gICAgY29uc3QgbW9kYWxpdHkgPSBpbnN0YW5jZXNbMF1bTU9EQUxJVFldLlZhbHVlWzBdO1xuICAgIGxldCBzb3BJbnN0YW5jZVVJRFNldDtcbiAgICBpZiAoaW1hZ2VJbmZvPy5zb3BJbnN0YW5jZVVJRHMgJiYgaW1hZ2VJbmZvPy5zb3BJbnN0YW5jZVVJRHMubGVuZ3RoID49IDApIHtcbiAgICAgIHNvcEluc3RhbmNlVUlEU2V0ID0gbmV3IFNldDxzdHJpbmc+KGltYWdlSW5mbz8uc29wSW5zdGFuY2VVSURzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaW5zdGFuY2VVSURzID0gaW5zdGFuY2VzLm1hcCgoaW5zdGFuY2VNZXRhRGF0YSkgPT4ge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2VNZXRhRGF0YVtTT1BfSU5TVEFOQ0VfVUlEXS5WYWx1ZVswXTtcbiAgICAgIH0pO1xuICAgICAgc29wSW5zdGFuY2VVSURTZXQgPSBuZXcgU2V0PHN0cmluZz4oaW5zdGFuY2VVSURzKTtcbiAgICAgIGltYWdlSW5mby5zb3BJbnN0YW5jZVVJRHMgPSBpbnN0YW5jZVVJRHM7XG4gICAgfVxuICAgIGxldCBpbWFnZUlkczogc3RyaW5nW10gPSBbXTtcbiAgICBpbnN0YW5jZXMuZm9yRWFjaCgoaW5zdGFuY2VNZXRhRGF0YSkgPT4ge1xuICAgICAgY29uc3Qgc29wSW5zdGFuY2VVSUQgPSBpbnN0YW5jZU1ldGFEYXRhW1NPUF9JTlNUQU5DRV9VSURdLlZhbHVlWzBdO1xuICAgICAgaWYgKHNvcEluc3RhbmNlVUlEU2V0Lmhhcyhzb3BJbnN0YW5jZVVJRCkpIHtcbiAgICAgICAgY29uc3QgaW1hZ2VJZCA9IEltYWdlSWRTZXJ2aWNlLndhZG9Sc0NyZWF0ZUltYWdlSWRzKHtcbiAgICAgICAgICAuLi5pbWFnZUluZm8sXG4gICAgICAgICAgc29wSW5zdGFuY2VVSURzOiBbc29wSW5zdGFuY2VVSURdLFxuICAgICAgICB9KTtcbiAgICAgICAgaW1hZ2VJZHMucHVzaCguLi5pbWFnZUlkKTsgLy8gb25seSBvbmUgaW1hZ2UgaWRcbiAgICAgICAgY29ybmVyc3RvbmVESUNPTUltYWdlTG9hZGVyLndhZG9ycy5tZXRhRGF0YU1hbmFnZXIuYWRkKGltYWdlSWRbMF0sIGluc3RhbmNlTWV0YURhdGEpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGltYWdlSWRzID0gdGhpcy5jb252ZXJ0TXVsdGlmcmFtZUltYWdlSWRzKGltYWdlSWRzKTtcblxuICAgIHRoaXMucGl4ZWxTcGFjaW5nUHJvdmlkZXIoaW1hZ2VJZHMpO1xuXG4gICAgaWYgKG1vZGFsaXR5ID09PSAnUFQnKSB7XG4gICAgICB0aGlzLnB0UHJvdmlkZXIoaW1hZ2VJZHMpO1xuICAgIH1cbiAgICByZXR1cm4gaW1hZ2VJZHM7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW1hZ2VJZHMoaW1hZ2VJbmZvOiBJbWFnZUluZm8pIHtcbiAgICBpZiAoaW1hZ2VJbmZvPy5zY2hlbWEgPT09IFJlcXVlc3RTY2hlbWEud2Fkb1JzKSB7XG4gICAgICByZXR1cm4gSW1hZ2VJZFNlcnZpY2Uud2Fkb1JzQ3JlYXRlSW1hZ2VJZHMoaW1hZ2VJbmZvKTtcbiAgICB9IGVsc2UgaWYgKGltYWdlSW5mbz8uc2NoZW1hID09PSBSZXF1ZXN0U2NoZW1hLndhZG9VcmkpIHtcbiAgICAgIHJldHVybiBJbWFnZUlkU2VydmljZS53YWRvVVJJQ3JlYXRlSW1hZ2VJZHMoaW1hZ2VJbmZvKTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgc3RhdGljIHdhZG9VUklDcmVhdGVJbWFnZUlkcyhpbWFnZUluZm86IEltYWdlSW5mbyk6IHN0cmluZ1tdIHtcbiAgICBpZiAoIWltYWdlSW5mby5zb3BJbnN0YW5jZVVJRHMgfHwgaW1hZ2VJbmZvLnNvcEluc3RhbmNlVUlEcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgaW1hZ2UgaW5mbycsIGltYWdlSW5mbyk7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHsgdXJsUm9vdCwgc3R1ZHlJbnN0YW5jZVVJRCwgc2VyaWVzSW5zdGFuY2VVSUQsIHNvcEluc3RhbmNlVUlEcyB9ID0gaW1hZ2VJbmZvO1xuICAgIGNvbnN0IHdhZG9VUklSb290ID0gYCR7UmVxdWVzdFNjaGVtYS53YWRvVXJpfSR7dXJsUm9vdH0/cmVxdWVzdFR5cGU9V0FETyZzdHVkeVVJRD0ke3N0dWR5SW5zdGFuY2VVSUR9JnNlcmllc1VJRD0ke3Nlcmllc0luc3RhbmNlVUlEfSZjb250ZW50VHlwZT1hcHBsaWNhdGlvbiUyRmRpY29tYDtcbiAgICByZXR1cm4gc29wSW5zdGFuY2VVSURzIS5tYXAoKHVpZCkgPT4ge1xuICAgICAgcmV0dXJuIGAke3dhZG9VUklSb290fSZvYmplY3RVSUQ9JHt1aWR9YDtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyB3YWRvUnNDcmVhdGVJbWFnZUlkcyhpbWFnZUluZm86IEltYWdlSW5mbyk6IHN0cmluZ1tdIHtcbiAgICBpZiAoIWltYWdlSW5mby5zb3BJbnN0YW5jZVVJRHMgfHwgaW1hZ2VJbmZvLnNvcEluc3RhbmNlVUlEcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgaW1hZ2UgaW5mbycsIGltYWdlSW5mbyk7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHsgdXJsUm9vdCwgc3R1ZHlJbnN0YW5jZVVJRCwgc2VyaWVzSW5zdGFuY2VVSUQsIHNvcEluc3RhbmNlVUlEcyB9ID0gaW1hZ2VJbmZvO1xuICAgIGNvbnN0IHdhZG9VUklSb290ID0gYCR7UmVxdWVzdFNjaGVtYS53YWRvUnN9JHt1cmxSb290fS9zdHVkaWVzLyR7c3R1ZHlJbnN0YW5jZVVJRH0vc2VyaWVzLyR7c2VyaWVzSW5zdGFuY2VVSUR9YDtcbiAgICByZXR1cm4gc29wSW5zdGFuY2VVSURzIS5tYXAoKHVpZCkgPT4ge1xuICAgICAgcmV0dXJuIGAke3dhZG9VUklSb290fS9pbnN0YW5jZXMvJHt1aWR9L2ZyYW1lcy8xYDtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnZlcnRNdWx0aWZyYW1lSW1hZ2VJZHMoaW1hZ2VJZHM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IG5ld0ltYWdlSWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGltYWdlSWRzLmZvckVhY2goKGltYWdlSWQpID0+IHtcbiAgICAgIGNvbnN0IHsgaW1hZ2VJZEZyYW1lbGVzcyB9ID0gdGhpcy5nZXRGcmFtZUluZm9ybWF0aW9uKGltYWdlSWQpO1xuICAgICAgY29uc3QgaW5zdGFuY2VNZXRhRGF0YSA9IG1ldGFEYXRhLmdldCgnbXVsdGlmcmFtZU1vZHVsZScsIGltYWdlSWQpO1xuICAgICAgaWYgKGluc3RhbmNlTWV0YURhdGEgJiYgaW5zdGFuY2VNZXRhRGF0YS5OdW1iZXJPZkZyYW1lcyAmJiBpbnN0YW5jZU1ldGFEYXRhLk51bWJlck9mRnJhbWVzID4gMSkge1xuICAgICAgICBjb25zdCBOdW1iZXJPZkZyYW1lcyA9IGluc3RhbmNlTWV0YURhdGEuTnVtYmVyT2ZGcmFtZXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTnVtYmVyT2ZGcmFtZXM7IGkrKykge1xuICAgICAgICAgIGNvbnN0IG5ld0ltYWdlSWQgPSBpbWFnZUlkRnJhbWVsZXNzICsgKGkgKyAxKTtcbiAgICAgICAgICBuZXdJbWFnZUlkcy5wdXNoKG5ld0ltYWdlSWQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgbmV3SW1hZ2VJZHMucHVzaChpbWFnZUlkKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3SW1hZ2VJZHM7XG4gIH1cblxuICBnZXRGcmFtZUluZm9ybWF0aW9uKGltYWdlSWQpOiB7XG4gICAgZnJhbWVJbmRleDogbnVtYmVyO1xuICAgIGltYWdlSWRGcmFtZWxlc3M6IHN0cmluZztcbiAgfSB7XG4gICAgaWYgKGltYWdlSWQuaW5jbHVkZXMoJ3dhZG9yczonKSkge1xuICAgICAgY29uc3QgZnJhbWVJbmRleCA9IGltYWdlSWQuaW5kZXhPZignL2ZyYW1lcy8nKTtcbiAgICAgIGNvbnN0IGltYWdlSWRGcmFtZWxlc3MgPSBmcmFtZUluZGV4ID4gMCA/IGltYWdlSWQuc2xpY2UoMCwgZnJhbWVJbmRleCArIDgpIDogaW1hZ2VJZDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZyYW1lSW5kZXgsXG4gICAgICAgIGltYWdlSWRGcmFtZWxlc3MsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmcmFtZUluZGV4ID0gaW1hZ2VJZC5pbmRleE9mKCcmZnJhbWU9Jyk7XG4gICAgICBsZXQgaW1hZ2VJZEZyYW1lbGVzcyA9IGZyYW1lSW5kZXggPiAwID8gaW1hZ2VJZC5zbGljZSgwLCBmcmFtZUluZGV4ICsgNykgOiBpbWFnZUlkO1xuICAgICAgaWYgKCFpbWFnZUlkRnJhbWVsZXNzLmluY2x1ZGVzKCcmZnJhbWU9JykpIHtcbiAgICAgICAgaW1hZ2VJZEZyYW1lbGVzcyA9IGltYWdlSWRGcmFtZWxlc3MgKyAnJmZyYW1lPSc7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmcmFtZUluZGV4LFxuICAgICAgICBpbWFnZUlkRnJhbWVsZXNzLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwaXhlbFNwYWNpbmdQcm92aWRlcihpbWFnZUlkczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpbWFnZUlkcy5mb3JFYWNoKChpbWFnZUlkKSA9PiB7XG4gICAgICBsZXQgaW5zdGFuY2VNZXRhRGF0YSA9IGNvcm5lcnN0b25lRElDT01JbWFnZUxvYWRlci53YWRvcnMubWV0YURhdGFNYW5hZ2VyLmdldChpbWFnZUlkKTtcblxuICAgICAgLy8gSXQgd2FzIHVzaW5nIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoLi4uKSkgYmVmb3JlIGJ1dCBpdCBpcyA4eCBzbG93ZXJcbiAgICAgIGluc3RhbmNlTWV0YURhdGEgPSB0aGlzLnJlbW92ZUludmFsaWRUYWdzKGluc3RhbmNlTWV0YURhdGEpO1xuXG4gICAgICBpZiAoaW5zdGFuY2VNZXRhRGF0YSkge1xuICAgICAgICAvLyBBZGQgY2FsaWJyYXRlZCBwaXhlbCBzcGFjaW5nXG4gICAgICAgIGNvbnN0IG1ldGFkYXRhID0gRGljb21NZXRhRGljdGlvbmFyeS5uYXR1cmFsaXplRGF0YXNldChpbnN0YW5jZU1ldGFEYXRhKTtcbiAgICAgICAgY29uc3QgcGl4ZWxTcGFjaW5nID0gZ2V0UGl4ZWxTcGFjaW5nSW5mb3JtYXRpb24obWV0YWRhdGEpO1xuXG4gICAgICAgIGlmIChwaXhlbFNwYWNpbmcpIHtcbiAgICAgICAgICB1dGlsaXRpZXMuY2FsaWJyYXRlZFBpeGVsU3BhY2luZ01ldGFkYXRhUHJvdmlkZXIuYWRkKFxuICAgICAgICAgICAgaW1hZ2VJZCxcbiAgICAgICAgICAgIHBpeGVsU3BhY2luZy5tYXAoKHMpID0+IHBhcnNlRmxvYXQocykpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBwdFByb3ZpZGVyKGltYWdlSWRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGluc3RhbmNlTWV0YWRhdGFBcnJheTogSW5zdGFuY2VNZXRhZGF0YVtdID0gW107XG4gICAgaW1hZ2VJZHMuZm9yRWFjaCgoaW1hZ2VJZCkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2VNZXRhZGF0YSA9IGdldFBUSW1hZ2VJZEluc3RhbmNlTWV0YWRhdGEoaW1hZ2VJZCk7XG5cbiAgICAgIC8vIFRPRE86IFRlbXBvcmFyeSBmaXggYmVjYXVzZSBzdGF0aWMtd2FkbyBpcyBwcm9kdWNpbmcgYSBzdHJpbmcsIG5vdCBhbiBhcnJheSBvZiB2YWx1ZXNcbiAgICAgIC8vIChvciBtYXliZSBkY21qcyBpc24ndCBwYXJzaW5nIGl0IGNvcnJlY3RseT8pXG4gICAgICAvLyBJdCdzIHNob3dpbmcgdXAgbGlrZSAnREVDWVxcXFxBVFROXFxcXFNDQVRcXFxcRFRJTVxcXFxSQU5cXFxcUkFETFxcXFxEQ0FMXFxcXFNMU0VOU1xcXFxOT1JNJ1xuICAgICAgLy8gYnV0IGNhbGN1bGF0ZS1zdXYgZXhwZWN0cyBbJ0RFQ1knLCAnQVRUTicsIC4uLl1cbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2VNZXRhZGF0YS5Db3JyZWN0ZWRJbWFnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgaW5zdGFuY2VNZXRhZGF0YS5Db3JyZWN0ZWRJbWFnZSA9IChpbnN0YW5jZU1ldGFkYXRhLkNvcnJlY3RlZEltYWdlIGFzIHN0cmluZykuc3BsaXQoJ1xcXFwnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluc3RhbmNlTWV0YWRhdGEpIHtcbiAgICAgICAgaW5zdGFuY2VNZXRhZGF0YUFycmF5LnB1c2goaW5zdGFuY2VNZXRhZGF0YSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGluc3RhbmNlTWV0YWRhdGFBcnJheS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHN1dlNjYWxpbmdGYWN0b3JzID0gY2FsY3VsYXRlU1VWU2NhbGluZ0ZhY3RvcnMoaW5zdGFuY2VNZXRhZGF0YUFycmF5KTtcbiAgICAgIGluc3RhbmNlTWV0YWRhdGFBcnJheS5mb3JFYWNoKChpbnN0YW5jZU1ldGFkYXRhLCBpbmRleCkgPT4ge1xuICAgICAgICBwdFNjYWxpbmdNZXRhRGF0YVByb3ZpZGVyLmFkZEluc3RhbmNlKGltYWdlSWRzW2luZGV4XSwgc3V2U2NhbGluZ0ZhY3RvcnNbaW5kZXhdKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUludmFsaWRUYWdzKHNyY01ldGFkYXRhKSB7XG4gICAgLy8gT2JqZWN0LmNyZWF0ZShudWxsKSBtYWtlIGl0IH45JSBmYXN0ZXJcbiAgICBjb25zdCBkc3RNZXRhZGF0YSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgY29uc3QgdGFnSWRzID0gT2JqZWN0LmtleXMoc3JjTWV0YWRhdGEpO1xuICAgIGxldCB0YWdWYWx1ZTtcblxuICAgIHRhZ0lkcy5mb3JFYWNoKCh0YWdJZCkgPT4ge1xuICAgICAgdGFnVmFsdWUgPSBzcmNNZXRhZGF0YVt0YWdJZF07XG5cbiAgICAgIGlmICh0YWdWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHRhZ1ZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgIGRzdE1ldGFkYXRhW3RhZ0lkXSA9IHRhZ1ZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRzdE1ldGFkYXRhO1xuICB9XG59XG4iXX0=