UNPKG

@tripsnek/tmf

Version:

TypeScript Modeling Framework - A TypeScript port of the Eclipse Modeling Framework (EMF)

273 lines 44.6 kB
import { EDataTypeImpl } from '../metamodel/impl/edata-type-impl.js'; import { EEnumLiteralImpl } from '../metamodel/impl/eenum-literal-impl.js'; import { EClassImpl } from '../metamodel/impl/eclass-impl.js'; import { EEnumImpl } from '../metamodel/impl/eenum-impl.js'; import { EAttributeImpl } from '../metamodel/impl/eattribute-impl.js'; import { EReferenceImpl } from '../metamodel/impl/ereference-impl.js'; import { EOperationImpl } from '../metamodel/impl/eoperation-impl.js'; import { EParameterImpl } from '../metamodel/impl/eparameter-impl.js'; import { TUtils } from '../tutils.js'; import { EPackageImpl } from '../metamodel/impl/epackageimpl.js'; /** * Parses Ecore XML strings into TMF metamodel instances. * This class handles the core parsing logic without file system dependencies. */ export class EcoreStringParser { parseFromJsString(ecoreJsonStr) { return this.parseFromJs(JSON.parse(ecoreJsonStr)); } parseFromJs(ecoreJs) { const ePackage = ecoreJs['ecore:EPackage']; //holds all types and features in a map for reference resolution (e.g. assigning //types to references and attributes, enforcing EOpposites) const typesMap = new Map(); const featuresMap = new Map(); //add primitive types const primitiveTypes = TUtils.PRIMITIVES; for (const type of primitiveTypes) { typesMap.set('ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//' + type, new EDataTypeImpl(undefined, type)); } // for (const key of typesMap.keys()) { // console.error('KEY ' + key + ' : ' + typeof typesMap[key]); // } //parse all classifiers first, so that we can resolve them later this.instantiateAllClassifiersAndFeatures(ePackage, typesMap, featuresMap, []); //parse the root EPackage and all contents const pkgPath = []; const rootPackage = this.parsePackage(ePackage, undefined, typesMap, featuresMap, pkgPath); return rootPackage; } /** * Instantiates all the EClassifiers, which need to exist in-memory for a full * pass so that features can be assigned types. * * @param pkgJson * @param typesMap * @param path */ instantiateAllClassifiersAndFeatures(pkgJson, typesMap, featuresMap, path) { //keeps track of the path to the current package path.push(pkgJson['$'].name); if (pkgJson['eClassifiers']) { for (const classEntry of pkgJson['eClassifiers']) { let eclassifier = new EClassImpl(); const eType = classEntry['$']['xsi:type']; if (eType === 'ecore:EEnum') { eclassifier = new EEnumImpl(); for (const literalEntry of classEntry['eLiterals']) { const literal = new EEnumLiteralImpl(); if (literalEntry['$']['name']) literal.setName(literalEntry['$']['name']); if (literalEntry['$']['value']) literal.setValue(Number.parseInt(literalEntry['$']['value'])); if (literalEntry['$']['literal']) literal.setLiteral(literalEntry['$']['literal']); //TODO: Would not have to do both if model was source generated eclassifier.addLiteral(literal); literal.setEEnum(eclassifier); } } else if (eType === 'ecore:EDataType') { eclassifier = new EDataTypeImpl(); } eclassifier.setName(classEntry['$']['name']); if (classEntry['$']['abstract']) { eclassifier.setAbstract(classEntry['$']['abstract']); } if (classEntry['$']['interface']) { eclassifier.setInterface(classEntry['$']['interface']); } const eclassUri = this.getEClassifierUri(path, eclassifier.getName()); typesMap.set(eclassUri, eclassifier); if (classEntry['eStructuralFeatures']) { for (const featureEntry of classEntry['eStructuralFeatures']) { //instantiate the feature const fprops = featureEntry['$']; let efeature; if (fprops['xsi:type'] === 'ecore:EAttribute') { efeature = new EAttributeImpl(); if (fprops.iD) efeature.setId(true); } else if (fprops['xsi:type'] === 'ecore:EReference') { efeature = new EReferenceImpl(); } else { console.error('Unknown type: ' + fprops['xsi:eType']); console.log(fprops); } //create map entry from uri to the feature if (efeature) featuresMap.set(eclassUri + '/' + fprops['name'], efeature); } } } } //recurse subdirectories if (pkgJson['eSubpackages']) { for (const packageEntry of pkgJson['eSubpackages']) { this.instantiateAllClassifiersAndFeatures(packageEntry, typesMap, featuresMap, path); } } path.pop(); } //builds up the URI by which EClassifiers are referenced (e.g. to type features) getEClassifierUri(path, className) { let uri = '#//'; for (let i = 1; i < path.length; i++) { uri += path[i] + '/'; } uri += className; return uri; } /** * Parses the package represented by pkgJson. * * @param pkgJson * @param parentPkg * @param typesMap * @param path */ parsePackage(pkgJson, parentPkg, typesMap, featuresMap, path) { const thisPkg = new EPackageImpl(pkgJson['$'].name, pkgJson['$'].nsURI); thisPkg.setNsPrefix(pkgJson['$'].nsPrefix); //keeps track of the current path to the package path.push(pkgJson['$'].name); if (parentPkg) { //TODO: Should not have to do both of these, should be inverses parentPkg.getESubPackages().add(thisPkg); thisPkg.setESuperPackage(parentPkg); } if (pkgJson['eClassifiers']) { for (const classEntry of pkgJson['eClassifiers']) { const eclassUri = this.getEClassifierUri(path, classEntry['$']['name']); const eclass = typesMap.get(eclassUri); if (!eclass) { console.error('COULD NOT FIND ECLASS IDENTIFIED BY ' + eclassUri); } //TODO: Should not have to do both of these, should be inverses eclass.setEPackage(thisPkg); thisPkg.getEClassifiers().add(eclass); //parse out super types if (classEntry['$']['eSuperTypes']) { for (const superType of classEntry['$']['eSuperTypes'].split(' ')) { const superTypeEClass = typesMap.get(superType); if (!superTypeEClass) { console.error('COULD NOT FIND ECLASS IDENTIFIED BY ' + superType); } eclass.getESuperTypes().add(superTypeEClass); } } if (eclass instanceof EClassImpl) { //parse out features this.parseFeatures(classEntry, typesMap, featuresMap, eclass, eclassUri); //parse EOperations if ('eOperations' in classEntry) { const nameToEop = new Map(); for (const operationEntry of classEntry['eOperations']) { const fprops = operationEntry['$']; const prevExistingEop = nameToEop.get(fprops.name); const eOperation = prevExistingEop ? prevExistingEop : new EOperationImpl(); if (!prevExistingEop) { eOperation.setName(fprops.name); nameToEop.set(eOperation.getName(), eOperation); eclass.getEOperations().add(eOperation); eOperation.setEContainingClass(eclass); if (fprops.eType) eOperation.setEType(typesMap.get(fprops.eType)); if (fprops.upperBound) { eOperation.setUpperBound(Number(fprops.upperBound)); } } if ('eParameters' in operationEntry) { for (const paramEntry of operationEntry['eParameters']) { const name = paramEntry.$.name; let paramExists = false; for (const p of eOperation.getEParameters()) if (name == p.getName()) paramExists = true; if (!paramExists) { const param = new EParameterImpl(); param.setName(paramEntry.$.name); if (paramEntry.$.eType) { param.setEType(typesMap.get(paramEntry.$.eType)); } if (paramEntry.$.upperBound) { param.setUpperBound(Number(paramEntry.$.upperBound)); } //TODO: Would not have to do both if model was source generated eOperation.getEParameters().add(param); param.setEOperation(eOperation); } } } } } } } } //recurse sub-packages if (pkgJson['eSubpackages']) { for (const packageEntry of pkgJson['eSubpackages']) { this.parsePackage(packageEntry, thisPkg, typesMap, featuresMap, path); } } path.pop(); return thisPkg; } /** * Parses eStructuralFeatures elements from Ecore XMI element. * * @param classEntry * @param typesMap * @param featuresMap * @param eclass * @param eclassUri */ parseFeatures(classEntry, typesMap, featuresMap, eclass, eclassUri) { if ('eStructuralFeatures' in classEntry) { for (const featureEntry of classEntry['eStructuralFeatures']) { const fprops = featureEntry['$']; const efeature = featuresMap.get(eclassUri + '/' + fprops['name']); if (efeature) { efeature.setName(fprops['name']); const type = typesMap.get(fprops['eType']); if (!type) { console.error('WARNING: COULD NOT LOCATE TYPE FOR ' + fprops.name + ' with etype ' + fprops.eType); continue; } efeature.setEType(type); if (fprops['upperBound']) { efeature.setUpperBound(Number(fprops['upperBound'])); } else { efeature.setUpperBound(1); } //transient,changeable,volatile efeature.setVolatile(fprops.volatile == null ? false : JSON.parse(fprops.volatile)); efeature.setChangeable(fprops.changeable == null ? true : JSON.parse(fprops.changeable)); efeature.setTransient(fprops.transient == null ? false : JSON.parse(fprops.transient)); //eopposites and containment if (efeature instanceof EReferenceImpl) { if (fprops['eOpposite']) { const eopp = featuresMap.get(fprops['eOpposite']); efeature.setEOpposite(eopp); } efeature.setContainment(fprops.containment == null ? false : JSON.parse(fprops.containment)); } //TODO: This should be handled automatically be einverse enforcement (if tmf were source-generated) eclass.getEStructuralFeatures().add(efeature); efeature.setEContainingClass(eclass); } } } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNvcmUtc3RyaW5nLXBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvZWNvcmUvZWNvcmUtc3RyaW5nLXBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDM0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUs1RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBR3RFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFdEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFakU7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUVuQixpQkFBaUIsQ0FBQyxZQUFpQjtRQUN4QyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFSSxXQUFXLENBQUMsT0FBWTtRQUM3QixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUUzQyxnRkFBZ0Y7UUFDaEYsMkRBQTJEO1FBQzNELE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO1FBQ2hELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUE4QixDQUFDO1FBRTFELHFC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LElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUNoRSxDQUFDO29CQUVGLDRCQUE0QjtvQkFDNUIsSUFBSSxRQUFRLFlBQVksY0FBYyxFQUFFLENBQUM7d0JBQ3ZDLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7NEJBQ3hCLE1BQU0sSUFBSSxHQUFlLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7NEJBQzlELFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQzlCLENBQUM7d0JBQ0QsUUFBUSxDQUFDLGNBQWMsQ0FDckIsTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJOzRCQUN4QixDQUFDLENBQUMsS0FBSzs0QkFDUCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQ25DLENBQUM7b0JBQ0osQ0FBQztvQkFFRCxtR0FBbUc7b0JBQ25HLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDOUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN2QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFRGF0YVR5cGVJbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZWRhdGEtdHlwZS1pbXBsLmpzJztcclxuaW1wb3J0IHsgRUNsYXNzIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lY2xhc3MuanMnO1xyXG5pbXBvcnQgeyBFRW51bUxpdGVyYWxJbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZWVudW0tbGl0ZXJhbC1pbXBsLmpzJztcclxuaW1wb3J0IHsgRUNsYXNzSW1wbCB9IGZyb20gJy4uL21ldGFtb2RlbC9pbXBsL2VjbGFzcy1pbXBsLmpzJztcclxuaW1wb3J0IHsgRUVudW1JbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZWVudW0taW1wbC5qcyc7XHJcbmltcG9ydCB7IEVDbGFzc2lmaWVyIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lY2xhc3NpZmllci5qcyc7XHJcbmltcG9ydCB7IEVFbnVtIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lZW51bS5qcyc7XHJcbmltcG9ydCB7IEVTdHJ1Y3R1cmFsRmVhdHVyZSB9IGZyb20gJy4uL21ldGFtb2RlbC9hcGkvZXN0cnVjdHVyYWwtZmVhdHVyZS5qcyc7XHJcbmltcG9ydCB7IEVQYWNrYWdlIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lcGFja2FnZS5qcyc7XHJcbmltcG9ydCB7IEVBdHRyaWJ1dGVJbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZWF0dHJpYnV0ZS1pbXBsLmpzJztcclxuaW1wb3J0IHsgRVJlZmVyZW5jZUltcGwgfSBmcm9tICcuLi9tZXRhbW9kZWwvaW1wbC9lcmVmZXJlbmNlLWltcGwuanMnO1xyXG5pbXBvcnQgeyBFQXR0cmlidXRlIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lYXR0cmlidXRlLmpzJztcclxuaW1wb3J0IHsgRU9wZXJhdGlvbiB9IGZyb20gJy4uL21ldGFtb2RlbC9hcGkvZW9wZXJhdGlvbi5qcyc7XHJcbmltcG9ydCB7IEVPcGVyYXRpb25JbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZW9wZXJhdGlvbi1pbXBsLmpzJztcclxuaW1wb3J0IHsgRVBhcmFtZXRlckltcGwgfSBmcm9tICcuLi9tZXRhbW9kZWwvaW1wbC9lcGFyYW1ldGVyLWltcGwuanMnO1xyXG5pbXBvcnQgeyBFUmVmZXJlbmNlIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lcmVmZXJlbmNlLmpzJztcclxuaW1wb3J0IHsgVFV0aWxzIH0gZnJvbSAnLi4vdHV0aWxzLmpzJztcclxuaW1wb3J0IHsgRVBhY2thZ2VJbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZXBhY2thZ2VpbXBsLmpzJztcclxuXHJcbi8qKlxyXG4gKiBQYXJzZXMgRWNvcmUgWE1MIHN0cmluZ3MgaW50byBUTUYgbWV0YW1vZGVsIGluc3RhbmNlcy5cclxuICogVGhpcyBjbGFzcyBoYW5kbGVzIHRoZSBjb3JlIHBhcnNpbmcgbG9naWMgd2l0aG91dCBmaWxlIHN5c3RlbSBkZXBlbmRlbmNpZXMuXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgRWNvcmVTdHJpbmdQYXJzZXIge1xyXG5cclxuICAgIHB1YmxpYyBwYXJzZUZyb21Kc1N0cmluZyhlY29yZUpzb25TdHI6IGFueSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5wYXJzZUZyb21KcyhKU09OLnBhcnNlKGVjb3JlSnNvblN0cikpO1xyXG4gICAgfVxyXG5cclxuICBwdWJsaWMgcGFyc2VGcm9tSnMoZWNvcmVKczogYW55KSB7XHJcbiAgICBjb25zdCBlUGFja2FnZSA9IGVjb3JlSnNbJ2Vjb3JlOkVQYWNrYWdlJ107XHJcblxyXG4gICAgLy9ob2xkcyBhbGwgdHlwZXMgYW5kIGZlYXR1cmVzIGluIGEgbWFwIGZvciByZWZlcmVuY2UgcmVzb2x1dGlvbiAoZS5nLiBhc3NpZ25pbmdcclxuICAgIC8vdHlwZXMgdG8gcmVmZXJlbmNlcyBhbmQgYXR0cmlidXRlcywgZW5mb3JjaW5nIEVPcHBvc2l0ZXMpXHJcbiAgICBjb25zdCB0eXBlc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBFQ2xhc3NpZmllcj4oKTtcclxuICAgIGNvbnN0IGZlYXR1cmVzTWFwID0gbmV3IE1hcDxzdHJpbmcsIEVTdHJ1Y3R1cmFsRmVhdHVyZT4oKTtcclxuXHJcbiAgICAvL2FkZCBwcmltaXRpdmUgdHlwZXNcclxuICAgIGNvbnN0IHByaW1pdGl2ZVR5cGVzID0gVFV0aWxzLlBSSU1JVElWRVM7XHJcbiAgICBmb3IgKGNvbnN0IHR5cGUgb2YgcHJpbWl0aXZlVHlwZXMpIHtcclxuICAgICAgdHlwZXNNYXAuc2V0KCdlY29yZTpFRGF0YVR5cGUgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9lbWYvMjAwMi9FY29yZSMvLycgKyB0eXBlLG5ldyBFRGF0YVR5cGVJbXBsKHVuZGVmaW5lZCwgdHlwZSkpO1xyXG4gICAgfVxyXG4gICAgLy8gZm9yIChjb25zdCBrZXkgb2YgdHlwZXNNYXAua2V5cygpKSB7XHJcbiAgICAvLyAgIGNvbnNvbGUuZXJyb3IoJ0tFWSAnICsga2V5ICsgJyA6ICcgKyB0eXBlb2YgdHlwZXNNYXBba2V5XSk7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgLy9wYXJzZSBhbGwgY2xhc3NpZmllcnMgZmlyc3QsIHNvIHRoYXQgd2UgY2FuIHJlc29sdmUgdGhlbSBsYXRlclxyXG4gICAgdGhpcy5pbnN0YW50aWF0ZUFsbENsYXNzaWZpZXJzQW5kRmVhdHVyZXMoXHJcbiAgICAgIGVQYWNrYWdlLFxyXG4gICAgICB0eXBlc01hcCxcclxuICAgICAgZmVhdHVyZXNNYXAsXHJcbiAgICAgIFtdXHJcbiAgICApO1xyXG5cclxuICAgIC8vcGFyc2UgdGhlIHJvb3QgRVBhY2thZ2UgYW5kIGFsbCBjb250ZW50c1xyXG4gICAgY29uc3QgcGtnUGF0aCA6IGFueVtdID0gW107XHJcbiAgICBjb25zdCByb290UGFja2FnZSA9IHRoaXMucGFyc2VQYWNrYWdlKFxyXG4gICAgICBlUGFja2FnZSxcclxuICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICB0eXBlc01hcCxcclxuICAgICAgZmVhdHVyZXNNYXAsXHJcbiAgICAgIHBrZ1BhdGhcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIHJvb3RQYWNrYWdlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5zdGFudGlhdGVzIGFsbCB0aGUgRUNsYXNzaWZpZXJzLCB3aGljaCBuZWVkIHRvIGV4aXN0IGluLW1lbW9yeSBmb3IgYSBmdWxsXHJcbiAgICogcGFzcyBzbyB0aGF0IGZlYXR1cmVzIGNhbiBiZSBhc3NpZ25lZCB0eXBlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBwa2dKc29uXHJcbiAgICogQHBhcmFtIHR5cGVzTWFwXHJcbiAgICogQHBhcmFtIHBhdGhcclxuICAgKi9cclxuICBwcml2YXRlIGluc3RhbnRpYXRlQWxsQ2xhc3NpZmllcnNBbmRGZWF0dXJlcyhcclxuICAgIHBrZ0pzb246IGFueSxcclxuICAgIHR5cGVzTWFwOiBNYXA8c3RyaW5nLCBFQ2xhc3NpZmllcj4sXHJcbiAgICBmZWF0dXJlc01hcDogTWFwPHN0cmluZywgRVN0cnVjdHVyYWxGZWF0dXJlPixcclxuICAgIHBhdGg6IHN0cmluZ1tdXHJcbiAgKSB7XHJcbiAgICAvL2tlZXBzIHRyYWNrIG9mIHRoZSBwYXRoIHRvIHRoZSBjdXJyZW50IHBhY2thZ2VcclxuICAgIHBhdGgucHVzaChwa2dKc29uWyckJ10ubmFtZSk7XHJcblxyXG4gICAgaWYgKHBrZ0pzb25bJ2VDbGFzc2lmaWVycyddKSB7XHJcbiAgICAgIGZvciAoY29uc3QgY2xhc3NFbnRyeSBvZiBwa2dKc29uWydlQ2xhc3NpZmllcnMnXSkge1xyXG4gICAgICAgIGxldCBlY2xhc3NpZmllcjogRUNsYXNzaWZpZXIgPSBuZXcgRUNsYXNzSW1wbCgpO1xyXG4gICAgICAgIGNvbnN0IGVUeXBlID0gY2xhc3NFbnRyeVsnJCddWyd4c2k6dHlwZSddO1xyXG4gICAgICAgIGlmIChlVHlwZSA9PT0gJ2Vjb3JlOkVFbnVtJykge1xyXG4gICAgICAgICAgZWNsYXNzaWZpZXIgPSBuZXcgRUVudW1JbXBsKCk7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IGxpdGVyYWxFbnRyeSBvZiBjbGFzc0VudHJ5WydlTGl0ZXJhbHMnXSkge1xyXG4gICAgICAgICAgICBjb25zdCBsaXRlcmFsID0gbmV3IEVFbnVtTGl0ZXJhbEltcGwoKTtcclxuICAgICAgICAgICAgaWYgKGxpdGVyYWxFbnRyeVsnJCddWyduYW1lJ10pXHJcbiAgICAgICAgICAgICAgbGl0ZXJhbC5zZXROYW1lKGxpdGVyYWxFbnRyeVsnJCddWyduYW1lJ10pO1xyXG4gICAgICAgICAgICBpZiAobGl0ZXJhbEVudHJ5WyckJ11bJ3ZhbHVlJ10pXHJcbiAgICAgICAgICAgICAgbGl0ZXJhbC5zZXRWYWx1ZShOdW1iZXIucGFyc2VJbnQobGl0ZXJhbEVudHJ5WyckJ11bJ3ZhbHVlJ10pKTtcclxuICAgICAgICAgICAgaWYgKGxpdGVyYWxFbnRyeVsnJCddWydsaXRlcmFsJ10pXHJcbiAgICAgICAgICAgICAgbGl0ZXJhbC5zZXRMaXRlcmFsKGxpdGVyYWxFbnRyeVsnJCddWydsaXRlcmFsJ10pO1xyXG5cclxuICAgICAgICAgICAgLy9UT0RPOiBXb3VsZCBub3QgaGF2ZSB0byBkbyBib3RoIGlmIG1vZGVsIHdhcyBzb3VyY2UgZ2VuZXJhdGVkXHJcbiAgICAgICAgICAgICg8RUVudW0+ZWNsYXNzaWZpZXIpLmFkZExpdGVyYWwobGl0ZXJhbCk7XHJcbiAgICAgICAgICAgIGxpdGVyYWwuc2V0RUVudW0oZWNsYXNzaWZpZXIgYXMgRUVudW0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoZVR5cGUgPT09ICdlY29yZTpFRGF0YVR5cGUnKSB7XHJcbiAgICAgICAgICBlY2xhc3NpZmllciA9IG5ldyBFRGF0YVR5cGVJbXBsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVjbGFzc2lmaWVyLnNldE5hbWUoY2xhc3NFbnRyeVsnJCddWyduYW1lJ10pO1xyXG4gICAgICAgIGlmIChjbGFzc0VudHJ5WyckJ11bJ2Fic3RyYWN0J10pIHtcclxuICAgICAgICAgICg8RUNsYXNzPmVjbGFzc2lmaWVyKS5zZXRBYnN0cmFjdChjbGFzc0VudHJ5WyckJ11bJ2Fic3RyYWN0J10pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2xhc3NFbnRyeVsnJCddWydpbnRlcmZhY2UnXSkge1xyXG4gICAgICAgICAgKDxFQ2xhc3M+ZWNsYXNzaWZpZXIpLnNldEludGVyZmFjZShjbGFzc0VudHJ5WyckJ11bJ2ludGVyZmFjZSddKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZWNsYXNzVXJpID0gdGhpcy5nZXRFQ2xhc3NpZmllclVyaShwYXRoLCBlY2xhc3NpZmllci5nZXROYW1lKCkpO1xyXG4gICAgICAgIHR5cGVzTWFwLnNldChlY2xhc3NVcmksZWNsYXNzaWZpZXIpO1xyXG5cclxuICAgICAgICBpZiAoY2xhc3NFbnRyeVsnZVN0cnVjdHVyYWxGZWF0dXJlcyddKSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IGZlYXR1cmVFbnRyeSBvZiBjbGFzc0VudHJ5WydlU3RydWN0dXJhbEZlYXR1cmVzJ10pIHtcclxuICAgICAgICAgICAgLy9pbnN0YW50aWF0ZSB0aGUgZmVhdHVyZVxyXG4gICAgICAgICAgICBjb25zdCBmcHJvcHMgPSBmZWF0dXJlRW50cnlbJyQnXTtcclxuICAgICAgICAgICAgbGV0IGVmZWF0dXJlOiBFU3RydWN0dXJhbEZlYXR1cmUgfCB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIGlmIChmcHJvcHNbJ3hzaTp0eXBlJ10gPT09ICdlY29yZTpFQXR0cmlidXRlJykge1xyXG4gICAgICAgICAgICAgIGVmZWF0dXJlID0gbmV3IEVBdHRyaWJ1dGVJbXBsKCk7XHJcbiAgICAgICAgICAgICAgaWYgKGZwcm9wcy5pRCkgKDxFQXR0cmlidXRlPmVmZWF0dXJlKS5zZXRJZCh0cnVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChmcHJvcHNbJ3hzaTp0eXBlJ10gPT09ICdlY29yZTpFUmVmZXJlbmNlJykge1xyXG4gICAgICAgICAgICAgIGVmZWF0dXJlID0gbmV3IEVSZWZlcmVuY2VJbXBsKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignVW5rbm93biB0eXBlOiAnICsgZnByb3BzWyd4c2k6ZVR5cGUnXSk7XHJcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coZnByb3BzKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9jcmVhdGUgbWFwIGVudHJ5IGZyb20gdXJpIHRvIHRoZSBmZWF0dXJlXHJcbiAgICAgICAgICAgIGlmKGVmZWF0dXJlKVxyXG4gICAgICAgICAgICAgIGZlYXR1cmVzTWFwLnNldChlY2xhc3NVcmkgKyAnLycgKyBmcHJvcHNbJ25hbWUnXSxlZmVhdHVyZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy9yZWN1cnNlIHN1YmRpcmVjdG9yaWVzXHJcbiAgICBpZiAocGtnSnNvblsnZVN1YnBhY2thZ2VzJ10pIHtcclxuICAgICAgZm9yIChjb25zdCBwYWNrYWdlRW50cnkgb2YgcGtnSnNvblsnZVN1YnBhY2thZ2VzJ10pIHtcclxuICAgICAgICB0aGlzLmluc3RhbnRpYXRlQWxsQ2xhc3NpZmllcnNBbmRGZWF0dXJlcyhcclxuICAgICAgICAgIHBhY2thZ2VFbnRyeSxcclxuICAgICAgICAgIHR5cGVzTWFwLFxyXG4gICAgICAgICAgZmVhdHVyZXNNYXAsXHJcbiAgICAgICAgICBwYXRoXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcGF0aC5wb3AoKTtcclxuICB9XHJcblxyXG4gIC8vYnVpbGRzIHVwIHRoZSBVUkkgYnkgd2hpY2ggRUNsYXNzaWZpZXJzIGFyZSByZWZlcmVuY2VkIChlLmcuIHRvIHR5cGUgZmVhdHVyZXMpXHJcbiAgcHJpdmF0ZSBnZXRFQ2xhc3NpZmllclVyaShwYXRoOiBzdHJpbmdbXSwgY2xhc3NOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgbGV0IHVyaSA9ICcjLy8nO1xyXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHVyaSArPSBwYXRoW2ldICsgJy8nO1xyXG4gICAgfVxyXG4gICAgdXJpICs9IGNsYXNzTmFtZTtcclxuICAgIHJldHVybiB1cmk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZXMgdGhlIHBhY2thZ2UgcmVwcmVzZW50ZWQgYnkgcGtnSnNvbi5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBwa2dKc29uXHJcbiAgICogQHBhcmFtIHBhcmVudFBrZ1xyXG4gICAqIEBwYXJhbSB0eXBlc01hcFxyXG4gICAqIEBwYXJhbSBwYXRoXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXJzZVBhY2thZ2UoXHJcbiAgICBwa2dKc29uOiBhbnksXHJcbiAgICBwYXJlbnRQa2c6IEVQYWNrYWdlIHwgdW5kZWZpbmVkLFxyXG4gICAgdHlwZXNNYXA6IE1hcDxzdHJpbmcsIEVDbGFzc2lmaWVyPixcclxuICAgIGZlYXR1cmVzTWFwOiBNYXA8c3RyaW5nLCBFU3RydWN0dXJhbEZlYXR1cmU+LFxyXG4gICAgcGF0aDogc3RyaW5nW11cclxuICApOiBFUGFja2FnZSB7XHJcbiAgICBjb25zdCB0aGlzUGtnID0gbmV3IEVQYWNrYWdlSW1wbChwa2dKc29uWyckJ10ubmFtZSxwa2dKc29uWyckJ10ubnNVUkkpO1xyXG4gICAgdGhpc1BrZy5zZXROc1ByZWZpeChwa2dKc29uWyckJ10ubnNQcmVmaXgpO1xyXG5cclxuICAgIC8va2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgcGF0aCB0byB0aGUgcGFja2FnZVxyXG4gICAgcGF0aC5wdXNoKHBrZ0pzb25bJyQnXS5uYW1lKTtcclxuICAgIGlmIChwYXJlbnRQa2cpIHtcclxuXHJcbiAgICAgLy9UT0RPOiBTaG91bGQgbm90IGhhdmUgdG8gZG8gYm90aCBvZiB0aGVzZSwgc2hvdWxkIGJlIGludmVyc2VzXHJcbiAgICAgIHBhcmVudFBrZy5nZXRFU3ViUGFja2FnZXMoKS5hZGQodGhpc1BrZyk7XHJcbiAgICAgIHRoaXNQa2cuc2V0RVN1cGVyUGFja2FnZShwYXJlbnRQa2cpO1xyXG4gICAgfVxyXG4gICAgaWYgKHBrZ0pzb25bJ2VDbGFzc2lmaWVycyddKSB7XHJcbiAgICAgIGZvciAoY29uc3QgY2xhc3NFbnRyeSBvZiBwa2dKc29uWydlQ2xhc3NpZmllcnMnXSkge1xyXG4gICAgICAgIGNvbnN0IGVjbGFzc1VyaSA9IHRoaXMuZ2V0RUNsYXNzaWZpZXJVcmkocGF0aCwgY2xhc3NFbnRyeVsnJCddWyduYW1lJ10pO1xyXG4gICAgICAgIGNvbnN0IGVjbGFzczogRUNsYXNzaWZpZXIgPSB0eXBlc01hcC5nZXQoZWNsYXNzVXJpKSBhcyBFQ2xhc3NpZmllcjtcclxuICAgICAgICBpZiAoIWVjbGFzcykge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcignQ09VTEQgTk9UIEZJTkQgRUNMQVNTIElERU5USUZJRUQgQlkgJyArIGVjbGFzc1VyaSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvL1RPRE86IFNob3VsZCBub3QgaGF2ZSB0byBkbyBib3RoIG9mIHRoZXNlLCBzaG91bGQgYmUgaW52ZXJzZXNcclxuICAgICAgICBlY2xhc3Muc2V0RVBhY2thZ2UodGhpc1BrZyk7XHJcbiAgICAgICAgdGhpc1BrZy5nZXRFQ2xhc3NpZmllcnMoKS5hZGQoZWNsYXNzKTtcclxuXHJcbiAgICAgICAgLy9wYXJzZSBvdXQgc3VwZXIgdHlwZXNcclxuICAgICAgICBpZiAoY2xhc3NFbnRyeVsnJCddWydlU3VwZXJUeXBlcyddKSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IHN1cGVyVHlwZSBvZiBjbGFzc0VudHJ5WyckJ11bJ2VTdXBlclR5cGVzJ10uc3BsaXQoJyAnKSkge1xyXG4gICAgICAgICAgICBjb25zdCBzdXBlclR5cGVFQ2xhc3MgPSA8RUNsYXNzPnR5cGVzTWFwLmdldChzdXBlclR5cGUpO1xyXG4gICAgICAgICAgICBpZiAoIXN1cGVyVHlwZUVDbGFzcykge1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0NPVUxEIE5PVCBGSU5EIEVDTEFTUyBJREVOVElGSUVEIEJZICcgKyBzdXBlclR5cGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICg8RUNsYXNzPmVjbGFzcykuZ2V0RVN1cGVyVHlwZXMoKS5hZGQoc3VwZXJUeXBlRUNsYXNzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChlY2xhc3MgaW5zdGFuY2VvZiBFQ2xhc3NJbXBsKSB7XHJcbiAgICAgICAgICAvL3BhcnNlIG91dCBmZWF0dXJlc1xyXG4gICAgICAgICAgdGhpcy5wYXJzZUZlYXR1cmVzKFxyXG4gICAgICAgICAgICBjbGFzc0VudHJ5LFxyXG4gICAgICAgICAgICB0eXBlc01hcCxcclxuICAgICAgICAgICAgZmVhdHVyZXNNYXAsXHJcbiAgICAgICAgICAgIGVjbGFzcyxcclxuICAgICAgICAgICAgZWNsYXNzVXJpXHJcbiAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgIC8vcGFyc2UgRU9wZXJhdGlvbnNcclxuICAgICAgICAgIGlmICgnZU9wZXJhdGlvbnMnIGluIGNsYXNzRW50cnkpIHtcclxuICAgICAgICAgICAgY29uc3QgbmFtZVRvRW9wID0gbmV3IE1hcDxzdHJpbmcsIEVPcGVyYXRpb24+KCk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uRW50cnkgb2YgY2xhc3NFbnRyeVsnZU9wZXJhdGlvbnMnXSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGZwcm9wcyA9IG9wZXJhdGlvbkVudHJ5WyckJ107XHJcbiAgICAgICAgICAgICAgY29uc3QgcHJldkV4aXN0aW5nRW9wID0gbmFtZVRvRW9wLmdldChmcHJvcHMubmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgIGNvbnN0IGVPcGVyYXRpb24gPSBwcmV2RXhpc3RpbmdFb3BcclxuICAgICAgICAgICAgICAgID8gcHJldkV4aXN0aW5nRW9wXHJcbiAgICAgICAgICAgICAgICA6IG5ldyBFT3BlcmF0aW9uSW1wbCgpO1xyXG4gICAgICAgICAgICAgIGlmICghcHJldkV4aXN0aW5nRW9wKSB7XHJcbiAgICAgICAgICAgICAgICBlT3BlcmF0aW9uLnNldE5hbWUoZnByb3BzLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgbmFtZVRvRW9wLnNldChlT3BlcmF0aW9uLmdldE5hbWUoKSwgZU9wZXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICBlY2xhc3MuZ2V0RU9wZXJhdGlvbnMoKS5hZGQoZU9wZXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICBlT3BlcmF0aW9uLnNldEVDb250YWluaW5nQ2xhc3MoZWNsYXNzKTtcclxuICAgICAgICAgICAgICAgIGlmIChmcHJvcHMuZVR5cGUpIGVPcGVyYXRpb24uc2V0RVR5cGUodHlwZXNNYXAuZ2V0KGZwcm9wcy5lVHlwZSkgYXMgRUNsYXNzaWZpZXIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZwcm9wcy51cHBlckJvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgIGVPcGVyYXRpb24uc2V0VXBwZXJCb3VuZChOdW1iZXIoZnByb3BzLnVwcGVyQm91bmQpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgIGlmICgnZVBhcmFtZXRlcnMnIGluIG9wZXJhdGlvbkVudHJ5KSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhcmFtRW50cnkgb2Ygb3BlcmF0aW9uRW50cnlbJ2VQYXJhbWV0ZXJzJ10pIHtcclxuICAgICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHBhcmFtRW50cnkuJC5uYW1lO1xyXG4gICAgICAgICAgICAgICAgICBsZXQgcGFyYW1FeGlzdHMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIGVPcGVyYXRpb24uZ2V0RVBhcmFtZXRlcnMoKSlcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBwLmdldE5hbWUoKSkgcGFyYW1FeGlzdHMgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICBpZiAoIXBhcmFtRXhpc3RzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW0gPSBuZXcgRVBhcmFtZXRlckltcGwoKTtcclxuICAgICAgICAgICAgICAgICAgICBwYXJhbS5zZXROYW1lKHBhcmFtRW50cnkuJC5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1FbnRyeS4kLmVUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBwYXJhbS5zZXRFVHlwZSh0eXBlc01hcC5nZXQocGFyYW1FbnRyeS4kLmVUeXBlKSBhcyBFQ2xhc3NpZmllcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbUVudHJ5LiQudXBwZXJCb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgcGFyYW0uc2V0VXBwZXJCb3VuZChOdW1iZXIocGFyYW1FbnRyeS4kLnVwcGVyQm91bmQpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiBXb3VsZCBub3QgaGF2ZSB0byBkbyBib3RoIGlmIG1vZGVsIHdhcyBzb3VyY2UgZ2VuZXJhdGVkXHJcbiAgICAgICAgICAgICAgICAgICAgZU9wZXJhdGlvbi5nZXRFUGFyYW1ldGVycygpLmFkZChwYXJhbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFyYW0uc2V0RU9wZXJhdGlvbihlT3BlcmF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vcmVjdXJzZSBzdWItcGFja2FnZXNcclxuICAgIGlmIChwa2dKc29uWydlU3VicGFja2FnZXMnXSkge1xyXG4gICAgICBmb3IgKGNvbnN0IHBhY2thZ2VFbnRyeSBvZiBwa2dKc29uWydlU3VicGFja2FnZXMnXSkge1xyXG4gICAgICAgIHRoaXMucGFyc2VQYWNrYWdlKHBhY2thZ2VFbnRyeSwgdGhpc1BrZywgdHlwZXNNYXAsIGZlYXR1cmVzTWFwLCBwYXRoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHBhdGgucG9wKCk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXNQa2c7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZXMgZVN0cnVjdHVyYWxGZWF0dXJlcyBlbGVtZW50cyBmcm9tIEVjb3JlIFhNSSBlbGVtZW50LlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGNsYXNzRW50cnlcclxuICAgKiBAcGFyYW0gdHlwZXNNYXBcclxuICAgKiBAcGFyYW0gZmVhdHVyZXNNYXBcclxuICAgKiBAcGFyYW0gZWNsYXNzXHJcbiAgICogQHBhcmFtIGVjbGFzc1VyaVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VGZWF0dXJlcyhcclxuICAgIGNsYXNzRW50cnk6IGFueSxcclxuICAgIHR5cGVzTWFwOiBNYXA8c3RyaW5nLCBFQ2xhc3NpZmllcj4sXHJcbiAgICBmZWF0dXJlc01hcDogTWFwPHN0cmluZywgRVN0cnVjdHVyYWxGZWF0dXJlPixcclxuICAgIGVjbGFzczogRUNsYXNzLFxyXG4gICAgZWNsYXNzVXJpOiBzdHJpbmdcclxuICApIHtcclxuICAgIGlmICgnZVN0cnVjdHVyYWxGZWF0dXJlcycgaW4gY2xhc3NFbnRyeSkge1xyXG4gICAgICBmb3IgKGNvbnN0IGZlYXR1cmVFbnRyeSBvZiBjbGFzc0VudHJ5WydlU3RydWN0dXJhbEZlYXR1cmVzJ10pIHtcclxuICAgICAgICBjb25zdCBmcHJvcHMgPSBmZWF0dXJlRW50cnlbJyQnXTtcclxuICAgICAgICBjb25zdCBlZmVhdHVyZTogRVN0cnVjdHVyYWxGZWF0dXJlID1cclxuICAgICAgICAgIGZlYXR1cmVzTWFwLmdldChlY2xhc3NVcmkgKyAnLycgKyBmcHJvcHNbJ25hbWUnXSkgYXMgRVN0cnVjdHVyYWxGZWF0dXJlO1xyXG4gICAgICAgIGlmIChlZmVhdHVyZSkge1xyXG4gICAgICAgICAgZWZlYXR1cmUuc2V0TmFtZShmcHJvcHNbJ25hbWUnXSk7XHJcbiAgICAgICAgICBjb25zdCB0eXBlOiBFQ2xhc3NpZmllciA9IHR5cGVzTWFwLmdldChmcHJvcHNbJ2VUeXBlJ10pIGFzIEVDbGFzc2lmaWVyO1xyXG4gICAgICAgICAgaWYgKCF0eXBlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICAgICAgICAgJ1dBUk5JTkc6IENPVUxEIE5PVCBMT0NBVEUgVFlQRSBGT1IgJyArXHJcbiAgICAgICAgICAgICAgICBmcHJvcHMubmFtZSArXHJcbiAgICAgICAgICAgICAgICAnIHdpdGggZXR5cGUgJyArXHJcbiAgICAgICAgICAgICAgICBmcHJvcHMuZVR5cGVcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlZmVhdHVyZS5zZXRFVHlwZSh0eXBlKTtcclxuICAgICAgICAgIGlmIChmcHJvcHNbJ3VwcGVyQm91bmQnXSkge1xyXG4gICAgICAgICAgICBlZmVhdHVyZS5zZXRVcHBlckJvdW5kKE51bWJlcihmcHJvcHNbJ3VwcGVyQm91bmQnXSkpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZWZlYXR1cmUuc2V0VXBwZXJCb3VuZCgxKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvL3RyYW5zaWVudCxjaGFuZ2VhYmxlLHZvbGF0aWxlXHJcbiAgICAgICAgICBlZmVhdHVyZS5zZXRWb2xhdGlsZShcclxuICAgICAgICAgICAgZnByb3BzLnZvbGF0aWxlID09IG51bGwgPyBmYWxzZSA6IEpTT04ucGFyc2UoZnByb3BzLnZvbGF0aWxlKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGVmZWF0dXJlLnNldENoYW5nZWFibGUoXHJcbiAgICAgICAgICAgIGZwcm9wcy5jaGFuZ2VhYmxlID09IG51bGwgPyB0cnVlIDogSlNPTi5wYXJzZShmcHJvcHMuY2hhbmdlYWJsZSlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBlZmVhdHVyZS5zZXRUcmFuc2llbnQoXHJcbiAgICAgICAgICAgIGZwcm9wcy50cmFuc2llbnQgPT0gbnVsbCA/IGZhbHNlIDogSlNPTi5wYXJzZShmcHJvcHMudHJhbnNpZW50KVxyXG4gICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAvL2VvcHBvc2l0ZXMgYW5kIGNvbnRhaW5tZW50XHJcbiAgICAgICAgICBpZiAoZWZlYXR1cmUgaW5zdGFuY2VvZiBFUmVmZXJlbmNlSW1wbCkge1xyXG4gICAgICAgICAgICBpZiAoZnByb3BzWydlT3Bwb3NpdGUnXSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGVvcHAgPSA8RVJlZmVyZW5jZT5mZWF0dXJlc01hcC5nZXQoZnByb3BzWydlT3Bwb3NpdGUnXSk7XHJcbiAgICAgICAgICAgICAgZWZlYXR1cmUuc2V0RU9wcG9zaXRlKGVvcHApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVmZWF0dXJlLnNldENvbnRhaW5tZW50KFxyXG4gICAgICAgICAgICAgIGZwcm9wcy5jb250YWlubWVudCA9PSBudWxsXHJcbiAgICAgICAgICAgICAgICA/IGZhbHNlXHJcbiAgICAgICAgICAgICAgICA6IEpTT04ucGFyc2UoZnByb3BzLmNvbnRhaW5tZW50KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIC8vVE9ETzogVGhpcyBzaG91bGQgYmUgaGFuZGxlZCBhdXRvbWF0aWNhbGx5IGJlIGVpbnZlcnNlIGVuZm9yY2VtZW50IChpZiB0bWYgd2VyZSBzb3VyY2UtZ2VuZXJhdGVkKVxyXG4gICAgICAgICAgZWNsYXNzLmdldEVTdHJ1Y3R1cmFsRmVhdHVyZXMoKS5hZGQoZWZlYXR1cmUpO1xyXG4gICAgICAgICAgZWZlYXR1cmUuc2V0RUNvbnRhaW5pbmdDbGFzcyhlY2xhc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufSJdfQ==