@dotglitch/ngx-common
Version:
Angular components and utilities that are commonly used.
217 lines • 32 kB
JavaScript
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==