ng-cornerstone
Version:
[](https://github.com/prettier/prettier) [](http://commitizen.git
183 lines • 27.7 kB
JavaScript
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=