@ssv/ngx.command
Version:
Command pattern implementation for angular. Command used to encapsulate information which is needed to perform an action.
165 lines • 20.7 kB
JavaScript
import { Directive, Input, HostListener, ElementRef, Renderer2, ChangeDetectorRef, inject, } from "@angular/core";
import { Subject, tap, delay, takeUntil } from "rxjs";
import { COMMAND_OPTIONS } from "./command.options";
import { Command } from "./command";
import { isCommand, isCommandCreator } from "./command.util";
import * as i0 from "@angular/core";
/**
* Controls the state of a component in sync with `Command`.
*
* @example
* ### Most common usage
* ```html
* <button [ssvCommand]="saveCmd">Save</button>
* ```
*
*
* ### Usage with options
* ```html
* <button [ssvCommand]="saveCmd" [ssvCommandOptions]="{executingCssClass: 'in-progress'}">Save</button>
* ```
*
*
* ### Usage with params
* This is useful for collections (loops) or using multiple actions with different args.
* *NOTE: This will share the `isExecuting` when used with multiple controls.*
*
* #### With single param
*
* ```html
* <button [ssvCommand]="saveCmd" [ssvCommandParams]="{id: 1}">Save</button>
* ```
* *NOTE: if you have only 1 argument as an array, it should be enclosed within an array e.g. `[['apple', 'banana']]`,
* else it will spread and you will `arg1: "apple", arg2: "banana"`*
*
* #### With multi params
* ```html
* <button [ssvCommand]="saveCmd" [ssvCommandParams]="[{id: 1}, 'hello', hero]">Save</button>
* ```
*
* ### Usage with Command Creator
* This is useful for collections (loops) or using multiple actions with different args, whilst not sharing `isExecuting`.
*
*
* ```html
* <button [ssvCommand]="{host: this, execute: removeHero$, canExecute: isValid$, params: [hero, 1337, 'xx']}">Save</button>
* ```
*
*/
const NAME_CAMEL = "ssvCommand";
// let nextUniqueId = 0;
export class CommandDirective {
// readonly id = `${NAME_CAMEL}-${nextUniqueId++}`;
globalOptions = inject(COMMAND_OPTIONS);
renderer = inject(Renderer2);
element = inject(ElementRef);
cdr = inject(ChangeDetectorRef);
commandOrCreator;
get commandOptions() { return this._commandOptions; }
set commandOptions(value) {
if (value === this._commandOptions) {
return;
}
this._commandOptions = {
...this.globalOptions,
...value,
};
}
commandParams;
get command() { return this._command; }
_command;
_commandOptions = this.globalOptions;
_destroy$ = new Subject();
ngOnInit() {
// console.log("[ssvCommand::init]", this.globalOptions);
if (!this.commandOrCreator) {
throw new Error(`${NAME_CAMEL}: [${NAME_CAMEL}] should be defined!`);
}
else if (isCommand(this.commandOrCreator)) {
this._command = this.commandOrCreator;
}
else if (isCommandCreator(this.commandOrCreator)) {
const isAsync = this.commandOrCreator.isAsync || this.commandOrCreator.isAsync === undefined;
// todo: find something like this for ivy (or angular10+)
// const hostComponent = (this.viewContainer as any)._view.component;
const execFn = this.commandOrCreator.execute.bind(this.commandOrCreator.host);
this.commandParams = this.commandParams || this.commandOrCreator.params;
const canExec = this.commandOrCreator.canExecute instanceof Function
? this.commandOrCreator.canExecute.bind(this.commandOrCreator.host, this.commandParams)()
: this.commandOrCreator.canExecute;
// console.log("[ssvCommand::init] command creator", {
// firstParam: this.commandParams ? this.commandParams[0] : null,
// params: this.commandParams
// });
this._command = new Command(execFn, canExec, isAsync);
}
else {
throw new Error(`${NAME_CAMEL}: [${NAME_CAMEL}] is not defined properly!`);
}
this._command.subscribe();
this._command.canExecute$.pipe(this.commandOptions.hasDisabledDelay
? delay(1)
: tap(() => { }), tap(x => {
this.trySetDisabled(!x);
// console.log("[ssvCommand::canExecute$]", { canExecute: x });
this.cdr.markForCheck();
}), takeUntil(this._destroy$)).subscribe();
if (this._command.isExecuting$) {
this._command.isExecuting$.pipe(tap(x => {
// console.log("[ssvCommand::isExecuting$]", x, this.commandOptions);
if (x) {
this.renderer.addClass(this.element.nativeElement, this.commandOptions.executingCssClass);
}
else {
this.renderer.removeClass(this.element.nativeElement, this.commandOptions.executingCssClass);
}
}), takeUntil(this._destroy$)).subscribe();
}
}
onClick() {
// console.log("[ssvCommand::onClick]", this.commandParams);
if (Array.isArray(this.commandParams)) {
this._command.execute(...this.commandParams);
}
else {
this._command.execute(this.commandParams);
}
}
ngOnDestroy() {
// console.log("[ssvCommand::destroy]");
this._destroy$.next();
this._destroy$.complete();
if (this._command) {
this._command.unsubscribe();
}
}
trySetDisabled(disabled) {
if (this.commandOptions.handleDisabled) {
// console.warn(">>>> disabled", { id: this.id, disabled });
this.renderer.setProperty(this.element.nativeElement, "disabled", disabled);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: CommandDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.9", type: CommandDirective, isStandalone: true, selector: "[ssvCommand]", inputs: { commandOrCreator: ["ssvCommand", "commandOrCreator"], commandOptions: ["ssvCommandOptions", "commandOptions"], commandParams: ["ssvCommandParams", "commandParams"] }, host: { listeners: { "click": "onClick()" } }, exportAs: ["ssvCommand"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: CommandDirective, decorators: [{
type: Directive,
args: [{
selector: `[${NAME_CAMEL}]`,
exportAs: NAME_CAMEL,
standalone: true,
}]
}], propDecorators: { commandOrCreator: [{
type: Input,
args: [NAME_CAMEL]
}], commandOptions: [{
type: Input,
args: [`${NAME_CAMEL}Options`]
}], commandParams: [{
type: Input,
args: [`${NAME_CAMEL}Params`]
}], onClick: [{
type: HostListener,
args: ["click"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL25neC5jb21tYW5kL3NyYy9jb21tYW5kLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUdULEtBQUssRUFDTCxZQUFZLEVBQ1osVUFBVSxFQUNWLFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsTUFBTSxHQUNOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdEQsT0FBTyxFQUF1QixlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFHN0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUNHO0FBRUgsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBRWhDLHdCQUF3QjtBQU94QixNQUFNLE9BQU8sZ0JBQWdCO0lBRTVCLG1EQUFtRDtJQUNsQyxhQUFhLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3hDLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0IsT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM3QixHQUFHLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFFOUIsZ0JBQWdCLENBQXdDO0lBRTNFLElBQ0ksY0FBYyxLQUFxQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLElBQUksY0FBYyxDQUFDLEtBQThCO1FBQ2hELElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxlQUFl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UUFBaUI7UUFDdkMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hDLDREQUE0RDtZQUM1RCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDN0UsQ0FBQztJQUNGLENBQUM7dUdBcEhXLGdCQUFnQjsyRkFBaEIsZ0JBQWdCOzsyRkFBaEIsZ0JBQWdCO2tCQUw1QixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSxJQUFJLFVBQVUsR0FBRztvQkFDM0IsUUFBUSxFQUFFLFVBQVU7b0JBQ3BCLFVBQVUsRUFBRSxJQUFJO2lCQUNoQjs4QkFTbUIsZ0JBQWdCO3NCQUFsQyxLQUFLO3VCQUFDLFVBQVU7Z0JBR2IsY0FBYztzQkFEakIsS0FBSzt1QkFBQyxHQUFHLFVBQVUsU0FBUztnQkFZQyxhQUFhO3NCQUExQyxLQUFLO3VCQUFDLEdBQUcsVUFBVSxRQUFRO2dCQXVFNUIsT0FBTztzQkFETixZQUFZO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHREaXJlY3RpdmUsXG5cdE9uSW5pdCxcblx0T25EZXN0cm95LFxuXHRJbnB1dCxcblx0SG9zdExpc3RlbmVyLFxuXHRFbGVtZW50UmVmLFxuXHRSZW5kZXJlcjIsXG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHRpbmplY3QsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBTdWJqZWN0LCB0YXAsIGRlbGF5LCB0YWtlVW50aWwgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQgeyB0eXBlIENvbW1hbmRPcHRpb25zLCBDT01NQU5EX09QVElPTlMgfSBmcm9tIFwiLi9jb21tYW5kLm9wdGlvbnNcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiLi9jb21tYW5kXCI7XG5pbXBvcnQgeyBpc0NvbW1hbmQsIGlzQ29tbWFuZENyZWF0b3IgfSBmcm9tIFwiLi9jb21tYW5kLnV0aWxcIjtcbmltcG9ydCB7IENvbW1hbmRDcmVhdG9yLCB0eXBlIElDb21tYW5kIH0gZnJvbSBcIi4vY29tbWFuZC5tb2RlbFwiO1xuXG4vKipcbiAqIENvbnRyb2xzIHRoZSBzdGF0ZSBvZiBhIGNvbXBvbmVudCBpbiBzeW5jIHdpdGggYENvbW1hbmRgLlxuICpcbiAqIEBleGFtcGxlXG4gKiAjIyMgTW9zdCBjb21tb24gdXNhZ2VcbiAqIGBgYGh0bWxcbiAqIDxidXR0b24gW3NzdkNvbW1hbmRdPVwic2F2ZUNtZFwiPlNhdmU8L2J1dHRvbj5cbiAqIGBgYFxuICpcbiAqXG4gKiAjIyMgVXNhZ2Ugd2l0aCBvcHRpb25zXG4gKiBgYGBodG1sXG4gKiA8YnV0dG9uIFtzc3ZDb21tYW5kXT1cInNhdmVDbWRcIiBbc3N2Q29tbWFuZE9wdGlvbnNdPVwie2V4ZWN1dGluZ0Nzc0NsYXNzOiAnaW4tcHJvZ3Jlc3MnfVwiPlNhdmU8L2J1dHRvbj5cbiAqIGBgYFxuICpcbiAqXG4gKiAjIyMgVXNhZ2Ugd2l0aCBwYXJhbXNcbiAqIFRoaXMgaXMgdXNlZnVsIGZvciBjb2xsZWN0aW9ucyAobG9vcHMpIG9yIHVzaW5nIG11bHRpcGxlIGFjdGlvbnMgd2l0aCBkaWZmZXJlbnQgYXJncy5cbiAqICpOT1RFOiBUaGlzIHdpbGwgc2hhcmUgdGhlIGBpc0V4ZWN1dGluZ2Agd2hlbiB1c2VkIHdpdGggbXVsdGlwbGUgY29udHJvbHMuKlxuICpcbiAqICMjIyMgV2l0aCBzaW5nbGUgcGFyYW1cbiAqXG4gKiBgYGBodG1sXG4gKiA8YnV0dG9uIFtzc3ZDb21tYW5kXT1cInNhdmVDbWRcIiBbc3N2Q29tbWFuZFBhcmFtc109XCJ7aWQ6IDF9XCI+U2F2ZTwvYnV0dG9uPlxuICogYGBgXG4gKiAqTk9URTogaWYgeW91IGhhdmUgb25seSAxIGFyZ3VtZW50IGFzIGFuIGFycmF5LCBpdCBzaG91bGQgYmUgZW5jbG9zZWQgd2l0aGluIGFuIGFycmF5IGUuZy4gYFtbJ2FwcGxlJywgJ2JhbmFuYSddXWAsXG4gKiBlbHNlIGl0IHdpbGwgc3ByZWFkIGFuZCB5b3Ugd2lsbCBgYXJnMTogXCJhcHBsZVwiLCBhcmcyOiBcImJhbmFuYVwiYCpcbiAqXG4gKiAjIyMjIFdpdGggbXVsdGkgcGFyYW1zXG4gKiBgYGBodG1sXG4gKiA8YnV0dG9uIFtzc3ZDb21tYW5kXT1cInNhdmVDbWRcIiBbc3N2Q29tbWFuZFBhcmFtc109XCJbe2lkOiAxfSwgJ2hlbGxvJywgaGVyb11cIj5TYXZlPC9idXR0b24+XG4gKiBgYGBcbiAqXG4gKiAjIyMgVXNhZ2Ugd2l0aCBDb21tYW5kIENyZWF0b3JcbiAqIFRoaXMgaXMgdXNlZnVsIGZvciBjb2xsZWN0aW9ucyAobG9vcHMpIG9yIHVzaW5nIG11bHRpcGxlIGFjdGlvbnMgd2l0aCBkaWZmZXJlbnQgYXJncywgd2hpbHN0IG5vdCBzaGFyaW5nIGBpc0V4ZWN1dGluZ2AuXG4gKlxuICpcbiAqIGBgYGh0bWxcbiAqIDxidXR0b24gW3NzdkNvbW1hbmRdPVwie2hvc3Q6IHRoaXMsIGV4ZWN1dGU6IHJlbW92ZUhlcm8kLCBjYW5FeGVjdXRlOiBpc1ZhbGlkJCwgcGFyYW1zOiBbaGVybywgMTMzNywgJ3h4J119XCI+U2F2ZTwvYnV0dG9uPlxuICogYGBgXG4gKlxuICovXG5cbmNvbnN0IE5BTUVfQ0FNRUwgPSBcInNzdkNvbW1hbmRcIjtcblxuLy8gbGV0IG5leHRVbmlxdWVJZCA9IDA7XG5cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogYFske05BTUVfQ0FNRUx9XWAsXG5cdGV4cG9ydEFzOiBOQU1FX0NBTUVMLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDb21tYW5kRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG5cdC8vIHJlYWRvbmx5IGlkID0gYCR7TkFNRV9DQU1FTH0tJHtuZXh0VW5pcXVlSWQrK31gO1xuXHRwcml2YXRlIHJlYWRvbmx5IGdsb2JhbE9wdGlvbnMgPSBpbmplY3QoQ09NTUFORF9PUFRJT05TKTtcblx0cHJpdmF0ZSByZWFkb25seSByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuXHRwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZik7XG5cdHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuXHRASW5wdXQoTkFNRV9DQU1FTCkgY29tbWFuZE9yQ3JlYXRvcjogSUNvbW1hbmQgfCBDb21tYW5kQ3JlYXRvciB8IHVuZGVmaW5lZDtcblxuXHRASW5wdXQoYCR7TkFNRV9DQU1FTH1PcHRpb25zYClcblx0Z2V0IGNvbW1hbmRPcHRpb25zKCk6IENvbW1hbmRPcHRpb25zIHsgcmV0dXJuIHRoaXMuX2NvbW1hbmRPcHRpb25zOyB9XG5cdHNldCBjb21tYW5kT3B0aW9ucyh2YWx1ZTogUGFydGlhbDxDb21tYW5kT3B0aW9ucz4pIHtcblx0XHRpZiAodmFsdWUgPT09IHRoaXMuX2NvbW1hbmRPcHRpb25zKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuX2NvbW1hbmRPcHRpb25zID0ge1xuXHRcdFx0Li4udGhpcy5nbG9iYWxPcHRpb25zLFxuXHRcdFx0Li4udmFsdWUsXG5cdFx0fTtcblx0fVxuXG5cdEBJbnB1dChgJHtOQU1FX0NBTUVMfVBhcmFtc2ApIGNvbW1hbmRQYXJhbXM6IHVua25vd24gfCB1bmtub3duW107XG5cblx0Z2V0IGNvbW1hbmQoKTogSUNvbW1hbmQgeyByZXR1cm4gdGhpcy5fY29tbWFuZDsgfVxuXG5cdHByaXZhdGUgX2NvbW1hbmQhOiBJQ29tbWFuZDtcblx0cHJpdmF0ZSBfY29tbWFuZE9wdGlvbnM6IENvbW1hbmRPcHRpb25zID0gdGhpcy5nbG9iYWxPcHRpb25zO1xuXHRwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cblx0bmdPbkluaXQoKTogdm9pZCB7XG5cdFx0Ly8gY29uc29sZS5sb2coXCJbc3N2Q29tbWFuZDo6aW5pdF1cIiwgdGhpcy5nbG9iYWxPcHRpb25zKTtcblx0XHRpZiAoIXRoaXMuY29tbWFuZE9yQ3JlYXRvcikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGAke05BTUVfQ0FNRUx9OiBbJHtOQU1FX0NBTUVMfV0gc2hvdWxkIGJlIGRlZmluZWQhYCk7XG5cdFx0fSBlbHNlIGlmIChpc0NvbW1hbmQodGhpcy5jb21tYW5kT3JDcmVhdG9yKSkge1xuXHRcdFx0dGhpcy5fY29tbWFuZCA9IHRoaXMuY29tbWFuZE9yQ3JlYXRvcjtcblx0XHR9IGVsc2UgaWYgKGlzQ29tbWFuZENyZWF0b3IodGhpcy5jb21tYW5kT3JDcmVhdG9yKSkge1xuXHRcdFx0Y29uc3QgaXNBc3luYyA9IHRoaXMuY29tbWFuZE9yQ3JlYXRvci5pc0FzeW5jIHx8IHRoaXMuY29tbWFuZE9yQ3JlYXRvci5pc0FzeW5jID09PSB1bmRlZmluZWQ7XG5cblx0XHRcdC8vIHRvZG86IGZpbmQgc29tZXRoaW5nIGxpa2UgdGhpcyBmb3IgaXZ5IChvciBhbmd1bGFyMTArKVxuXHRcdFx0Ly8gY29uc3QgaG9zdENvbXBvbmVudCA9ICh0aGlzLnZpZXdDb250YWluZXIgYXMgYW55KS5fdmlldy5jb21wb25lbnQ7XG5cblx0XHRcdGNvbnN0IGV4ZWNGbiA9IHRoaXMuY29tbWFuZE9yQ3JlYXRvci5leGVjdXRlLmJpbmQodGhpcy5jb21tYW5kT3JDcmVhdG9yLmhvc3QpO1xuXHRcdFx0dGhpcy5jb21tYW5kUGFyYW1zID0gdGhpcy5jb21tYW5kUGFyYW1zIHx8IHRoaXMuY29tbWFuZE9yQ3JlYXRvci5wYXJhbXM7XG5cblx0XHRcdGNvbnN0IGNhbkV4ZWMgPSB0aGlzLmNvbW1hbmRPckNyZWF0b3IuY2FuRXhlY3V0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uXG5cdFx0XHRcdD8gdGhpcy5jb21tYW5kT3JDcmVhdG9yLmNhbkV4ZWN1dGUuYmluZCh0aGlzLmNvbW1hbmRPckNyZWF0b3IuaG9zdCwgdGhpcy5jb21tYW5kUGFyYW1zKSgpXG5cdFx0XHRcdDogdGhpcy5jb21tYW5kT3JDcmVhdG9yLmNhbkV4ZWN1dGU7XG5cblx0XHRcdC8vIGNvbnNvbGUubG9nKFwiW3NzdkNvbW1hbmQ6OmluaXRdIGNvbW1hbmQgY3JlYXRvclwiLCB7XG5cdFx0XHQvLyBcdGZpcnN0UGFyYW06IHRoaXMuY29tbWFuZFBhcmFtcyA/IHRoaXMuY29tbWFuZFBhcmFtc1swXSA6IG51bGwsXG5cdFx0XHQvLyBcdHBhcmFtczogdGhpcy5jb21tYW5kUGFyYW1zXG5cdFx0XHQvLyB9KTtcblx0XHRcdHRoaXMuX2NvbW1hbmQgPSBuZXcgQ29tbWFuZChleGVjRm4sIGNhbkV4ZWMsIGlzQXN5bmMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYCR7TkFNRV9DQU1FTH06IFske05BTUVfQ0FNRUx9XSBpcyBub3QgZGVmaW5lZCBwcm9wZXJseSFgKTtcblx0XHR9XG5cblx0XHR0aGlzLl9jb21tYW5kLnN1YnNjcmliZSgpO1xuXHRcdHRoaXMuX2NvbW1hbmQuY2FuRXhlY3V0ZSQucGlwZShcblx0XHRcdHRoaXMuY29tbWFuZE9wdGlvbnMuaGFzRGlzYWJsZWREZWxheVxuXHRcdFx0XHQ/IGRlbGF5KDEpXG5cdFx0XHRcdDogdGFwKCgpID0+IHsgLyogc3R1YiAqLyB9KSxcblx0XHRcdHRhcCh4ID0+IHtcblx0XHRcdFx0dGhpcy50cnlTZXREaXNhYmxlZCgheCk7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKFwiW3NzdkNvbW1hbmQ6OmNhbkV4ZWN1dGUkXVwiLCB7IGNhbkV4ZWN1dGU6IHggfSk7XG5cdFx0XHRcdHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXHRcdFx0fSksXG5cdFx0XHR0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuXHRcdCkuc3Vic2NyaWJlKCk7XG5cblx0XHRpZiAodGhpcy5fY29tbWFuZC5pc0V4ZWN1dGluZyQpIHtcblx0XHRcdHRoaXMuX2NvbW1hbmQuaXNFeGVjdXRpbmckLnBpcGUoXG5cdFx0XHRcdHRhcCh4ID0+IHtcblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyhcIltzc3ZDb21tYW5kOjppc0V4ZWN1dGluZyRdXCIsIHgsIHRoaXMuY29tbWFuZE9wdGlvbnMpO1xuXHRcdFx0XHRcdGlmICh4KSB7XG5cdFx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLmFkZENsYXNzKFxuXHRcdFx0XHRcdFx0XHR0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCxcblx0XHRcdFx0XHRcdFx0dGhpcy5jb21tYW5kT3B0aW9ucy5leGVjdXRpbmdDc3NDbGFzc1xuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhcblx0XHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdFx0XHRcdHRoaXMuY29tbWFuZE9wdGlvbnMuZXhlY3V0aW5nQ3NzQ2xhc3Ncblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSxcblx0XHRcdFx0dGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcblx0XHRcdCkuc3Vic2NyaWJlKCk7XG5cdFx0fVxuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImNsaWNrXCIpXG5cdG9uQ2xpY2soKTogdm9pZCB7XG5cdFx0Ly8gY29uc29sZS5sb2coXCJbc3N2Q29tbWFuZDo6b25DbGlja11cIiwgdGhpcy5jb21tYW5kUGFyYW1zKTtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmNvbW1hbmRQYXJhbXMpKSB7XG5cdFx0XHR0aGlzLl9jb21tYW5kLmV4ZWN1dGUoLi4udGhpcy5jb21tYW5kUGFyYW1zKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fY29tbWFuZC5leGVjdXRlKHRoaXMuY29tbWFuZFBhcmFtcyk7XG5cdFx0fVxuXHR9XG5cblx0bmdPbkRlc3Ryb3koKTogdm9pZCB7XG5cdFx0Ly8gY29uc29sZS5sb2coXCJbc3N2Q29tbWFuZDo6ZGVzdHJveV1cIik7XG5cdFx0dGhpcy5fZGVzdHJveSQubmV4dCgpO1xuXHRcdHRoaXMuX2Rlc3Ryb3kkLmNvbXBsZXRlKCk7XG5cdFx0aWYgKHRoaXMuX2NvbW1hbmQpIHtcblx0XHRcdHRoaXMuX2NvbW1hbmQudW5zdWJzY3JpYmUoKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHRyeVNldERpc2FibGVkKGRpc2FibGVkOiBib29sZWFuKSB7XG5cdFx0aWYgKHRoaXMuY29tbWFuZE9wdGlvbnMuaGFuZGxlRGlzYWJsZWQpIHtcblx0XHRcdC8vIGNvbnNvbGUud2FybihcIj4+Pj4gZGlzYWJsZWRcIiwgeyBpZDogdGhpcy5pZCwgZGlzYWJsZWQgfSk7XG5cdFx0XHR0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LCBcImRpc2FibGVkXCIsIGRpc2FibGVkKTtcblx0XHR9XG5cdH1cblxufVxuXG4iXX0=