ngx-dynamic-hooks
Version:
Automatically insert live Angular components into a dynamic string of content (based on their selector or any pattern of your choice) and render the result in the DOM.
154 lines • 20.8 kB
JavaScript
import { NgZone, createEnvironmentInjector } from '@angular/core';
import { createApplication } from '@angular/platform-browser';
import { firstValueFrom } from 'rxjs';
import { DynamicHooksService } from './services/dynamicHooksService';
// Global state
// ----------
let sharedInjector = null;
let scopes = [];
let allParseResults = [];
const createInjector = async (providers = [], parent) => {
// If no parent, create new root injector, so passed providers will also be actual root providers
return parent ? createEnvironmentInjector(providers, parent) : (await createApplication({ providers })).injector;
};
/**
* Destroys all scopes and components created by standalone mode
*/
export const destroyAll = () => {
// Destroy all scopes
for (const scope of scopes) {
scope.destroy();
}
// Then all remaining independent parseResults
for (const parseResult of allParseResults) {
parseResult.destroy();
}
sharedInjector = null;
scopes = [];
allParseResults = [];
};
// Providers scope
// ----------
/**
* Creates an isolated scope with its own providers that the dynamically-created components will then have access to.
*
* @param providers - A list of providers
* @param parentScope - An optional parent scope created previously. Makes the parent providers also accessible to this scope.
*/
export const createProviders = (providers = [], parentScope) => {
return new ProvidersScope(providers, parentScope);
};
/**
* A scope with an internal list of providers. All dynamic components created by its `parse` method will have access to them.
*/
export class ProvidersScope {
get injector() {
return this._injector;
}
;
get parseResults() {
return this._parseResults;
}
;
get isDestroyed() {
return this._isDestroyed;
}
;
constructor(providers = [], parentScope) {
this.providers = providers;
this.parentScope = parentScope;
this._injector = null;
this._parseResults = [];
this._isDestroyed = false;
scopes.push(this);
}
/**
* Parses content and loads components for all found hooks in standalone mode
*
* @param content - The content to parse
* @param parsers - The parsers to use
* @param context - An optional context object
* @param options - An optional list of options
* @param targetElement - An optional HTML element to use as the container for the loaded content.
* @param targetHookIndex - An optional object to fill with the programmatic hook data. If none is provided, one is created and returned for you.
* @param environmentInjector - An optional environmentInjector to use for the dynamically-loaded components. If none is provided, the default environmentInjector is used.
*/
async parse(content, parsers, context = null, options = null, targetElement = null, targetHookIndex = {}, environmentInjector = null) {
this.checkIfDestroyed();
return parse(content, parsers, context, options, targetElement, targetHookIndex, environmentInjector || await this.resolveInjector())
.then(parseResult => {
this.parseResults.push(parseResult);
return parseResult;
});
}
/**
* Returns the injector for this scope
*/
async resolveInjector() {
this.checkIfDestroyed();
if (!this.injector) {
const parentInjector = this.parentScope ? await this.parentScope.resolveInjector() : undefined;
this._injector = await createInjector(this.providers, parentInjector);
}
return this.injector;
}
/**
* Destroys this scope and all of its created components
*/
destroy() {
this.checkIfDestroyed();
for (const parseResult of this.parseResults) {
parseResult.destroy();
allParseResults = allParseResults.filter(entry => entry !== parseResult);
}
if (this.injector) {
this.injector.destroy();
}
scopes = scopes.filter(scope => scope !== this);
this._isDestroyed = true;
}
checkIfDestroyed() {
if (this.isDestroyed) {
throw new Error('This scope has already been destroyed. It or its methods cannot be used any longer.');
}
}
}
// parse
// ----------
/**
* Parses content and loads components for all found hooks in standalone mode
*
* @param content - The content to parse
* @param parsers - The parsers to use
* @param context - An optional context object
* @param options - An optional list of options
* @param targetElement - An optional HTML element to use as the container for the loaded content.
* @param targetHookIndex - An optional object to fill with the programmatic hook data. If none is provided, one is created and returned for you.
* @param environmentInjector - An optional environmentInjector to use for the dynamically-loaded components. If none is provided, the default environmentInjector is used.
*/
export const parse = async (content, parsers, context = null, options = null, targetElement = null, targetHookIndex = {}, environmentInjector = null) => {
// Reuse the same global injector for all independent parse calls
if (!environmentInjector) {
if (!sharedInjector) {
sharedInjector = await createInjector();
}
environmentInjector = sharedInjector;
}
// In standalone mode, emit HTML events from outputs by default
if (!options) {
options = {};
}
if (!options.hasOwnProperty('triggerDOMEvents')) {
options.triggerDOMEvents = true;
}
const dynHooksService = environmentInjector.get(DynamicHooksService);
// Needs to be run inside NgZone manually
return environmentInjector.get(NgZone).run(() => {
return firstValueFrom(dynHooksService
.parse(content, parsers, context, options, null, null, targetElement, targetHookIndex, environmentInjector, null)).then(parseResult => {
allParseResults.push(parseResult);
return parseResult;
});
});
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvc3RhbmRhbG9uZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTZDLE1BQU0sRUFBWSx5QkFBeUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBS3RDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRXJFLGVBQWU7QUFDZixhQUFhO0FBRWIsSUFBSSxjQUFjLEdBQTZCLElBQUksQ0FBQztBQUNwRCxJQUFJLE1BQU0sR0FBcUIsRUFBRSxDQUFDO0FBQ2xDLElBQUksZUFBZSxHQUFrQixFQUFFLENBQUM7QUFFeEMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLFlBQWlELEVBQUUsRUFBRSxNQUE0QixFQUFFLEVBQUU7SUFDakgsaUdBQWlHO0lBQ2pHLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxpQkFBaUIsQ0FBQyxFQUFDLFNBQVMsRUFBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7QUFDakgsQ0FBQyxDQUFBO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxFQUFFO0lBQzdCLHFCQUFxQjtJQUNyQixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsOENBQThDO0lBQzlDLEtBQUssTUFBTSxXQUFXLElBQUksZUFBZSxFQUFFLENBQUM7UUFDMUMsV0FBVyxDQUFDLE9B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QUFPLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO1FBQzlDLE9BQU8sY0FBYyxDQUFDLGVBQWU7YUFDbEMsS0FBSyxDQUNKLE9BQU8sRUFDUCxPQUFPLEVBQ1AsT0FBTyxFQUNQLE9BQU8sRUFDUCxJQUFJLEVBQ0osSUFBSSxFQUNKLGFBQWEsRUFDYixlQUFlLEVBQ2YsbUJBQW1CLEVBQ25CLElBQUksQ0FDTCxDQUNGLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ25CLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEMsT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVudmlyb25tZW50SW5qZWN0b3IsIEVudmlyb25tZW50UHJvdmlkZXJzLCBOZ1pvbmUsIFByb3ZpZGVyLCBjcmVhdGVFbnZpcm9ubWVudEluamVjdG9yIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjcmVhdGVBcHBsaWNhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSG9va1BhcnNlckVudHJ5IH0gZnJvbSAnLi9zZXJ2aWNlcy9zZXR0aW5ncy9wYXJzZXJFbnRyeSc7XG5pbXBvcnQgeyBQYXJzZU9wdGlvbnMgfSBmcm9tICcuL3NlcnZpY2VzL3NldHRpbmdzL29wdGlvbnMnO1xuaW1wb3J0IHsgSG9va0luZGV4LCBQYXJzZVJlc3VsdCB9IGZyb20gJy4vaW50ZXJmYWNlc1B1YmxpYyc7XG5pbXBvcnQgeyBEeW5hbWljSG9va3NTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9keW5hbWljSG9va3NTZXJ2aWNlJztcblxuLy8gR2xvYmFsIHN0YXRlXG4vLyAtLS0tLS0tLS0tXG5cbmxldCBzaGFyZWRJbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcnxudWxsID0gbnVsbDtcbmxldCBzY29wZXM6IFByb3ZpZGVyc1Njb3BlW10gPSBbXTtcbmxldCBhbGxQYXJzZVJlc3VsdHM6IFBhcnNlUmVzdWx0W10gPSBbXTtcblxuY29uc3QgY3JlYXRlSW5qZWN0b3IgPSBhc3luYyAocHJvdmlkZXJzOiAoUHJvdmlkZXIgfCBFbnZpcm9ubWVudFByb3ZpZGVycylbXSA9IFtdLCBwYXJlbnQ/OiBFbnZpcm9ubWVudEluamVjdG9yKSA9PiB7XG4gIC8vIElmIG5vIHBhcmVudCwgY3JlYXRlIG5ldyByb290IGluamVjdG9yLCBzbyBwYXNzZWQgcHJvdmlkZXJzIHdpbGwgYWxzbyBiZSBhY3R1YWwgcm9vdCBwcm92aWRlcnNcbiAgcmV0dXJuIHBhcmVudCA/IGNyZWF0ZUVudmlyb25tZW50SW5qZWN0b3IocHJvdmlkZXJzLCBwYXJlbnQpIDogKGF3YWl0IGNyZWF0ZUFwcGxpY2F0aW9uKHtwcm92aWRlcnN9KSkuaW5qZWN0b3I7XG59XG5cbi8qKlxuICogRGVzdHJveXMgYWxsIHNjb3BlcyBhbmQgY29tcG9uZW50cyBjcmVhdGVkIGJ5IHN0YW5kYWxvbmUgbW9kZVxuICovXG5leHBvcnQgY29uc3QgZGVzdHJveUFsbCA9ICgpID0+IHtcbiAgLy8gRGVzdHJveSBhbGwgc2NvcGVzXG4gIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKSB7XG4gICAgc2NvcGUuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gVGhlbiBhbGwgcmVtYWluaW5nIGluZGVwZW5kZW50IHBhcnNlUmVzdWx0c1xuICBmb3IgKGNvbnN0IHBhcnNlUmVzdWx0IG9mIGFsbFBhcnNlUmVzdWx0cykge1xuICAgIHBhcnNlUmVzdWx0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIHNoYXJlZEluamVjdG9yID0gbnVsbDtcbiAgc2NvcGVzID0gW107XG4gIGFsbFBhcnNlUmVzdWx0cyA9IFtdO1xufVxuXG4vLyBQcm92aWRlcnMgc2NvcGVcbi8vIC0tLS0tLS0tLS1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGlzb2xhdGVkIHNjb3BlIHdpdGggaXRzIG93biBwcm92aWRlcnMgdGhhdCB0aGUgZHluYW1pY2FsbHktY3JlYXRlZCBjb21wb25lbnRzIHdpbGwgdGhlbiBoYXZlIGFjY2VzcyB0by5cbiAqIFxuICogQHBhcmFtIHByb3ZpZGVycyAtIEEgbGlzdCBvZiBwcm92aWRlcnNcbiAqIEBwYXJhbSBwYXJlbnRTY29wZSAtIEFuIG9wdGlvbmFsIHBhcmVudCBzY29wZSBjcmVhdGVkIHByZXZpb3VzbHkuIE1ha2VzIHRoZSBwYXJlbnQgcHJvdmlkZXJzIGFsc28gYWNjZXNzaWJsZSB0byB0aGlzIHNjb3BlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlUHJvdmlkZXJzID0gKHByb3ZpZGVyczogKFByb3ZpZGVyIHwgRW52aXJvbm1lbnRQcm92aWRlcnMpW10gPSBbXSwgcGFyZW50U2NvcGU/OiBQcm92aWRlcnNTY29wZSk6IFByb3ZpZGVyc1Njb3BlID0+IHtcbiAgcmV0dXJuIG5ldyBQcm92aWRlcnNTY29wZShwcm92aWRlcnMsIHBhcmVudFNjb3BlKTtcbn1cblxuLyoqXG4gKiBBIHNjb3BlIHdpdGggYW4gaW50ZXJuYWwgbGlzdCBvZiBwcm92aWRlcnMuIEFsbCBkeW5hbWljIGNvbXBvbmVudHMgY3JlYXRlZCBieSBpdHMgYHBhcnNlYCBtZXRob2Qgd2lsbCBoYXZlIGFjY2VzcyB0byB0aGVtLlxuICovXG5leHBvcnQgY2xhc3MgUHJvdmlkZXJzU2NvcGUge1xuICBwcml2YXRlIF9pbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcnxudWxsID0gbnVsbDtcbiAgcHVibGljIGdldCBpbmplY3RvcigpOiBFbnZpcm9ubWVudEluamVjdG9yfG51bGwgeyBcbiAgICByZXR1cm4gdGhpcy5faW5qZWN0b3I7XG4gIH07XG4gIHByaXZhdGUgX3BhcnNlUmVzdWx0czogUGFyc2VSZXN1bHRbXSA9IFtdO1xuICBwdWJsaWMgZ2V0IHBhcnNlUmVzdWx0cygpOiBQYXJzZVJlc3VsdFtdIHsgXG4gICAgcmV0dXJuIHRoaXMuX3BhcnNlUmVzdWx0cztcbiAgfTtcbiAgcHJpdmF0ZSBfaXNEZXN0cm95ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgZ2V0IGlzRGVzdHJveWVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pc0Rlc3Ryb3llZDtcbiAgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHByb3ZpZGVyczogKFByb3ZpZGVyIHwgRW52aXJvbm1lbnRQcm92aWRlcnMpW10gPSBbXSwgcHJpdmF0ZSBwYXJlbnRTY29wZT86IFByb3ZpZGVyc1Njb3BlKSB7XG4gICAgc2NvcGVzLnB1c2godGhpcyk7XG4gIH1cblxuICAvKipcbiAgKiBQYXJzZXMgY29udGVudCBhbmQgbG9hZHMgY29tcG9uZW50cyBmb3IgYWxsIGZvdW5kIGhvb2tzIGluIHN0YW5kYWxvbmUgbW9kZVxuICAqIFxuICAqIEBwYXJhbSBjb250ZW50IC0gVGhlIGNvbnRlbnQgdG8gcGFyc2VcbiAgKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIHRvIHVzZVxuICAqIEBwYXJhbSBjb250ZXh0IC0gQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3RcbiAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIGxpc3Qgb2Ygb3B0aW9uc1xuICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IC0gQW4gb3B0aW9uYWwgSFRNTCBlbGVtZW50IHRvIHVzZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gICogQHBhcmFtIHRhcmdldEhvb2tJbmRleCAtIEFuIG9wdGlvbmFsIG9iamVjdCB0byBmaWxsIHdpdGggdGhlIHByb2dyYW1tYXRpYyBob29rIGRhdGEuIElmIG5vbmUgaXMgcHJvdmlkZWQsIG9uZSBpcyBjcmVhdGVkIGFuZCByZXR1cm5lZCBmb3IgeW91LlxuICAqIEBwYXJhbSBlbnZpcm9ubWVudEluamVjdG9yIC0gQW4gb3B0aW9uYWwgZW52aXJvbm1lbnRJbmplY3RvciB0byB1c2UgZm9yIHRoZSBkeW5hbWljYWxseS1sb2FkZWQgY29tcG9uZW50cy4gSWYgbm9uZSBpcyBwcm92aWRlZCwgdGhlIGRlZmF1bHQgZW52aXJvbm1lbnRJbmplY3RvciBpcyB1c2VkLlxuICAqL1xuICBwdWJsaWMgYXN5bmMgcGFyc2UoXG4gICAgY29udGVudDogYW55LFxuICAgIHBhcnNlcnM6IEhvb2tQYXJzZXJFbnRyeVtdLFxuICAgIGNvbnRleHQ6IGFueSA9IG51bGwsICBcbiAgICBvcHRpb25zOiBQYXJzZU9wdGlvbnN8bnVsbCA9IG51bGwsXG4gICAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnR8bnVsbCA9IG51bGwsXG4gICAgdGFyZ2V0SG9va0luZGV4OiBIb29rSW5kZXggPSB7fSxcbiAgICBlbnZpcm9ubWVudEluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yfG51bGwgPSBudWxsXG4gICk6IFByb21pc2U8UGFyc2VSZXN1bHQ+IHtcbiAgICB0aGlzLmNoZWNrSWZEZXN0cm95ZWQoKTtcblxuICAgIHJldHVybiBwYXJzZShjb250ZW50LCBwYXJzZXJzLCBjb250ZXh0LCBvcHRpb25zLCAgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0SG9va0luZGV4LCBlbnZpcm9ubWVudEluamVjdG9yIHx8IGF3YWl0IHRoaXMucmVzb2x2ZUluamVjdG9yKCkpXG4gICAgLnRoZW4ocGFyc2VSZXN1bHQgPT4ge1xuICAgICAgdGhpcy5wYXJzZVJlc3VsdHMucHVzaChwYXJzZVJlc3VsdCk7XG4gICAgICByZXR1cm4gcGFyc2VSZXN1bHQ7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaW5qZWN0b3IgZm9yIHRoaXMgc2NvcGVcbiAgICovXG4gIHB1YmxpYyBhc3luYyByZXNvbHZlSW5qZWN0b3IoKSB7XG4gICAgdGhpcy5jaGVja0lmRGVzdHJveWVkKCk7XG5cbiAgICBpZiAoIXRoaXMuaW5qZWN0b3IpIHtcbiAgICAgIGNvbnN0IHBhcmVudEluamVjdG9yID0gdGhpcy5wYXJlbnRTY29wZSA/IGF3YWl0IHRoaXMucGFyZW50U2NvcGUucmVzb2x2ZUluamVjdG9yKCkgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9pbmplY3RvciA9IGF3YWl0IGNyZWF0ZUluamVjdG9yKHRoaXMucHJvdmlkZXJzLCBwYXJlbnRJbmplY3Rvcik7XG4gICAgfVxuICBcbiAgICByZXR1cm4gdGhpcy5pbmplY3RvciE7XG4gIH1cblxuICAvKipcbiAgICogRGVzdHJveXMgdGhpcyBzY29wZSBhbmQgYWxsIG9mIGl0cyBjcmVhdGVkIGNvbXBvbmVudHNcbiAgICovXG4gIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tJZkRlc3Ryb3llZCgpO1xuXG4gICAgZm9yIChjb25zdCBwYXJzZVJlc3VsdCBvZiB0aGlzLnBhcnNlUmVzdWx0cykge1xuICAgICAgcGFyc2VSZXN1bHQuZGVzdHJveSgpO1xuICAgICAgYWxsUGFyc2VSZXN1bHRzID0gYWxsUGFyc2VSZXN1bHRzLmZpbHRlcihlbnRyeSA9PiBlbnRyeSAhPT0gcGFyc2VSZXN1bHQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmluamVjdG9yKSB7XG4gICAgICB0aGlzLmluamVjdG9yLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBzY29wZXMgPSBzY29wZXMuZmlsdGVyKHNjb3BlID0+IHNjb3BlICE9PSB0aGlzKTtcbiAgICB0aGlzLl9pc0Rlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSWZEZXN0cm95ZWQoKSB7XG4gICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhpcyBzY29wZSBoYXMgYWxyZWFkeSBiZWVuIGRlc3Ryb3llZC4gSXQgb3IgaXRzIG1ldGhvZHMgY2Fubm90IGJlIHVzZWQgYW55IGxvbmdlci4nKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gcGFyc2Vcbi8vIC0tLS0tLS0tLS1cblxuLyoqXG4gKiBQYXJzZXMgY29udGVudCBhbmQgbG9hZHMgY29tcG9uZW50cyBmb3IgYWxsIGZvdW5kIGhvb2tzIGluIHN0YW5kYWxvbmUgbW9kZVxuICogXG4gKiBAcGFyYW0gY29udGVudCAtIFRoZSBjb250ZW50IHRvIHBhcnNlXG4gKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIHRvIHVzZVxuICogQHBhcmFtIGNvbnRleHQgLSBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdFxuICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBsaXN0IG9mIG9wdGlvbnNcbiAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IC0gQW4gb3B0aW9uYWwgSFRNTCBlbGVtZW50IHRvIHVzZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gKiBAcGFyYW0gdGFyZ2V0SG9va0luZGV4IC0gQW4gb3B0aW9uYWwgb2JqZWN0IHRvIGZpbGwgd2l0aCB0aGUgcHJvZ3JhbW1hdGljIGhvb2sgZGF0YS4gSWYgbm9uZSBpcyBwcm92aWRlZCwgb25lIGlzIGNyZWF0ZWQgYW5kIHJldHVybmVkIGZvciB5b3UuXG4gKiBAcGFyYW0gZW52aXJvbm1lbnRJbmplY3RvciAtIEFuIG9wdGlvbmFsIGVudmlyb25tZW50SW5qZWN0b3IgdG8gdXNlIGZvciB0aGUgZHluYW1pY2FsbHktbG9hZGVkIGNvbXBvbmVudHMuIElmIG5vbmUgaXMgcHJvdmlkZWQsIHRoZSBkZWZhdWx0IGVudmlyb25tZW50SW5qZWN0b3IgaXMgdXNlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHBhcnNlID0gYXN5bmMgKFxuICBjb250ZW50OiBhbnksXG4gIHBhcnNlcnM6IEhvb2tQYXJzZXJFbnRyeVtdLFxuICBjb250ZXh0OiBhbnkgPSBudWxsLCAgXG4gIG9wdGlvbnM6IFBhcnNlT3B0aW9uc3xudWxsID0gbnVsbCxcbiAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnR8bnVsbCA9IG51bGwsXG4gIHRhcmdldEhvb2tJbmRleDogSG9va0luZGV4ID0ge30sXG4gIGVudmlyb25tZW50SW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3J8bnVsbCA9IG51bGwsXG4pOiBQcm9taXNlPFBhcnNlUmVzdWx0PiA9PiB7XG5cbiAgLy8gUmV1c2UgdGhlIHNhbWUgZ2xvYmFsIGluamVjdG9yIGZvciBhbGwgaW5kZXBlbmRlbnQgcGFyc2UgY2FsbHNcbiAgaWYgKCFlbnZpcm9ubWVudEluamVjdG9yKSB7XG4gICAgaWYgKCFzaGFyZWRJbmplY3Rvcikge1xuICAgICAgc2hhcmVkSW5qZWN0b3IgPSBhd2FpdCBjcmVhdGVJbmplY3RvcigpO1xuICAgIH1cbiAgICBlbnZpcm9ubWVudEluamVjdG9yID0gc2hhcmVkSW5qZWN0b3I7XG4gIH1cblxuICAvLyBJbiBzdGFuZGFsb25lIG1vZGUsIGVtaXQgSFRNTCBldmVudHMgZnJvbSBvdXRwdXRzIGJ5IGRlZmF1bHRcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cbiAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCd0cmlnZ2VyRE9NRXZlbnRzJykpIHtcbiAgICBvcHRpb25zLnRyaWdnZXJET01FdmVudHMgPSB0cnVlO1xuICB9XG5cbiAgY29uc3QgZHluSG9va3NTZXJ2aWNlID0gZW52aXJvbm1lbnRJbmplY3Rvci5nZXQoRHluYW1pY0hvb2tzU2VydmljZSk7XG5cbiAgLy8gTmVlZHMgdG8gYmUgcnVuIGluc2lkZSBOZ1pvbmUgbWFudWFsbHlcbiAgcmV0dXJuIGVudmlyb25tZW50SW5qZWN0b3IuZ2V0KE5nWm9uZSkucnVuKCgpID0+IHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZUZyb20oZHluSG9va3NTZXJ2aWNlXG4gICAgICAucGFyc2UoXG4gICAgICAgIGNvbnRlbnQsIFxuICAgICAgICBwYXJzZXJzLFxuICAgICAgICBjb250ZXh0LCBcbiAgICAgICAgb3B0aW9ucywgXG4gICAgICAgIG51bGwsIFxuICAgICAgICBudWxsLFxuICAgICAgICB0YXJnZXRFbGVtZW50LCBcbiAgICAgICAgdGFyZ2V0SG9va0luZGV4LCBcbiAgICAgICAgZW52aXJvbm1lbnRJbmplY3RvcixcbiAgICAgICAgbnVsbFxuICAgICAgKVxuICAgICkudGhlbihwYXJzZVJlc3VsdCA9PiB7XG4gICAgICBhbGxQYXJzZVJlc3VsdHMucHVzaChwYXJzZVJlc3VsdCk7XG4gICAgICByZXR1cm4gcGFyc2VSZXN1bHQ7XG4gICAgfSk7XG4gIH0pO1xufSJdfQ==