UNPKG

@tripsnek/tmf

Version:

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

476 lines 60.5 kB
import { TGenUtils as DU } from './tgen-utils.js';
import { EAttributeImpl } from '../metamodel/impl/eattribute-impl.js';
import { EClassImpl } from '../metamodel/impl/eclass-impl.js';
import { EReferenceImpl } from '../metamodel/impl/ereference-impl.js';
import { EEnumImpl } from '../metamodel/impl/eenum-impl.js';
import { EDataTypeImpl } from '../metamodel/impl/edata-type-impl.js';
/**
 * Responsible for generating the interface and implementation of an
 * EPackage source file, which provides static access to all the elements
 * of a package in a TMF model.
 *
 * Note that generation of several swathes of the package content
 * are ganged together into a single pass over the model. This owes
 * to the fact that sufficient logic is shared across their computations, largely
 * related to the tracking of IDs for individual elements, that it would
 * be difficult to separate them out.
 */
export class TGeneratorPackage {
    rootPackage;
    generatePackageContents(pkg) {
        const className = DU.genPackageClassName(pkg);
        this.rootPackage = pkg;
        while (this.rootPackage.getESuperPackage())
            this.rootPackage = this.rootPackage.getESuperPackage();
        //track package dependencies, import them at the end
        const pkgToImport = new Set();
        //static library of all package contents
        let literalsContent = `
  /** Provides static access to EClass and EStructuralFeature instances */
  public static Literals = class {`;
        let fieldDeclarationsContent = '';
        let gettersContent = '';
        //insert create/initialize methods
        let createContent = `  public createPackageContents(): void {
    if (this.isCreated) return;
    this.isCreated = true;`;
        let initContent = `  public initializePackageContents(): void {
    if (this.isInitialized) return;
    this.isInitialized = true;

    //reusable handle for eoperations, used for adding parameters
    let op: EOperation;`;
        let idFieldsContent = '';
        //iterate over all classes and features, create and initialize them AND create getters using the feature IDs
        let ecIdCounter = 0;
        //sort eclassifiers in such a way that base types are guaranteed to precede derived types so
        //that we can reference feature IDs in correct order
        const sortedClassifiers = this.sortClassifiersWithBaseTypesFirst(pkg);
        //NOTE: This is the 'single-pass' loop for generating IDs, declaring element fields
        //and initializing each and hooking up their references where appropriate. The
        //content for all of these is then integrated into the full template of the package
        //file in the return statement for this method
        for (const eclassifier of sortedClassifiers) {
            const eclassIdField = DU.genClassIdFieldName(eclassifier);
            idFieldsContent += `
  public static ${eclassIdField} = ${ecIdCounter};`;
            ecIdCounter++;
            //add eclassifier field
            let type = 'EClass';
            if (eclassifier instanceof EEnumImpl)
                type = 'EEnum';
            else if (eclassifier instanceof EDataTypeImpl)
                type = 'EDataType';
            const eclassFieldName = DU.uncapitalize(eclassifier.getName()) + type;
            fieldDeclarationsContent += `
  private ${eclassFieldName}!: ${type};`;
            //add eclass getter
            const eclassGetter = DU.genEclassGetterName(eclassifier);
            gettersContent += `
  public ${eclassGetter}(): ${type} {
    return this.${eclassFieldName};
  }`;
            //add creation
            createContent += `
    this.${eclassFieldName} = this.create${type}(${className}.${eclassIdField});`;
            //add Literals entry for EClassifier
            literalsContent += `
    static ${eclassIdField}: ${type} = ${className}._eINSTANCE.${DU.genEclassGetterName(eclassifier)}();`;
            //add class initialization
            if (eclassifier instanceof EClassImpl) {
                const eclass = eclassifier;
                for (const superType of eclassifier.getESuperTypes()) {
                    const pkgRef = DU.getReferenceToPackageInstance(superType, eclassifier, pkgToImport);
                    initContent += `
    this.${eclassFieldName}.getESuperTypes().add(${pkgRef}.${DU.genEclassGetterName(superType)}());`;
                }
                initContent += `
    this.init${type}(
      this.${eclassFieldName},
      '${eclassifier.getName()}',
      ${eclassifier.isAbstract()},
      ${eclassifier.isInterface()},
      true
    );`;
            }
            else {
                initContent += `
    this.init${type}(
      this.${eclassFieldName}, '${eclassifier.getName()}');`;
                if (eclassifier instanceof EEnumImpl) {
                    let literalInd = 0;
                    for (const literal of eclassifier.getELiterals()) {
                        const litRef = eclassifier.getName() + '.' + literal.getName();
                        initContent += `
    this.addEEnumLiteral(this.${eclassFieldName}, '${literal.getName()}', ${literalInd});`;
                        literalInd++;
                    }
                }
            }
            //process references and attributes
            if (eclassifier instanceof EClassImpl) {
                //find super type
                const superType = eclassifier.getESuperTypes().size() > 0
                    ? eclassifier.getESuperTypes().get(0)
                    : null;
                //write out feature count field (will be the starting point for ID'ing new fields on this eclass)
                const featureCountField = DU.genFeatureCountFieldName(eclassifier);
                const superTypeFeatureCount = superType ? superType.getEAllStructuralFeatures().size() : 0;
                //Eliminating references to super types in static initializers, since they could be in other packages (circular import)
                // const superTypeCountField = superType
                //   ? DU.genPackageClassName(superType.getEPackage()) +
                //     '.' +
                //     DU.genFeatureCountFieldName(superType) +
                //     ' + '
                //   : '';
                //       if (superTypeCountField) {
                //         idFieldsContent += `
                // public static ${featureCountField} =
                //   ${superTypeCountField}${eclassifier.getEStructuralFeatures().size()};`;
                //       } else {
                //         idFieldsContent += `
                // public static ${featureCountField} = ${eclassifier.getEStructuralFeatures().size()};`;
                //       }
                //this is the replacement - just a straight count of all features, shoudl be same
                idFieldsContent += `
  public static ${featureCountField} = ${eclassifier.getEAllStructuralFeatures().size()};`;
                //keeps track of the feature's index in it's eClass (used for feature getter)
                let thisClassFeatureIndex = 0;
                for (const feature of eclassifier.getEStructuralFeatures()) {
                    const featureIdField = DU.genFeatureIdFieldName(feature);
                    //Eliminating references to super types in static initializers, since they could be in other packages (circular import)          
                    //         if (superTypeCountField) {
                    //           idFieldsContent += `
                    // public static ${featureIdField} = ${superTypeCountField}${thisClassFeatureIndex};`;
                    //         } else {
                    //           idFieldsContent += `
                    // public static ${featureIdField} = ${thisClassFeatureIndex};`;
                    //         }
                    //this is the replacement - just add to the super type feature count
                    idFieldsContent += `
  public static ${featureIdField} = ${superTypeFeatureCount + thisClassFeatureIndex};`;
                    const featureType = feature instanceof EAttributeImpl ? 'EAttribute' : 'EReference';
                    literalsContent += `
    static ${featureIdField}: ${featureType} =
      ${className}._eINSTANCE.get${DU.capitalize(eclassifier.getName())}_${DU.capitalize(feature.getName())}();`;
                    //create features
                    createContent += `
    this.create${featureType}(
      this.${eclassFieldName},
      ${className}.${featureIdField}
    );`;
                    const featureGetterName = DU.genFeatureGetterName(feature);
                    //add feature getter
                    gettersContent += `
  public ${featureGetterName}(): ${featureType} {
    return <${featureType}>this.${eclassFieldName}.getEStructuralFeatures().get(${thisClassFeatureIndex});
  }`;
                    //the getter for the feature's type (Eclassifier instance)
                    const featureTypeGetter = this.getterForEType(feature.getEType(), eclassifier, pkgToImport, pkg);
                    //initializers
                    initContent += `
    this.init${featureType}(
      this.${featureGetterName}()`;
                    if (feature instanceof EAttributeImpl) {
                        initContent += `,
      ${featureTypeGetter},
      '${feature.getName()}',
      ${feature.getDefaultValueLiteral() ? feature.getDefaultValueLiteral() : `''`},
      ${feature.getLowerBound()},
      ${feature.getUpperBound()},
      '',
      ${feature.isTransient() ?? false},
      ${feature.isVolatile() ?? false},
      ${feature.isChangeable() ?? true},
      true,
      ${feature.isId() ?? false},
      false,
      false,
      false`;
                    }
                    else if (feature instanceof EReferenceImpl) {
                        const pkgRef = DU.getReferenceToPackageInstance(feature.getEType(), eclassifier, pkgToImport);
                        let eopposite = 'undefined';
                        if (feature.getEOpposite()) {
                            eopposite = `${pkgRef}.${DU.genFeatureGetterName(feature.getEOpposite())}()`;
                        }
                        initContent += `,
      ${featureTypeGetter},
      ${eopposite},
      '${feature.getName()}',
      '',
      ${feature.getLowerBound()},
      ${feature.getUpperBound()},
      '',
      ${feature.isTransient() ?? false},
      ${feature.isVolatile() ?? false},
      ${feature.isChangeable() ?? false},
      ${feature.isContainment() ?? false},
      false,
      true,
      false,
      false,
      false`;
                    }
                    initContent += `
    );`;
                    thisClassFeatureIndex++;
                }
                //logic for creating and initializing EOperations
                let eopIndex = 0;
                for (const eop of eclassifier.getEOperations()) {
                    const eopIdField = DU.genOperationIdFieldName(eop);
                    //add ID content
                    idFieldsContent += `
  public static ${eopIdField} = ${eopIndex};`;
                    createContent += `
    this.createEOperation(this.${eclassFieldName}, ${className}.${eopIdField});`;
                    const featureGetterName = DU.genOperationGetterName(eop);
                    gettersContent += `
  public ${featureGetterName}(): EOperation {
    return this.${eclassFieldName}.getEOperations().get(${eopIndex});
  }`;
                    initContent += `
    op = this.initEOperation(
      this.${featureGetterName}(),
      ${this.getterForEType(eop.getEType(), eclassifier, pkgToImport, pkg)},
      '${eop.getName()}',
      0,
      ${eop.isMany() ? -1 : 1},
      true,
      true
    );`;
                    for (const p of eop.getEParameters()) {
                        //TODO: Create parameters and add them to EOphere
                        initContent += `
    this.createEParameter(
      op,
      '${p.getName()}',
      ${p.isMany() ? -1 : 1},
       ${this.getterForEType(p.getEType(), eclassifier, pkgToImport, pkg)}
    );`;
                    }
                    eopIndex++;
                }
            }
        }
        createContent += `
  }`;
        initContent += `
  }`;
        literalsContent += `
  };`;
        //EcorePackage cannot extend EPackageImpl, as it it would create circular reference
        const toExtend = pkg.getName().toLowerCase() === 'ecore' ? 'EPackage' : 'EPackageImpl';
        let subPkgSetters = '';
        // for(const subPkg of pkg.getESubPackages()){
        //   if(!pkgToImport.has(subPkg)){
        //     pkgToImport.add(subPkg);
        //   }
        //   subPkgSetters += `
        // ${DU.genPackageClassName(subPkg)}.eINSTANCE.setESuperPackage(the${className})`;
        // }
        return `${this.generateImports(pkgToImport, pkg)}
export class ${className} extends ${toExtend} {${idFieldsContent}

  /** Singleton */
  public static _eINSTANCE: ${className} = ${className}.init();

  //if the singleton is initialized
  private static isInited = false;

  static eNS_URI =
    '${pkg.getNsURI()}';
  static eNAME = '${pkg.getName()}';
  static eNS_PREFIX = '${pkg.getNsPrefix()}';
${literalsContent}

  //flags that keep track of whether package is initialized
  private isCreated = false;
  private isInitialized = false;
${fieldDeclarationsContent}

  //causes EPackage.Registry registration event
  //hard-coded URI, since referring to the static eNS_URI field in constructor can cause issues
  constructor() {
    super(
      '${pkg.getName()}',
      '${pkg.getNsURI()}',
      '${pkg.getNsPrefix()}'
    );
  }

  /**
   * Invoked once. Initializes the Singleton.
   *
   * NOTE: Lots of differences here with the EMF version, which interacts with the package Registry,
   * other packages from the same model to register interdependencies, and freezes the package meta-data.
   */
  private static init(): ${className} {
    if (${className}.isInited) return this._eINSTANCE;
    // Obtain or create and register package
    const the${className} = new ${className}();
    //this is necessary specifically for EcorePackage generation, which needs to refer to itself
    this._eINSTANCE = the${className};
    ${className}.isInited = true;
${subPkgSetters}    

    // Create package meta-data objects
    the${className}.createPackageContents();

    // Initialize created meta-data
    // the${className}.initializePackageContents();
    return this._eINSTANCE;
  }

  static get eINSTANCE(): ${className}{
    this.ensureInitialized();
    return this._eINSTANCE;
  }  

  /**
   * Ensures this package and it's depdendencies are fully initialized and registered with TJson
   */
  private static ensureInitialized(): void {
    const packageName = '${pkg.getName()}';

    if (PackageRegistry.isInitialized(packageName)) {
      return;
    }

    // Initialize this package's contents
    const pkg = this._eINSTANCE;
    pkg.initializePackageContents();

    // Mark as initialized first to prevent cycles
    PackageRegistry.markInitialized(packageName);

    // Register with TJson
    PackageRegistry.registerWithTJson(packageName, pkg);
  }

  /**
   * Called by the factory to register itself with this package
   */
  static registerFactory(factory: EFactory): void {
    this._eINSTANCE.setEFactoryInstance(factory);
  }  

  //this used to be direct lazy retrieval of the
  //factory instance from the corresponding .ts factory file, but
  //that was eliminated to avoid circular imports
  public override getEFactoryInstance(): EFactory {
    if (!this._eFactoryInstance) {
      // Try to get factory from registry
      const factory = PackageRegistry.getFactory('${pkg.getName()}');
      if (factory) {
        this.setEFactoryInstance(factory);
      }
    }  
    return this._eFactoryInstance;
  }

  /**
   * This will be invoked by the Factory when it is initialized, any invocations
   * afterwards will have no effect.
   */
  public override setEFactoryInstance(factoryInst: EFactory): void {
    if (!this._eFactoryInstance) this._eFactoryInstance = factoryInst;
  }
${gettersContent}

${createContent}

${initContent}
}
`;
    }
    /**
     * User for generating 'get' on the EType for a feature or operation.
     *
     * @param etype
     * @param owningEClass
     * @param pkgToImport
     * @param pkg
     * @returns
     */
    getterForEType(etype, owningEClass, pkgToImport, pkg) {
        let featureTypeGetter = undefined;
        if (etype) {
            const pkgRef = DU.getReferenceToPackageInstance(etype, owningEClass, pkgToImport);
            if (etype instanceof EEnumImpl) {
                featureTypeGetter = `${pkgRef}.get${etype.getName()}()`;
            }
            else if (etype instanceof EClassImpl) {
                const pkgRef = DU.getReferenceToPackageInstance(etype, owningEClass, pkgToImport);
                if (etype) {
                    featureTypeGetter = `${pkgRef}.${DU.genEclassGetterName(etype)}()`;
                }
            }
            else {
                let ecorePkgGetter = 'this.getEcorePackage()';
                if (pkg.getName().toLowerCase() === 'ecore')
                    ecorePkgGetter = 'this';
                featureTypeGetter = ecorePkgGetter + '.get' + etype.getName() + '()';
            }
        }
        return featureTypeGetter;
    }
    generateImports(pkgToImport, pkg) {
        //build path to root package initializer
        const pathToRoot = DU.getPathToRoot(pkg);
        let imports = `${DU.generateImportStatementsForExternalPackages(pkgToImport, pkg, './')}
import { EClass } from '@tripsnek/tmf';
import { EEnum } from '@tripsnek/tmf';
import { PackageRegistry } from '${pathToRoot}package-registry.js';
import { EPackageImpl } from '@tripsnek/tmf';
import { EAttribute } from '@tripsnek/tmf';
import { EFactory } from '@tripsnek/tmf';
import { EReference } from '@tripsnek/tmf';
import { EOperation } from '@tripsnek/tmf';`;
        //we use relative imports for the EcorePackage, since it is in the same lib as the metamodel
        if (pkg.getName().toLowerCase() === 'ecore') {
            imports = `${DU.generateImportStatementsForExternalPackages(pkgToImport, pkg, '')}
import { EPackage } from './epackage.js';
import { EDataType } from './edata-type.js';
import { EClass } from './eclass.js';
import { EReference } from './ereference.js';
import { EAttribute } from './eattribute.js';
import { EFactory } from './efactory.js';`;
        }
        return imports;
    }
    /**
     * Sort eclassifiers in such a way that base types are guaranteed to precede derived types so
     * that we can reference feature IDs in correct order
     */
    sortClassifiersWithBaseTypesFirst(pkg) {
        const sortedClassifiers = new Array();
        for (const eclassifier of pkg.getEClassifiers()) {
            if (eclassifier instanceof EClassImpl) {
                const eclass = eclassifier;
                if (sortedClassifiers.indexOf(eclass) === -1) {
                    //insert eclass after it's last super type
                    let idxLastSuperType = -1;
                    for (const st of eclass.getEAllSuperTypes()) {
                        if (sortedClassifiers.indexOf(st) > -1) {
                            const index = sortedClassifiers.indexOf(st);
                            if (index > idxLastSuperType)
                                idxLastSuperType = index;
                        }
                    }
                    if (idxLastSuperType >= 0)
                        sortedClassifiers.splice(idxLastSuperType + 1, 0, eclass);
                    else
                        sortedClassifiers.splice(0, 0, eclass);
                }
            }
            //enums and other EClassifiers can go wherever
            else {
                sortedClassifiers.push(eclassifier);
            }
        }
        return sortedClassifiers;
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGdlbmVyYXRvci1wYWNrYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9zb3VyY2UtZ2VuZXJhdG9ycy90Z2VuZXJhdG9yLXBhY2thZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLFNBQVMsSUFBSSxFQUFFLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDNUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRXJFOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBRTNCLFdBQVcsQ0FBYTtJQUVsQix1QkFBdUIsQ0FBQyxHQUFhO1FBQzFDLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztRQUN2QixPQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUU7WUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUVsRyxvREFBb0Q7UUFDcEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQVksQ0FBQztRQUV4Qyx3Q0FBd0M7UUFDeEMsSUFBSSxlQUFlLEdBQUc7O21DQUVTLENBQUM7UUFFaEMsSUFBSSx3QkFBd0IsR0FBRyxFQUFFLENBQUM7UUFDbEMsSUFBSSxjQUFjLEdBQUcsRUFBRSxDQUFDO1FBRXhCLGtDQUFrQztRQUNsQyxJQUFJLGFBQWEsR0FBRzs7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SUFBSSxNQUFNLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDO3dCQUM1QyxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDOzRCQUN2QyxNQUFNLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7NEJBQzVDLElBQUksS0FBSyxHQUFHLGdCQUFnQjtnQ0FBRSxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7d0JBQ3pELENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxJQUFJLGdCQUFnQixJQUFJLENBQUM7d0JBQ3ZCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDOzt3QkFDdkQsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzlDLENBQUM7WUFDSCxDQUFDO1lBRUQsOENBQThDO2lCQUN6QyxDQUFDO2dCQUNKLGlCQUFpQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN0QyxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRVBhY2thZ2UgfSBmcm9tICcuLi9tZXRhbW9kZWwvYXBpL2VwYWNrYWdlLmpzJztcclxuaW1wb3J0IHsgRUVudW0gfSBmcm9tICcuLi9tZXRhbW9kZWwvYXBpL2VlbnVtLmpzJztcclxuaW1wb3J0IHsgRUNsYXNzIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2FwaS9lY2xhc3MuanMnO1xyXG5pbXBvcnQgeyBFQ2xhc3NpZmllciB9IGZyb20gJy4uL21ldGFtb2RlbC9hcGkvZWNsYXNzaWZpZXIuanMnO1xyXG5pbXBvcnQgeyBUR2VuVXRpbHMgYXMgRFUgfSBmcm9tICcuL3RnZW4tdXRpbHMuanMnO1xyXG5pbXBvcnQgeyBFQXR0cmlidXRlSW1wbCB9IGZyb20gJy4uL21ldGFtb2RlbC9pbXBsL2VhdHRyaWJ1dGUtaW1wbC5qcyc7XHJcbmltcG9ydCB7IEVDbGFzc0ltcGwgfSBmcm9tICcuLi9tZXRhbW9kZWwvaW1wbC9lY2xhc3MtaW1wbC5qcyc7XHJcbmltcG9ydCB7IEVSZWZlcmVuY2VJbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZXJlZmVyZW5jZS1pbXBsLmpzJztcclxuaW1wb3J0IHsgRUVudW1JbXBsIH0gZnJvbSAnLi4vbWV0YW1vZGVsL2ltcGwvZWVudW0taW1wbC5qcyc7XHJcbmltcG9ydCB7IEVEYXRhVHlwZUltcGwgfSBmcm9tICcuLi9tZXRhbW9kZWwvaW1wbC9lZGF0YS10eXBlLWltcGwuanMnO1xyXG5cclxuLyoqXHJcbiAqIFJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBpbnRlcmZhY2UgYW5kIGltcGxlbWVudGF0aW9uIG9mIGFuXHJcbiAqIEVQYWNrYWdlIHNvdXJjZSBmaWxlLCB3aGljaCBwcm92aWRlcyBzdGF0aWMgYWNjZXNzIHRvIGFsbCB0aGUgZWxlbWVudHNcclxuICogb2YgYSBwYWNrYWdlIGluIGEgVE1GIG1vZGVsLlxyXG4gKlxyXG4gKiBOb3RlIHRoYXQgZ2VuZXJhdGlvbiBvZiBzZXZlcmFsIHN3YXRoZXMgb2YgdGhlIHBhY2thZ2UgY29udGVudFxyXG4gKiBhcmUgZ2FuZ2VkIHRvZ2V0aGVyIGludG8gYSBzaW5nbGUgcGFzcyBvdmVyIHRoZSBtb2RlbC4gVGhpcyBvd2VzXHJcbiAqIHRvIHRoZSBmYWN0IHRoYXQgc3VmZmljaWVudCBsb2dpYyBpcyBzaGFyZWQgYWNyb3NzIHRoZWlyIGNvbXB1dGF0aW9ucywgbGFyZ2VseVxyXG4gKiByZWxhdGVkIHRvIHRoZSB0cmFja2luZyBvZiBJRHMgZm9yIGluZGl2aWR1YWwgZWxlbWVudHMsIHRoYXQgaXQgd291bGRcclxuICogYmUgZGlmZmljdWx0IHRvIHNlcGFyYXRlIHRoZW0gb3V0LlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFRHZW5lcmF0b3JQYWNrYWdlIHtcclxuXHJcbiAgIHJvb3RQYWNrYWdlISA6IEVQYWNrYWdlO1xyXG5cclxuICBwdWJsaWMgZ2VuZXJhdGVQYWNrYWdlQ29udGVudHMocGtnOiBFUGFja2FnZSk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBjbGFzc05hbWUgPSBEVS5nZW5QYWNrYWdlQ2xhc3NOYW1lKHBrZyk7XHJcbiAgICB0aGlzLnJvb3RQYWNrYWdlID0gcGtnO1xyXG4gICAgd2hpbGUodGhpcy5yb290UGFja2FnZS5nZXRFU3VwZXJQYWNrYWdlKCkpIHRoaXMucm9vdFBhY2thZ2UgPSB0aGlzLnJvb3RQYWNrYWdlLmdldEVTdXBlclBhY2thZ2UoKTtcclxuXHJcbiAgICAvL3RyYWNrIHBhY2thZ2UgZGVwZW5kZW5jaWVzLCBpbXBvcnQgdGhlbSBhdCB0aGUgZW5kXHJcbiAgICBjb25zdCBwa2dUb0ltcG9ydCA9IG5ldyBTZXQ8RVBhY2thZ2U+KCk7XHJcblxyXG4gICAgLy9zdGF0aWMgbGlicmFyeSBvZiBhbGwgcGFja2FnZSBjb250ZW50c1xyXG4gICAgbGV0IGxpdGVyYWxzQ29udGVudCA9IGBcclxuICAvKiogUHJvdmlkZXMgc3RhdGljIGFjY2VzcyB0byBFQ2xhc3MgYW5kIEVTdHJ1Y3R1cmFsRmVhdHVyZSBpbnN0YW5jZXMgKi9cclxuICBwdWJsaWMgc3RhdGljIExpdGVyYWxzID0gY2xhc3Mge2A7XHJcblxyXG4gICAgbGV0IGZpZWxkRGVjbGFyYXRpb25zQ29udGVudCA9ICcnO1xyXG4gICAgbGV0IGdldHRlcnNDb250ZW50ID0gJyc7XHJcblxyXG4gICAgLy9pbnNlcnQgY3JlYXRlL2luaXRpYWxpemUgbWV0aG9kc1xyXG4gICAgbGV0IGNyZWF0ZUNvbnRlbnQgPSBgICBwdWJsaWMgY3JlYXRlUGFja2FnZUNvbnRlbnRzKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXNDcmVhdGVkKSByZXR1cm47XHJcbiAgICB0aGlzLmlzQ3JlYXRlZCA9IHRydWU7YDtcclxuXHJcbiAgICBsZXQgaW5pdENvbnRlbnQgPSBgICBwdWJsaWMgaW5pdGlhbGl6ZVBhY2thZ2VDb250ZW50cygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHJldHVybjtcclxuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XHJcblxyXG4gICAgLy9yZXVzYWJsZSBoYW5kbGUgZm9yIGVvcGVyYXRpb25zLCB1c2VkIGZvciBhZGRpbmcgcGFyYW1ldGVyc1xyXG4gICAgbGV0IG9wOiBFT3BlcmF0aW9uO2A7XHJcblxyXG4gICAgbGV0IGlkRmllbGRzQ29udGVudCA9ICcnO1xyXG5cclxuICAgIC8vaXRlcmF0ZSBvdmVyIGFsbCBjbGFzc2VzIGFuZCBmZWF0dXJlcywgY3JlYXRlIGFuZCBpbml0aWFsaXplIHRoZW0gQU5EIGNyZWF0ZSBnZXR0ZXJzIHVzaW5nIHRoZSBmZWF0dXJlIElEc1xyXG4gICAgbGV0IGVjSWRDb3VudGVyID0gMDtcclxuXHJcbiAgICAvL3NvcnQgZWNsYXNzaWZpZXJzIGluIHN1Y2ggYSB3YXkgdGhhdCBiYXNlIHR5cGVzIGFyZSBndWFyYW50ZWVkIHRvIHByZWNlZGUgZGVyaXZlZCB0eXBlcyBzb1xyXG4gICAgLy90aGF0IHdlIGNhbiByZWZlcmVuY2UgZmVhdHVyZSBJRHMgaW4gY29ycmVjdCBvcmRlclxyXG4gICAgY29uc3Qgc29ydGVkQ2xhc3NpZmllcnMgPSB0aGlzLnNvcnRDbGFzc2lmaWVyc1dpdGhCYXNlVHlwZXNGaXJzdChwa2cpO1xyXG5cclxuICAgIC8vTk9URTogVGhpcyBpcyB0aGUgJ3NpbmdsZS1wYXNzJyBsb29wIGZvciBnZW5lcmF0aW5nIElEcywgZGVjbGFyaW5nIGVsZW1lbnQgZmllbGRzXHJcbiAgICAvL2FuZCBpbml0aWFsaXppbmcgZWFjaCBhbmQgaG9va2luZyB1cCB0aGVpciByZWZlcmVuY2VzIHdoZXJlIGFwcHJvcHJpYXRlLiBUaGVcclxuICAgIC8vY29udGVudCBmb3IgYWxsIG9mIHRoZXNlIGlzIHRoZW4gaW50ZWdyYXRlZCBpbnRvIHRoZSBmdWxsIHRlbXBsYXRlIG9mIHRoZSBwYWNrYWdlXHJcbiAgICAvL2ZpbGUgaW4gdGhlIHJldHVybiBzdGF0ZW1lbnQgZm9yIHRoaXMgbWV0aG9kXHJcbiAgICBmb3IgKGNvbnN0IGVjbGFzc2lmaWVyIG9mIHNvcnRlZENsYXNzaWZpZXJzKSB7XHJcbiAgICAgIGNvbnN0IGVjbGFzc0lkRmllbGQgPSBEVS5nZW5DbGFzc0lkRmllbGROYW1lKGVjbGFzc2lmaWVyKTtcclxuICAgICAgaWRGaWVsZHNDb250ZW50ICs9IGBcclxuICBwdWJsaWMgc3RhdGljICR7ZWNsYXNzSWRGaWVsZH0gPSAke2VjSWRDb3VudGVyfTtgO1xyXG4gICAgICBlY0lkQ291bnRlcisrO1xyXG5cclxuICAgICAgLy9hZGQgZWNsYXNzaWZpZXIgZmllbGRcclxuICAgICAgbGV0IHR5cGUgPSAnRUNsYXNzJztcclxuICAgICAgaWYgKGVjbGFzc2lmaWVyIGluc3RhbmNlb2YgRUVudW1JbXBsKSB0eXBlID0gJ0VFbnVtJztcclxuICAgICAgZWxzZSBpZiAoZWNsYXNzaWZpZXIgaW5zdGFuY2VvZiBFRGF0YVR5cGVJbXBsKSB0eXBlID0gJ0VEYXRhVHlwZSc7XHJcbiAgICAgIGNvbnN0IGVjbGFzc0ZpZWxkTmFtZSA9IERVLnVuY2FwaXRhbGl6ZShlY2xhc3NpZmllci5nZXROYW1lKCkpICsgdHlwZTtcclxuICAgICAgZmllbGREZWNsYXJhdGlvbnNDb250ZW50ICs9IGBcclxuICBwcml2YXRlICR7ZWNsYXNzRmllbGROYW1lfSE6ICR7dHlwZX07YDtcclxuXHJcbiAgICAgIC8vYWRkIGVjbGFzcyBnZXR0ZXJcclxuICAgICAgY29uc3QgZWNsYXNzR2V0dGVyID0gRFUuZ2VuRWNsYXNzR2V0dGVyTmFtZShlY2xhc3NpZmllcik7XHJcbiAgICAgIGdldHRlcnNDb250ZW50ICs9IGBcclxuICBwdWJsaWMgJHtlY2xhc3NHZXR0ZXJ9KCk6ICR7dHlwZX0ge1xyXG4gICAgcmV0dXJuIHRoaXMuJHtlY2xhc3NGaWVsZE5hbWV9O1xyXG4gIH1gO1xyXG5cclxuICAgICAgLy9hZGQgY3JlYXRpb25cclxuICAgICAgY3JlYXRlQ29udGVudCArPSBgXHJcbiAgICB0aGlzLiR7ZWNsYXNzRmllbGROYW1lfSA9IHRoaXMuY3JlYXRlJHt0eXBlfSgke2NsYXNzTmFtZX0uJHtlY2xhc3NJZEZpZWxkfSk7YDtcclxuXHJcbiAgICAgIC8vYWRkIExpdGVyYWxzIGVudHJ5IGZvciBFQ2xhc3NpZmllclxyXG4gICAgICBsaXRlcmFsc0NvbnRlbnQgKz0gYFxyXG4gICAgc3RhdGljICR7ZWNsYXNzSWRGaWVsZH06ICR7dHlwZX0gPSAke2NsYXNzTmFtZX0uX2VJTlNUQU5DRS4ke0RVLmdlbkVjbGFzc0dldHRlck5hbWUoXHJcbiAgICAgICAgZWNsYXNzaWZpZXJcclxuICAgICAgKX0oKTtgO1xyXG5cclxuICAgICAgLy9hZGQgY2xhc3MgaW5pdGlhbGl6YXRpb25cclxuICAgICAgaWYgKGVjbGFzc2lmaWVyIGluc3RhbmNlb2YgRUNsYXNzSW1wbCkge1xyXG4gICAgICAgIGNvbnN0IGVjbGFzcyA9IDxFQ2xhc3M+ZWNsYXNzaWZpZXI7XHJcbiAgICAgICAgZm9yIChjb25zdCBzdXBlclR5cGUgb2YgZWNsYXNzaWZpZXIuZ2V0RVN1cGVyVHlwZXMoKSkge1xyXG4gICAgICAgICAgY29uc3QgcGtnUmVmID0gRFUuZ2V0UmVmZXJlbmNlVG9QYWNrYWdlSW5zdGFuY2UoXHJcbiAgICAgICAgICAgIHN1cGVyVHlwZSxcclxuICAgICAgICAgICAgZWNsYXNzaWZpZXIsXHJcbiAgICAgICAgICAgIHBrZ1RvSW1wb3J0XHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgaW5pdENvbnRlbnQgKz0gYFxyXG4gICAgdGhpcy4ke2VjbGFzc0ZpZWxkTmFtZX0uZ2V0RVN1cGVyVHlwZXMoKS5hZGQoJHtwa2dSZWZ9LiR7RFUuZ2VuRWNsYXNzR2V0dGVyTmFtZShcclxuICAgICAgICAgICAgc3VwZXJUeXBlXHJcbiAgICAgICAgICApfSgpKTtgO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpbml0Q29udGVudCArPSBgXHJcbiAgICB0aGlzLmluaXQke3R5cGV9KFxyXG4gICAgICB0aGlzLiR7ZWNsYXNzRmllbGROYW1lfSxcclxuICAgICAgJyR7ZWNsYXNzaWZpZXIuZ2V0TmFtZSgpfScsXHJcbiAgICAgICR7ZWNsYXNzaWZpZXIuaXNBYnN0cmFjdCgpfSxcclxuICAgICAgJHtlY2xhc3NpZmllci5pc0ludGVyZmFjZSgpfSxcclxuICAgICAgdHJ1ZVxyXG4gICAgKTtgO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGluaXRDb250ZW50ICs9IGBcclxuICAgIHRoaXMuaW5pdCR7dHlwZX0oXHJcbiAgICAgIHRoaXMuJHtlY2xhc3NGaWVsZE5hbWV9LCAnJHtlY2xhc3NpZmllci5nZXROYW1lKCl9Jyk7YDtcclxuXHJcbiAgICAgICAgaWYgKGVjbGFzc2lmaWVyIGluc3RhbmNlb2YgRUVudW1JbXBsKSB7XHJcbiAgICAgICAgICBsZXQgbGl0ZXJhbEluZCA9IDA7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IGxpdGVyYWwgb2YgKDxFRW51bT5lY2xhc3NpZmllcikuZ2V0RUxpdGVyYWxzKCkpIHtcclxuICAgICAgICAgICAgY29uc3QgbGl0UmVmID0gZWNsYXNzaWZpZXIuZ2V0TmFtZSgpICsgJy4nICsgbGl0ZXJhbC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgIGluaXRDb250ZW50ICs9IGBcclxuICAgIHRoaXMuYWRkRUVudW1MaXRlcmFsKHRoaXMuJHtlY2xhc3NGaWVsZE5hbWV9LCAnJHtsaXRlcmFsLmdldE5hbWUoKX0nLCAke2xpdGVyYWxJbmR9KTtgO1xyXG4gICAgICAgICAgICBsaXRlcmFsSW5kKys7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvL3Byb2Nlc3MgcmVmZXJlbmNlcyBhbmQgYXR0cmlidXRlc1xyXG4gICAgICBpZiAoZWNsYXNzaWZpZXIgaW5zdGFuY2VvZiBFQ2xhc3NJbXBsKSB7XHJcbiAgICAgICAgLy9maW5kIHN1cGVyIHR5cGVcclxuICAgICAgICBjb25zdCBzdXBlclR5cGUgPVxyXG4gICAgICAgICAgZWNsYXNzaWZpZXIuZ2V0RVN1cGVyVHlwZXMoKS5zaXplKCkgPiAwXHJcbiAgICAgICAgICAgID8gZWNsYXNzaWZpZXIuZ2V0RVN1cGVyVHlwZXMoKS5nZXQoMClcclxuICAgICAgICAgICAgOiBudWxsO1xyXG5cclxuICAgICAgICAvL3dyaXRlIG91dCBmZWF0dXJlIGNvdW50IGZpZWxkICh3aWxsIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgSUQnaW5nIG5ldyBmaWVsZHMgb24gdGhpcyBlY2xhc3MpXHJcbiAgICAgICAgY29uc3QgZmVhdHVyZUNvdW50RmllbGQgPSBEVS5nZW5GZWF0dXJlQ291bnRGaWVsZE5hbWUoZWNsYXNzaWZpZXIpO1xyXG5cclxuICAgICAgICBjb25zdCBzdXBlclR5cGVGZWF0dXJlQ291bnQgPSAgc3VwZXJUeXBlPyBzdXBlclR5cGUuZ2V0RUFsbFN0cnVjdHVyYWxGZWF0dXJlcygpLnNpemUoKSA6IDA7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAvL0VsaW1pbmF0aW5nIHJlZmVyZW5jZXMgdG8gc3VwZXIgdHlwZXMgaW4gc3RhdGljIGluaXRpYWxpemVycywgc2luY2UgdGhleSBjb3VsZCBiZSBpbiBvdGhlciBwYWNrYWdlcyAoY2lyY3VsYXIgaW1wb3J0KVxyXG4gICAgICAgIC8vIGNvbnN0IHN1cGVyVHlwZUNvdW50RmllbGQgPSBzdXBlclR5cGVcclxuICAgICAgICAvLyAgID8gRFUuZ2VuUGFja2FnZUNsYXNzTmFtZShzdXBlclR5cGUuZ2V0RVBhY2thZ2UoKSkgK1xyXG4gICAgICAgIC8vICAgICAnLicgK1xyXG4gICAgICAgIC8vICAgICBEVS5nZW5GZWF0dXJlQ291bnRGaWVsZE5hbWUoc3VwZXJUeXBlKSArXHJcbiAgICAgICAgLy8gICAgICcgKyAnXHJcbiAgICAgICAgLy8gICA6ICcnO1xyXG4gICAgICAgIFxyXG4gIC8vICAgICAgIGlmIChzdXBlclR5cGVDb3VudEZpZWxkKSB7XHJcbiAgLy8gICAgICAgICBpZEZpZWxkc0NvbnRlbnQgKz0gYFxyXG4gIC8vIHB1YmxpYyBzdGF0aWMgJHtmZWF0dXJlQ291bnRGaWVsZH0gPVxyXG4gIC8vICAgJHtzdXBlclR5cGVDb3VudEZpZWxkfSR7ZWNsYXNzaWZpZXIuZ2V0RVN0cnVjdHVyYWxGZWF0dXJlcygpLnNpemUoKX07YDtcclxuICAvLyAgICAgICB9IGVsc2Uge1xyXG4gIC8vICAgICAgICAgaWRGaWVsZHNDb250ZW50ICs9IGBcclxuICAvLyBwdWJsaWMgc3RhdGljICR7ZmVhdHVyZUNvdW50RmllbGR9ID0gJHtlY2xhc3NpZmllci5nZXRFU3RydWN0dXJhbEZlYXR1cmVzKCkuc2l6ZSgpfTtgO1xyXG4gIC8vICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvL3RoaXMgaXMgdGhlIHJlcGxhY2VtZW50IC0ganVzdCBhIHN0cmFpZ2h0IGNvdW50IG9mIGFsbCBmZWF0dXJlcywgc2hvdWRsIGJlIHNhbWVcclxuICAgICAgICAgIGlkRmllbGRzQ29udGVudCArPSBgXHJcbiAgcHVibGljIHN0YXRpYyAke2ZlYXR1cmVDb3VudEZpZWxkfSA9ICR7ZWNsYXNzaWZpZXIuZ2V0RUFsbFN0cnVjdHVyYWxGZWF0dXJlcygpLnNpemUoKX07YDtcclxuXHJcbiAgICAgICAgLy9rZWVwcyB0cmFjayBvZiB0aGUgZmVhdHVyZSdzIGluZGV4IGluIGl0J3MgZUNsYXNzICh1c2VkIGZvciBmZWF0dXJlIGdldHRlcilcclxuICAgICAgICBsZXQgdGhpc0NsYXNzRmVhdHVyZUluZGV4ID0gMDtcclxuICAgICAgICBmb3IgKGNvbnN0IGZlYXR1cmUgb2YgKDxFQ2xhc3M+ZWNsYXNzaWZpZXIpLmdldEVTdHJ1Y3R1cmFsRmVhdHVyZXMoKSkge1xyXG4gICAgICAgICAgY29uc3QgZmVhdHVyZUlkRmllbGQgPSBEVS5nZW5GZWF0dXJlSWRGaWVsZE5hbWUoZmVhdHVyZSk7XHJcbiAgICAgICAgICBcclxuICAgICAgICAgIC8vRWxpbWluYXRpbmcgcmVmZXJlbmNlcyB0byBzdXBlciB0eXBlcyBpbiBzdGF0aWMgaW5pdGlhbGl6ZXJzLCBzaW5jZSB0aGV5IGNvdWxkIGJlIGluIG90aGVyIHBhY2thZ2VzIChjaXJjdWxhciBpbXBvcnQpICAgICAgICAgIFxyXG4gIC8vICAgICAgICAgaWYgKHN1cGVyVHlwZUNvdW50RmllbGQpIHtcclxuICAvLyAgICAgICAgICAgaWRGaWVsZHNDb250ZW50ICs9IGBcclxuICAvLyBwdWJsaWMgc3RhdGljICR7ZmVhdHVyZUlkRmllbGR9ID0gJHtzdXBlclR5cGVDb3VudEZpZWxkfSR7dGhpc0NsYXNzRmVhdHVyZUluZGV4fTtgO1xyXG4gIC8vICAgICAgICAgfSBlbHNlIHtcclxuICAvLyAgICAgICAgICAgaWRGaWVsZHNDb250ZW50ICs9IGBcclxuICAvLyBwdWJsaWMgc3RhdGljICR7ZmVhdHVyZUlkRmllbGR9ID0gJHt0aGlzQ2xhc3NGZWF0dXJlSW5kZXh9O2A7XHJcbiAgLy8gICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vdGhpcyBpcyB0aGUgcmVwbGFjZW1lbnQgLSBqdXN0IGFkZCB0byB0aGUgc3VwZXIgdHlwZSBmZWF0dXJlIGNvdW50XHJcbiAgICAgICAgICAgIGlkRmllbGRzQ29udGVudCArPSBgXHJcbiAgcHVibGljIHN0YXRpYyAke2ZlYXR1cmVJZEZpZWxkfSA9ICR7c3VwZXJUeXBlRmVhdHVyZUNvdW50ICsgdGhpc0NsYXNzRmVhdHVyZUluZGV4fTtgOyAgICAgICAgXHJcblxyXG5cclxuICAgICAgICAgIGNvbnN0IGZlYXR1cmVUeXBlID1cclxuICAgICAgICAgICAgZmVhdHVyZSBpbnN0YW5jZW9mIEVBdHRyaWJ1dGVJbXBsID8gJ0VBdHRyaWJ1dGUnIDogJ0VSZWZlcmVuY2UnO1xyXG4gICAgICAgICAgbGl0ZXJhbHNDb250ZW50ICs9IGBcclxuICAgIHN0YXRpYyAke2ZlYXR1cmVJZEZpZWxkfTogJHtmZWF0dXJlVHlwZX0gPVxyXG4gICAgICAke2NsYXNzTmFtZX0uX2VJTlNUQU5DRS5nZXQke0RVLmNhcGl0YWxpemUoXHJcbiAgICAgICAgICAgIGVjbGFzc2lmaWVyLmdldE5hbWUoKVxyXG4gICAgICAgICAgKX1fJHtEVS5jYXBpdGFsaXplKGZlYXR1cmUuZ2V0TmFtZSgpKX0oKTtgO1xyXG5cclxuICAgICAgICAgIC8vY3JlYXRlIGZlYXR1cmVzXHJcbiAgICAgICAgICBjcmVhdGVDb250ZW50ICs9IGBcclxuICAgIHRoaXMuY3JlYXRlJHtmZWF0dXJlVHlwZX0oXHJcbiAgICAgIHRoaXMuJHtlY2xhc3NGaWVsZE5hbWV9LFxyXG4gICAgICAke2NsYXNzTmFtZX0uJHtmZWF0dXJlSWRGaWVsZH1cclxuICAgICk7YDtcclxuXHJcbiAgICAgICAgICBjb25zdCBmZWF0dXJlR2V0dGVyTmFtZSA9IERVLmdlbkZlYXR1cmVHZXR0ZXJOYW1lKGZlYXR1cmUpO1xyXG5cclxuICAgICAgICAgIC8vYWRkIGZlYXR1cmUgZ2V0dGVyXHJcbiAgICAgICAgICBnZXR0ZXJzQ29udGVudCArPSBgXHJcbiAgcHVibGljICR7ZmVhdHVyZUdldHRlck5hbWV9KCk6ICR7ZmVhdHVyZVR5cGV9IHtcclxuICAgIHJldHVybiA8JHtmZWF0dXJlVHlwZX0+dGhpcy4ke2VjbGFzc0ZpZWxkTmFtZX0uZ2V0RVN0cnVjdHVyYWxGZWF0dXJlcygpLmdldCgke3RoaXNDbGFzc0ZlYXR1cmVJbmRleH0pO1xyXG4gIH1gO1xyXG5cclxuICAgICAgICAgIC8vdGhlIGdldHRlciBmb3IgdGhlIGZlYXR1cmUncyB0eXBlIChFY2xhc3NpZmllciBpbnN0YW5jZSlcclxuICAgICAgICAgIGNvbnN0IGZlYXR1cmVUeXBlR2V0dGVyID0gdGhpcy5nZXR0ZXJGb3JFVHlwZShcclxuICAgICAgICAgICAgZmVhdHVyZS5nZXRFVHlwZSgpISxcclxuICAgICAgICAgICAgZWNsYXNzaWZpZXIsXHJcbiAgICAgICAgICAgIHBrZ1RvSW1wb3J0LFxyXG4gICAgICAgICAgICBwa2dcclxuICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgLy9pbml0aWFsaXplcnNcclxuICAgICAgICAgIGluaXRDb250ZW50ICs9IGBcclxuICAgIHRoaXMuaW5pdCR7ZmVhdHVyZVR5cGV9KFxyXG4gICAgICB0aGlzLiR7ZmVhdHVyZUdldHRlck5hbWV9KClgO1xyXG4gICAgICAgICAgaWYgKGZlYXR1cmUgaW5zdGFuY2VvZiBFQXR0cmlidXRlSW1wbCkge1xyXG4gICAgICAgICAgICBpbml0Q29udGVudCArPSBgLFxyXG4gICAgICAke2ZlYXR1cmVUeXBlR2V0dGVyfSxcclxuICAgICAgJyR7ZmVhdHVyZS5nZXROYW1lKCl9JyxcclxuICAgICAgJHtmZWF0dXJlLmdldERlZmF1bHRWYWx1ZUxpdGVyYWwoKSA/IGZlYXR1cmUuZ2V0RGVmYXVsdFZhbHVlTGl0ZXJhbCgpIDogYCcnYH0sXHJcbiAgICAgICR7ZmVhdHVyZS5nZXRMb3dlckJvdW5kKCl9LFxyXG4gICAgICAke2ZlYXR1cmUuZ2V0VXBwZXJCb3VuZCgpfSxcclxuICAgICAgJycsXHJcbiAgICAgICR7ZmVhdHVyZS5pc1RyYW5zaWVudCgpID8/IGZhbHNlfSxcclxuICAgICAgJHtmZWF0dXJlLmlzVm9sYXRpbGUoKSA/PyBmYWxzZX0sXHJcbiAgICAgICR7ZmVhdHVyZS5pc0NoYW5nZWFibGUoKSA/PyB0cnVlfSxcclxuICAgICAgdHJ1ZSxcclxuICAgICAgJHtmZWF0dXJlLmlzSWQoKSA/PyBmYWxzZX0sXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICBmYWxzZSxcclxuICAgICAgZmFsc2VgIFxyXG4gICAgICAgICAgfSBlbHNlIGlmIChmZWF0dXJlIGluc3RhbmNlb2YgRVJlZmVyZW5jZUltcGwpIHtcclxuICAgICAgICAgICAgY29uc3QgcGtnUmVmID0gRFUuZ2V0UmVmZXJlbmNlVG9QYWNrYWdlSW5zdGFuY2UoXHJcbiAgICAgICAgICAgICAgZmVhdHVyZS5nZXRFVHlwZSgpISxcclxuICAgICAgICAgICAgICBlY2xhc3NpZmllcixcclxuICAgICAgICAgICAgICBwa2dUb0ltcG9ydFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBsZXQgZW9wcG9zaXRlID0gJ3VuZGVmaW5lZCc7XHJcbiAgICAgICAgICAgIGlmIChmZWF0dXJlLmdldEVPcHBvc2l0ZSgpKSB7XHJcbiAgICAgICAgICAgICAgZW9wcG9zaXRlID0gYCR7cGtnUmVmfS4ke0RVLmdlbkZlYXR1cmVHZXR0ZXJOYW1lKFxyXG4gICAgICAgICAgICAgICAgZmVhdHVyZS5nZXRFT3Bwb3NpdGUoKSFcclxuICAgICAgICAgICAgICApfSgpYDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpbml0Q29udGVudCArPSBgLFxyXG4gICAgICAke2ZlYXR1cmVUeXBlR2V0dGVyfSxcclxuICAgICAgJHtlb3Bwb3NpdGV9LFxyXG4gICAgICAnJHtmZWF0dXJlLmdldE5hbWUoKX0nLFxyXG4gICAgICAnJyxcclxuICAgICAgJHtmZWF0dXJlLmdldExvd2VyQm91bmQoKX0sXHJcbiAgICAgICR7ZmVhdHVyZS5nZXRVcHBlckJvdW5kKCl9LFxyXG4gICAgICAnJyxcclxuICAgICAgJHtmZWF0dXJlLmlzVHJhbnNpZW50KCkgPz8gZmFsc2V9LFxyXG4gICAgICAke2ZlYXR1cmUuaXNWb2xhdGlsZSgpID8/IGZhbHNlfSxcclxuICAgICAgJHtmZWF0dXJlLmlzQ2hhbmdlYWJsZSgpID8/IGZhbHNlfSxcclxuICAgICAgJHtmZWF0dXJlLmlzQ29udGFpbm1lbnQoKSA/PyBmYWxzZX0sXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICB0cnVlLFxyXG4gICAgICBmYWxzZSxcclxuICAgICAgZmFsc2UsXHJcbiAgICAgIGZhbHNlYDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGluaXRDb250ZW50ICs9IGBcclxuICAgICk7YDtcclxuICAgICAgICAgIHRoaXNDbGFzc0ZlYXR1cmVJbmRleCsrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9sb2dpYyBmb3IgY3JlYXRpbmcgYW5kIGluaXRpYWxpemluZyBFT3BlcmF0aW9uc1xyXG4gICAgICAgIGxldCBlb3BJbmRleCA9IDA7XHJcbiAgICAgICAgZm9yIChjb25zdCBlb3Agb2YgZWNsYXNzaWZpZXIuZ2V0RU9wZXJhdGlvbnMoKSkge1xyXG4gICAgICAgICAgY29uc3QgZW9wSWRGaWVsZCA9IERVLmdlbk9wZXJhdGlvbklkRmllbGROYW1lKGVvcCk7XHJcbiAgICAgICAgICAvL2FkZCBJRCBjb250ZW50XHJcbiAgICAgICAgICBpZEZpZWxkc0NvbnRlbnQgKz0gYFxyXG4gIHB1YmxpYyBzdGF0aWMgJHtlb3BJZEZpZWxkfSA9ICR7ZW9wSW5kZXh9O2A7XHJcbiAgICAgICAgICBjcmVhdGVDb250ZW50ICs9IGBcclxuICAgIHRoaXMuY3JlYXRlRU9wZXJhdGlvbih0aGlzLiR7ZWNsYXNzRmllbGROYW1lfSwgJHtjbGFzc05hbWV9LiR7ZW9wSWRGaWVsZH0pO2A7XHJcbiAgICAgICAgICBjb25zdCBmZWF0dXJlR2V0dGVyTmFtZSA9IERVLmdlbk9wZXJhdGlvbkdldHRlck5hbWUoZW9wKTtcclxuICAgICAgICAgIGdldHRlcnNDb250ZW50ICs9IGBcclxuICBwdWJsaWMgJHtmZWF0dXJlR2V0dGVyTmFtZX0oKTogRU9wZXJhdGlvbiB7XHJcbiAgICByZXR1cm4gdGhpcy4ke2VjbGFzc0ZpZWxkTmFtZX0uZ2V0RU9wZXJhdGlvbnMoKS5nZXQoJHtlb3BJbmRleH0pO1xyXG4gIH1gO1xyXG4gICAgICAgICAgaW5pdENvbnRlbnQgKz0gYFxyXG4gICAgb3AgPSB0aGlzLmluaXRFT3BlcmF0aW9uKFxyXG4gICAgICB0aGlzLiR7ZmVhdHVyZUdldHRlck5hbWV9KCksXHJcbiAgICAgICR7dGhpcy5nZXR0ZXJGb3JFVHlwZShlb3AuZ2V0RVR5cGUoKSEsIGVjbGFzc2lmaWVyLCBwa2dUb0ltcG9ydCwgcGtnKX0sXHJcbiAgICAgICcke2VvcC5nZXROYW1lKCl9JyxcclxuICAgICAgMCxcclxuICAgICAgJHtlb3AuaXNNYW55KCkgPyAtMSA6IDF9LFxyXG4gICAgICB0cnVlLFxyXG4gICAgICB0cnVlXHJcbiAgICApO2A7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IHAgb2YgZW9wLmdldEVQYXJhbWV0ZXJzKCkpIHtcclxuICAgICAgICAgICAgLy9UT0RPOiBDcmVhdGUgcGFyYW1ldGVycyBhbmQgYWRkIHRoZW0gdG8gRU9waGVyZVxyXG4gICAgICAgICAgICBpbml0Q29udGVudCArPSBgXHJcbiAgICB0aGlzLmNyZWF0ZUVQYXJhbWV0ZXIoXHJcbiAgICAgIG9wLFxyXG4gICAgICAnJHtwLmdldE5hbWUoKX0nLFxyXG4gICAgICAke3AuaXNNYW55KCkgPyAtMSA6IDF9LFxyXG4gICAgICAgJHt0aGlzLmdldHRlckZvckVUeXBlKHAuZ2V0RVR5cGUoKSwgZWNsYXNzaWZpZXIsIHBrZ1RvSW1wb3J0LCBwa2cpfVxyXG4gICAgKTtgXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlb3BJbmRleCsrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZUNvbnRlbnQgKz0gYFxyXG4gIH1gO1xyXG4gICAgaW5pdENvbnRlbnQgKz0gYFxyXG4gIH1gO1xyXG4gICAgbGl0ZXJhbHNDb250ZW50ICs9IGBcclxuICB9O2A7XHJcblxyXG4gICAgLy9FY29yZVBhY2thZ2UgY2Fubm90IGV4dGVuZCBFUGFja2FnZUltcGwsIGFzIGl0IGl0IHdvdWxkIGNyZWF0ZSBjaXJjdWxhciByZWZlcmVuY2VcclxuICAgIGNvbnN0IHRvRXh0ZW5kID1cclxuICAgICAgcGtnLmdldE5hbWUoKS50b0xvd2VyQ2FzZSgpID09PSAnZWNvcmUnID8gJ0VQYWNrYWdlJyA6ICdFUGFja2FnZUltcGwnO1xyXG5cclxuICBsZXQgc3ViUGtnU2V0dGVycyA9ICcnO1xyXG5cclxuICAgIC8vIGZvcihjb25zdCBzdWJQa2cgb2YgcGtnLmdldEVTdWJQYWNrYWdlcygpKXtcclxuICAgIC8vICAgaWYoIXBrZ1RvSW1wb3J0LmhhcyhzdWJQa2cpKXtcclxuICAgIC8vICAgICBwa2dUb0ltcG9ydC5hZGQoc3ViUGtnKTtcclxuICAgIC8vICAgfVxyXG4gICAgLy8gICBzdWJQa2dTZXR0ZXJzICs9IGBcclxuICAgIC8vICR7RFUuZ2VuUGFja2FnZUNsYXNzTmFtZShzdWJQa2cpfS5lSU5TVEFOQ0Uuc2V0RVN1cGVyUGFja2FnZSh0aGUke2NsYXNzTmFtZX0pYDtcclxuICAgIC8vIH1cclxuXHJcbiAgICByZXR1cm4gYCR7dGhpcy5nZW5lcmF0ZUltcG9ydHMocGtnVG9JbXBvcnQsIHBrZyl9XHJcbmV4cG9ydCBjbGFzcyAke2NsYXNzTmFtZX0gZXh0ZW5kcyAke3RvRXh0ZW5kfSB7JHtpZEZpZWxkc0NvbnRlbnR9XHJcblxyXG4gIC8qKiBTaW5nbGV0b24gKi9cclxuICBwdWJsaWMgc3RhdGljIF9lSU5TVEFOQ0U6ICR7Y2xhc3NOYW1lfSA9ICR7Y2xhc3NOYW1lfS5pbml0KCk7XHJcblxyXG4gIC8vaWYgdGhlIHNpbmdsZXRvbiBpcyBpbml0aWFsaXplZFxyXG4gIHByaXZhdGUgc3RhdGljIGlzSW5pdGVkID0gZmFsc2U7XHJcblxyXG4gIHN0YXRpYyBlTlNfVVJJID1cclxuICAgICcke3BrZy5nZXROc1VSSSgpfSc7XHJcbiAgc3RhdGljIGVOQU1FID0gJyR7cGtnLmdldE5hbWUoKX0nO1xyXG4gIHN0YXRpYyBlTlNfUFJFRklYID0gJyR7cGtnLmdldE5zUHJlZml4KCl9JztcclxuJHtsaXRlcmFsc0NvbnRlbnR9XHJcblxyXG4gIC8vZmxhZ3MgdGhhdCBrZWVwIHRyYWNrIG9mIHdoZXRoZXIgcGFja2FnZSBpcyBpbml0aWFsaXplZFxyXG4gIHByaXZhdGUgaXNDcmVhdGVkID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBpc0luaXRpYWxpemVkID0gZmFsc2U7XHJcbiR7ZmllbGREZWNsYXJhdGlvbnNDb250ZW50fVxyXG5cclxuICAvL2NhdXNlcyBFUGFja2FnZS5SZWdpc3RyeSByZWdpc3RyYXRpb24gZXZlbnRcclxuICAvL2hhcmQtY29kZWQgVVJJLCBzaW5jZSByZWZlcnJpbmcgdG8gdGhlIHN0YXRpYyBlTlNfVVJJIGZpZWxkIGluIGNvbnN0cnVjdG9yIGNhbiBjYXVzZSBpc3N1ZXNcclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHN1cGVyKFxyXG4gICAgICAnJHtwa2cuZ2V0TmFtZSgpfScsXHJcbiAgICAgICcke3BrZy5nZXROc1VSSSgpfScsXHJcbiAgICAgICcke3BrZy5nZXROc1ByZWZpeCgpfSdcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbnZva2VkIG9uY2UuIEluaXRpYWxpemVzIHRoZSBTaW5nbGV0b24uXHJcbiAgICpcclxuICAgKiBOT1RFOiBMb3RzIG9mIGRpZmZlcmVuY2VzIGhlcmUgd2l0aCB0aGUgRU1GIHZlcnNpb24sIHdoaWNoIGludGVyYWN0cyB3aXRoIHRoZSBwYWNrYWdlIFJlZ2lzdHJ5LFxyXG4gICAqIG90aGVyIHBhY2thZ2VzIGZyb20gdGhlIHNhbWUgbW9kZWwgdG8gcmVnaXN0ZXIgaW50ZXJkZXBlbmRlbmNpZXMsIGFuZCBmcmVlemVzIHRoZSBwYWNrYWdlIG1ldGEtZGF0YS5cclxuICAgKi9cclxuICBwcml2YXRlIHN0YXRpYyBpbml0KCk6ICR7Y2xhc3NOYW1lfSB7XHJcbiAgICBpZiAoJHtjbGFzc05hbWV9LmlzSW5pdGVkKSByZXR1cm4gdGhpcy5fZUlOU1RBTkNFO1xyXG4gICAgLy8gT2J0YWluIG9yIGNyZWF0ZSBhbmQgcmVnaXN0ZXIgcGFja2FnZVxyXG4gICAgY29uc3QgdGhlJHtjbGFzc05hbWV9ID0gbmV3ICR7Y2xhc3NOYW1lfSgpO1xyXG4gICAgLy90aGlzIGlzIG5lY2Vzc2FyeSBzcGVjaWZpY2FsbHkgZm9yIEVjb3JlUGFja2FnZSBnZW5lcmF0aW9uLCB3aGljaCBuZWVkcyB0byByZWZlciB0byBpdHNlbGZcclxuICAgIHRoaXMuX2VJTlNUQU5DRSA9IHRoZSR7Y2xhc3NOYW1lfTtcclxuICAgICR7Y2xhc3NOYW1lfS5pc0luaXRlZCA9IHRydWU7XHJcbiR7c3ViUGtnU2V0dGVyc30gICAgXHJcblxyXG4gICAgLy8gQ3JlYXRlIHBhY2thZ2UgbWV0YS1kYXRhIG9iamVjdHNcclxuICAgIHRoZSR7Y2xhc3NOYW1lfS5jcmVhdGVQYWNrYWdlQ29udGVudHMoKTtcclxuXHJcbiAgICAvLyBJbml0aWFsaXplIGNyZWF0ZWQgbWV0YS1kYXRhXHJcbiAgICAvLyB0aGUke2NsYXNzTmFtZX0uaW5pdGlhbGl6ZVBhY2thZ2VDb250ZW50cygpO1xyXG4gICAgcmV0dXJuIHRoaXMuX2VJTlNUQU5DRTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBnZXQgZUlOU1RBTkNFKCk6ICR7Y2xhc3NOYW1lfXtcclxuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcclxuICAgIHJldHVybiB0aGlzLl9lSU5TVEFOQ0U7XHJcbiAgfSAgXHJcblxyXG4gIC8qKlxyXG4gICAqIEVuc3VyZXMgdGhpcyBwYWNrYWdlIGFuZCBpdCdzIGRlcGRlbmRlbmNpZXMgYXJlIGZ1bGx5IGluaXRpYWxpemVkIGFuZCByZWdpc3RlcmVkIHdpdGggVEpzb25cclxuICAgKi9cclxuICBwcml2YXRlIHN0YXRpYyBlbnN1cmVJbml0aWFsaXplZCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBhY2thZ2VOYW1lID0gJyR7cGtnLmdldE5hbWUoKX0nO1xyXG5cclxuICAgIGlmIChQYWNrYWdlUmVnaXN0cnkuaXNJbml0aWFsaXplZChwYWNrYWdlTmFtZSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEluaXRpYWxpemUgdGhpcyBwYWNrYWdlJ3MgY29udGVudHNcclxuICAgIGNvbnN0IHBrZyA9IHRoaXMuX2VJTlNUQU5DRTtcclxuICAgIHBrZy5pbml0aWFsaXplUGFja2FnZUNvbnRlbnRzKCk7XHJcblxyXG4gICAgLy8gTWFyayBhcyBpbml0aWFsaXplZCBmaXJzdCB0byBwcmV2ZW50IGN5Y2xlc1xyXG4gICAgUGFja2FnZVJlZ2lzdHJ5Lm1hcmtJbml0aWFsaXplZChwYWNrYWdlTmFtZSk7XHJcblxyXG4gICAgLy8gUmVnaXN0ZXIgd2l0aCBUSnNvblxyXG4gICAgUGFja2FnZVJlZ2lzdHJ5LnJlZ2lzdGVyV2l0aFRKc29uKHBhY2thZ2VOYW1lLCBwa2cpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsbGVkIGJ5IHRoZSBmYWN0b3J5IHRvIHJlZ2lzdGVyIGl0c2VsZiB3aXRoIHRoaXMgcGFja2FnZVxyXG4gICAqL1xyXG4gIHN0YXRpYyByZWdpc3RlckZhY3RvcnkoZmFjdG9yeTogRUZhY3RvcnkpOiB2b2lkIHtcclxuICAgIHRoaXMuX2VJTlNUQU5DRS5zZXRFRmFjdG9yeUluc3RhbmNlKGZhY3RvcnkpO1xyXG4gIH0gIFxyXG5cclxuICAvL3RoaXMgdXNlZCB0byBiZSBkaXJlY3QgbGF6eSByZXRyaWV2YWwgb2YgdGhlXHJcbiAgLy9mYWN0b3J5IGluc3RhbmNlIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgLnRzIGZhY3RvcnkgZmlsZSwgYnV0XHJcbiAgLy90aGF0IHdhcyBlbGltaW5hdGVkIHRvIGF2b2lkIGNpcmN1bGFyIGltcG9ydHNcclxuICBwdWJsaWMgb3ZlcnJpZGUgZ2V0RUZhY3RvcnlJbnN0YW5jZSgpOiBFRmFjdG9yeSB7XHJcbiAgICBpZiAoIXRoaXMuX2VGYWN0b3J5SW5zdGFuY2UpIHtcclxuICAgICAgLy8gVHJ5IHRvIGdldCBmYWN0b3J5IGZyb20gcmVnaXN0cnlcclxuICAgICAgY29uc3QgZmFjdG9yeSA9IFBhY2thZ2VSZWdpc3RyeS5nZXRGYWN0b3J5KCcke3BrZy5nZXROYW1lKCl9Jyk7XHJcbiAgICAgIGlmIChmYWN0b3J5KSB7XHJcbiAgICAgICAgdGhpcy5zZXRFRmFjdG9yeUluc3RhbmNlKGZhY3RvcnkpO1xyXG4gICAgICB9XHJcbiAgICB9ICBcclxuICAgIHJldHVybiB0aGlzLl9lRmFjdG9yeUluc3RhbmNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyB3aWxsIGJlIGludm9rZWQgYnkgdGhlIEZhY3Rvcnkgd2hlbiBpdCBpcyBpbml0aWFsaXplZCwgYW55IGludm9jYXRpb25zXHJcbiAgICogYWZ0ZXJ3YXJkcyB3aWxsIGhhdmUgbm8gZWZmZWN0LlxyXG4gICAqL1xyXG4gIHB1YmxpYyBvdmVycmlkZSBzZXRFRmFjdG9yeUluc3RhbmNlKGZhY3RvcnlJbnN0OiBFRmFjdG9yeSk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLl9lRmFjdG9yeUluc3RhbmNlKSB0aGlzLl9lRmFjdG9yeUluc3RhbmNlID0gZmFjdG9yeUluc3Q7XHJcbiAgfVxyXG4ke2dldHRlcnNDb250ZW50fVxyXG5cclxuJHtjcmVhdGVDb250ZW50fVxyXG5cclxuJHtpbml0Q29udGVudH1cclxufVxyXG5gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXNlciBmb3IgZ2VuZXJhdGluZyAnZ2V0JyBvbiB0aGUgRVR5cGUgZm9yIGEgZmVhdHVyZSBvciBvcGVyYXRpb24uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZXR5cGVcclxuICAgKiBAcGFyYW0gb3duaW5nRUNsYXNzXHJcbiAgICogQHBhcmFtIHBrZ1RvSW1wb3J0XHJcbiAgICogQHBhcmFtIHBrZ1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXR0ZXJGb3JFVHlwZShcclxuICAgIGV0eXBlOiBFQ2xhc3NpZmllcixcclxuICAgIG93bmluZ0VDbGFzczogRUNsYXNzLFxyXG4gICAgcGtnVG9JbXBvcnQ6IFNldDxFUGFja2FnZT4sXHJcbiAgICBwa2c6IEVQYWNrYWdlXHJcbiAgKSB7XHJcbiAgICBsZXQgZmVhdHVyZVR5cGVHZXR0ZXIgPSB1bmRlZmluZWQ7XHJcbiAgICBpZiAoZXR5cGUpIHtcclxuICAgICAgY29uc3QgcGtnUmVmID0gRFUuZ2V0UmVmZXJlbmNlVG9QYWNrYWdlSW5zdGFuY2UoXHJcbiAgICAgICAgZXR5cGUsXHJcbiAgICAgICAgb3duaW5nRUNsYXNzLFxyXG4gICAgICAgIHBrZ1RvSW1wb3J0XHJcbiAgICAgICk7XHJcbiAgICAgIGlmIChldHlwZSBpbnN0YW5jZW9mIEVFbnVtSW1wbCkge1xyXG4gICAgICAgIGZlYXR1cmVUeXBlR2V0dGVyID0gYCR7cGtnUmVmfS5nZXQke2V0eXBlLmdldE5hbWUoKX0oKWA7XHJcbiAgICAgIH0gZWxzZSBpZiAoZXR5cGUgaW5zdGFuY2VvZiBFQ2xhc3NJbXBsKSB7XHJcbiAgICAgICAgY29uc3QgcGtnUmVmID0gRFUuZ2V0UmVmZXJlbmNlVG9QYWNrYWdlSW5zdGFuY2UoXHJcbiAgICAgICAgICBldHlwZSxcclxuICAgICAgICAgIG93bmluZ0VDbGFzcyxcclxuICAgICAgICAgIHBrZ1RvSW1wb3J0XHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAoZXR5cGUpIHtcclxuICAgICAgICAgIGZlYXR1cmVUeXBlR2V0dGVyID0gYCR7cGtnUmVmfS4ke0RVLmdlbkVjbGFzc0dldHRlck5hbWUoZXR5cGUpfSgpYDtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IGVjb3JlUGtnR2V0dGVyID0gJ3RoaXMuZ2V0RWNvcmVQYWNrYWdlKCknO1xyXG4gICAgICAgIGlmIChwa2cuZ2V0TmFtZSgpLnRvTG93ZXJDYXNlKCkgPT09ICdlY29yZScpIGVjb3JlUGtnR2V0dGVyID0gJ3RoaXMnO1xyXG4gICAgICAgIGZlYXR1cmVUeXBlR2V0dGVyID0gZWNvcmVQa2dHZXR0ZXIgKyAnLmdldCcgKyBldHlwZS5nZXROYW1lKCkgKyAnKCknO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmVhdHVyZVR5cGVHZXR0ZXI7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlSW1wb3J0cyhwa2dUb0ltcG9ydDogU2V0PEVQYWNrYWdlPiwgcGtnOiBFUGFja2FnZSkge1xyXG5cclxuICAgIC8vYnVpbGQgcGF0aCB0byByb290IHBhY2thZ2UgaW5pdGlhbGl6ZXJcclxuICAgIGNvbnN0IHBhdGhUb1Jvb3QgPSBEVS5nZXRQYXRoVG9Sb290KHBrZyk7XHJcblxyXG4gICAgbGV0IGltcG9ydHMgPSBgJHtEVS5nZW5lcmF0ZUltcG9ydFN0YXRlbWVudHNGb3JFeHRlcm5hbFBhY2thZ2VzKHBrZ1RvSW1wb3J0LCBwa2csICcuLycpfVxyXG5pbXBvcnQgeyBFQ2xhc3MgfSBmcm9tICdAdHJpcHNuZWsvdG1mJztcclxuaW1wb3J0IHsgRUVudW0gfSBmcm9tICdAdHJpcHNuZWsvdG1mJztcclxuaW1wb3J0IHsgUGFja2FnZVJlZ2lzdHJ5IH0gZnJvbSAnJHtwYXRoVG9Sb290fXBhY2thZ2UtcmVnaXN0cnkuanMnO1xyXG5pbXBvcnQgeyBFUGFja2FnZUltcGwgfSBmcm9tICdAdHJpcHNuZWsvdG1mJztcclxuaW1wb3J0IHsgRUF0dHJpYnV0ZSB9IGZyb20gJ0B0cmlwc25lay90bWYnO1xyXG5pbXBvcnQgeyBFRmFjdG9yeSB9IGZyb20gJ0B0cmlwc25lay90bWYnO1xyXG5pbXBvcnQgeyBFUmVmZXJlbmNlIH0gZnJvbSAnQHRyaXBzbmVrL3RtZic7XHJcbmltcG9ydCB7IEVPcGVyYXRpb24gfSBmcm9tICdAdHJpcHNuZWsvdG1mJztgO1xyXG5cclxuICAgIC8vd2UgdXNlIHJlbGF0aXZlIGltcG9ydHMgZm9yIHRoZSBFY29yZVBhY2thZ2UsIHNpbmNlIGl0IGlzIGluIHRoZSBzYW1lIGxpYiBhcyB0aGUgbWV0YW1vZGVsXHJcbiAgICBpZiAocGtnLmdldE5hbWUoKS50b0xvd2VyQ2FzZSgpID09PSAnZWNvcmUnKSB7XHJcbiAgICAgIGltcG9ydHMgPSBgJHtEVS5nZW5lcmF0ZUltcG9ydFN0YXRlbWVudHNGb3JFeHRlcm5hbFBhY2thZ2VzKHBrZ1RvSW1wb3J0LCBwa2csICcnKX1cclxuaW1wb3J0IHsgRVBhY2thZ2UgfSBmcm9tICcuL2VwYWNrYWdlLmpzJztcclxuaW1wb3J0IHsgRURhdGFUeXBlIH0gZnJvbSAnLi9lZGF0YS10eXBlLmpzJztcclxuaW1wb3J0IHsgRUNsYXNzIH0gZnJvbSAnLi9lY2xhc3MuanMnO1xyXG5pbXBvcnQgeyBFUmVmZXJlbmNlIH0gZnJvbSAnLi9lcmVmZXJlbmNlLmpzJztcclxuaW1wb3J0IHsgRUF0dHJpYnV0ZSB9IGZyb20gJy4vZWF0dHJpYnV0ZS5qcyc7XHJcbmltcG9ydCB7IEVGYWN0b3J5IH0gZnJvbSAnLi9lZmFjdG9yeS5qcyc7YDtcclxuICAgIH1cclxuICAgIHJldHVybiBpbXBvcnRzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU29ydCBlY2xhc3NpZmllcnMgaW4gc3VjaCBhIHdheSB0aGF0IGJhc2UgdHlwZXMgYXJlIGd1YXJhbnRlZWQgdG8gcHJlY2VkZSBkZXJpdmVkIHR5cGVzIHNvXHJcbiAgICogdGhhdCB3ZSBjYW4gcmVmZXJlbmNlIGZlYXR1cmUgSURzIGluIGNvcnJlY3Qgb3JkZXJcclxuICAgKi9cclxuICBwcml2YXRlIHNvcnRDbGFzc2lmaWVyc1dpdGhCYXNlVHlwZXNGaXJzdChwa2c6IEVQYWNrYWdlKSB7XHJcbiAgICBjb25zdCBzb3J0ZWRDbGFzc2lmaWVycyA9IG5ldyBBcnJheTxFQ2xhc3NpZmllcj4oKTtcclxuICAgIGZvciAoY29uc3QgZWNsYXNzaWZpZXIgb2YgcGtnLmdldEVDbGFzc2lmaWVycygpKSB7XHJcbiAgICAgIGlmIChlY2xhc3NpZmllciBpbnN0YW5jZW9mIEVDbGFzc0ltcGwpIHtcclxuICAgICAgICBjb25zdCBlY2xhc3MgPSA8RUNsYXNzPmVjbGFzc2lmaWVyO1xyXG4gICAgICAgIGlmIChzb3J0ZWRDbGFzc2lmaWVycy5pbmRleE9mKGVjbGFzcykgPT09IC0xKSB7XHJcbiAgICAgICAgICAvL2luc2VydCBlY2xhc3MgYWZ0ZXIgaXQncyBsYXN0IHN1cGVyIHR5cGVcclxuICAgICAgICAgIGxldCBpZHhMYXN0U3VwZXJUeXBlID0gLTE7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IHN0IG9mIGVjbGFzcy5nZXRFQWxsU3VwZXJUeXBlcygpKSB7XHJcbiAgICAgICAgICAgIGlmIChzb3J0ZWRDbGFzc2lmaWVycy5pbmRleE9mKHN0KSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzb3J0ZWRDbGFzc2lmaWVycy5pbmRleE9mKHN0KTtcclxuICAgICAgICAgICAgICBpZiAoaW5kZXggPiBpZHhMYXN0U3VwZXJUeXBlKSBpZHhMYXN0U3VwZXJUeXBlID0gaW5kZXg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChpZHhMYXN0U3VwZXJUeXBlID49IDApXHJcbiAgICAgICAgICAgIHNvcnRlZENsYXNzaWZpZXJzLnNwbGljZShpZHhMYXN0U3VwZXJUeXBlICsgMSwgMCwgZWNsYXNzKTtcclxuICAgICAgICAgIGVsc2Ugc29ydGVkQ2xhc3NpZmllcnMuc3BsaWNlKDAsIDAsIGVjbGFzcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvL2VudW1zIGFuZCBvdGhlciBFQ2xhc3NpZmllcnMgY2FuIGdvIHdoZXJldmVyXHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHNvcnRlZENsYXNzaWZpZXJzLnB1c2goZWNsYXNzaWZpZXIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc29ydGVkQ2xhc3NpZmllcnM7XHJcbiAgfVxyXG59Il19