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.
123 lines • 21.1 kB
JavaScript
import { Injectable } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "../../services/utils/dataTypeParser";
import * as i2 from "../../services/utils/logger";
/**
* A helper service for the SelectorHookParsers that evaluates bindings and only updates them when needed so references are retained when possible
*/
export class BindingsValueManager {
constructor(dataTypeParser, logger) {
this.dataTypeParser = dataTypeParser;
this.logger = logger;
}
// Inputs
// -------------------------------------------------------------------------------------
/**
* Checks input bindings and evaluates/updates them as needed
*
* @param bindings - A list of @Input() bindings
* @param context - The current context object
* @param parserConfig - The parser config
* @param options - The current ParseOptions
*/
checkInputBindings(bindings, context, parserConfig, options) {
for (const [inputName, inputBinding] of Object.entries(bindings)) {
// If no need to parse, use raw as value
if (!parserConfig.parseInputs) {
inputBinding.value = inputBinding.raw;
}
else {
// If not yet parsed, do so
if (!inputBinding.parsed) {
try {
inputBinding.value = this.dataTypeParser.evaluate(inputBinding.raw, parserConfig.allowContextInBindings ? context : {}, undefined, parserConfig.unescapeStrings, inputBinding.boundContextVariables, parserConfig.allowContextFunctionCalls, options);
inputBinding.parsed = true;
}
catch (e) {
this.logger.error([`Hook input parsing error\nselector: ` + parserConfig.selector + `\ninput: ` + inputName + `\nvalue: "` + inputBinding.value + `"`], options);
this.logger.error([e.stack], options);
// If binding could not be parsed at all due to syntax error, remove from list of inputs.
// No amount of calls to updateInputBindings() will fix this kind of error.
delete bindings[inputName];
}
// Otherwise check if needs an update
}
else {
this.updateInputBindingIfStale(inputBinding, context, parserConfig);
}
}
}
}
/**
* We can detect if a binding needs to be reevaluated via the bound context variables. There are three cases to consider:
*
* a) If a binding does not use context vars, don't reevaluate (binding is static and won't ever need to be updated)
* b) If a binding does use context vars, but context vars haven't changed, don't reevaluate either (would evalute the same)
* c) If a binding uses context vars and they have changed, reevaluate the binding from scratch to get the new version
*
* This is in line with the standard Angular behavior when evaluating template vars like [input]="{prop: this.something}".
* When 'this.something' changes so that it returns false on a === comparison with its previous value, Angular does not
* simply replace the reference bound to 'prop', but recreates the whole object literal and passes a new reference into the
* input, triggering ngOnChanges.
*
* @param binding - The previous bindings
* @param context - The current context object
* @param parserConfig - The current parser config
*/
updateInputBindingIfStale(binding, context, parserConfig) {
if (Object.keys(binding.boundContextVariables).length > 0) {
// Check if bound context vars have changed
let boundContextVarHasChanged = false;
for (const [contextVarName, contextVarValue] of Object.entries(binding.boundContextVariables)) {
const encodedContextVarName = this.dataTypeParser.encodeDataTypeString(contextVarName);
// Compare with previous value
const newContextVarValue = this.dataTypeParser.loadContextVariable(encodedContextVarName, context, undefined, parserConfig.unescapeStrings, {}, parserConfig.allowContextFunctionCalls);
if (newContextVarValue !== contextVarValue) {
boundContextVarHasChanged = true;
break;
}
}
// Bound context var has changed! Reevaluate whole binding (which may include more than one context var, or point to some child property)
if (boundContextVarHasChanged) {
binding.boundContextVariables = {};
binding.value = this.dataTypeParser.evaluate(binding.raw, parserConfig.allowContextInBindings ? context : {}, undefined, parserConfig.unescapeStrings, binding.boundContextVariables, parserConfig.allowContextFunctionCalls);
}
}
}
// Outputs
// -------------------------------------------------------------------------------------
/**
* Checks output bindings and evaluates/updates them as needed
*
* @param bindings - A list of @Output() bindings
* @param parserConfig - The current parser config
* @param options - The current ParseOptions
*/
checkOutputBindings(bindings, parserConfig, options) {
for (const [outputName, outputBinding] of Object.entries(bindings)) {
// Unlike inputs, outputs only need to be created once by the parser, never updated, as you only create a wrapper function around the logic to execute.
// As this logic is run fresh whenever the output triggers, there is no need to replace this wrapper function on updates.
if (!outputBinding.parsed) {
outputBinding.value = (event, context) => {
try {
this.dataTypeParser.evaluate(outputBinding.raw, parserConfig.allowContextInBindings ? context : {}, event, parserConfig.unescapeStrings, outputBinding.boundContextVariables, parserConfig.allowContextFunctionCalls);
}
catch (e) {
this.logger.error([`Hook output parsing error\nselector: ` + parserConfig.selector + `\noutput: ` + outputName + `\nvalue: "` + outputBinding.value + `"`], options);
this.logger.error([e.stack], options);
}
};
outputBinding.parsed = true;
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BindingsValueManager, deps: [{ token: i1.DataTypeParser }, { token: i2.Logger }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BindingsValueManager, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BindingsValueManager, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.DataTypeParser }, { type: i2.Logger }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluZGluZ3NWYWx1ZU1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHluYW1pYy1ob29rcy9zcmMvbGliL3BhcnNlcnMvc2VsZWN0b3IvYmluZGluZ3NWYWx1ZU1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQVMzQzs7R0FFRztBQUlILE1BQU0sT0FBTyxvQkFBb0I7SUFFL0IsWUFBb0IsY0FBOEIsRUFBVSxNQUFjO1FBQXRELG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUFVLFdBQU0sR0FBTixNQUFNLENBQVE7SUFDMUUsQ0FBQztJQUVELFNBQVM7SUFDVCx3RkFBd0Y7SUFFeEY7Ozs7Ozs7T0FPRztJQUNILGtCQUFrQixDQUFDLFFBQTBDLEVBQUUsT0FBWSxFQUFFLFlBQXNDLEVBQUUsT0FBcUI7UUFDeEksS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNqRSx3Q0FBd0M7WUFDeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDOUIsWUFBWSxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDO1lBRXhDLENBQUM7aUJBQU0sQ0FBQztnQkFDTiwyQkFBMkI7Z0JBQzNCLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ3pCLElBQUksQ0FBQzt3QkFDSCxZQUFZLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUMvQyxZQUFZLENBQUMsR0FBRyxFQUNoQixZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUNsRCxTQUFTLEVBQ1QsWUFBWSxDQUFDLGVBQWUsRUFDNUIsWUFBWSxDQUFDLHFCQUFxQixFQUNsQyxZQUFZLENBQUMseUJBQXlCLEVBQ3RDLE9BQU8sQ0FDUixDQUFDO3dCQUNGLFlBQVksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO29CQUM3QixDQUFDO29CQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7d0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsc0NBQXNDLEdBQUcsWUFBWSxDQUFDLFFBQVEsR0FBSSxXQUFXLEdBQUcsU0FBUyxHQUFHLFlBQVksR0FBRyxZQUFZLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3dCQUNsSyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDdEMseUZBQXlGO3dCQUN6RiwyRUFBMkU7d0JBQzNFLE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUM3QixDQUFDO29CQUVILHFDQUFxQztnQkFDckMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUN0RSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0sseUJBQXlCLENBQUMsT0FBd0IsRUFBRSxPQUFZLEVBQUUsWUFBc0M7UUFFOUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMxRCwyQ0FBMkM7WUFDM0MsSUFBSSx5QkFBeUIsR0FBRyxLQUFLLENBQUM7WUFDdEMsS0FBSyxNQUFNLENBQUMsY0FBYyxFQUFFLGVBQWUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztnQkFDOUYsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUN2Riw4QkFBOEI7Z0JBQzlCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxxQkFBcUIsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksQ0FBQyxlQUFlLEVBQUUsRUFBRSxFQUFFLFlBQVksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO2dCQUN4TCxJQUFJLGtCQUFrQixLQUFLLGVBQWUsRUFBRSxDQUFDO29CQUMzQyx5QkFBeUIsR0FBRyxJQUFJLENBQUM7b0JBQ2pDLE1BQU07Z0JBQ1IsQ0FBQztZQUNILENBQUM7WUFFRCx5SUFBeUk7WUFDekksSUFBSSx5QkFBeUIsRUFBRSxDQUFDO2dCQUM5QixPQUFPLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO2dCQUNuQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUMxQyxPQUFPLENBQUMsR0FBRyxFQUNYLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQ2xELFNBQVMsRUFDVCxZQUFZLENBQUMsZUFBZSxFQUM1QixPQUFPLENBQUMscUJBQXFCLEVBQzdCLFlBQVksQ0FBQyx5QkFBeUIsQ0FDdkMsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELFVBQVU7SUFDVix3RkFBd0Y7SUFFeEY7Ozs7OztPQU1HO0lBQ0gsbUJBQW1CLENBQUMsUUFBMEMsRUFBRSxZQUFzQyxFQUFFLE9BQXFCO1FBQzNILEtBQUssTUFBTSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDbkUsdUpBQXVKO1lBQ3ZKLHlIQUF5SDtZQUN6SCxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMxQixhQUFhLENBQUMsS0FBSyxHQUFHLENBQUMsS0FBVSxFQUFFLE9BQVksRUFBRSxFQUFFO29CQUNqRCxJQUFJLENBQUM7d0JBQ0gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQzFCLGFBQWEsQ0FBQyxHQUFHLEVBQ2pCLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQ2xELEtBQUssRUFDTCxZQUFZLENBQUMsZUFBZSxFQUM1QixhQUFhLENBQUMscUJBQXFCLEVBQ25DLFlBQVksQ0FBQyx5QkFBeUIsQ0FDdkMsQ0FBQztvQkFDSixDQUFDO29CQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7d0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsdUNBQXVDLEdBQUcsWUFBWSxDQUFDLFFBQVEsR0FBSSxZQUFZLEdBQUcsVUFBVSxHQUFHLFlBQVksR0FBRyxhQUFhLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3dCQUN0SyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztvQkFDeEMsQ0FBQztnQkFDSCxDQUFDLENBQUM7Z0JBQ0YsYUFBYSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOytHQW5JVSxvQkFBb0I7bUhBQXBCLG9CQUFvQixjQUZuQixNQUFNOzs0RkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBEYXRhVHlwZVBhcnNlciB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3V0aWxzL2RhdGFUeXBlUGFyc2VyJztcbmltcG9ydCB7IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZyB9IGZyb20gJy4vc2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnJztcbmltcG9ydCB7IFJpY2hCaW5kaW5nRGF0YSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdXRpbHMvbG9nZ2VyJztcbmltcG9ydCB7IFBhcnNlT3B0aW9ucyB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3NldHRpbmdzL29wdGlvbnMnO1xuXG5cbi8qKlxuICogQSBoZWxwZXIgc2VydmljZSBmb3IgdGhlIFNlbGVjdG9ySG9va1BhcnNlcnMgdGhhdCBldmFsdWF0ZXMgYmluZGluZ3MgYW5kIG9ubHkgdXBkYXRlcyB0aGVtIHdoZW4gbmVlZGVkIHNvIHJlZmVyZW5jZXMgYXJlIHJldGFpbmVkIHdoZW4gcG9zc2libGVcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQmluZGluZ3NWYWx1ZU1hbmFnZXIge1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0YVR5cGVQYXJzZXI6IERhdGFUeXBlUGFyc2VyLCBwcml2YXRlIGxvZ2dlcjogTG9nZ2VyKSB7XG4gIH1cblxuICAvLyBJbnB1dHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaW5wdXQgYmluZGluZ3MgYW5kIGV2YWx1YXRlcy91cGRhdGVzIHRoZW0gYXMgbmVlZGVkXG4gICAqXG4gICAqIEBwYXJhbSBiaW5kaW5ncyAtIEEgbGlzdCBvZiBASW5wdXQoKSBiaW5kaW5nc1xuICAgKiBAcGFyYW0gY29udGV4dCAtIFRoZSBjdXJyZW50IGNvbnRleHQgb2JqZWN0XG4gICAqIEBwYXJhbSBwYXJzZXJDb25maWcgLSBUaGUgcGFyc2VyIGNvbmZpZ1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjdXJyZW50IFBhcnNlT3B0aW9uc1xuICAgKi9cbiAgY2hlY2tJbnB1dEJpbmRpbmdzKGJpbmRpbmdzOiB7W2tleTogc3RyaW5nXTogUmljaEJpbmRpbmdEYXRhfSwgY29udGV4dDogYW55LCBwYXJzZXJDb25maWc6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZywgb3B0aW9uczogUGFyc2VPcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBbaW5wdXROYW1lLCBpbnB1dEJpbmRpbmddIG9mIE9iamVjdC5lbnRyaWVzKGJpbmRpbmdzKSkge1xuICAgICAgLy8gSWYgbm8gbmVlZCB0byBwYXJzZSwgdXNlIHJhdyBhcyB2YWx1ZVxuICAgICAgaWYgKCFwYXJzZXJDb25maWcucGFyc2VJbnB1dHMpIHtcbiAgICAgICAgaW5wdXRCaW5kaW5nLnZhbHVlID0gaW5wdXRCaW5kaW5nLnJhdztcbiAgICBcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIG5vdCB5ZXQgcGFyc2VkLCBkbyBzb1xuICAgICAgICBpZiAoIWlucHV0QmluZGluZy5wYXJzZWQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaW5wdXRCaW5kaW5nLnZhbHVlID0gdGhpcy5kYXRhVHlwZVBhcnNlci5ldmFsdWF0ZShcbiAgICAgICAgICAgICAgaW5wdXRCaW5kaW5nLnJhdyxcbiAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmFsbG93Q29udGV4dEluQmluZGluZ3MgPyBjb250ZXh0IDoge30sXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLnVuZXNjYXBlU3RyaW5ncyxcbiAgICAgICAgICAgICAgaW5wdXRCaW5kaW5nLmJvdW5kQ29udGV4dFZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmFsbG93Q29udGV4dEZ1bmN0aW9uQ2FsbHMsXG4gICAgICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpbnB1dEJpbmRpbmcucGFyc2VkID0gdHJ1ZTtcbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFtgSG9vayBpbnB1dCBwYXJzaW5nIGVycm9yXFxuc2VsZWN0b3I6IGAgKyBwYXJzZXJDb25maWcuc2VsZWN0b3IgKyAgYFxcbmlucHV0OiBgICsgaW5wdXROYW1lICsgYFxcbnZhbHVlOiBcImAgKyBpbnB1dEJpbmRpbmcudmFsdWUgKyBgXCJgXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihbZS5zdGFja10sIG9wdGlvbnMpO1xuICAgICAgICAgICAgLy8gSWYgYmluZGluZyBjb3VsZCBub3QgYmUgcGFyc2VkIGF0IGFsbCBkdWUgdG8gc3ludGF4IGVycm9yLCByZW1vdmUgZnJvbSBsaXN0IG9mIGlucHV0cy5cbiAgICAgICAgICAgIC8vIE5vIGFtb3VudCBvZiBjYWxscyB0byB1cGRhdGVJbnB1dEJpbmRpbmdzKCkgd2lsbCBmaXggdGhpcyBraW5kIG9mIGVycm9yLlxuICAgICAgICAgICAgZGVsZXRlIGJpbmRpbmdzW2lucHV0TmFtZV07XG4gICAgICAgICAgfVxuXG4gICAgICAgIC8vIE90aGVyd2lzZSBjaGVjayBpZiBuZWVkcyBhbiB1cGRhdGVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUlucHV0QmluZGluZ0lmU3RhbGUoaW5wdXRCaW5kaW5nLCBjb250ZXh0LCBwYXJzZXJDb25maWcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdlIGNhbiBkZXRlY3QgaWYgYSBiaW5kaW5nIG5lZWRzIHRvIGJlIHJlZXZhbHVhdGVkIHZpYSB0aGUgYm91bmQgY29udGV4dCB2YXJpYWJsZXMuIFRoZXJlIGFyZSB0aHJlZSBjYXNlcyB0byBjb25zaWRlcjpcbiAgICpcbiAgICogYSkgSWYgYSBiaW5kaW5nIGRvZXMgbm90IHVzZSBjb250ZXh0IHZhcnMsIGRvbid0IHJlZXZhbHVhdGUgKGJpbmRpbmcgaXMgc3RhdGljIGFuZCB3b24ndCBldmVyIG5lZWQgdG8gYmUgdXBkYXRlZClcbiAgICogYikgSWYgYSBiaW5kaW5nIGRvZXMgdXNlIGNvbnRleHQgdmFycywgYnV0IGNvbnRleHQgdmFycyBoYXZlbid0IGNoYW5nZWQsIGRvbid0IHJlZXZhbHVhdGUgZWl0aGVyICh3b3VsZCBldmFsdXRlIHRoZSBzYW1lKVxuICAgKiBjKSBJZiBhIGJpbmRpbmcgdXNlcyBjb250ZXh0IHZhcnMgYW5kIHRoZXkgaGF2ZSBjaGFuZ2VkLCByZWV2YWx1YXRlIHRoZSBiaW5kaW5nIGZyb20gc2NyYXRjaCB0byBnZXQgdGhlIG5ldyB2ZXJzaW9uXG4gICAqXG4gICAqIFRoaXMgaXMgaW4gbGluZSB3aXRoIHRoZSBzdGFuZGFyZCBBbmd1bGFyIGJlaGF2aW9yIHdoZW4gZXZhbHVhdGluZyB0ZW1wbGF0ZSB2YXJzIGxpa2UgW2lucHV0XT1cIntwcm9wOiB0aGlzLnNvbWV0aGluZ31cIi5cbiAgICogV2hlbiAndGhpcy5zb21ldGhpbmcnIGNoYW5nZXMgc28gdGhhdCBpdCByZXR1cm5zIGZhbHNlIG9uIGEgPT09IGNvbXBhcmlzb24gd2l0aCBpdHMgcHJldmlvdXMgdmFsdWUsIEFuZ3VsYXIgZG9lcyBub3RcbiAgICogc2ltcGx5IHJlcGxhY2UgdGhlIHJlZmVyZW5jZSBib3VuZCB0byAncHJvcCcsIGJ1dCByZWNyZWF0ZXMgdGhlIHdob2xlIG9iamVjdCBsaXRlcmFsIGFuZCBwYXNzZXMgYSBuZXcgcmVmZXJlbmNlIGludG8gdGhlXG4gICAqIGlucHV0LCB0cmlnZ2VyaW5nIG5nT25DaGFuZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0gYmluZGluZyAtIFRoZSBwcmV2aW91cyBiaW5kaW5nc1xuICAgKiBAcGFyYW0gY29udGV4dCAtIFRoZSBjdXJyZW50IGNvbnRleHQgb2JqZWN0XG4gICAqIEBwYXJhbSBwYXJzZXJDb25maWcgLSBUaGUgY3VycmVudCBwYXJzZXIgY29uZmlnXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUlucHV0QmluZGluZ0lmU3RhbGUoYmluZGluZzogUmljaEJpbmRpbmdEYXRhLCBjb250ZXh0OiBhbnksIHBhcnNlckNvbmZpZzogU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnKTogdm9pZCB7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMoYmluZGluZy5ib3VuZENvbnRleHRWYXJpYWJsZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIENoZWNrIGlmIGJvdW5kIGNvbnRleHQgdmFycyBoYXZlIGNoYW5nZWRcbiAgICAgIGxldCBib3VuZENvbnRleHRWYXJIYXNDaGFuZ2VkID0gZmFsc2U7XG4gICAgICBmb3IgKGNvbnN0IFtjb250ZXh0VmFyTmFtZSwgY29udGV4dFZhclZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhiaW5kaW5nLmJvdW5kQ29udGV4dFZhcmlhYmxlcykpIHtcbiAgICAgICAgY29uc3QgZW5jb2RlZENvbnRleHRWYXJOYW1lID0gdGhpcy5kYXRhVHlwZVBhcnNlci5lbmNvZGVEYXRhVHlwZVN0cmluZyhjb250ZXh0VmFyTmFtZSk7XG4gICAgICAgIC8vIENvbXBhcmUgd2l0aCBwcmV2aW91cyB2YWx1ZVxuICAgICAgICBjb25zdCBuZXdDb250ZXh0VmFyVmFsdWUgPSB0aGlzLmRhdGFUeXBlUGFyc2VyLmxvYWRDb250ZXh0VmFyaWFibGUoZW5jb2RlZENvbnRleHRWYXJOYW1lLCBjb250ZXh0LCB1bmRlZmluZWQsIHBhcnNlckNvbmZpZy51bmVzY2FwZVN0cmluZ3MsIHt9LCBwYXJzZXJDb25maWcuYWxsb3dDb250ZXh0RnVuY3Rpb25DYWxscyk7XG4gICAgICAgIGlmIChuZXdDb250ZXh0VmFyVmFsdWUgIT09IGNvbnRleHRWYXJWYWx1ZSkge1xuICAgICAgICAgIGJvdW5kQ29udGV4dFZhckhhc0NoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEJvdW5kIGNvbnRleHQgdmFyIGhhcyBjaGFuZ2VkISBSZWV2YWx1YXRlIHdob2xlIGJpbmRpbmcgKHdoaWNoIG1heSBpbmNsdWRlIG1vcmUgdGhhbiBvbmUgY29udGV4dCB2YXIsIG9yIHBvaW50IHRvIHNvbWUgY2hpbGQgcHJvcGVydHkpXG4gICAgICBpZiAoYm91bmRDb250ZXh0VmFySGFzQ2hhbmdlZCkge1xuICAgICAgICBiaW5kaW5nLmJvdW5kQ29udGV4dFZhcmlhYmxlcyA9IHt9O1xuICAgICAgICBiaW5kaW5nLnZhbHVlID0gdGhpcy5kYXRhVHlwZVBhcnNlci5ldmFsdWF0ZShcbiAgICAgICAgICBiaW5kaW5nLnJhdyxcbiAgICAgICAgICBwYXJzZXJDb25maWcuYWxsb3dDb250ZXh0SW5CaW5kaW5ncyA/IGNvbnRleHQgOiB7fSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgcGFyc2VyQ29uZmlnLnVuZXNjYXBlU3RyaW5ncyxcbiAgICAgICAgICBiaW5kaW5nLmJvdW5kQ29udGV4dFZhcmlhYmxlcyxcbiAgICAgICAgICBwYXJzZXJDb25maWcuYWxsb3dDb250ZXh0RnVuY3Rpb25DYWxsc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIE91dHB1dHNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgb3V0cHV0IGJpbmRpbmdzIGFuZCBldmFsdWF0ZXMvdXBkYXRlcyB0aGVtIGFzIG5lZWRlZFxuICAgKlxuICAgKiBAcGFyYW0gYmluZGluZ3MgLSBBIGxpc3Qgb2YgQE91dHB1dCgpIGJpbmRpbmdzXG4gICAqIEBwYXJhbSBwYXJzZXJDb25maWcgLSBUaGUgY3VycmVudCBwYXJzZXIgY29uZmlnXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGN1cnJlbnQgUGFyc2VPcHRpb25zXG4gICAqL1xuICBjaGVja091dHB1dEJpbmRpbmdzKGJpbmRpbmdzOiB7W2tleTogc3RyaW5nXTogUmljaEJpbmRpbmdEYXRhfSwgcGFyc2VyQ29uZmlnOiBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcsIG9wdGlvbnM6IFBhcnNlT3B0aW9ucykge1xuICAgIGZvciAoY29uc3QgW291dHB1dE5hbWUsIG91dHB1dEJpbmRpbmddIG9mIE9iamVjdC5lbnRyaWVzKGJpbmRpbmdzKSkge1xuICAgICAgLy8gVW5saWtlIGlucHV0cywgb3V0cHV0cyBvbmx5IG5lZWQgdG8gYmUgY3JlYXRlZCBvbmNlIGJ5IHRoZSBwYXJzZXIsIG5ldmVyIHVwZGF0ZWQsIGFzIHlvdSBvbmx5IGNyZWF0ZSBhIHdyYXBwZXIgZnVuY3Rpb24gYXJvdW5kIHRoZSBsb2dpYyB0byBleGVjdXRlLlxuICAgICAgLy8gQXMgdGhpcyBsb2dpYyBpcyBydW4gZnJlc2ggd2hlbmV2ZXIgdGhlIG91dHB1dCB0cmlnZ2VycywgdGhlcmUgaXMgbm8gbmVlZCB0byByZXBsYWNlIHRoaXMgd3JhcHBlciBmdW5jdGlvbiBvbiB1cGRhdGVzLlxuICAgICAgaWYgKCFvdXRwdXRCaW5kaW5nLnBhcnNlZCkge1xuICAgICAgICBvdXRwdXRCaW5kaW5nLnZhbHVlID0gKGV2ZW50OiBhbnksIGNvbnRleHQ6IGFueSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFUeXBlUGFyc2VyLmV2YWx1YXRlKFxuICAgICAgICAgICAgICBvdXRwdXRCaW5kaW5nLnJhdyxcbiAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmFsbG93Q29udGV4dEluQmluZGluZ3MgPyBjb250ZXh0IDoge30sXG4gICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICBwYXJzZXJDb25maWcudW5lc2NhcGVTdHJpbmdzLFxuICAgICAgICAgICAgICBvdXRwdXRCaW5kaW5nLmJvdW5kQ29udGV4dFZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmFsbG93Q29udGV4dEZ1bmN0aW9uQ2FsbHNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihbYEhvb2sgb3V0cHV0IHBhcnNpbmcgZXJyb3JcXG5zZWxlY3RvcjogYCArIHBhcnNlckNvbmZpZy5zZWxlY3RvciArICBgXFxub3V0cHV0OiBgICsgb3V0cHV0TmFtZSArIGBcXG52YWx1ZTogXCJgICsgb3V0cHV0QmluZGluZy52YWx1ZSArIGBcImBdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFtlLnN0YWNrXSwgb3B0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBvdXRwdXRCaW5kaW5nLnBhcnNlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==