UNPKG

@dotglitch/ngx-common

Version:

Angular components and utilities that are commonly used.

217 lines 32 kB
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core'; import { ComponentResolveStrategy } from './types'; import { stringToSlug, ConsoleLogger } from '../../utils'; import * as i0 from "@angular/core"; // Monkey-patch the type of these symbols. const $id = Symbol("id"); const $group = Symbol("group"); export const NGX_LAZY_LOADER_CONFIG = new InjectionToken('lazyloader-config'); export class LazyLoaderService { get err() { return LazyLoaderService.config.logger.err; } get log() { return LazyLoaderService.config.logger.log; } get warn() { return LazyLoaderService.config.logger.warn; } // A proxied registry that mutates reference keys static { this.registry = {}; } constructor(config = {}) { // Ensure this is singleton and works regardless of special instancing requirements. LazyLoaderService.configure(config); } static configure(config) { const { log, warn, err } = ConsoleLogger("ngx-lazy-loader", "#009688"); this.config = { componentResolveStrategy: ComponentResolveStrategy.PickFirst, logger: { log, warn, err }, ...config }; config?.entries?.forEach(e => this.addComponentToRegistry(e)); // If a custom resolution strategy is provided but no resolution function is passed, // we throw an error if (this.config.componentResolveStrategy == ComponentResolveStrategy.Custom && !this.config.customResolver) { throw new Error("Cannot initialize. Configuration specifies a custom resolve matcher but none was provided"); } if (this.config.loaderDistractorComponent && this.config.loaderDistractorTemplate) throw new Error("Cannot have both a Component and Template for Distractor view."); if (this.config.errorComponent && this.config.errorTemplate) throw new Error("Cannot have both a Component and Template for Error view."); if (this.config.notFoundComponent && this.config.notFoundTemplate) throw new Error("Cannot have both a Component and Template for NotFound view."); } static addComponentToRegistry(registration) { if (!registration) throw new Error("Cannot add <undefined> component into registry."); // Clone the object into our repository and transfer the id into a standardized slug format const id = stringToSlug(registration.id ?? Date.now().toString()); // purge non-basic ASCII chars const group = registration.group || "default"; registration[$id] = id; registration[$group] = id; if (!this.registry[group]) this.registry[group] = []; // Check if we already have a registration for the component // if (this.registry[group] && typeof this.registry[group]['load'] == "function") { // // Warn the developer that the state is problematic // this.config.logger.warn( // `A previous entry already exists for ${id}! The old registration will be overridden.` + // `Please ensure you use groups if you intend to have duplicate component ids. ` + // `If this was intentional, first remove the old component from the registry before adding a new instance` // ); // // If we're in dev mode, break the loader surface // if (isDevMode()) // return; // } this.registry[group].push(registration); } /** * Register an Angular component * @param id identifier that is used to resolve the component * @param group * @param component Angular Component Class constructor */ registerComponent(args) { if (this.isComponentRegistered(args.id, args.group)) { this.log(`Will not re-register component '${args.id}' in group '${args.group || 'default'}' `); return; } LazyLoaderService.addComponentToRegistry({ id: stringToSlug(args.id), matcher: args.matcher, group: stringToSlug(args.group || "default"), load: args.load || (() => args.component) }); } /** * * @param id * @param group */ unregisterComponent(id, group = "default") { const _id = stringToSlug(id); const _group = stringToSlug(group); if (!this.resolveRegistrationEntry(id, group)) throw new Error("Cannot unregister component ${}! Component is not present in registry"); // TODO: handle clearing running instances delete LazyLoaderService.registry[_group][_id]; } /** * Get the registration entry for a component. * Returns null if component is not in the registry. */ resolveRegistrationEntry(value, group = "default") { const _id = stringToSlug(value); const _group = stringToSlug(group); const targetGroup = (LazyLoaderService.registry[_group] || []); let items = targetGroup.filter(t => { if (!t) return false; // No matcher, check id if (!t.matcher) return t.id == value || t[$id] == _id; // Matcher is regex if (t.matcher instanceof RegExp) return t.matcher.test(value) || t.matcher.test(_id); // Matcher is string => regex if (typeof t.matcher == 'string') { const rx = new RegExp(t.matcher, 'ui'); return rx.test(value) || rx.test(_id); } // Matcher is array if (Array.isArray(t.matcher)) { return !!t.matcher.find(e => stringToSlug(e) == _id); } // Custom matcher function if (typeof t.matcher == "function") return t.matcher(_id); return false; }); if (items.length > 1) { this.warn("Resolved multiple components for the provided `[component]` binding. This may cause UI conflicts."); } if (items.length == 0) { return null; } const out = items[0]; if (out.matcher instanceof RegExp) { const result = value.match(out.matcher) || _id.match(out.matcher); return { entry: out, matchGroups: result?.groups }; } return { entry: out }; } /** * Check if a component is currently registered * Can be used to validate regex matchers and aliases. */ isComponentRegistered(value, group = "default") { return !!this.resolveRegistrationEntry(value, group); } /** * * @param bundle * @returns The component `Object` if a component was resolved, `null` if no component was found * `false` if the specified strategy was an invalid selection */ resolveComponent(id, group, modules) { switch (LazyLoaderService.config.componentResolveStrategy) { case ComponentResolveStrategy.PickFirst: { return modules[0]; } // Exact id -> classname match case ComponentResolveStrategy.MatchIdToClassName: { const matches = modules .filter(k => k.name == id); if (matches.length == 0) return null; return matches[0]; } // Fuzzy id -> classname match case ComponentResolveStrategy.FuzzyIdClassName: { const _id = id.replace(/[^a-z0-9_\-]/ig, ''); if (_id.length == 0) { LazyLoaderService.config.logger.err("Fuzzy classname matching stripped all symbols from the ID specified!"); return false; } const rx = new RegExp(`^${id}(component|module)?$`, "i"); const matches = modules .filter(mod => { let kid = mod.name.replace(/[^a-z0-9_\-]/ig, ''); return rx.test(kid); }); if (matches.length > 1) { LazyLoaderService.config.logger.err("Fuzzy classname matching resolved multiple targets!"); return false; } if (matches.length == 0) { LazyLoaderService.config.logger.err("Fuzzy classname matching resolved no targets!"); return null; } return matches[0]; } case ComponentResolveStrategy.Custom: { return LazyLoaderService.config.customResolver(modules); } default: { return false; } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: LazyLoaderService, deps: [{ token: NGX_LAZY_LOADER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: LazyLoaderService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: LazyLoaderService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NGX_LAZY_LOADER_CONFIG] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF6eS1sb2FkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9sYXp5LWxvYWRlci9sYXp5LWxvYWRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUE0RCx3QkFBd0IsRUFBZ0QsTUFBTSxTQUFTLENBQUM7QUFDM0osT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBRTFELDBDQUEwQztBQUMxQyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFrQixDQUFDO0FBQzFDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQWtCLENBQUM7QUFFaEQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxjQUFjLENBQXNCLG1CQUFtQixDQUFDLENBQUM7QUFLbkcsTUFBTSxPQUFPLGlCQUFpQjtJQUMxQixJQUFZLEdBQUcsS0FBSyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRSxJQUFZLEdBQUcsS0FBSyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRSxJQUFZLElBQUksS0FBSyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUVuRSxpREFBaUQ7YUFDbEMsYUFBUSxHQUVuQixFQUFFLEFBRmlCLENBRWhCO0lBSVAsWUFBd0QsU0FBOEIsRUFBRTtRQUNwRixvRkFBb0Y7UUFDcEYsaUJBQWlCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFD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LENBQUMsRUFBRSxDQUFDO29CQUN0QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO29CQUNyRixPQUFPLElBQUksQ0FBQztnQkFDaEIsQ0FBQztnQkFFRCxPQUFPLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QixDQUFDO1lBQ0QsS0FBSyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBYyxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUNELE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ04sT0FBTyxLQUFLLENBQUM7WUFDakIsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDOzhHQTFQUSxpQkFBaUIsa0JBWU0sc0JBQXNCO2tIQVo3QyxpQkFBaUIsY0FGZCxNQUFNOzsyRkFFVCxpQkFBaUI7a0JBSDdCLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCOzswQkFhZ0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxzQkFBc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcGlsZWRDb21wb25lbnQsIENvbXBpbGVkTW9kdWxlLCBDb21wb25lbnRSZWdpc3RyYXRpb24sIENvbXBvbmVudFJlc29sdmVTdHJhdGVneSwgRHluYW1pY1JlZ2lzdHJhdGlvbkFyZ3MsIE5neExhenlMb2FkZXJDb25maWcgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IHN0cmluZ1RvU2x1ZywgQ29uc29sZUxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzJztcblxuLy8gTW9ua2V5LXBhdGNoIHRoZSB0eXBlIG9mIHRoZXNlIHN5bWJvbHMuXG5jb25zdCAkaWQgPSBTeW1ib2woXCJpZFwiKSBhcyBhbnkgYXMgc3RyaW5nO1xuY29uc3QgJGdyb3VwID0gU3ltYm9sKFwiZ3JvdXBcIikgYXMgYW55IGFzIHN0cmluZztcblxuZXhwb3J0IGNvbnN0IE5HWF9MQVpZX0xPQURFUl9DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW48Tmd4TGF6eUxvYWRlckNvbmZpZz4oJ2xhenlsb2FkZXItY29uZmlnJyk7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTGF6eUxvYWRlclNlcnZpY2Uge1xuICAgIHByaXZhdGUgZ2V0IGVycigpIHsgcmV0dXJuIExhenlMb2FkZXJTZXJ2aWNlLmNvbmZpZy5sb2dnZXIuZXJyOyB9XG4gICAgcHJpdmF0ZSBnZXQgbG9nKCkgeyByZXR1cm4gTGF6eUxvYWRlclNlcnZpY2UuY29uZmlnLmxvZ2dlci5sb2c7IH1cbiAgICBwcml2YXRlIGdldCB3YXJuKCkgeyByZXR1cm4gTGF6eUxvYWRlclNlcnZpY2UuY29uZmlnLmxvZ2dlci53YXJuOyB9XG5cbiAgICAvLyBBIHByb3hpZWQgcmVnaXN0cnkgdGhhdCBtdXRhdGVzIHJlZmVyZW5jZSBrZXlzXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVnaXN0cnk6IHtcbiAgICAgICAgW2tleTogc3RyaW5nXTogQ29tcG9uZW50UmVnaXN0cmF0aW9uW107XG4gICAgfSA9IHt9O1xuXG4gICAgcHVibGljIHN0YXRpYyBjb25maWc6IE5neExhenlMb2FkZXJDb25maWc7XG5cbiAgICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KE5HWF9MQVpZX0xPQURFUl9DT05GSUcpIGNvbmZpZzogTmd4TGF6eUxvYWRlckNvbmZpZyA9IHt9KSB7XG4gICAgICAgIC8vIEVuc3VyZSB0aGlzIGlzIHNpbmdsZXRvbiBhbmQgd29ya3MgcmVnYXJkbGVzcyBvZiBzcGVjaWFsIGluc3RhbmNpbmcgcmVxdWlyZW1lbnRzLlxuICAgICAgICBMYXp5TG9hZGVyU2VydmljZS5jb25maWd1cmUoY29uZmlnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBjb25maWd1cmUoY29uZmlnOiBOZ3hMYXp5TG9hZGVyQ29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHsgbG9nLCB3YXJuLCBlcnIgfSA9IENvbnNvbGVMb2dnZXIoXCJuZ3gtbGF6eS1sb2FkZXJcIiwgXCIjMDA5Njg4XCIpO1xuXG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgY29tcG9uZW50UmVzb2x2ZVN0cmF0ZWd5OiBDb21wb25lbnRSZXNvbHZlU3RyYXRlZ3kuUGlja0ZpcnN0LFxuICAgICAgICAgICAgbG9nZ2VyOiB7XG4gICAgICAgICAgICAgICAgbG9nLFxuICAgICAgICAgICAgICAgIHdhcm4sXG4gICAgICAgICAgICAgICAgZXJyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLi4uY29uZmlnXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uZmlnPy5lbnRyaWVzPy5mb3JFYWNoKGUgPT4gdGhpcy5hZGRDb21wb25lbnRUb1JlZ2lzdHJ5KGUpKVxuXG4gICAgICAgIC8vIElmIGEgY3VzdG9tIHJlc29sdXRpb24gc3RyYXRlZ3kgaXMgcHJvdmlkZWQgYnV0IG5vIHJlc29sdXRpb24gZnVuY3Rpb24gaXMgcGFzc2VkLFxuICAgICAgICAvLyB3ZSB0aHJvdyBhbiBlcnJvclxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5jb21wb25lbnRSZXNvbHZlU3RyYXRlZ3kgPT0gQ29tcG9uZW50UmVzb2x2ZVN0cmF0ZWd5LkN1c3RvbSAmJlxuICAgICAgICAgICAgIXRoaXMuY29uZmlnLmN1c3RvbVJlc29sdmVyXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGluaXRpYWxpemUuIENvbmZpZ3VyYXRpb24gc3BlY2lmaWVzIGEgY3VzdG9tIHJlc29sdmUgbWF0Y2hlciBidXQgbm9uZSB3YXMgcHJvdmlkZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jb25maWcubG9hZGVyRGlzdHJhY3RvckNvbXBvbmVudCAmJiB0aGlzLmNvbmZpZy5sb2FkZXJEaXN0cmFjdG9yVGVtcGxhdGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgaGF2ZSBib3RoIGEgQ29tcG9uZW50IGFuZCBUZW1wbGF0ZSBmb3IgRGlzdHJhY3RvciB2aWV3LlwiKVxuICAgICAgICBpZiAodGhpcy5jb25maWcuZXJyb3JDb21wb25lbnQgJiYgdGhpcy5jb25maWcuZXJyb3JUZW1wbGF0ZSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBoYXZlIGJvdGggYSBDb21wb25lbnQgYW5kIFRlbXBsYXRlIGZvciBFcnJvciB2aWV3LlwiKVxuICAgICAgICBpZiAodGhpcy5jb25maWcubm90Rm91bmRDb21wb25lbnQgJiYgdGhpcy5jb25maWcubm90Rm91bmRUZW1wbGF0ZSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBoYXZlIGJvdGggYSBDb21wb25lbnQgYW5kIFRlbXBsYXRlIGZvciBOb3RGb3VuZCB2aWV3LlwiKVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYWRkQ29tcG9uZW50VG9SZWdpc3RyeShyZWdpc3RyYXRpb246IENvbXBvbmVudFJlZ2lzdHJhdGlvbikge1xuICAgICAgICBpZiAoIXJlZ2lzdHJhdGlvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBhZGQgPHVuZGVmaW5lZD4gY29tcG9uZW50IGludG8gcmVnaXN0cnkuXCIpO1xuXG4gICAgICAgIC8vIENsb25lIHRoZSBvYmplY3QgaW50byBvdXIgcmVwb3NpdG9yeSBhbmQgdHJhbnNmZXIgdGhlIGlkIGludG8gYSBzdGFuZGFyZGl6ZWQgc2x1ZyBmb3JtYXRcblxuICAgICAgICBjb25zdCBpZCA9IHN0cmluZ1RvU2x1ZyhyZWdpc3RyYXRpb24uaWQgPz8gRGF0ZS5ub3coKS50b1N0cmluZygpKTsgLy8gcHVyZ2Ugbm9uLWJhc2ljIEFTQ0lJIGNoYXJzXG4gICAgICAgIGNvbnN0IGdyb3VwID0gcmVnaXN0cmF0aW9uLmdyb3VwIHx8IFwiZGVmYXVsdFwiO1xuXG4gICAgICAgIHJlZ2lzdHJhdGlvblskaWRdID0gaWQ7XG4gICAgICAgIHJlZ2lzdHJhdGlvblskZ3JvdXBdID0gaWQ7XG5cblxuICAgICAgICBpZiAoIXRoaXMucmVnaXN0cnlbZ3JvdXBdKVxuICAgICAgICAgICAgdGhpcy5yZWdpc3RyeVtncm91cF0gPSBbXTtcblxuICAgICAgICAvLyBDaGVjayBpZiB3ZSBhbHJlYWR5IGhhdmUgYSByZWdpc3RyYXRpb24gZm9yIHRoZSBjb21wb25lbnRcbiAgICAgICAgLy8gaWYgKHRoaXMucmVnaXN0cnlbZ3JvdXBdICYmIHR5cGVvZiB0aGlzLnJlZ2lzdHJ5W2dyb3VwXVsnbG9hZCddID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyAgICAgLy8gV2FybiB0aGUgZGV2ZWxvcGVyIHRoYXQgdGhlIHN0YXRlIGlzIHByb2JsZW1hdGljXG4gICAgICAgIC8vICAgICB0aGlzLmNvbmZpZy5sb2dnZXIud2FybihcbiAgICAgICAgLy8gICAgICAgICBgQSBwcmV2aW91cyBlbnRyeSBhbHJlYWR5IGV4aXN0cyBmb3IgJHtpZH0hIFRoZSBvbGQgcmVnaXN0cmF0aW9uIHdpbGwgYmUgb3ZlcnJpZGRlbi5gICtcbiAgICAgICAgLy8gICAgICAgICBgUGxlYXNlIGVuc3VyZSB5b3UgdXNlIGdyb3VwcyBpZiB5b3UgaW50ZW5kIHRvIGhhdmUgZHVwbGljYXRlIGNvbXBvbmVudCBpZHMuIGAgK1xuICAgICAgICAvLyAgICAgICAgIGBJZiB0aGlzIHdhcyBpbnRlbnRpb25hbCwgZmlyc3QgcmVtb3ZlIHRoZSBvbGQgY29tcG9uZW50IGZyb20gdGhlIHJlZ2lzdHJ5IGJlZm9yZSBhZGRpbmcgYSBuZXcgaW5zdGFuY2VgXG4gICAgICAgIC8vICAgICApO1xuXG4gICAgICAgIC8vICAgICAvLyBJZiB3ZSdyZSBpbiBkZXYgbW9kZSwgYnJlYWsgdGhlIGxvYWRlciBzdXJmYWNlXG4gICAgICAgIC8vICAgICBpZiAoaXNEZXZNb2RlKCkpXG4gICAgICAgIC8vICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyB9XG5cbiAgICAgICAgdGhpcy5yZWdpc3RyeVtncm91cF0ucHVzaChyZWdpc3RyYXRpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGFuIEFuZ3VsYXIgY29tcG9uZW50XG4gICAgICogQHBhcmFtIGlkIGlkZW50aWZpZXIgdGhhdCBpcyB1c2VkIHRvIHJlc29sdmUgdGhlIGNvbXBvbmVudFxuICAgICAqIEBwYXJhbSBncm91cFxuICAgICAqIEBwYXJhbSBjb21wb25lbnQgQW5ndWxhciBDb21wb25lbnQgQ2xhc3MgY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJDb21wb25lbnQ8VCBleHRlbmRzIHsgbmV3KC4uLmFyZ3M6IGFueVtdKTogSW5zdGFuY2VUeXBlPFQ+OyB9PihhcmdzOiBEeW5hbWljUmVnaXN0cmF0aW9uQXJnczxUPikge1xuICAgICAgICBpZiAodGhpcy5pc0NvbXBvbmVudFJlZ2lzdGVyZWQoYXJncy5pZCwgYXJncy5ncm91cCkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKGBXaWxsIG5vdCByZS1yZWdpc3RlciBjb21wb25lbnQgJyR7YXJncy5pZH0nIGluIGdyb3VwICcke2FyZ3MuZ3JvdXAgfHwgJ2RlZmF1bHQnfScgYCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBMYXp5TG9hZGVyU2VydmljZS5hZGRDb21wb25lbnRUb1JlZ2lzdHJ5KHtcbiAgICAgICAgICAgIGlkOiBzdHJpbmdUb1NsdWcoYXJncy5pZCksXG4gICAgICAgICAgICBtYXRjaGVyOiBhcmdzLm1hdGNoZXIsXG4gICAgICAgICAgICBncm91cDogc3RyaW5nVG9TbHVnKGFyZ3MuZ3JvdXAgfHwgXCJkZWZhdWx0XCIpLFxuICAgICAgICAgICAgbG9hZDogYXJncy5sb2FkIHx8ICgoKSA9PiBhcmdzLmNvbXBvbmVudClcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaWRcbiAgICAgKiBAcGFyYW0gZ3JvdXBcbiAgICAgKi9cbiAgICBwdWJsaWMgdW5yZWdpc3RlckNvbXBvbmVudChpZDogc3RyaW5nLCBncm91cCA9IFwiZGVmYXVsdFwiKSB7XG4gICAgICAgIGNvbnN0IF9pZCA9IHN0cmluZ1RvU2x1ZyhpZCk7XG4gICAgICAgIGNvbnN0IF9ncm91cCA9IHN0cmluZ1RvU2x1Zyhncm91cCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlc29sdmVSZWdpc3RyYXRpb25FbnRyeShpZCwgZ3JvdXApKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHVucmVnaXN0ZXIgY29tcG9uZW50ICR7fSEgQ29tcG9uZW50IGlzIG5vdCBwcmVzZW50IGluIHJlZ2lzdHJ5XCIpXG5cbiAgICAgICAgLy8gVE9ETzogaGFuZGxlIGNsZWFyaW5nIHJ1bm5pbmcgaW5zdGFuY2VzXG4gICAgICAgIGRlbGV0ZSBMYXp5TG9hZGVyU2VydmljZS5yZWdpc3RyeVtfZ3JvdXBdW19pZF07XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHJlZ2lzdHJhdGlvbiBlbnRyeSBmb3IgYSBjb21wb25lbnQuXG4gICAgICogUmV0dXJucyBudWxsIGlmIGNvbXBvbmVudCBpcyBub3QgaW4gdGhlIHJlZ2lzdHJ5LlxuICAgICAqL1xuICAgIHB1YmxpYyByZXNvbHZlUmVnaXN0cmF0aW9uRW50cnkodmFsdWU6IHN0cmluZywgZ3JvdXAgPSBcImRlZmF1bHRcIikge1xuICAgICAgICBjb25zdCBfaWQgPSBzdHJpbmdUb1NsdWcodmFsdWUpO1xuICAgICAgICBjb25zdCBfZ3JvdXAgPSBzdHJpbmdUb1NsdWcoZ3JvdXApO1xuXG4gICAgICAgIGNvbnN0IHRhcmdldEdyb3VwID0gKExhenlMb2FkZXJTZXJ2aWNlLnJlZ2lzdHJ5W19ncm91cF0gfHwgW10pO1xuXG4gICAgICAgIGxldCBpdGVtcyA9IHRhcmdldEdyb3VwLmZpbHRlcih0ID0+IHtcbiAgICAgICAgICAgIGlmICghdCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBObyBtYXRjaGVyLCBjaGVjayBpZFxuICAgICAgICAgICAgaWYgKCF0Lm1hdGNoZXIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHQuaWQgPT0gdmFsdWUgfHwgdFskaWRdID09IF9pZDtcblxuICAgICAgICAgICAgLy8gTWF0Y2hlciBpcyByZWdleFxuICAgICAgICAgICAgaWYgKHQubWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAgICAgICAgICAgICByZXR1cm4gdC5tYXRjaGVyLnRlc3QodmFsdWUpIHx8IHQubWF0Y2hlci50ZXN0KF9pZCk7XG5cbiAgICAgICAgICAgIC8vIE1hdGNoZXIgaXMgc3RyaW5nID0+IHJlZ2V4XG4gICAgICAgICAgICBpZiAodHlwZW9mIHQubWF0Y2hlciA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJ4ID0gbmV3IFJlZ0V4cCh0Lm1hdGNoZXIsICd1aScpO1xuICAgICAgICAgICAgICAgIHJldHVybiByeC50ZXN0KHZhbHVlKSB8fCByeC50ZXN0KF9pZCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE1hdGNoZXIgaXMgYXJyYXlcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHQubWF0Y2hlcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gISF0Lm1hdGNoZXIuZmluZChlID0+IHN0cmluZ1RvU2x1ZyhlKSA9PSBfaWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDdXN0b20gbWF0Y2hlciBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0Lm1hdGNoZXIgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgICAgIHJldHVybiB0Lm1hdGNoZXIoX2lkKTtcblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhpcy53YXJuKFwiUmVzb2x2ZWQgbXVsdGlwbGUgY29tcG9uZW50cyBmb3IgdGhlIHByb3ZpZGVkIGBbY29tcG9uZW50XWAgYmluZGluZy4gVGhpcyBtYXkgY2F1c2UgVUkgY29uZmxpY3RzLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3V0ID0gaXRlbXNbMF07XG5cbiAgICAgICAgaWYgKG91dC5tYXRjaGVyIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB2YWx1ZS5tYXRjaChvdXQubWF0Y2hlcikgfHwgX2lkLm1hdGNoKG91dC5tYXRjaGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlbnRyeTogb3V0LFxuICAgICAgICAgICAgICAgIG1hdGNoR3JvdXBzOiByZXN1bHQ/Lmdyb3Vwc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGVudHJ5OiBvdXQgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhIGNvbXBvbmVudCBpcyBjdXJyZW50bHkgcmVnaXN0ZXJlZFxuICAgICAqIENhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIHJlZ2V4IG1hdGNoZXJzIGFuZCBhbGlhc2VzLlxuICAgICAqL1xuICAgIHB1YmxpYyBpc0NvbXBvbmVudFJlZ2lzdGVyZWQodmFsdWU6IHN0cmluZywgZ3JvdXAgPSBcImRlZmF1bHRcIikge1xuICAgICAgICByZXR1cm4gISF0aGlzLnJlc29sdmVSZWdpc3RyYXRpb25FbnRyeSh2YWx1ZSwgZ3JvdXApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIGJ1bmRsZVxuICAgICAqIEByZXR1cm5zIFRoZSBjb21wb25lbnQgYE9iamVjdGAgaWYgYSBjb21wb25lbnQgd2FzIHJlc29sdmVkLCBgbnVsbGAgaWYgbm8gY29tcG9uZW50IHdhcyBmb3VuZFxuICAgICAqIGBmYWxzZWAgaWYgdGhlIHNwZWNpZmllZCBzdHJhdGVneSB3YXMgYW4gaW52YWxpZCBzZWxlY3Rpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVzb2x2ZUNvbXBvbmVudChpZDogc3RyaW5nLCBncm91cDogc3RyaW5nLCBtb2R1bGVzOiAoQ29tcGlsZWRDb21wb25lbnQgfCBDb21waWxlZE1vZHVsZSlbXSk6IE9iamVjdCB8IG51bGwgfCBmYWxzZSB7XG5cbiAgICAgICAgc3dpdGNoIChMYXp5TG9hZGVyU2VydmljZS5jb25maWcuY29tcG9uZW50UmVzb2x2ZVN0cmF0ZWd5KSB7XG4gICAgICAgICAgICBjYXNlIENvbXBvbmVudFJlc29sdmVTdHJhdGVneS5QaWNrRmlyc3Q6IHtcblxuICAgICAgICAgICAgICAgIHJldHVybiBtb2R1bGVzWzBdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeGFjdCBpZCAtPiBjbGFzc25hbWUgbWF0Y2hcbiAgICAgICAgICAgIGNhc2UgQ29tcG9uZW50UmVzb2x2ZVN0cmF0ZWd5Lk1hdGNoSWRUb0NsYXNzTmFtZToge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPVxuICAgICAgICAgICAgICAgICAgICBtb2R1bGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGsgPT4gay5uYW1lID09IGlkKTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PSAwKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRnV6enkgaWQgLT4gY2xhc3NuYW1lIG1hdGNoXG4gICAgICAgICAgICBjYXNlIENvbXBvbmVudFJlc29sdmVTdHJhdGVneS5GdXp6eUlkQ2xhc3NOYW1lOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgX2lkID0gaWQucmVwbGFjZSgvW15hLXowLTlfXFwtXS9pZywgJycpO1xuXG4gICAgICAgICAgICAgICAgaWYgKF9pZC5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBMYXp5TG9hZGVyU2VydmljZS5jb25maWcubG9nZ2VyLmVycihcIkZ1enp5IGNsYXNzbmFtZSBtYXRjaGluZyBzdHJpcHBlZCBhbGwgc3ltYm9scyBmcm9tIHRoZSBJRCBzcGVjaWZpZWQhXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcnggPSBuZXcgUmVnRXhwKGBeJHtpZH0oY29tcG9uZW50fG1vZHVsZSk/JGAsIFwiaVwiKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSBtb2R1bGVzXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIobW9kID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBraWQgPSBtb2QubmFtZS5yZXBsYWNlKC9bXmEtejAtOV9cXC1dL2lnLCAnJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByeC50ZXN0KGtpZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBMYXp5TG9hZGVyU2VydmljZS5jb25maWcubG9nZ2VyLmVycihcIkZ1enp5IGNsYXNzbmFtZSBtYXRjaGluZyByZXNvbHZlZCBtdWx0aXBsZSB0YXJnZXRzIVwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIExhenlMb2FkZXJTZXJ2aWNlLmNvbmZpZy5sb2dnZXIuZXJyKFwiRnV6enkgY2xhc3NuYW1lIG1hdGNoaW5nIHJlc29sdmVkIG5vIHRhcmdldHMhXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgQ29tcG9uZW50UmVzb2x2ZVN0cmF0ZWd5LkN1c3RvbToge1xuICAgICAgICAgICAgICAgIHJldHVybiBMYXp5TG9hZGVyU2VydmljZS5jb25maWcuY3VzdG9tUmVzb2x2ZXIobW9kdWxlcyBhcyBhbnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==