UNPKG

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.

133 lines 22 kB
/** * An element parser to load components with their bindings like in Angular templates. */ export class ElementSelectorHookParser { constructor(config, configResolver, platformService, bindingsValueManager) { this.configResolver = configResolver; this.platformService = platformService; this.bindingsValueManager = bindingsValueManager; this.savedBindings = {}; this.config = this.configResolver.processConfig(config); this.name = this.config.name; } findHookElements(contentElement, context, options) { return Array.from(this.platformService.querySelectorAll(contentElement, this.config.selector)); } loadComponent(hookId, hookValue, context, childNodes, options) { // Always scrub potential []-input- and ()-output-attrs from anchor elements this.scrubAngularBindingAttrs(hookValue.element); return { component: this.config.component, hostElementTag: this.config.hostElementTag, injector: this.config.injector, environmentInjector: this.config.environmentInjector }; } getBindings(hookId, hookValue, context, options) { let hookBindings = this.savedBindings[hookId]; // Parse bindings once from hookValue, then reuse on subsequent runs (raw values will never change as hookValue.element is a snapshot) if (hookBindings === undefined) { hookBindings = this.createBindings(hookValue.elementSnapshot); this.savedBindings[hookId] = hookBindings; } // (Re)evaluate if needed this.bindingsValueManager.checkInputBindings(hookBindings.inputs, context, this.config, options); this.bindingsValueManager.checkOutputBindings(hookBindings.outputs, this.config, options); return { inputs: this.getValuesFromSavedBindings(hookBindings.inputs), outputs: this.getValuesFromSavedBindings(hookBindings.outputs) }; } // Bindings // -------------------------------------------------------------------------- /** * Always removes angular-typical template attrs like []-input and ()-outputs from anchors * * @param anchorElement - The element to strub */ scrubAngularBindingAttrs(anchorElement) { const attrsToScrub = Array.from(anchorElement.attributes) .map((attrObj) => attrObj.name) .filter((attr) => (attr.startsWith('[') && attr.endsWith(']')) || (attr.startsWith('(') && attr.endsWith(')'))); for (const attr of attrsToScrub) { this.platformService.removeAttribute(anchorElement, attr); } } /** * Returns RichBindingData for Angular-style inputs & output attrs from an element * * @param element - The element to inspect */ createBindings(element) { const rawInputs = this.collectRawBindings(element, 'inputs', this.config.inputsBlacklist || null, this.config.inputsWhitelist || null); const inputBindings = {}; for (const [rawInputKey, rawInputValue] of Object.entries(rawInputs)) { inputBindings[rawInputKey] = { raw: rawInputValue, parsed: false, value: null, boundContextVariables: {} }; } const rawOutputs = this.collectRawBindings(element, 'outputs', this.config.outputsBlacklist || null, this.config.outputsWhitelist || null); const outputBindings = {}; for (const [rawOutputKey, rawOutputValue] of Object.entries(rawOutputs)) { outputBindings[rawOutputKey] = { raw: rawOutputValue, parsed: false, value: null, boundContextVariables: {} }; } return { inputs: inputBindings, outputs: outputBindings }; } /** * Returns Angular-style inputs or output attrs from an element * * @param element - The element to inspect * @param type - Whether to return the inputs or outputs * @param blacklist - A list of inputs/outputs to blacklist * @param whitelist - A list of inputs/outputs to whitelist */ collectRawBindings(element, type, blacklist, whitelist) { const bindings = {}; // Collect raw bindings const attrNames = this.platformService.getAttributeNames(element); for (let attrName of attrNames) { if (type === 'inputs' && (!attrName.startsWith('(') || !attrName.endsWith(')')) || type === 'outputs' && (attrName.startsWith('(') && attrName.endsWith(')'))) { let binding = this.platformService.getAttribute(element, attrName); // If input has []-brackets: Transform empty attr to undefined if (type === 'inputs' && attrName.startsWith('[') && attrName.endsWith(']') && binding === '') { binding = undefined; } // If input has no []-brackets: Should be interpreted as plain strings, so wrap in quotes if (type === 'inputs' && (!attrName.startsWith('[') || !attrName.endsWith(']'))) { binding = `'${binding}'`; } // Trim [] and () brackets from attr name attrName = attrName.replace(/^\[|^\(|\]$|\)$/g, ''); bindings[attrName] = binding; } } // Filter bindings const filteredBindings = {}; for (const [bindingName, bindingValue] of Object.entries(bindings)) { if (blacklist && blacklist.includes(bindingName)) { continue; } if (whitelist && !whitelist.includes(bindingName)) { continue; } filteredBindings[bindingName] = bindingValue; } return filteredBindings; } /** * Transforms a RichBindingData object into a normal bindings object * * @param richBindingsObject - The object containing the RichBindingData */ getValuesFromSavedBindings(richBindingsObject) { const result = {}; for (const [key, value] of Object.entries(richBindingsObject)) { result[key] = value.value; } return result; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudFNlbGVjdG9ySG9va1BhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvcGFyc2Vycy9zZWxlY3Rvci9lbGVtZW50L2VsZW1lbnRTZWxlY3Rvckhvb2tQYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUE7O0dBRUc7QUFDSCxNQUFNLE9BQU8seUJBQXlCO0lBS3BDLFlBQVksTUFBZ0MsRUFBVSxjQUFnRCxFQUFVLGVBQW9DLEVBQVUsb0JBQTBDO1FBQWxKLG1CQUFjLEdBQWQsY0FBYyxDQUFrQztRQUFVLG9CQUFlLEdBQWYsZUFBZSxDQUFxQjtRQUFVLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFGeE0sa0JBQWEsR0FBbUMsRUFBRSxDQUFDO1FBR2pELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRU0sZ0JBQWdCLENBQUMsY0FBbUIsRUFBRSxPQUFZLEVBQUUsT0FBcUI7UUFDOUUsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUyxDQUFDLENBQUMsQ0FBQztJQUNsRyxDQUFDO0lBRU0sYUFBYSxDQUFDLE1BQWMsRUFBRSxTQUFvQixFQUFFLE9BQVksRUFBRSxVQUFpQixFQUFFLE9BQXFCO1FBRS9HLDZFQUE2RTtRQUM3RSxJQUFJLENBQUMsd0JBQXdCLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWpELE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTO1lB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UUFFRCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssMEJBQTBCLENBQUMsa0JBQW9EO1FBQ3JGLE1BQU0sTUFBTSxHQUF5QixFQUFFLENBQUM7UUFDeEMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1lBQzlELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzVCLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSaWNoQmluZGluZ0RhdGEsIFNhdmVkQmluZGluZ3MgfSBmcm9tICcuLi8uLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEhvb2tQYXJzZXIsIEhvb2tWYWx1ZSwgSG9va0NvbXBvbmVudERhdGEsIEhvb2tCaW5kaW5ncyB9IGZyb20gJy4uLy4uLy4uL2ludGVyZmFjZXNQdWJsaWMnO1xuaW1wb3J0IHsgQmluZGluZ3NWYWx1ZU1hbmFnZXIgfSBmcm9tICcuLi9iaW5kaW5nc1ZhbHVlTWFuYWdlcic7XG5pbXBvcnQgeyBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcgfSBmcm9tICcuLi9zZWxlY3Rvckhvb2tQYXJzZXJDb25maWcnO1xuaW1wb3J0IHsgU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnUmVzb2x2ZXIgfSBmcm9tICcuLi9zZWxlY3Rvckhvb2tQYXJzZXJDb25maWdSZXNvbHZlcic7XG5pbXBvcnQgeyBBdXRvUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcGxhdGZvcm0vYXV0b1BsYXRmb3JtU2VydmljZSc7XG5pbXBvcnQgeyBQYXJzZU9wdGlvbnMgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9zZXR0aW5ncy9vcHRpb25zJztcblxuLyoqXG4gKiBBbiBlbGVtZW50IHBhcnNlciB0byBsb2FkIGNvbXBvbmVudHMgd2l0aCB0aGVpciBiaW5kaW5ncyBsaWtlIGluIEFuZ3VsYXIgdGVtcGxhdGVzLlxuICovXG5leHBvcnQgY2xhc3MgRWxlbWVudFNlbGVjdG9ySG9va1BhcnNlciBpbXBsZW1lbnRzIEhvb2tQYXJzZXIge1xuICBuYW1lOiBzdHJpbmd8dW5kZWZpbmVkO1xuICBjb25maWc6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZztcbiAgc2F2ZWRCaW5kaW5nczoge1trZXk6IG51bWJlcl06IFNhdmVkQmluZGluZ3N9ID0ge307XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcsIHByaXZhdGUgY29uZmlnUmVzb2x2ZXI6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZ1Jlc29sdmVyLCBwcml2YXRlIHBsYXRmb3JtU2VydmljZTogQXV0b1BsYXRmb3JtU2VydmljZSwgcHJpdmF0ZSBiaW5kaW5nc1ZhbHVlTWFuYWdlcjogQmluZGluZ3NWYWx1ZU1hbmFnZXIpIHtcbiAgICB0aGlzLmNvbmZpZyA9IHRoaXMuY29uZmlnUmVzb2x2ZXIucHJvY2Vzc0NvbmZpZyhjb25maWcpO1xuICAgIHRoaXMubmFtZSA9IHRoaXMuY29uZmlnLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgZmluZEhvb2tFbGVtZW50cyhjb250ZW50RWxlbWVudDogYW55LCBjb250ZXh0OiBhbnksIG9wdGlvbnM6IFBhcnNlT3B0aW9ucyk6IGFueVtdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnBsYXRmb3JtU2VydmljZS5xdWVyeVNlbGVjdG9yQWxsKGNvbnRlbnRFbGVtZW50LCB0aGlzLmNvbmZpZy5zZWxlY3RvciEpKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkQ29tcG9uZW50KGhvb2tJZDogbnVtYmVyLCBob29rVmFsdWU6IEhvb2tWYWx1ZSwgY29udGV4dDogYW55LCBjaGlsZE5vZGVzOiBhbnlbXSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogSG9va0NvbXBvbmVudERhdGEge1xuXG4gICAgLy8gQWx3YXlzIHNjcnViIHBvdGVudGlhbCBbXS1pbnB1dC0gYW5kICgpLW91dHB1dC1hdHRycyBmcm9tIGFuY2hvciBlbGVtZW50cyBcbiAgICB0aGlzLnNjcnViQW5ndWxhckJpbmRpbmdBdHRycyhob29rVmFsdWUuZWxlbWVudCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcG9uZW50OiB0aGlzLmNvbmZpZy5jb21wb25lbnQsXG4gICAgICBob3N0RWxlbWVudFRhZzogdGhpcy5jb25maWcuaG9zdEVsZW1lbnRUYWcsXG4gICAgICBpbmplY3RvcjogdGhpcy5jb25maWcuaW5qZWN0b3IsXG4gICAgICBlbnZpcm9ubWVudEluamVjdG9yOiB0aGlzLmNvbmZpZy5lbnZpcm9ubWVudEluamVjdG9yXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRCaW5kaW5ncyhob29rSWQ6IG51bWJlciwgaG9va1ZhbHVlOiBIb29rVmFsdWUsIGNvbnRleHQ6IGFueSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogSG9va0JpbmRpbmdzIHtcbiAgICBsZXQgaG9va0JpbmRpbmdzID0gdGhpcy5zYXZlZEJpbmRpbmdzW2hvb2tJZF07XG5cbiAgICAvLyBQYXJzZSBiaW5kaW5ncyBvbmNlIGZyb20gaG9va1ZhbHVlLCB0aGVuIHJldXNlIG9uIHN1YnNlcXVlbnQgcnVucyAocmF3IHZhbHVlcyB3aWxsIG5ldmVyIGNoYW5nZSBhcyBob29rVmFsdWUuZWxlbWVudCBpcyBhIHNuYXBzaG90KVxuICAgIGlmIChob29rQmluZGluZ3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaG9va0JpbmRpbmdzID0gdGhpcy5jcmVhdGVCaW5kaW5ncyhob29rVmFsdWUuZWxlbWVudFNuYXBzaG90ISk7XG4gICAgICB0aGlzLnNhdmVkQmluZGluZ3NbaG9va0lkXSA9IGhvb2tCaW5kaW5ncztcbiAgICB9XG5cbiAgICAvLyAoUmUpZXZhbHVhdGUgaWYgbmVlZGVkXG4gICAgdGhpcy5iaW5kaW5nc1ZhbHVlTWFuYWdlci5jaGVja0lucHV0QmluZGluZ3MoaG9va0JpbmRpbmdzLmlucHV0cyEsIGNvbnRleHQsIHRoaXMuY29uZmlnLCBvcHRpb25zKTtcbiAgICB0aGlzLmJpbmRpbmdzVmFsdWVNYW5hZ2VyLmNoZWNrT3V0cHV0QmluZGluZ3MoaG9va0JpbmRpbmdzLm91dHB1dHMhLCB0aGlzLmNvbmZpZywgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXRzOiB0aGlzLmdldFZhbHVlc0Zyb21TYXZlZEJpbmRpbmdzKGhvb2tCaW5kaW5ncy5pbnB1dHMhKSxcbiAgICAgIG91dHB1dHM6IHRoaXMuZ2V0VmFsdWVzRnJvbVNhdmVkQmluZGluZ3MoaG9va0JpbmRpbmdzLm91dHB1dHMhKVxuICAgIH07XG4gIH1cblxuICAvLyBCaW5kaW5nc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBBbHdheXMgcmVtb3ZlcyBhbmd1bGFyLXR5cGljYWwgdGVtcGxhdGUgYXR0cnMgbGlrZSBbXS1pbnB1dCBhbmQgKCktb3V0cHV0cyBmcm9tIGFuY2hvcnNcbiAgICpcbiAgICogQHBhcmFtIGFuY2hvckVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBzdHJ1YlxuICAgKi9cbiAgc2NydWJBbmd1bGFyQmluZGluZ0F0dHJzKGFuY2hvckVsZW1lbnQ6IGFueSkge1xuICAgIGNvbnN0IGF0dHJzVG9TY3J1YiA9IEFycmF5LmZyb20oYW5jaG9yRWxlbWVudC5hdHRyaWJ1dGVzKVxuICAgICAgLm1hcCgoYXR0ck9iajogYW55KSA9PiBhdHRyT2JqLm5hbWUpXG4gICAgICAuZmlsdGVyKChhdHRyOiBzdHJpbmcpID0+IFxuICAgICAgICAoYXR0ci5zdGFydHNXaXRoKCdbJykgJiYgYXR0ci5lbmRzV2l0aCgnXScpKSB8fFxuICAgICAgICAoYXR0ci5zdGFydHNXaXRoKCcoJykgJiYgYXR0ci5lbmRzV2l0aCgnKScpKVxuICAgICAgKTtcblxuICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyc1RvU2NydWIpIHtcbiAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLnJlbW92ZUF0dHJpYnV0ZShhbmNob3JFbGVtZW50LCBhdHRyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBSaWNoQmluZGluZ0RhdGEgZm9yIEFuZ3VsYXItc3R5bGUgaW5wdXRzICYgb3V0cHV0IGF0dHJzIGZyb20gYW4gZWxlbWVudFxuICAgKiBcbiAgICogQHBhcmFtIGVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBpbnNwZWN0XG4gICAqL1xuICBjcmVhdGVCaW5kaW5ncyhlbGVtZW50OiBhbnkpOiBTYXZlZEJpbmRpbmdzIHtcbiAgICBjb25zdCByYXdJbnB1dHMgPSB0aGlzLmNvbGxlY3RSYXdCaW5kaW5ncyhlbGVtZW50ISwgJ2lucHV0cycsIHRoaXMuY29uZmlnLmlucHV0c0JsYWNrbGlzdCB8fCBudWxsLCB0aGlzLmNvbmZpZy5pbnB1dHNXaGl0ZWxpc3QgfHwgbnVsbCk7XG4gICAgY29uc3QgaW5wdXRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IFJpY2hCaW5kaW5nRGF0YX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtyYXdJbnB1dEtleSwgcmF3SW5wdXRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocmF3SW5wdXRzKSkge1xuICAgICAgaW5wdXRCaW5kaW5nc1tyYXdJbnB1dEtleV0gPSB7cmF3OiByYXdJbnB1dFZhbHVlLCBwYXJzZWQ6IGZhbHNlLCB2YWx1ZTogbnVsbCwgYm91bmRDb250ZXh0VmFyaWFibGVzOiB7fX07XG4gICAgfVxuXG4gICAgY29uc3QgcmF3T3V0cHV0cyA9IHRoaXMuY29sbGVjdFJhd0JpbmRpbmdzKGVsZW1lbnQhLCAnb3V0cHV0cycsIHRoaXMuY29uZmlnLm91dHB1dHNCbGFja2xpc3QgfHwgbnVsbCwgdGhpcy5jb25maWcub3V0cHV0c1doaXRlbGlzdCB8fCBudWxsKTtcbiAgICBjb25zdCBvdXRwdXRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IFJpY2hCaW5kaW5nRGF0YX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtyYXdPdXRwdXRLZXksIHJhd091dHB1dFZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyYXdPdXRwdXRzKSkge1xuICAgICAgb3V0cHV0QmluZGluZ3NbcmF3T3V0cHV0S2V5XSA9IHtyYXc6IHJhd091dHB1dFZhbHVlLCBwYXJzZWQ6IGZhbHNlLCB2YWx1ZTogbnVsbCwgYm91bmRDb250ZXh0VmFyaWFibGVzOiB7fX07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0czogaW5wdXRCaW5kaW5ncyxcbiAgICAgIG91dHB1dHM6IG91dHB1dEJpbmRpbmdzXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIEFuZ3VsYXItc3R5bGUgaW5wdXRzIG9yIG91dHB1dCBhdHRycyBmcm9tIGFuIGVsZW1lbnRcbiAgICogXG4gICAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gaW5zcGVjdFxuICAgKiBAcGFyYW0gdHlwZSAtIFdoZXRoZXIgdG8gcmV0dXJuIHRoZSBpbnB1dHMgb3Igb3V0cHV0c1xuICAgKiBAcGFyYW0gYmxhY2tsaXN0IC0gQSBsaXN0IG9mIGlucHV0cy9vdXRwdXRzIHRvIGJsYWNrbGlzdFxuICAgKiBAcGFyYW0gd2hpdGVsaXN0IC0gQSBsaXN0IG9mIGlucHV0cy9vdXRwdXRzIHRvIHdoaXRlbGlzdFxuICAgKi9cbiAgY29sbGVjdFJhd0JpbmRpbmdzIChlbGVtZW50OiBhbnksIHR5cGU6ICdpbnB1dHMnfCdvdXRwdXRzJywgYmxhY2tsaXN0OiBzdHJpbmdbXXxudWxsLCB3aGl0ZWxpc3Q6IHN0cmluZ1tdfG51bGwpOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gICAgY29uc3QgYmluZGluZ3M6IHtba2V5OiBzdHJpbmddOiBhbnl9ID0ge307XG5cbiAgICAvLyBDb2xsZWN0IHJhdyBiaW5kaW5nc1xuICAgIGNvbnN0IGF0dHJOYW1lcyA9IHRoaXMucGxhdGZvcm1TZXJ2aWNlLmdldEF0dHJpYnV0ZU5hbWVzKGVsZW1lbnQpO1xuICAgIGZvciAobGV0IGF0dHJOYW1lIG9mIGF0dHJOYW1lcykge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlID09PSAnaW5wdXRzJyAmJiAoIWF0dHJOYW1lLnN0YXJ0c1dpdGgoJygnKSB8fCAhYXR0ck5hbWUuZW5kc1dpdGgoJyknKSkgfHxcbiAgICAgICAgdHlwZSA9PT0gJ291dHB1dHMnICYmIChhdHRyTmFtZS5zdGFydHNXaXRoKCcoJykgJiYgYXR0ck5hbWUuZW5kc1dpdGgoJyknKSlcbiAgICAgICkge1xuICAgICAgICBsZXQgYmluZGluZzogYW55ID0gdGhpcy5wbGF0Zm9ybVNlcnZpY2UuZ2V0QXR0cmlidXRlKGVsZW1lbnQsIGF0dHJOYW1lKTtcblxuICAgICAgICAvLyBJZiBpbnB1dCBoYXMgW10tYnJhY2tldHM6IFRyYW5zZm9ybSBlbXB0eSBhdHRyIHRvIHVuZGVmaW5lZFxuICAgICAgICBpZiAodHlwZSA9PT0gJ2lucHV0cycgJiYgYXR0ck5hbWUuc3RhcnRzV2l0aCgnWycpICYmIGF0dHJOYW1lLmVuZHNXaXRoKCddJykgJiYgYmluZGluZyA9PT0gJycpIHtcbiAgICAgICAgICBiaW5kaW5nID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgaW5wdXQgaGFzIG5vIFtdLWJyYWNrZXRzOiBTaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgcGxhaW4gc3RyaW5ncywgc28gd3JhcCBpbiBxdW90ZXNcbiAgICAgICAgaWYgKHR5cGUgPT09ICdpbnB1dHMnICYmICghYXR0ck5hbWUuc3RhcnRzV2l0aCgnWycpIHx8ICFhdHRyTmFtZS5lbmRzV2l0aCgnXScpKSkge1xuICAgICAgICAgIGJpbmRpbmcgPSBgJyR7YmluZGluZ30nYDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaW0gW10gYW5kICgpIGJyYWNrZXRzIGZyb20gYXR0ciBuYW1lXG4gICAgICAgIGF0dHJOYW1lID0gYXR0ck5hbWUucmVwbGFjZSgvXlxcW3xeXFwofFxcXSR8XFwpJC9nLCAnJyk7XG5cbiAgICAgICAgYmluZGluZ3NbYXR0ck5hbWVdID0gYmluZGluZztcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gRmlsdGVyIGJpbmRpbmdzXG4gICAgY29uc3QgZmlsdGVyZWRCaW5kaW5nczoge1trZXk6IHN0cmluZ106IGFueX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtiaW5kaW5nTmFtZSwgYmluZGluZ1ZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhiaW5kaW5ncykpIHtcbiAgICAgIGlmIChibGFja2xpc3QgJiYgYmxhY2tsaXN0LmluY2x1ZGVzKGJpbmRpbmdOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh3aGl0ZWxpc3QgJiYgIXdoaXRlbGlzdC5pbmNsdWRlcyhiaW5kaW5nTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBmaWx0ZXJlZEJpbmRpbmdzW2JpbmRpbmdOYW1lXSA9IGJpbmRpbmdWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyZWRCaW5kaW5ncztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm1zIGEgUmljaEJpbmRpbmdEYXRhIG9iamVjdCBpbnRvIGEgbm9ybWFsIGJpbmRpbmdzIG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gcmljaEJpbmRpbmdzT2JqZWN0IC0gVGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBSaWNoQmluZGluZ0RhdGFcbiAgICovXG4gIHByaXZhdGUgZ2V0VmFsdWVzRnJvbVNhdmVkQmluZGluZ3MocmljaEJpbmRpbmdzT2JqZWN0OiB7W2tleTogc3RyaW5nXTogUmljaEJpbmRpbmdEYXRhfSk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICBjb25zdCByZXN1bHQ6IHtba2V5OiBzdHJpbmddOiBhbnl9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocmljaEJpbmRpbmdzT2JqZWN0KSkge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZS52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIl19