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.

211 lines 29.4 kB
import { Injectable, reflectComponentType } from '@angular/core'; import { TextSelectorHookParser } from '../../parsers/selector/text/textSelectorHookParser'; import { ElementSelectorHookParser } from '../../parsers/selector/element/elementSelectorHookParser'; import * as i0 from "@angular/core"; import * as i1 from "../../parsers/selector/selectorHookParserConfigResolver"; import * as i2 from "../platform/autoPlatformService"; import * as i3 from "../../parsers/selector/text/tagHookFinder"; import * as i4 from "../../parsers/selector/bindingsValueManager"; import * as i5 from "../utils/logger"; /** * A helper class for resolving HookParserEntries */ export class ParserEntryResolver { constructor(injector, parserResolver, platformService, tagHookFinder, bindingsValueManager, logger) { this.injector = injector; this.parserResolver = parserResolver; this.platformService = platformService; this.tagHookFinder = tagHookFinder; this.bindingsValueManager = bindingsValueManager; this.logger = logger; } /** * Takes a list of HookParserEntries and transforms them into a list of loaded HookParsers * * @param parserEntries - The list of HookParserEntries to process * @param injector - The injector to use for resolving parsers * @param blacklist - (optional) Which parsers to blacklist by name * @param whitelist - (optional) Which parsers to whitelist by name * @param options - The current ParseOptions */ resolve(parserEntries, injector, blacklist, whitelist, options) { // Load all requested parsers const parsers = []; for (const parser of parserEntries) { const resolvedParser = this.resolveEntry(parser, injector, options); if (resolvedParser) { parsers.push(resolvedParser); } } // Check parser functions const validParsers = this.validateParserFunctions(parsers, options); // Check parser names this.checkParserNames(validParsers, options); // If no need to filter, return resolved parsers if (!blacklist && !whitelist) { return validParsers; } // Check black/whitelist this.checkBlackAndWhitelist(validParsers, blacklist, whitelist, options); // Filter parsers const filteredParsers = []; for (const validParser of validParsers) { if (validParser.hasOwnProperty('name') && typeof validParser.name === 'string') { if (blacklist && blacklist.includes(validParser.name)) { continue; } if (whitelist && !whitelist.includes(validParser.name)) { continue; } } filteredParsers.push(validParser); } return filteredParsers; } /** * Figures out what kind of config type the HookParserEntry is and loads it appropriately. * * The potential types are: * - 1. a component class (shorthand for nr. 5) * - 2. a parser service * - 3. a parser class * - 4. a parser instance * - 5. an object literal to configure SelectorHookParser with * * @param parserEntry - The HookParserEntry to process * @param injector - The injector to use for resolving this parser * @param options - The current ParseOptions */ resolveEntry(parserEntry, injector, options) { // Check if class if (parserEntry.hasOwnProperty('prototype')) { // Check if component class const componentMeta = reflectComponentType(parserEntry); if (componentMeta) { return this.createSelectorHookParser({ component: parserEntry }); // Else must be parser class } else { // Check if service try { return injector.get(parserEntry); // Otherwise instantiate manually } catch (e) { return new parserEntry(); } } } // Check if object else if (typeof parserEntry === 'object') { // Is instance if (parserEntry.constructor.name !== 'Object') { return parserEntry; // Is object literal } else { try { return this.createSelectorHookParser(parserEntry); } catch (e) { this.logger.error(['Invalid parser config - ' + e.message, parserEntry], options); return null; } } } this.logger.error(['Invalid parser config - ', parserEntry], options); return null; } /** * Depending on the config, load either string or element SelectorHookParser * * @param config - The selectorHookParserConfig */ createSelectorHookParser(config) { if ((config.hasOwnProperty('parseWithRegex') && config.parseWithRegex) || (config.hasOwnProperty('enclosing') && !config.enclosing) || (config.hasOwnProperty('bracketStyle') && config.bracketStyle)) { return new TextSelectorHookParser(config, this.parserResolver, this.tagHookFinder, this.bindingsValueManager); } else { return new ElementSelectorHookParser(config, this.parserResolver, this.platformService, this.bindingsValueManager); } } /** * Makes sure that the parsers have all required functions * * @param parsers - The parsers in question * @param options - The current ParseOptions */ validateParserFunctions(parsers, options) { const validParsers = []; for (const parser of parsers) { if (typeof parser.findHooks !== 'function' && typeof parser.findHookElements !== 'function') { this.logger.error(['Submitted parser neither implements "findHooks()" nor "findHookElements()". One is required. Removing from list of active parsers:', parser], options); continue; } if (typeof parser.loadComponent !== 'function') { this.logger.error(['Submitted parser does not implement "loadComponent()". Removing from list of active parsers:', parser], options); continue; } if (typeof parser.getBindings !== 'function') { this.logger.error(['Submitted parser does not implement "getBindings()". Removing from list of active parsers:', parser], options); continue; } validParsers.push(parser); } return validParsers; } /** * Makes sure that all parser names are unique * * @param parsers - The parsers in question * @param options - The current ParseOptions */ checkParserNames(parsers, options) { const parserNames = parsers.map(entry => entry.name).filter(entry => entry !== undefined); const previousNames = []; const alreadyWarnedNames = []; for (const parserName of parserNames) { if (previousNames.includes(parserName) && !alreadyWarnedNames.includes(parserName)) { this.logger.warn(['Parser name "' + parserName + '" is not unique and appears multiple times in the list of active parsers.'], options); alreadyWarnedNames.push(parserName); } previousNames.push(parserName); } } /** * A black/whitelist validation function for the benefit of the user. Outputs warnings in the console if something is off. * * @param parsers - The parsers in question * @param blacklist - The blacklist in question * @param whitelist - The whitelist in question * @param options - The current ParseOptions */ checkBlackAndWhitelist(parsers, blacklist, whitelist, options) { const parserNames = parsers.map(entry => entry.name).filter(entry => entry !== undefined); if (blacklist) { for (const blacklistedParser of blacklist) { if (!parserNames.includes(blacklistedParser)) { this.logger.warn(['Blacklisted parser name "' + blacklistedParser + '" does not appear in the list of global parsers names. Make sure both spellings are identical.'], options); } } } if (whitelist) { for (const whitelistedParser of whitelist) { if (!parserNames.includes(whitelistedParser)) { this.logger.warn(['Whitelisted parser name "' + whitelistedParser + '" does not appear in the list of global parsers names. Make sure both spellings are identical.'], options); } } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ParserEntryResolver, deps: [{ token: i0.Injector }, { token: i1.SelectorHookParserConfigResolver }, { token: i2.AutoPlatformService }, { token: i3.TagHookFinder }, { token: i4.BindingsValueManager }, { token: i5.Logger }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ParserEntryResolver, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ParserEntryResolver, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.SelectorHookParserConfigResolver }, { type: i2.AutoPlatformService }, { type: i3.TagHookFinder }, { type: i4.BindingsValueManager }, { type: i5.Logger }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyRW50cnlSZXNvbHZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvc2VydmljZXMvc2V0dGluZ3MvcGFyc2VyRW50cnlSZXNvbHZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFZLG9CQUFvQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG9EQUFvRCxDQUFDO0FBTTVGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDBEQUEwRCxDQUFDOzs7Ozs7O0FBS3JHOztHQUVHO0FBSUgsTUFBTSxPQUFPLG1CQUFtQjtJQUU5QixZQUNVLFFBQWtCLEVBQ2xCLGNBQWdELEVBQ2hELGVBQW9DLEVBQ3BDLGFBQTRCLEVBQzVCLG9CQUEwQyxFQUMxQyxNQUFjO1FBTGQsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixtQkFBYyxHQUFkLGNBQWMsQ0FBa0M7UUFDaEQsb0JBQWUsR0FBZixlQUFlLENBQXFCO1FBQ3BDLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUV4QixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxPQUFPLENBQUMsYUFBZ0MsRUFBRSxRQUFrQixFQUFFLFNBQXdCLEVBQUUsU0FBd0IsRUFBRSxPQUFxQjtRQUVySSw2QkFBNkI7UUFDN0IsTUFBTSxPQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUNqQyxLQUFLLE1BQU0sTUFBTSxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ25DLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRSxJQUFJLGNBQWMsRUFBRSxDQUFDO2dC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QkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIHJlZmxlY3RDb21wb25lbnRUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIb29rUGFyc2VyIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlc1B1YmxpYyc7XG5pbXBvcnQgeyBUZXh0U2VsZWN0b3JIb29rUGFyc2VyIH0gZnJvbSAnLi4vLi4vcGFyc2Vycy9zZWxlY3Rvci90ZXh0L3RleHRTZWxlY3Rvckhvb2tQYXJzZXInO1xuaW1wb3J0IHsgU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnIH0gZnJvbSAnLi4vLi4vcGFyc2Vycy9zZWxlY3Rvci9zZWxlY3Rvckhvb2tQYXJzZXJDb25maWcnO1xuaW1wb3J0IHsgU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnUmVzb2x2ZXIgfSBmcm9tICcuLi8uLi9wYXJzZXJzL3NlbGVjdG9yL3NlbGVjdG9ySG9va1BhcnNlckNvbmZpZ1Jlc29sdmVyJztcbmltcG9ydCB7IFRhZ0hvb2tGaW5kZXIgfSBmcm9tICcuLi8uLi9wYXJzZXJzL3NlbGVjdG9yL3RleHQvdGFnSG9va0ZpbmRlcic7XG5pbXBvcnQgeyBCaW5kaW5nc1ZhbHVlTWFuYWdlciB9IGZyb20gJy4uLy4uL3BhcnNlcnMvc2VsZWN0b3IvYmluZGluZ3NWYWx1ZU1hbmFnZXInO1xuaW1wb3J0IHsgSG9va1BhcnNlckVudHJ5IH0gZnJvbSAnLi9wYXJzZXJFbnRyeSc7XG5pbXBvcnQgeyBFbGVtZW50U2VsZWN0b3JIb29rUGFyc2VyIH0gZnJvbSAnLi4vLi4vcGFyc2Vycy9zZWxlY3Rvci9lbGVtZW50L2VsZW1lbnRTZWxlY3Rvckhvb2tQYXJzZXInO1xuaW1wb3J0IHsgQXV0b1BsYXRmb3JtU2VydmljZSB9IGZyb20gJy4uL3BsYXRmb3JtL2F1dG9QbGF0Zm9ybVNlcnZpY2UnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyJztcbmltcG9ydCB7IFBhcnNlT3B0aW9ucyB9IGZyb20gJy4uL3NldHRpbmdzL29wdGlvbnMnO1xuXG4vKipcbiAqIEEgaGVscGVyIGNsYXNzIGZvciByZXNvbHZpbmcgSG9va1BhcnNlckVudHJpZXNcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgUGFyc2VyRW50cnlSZXNvbHZlciB7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsIFxuICAgIHByaXZhdGUgcGFyc2VyUmVzb2x2ZXI6IFNlbGVjdG9ySG9va1BhcnNlckNvbmZpZ1Jlc29sdmVyLCBcbiAgICBwcml2YXRlIHBsYXRmb3JtU2VydmljZTogQXV0b1BsYXRmb3JtU2VydmljZSwgXG4gICAgcHJpdmF0ZSB0YWdIb29rRmluZGVyOiBUYWdIb29rRmluZGVyLCBcbiAgICBwcml2YXRlIGJpbmRpbmdzVmFsdWVNYW5hZ2VyOiBCaW5kaW5nc1ZhbHVlTWFuYWdlcixcbiAgICBwcml2YXRlIGxvZ2dlcjogTG9nZ2VyXG4gICkge1xuICB9XG5cbiAgLyoqXG4gICAqIFRha2VzIGEgbGlzdCBvZiBIb29rUGFyc2VyRW50cmllcyBhbmQgdHJhbnNmb3JtcyB0aGVtIGludG8gYSBsaXN0IG9mIGxvYWRlZCBIb29rUGFyc2Vyc1xuICAgKlxuICAgKiBAcGFyYW0gcGFyc2VyRW50cmllcyAtIFRoZSBsaXN0IG9mIEhvb2tQYXJzZXJFbnRyaWVzIHRvIHByb2Nlc3NcbiAgICogQHBhcmFtIGluamVjdG9yIC0gVGhlIGluamVjdG9yIHRvIHVzZSBmb3IgcmVzb2x2aW5nIHBhcnNlcnNcbiAgICogQHBhcmFtIGJsYWNrbGlzdCAtIChvcHRpb25hbCkgV2hpY2ggcGFyc2VycyB0byBibGFja2xpc3QgYnkgbmFtZVxuICAgKiBAcGFyYW0gd2hpdGVsaXN0IC0gKG9wdGlvbmFsKSBXaGljaCBwYXJzZXJzIHRvIHdoaXRlbGlzdCBieSBuYW1lXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGN1cnJlbnQgUGFyc2VPcHRpb25zXG4gICAqL1xuICByZXNvbHZlKHBhcnNlckVudHJpZXM6IEhvb2tQYXJzZXJFbnRyeVtdLCBpbmplY3RvcjogSW5qZWN0b3IsIGJsYWNrbGlzdDogc3RyaW5nW118bnVsbCwgd2hpdGVsaXN0OiBzdHJpbmdbXXxudWxsLCBvcHRpb25zOiBQYXJzZU9wdGlvbnMpOiBIb29rUGFyc2VyW10ge1xuXG4gICAgLy8gTG9hZCBhbGwgcmVxdWVzdGVkIHBhcnNlcnNcbiAgICBjb25zdCBwYXJzZXJzOiBIb29rUGFyc2VyW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhcnNlciBvZiBwYXJzZXJFbnRyaWVzKSB7XG4gICAgICBjb25zdCByZXNvbHZlZFBhcnNlciA9IHRoaXMucmVzb2x2ZUVudHJ5KHBhcnNlciwgaW5qZWN0b3IsIG9wdGlvbnMpO1xuICAgICAgaWYgKHJlc29sdmVkUGFyc2VyKSB7XG4gICAgICAgIHBhcnNlcnMucHVzaChyZXNvbHZlZFBhcnNlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgcGFyc2VyIGZ1bmN0aW9uc1xuICAgIGNvbnN0IHZhbGlkUGFyc2VycyA9IHRoaXMudmFsaWRhdGVQYXJzZXJGdW5jdGlvbnMocGFyc2Vycywgb3B0aW9ucyk7XG5cbiAgICAvLyBDaGVjayBwYXJzZXIgbmFtZXNcbiAgICB0aGlzLmNoZWNrUGFyc2VyTmFtZXModmFsaWRQYXJzZXJzLCBvcHRpb25zKTtcblxuICAgIC8vIElmIG5vIG5lZWQgdG8gZmlsdGVyLCByZXR1cm4gcmVzb2x2ZWQgcGFyc2Vyc1xuICAgIGlmICghYmxhY2tsaXN0ICYmICF3aGl0ZWxpc3QpIHtcbiAgICAgICAgcmV0dXJuIHZhbGlkUGFyc2VycztcbiAgICB9XG5cbiAgICAvLyBDaGVjayBibGFjay93aGl0ZWxpc3RcbiAgICB0aGlzLmNoZWNrQmxhY2tBbmRXaGl0ZWxpc3QodmFsaWRQYXJzZXJzLCBibGFja2xpc3QsIHdoaXRlbGlzdCwgb3B0aW9ucyk7XG5cbiAgICAvLyBGaWx0ZXIgcGFyc2Vyc1xuICAgIGNvbnN0IGZpbHRlcmVkUGFyc2VycyA9IFtdO1xuICAgIGZvciAoY29uc3QgdmFsaWRQYXJzZXIgb2YgdmFsaWRQYXJzZXJzKSB7XG4gICAgICBpZiAodmFsaWRQYXJzZXIuaGFzT3duUHJvcGVydHkoJ25hbWUnKSAmJiB0eXBlb2YgdmFsaWRQYXJzZXIubmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgaWYgKGJsYWNrbGlzdCAmJiBibGFja2xpc3QuaW5jbHVkZXModmFsaWRQYXJzZXIubmFtZSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAod2hpdGVsaXN0ICYmICF3aGl0ZWxpc3QuaW5jbHVkZXModmFsaWRQYXJzZXIubmFtZSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZmlsdGVyZWRQYXJzZXJzLnB1c2godmFsaWRQYXJzZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJlZFBhcnNlcnM7XG4gIH1cblxuICAvKipcbiAgICogRmlndXJlcyBvdXQgd2hhdCBraW5kIG9mIGNvbmZpZyB0eXBlIHRoZSBIb29rUGFyc2VyRW50cnkgaXMgYW5kIGxvYWRzIGl0IGFwcHJvcHJpYXRlbHkuXG4gICAqXG4gICAqIFRoZSBwb3RlbnRpYWwgdHlwZXMgYXJlOlxuICAgKiAtIDEuIGEgY29tcG9uZW50IGNsYXNzIChzaG9ydGhhbmQgZm9yIG5yLiA1KVxuICAgKiAtIDIuIGEgcGFyc2VyIHNlcnZpY2VcbiAgICogLSAzLiBhIHBhcnNlciBjbGFzc1xuICAgKiAtIDQuIGEgcGFyc2VyIGluc3RhbmNlXG4gICAqIC0gNS4gYW4gb2JqZWN0IGxpdGVyYWwgdG8gY29uZmlndXJlIFNlbGVjdG9ySG9va1BhcnNlciB3aXRoXG4gICAqXG4gICAqIEBwYXJhbSBwYXJzZXJFbnRyeSAtIFRoZSBIb29rUGFyc2VyRW50cnkgdG8gcHJvY2Vzc1xuICAgKiBAcGFyYW0gaW5qZWN0b3IgLSBUaGUgaW5qZWN0b3IgdG8gdXNlIGZvciByZXNvbHZpbmcgdGhpcyBwYXJzZXJcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgY3VycmVudCBQYXJzZU9wdGlvbnNcbiAgICovXG4gIHJlc29sdmVFbnRyeShwYXJzZXJFbnRyeTogSG9va1BhcnNlckVudHJ5LCBpbmplY3RvcjogSW5qZWN0b3IsIG9wdGlvbnM6IFBhcnNlT3B0aW9ucyk6IEhvb2tQYXJzZXJ8bnVsbCB7XG4gICAgLy8gQ2hlY2sgaWYgY2xhc3NcbiAgICBpZiAocGFyc2VyRW50cnkuaGFzT3duUHJvcGVydHkoJ3Byb3RvdHlwZScpKSB7XG4gICAgICAvLyBDaGVjayBpZiBjb21wb25lbnQgY2xhc3NcbiAgICAgIGNvbnN0IGNvbXBvbmVudE1ldGEgPSByZWZsZWN0Q29tcG9uZW50VHlwZShwYXJzZXJFbnRyeSBhcyBhbnkpO1xuICAgICAgaWYgKGNvbXBvbmVudE1ldGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2VsZWN0b3JIb29rUGFyc2VyKHtjb21wb25lbnQ6IHBhcnNlckVudHJ5IGFzIGFueX0pO1xuICAgICAgLy8gRWxzZSBtdXN0IGJlIHBhcnNlciBjbGFzc1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgc2VydmljZVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBpbmplY3Rvci5nZXQocGFyc2VyRW50cnkpO1xuICAgICAgICAvLyBPdGhlcndpc2UgaW5zdGFudGlhdGUgbWFudWFsbHlcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJldHVybiBuZXcgKHBhcnNlckVudHJ5IGFzIG5ldyguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgb2JqZWN0XG4gICAgZWxzZSBpZiAodHlwZW9mIHBhcnNlckVudHJ5ID09PSAnb2JqZWN0Jykge1xuICAgICAgLy8gSXMgaW5zdGFuY2VcbiAgICAgIGlmIChwYXJzZXJFbnRyeS5jb25zdHJ1Y3Rvci5uYW1lICE9PSAnT2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gcGFyc2VyRW50cnkgYXMgSG9va1BhcnNlcjtcbiAgICAgIC8vIElzIG9iamVjdCBsaXRlcmFsXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVNlbGVjdG9ySG9va1BhcnNlcihwYXJzZXJFbnRyeSBhcyBTZWxlY3Rvckhvb2tQYXJzZXJDb25maWcpO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpICB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoWydJbnZhbGlkIHBhcnNlciBjb25maWcgLSAnICsgZS5tZXNzYWdlLCBwYXJzZXJFbnRyeV0sIG9wdGlvbnMpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHRoaXMubG9nZ2VyLmVycm9yKFsnSW52YWxpZCBwYXJzZXIgY29uZmlnIC0gJywgcGFyc2VyRW50cnldLCBvcHRpb25zKVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIERlcGVuZGluZyBvbiB0aGUgY29uZmlnLCBsb2FkIGVpdGhlciBzdHJpbmcgb3IgZWxlbWVudCBTZWxlY3Rvckhvb2tQYXJzZXJcbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIFRoZSBzZWxlY3Rvckhvb2tQYXJzZXJDb25maWdcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlU2VsZWN0b3JIb29rUGFyc2VyKGNvbmZpZzogU2VsZWN0b3JIb29rUGFyc2VyQ29uZmlnKTogSG9va1BhcnNlciB7XG4gICAgaWYgKFxuICAgICAgKGNvbmZpZy5oYXNPd25Qcm9wZXJ0eSgncGFyc2VXaXRoUmVnZXgnKSAmJiBjb25maWcucGFyc2VXaXRoUmVnZXgpIHx8IFxuICAgICAgKGNvbmZpZy5oYXNPd25Qcm9wZXJ0eSgnZW5jbG9zaW5nJykgJiYgIWNvbmZpZy5lbmNsb3NpbmcpIHx8IFxuICAgICAgKGNvbmZpZy5oYXNPd25Qcm9wZXJ0eSgnYnJhY2tldFN0eWxlJykgJiYgY29uZmlnLmJyYWNrZXRTdHlsZSlcbiAgICApIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdG9ySG9va1BhcnNlcihjb25maWcsIHRoaXMucGFyc2VyUmVzb2x2ZXIsIHRoaXMudGFnSG9va0ZpbmRlciwgdGhpcy5iaW5kaW5nc1ZhbHVlTWFuYWdlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgRWxlbWVudFNlbGVjdG9ySG9va1BhcnNlcihjb25maWcsIHRoaXMucGFyc2VyUmVzb2x2ZXIsIHRoaXMucGxhdGZvcm1TZXJ2aWNlLCB0aGlzLmJpbmRpbmdzVmFsdWVNYW5hZ2VyKTtcbiAgICB9ICAgIFxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIHN1cmUgdGhhdCB0aGUgcGFyc2VycyBoYXZlIGFsbCByZXF1aXJlZCBmdW5jdGlvbnNcbiAgICpcbiAgICogQHBhcmFtIHBhcnNlcnMgLSBUaGUgcGFyc2VycyBpbiBxdWVzdGlvblxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjdXJyZW50IFBhcnNlT3B0aW9uc1xuICAgKi9cbiAgdmFsaWRhdGVQYXJzZXJGdW5jdGlvbnMocGFyc2VyczogSG9va1BhcnNlcltdLCBvcHRpb25zOiBQYXJzZU9wdGlvbnMpOiBIb29rUGFyc2VyW10ge1xuICAgIGNvbnN0IHZhbGlkUGFyc2VycyA9IFtdO1xuICAgIGZvciAoY29uc3QgcGFyc2VyIG9mIHBhcnNlcnMpIHtcbiAgICAgIGlmICh0eXBlb2YgcGFyc2VyLmZpbmRIb29rcyAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgcGFyc2VyLmZpbmRIb29rRWxlbWVudHMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoWydTdWJtaXR0ZWQgcGFyc2VyIG5laXRoZXIgaW1wbGVtZW50cyBcImZpbmRIb29rcygpXCIgbm9yIFwiZmluZEhvb2tFbGVtZW50cygpXCIuIE9uZSBpcyByZXF1aXJlZC4gUmVtb3ZpbmcgZnJvbSBsaXN0IG9mIGFjdGl2ZSBwYXJzZXJzOicsIHBhcnNlcl0sIG9wdGlvbnMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFyc2VyLmxvYWRDb21wb25lbnQgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoWydTdWJtaXR0ZWQgcGFyc2VyIGRvZXMgbm90IGltcGxlbWVudCBcImxvYWRDb21wb25lbnQoKVwiLiBSZW1vdmluZyBmcm9tIGxpc3Qgb2YgYWN0aXZlIHBhcnNlcnM6JywgcGFyc2VyXSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBwYXJzZXIuZ2V0QmluZGluZ3MgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoWydTdWJtaXR0ZWQgcGFyc2VyIGRvZXMgbm90IGltcGxlbWVudCBcImdldEJpbmRpbmdzKClcIi4gUmVtb3ZpbmcgZnJvbSBsaXN0IG9mIGFjdGl2ZSBwYXJzZXJzOicsIHBhcnNlcl0sIG9wdGlvbnMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhbGlkUGFyc2Vycy5wdXNoKHBhcnNlcik7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZFBhcnNlcnM7XG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgc3VyZSB0aGF0IGFsbCBwYXJzZXIgbmFtZXMgYXJlIHVuaXF1ZVxuICAgKlxuICAgKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIGluIHF1ZXN0aW9uXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGN1cnJlbnQgUGFyc2VPcHRpb25zXG4gICAqL1xuICBjaGVja1BhcnNlck5hbWVzKHBhcnNlcnM6IEhvb2tQYXJzZXJbXSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogdm9pZCB7XG4gICAgY29uc3QgcGFyc2VyTmFtZXM6IHN0cmluZ1tdID0gcGFyc2Vycy5tYXAoZW50cnkgPT4gZW50cnkubmFtZSkuZmlsdGVyKGVudHJ5ID0+IGVudHJ5ICE9PSB1bmRlZmluZWQpIGFzIHN0cmluZ1tdO1xuICAgIGNvbnN0IHByZXZpb3VzTmFtZXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgYWxyZWFkeVdhcm5lZE5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcGFyc2VyTmFtZSBvZiBwYXJzZXJOYW1lcykge1xuICAgICAgaWYgKHByZXZpb3VzTmFtZXMuaW5jbHVkZXMocGFyc2VyTmFtZSkgJiYgIWFscmVhZHlXYXJuZWROYW1lcy5pbmNsdWRlcyhwYXJzZXJOYW1lKSkge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKFsnUGFyc2VyIG5hbWUgXCInICsgcGFyc2VyTmFtZSArICdcIiBpcyBub3QgdW5pcXVlIGFuZCBhcHBlYXJzIG11bHRpcGxlIHRpbWVzIGluIHRoZSBsaXN0IG9mIGFjdGl2ZSBwYXJzZXJzLiddLCBvcHRpb25zKTtcbiAgICAgICAgYWxyZWFkeVdhcm5lZE5hbWVzLnB1c2gocGFyc2VyTmFtZSk7XG4gICAgICB9XG4gICAgICBwcmV2aW91c05hbWVzLnB1c2gocGFyc2VyTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEEgYmxhY2svd2hpdGVsaXN0IHZhbGlkYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBiZW5lZml0IG9mIHRoZSB1c2VyLiBPdXRwdXRzIHdhcm5pbmdzIGluIHRoZSBjb25zb2xlIGlmIHNvbWV0aGluZyBpcyBvZmYuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJzZXJzIC0gVGhlIHBhcnNlcnMgaW4gcXVlc3Rpb25cbiAgICogQHBhcmFtIGJsYWNrbGlzdCAtIFRoZSBibGFja2xpc3QgaW4gcXVlc3Rpb25cbiAgICogQHBhcmFtIHdoaXRlbGlzdCAtIFRoZSB3aGl0ZWxpc3QgaW4gcXVlc3Rpb25cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgY3VycmVudCBQYXJzZU9wdGlvbnNcbiAgICovXG4gIGNoZWNrQmxhY2tBbmRXaGl0ZWxpc3QocGFyc2VyczogSG9va1BhcnNlcltdLCBibGFja2xpc3Q6IHN0cmluZ1tdfG51bGwsIHdoaXRlbGlzdDogc3RyaW5nW118bnVsbCwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogdm9pZCB7XG4gICAgY29uc3QgcGFyc2VyTmFtZXM6IHN0cmluZ1tdID0gcGFyc2Vycy5tYXAoZW50cnkgPT4gZW50cnkubmFtZSkuZmlsdGVyKGVudHJ5ID0+IGVudHJ5ICE9PSB1bmRlZmluZWQpIGFzIHN0cmluZ1tdO1xuICAgIGlmIChibGFja2xpc3QpIHtcbiAgICAgIGZvciAoY29uc3QgYmxhY2tsaXN0ZWRQYXJzZXIgb2YgYmxhY2tsaXN0KSB7XG4gICAgICAgIGlmICghcGFyc2VyTmFtZXMuaW5jbHVkZXMoYmxhY2tsaXN0ZWRQYXJzZXIpKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIud2FybihbJ0JsYWNrbGlzdGVkIHBhcnNlciBuYW1lIFwiJyArIGJsYWNrbGlzdGVkUGFyc2VyICsgJ1wiIGRvZXMgbm90IGFwcGVhciBpbiB0aGUgbGlzdCBvZiBnbG9iYWwgcGFyc2VycyBuYW1lcy4gTWFrZSBzdXJlIGJvdGggc3BlbGxpbmdzIGFyZSBpZGVudGljYWwuJ10sIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh3aGl0ZWxpc3QpIHtcbiAgICAgIGZvciAoY29uc3Qgd2hpdGVsaXN0ZWRQYXJzZXIgb2Ygd2hpdGVsaXN0KSB7XG4gICAgICAgIGlmICghcGFyc2VyTmFtZXMuaW5jbHVkZXMod2hpdGVsaXN0ZWRQYXJzZXIpKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIud2FybihbJ1doaXRlbGlzdGVkIHBhcnNlciBuYW1lIFwiJyArIHdoaXRlbGlzdGVkUGFyc2VyICsgJ1wiIGRvZXMgbm90IGFwcGVhciBpbiB0aGUgbGlzdCBvZiBnbG9iYWwgcGFyc2VycyBuYW1lcy4gTWFrZSBzdXJlIGJvdGggc3BlbGxpbmdzIGFyZSBpZGVudGljYWwuJ10sIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==