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.

161 lines 25.7 kB
import { Injectable, Optional, Inject } from '@angular/core'; import { of } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { DYNAMICHOOKS_ALLSETTINGS, DYNAMICHOOKS_ANCESTORSETTINGS, DYNAMICHOOKS_MODULESETTINGS } from '../interfaces'; import { contentElementAttr } from '../constants/core'; import * as i0 from "@angular/core"; import * as i1 from "./settings/settingsResolver"; import * as i2 from "./core/textHookFinder"; import * as i3 from "./core/elementHookFinder"; import * as i4 from "./utils/contentSanitizer"; import * as i5 from "./core/componentCreator"; import * as i6 from "./platform/autoPlatformService"; /** * The core service for the ngx-dynamic-hooks library. Provides the main logic internally used by all components. */ export class DynamicHooksService { constructor(allSettings, ancestorSettings, moduleSettings, settingsResolver, textHookFinder, elementHookFinder, contentSanitizer, componentCreator, platformService, environmentInjector, injector) { this.allSettings = allSettings; this.ancestorSettings = ancestorSettings; this.moduleSettings = moduleSettings; this.settingsResolver = settingsResolver; this.textHookFinder = textHookFinder; this.elementHookFinder = elementHookFinder; this.contentSanitizer = contentSanitizer; this.componentCreator = componentCreator; this.platformService = platformService; this.environmentInjector = environmentInjector; this.injector = injector; } /** * Parses content and loads components for all found hooks * * @param content - The content to parse * @param parsers - An optional list of parsers to use instead of the global ones * @param context - An optional context object * @param options - An optional list of options * @param globalParsersBlacklist - An optional list of global parsers to blacklist * @param globalParsersWhitelist - An optional list of global parsers to whitelist * @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. * @param injector - An optional injector to use for the dynamically-loaded components. If none is provided, the default injector is used. */ parse(content = null, parsers = null, context = null, options = null, globalParsersBlacklist = null, globalParsersWhitelist = null, targetElement = null, targetHookIndex = {}, environmentInjector = null, injector = null) { const usedEnvironmentInjector = environmentInjector || this.environmentInjector; const usedInjector = injector || this.injector; // Resolve options and parsers const { parsers: usedParsers, options: usedOptions } = this.settingsResolver.resolve(usedInjector, // Use element injector for resolving service parsers (instead of environment injector). Will fallback to environment injector anyway if doesn't find anything. content, this.allSettings, this.ancestorSettings, this.moduleSettings, parsers, options, globalParsersBlacklist, globalParsersWhitelist); // Needs string or element as content if (!content) { return of({ element: targetElement || this.platformService.createElement('div'), hookIndex: targetHookIndex, context: context, usedParsers, usedOptions, usedInjector, usedEnvironmentInjector, destroy: () => this.destroy(targetHookIndex) }); } const token = Math.random().toString(36).substring(2, 12); let contentElement = typeof content === 'string' ? this.platformService.createElement('div') : content; this.platformService.setAttribute(contentElement, contentElementAttr, '1'); // a) Find all text hooks in string content if (typeof content === 'string') { const result = this.textHookFinder.find(content, context, usedParsers, token, usedOptions, targetHookIndex); this.platformService.setInnerContent(contentElement, result.content); // b) Find all text hooks in element content } else { this.textHookFinder.findInElement(contentElement, context, usedParsers, token, usedOptions, targetHookIndex); } // Find all element hooks targetHookIndex = this.elementHookFinder.find(contentElement, context, usedParsers, token, usedOptions, targetHookIndex); // Sanitize? if (usedOptions?.sanitize) { this.contentSanitizer.sanitize(contentElement, targetHookIndex, token); } // After sanitizing, insert into targetElement, if any if (targetElement && targetElement !== contentElement) { this.platformService.removeAttribute(contentElement, contentElementAttr); this.platformService.setAttribute(targetElement, contentElementAttr, '1'); this.platformService.clearChildNodes(targetElement); for (const childNode of this.platformService.getChildNodes(contentElement)) { this.platformService.appendChild(targetElement, childNode); } contentElement = targetElement; } // Dynamically create components in component selector elements return this.componentCreator.init(contentElement, targetHookIndex, token, context, usedOptions, usedEnvironmentInjector, usedInjector) .pipe(first()) .pipe(map((allComponentsLoaded) => { // Everything done! this.platformService.removeAttribute(contentElement, contentElementAttr); return { element: contentElement, hookIndex: targetHookIndex, context: context, usedParsers, usedOptions, usedInjector, usedEnvironmentInjector, destroy: () => this.destroy(targetHookIndex) }; })); } /** * Cleanly destroys all loaded components in a given HookIndex * * @param hookIndex - The hookIndex to process */ destroy(hookIndex) { if (hookIndex) { // Destroy dynamic components for (const hookIndexEntry of Object.values(hookIndex)) { if (hookIndexEntry.componentRef) { hookIndexEntry.componentRef.destroy(); } } // Unsubscribe from hook outputs for (const hook of Object.values(hookIndex)) { for (const parserSub of Object.values(hook.outputSubscriptions)) { if (parserSub) { parserSub.unsubscribe(); } } for (const htmlEventSub of Object.values(hook.htmlEventSubscriptions)) { if (htmlEventSub) { htmlEventSub.unsubscribe(); } } } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicHooksService, deps: [{ token: DYNAMICHOOKS_ALLSETTINGS, optional: true }, { token: DYNAMICHOOKS_ANCESTORSETTINGS, optional: true }, { token: DYNAMICHOOKS_MODULESETTINGS, optional: true }, { token: i1.SettingsResolver }, { token: i2.TextHookFinder }, { token: i3.ElementHookFinder }, { token: i4.ContentSanitizer }, { token: i5.ComponentCreator }, { token: i6.AutoPlatformService }, { token: i0.EnvironmentInjector }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicHooksService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicHooksService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DYNAMICHOOKS_ALLSETTINGS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DYNAMICHOOKS_ANCESTORSETTINGS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DYNAMICHOOKS_MODULESETTINGS] }] }, { type: i1.SettingsResolver }, { type: i2.TextHookFinder }, { type: i3.ElementHookFinder }, { type: i4.ContentSanitizer }, { type: i5.ComponentCreator }, { type: i6.AutoPlatformService }, { type: i0.EnvironmentInjector }, { type: i0.Injector }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pY0hvb2tzU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvc2VydmljZXMvZHluYW1pY0hvb2tzU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQWlDLE1BQU0sZUFBZSxDQUFDO0FBQzVGLE9BQU8sRUFBRSxFQUFFLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVE1QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsNkJBQTZCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFLckgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7Ozs7O0FBRXZEOztHQUVHO0FBSUgsTUFBTSxPQUFPLG1CQUFtQjtJQUU5QixZQUN3RCxXQUF3QyxFQUNwQyxnQkFBNkMsRUFDOUMsY0FBeUMsRUFDMUYsZ0JBQWtDLEVBQ2xDLGNBQThCLEVBQzlCLGlCQUFvQyxFQUNwQyxnQkFBa0MsRUFDbEMsZ0JBQWtDLEVBQ2xDLGVBQW9DLEVBQ3BDLG1CQUF3QyxFQUN4QyxRQUFrQjtRQVY0QixnQkFBVyxHQUFYLFdBQVcsQ0FBNkI7UUFDcEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUE2QjtRQUM5QyxtQkFBYyxHQUFkLGNBQWMsQ0FBMkI7UUFDMUYscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsb0JBQWUsR0FBZixlQUFlLENB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QVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFJSSxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHdCQUF3Qjs7MEJBQzNDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsNkJBQTZCOzswQkFDaEQsUUFBUTs7MEJBQUksTUFBTTsyQkFBQywyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPcHRpb25hbCwgSW5qZWN0LCBJbmplY3RvciwgRW52aXJvbm1lbnRJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgb2YsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpcnN0LCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IEhvb2tJbmRleCwgUGFyc2VSZXN1bHQgfSBmcm9tICcuLi9pbnRlcmZhY2VzUHVibGljJztcbmltcG9ydCB7IFBhcnNlT3B0aW9ucyB9IGZyb20gJy4vc2V0dGluZ3Mvb3B0aW9ucyc7XG5pbXBvcnQgeyBUZXh0SG9va0ZpbmRlciB9IGZyb20gJy4vY29yZS90ZXh0SG9va0ZpbmRlcic7XG5pbXBvcnQgeyBDb21wb25lbnRDcmVhdG9yIH0gZnJvbSAnLi9jb3JlL2NvbXBvbmVudENyZWF0b3InO1xuaW1wb3J0IHsgRHluYW1pY0hvb2tzU2V0dGluZ3MgfSBmcm9tICcuL3NldHRpbmdzL3NldHRpbmdzJztcbmltcG9ydCB7IEhvb2tQYXJzZXJFbnRyeSB9IGZyb20gJy4vc2V0dGluZ3MvcGFyc2VyRW50cnknO1xuaW1wb3J0IHsgRFlOQU1JQ0hPT0tTX0FMTFNFVFRJTkdTLCBEWU5BTUlDSE9PS1NfQU5DRVNUT1JTRVRUSU5HUywgRFlOQU1JQ0hPT0tTX01PRFVMRVNFVFRJTkdTIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBTZXR0aW5nc1Jlc29sdmVyIH0gZnJvbSAnLi9zZXR0aW5ncy9zZXR0aW5nc1Jlc29sdmVyJztcbmltcG9ydCB7IENvbnRlbnRTYW5pdGl6ZXIgfSBmcm9tICcuL3V0aWxzL2NvbnRlbnRTYW5pdGl6ZXInO1xuaW1wb3J0IHsgQXV0b1BsYXRmb3JtU2VydmljZSB9IGZyb20gJy4vcGxhdGZvcm0vYXV0b1BsYXRmb3JtU2VydmljZSc7XG5pbXBvcnQgeyBFbGVtZW50SG9va0ZpbmRlciB9IGZyb20gJy4vY29yZS9lbGVtZW50SG9va0ZpbmRlcic7XG5pbXBvcnQgeyBjb250ZW50RWxlbWVudEF0dHIgfSBmcm9tICcuLi9jb25zdGFudHMvY29yZSc7XG5cbi8qKlxuICogVGhlIGNvcmUgc2VydmljZSBmb3IgdGhlIG5neC1keW5hbWljLWhvb2tzIGxpYnJhcnkuIFByb3ZpZGVzIHRoZSBtYWluIGxvZ2ljIGludGVybmFsbHkgdXNlZCBieSBhbGwgY29tcG9uZW50cy5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgRHluYW1pY0hvb2tzU2VydmljZSB7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChEWU5BTUlDSE9PS1NfQUxMU0VUVElOR1MpIHByaXZhdGUgYWxsU2V0dGluZ3M6IER5bmFtaWNIb29rc1NldHRpbmdzW118bnVsbCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERZTkFNSUNIT09LU19BTkNFU1RPUlNFVFRJTkdTKSBwdWJsaWMgYW5jZXN0b3JTZXR0aW5nczogRHluYW1pY0hvb2tzU2V0dGluZ3NbXXxudWxsLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRFlOQU1JQ0hPT0tTX01PRFVMRVNFVFRJTkdTKSBwcml2YXRlIG1vZHVsZVNldHRpbmdzOiBEeW5hbWljSG9va3NTZXR0aW5nc3xudWxsLFxuICAgIHByaXZhdGUgc2V0dGluZ3NSZXNvbHZlcjogU2V0dGluZ3NSZXNvbHZlcixcbiAgICBwcml2YXRlIHRleHRIb29rRmluZGVyOiBUZXh0SG9va0ZpbmRlcixcbiAgICBwcml2YXRlIGVsZW1lbnRIb29rRmluZGVyOiBFbGVtZW50SG9va0ZpbmRlcixcbiAgICBwcml2YXRlIGNvbnRlbnRTYW5pdGl6ZXI6IENvbnRlbnRTYW5pdGl6ZXIsXG4gICAgcHJpdmF0ZSBjb21wb25lbnRDcmVhdG9yOiBDb21wb25lbnRDcmVhdG9yLFxuICAgIHByaXZhdGUgcGxhdGZvcm1TZXJ2aWNlOiBBdXRvUGxhdGZvcm1TZXJ2aWNlLFxuICAgIHByaXZhdGUgZW52aXJvbm1lbnRJbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcixcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvclxuICApIHtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgY29udGVudCBhbmQgbG9hZHMgY29tcG9uZW50cyBmb3IgYWxsIGZvdW5kIGhvb2tzXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZW50IC0gVGhlIGNvbnRlbnQgdG8gcGFyc2VcbiAgICogQHBhcmFtIHBhcnNlcnMgLSBBbiBvcHRpb25hbCBsaXN0IG9mIHBhcnNlcnMgdG8gdXNlIGluc3RlYWQgb2YgdGhlIGdsb2JhbCBvbmVzXG4gICAqIEBwYXJhbSBjb250ZXh0IC0gQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3RcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBsaXN0IG9mIG9wdGlvbnNcbiAgICogQHBhcmFtIGdsb2JhbFBhcnNlcnNCbGFja2xpc3QgLSBBbiBvcHRpb25hbCBsaXN0IG9mIGdsb2JhbCBwYXJzZXJzIHRvIGJsYWNrbGlzdFxuICAgKiBAcGFyYW0gZ2xvYmFsUGFyc2Vyc1doaXRlbGlzdCAtIEFuIG9wdGlvbmFsIGxpc3Qgb2YgZ2xvYmFsIHBhcnNlcnMgdG8gd2hpdGVsaXN0XG4gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IC0gQW4gb3B0aW9uYWwgSFRNTCBlbGVtZW50IHRvIHVzZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gICAqIEBwYXJhbSB0YXJnZXRIb29rSW5kZXggLSBBbiBvcHRpb25hbCBvYmplY3QgdG8gZmlsbCB3aXRoIHRoZSBwcm9ncmFtbWF0aWMgaG9vayBkYXRhLiBJZiBub25lIGlzIHByb3ZpZGVkLCBvbmUgaXMgY3JlYXRlZCBhbmQgcmV0dXJuZWQgZm9yIHlvdS5cbiAgICogQHBhcmFtIGVudmlyb25tZW50SW5qZWN0b3IgLSBBbiBvcHRpb25hbCBlbnZpcm9ubWVudEluamVjdG9yIHRvIHVzZSBmb3IgdGhlIGR5bmFtaWNhbGx5LWxvYWRlZCBjb21wb25lbnRzLiBJZiBub25lIGlzIHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBlbnZpcm9ubWVudEluamVjdG9yIGlzIHVzZWQuXG4gICAqIEBwYXJhbSBpbmplY3RvciAtIEFuIG9wdGlvbmFsIGluamVjdG9yIHRvIHVzZSBmb3IgdGhlIGR5bmFtaWNhbGx5LWxvYWRlZCBjb21wb25lbnRzLiBJZiBub25lIGlzIHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBpbmplY3RvciBpcyB1c2VkLlxuICAgKi9cbiAgcGFyc2UoXG4gICAgY29udGVudDogYW55ID0gbnVsbCxcbiAgICBwYXJzZXJzOiBIb29rUGFyc2VyRW50cnlbXXxudWxsID0gbnVsbCxcbiAgICBjb250ZXh0OiBhbnkgPSBudWxsLFxuICAgIG9wdGlvbnM6IFBhcnNlT3B0aW9uc3xudWxsID0gbnVsbCxcbiAgICBnbG9iYWxQYXJzZXJzQmxhY2tsaXN0OiBzdHJpbmdbXXxudWxsID0gbnVsbCxcbiAgICBnbG9iYWxQYXJzZXJzV2hpdGVsaXN0OiBzdHJpbmdbXXxudWxsID0gbnVsbCxcbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudHxudWxsID0gbnVsbCxcbiAgICB0YXJnZXRIb29rSW5kZXg6IEhvb2tJbmRleCA9IHt9LFxuICAgIGVudmlyb25tZW50SW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3J8bnVsbCA9IG51bGwsXG4gICAgaW5qZWN0b3I6IEluamVjdG9yfG51bGwgPSBudWxsXG4gICk6IE9ic2VydmFibGU8UGFyc2VSZXN1bHQ+IHtcbiAgICBjb25zdCB1c2VkRW52aXJvbm1lbnRJbmplY3RvciA9IGVudmlyb25tZW50SW5qZWN0b3IgfHwgdGhpcy5lbnZpcm9ubWVudEluamVjdG9yO1xuICAgIGNvbnN0IHVzZWRJbmplY3RvciA9IGluamVjdG9yIHx8IHRoaXMuaW5qZWN0b3I7XG5cbiAgICAvLyBSZXNvbHZlIG9wdGlvbnMgYW5kIHBhcnNlcnNcbiAgICBjb25zdCB7IHBhcnNlcnM6IHVzZWRQYXJzZXJzLCBvcHRpb25zOiB1c2VkT3B0aW9ucyB9ID0gdGhpcy5zZXR0aW5nc1Jlc29sdmVyLnJlc29sdmUoXG4gICAgICB1c2VkSW5qZWN0b3IsIC8vIFVzZSBlbGVtZW50IGluamVjdG9yIGZvciByZXNvbHZpbmcgc2VydmljZSBwYXJzZXJzIChpbnN0ZWFkIG9mIGVudmlyb25tZW50IGluamVjdG9yKS4gV2lsbCBmYWxsYmFjayB0byBlbnZpcm9ubWVudCBpbmplY3RvciBhbnl3YXkgaWYgZG9lc24ndCBmaW5kIGFueXRoaW5nLlxuICAgICAgY29udGVudCxcbiAgICAgIHRoaXMuYWxsU2V0dGluZ3MsIFxuICAgICAgdGhpcy5hbmNlc3RvclNldHRpbmdzLCBcbiAgICAgIHRoaXMubW9kdWxlU2V0dGluZ3MsIFxuICAgICAgcGFyc2VycywgXG4gICAgICBvcHRpb25zLCBcbiAgICAgIGdsb2JhbFBhcnNlcnNCbGFja2xpc3QsIFxuICAgICAgZ2xvYmFsUGFyc2Vyc1doaXRlbGlzdFxuICAgICk7XG5cbiAgICAvLyBOZWVkcyBzdHJpbmcgb3IgZWxlbWVudCBhcyBjb250ZW50XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICByZXR1cm4gb2Yoe1xuICAgICAgICBlbGVtZW50OiB0YXJnZXRFbGVtZW50IHx8IHRoaXMucGxhdGZvcm1TZXJ2aWNlLmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgICBob29rSW5kZXg6IHRhcmdldEhvb2tJbmRleCxcbiAgICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgICAgdXNlZFBhcnNlcnMsXG4gICAgICAgIHVzZWRPcHRpb25zLFxuICAgICAgICB1c2VkSW5qZWN0b3IsXG4gICAgICAgIHVzZWRFbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgICBkZXN0cm95OiAoKSA9PiB0aGlzLmRlc3Ryb3kodGFyZ2V0SG9va0luZGV4KVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgdG9rZW4gPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTIpO1xuICAgIGxldCBjb250ZW50RWxlbWVudCA9IHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJyA/IHRoaXMucGxhdGZvcm1TZXJ2aWNlLmNyZWF0ZUVsZW1lbnQoJ2RpdicpIDogY29udGVudDtcbiAgICB0aGlzLnBsYXRmb3JtU2VydmljZS5zZXRBdHRyaWJ1dGUoY29udGVudEVsZW1lbnQsIGNvbnRlbnRFbGVtZW50QXR0ciwgJzEnKTtcblxuICAgIC8vIGEpIEZpbmQgYWxsIHRleHQgaG9va3MgaW4gc3RyaW5nIGNvbnRlbnRcbiAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnRleHRIb29rRmluZGVyLmZpbmQoY29udGVudCwgY29udGV4dCwgdXNlZFBhcnNlcnMsIHRva2VuLCB1c2VkT3B0aW9ucywgdGFyZ2V0SG9va0luZGV4KTtcbiAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLnNldElubmVyQ29udGVudChjb250ZW50RWxlbWVudCwgcmVzdWx0LmNvbnRlbnQpO1xuICAgICAgXG4gICAgLy8gYikgRmluZCBhbGwgdGV4dCBob29rcyBpbiBlbGVtZW50IGNvbnRlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50ZXh0SG9va0ZpbmRlci5maW5kSW5FbGVtZW50KGNvbnRlbnRFbGVtZW50LCBjb250ZXh0LCB1c2VkUGFyc2VycywgdG9rZW4sIHVzZWRPcHRpb25zLCB0YXJnZXRIb29rSW5kZXgpO1xuICAgIH1cblxuICAgIC8vIEZpbmQgYWxsIGVsZW1lbnQgaG9va3NcbiAgICB0YXJnZXRIb29rSW5kZXggPSB0aGlzLmVsZW1lbnRIb29rRmluZGVyLmZpbmQoY29udGVudEVsZW1lbnQsIGNvbnRleHQsIHVzZWRQYXJzZXJzLCB0b2tlbiwgdXNlZE9wdGlvbnMsIHRhcmdldEhvb2tJbmRleCk7XG5cbiAgICAvLyBTYW5pdGl6ZT9cbiAgICBpZiAodXNlZE9wdGlvbnM/LnNhbml0aXplKSB7XG4gICAgICB0aGlzLmNvbnRlbnRTYW5pdGl6ZXIuc2FuaXRpemUoY29udGVudEVsZW1lbnQsIHRhcmdldEhvb2tJbmRleCwgdG9rZW4pO1xuICAgIH1cblxuICAgIC8vIEFmdGVyIHNhbml0aXppbmcsIGluc2VydCBpbnRvIHRhcmdldEVsZW1lbnQsIGlmIGFueVxuICAgIGlmICh0YXJnZXRFbGVtZW50ICYmIHRhcmdldEVsZW1lbnQgIT09IGNvbnRlbnRFbGVtZW50KSB7XG4gICAgICB0aGlzLnBsYXRmb3JtU2VydmljZS5yZW1vdmVBdHRyaWJ1dGUoY29udGVudEVsZW1lbnQsIGNvbnRlbnRFbGVtZW50QXR0cik7XG4gICAgICB0aGlzLnBsYXRmb3JtU2VydmljZS5zZXRBdHRyaWJ1dGUodGFyZ2V0RWxlbWVudCwgY29udGVudEVsZW1lbnRBdHRyLCAnMScpO1xuICAgICAgdGhpcy5wbGF0Zm9ybVNlcnZpY2UuY2xlYXJDaGlsZE5vZGVzKHRhcmdldEVsZW1lbnQpO1xuICAgICAgZm9yIChjb25zdCBjaGlsZE5vZGUgb2YgdGhpcy5wbGF0Zm9ybVNlcnZpY2UuZ2V0Q2hpbGROb2Rlcyhjb250ZW50RWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5wbGF0Zm9ybVNlcnZpY2UuYXBwZW5kQ2hpbGQodGFyZ2V0RWxlbWVudCwgY2hpbGROb2RlKTtcbiAgICAgIH1cbiAgICAgIGNvbnRlbnRFbGVtZW50ID0gdGFyZ2V0RWxlbWVudFxuICAgIH1cblxuICAgIC8vIER5bmFtaWNhbGx5IGNyZWF0ZSBjb21wb25lbnRzIGluIGNvbXBvbmVudCBzZWxlY3RvciBlbGVtZW50c1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudENyZWF0b3IuaW5pdChjb250ZW50RWxlbWVudCwgdGFyZ2V0SG9va0luZGV4LCB0b2tlbiwgY29udGV4dCwgdXNlZE9wdGlvbnMsIHVzZWRFbnZpcm9ubWVudEluamVjdG9yLCB1c2VkSW5qZWN0b3IpXG4gICAgLnBpcGUoZmlyc3QoKSlcbiAgICAucGlwZShtYXAoKGFsbENvbXBvbmVudHNMb2FkZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIC8vIEV2ZXJ5dGhpbmcgZG9uZSFcbiAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLnJlbW92ZUF0dHJpYnV0ZShjb250ZW50RWxlbWVudCwgY29udGVudEVsZW1lbnRBdHRyKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVsZW1lbnQ6IGNvbnRlbnRFbGVtZW50LFxuICAgICAgICBob29rSW5kZXg6IHRhcmdldEhvb2tJbmRleCxcbiAgICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgICAgdXNlZFBhcnNlcnMsXG4gICAgICAgIHVzZWRPcHRpb25zLFxuICAgICAgICB1c2VkSW5qZWN0b3IsXG4gICAgICAgIHVzZWRFbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgICBkZXN0cm95OiAoKSA9PiB0aGlzLmRlc3Ryb3kodGFyZ2V0SG9va0luZGV4KVxuICAgICAgfTtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5seSBkZXN0cm95cyBhbGwgbG9hZGVkIGNvbXBvbmVudHMgaW4gYSBnaXZlbiBIb29rSW5kZXhcbiAgICpcbiAgICogQHBhcmFtIGhvb2tJbmRleCAtIFRoZSBob29rSW5kZXggdG8gcHJvY2Vzc1xuICAgKi9cbiAgZGVzdHJveShob29rSW5kZXg6IEhvb2tJbmRleCk6IHZvaWQge1xuICAgIGlmIChob29rSW5kZXgpIHtcbiAgICAgIC8vIERlc3Ryb3kgZHluYW1pYyBjb21wb25lbnRzXG4gICAgICBmb3IgKGNvbnN0IGhvb2tJbmRleEVudHJ5IG9mIE9iamVjdC52YWx1ZXMoaG9va0luZGV4KSkge1xuICAgICAgICBpZiAoaG9va0luZGV4RW50cnkuY29tcG9uZW50UmVmKSB7XG4gICAgICAgICAgaG9va0luZGV4RW50cnkuY29tcG9uZW50UmVmLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBVbnN1YnNjcmliZSBmcm9tIGhvb2sgb3V0cHV0c1xuICAgICAgZm9yIChjb25zdCBob29rIG9mIE9iamVjdC52YWx1ZXMoaG9va0luZGV4KSkge1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnNlclN1YiBvZiBPYmplY3QudmFsdWVzKGhvb2sub3V0cHV0U3Vic2NyaXB0aW9ucykpIHtcbiAgICAgICAgICBpZiAocGFyc2VyU3ViKSB7IHBhcnNlclN1Yi51bnN1YnNjcmliZSgpOyB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBodG1sRXZlbnRTdWIgb2YgT2JqZWN0LnZhbHVlcyhob29rLmh0bWxFdmVudFN1YnNjcmlwdGlvbnMpKSB7XG4gICAgICAgICAgaWYgKGh0bWxFdmVudFN1YikgeyBodG1sRXZlbnRTdWIudW5zdWJzY3JpYmUoKTsgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==