@qoollo/ngx-form-url-saver
Version:
Angular directive for syncing form's data with URL query
171 lines • 25.8 kB
JavaScript
import { SeparatedQueryGenerationStrategy } from './query-generation-strategies/separated-query-generation-strategy';
import { UnitedQueryGenerationStrategy } from './query-generation-strategies/united-query-generation-strategy';
import { Directive, forwardRef, Inject, Input, Optional, Self } from '@angular/core';
import { ControlContainer, FormGroupDirective, NG_ASYNC_VALIDATORS, NG_VALIDATORS, } from '@angular/forms';
import { debounceTime, map, startWith } from 'rxjs';
import { FORM_VALUE_HANDLING_TOKEN, NGX_FORM_URL_SAVER_STRATEGY_PROVIDER } from './form-value-handling-strategies/token';
import { SeparatedComplexQueryGenerationStrategy } from './query-generation-strategies/separated-complex-query-generation-strategy';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
const formDirectiveProvider = {
provide: ControlContainer,
useExisting: forwardRef(() => FormUrlSaverDirective),
};
/**
* @description
* The directive is a descendant of Angular `FormGroupDirective`
* and is used to automatically write the `FormGroup` value to the query parameters.
*
* {@link https://github.com/angular/angular/blob/main/packages/forms/src/directives/reactive_directives/form_group_directive.ts Angular FormGroupDirective}
*
* Allows you to set a delay (_debounce_) for query updates.
*
* Allows you to select the method (_strategy_) of writing query parameters.
* 'united' - the form value will be completely written in one parameter
* 'separated' - each form field will be written in its own query parameter.
* 'complex' - each form field will be written in its own query parameter, while saving nested objects in the form is supported.
*
* It is possible to override the behavior of converting the form value to a string.
* Default is JSON.stringify.
* Use the ValueHandlingStrategy interface and FORM_VALUE_HANDLING_TOKEN
*
*/
export class FormUrlSaverDirective extends FormGroupDirective {
constructor(router, activatedRoute, cdr, formHandlingStrategy,
/**
* Default Angular FormGroupDirective dependencies
*/
_validators, _asyncValidators) {
super(_validators, _asyncValidators);
this.router = router;
this.activatedRoute = activatedRoute;
this.cdr = cdr;
this.formHandlingStrategy = formHandlingStrategy;
this._validators = _validators;
this._asyncValidators = _asyncValidators;
this.BASE_DEBOUNCE_TIME = 500;
this.form = null;
/**
* Query parameter update delay time
*/
this.debounceTime = this.BASE_DEBOUNCE_TIME;
/**
* Strategy for creating query parameters.
*
* If 'united' is specified, the form value will be completely written using the key of one query parameter
*
* If 'separated' is specified, each form field will be written with a separate key corresponding to its name in the form
*
* If 'complex' is specified, each form field will be written in its own query parameter, while saving nested objects in the form is supported.
*/
this.strategy = 'complex';
/**
* The key by which the form value will be written if the 'united' strategy is selected.
*/
this.queryKey = 'form';
this.useDateTime = false;
}
// #region Lifecycle methods
ngAfterViewInit() {
this.queryStrategy = this.createQueryGenerationStrategy();
this.fillFormFromQuery();
this.subscribeToFormValueChanges();
this.cdr.detectChanges();
}
ngOnDestroy() {
super.ngOnDestroy();
this.formValueChangedSubscription?.unsubscribe();
this.clearFormQuery();
}
// #endregion
getUpdatedObjectByPath(object, path, parser) {
const decomposedPath = path.split('.');
const base = decomposedPath[0];
let temp;
if (base === undefined || !object) {
return { ...object };
}
temp = decomposedPath.length <= 1 ? parser(object[base]) : this.getUpdatedObjectByPath(object[base], decomposedPath.slice(1).join('.'), parser);
return {
...object,
[base]: temp,
};
}
fillFormFromQuery() {
const currentQueryParams = this.activatedRoute.snapshot.queryParams;
const inferredFormValue = this.queryStrategy.inferFormValueFromQuery(currentQueryParams, this.form.value);
let updatedObject = inferredFormValue;
this.dataTransformMap?.forEach((parser, path) => {
updatedObject = this.getUpdatedObjectByPath(updatedObject, path, parser);
});
this.form.patchValue(updatedObject);
this.subscribeToFormValueChanges();
}
createQueryGenerationStrategy() {
const strategies = {
'united': new UnitedQueryGenerationStrategy(this.formHandlingStrategy, this.queryKey),
'separated': new SeparatedQueryGenerationStrategy(this.formHandlingStrategy),
'complex': new SeparatedComplexQueryGenerationStrategy(this.useDateTime)
};
return strategies[this.strategy];
}
subscribeToFormValueChanges() {
this.formValueChangedSubscription = this.form.valueChanges.pipe(startWith(this.form.value), debounceTime(this.debounceTime), map((value, index) => [value, index])).subscribe(([value, index]) => {
void this.router.navigate([], {
queryParams: this.queryStrategy.convertFormValueToQueryObject(value),
queryParamsHandling: 'merge',
replaceUrl: index === 0,
});
});
}
clearFormQuery() {
setTimeout(() => {
void this.router.navigate([], {
queryParams: this.queryStrategy.createClearingObject(this.form.value),
queryParamsHandling: 'merge',
replaceUrl: true,
});
}, 0);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: FormUrlSaverDirective, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i0.ChangeDetectorRef }, { token: FORM_VALUE_HANDLING_TOKEN }, { token: NG_VALIDATORS, optional: true, self: true }, { token: NG_ASYNC_VALIDATORS, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.2", type: FormUrlSaverDirective, isStandalone: true, selector: "[ngxFormUrlSaver]", inputs: { form: ["ngxFormUrlSaver", "form"], debounceTime: "debounceTime", strategy: "strategy", queryKey: "queryKey", useDateTime: "useDateTime", dataTransformMap: "dataTransformMap" }, providers: [formDirectiveProvider, NGX_FORM_URL_SAVER_STRATEGY_PROVIDER], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: FormUrlSaverDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngxFormUrlSaver]',
providers: [formDirectiveProvider, NGX_FORM_URL_SAVER_STRATEGY_PROVIDER],
standalone: true,
}]
}], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Inject,
args: [FORM_VALUE_HANDLING_TOKEN]
}] }, { type: Array, decorators: [{
type: Optional
}, {
type: Self
}, {
type: Inject,
args: [NG_VALIDATORS]
}] }, { type: Array, decorators: [{
type: Optional
}, {
type: Self
}, {
type: Inject,
args: [NG_ASYNC_VALIDATORS]
}] }], propDecorators: { form: [{
type: Input,
args: ['ngxFormUrlSaver']
}], debounceTime: [{
type: Input
}], strategy: [{
type: Input
}], queryKey: [{
type: Input
}], useDateTime: [{
type: Input
}], dataTransformMap: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS11cmwtc2F2ZXIuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZm9ybS11cmwtc2F2ZXItbGliL3NyYy9saWIvZm9ybS11cmwtc2F2ZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQ3JILE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBRy9HLE9BQU8sRUFBb0MsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEksT0FBTyxFQUdILGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsbUJBQW1CLEVBQ25CLGFBQWEsR0FJaEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsWUFBWSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRXpILE9BQU8sRUFBRSx1Q0FBdUMsRUFBRSxNQUFNLDJFQUEyRSxDQUFDOzs7QUFFcEksTUFBTSxxQkFBcUIsR0FBRztJQUMxQixPQUFPLEVBQUUsZ0JBQWdCO0lBQ3pCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUM7Q0FDdkQsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFNSCxNQUFNLE9BQU8scUJBQXNCLFNBQVEsa0JBQWtCO0lBc0V6RCxZQUNxQixNQUFjLEVBQ2QsY0FBOEIsRUFDOUIsR0FBc0IsRUFHdEIsb0JBQTJDO0lBRTVEOztPQUVHO0lBRWMsV0FBNkMsRUFFN0MsZ0JBQTREO1FBRTdFLEtBQUssQ0FBQyxXQUFXLEVBQUUsZ0JB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QUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3JFLG1CQUFtQixFQUFFLE9BQU87Z0JBQzVCLFVBQVUsRUFBRSxJQUFJO2FBQ25CLENBQUMsQ0FBQztRQUNQLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNWLENBQUM7OEdBM0tRLHFCQUFxQix1R0EyRWxCLHlCQUF5QixhQU1MLGFBQWEseUNBRWIsbUJBQW1CO2tHQW5GMUMscUJBQXFCLDJQQUhuQixDQUFDLHFCQUFxQixFQUFFLG9DQUFvQyxDQUFDOzsyRkFHL0QscUJBQXFCO2tCQUxqQyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFNBQVMsRUFBRSxDQUFDLHFCQUFxQixFQUFFLG9DQUFvQyxDQUFDO29CQUN4RSxVQUFVLEVBQUUsSUFBSTtpQkFDbkI7OzBCQTRFUSxNQUFNOzJCQUFDLHlCQUF5Qjs7MEJBTWhDLFFBQVE7OzBCQUFJLElBQUk7OzBCQUFJLE1BQU07MkJBQUMsYUFBYTs7MEJBRXhDLFFBQVE7OzBCQUFJLElBQUk7OzBCQUFJLE1BQU07MkJBQUMsbUJBQW1CO3lDQTlFbkMsSUFBSTtzQkFEbkIsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBT2pCLFlBQVk7c0JBRGxCLEtBQUs7Z0JBYUMsUUFBUTtzQkFEZCxLQUFLO2dCQU9DLFFBQVE7c0JBRGQsS0FBSztnQkFJQyxXQUFXO3NCQURqQixLQUFLO2dCQWlDQyxnQkFBZ0I7c0JBRHRCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTZXBhcmF0ZWRRdWVyeUdlbmVyYXRpb25TdHJhdGVneSB9IGZyb20gJy4vcXVlcnktZ2VuZXJhdGlvbi1zdHJhdGVnaWVzL3NlcGFyYXRlZC1xdWVyeS1nZW5lcmF0aW9uLXN0cmF0ZWd5JztcbmltcG9ydCB7IFVuaXRlZFF1ZXJ5R2VuZXJhdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9xdWVyeS1nZW5lcmF0aW9uLXN0cmF0ZWdpZXMvdW5pdGVkLXF1ZXJ5LWdlbmVyYXRpb24tc3RyYXRlZ3knO1xuaW1wb3J0IHsgUXVlcnlHZW5lcmF0aW9uU3RyYXRlZ3kgfSBmcm9tICcuL3F1ZXJ5LWdlbmVyYXRpb24tc3RyYXRlZ2llcy9xdWVyeS1nZW5lcmF0aW9uLXN0cmF0ZWd5LmludGVyZmFjZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdG9yUmVmLCBEaXJlY3RpdmUsIGZvcndhcmRSZWYsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT3B0aW9uYWwsIFNlbGYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gICAgQXN5bmNWYWxpZGF0b3IsXG4gICAgQXN5bmNWYWxpZGF0b3JGbixcbiAgICBDb250cm9sQ29udGFpbmVyLFxuICAgIEZvcm1Hcm91cERpcmVjdGl2ZSxcbiAgICBOR19BU1lOQ19WQUxJREFUT1JTLFxuICAgIE5HX1ZBTElEQVRPUlMsXG4gICAgVW50eXBlZEZvcm1Hcm91cCxcbiAgICBWYWxpZGF0b3IsXG4gICAgVmFsaWRhdG9yRm4sXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgbWFwLCBzdGFydFdpdGgsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgRk9STV9WQUxVRV9IQU5ETElOR19UT0tFTiwgTkdYX0ZPUk1fVVJMX1NBVkVSX1NUUkFURUdZX1BST1ZJREVSIH0gZnJvbSAnLi9mb3JtLXZhbHVlLWhhbmRsaW5nLXN0cmF0ZWdpZXMvdG9rZW4nO1xuaW1wb3J0IHsgVmFsdWVIYW5kbGluZ1N0cmF0ZWd5IH0gZnJvbSAnLi9mb3JtLXZhbHVlLWhhbmRsaW5nLXN0cmF0ZWdpZXMvdmFsdWUtaGFuZGxpbmctc3RyYXRlZ3kuaW50ZXJmYWNlJztcbmltcG9ydCB7IFNlcGFyYXRlZENvbXBsZXhRdWVyeUdlbmVyYXRpb25TdHJhdGVneSB9IGZyb20gJy4vcXVlcnktZ2VuZXJhdGlvbi1zdHJhdGVnaWVzL3NlcGFyYXRlZC1jb21wbGV4LXF1ZXJ5LWdlbmVyYXRpb24tc3RyYXRlZ3knO1xuXG5jb25zdCBmb3JtRGlyZWN0aXZlUHJvdmlkZXIgPSB7XG4gICAgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lcixcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBGb3JtVXJsU2F2ZXJEaXJlY3RpdmUpLFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFRoZSBkaXJlY3RpdmUgaXMgYSBkZXNjZW5kYW50IG9mIEFuZ3VsYXIgYEZvcm1Hcm91cERpcmVjdGl2ZWBcbiAqIGFuZCBpcyB1c2VkIHRvIGF1dG9tYXRpY2FsbHkgd3JpdGUgdGhlIGBGb3JtR3JvdXBgIHZhbHVlIHRvIHRoZSBxdWVyeSBwYXJhbWV0ZXJzLlxuICpcbiAqIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2Jsb2IvbWFpbi9wYWNrYWdlcy9mb3Jtcy9zcmMvZGlyZWN0aXZlcy9yZWFjdGl2ZV9kaXJlY3RpdmVzL2Zvcm1fZ3JvdXBfZGlyZWN0aXZlLnRzIEFuZ3VsYXIgRm9ybUdyb3VwRGlyZWN0aXZlfVxuICpcbiAqIEFsbG93cyB5b3UgdG8gc2V0IGEgZGVsYXkgKF9kZWJvdW5jZV8pIGZvciBxdWVyeSB1cGRhdGVzLlxuICpcbiAqIEFsbG93cyB5b3UgdG8gc2VsZWN0IHRoZSBtZXRob2QgKF9zdHJhdGVneV8pIG9mIHdyaXRpbmcgcXVlcnkgcGFyYW1ldGVycy5cbiAqICd1bml0ZWQnIC0gdGhlIGZvcm0gdmFsdWUgd2lsbCBiZSBjb21wbGV0ZWx5IHdyaXR0ZW4gaW4gb25lIHBhcmFtZXRlclxuICogJ3NlcGFyYXRlZCcgLSBlYWNoIGZvcm0gZmllbGQgd2lsbCBiZSB3cml0dGVuIGluIGl0cyBvd24gcXVlcnkgcGFyYW1ldGVyLlxuICogJ2NvbXBsZXgnIC0gZWFjaCBmb3JtIGZpZWxkIHdpbGwgYmUgd3JpdHRlbiBpbiBpdHMgb3duIHF1ZXJ5IHBhcmFtZXRlciwgd2hpbGUgc2F2aW5nIG5lc3RlZCBvYmplY3RzIGluIHRoZSBmb3JtIGlzIHN1cHBvcnRlZC5cbiAqXG4gKiBJdCBpcyBwb3NzaWJsZSB0byBvdmVycmlkZSB0aGUgYmVoYXZpb3Igb2YgY29udmVydGluZyB0aGUgZm9ybSB2YWx1ZSB0byBhIHN0cmluZy5cbiAqIERlZmF1bHQgaXMgSlNPTi5zdHJpbmdpZnkuXG4gKiBVc2UgdGhlIFZhbHVlSGFuZGxpbmdTdHJhdGVneSBpbnRlcmZhY2UgYW5kIEZPUk1fVkFMVUVfSEFORExJTkdfVE9LRU5cbiAqXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW25neEZvcm1VcmxTYXZlcl0nLFxuICAgIHByb3ZpZGVyczogW2Zvcm1EaXJlY3RpdmVQcm92aWRlciwgTkdYX0ZPUk1fVVJMX1NBVkVSX1NUUkFURUdZX1BST1ZJREVSXSxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBGb3JtVXJsU2F2ZXJEaXJlY3RpdmUgZXh0ZW5kcyBGb3JtR3JvdXBEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBCQVNFX0RFQk9VTkNFX1RJTUUgPSA1MDA7XG5cbiAgICBASW5wdXQoJ25neEZvcm1VcmxTYXZlcicpXG4gICAgcHVibGljIG92ZXJyaWRlIGZvcm06IFVudHlwZWRGb3JtR3JvdXAgPSBudWxsITtcblxuICAgIC8qKlxuICAgICAqIFF1ZXJ5IHBhcmFtZXRlciB1cGRhdGUgZGVsYXkgdGltZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGRlYm91bmNlVGltZSA9IHRoaXMuQkFTRV9ERUJPVU5DRV9USU1FO1xuXG4gICAgLyoqXG4gICAgICogU3RyYXRlZ3kgZm9yIGNyZWF0aW5nIHF1ZXJ5IHBhcmFtZXRlcnMuXG4gICAgICpcbiAgICAgKiBJZiAndW5pdGVkJyBpcyBzcGVjaWZpZWQsIHRoZSBmb3JtIHZhbHVlIHdpbGwgYmUgY29tcGxldGVseSB3cml0dGVuIHVzaW5nIHRoZSBrZXkgb2Ygb25lIHF1ZXJ5IHBhcmFtZXRlclxuICAgICAqXG4gICAgICogSWYgJ3NlcGFyYXRlZCcgaXMgc3BlY2lmaWVkLCBlYWNoIGZvcm0gZmllbGQgd2lsbCBiZSB3cml0dGVuIHdpdGggYSBzZXBhcmF0ZSBrZXkgY29ycmVzcG9uZGluZyB0byBpdHMgbmFtZSBpbiB0aGUgZm9ybVxuICAgICAqXG4gICAgICogSWYgJ2NvbXBsZXgnIGlzIHNwZWNpZmllZCwgZWFjaCBmb3JtIGZpZWxkIHdpbGwgYmUgd3JpdHRlbiBpbiBpdHMgb3duIHF1ZXJ5IHBhcmFtZXRlciwgd2hpbGUgc2F2aW5nIG5lc3RlZCBvYmplY3RzIGluIHRoZSBmb3JtIGlzIHN1cHBvcnRlZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzdHJhdGVneTogJ3VuaXRlZCcgfCAnc2VwYXJhdGVkJyB8ICdjb21wbGV4JyA9ICdjb21wbGV4JztcblxuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgYnkgd2hpY2ggdGhlIGZvcm0gdmFsdWUgd2lsbCBiZSB3cml0dGVuIGlmIHRoZSAndW5pdGVkJyBzdHJhdGVneSBpcyBzZWxlY3RlZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBxdWVyeUtleSA9ICdmb3JtJztcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHVzZURhdGVUaW1lID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBNYXAgY29uc2lzdGluZyBvZiBhIHBhdGggdG8gYW4gb2JqZWN0IGluIGEgZm9ybSBhbmQgYSBmdW5jdGlvbiB0aGF0IGNvbnZlcnRzIGEgdmFsdWUgZnJvbSBhbiBhbnkgZGF0YSB0byBhbm90aGVyIGRhdGEgc3RydWN0dXJlLlxuICAgICAqIERhdGEgdHJhbnNmb3JtIGZ1bmN0aW9uIGNhbGxlZCBhZnRlciBgcXVlcnkgc3RyYXRlZ3lgIHBhcnNlZCB1cmwgaW4gYG5nQWZ0ZXJWaWV3SW5pdGAgbGlmZWN5Y2xlIGhvb2sgYW5kIHVwZGF0ZWQgcGFyc2VkIG9iamVjdFxuICAgICAqIHRoZW4gcGF0Y2ggZm9ybSB3aXRoIHVwZGF0ZWQgb2JqZWN0XG4gICAgICpcbiAgICAgKiAjIyMgRXhhbXBsZTpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogZm9ybSA9IG5ldyBGb3JtR3JvdXAoe1xuICAgICAqICBkYXRlOiBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbCksXG4gICAgICogfSk7XG4gICAgICogLy8gQWZ0ZXIgdXJsIHBhcnNlZCBieSBzdHJhdGVneSBhbmQgcmV0dXJuIG9iamVjdCBkYXRhVHJhbnNmb3JtTWFwIHdpbGwgYXBwbHkuXG4gICAgICogZGF0YVRyYW5zZm9ybU1hcCA9IG5ldyBNYXAoW1xuICAgICAqIC8vIEFwcGx5IHRvIHBhcnNlZCBvYmplY3QgYW5kIHRyYW5zZm9ybSB2YWx1ZSAoYXBwbHkgZGF0YSB0cmFuc2Zvcm0gZnVuY3Rpb24pIGJ5IHBhdGggJ2RhdGUnXG4gICAgICogIFsnZGF0ZScsIChkYXRhOiBzdHJpbmcpID0+IGRhdGEgPyBuZXcgRGF0ZShkYXRhKSA6IGRhdGFdXG4gICAgICogXSlcbiAgICAgKiAvLyBkYXRlIHdpbGwgcGFyc2VkIGJ5IHN0cmF0ZWd5IGFzIHN0cmluZ1xuICAgICAqIHVybFF1ZXJ5ID0gJy8/Zm9ybT17XCJkYXRlXCI6XCIyMDI0LTEwLTI5VDIxOjAwOjAwLjAwMFpcIn0nXG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxmb3JtIFtuZ3hGb3JtVXJsU2F2ZXJdPVwiZm9ybVwiPlxuICAgICAqICA8IS0tIHByaW1lTmcgY2FsZW5kYXIgLS0+XG4gICAgICogIDxwLWNhbGVuZGFyIGZvcm1Db250cm9sTmFtZT1cImRhdGVcIiBkYXRlRm9ybWF0PVwiZGQubW0ueXlcIi8+XG4gICAgICogPC9mb3JtPlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHR5cGUge01hcDxzdHJpbmcsIGZ1bmN0aW9uKGFueSk6IGFueT59XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIHBhdGggdG8gZm9ybSB2YWx1ZSBuZXN0ZWQgb2JqZWN0LiBQYXRoIGxvb2sgbGlrZSAncGF0aC50by5vYmplY3Qua2V5JyBvciAncGF0aCcgaWYgcm9vdFxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oYW55KTogYW55fSB2YWx1ZSAtIGNvbnZlcnRpbmcgZnVuY3Rpb24gZnJvbSBhbnkgZGF0YSB0byBhbnkgZGF0YSBzdHJ1Y3R1cmVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBkYXRhVHJhbnNmb3JtTWFwPzogTWFwPHN0cmluZywgKGRhdGE6IGFueSkgPT4gYW55PjtcblxuICAgIHByaXZhdGUgZm9ybVZhbHVlQ2hhbmdlZFN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICAgIHByaXZhdGUgcXVlcnlTdHJhdGVneSE6IFF1ZXJ5R2VuZXJhdGlvblN0cmF0ZWd5O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuXG4gICAgICAgIEBJbmplY3QoRk9STV9WQUxVRV9IQU5ETElOR19UT0tFTilcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBmb3JtSGFuZGxpbmdTdHJhdGVneTogVmFsdWVIYW5kbGluZ1N0cmF0ZWd5LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWZhdWx0IEFuZ3VsYXIgRm9ybUdyb3VwRGlyZWN0aXZlIGRlcGVuZGVuY2llc1xuICAgICAgICAgKi9cbiAgICAgICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBASW5qZWN0KE5HX1ZBTElEQVRPUlMpXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3ZhbGlkYXRvcnM6IEFycmF5PChWYWxpZGF0b3IgfCBWYWxpZGF0b3JGbik+LFxuICAgICAgICBAT3B0aW9uYWwoKSBAU2VsZigpIEBJbmplY3QoTkdfQVNZTkNfVkFMSURBVE9SUylcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfYXN5bmNWYWxpZGF0b3JzOiBBcnJheTwoQXN5bmNWYWxpZGF0b3IgfCBBc3luY1ZhbGlkYXRvckZuKT4sXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKF92YWxpZGF0b3JzLCBfYXN5bmNWYWxpZGF0b3JzKTtcbiAgICB9XG5cbiAgICAvLyAjcmVnaW9uIExpZmVjeWNsZSBtZXRob2RzXG5cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnF1ZXJ5U3RyYXRlZ3kgPSB0aGlzLmNyZWF0ZVF1ZXJ5R2VuZXJhdGlvblN0cmF0ZWd5KCk7XG5cbiAgICAgICAgdGhpcy5maWxsRm9ybUZyb21RdWVyeSgpO1xuXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlVG9Gb3JtVmFsdWVDaGFuZ2VzKCk7XG5cbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvdmVycmlkZSBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcblxuICAgICAgICB0aGlzLmZvcm1WYWx1ZUNoYW5nZWRTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgdGhpcy5jbGVhckZvcm1RdWVyeSgpO1xuICAgIH1cblxuICAgIC8vICNlbmRyZWdpb25cblxuICAgIHByaXZhdGUgZ2V0VXBkYXRlZE9iamVjdEJ5UGF0aChvYmplY3Q6IFJlY29yZDxzdHJpbmcsIGFueT4sIHBhdGg6IHN0cmluZywgcGFyc2VyOiAoZGF0YTogdW5rbm93bikgPT4gdW5rbm93bik6IG9iamVjdCB7XG4gICAgICAgIGNvbnN0IGRlY29tcG9zZWRQYXRoID0gcGF0aC5zcGxpdCgnLicpO1xuICAgICAgICBjb25zdCBiYXNlID0gZGVjb21wb3NlZFBhdGhbMF07XG4gICAgICAgIGxldCB0ZW1wXG5cbiAgICAgICAgaWYgKGJhc2UgPT09IHVuZGVmaW5lZCB8fCAhb2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5vYmplY3QgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRlbXAgPSBkZWNvbXBvc2VkUGF0aC5sZW5ndGggPD0gMSA/IHBhcnNlcihvYmplY3RbYmFzZV0pIDogdGhpcy5nZXRVcGRhdGVkT2JqZWN0QnlQYXRoKG9iamVjdFtiYXNlXSwgZGVjb21wb3NlZFBhdGguc2xpY2UoMSkuam9pbignLicpLCBwYXJzZXIpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5vYmplY3QsXG4gICAgICAgICAgICBbYmFzZV06IHRlbXAsXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGZpbGxGb3JtRnJvbVF1ZXJ5KCkge1xuICAgICAgICBjb25zdCBjdXJyZW50UXVlcnlQYXJhbXMgPSB0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zO1xuICAgICAgICBjb25zdCBpbmZlcnJlZEZvcm1WYWx1ZSA9IHRoaXMucXVlcnlTdHJhdGVneS5pbmZlckZvcm1WYWx1ZUZyb21RdWVyeShjdXJyZW50UXVlcnlQYXJhbXMsIHRoaXMuZm9ybS52YWx1ZSk7XG4gICAgICAgIGxldCB1cGRhdGVkT2JqZWN0ID0gaW5mZXJyZWRGb3JtVmFsdWU7XG4gICAgICAgIHRoaXMuZGF0YVRyYW5zZm9ybU1hcD8uZm9yRWFjaCgocGFyc2VyLCBwYXRoKSA9PiB7XG4gICAgICAgICAgICB1cGRhdGVkT2JqZWN0ID0gdGhpcy5nZXRVcGRhdGVkT2JqZWN0QnlQYXRoKHVwZGF0ZWRPYmplY3QsIHBhdGgsIHBhcnNlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh1cGRhdGVkT2JqZWN0KTtcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVUb0Zvcm1WYWx1ZUNoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVF1ZXJ5R2VuZXJhdGlvblN0cmF0ZWd5KCkge1xuICAgICAgICBjb25zdCBzdHJhdGVnaWVzID0ge1xuICAgICAgICAgICAgJ3VuaXRlZCc6IG5ldyBVbml0ZWRRdWVyeUdlbmVyYXRpb25TdHJhdGVneSh0aGlzLmZvcm1IYW5kbGluZ1N0cmF0ZWd5LCB0aGlzLnF1ZXJ5S2V5KSxcbiAgICAgICAgICAgICdzZXBhcmF0ZWQnOiBuZXcgU2VwYXJhdGVkUXVlcnlHZW5lcmF0aW9uU3RyYXRlZ3kodGhpcy5mb3JtSGFuZGxpbmdTdHJhdGVneSksXG4gICAgICAgICAgICAnY29tcGxleCc6IG5ldyBTZXBhcmF0ZWRDb21wbGV4UXVlcnlHZW5lcmF0aW9uU3RyYXRlZ3kodGhpcy51c2VEYXRlVGltZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzdHJhdGVnaWVzW3RoaXMuc3RyYXRlZ3ldO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3Vic2NyaWJlVG9Gb3JtVmFsdWVDaGFuZ2VzKCkge1xuICAgICAgICB0aGlzLmZvcm1WYWx1ZUNoYW5nZWRTdWJzY3JpcHRpb24gPSB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnBpcGUoXG4gICAgICAgICAgICBzdGFydFdpdGgodGhpcy5mb3JtLnZhbHVlKSxcbiAgICAgICAgICAgIGRlYm91bmNlVGltZSh0aGlzLmRlYm91bmNlVGltZSksXG4gICAgICAgICAgICBtYXAoKHZhbHVlLCBpbmRleCkgPT4gW3ZhbHVlLCBpbmRleF0gYXMgY29uc3QpLFxuICAgICAgICApLnN1YnNjcmliZSgoW3ZhbHVlLCBpbmRleF0pID0+IHtcbiAgICAgICAgICAgIHZvaWQgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW10sIHtcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczogdGhpcy5xdWVyeVN0cmF0ZWd5LmNvbnZlcnRGb3JtVmFsdWVUb1F1ZXJ5T2JqZWN0KHZhbHVlKSxcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtc0hhbmRsaW5nOiAnbWVyZ2UnLFxuICAgICAgICAgICAgICAgIHJlcGxhY2VVcmw6IGluZGV4ID09PSAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2xlYXJGb3JtUXVlcnkoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdm9pZCB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXSwge1xuICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW1zOiB0aGlzLnF1ZXJ5U3RyYXRlZ3kuY3JlYXRlQ2xlYXJpbmdPYmplY3QodGhpcy5mb3JtLnZhbHVlKSxcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtc0hhbmRsaW5nOiAnbWVyZ2UnLFxuICAgICAgICAgICAgICAgIHJlcGxhY2VVcmw6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgMCk7XG4gICAgfVxuXG59XG4iXX0=