@ng-dynamic-forms/core
Version:
A rapid form development library for Angular
247 lines • 43.3 kB
JavaScript
import { Directive } from "@angular/core";
import { DynamicFormControlEventType, isDynamicFormControlEvent } from "./dynamic-form-control-event";
import { DynamicFormValueControlModel } from "../model/dynamic-form-value-control.model";
import { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormArrayGroupModel } from "../model/form-array/dynamic-form-array.model";
import { DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX } from "../model/checkbox/dynamic-checkbox.model";
import { DYNAMIC_FORM_CONTROL_INPUT_TYPE_FILE, DYNAMIC_FORM_CONTROL_TYPE_INPUT } from "../model/input/dynamic-input.model";
import { isString } from "../utils/core.utils";
import { DynamicFormGroupComponent } from "./dynamic-form-group.component";
import { DynamicFormArrayComponent } from "./dynamic-form-array.component";
import { bufferCount, filter, map } from "rxjs/operators";
import * as i0 from "@angular/core";
import * as i1 from "../service/dynamic-form-layout.service";
import * as i2 from "../service/dynamic-form-validation.service";
import * as i3 from "../service/dynamic-form-component.service";
import * as i4 from "../service/dynamic-form-relation.service";
// tslint:disable-next-line:directive-class-suffix
export class DynamicFormControlContainerComponent {
constructor(changeDetectorRef, componentFactoryResolver, layoutService, validationService, componentService, relationService) {
this.changeDetectorRef = changeDetectorRef;
this.componentFactoryResolver = componentFactoryResolver;
this.layoutService = layoutService;
this.validationService = validationService;
this.componentService = componentService;
this.relationService = relationService;
this._hasFocus = false;
this.context = null;
this.componentSubscriptions = [];
this.subscriptions = [];
}
ngOnChanges(changes) {
const groupChange = changes.group;
const layoutChange = changes.layout;
const modelChange = changes.model;
if (layoutChange || modelChange) {
this.onLayoutOrModelChange();
}
if (modelChange) {
this.onModelChange();
}
if (groupChange || modelChange) {
this.onGroupOrModelChange();
}
}
ngOnInit() {
this.subscriptions.push(this.control.statusChanges.pipe(bufferCount(2, 1), map(states => states[0]), filter(previousState => previousState === "PENDING")).subscribe(_status => this.markForCheck()));
}
ngOnDestroy() {
this.destroyFormControlComponent();
this.unsubscribe();
}
get id() {
return this.layoutService.getElementId(this.model);
}
get hasFocus() {
return this._hasFocus;
}
get isInvalid() {
return this.control.invalid;
}
get isValid() {
return this.control.valid;
}
get errorMessages() {
return this.validationService.createErrorMessages(this.control, this.model);
}
get showErrorMessages() {
return this.validationService.showErrorMessages(this.control, this.model, this.hasFocus);
}
get hasLabel() {
return isString(this.model.label);
}
get hasHint() {
return isString(this.model.hint);
}
get hint() {
return this.model.hint ?? null;
}
get isCheckbox() {
return this.model.type === DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX;
}
get templates() {
return this.inputTemplateList !== undefined ? this.inputTemplateList : this.contentTemplateList;
}
get startTemplate() {
return this.model.type !== DYNAMIC_FORM_CONTROL_TYPE_ARRAY ?
this.layoutService.getStartTemplate(this.model, this.templates) : undefined;
}
get endTemplate() {
return this.model.type !== DYNAMIC_FORM_CONTROL_TYPE_ARRAY ?
this.layoutService.getEndTemplate(this.model, this.templates) : undefined;
}
getClass(context, place) {
return this.layoutService.getClass(this.controlLayout, context, place);
}
markForCheck() {
this.changeDetectorRef.markForCheck();
const component = this.componentRef && this.componentRef.instance;
if (component && (component instanceof DynamicFormGroupComponent || component instanceof DynamicFormArrayComponent)) {
component.markForCheck();
}
}
createFormControlComponent() {
const componentType = this.componentType;
if (componentType !== null) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
this.componentViewContainerRef.clear();
this.componentRef = this.componentViewContainerRef.createComponent(componentFactory);
const component = this.componentRef.instance;
component.formLayout = this.layout;
component.group = this.group;
component.layout = this.controlLayout;
component.model = this.model;
if (this.templates) {
component.templates = this.templates;
}
this.componentSubscriptions.push(component.blur.subscribe(($event) => this.onBlur($event)));
this.componentSubscriptions.push(component.change.subscribe(($event) => this.onChange($event)));
this.componentSubscriptions.push(component.focus.subscribe(($event) => this.onFocus($event)));
if (component.customEvent !== undefined) {
this.componentSubscriptions.push(component.customEvent.subscribe(($event) => this.onCustomEvent($event)));
}
this.registerFormControlComponentRef(this.componentRef);
}
}
destroyFormControlComponent() {
if (this.componentRef) {
this.componentSubscriptions.forEach(subscription => subscription.unsubscribe());
this.componentSubscriptions = [];
this.unregisterFormControlComponentRef();
this.componentRef.destroy();
}
}
createDynamicFormControlEvent($event, type) {
return { $event, context: this.context, control: this.control, group: this.group, model: this.model, type };
}
unsubscribe() {
// this.componentSubscriptions.forEach(subscription => subscription.unsubscribe());
// this.componentSubscriptions = [];
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
}
onControlValueChanges(value) {
if (this.model instanceof DynamicFormValueControlModel && this.model.value !== value) {
this.model.value = value;
}
}
onModelValueUpdates(value) {
if (this.control.value !== value) {
this.control.setValue(value);
}
}
onModelDisabledUpdates(disabled) {
disabled ? this.control.disable() : this.control.enable();
}
onLayoutOrModelChange() {
this.controlLayout = this.layoutService.findByModel(this.model, this.layout) ?? this.model.layout;
this.klass = `${Array.isArray(this.hostClass) ? this.hostClass.join(" ") : ""} ${this.layoutService.getHostClass(this.controlLayout)}`;
}
onModelChange() {
this.destroyFormControlComponent();
this.createFormControlComponent();
}
onGroupOrModelChange() {
if (this.model) {
this.unsubscribe();
if (this.group) {
this.control = this.group.get(this.model.id);
this.subscriptions.push(this.control.valueChanges.subscribe(value => this.onControlValueChanges(value)));
}
this.subscriptions.push(this.model.disabledChanges.subscribe(value => this.onModelDisabledUpdates(value)));
if (this.model instanceof DynamicFormValueControlModel) {
const model = this.model;
this.subscriptions.push(model.valueChanges.subscribe(value => this.onModelValueUpdates(value)));
}
if (this.model.relations.length > 0) {
this.subscriptions.push(...this.relationService.subscribeRelations(this.model, this.group, this.control));
}
}
}
onChange($event) {
if ($event instanceof Event) { // native HTML5 change event
if (this.model.type === DYNAMIC_FORM_CONTROL_TYPE_INPUT) {
const model = this.model;
if (model.inputType === DYNAMIC_FORM_CONTROL_INPUT_TYPE_FILE) {
const inputElement = $event.target;
model.files = inputElement.files;
}
}
this.change.emit(this.createDynamicFormControlEvent($event, DynamicFormControlEventType.Change));
}
else if (isDynamicFormControlEvent($event)) { // event bypass
this.change.emit($event);
}
else { // custom library value change event
this.change.emit(this.createDynamicFormControlEvent($event, DynamicFormControlEventType.Change));
}
}
onBlur($event) {
if (isDynamicFormControlEvent($event)) { // event bypass
this.blur.emit($event);
}
else { // native HTML 5 or UI library blur event
this._hasFocus = false;
this.blur.emit(this.createDynamicFormControlEvent($event, DynamicFormControlEventType.Blur));
}
}
onFocus($event) {
if (isDynamicFormControlEvent($event)) { // event bypass
this.focus.emit($event);
}
else { // native HTML 5 or UI library focus event
this._hasFocus = true;
this.focus.emit(this.createDynamicFormControlEvent($event, DynamicFormControlEventType.Focus));
}
}
onCustomEvent($event) {
const emitter = this.customEvent;
if (isDynamicFormControlEvent($event)) { // child event bypass
emitter.emit($event);
}
else { // native UI library custom event
emitter.emit(this.createDynamicFormControlEvent($event.customEvent, $event.customEventType));
}
}
registerFormControlComponentRef(ref) {
if (this.context instanceof DynamicFormArrayGroupModel) {
this.componentService.registerFormControl(this.model, ref, this.context.index);
}
else {
this.componentService.registerFormControl(this.model, ref);
}
}
unregisterFormControlComponentRef() {
if (this.context instanceof DynamicFormArrayGroupModel) {
this.componentService.unregisterFormControl(this.model.id, this.context.index);
}
else {
this.componentService.unregisterFormControl(this.model.id);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.3", ngImport: i0, type: DynamicFormControlContainerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ComponentFactoryResolver }, { token: i1.DynamicFormLayoutService }, { token: i2.DynamicFormValidationService }, { token: i3.DynamicFormComponentService }, { token: i4.DynamicFormRelationService }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.3", type: DynamicFormControlContainerComponent, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.3", ngImport: i0, type: DynamicFormControlContainerComponent, decorators: [{
type: Directive
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ComponentFactoryResolver }, { type: i1.DynamicFormLayoutService }, { type: i2.DynamicFormValidationService }, { type: i3.DynamicFormComponentService }, { type: i4.DynamicFormRelationService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1mb3JtLWNvbnRyb2wtY29udGFpbmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWR5bmFtaWMtZm9ybXMvY29yZS9zcmMvbGliL2NvbXBvbmVudC9keW5hbWljLWZvcm0tY29udHJvbC1jb250YWluZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHVyxTQUFTLEVBUzFCLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFHSCwyQkFBMkIsRUFDM0IseUJBQXlCLEVBQzVCLE1BQU0sOEJBQThCLENBQUM7QUFFdEMsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDekYsT0FBTyxFQUNILCtCQUErQixFQUMvQiwwQkFBMEIsRUFDN0IsTUFBTSw4Q0FBOEMsQ0FBQztBQUN0RCxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM5RixPQUFPLEVBQ0gsb0NBQW9DLEVBQ3BDLCtCQUErQixFQUVsQyxNQUFNLG9DQUFvQyxDQUFDO0FBVzVDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBRzFELGtEQUFrRDtBQUNsRCxNQUFNLE9BQWdCLG9DQUFvQztJQTBCdEQsWUFBZ0MsaUJBQW9DLEVBQ3BDLHdCQUFrRCxFQUNsRCxhQUF1QyxFQUN2QyxpQkFBK0MsRUFDL0MsZ0JBQTZDLEVBQzdDLGVBQTJDO1FBTDNDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsNkJB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LG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7U0FFbEY7YUFBTTtZQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzlEO0lBQ0wsQ0FBQztJQUVPLGlDQUFpQztRQUNyQyxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksMEJBQTBCLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7U0FFbEY7YUFBTTtZQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzlEO0lBQ0wsQ0FBQzs4R0FwVGlCLG9DQUFvQztrR0FBcEMsb0NBQW9DOzsyRkFBcEMsb0NBQW9DO2tCQUZ6RCxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgQ29tcG9uZW50UmVmLCBEaXJlY3RpdmUsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIFF1ZXJ5TGlzdCxcbiAgICBTaW1wbGVDaGFuZ2VzLFxuICAgIFR5cGUsXG4gICAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1Db250cm9sLCBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHtcbiAgICBEeW5hbWljRm9ybUNvbnRyb2xDdXN0b21FdmVudCxcbiAgICBEeW5hbWljRm9ybUNvbnRyb2xFdmVudCxcbiAgICBEeW5hbWljRm9ybUNvbnRyb2xFdmVudFR5cGUsXG4gICAgaXNEeW5hbWljRm9ybUNvbnRyb2xFdmVudFxufSBmcm9tIFwiLi9keW5hbWljLWZvcm0tY29udHJvbC1ldmVudFwiO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1Db250cm9sTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvZHluYW1pYy1mb3JtLWNvbnRyb2wubW9kZWxcIjtcbmltcG9ydCB7IER5bmFtaWNGb3JtVmFsdWVDb250cm9sTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvZHluYW1pYy1mb3JtLXZhbHVlLWNvbnRyb2wubW9kZWxcIjtcbmltcG9ydCB7XG4gICAgRFlOQU1JQ19GT1JNX0NPTlRST0xfVFlQRV9BUlJBWSxcbiAgICBEeW5hbWljRm9ybUFycmF5R3JvdXBNb2RlbFxufSBmcm9tIFwiLi4vbW9kZWwvZm9ybS1hcnJheS9keW5hbWljLWZvcm0tYXJyYXkubW9kZWxcIjtcbmltcG9ydCB7IERZTkFNSUNfRk9STV9DT05UUk9MX1RZUEVfQ0hFQ0tCT1ggfSBmcm9tIFwiLi4vbW9kZWwvY2hlY2tib3gvZHluYW1pYy1jaGVja2JveC5tb2RlbFwiO1xuaW1wb3J0IHtcbiAgICBEWU5BTUlDX0ZPUk1fQ09OVFJPTF9JTlBVVF9UWVBFX0ZJTEUsXG4gICAgRFlOQU1JQ19GT1JNX0NPTlRST0xfVFlQRV9JTlBVVCxcbiAgICBEeW5hbWljSW5wdXRNb2RlbFxufSBmcm9tIFwiLi4vbW9kZWwvaW5wdXQvZHluYW1pYy1pbnB1dC5tb2RlbFwiO1xuaW1wb3J0IHtcbiAgICBEeW5hbWljRm9ybUNvbnRyb2xMYXlvdXQsXG4gICAgRHluYW1pY0Zvcm1Db250cm9sTGF5b3V0Q29udGV4dCxcbiAgICBEeW5hbWljRm9ybUNvbnRyb2xMYXlvdXRQbGFjZVxufSBmcm9tIFwiLi4vbW9kZWwvbWlzYy9keW5hbWljLWZvcm0tY29udHJvbC1sYXlvdXQubW9kZWxcIjtcbmltcG9ydCB7IER5bmFtaWNGb3JtQ29udHJvbCB9IGZyb20gXCIuL2R5bmFtaWMtZm9ybS1jb250cm9sLWludGVyZmFjZVwiO1xuaW1wb3J0IHsgRHluYW1pY1RlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSBcIi4uL2RpcmVjdGl2ZS9keW5hbWljLXRlbXBsYXRlLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1MYXlvdXQsIER5bmFtaWNGb3JtTGF5b3V0U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL2R5bmFtaWMtZm9ybS1sYXlvdXQuc2VydmljZVwiO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1WYWxpZGF0aW9uU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL2R5bmFtaWMtZm9ybS12YWxpZGF0aW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IER5bmFtaWNGb3JtQ29tcG9uZW50U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL2R5bmFtaWMtZm9ybS1jb21wb25lbnQuc2VydmljZVwiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbHMvY29yZS51dGlsc1wiO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1SZWxhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZS9keW5hbWljLWZvcm0tcmVsYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1Hcm91cENvbXBvbmVudCB9IGZyb20gXCIuL2R5bmFtaWMtZm9ybS1ncm91cC5jb21wb25lbnRcIjtcbmltcG9ydCB7IER5bmFtaWNGb3JtQXJyYXlDb21wb25lbnQgfSBmcm9tIFwiLi9keW5hbWljLWZvcm0tYXJyYXkuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBidWZmZXJDb3VudCwgZmlsdGVyLCBtYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcblxuQERpcmVjdGl2ZSgpXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGlyZWN0aXZlLWNsYXNzLXN1ZmZpeFxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIER5bmFtaWNGb3JtQ29udHJvbENvbnRhaW5lckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAgIHByaXZhdGUgX2hhc0ZvY3VzID0gZmFsc2U7XG5cbiAgICBjb250ZXh0OiBEeW5hbWljRm9ybUFycmF5R3JvdXBNb2RlbCB8IG51bGwgPSBudWxsO1xuICAgIGNvbnRyb2whOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gICAgZ3JvdXAhOiBVbnR5cGVkRm9ybUdyb3VwO1xuICAgIGhvc3RDbGFzcz86IHN0cmluZ1tdO1xuICAgIGtsYXNzPzogc3RyaW5nO1xuICAgIGxheW91dD86IER5bmFtaWNGb3JtTGF5b3V0O1xuICAgIG1vZGVsITogRHluYW1pY0Zvcm1Db250cm9sTW9kZWw7XG5cbiAgICBjb250ZW50VGVtcGxhdGVMaXN0PzogUXVlcnlMaXN0PER5bmFtaWNUZW1wbGF0ZURpcmVjdGl2ZT47XG4gICAgaW5wdXRUZW1wbGF0ZUxpc3Q/OiBRdWVyeUxpc3Q8RHluYW1pY1RlbXBsYXRlRGlyZWN0aXZlPjtcblxuICAgIGJsdXIhOiBFdmVudEVtaXR0ZXI8RHluYW1pY0Zvcm1Db250cm9sRXZlbnQ+O1xuICAgIGNoYW5nZSE6IEV2ZW50RW1pdHRlcjxEeW5hbWljRm9ybUNvbnRyb2xFdmVudD47XG4gICAgY3VzdG9tRXZlbnQ/OiBFdmVudEVtaXR0ZXI8RHluYW1pY0Zvcm1Db250cm9sRXZlbnQ+O1xuICAgIGZvY3VzITogRXZlbnRFbWl0dGVyPER5bmFtaWNGb3JtQ29udHJvbEV2ZW50PjtcblxuICAgIGNvbXBvbmVudFZpZXdDb250YWluZXJSZWYhOiBWaWV3Q29udGFpbmVyUmVmO1xuXG4gICAgcHJvdGVjdGVkIGNvbXBvbmVudFJlZiE6IENvbXBvbmVudFJlZjxEeW5hbWljRm9ybUNvbnRyb2w+O1xuICAgIHByb3RlY3RlZCBjb21wb25lbnRTdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuICAgIHByb3RlY3RlZCBjb250cm9sTGF5b3V0PzogRHluYW1pY0Zvcm1Db250cm9sTGF5b3V0O1xuICAgIHByb3RlY3RlZCBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIGxheW91dFNlcnZpY2U6IER5bmFtaWNGb3JtTGF5b3V0U2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZhbGlkYXRpb25TZXJ2aWNlOiBEeW5hbWljRm9ybVZhbGlkYXRpb25TZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgY29tcG9uZW50U2VydmljZTogRHluYW1pY0Zvcm1Db21wb25lbnRTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgcmVsYXRpb25TZXJ2aWNlOiBEeW5hbWljRm9ybVJlbGF0aW9uU2VydmljZSkge1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZ3JvdXBDaGFuZ2UgPSAoY2hhbmdlcyBhcyBQaWNrPFNpbXBsZUNoYW5nZXMsIFwiZ3JvdXBcIj4pLmdyb3VwO1xuICAgICAgICBjb25zdCBsYXlvdXRDaGFuZ2UgPSAoY2hhbmdlcyBhcyBQaWNrPFNpbXBsZUNoYW5nZXMsIFwibGF5b3V0XCI+KS5sYXlvdXQ7XG4gICAgICAgIGNvbnN0IG1vZGVsQ2hhbmdlID0gKGNoYW5nZXMgYXMgUGljazxTaW1wbGVDaGFuZ2VzLCBcIm1vZGVsXCI+KS5tb2RlbDtcblxuICAgICAgICBpZiAobGF5b3V0Q2hhbmdlIHx8IG1vZGVsQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLm9uTGF5b3V0T3JNb2RlbENoYW5nZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1vZGVsQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLm9uTW9kZWxDaGFuZ2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChncm91cENoYW5nZSB8fCBtb2RlbENoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5vbkdyb3VwT3JNb2RlbENoYW5nZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKHRoaXMuY29udHJvbC5zdGF0dXNDaGFuZ2VzLnBpcGUoXG4gICAgICAgICAgICBidWZmZXJDb3VudCgyLCAxKSxcbiAgICAgICAgICAgIG1hcChzdGF0ZXMgPT4gc3RhdGVzWzBdKSxcbiAgICAgICAgICAgIGZpbHRlcihwcmV2aW91c1N0YXRlID0+IHByZXZpb3VzU3RhdGUgPT09IFwiUEVORElOR1wiKVxuICAgICAgICApLnN1YnNjcmliZShfc3RhdHVzID0+IHRoaXMubWFya0ZvckNoZWNrKCkpKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kZXN0cm95Rm9ybUNvbnRyb2xDb21wb25lbnQoKTtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIGFic3RyYWN0IGdldCBjb21wb25lbnRUeXBlKCk6IFR5cGU8RHluYW1pY0Zvcm1Db250cm9sPiB8IG51bGw7XG5cbiAgICBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0U2VydmljZS5nZXRFbGVtZW50SWQodGhpcy5tb2RlbCk7XG4gICAgfVxuXG4gICAgZ2V0IGhhc0ZvY3VzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFzRm9jdXM7XG4gICAgfVxuXG4gICAgZ2V0IGlzSW52YWxpZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJvbC5pbnZhbGlkO1xuICAgIH1cblxuICAgIGdldCBpc1ZhbGlkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250cm9sLnZhbGlkO1xuICAgIH1cblxuICAgIGdldCBlcnJvck1lc3NhZ2VzKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGlvblNlcnZpY2UuY3JlYXRlRXJyb3JNZXNzYWdlcyh0aGlzLmNvbnRyb2wsIHRoaXMubW9kZWwpO1xuICAgIH1cblxuICAgIGdldCBzaG93RXJyb3JNZXNzYWdlcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGlvblNlcnZpY2Uuc2hvd0Vycm9yTWVzc2FnZXModGhpcy5jb250cm9sLCB0aGlzLm1vZGVsLCB0aGlzLmhhc0ZvY3VzKTtcbiAgICB9XG5cbiAgICBnZXQgaGFzTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBpc1N0cmluZyh0aGlzLm1vZGVsLmxhYmVsKTtcbiAgICB9XG5cbiAgICBnZXQgaGFzSGludCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKCh0aGlzLm1vZGVsIGFzIER5bmFtaWNGb3JtVmFsdWVDb250cm9sTW9kZWw8YW55PikuaGludCk7XG4gICAgfVxuXG4gICAgZ2V0IGhpbnQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiAodGhpcy5tb2RlbCBhcyBEeW5hbWljRm9ybVZhbHVlQ29udHJvbE1vZGVsPGFueT4pLmhpbnQgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgaXNDaGVja2JveCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudHlwZSA9PT0gRFlOQU1JQ19GT1JNX0NPTlRST0xfVFlQRV9DSEVDS0JPWDtcbiAgICB9XG5cbiAgICBnZXQgdGVtcGxhdGVzKCk6IFF1ZXJ5TGlzdDxEeW5hbWljVGVtcGxhdGVEaXJlY3RpdmU+IHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXRUZW1wbGF0ZUxpc3QgIT09IHVuZGVmaW5lZCA/IHRoaXMuaW5wdXRUZW1wbGF0ZUxpc3QgOiB0aGlzLmNvbnRlbnRUZW1wbGF0ZUxpc3Q7XG4gICAgfVxuXG4gICAgZ2V0IHN0YXJ0VGVtcGxhdGUoKTogRHluYW1pY1RlbXBsYXRlRGlyZWN0aXZlIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudHlwZSAhPT0gRFlOQU1JQ19GT1JNX0NPTlRST0xfVFlQRV9BUlJBWSA/XG4gICAgICAgICAgICB0aGlzLmxheW91dFNlcnZpY2UuZ2V0U3RhcnRUZW1wbGF0ZSh0aGlzLm1vZGVsLCB0aGlzLnRlbXBsYXRlcykgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZ2V0IGVuZFRlbXBsYXRlKCk6IER5bmFtaWNUZW1wbGF0ZURpcmVjdGl2ZSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnR5cGUgIT09IERZTkFNSUNfRk9STV9DT05UUk9MX1RZUEVfQVJSQVkgP1xuICAgICAgICAgICAgdGhpcy5sYXlvdXRTZXJ2aWNlLmdldEVuZFRlbXBsYXRlKHRoaXMubW9kZWwsIHRoaXMudGVtcGxhdGVzKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBnZXRDbGFzcyhjb250ZXh0OiBEeW5hbWljRm9ybUNvbnRyb2xMYXlvdXRDb250ZXh0LCBwbGFjZTogRHluYW1pY0Zvcm1Db250cm9sTGF5b3V0UGxhY2UpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5sYXlvdXRTZXJ2aWNlLmdldENsYXNzKHRoaXMuY29udHJvbExheW91dCwgY29udGV4dCwgcGxhY2UpO1xuICAgIH1cblxuICAgIG1hcmtGb3JDaGVjaygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudFJlZiAmJiB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZTtcblxuICAgICAgICBpZiAoY29tcG9uZW50ICYmIChjb21wb25lbnQgaW5zdGFuY2VvZiBEeW5hbWljRm9ybUdyb3VwQ29tcG9uZW50IHx8IGNvbXBvbmVudCBpbnN0YW5jZW9mIER5bmFtaWNGb3JtQXJyYXlDb21wb25lbnQpKSB7XG4gICAgICAgICAgICBjb21wb25lbnQubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY3JlYXRlRm9ybUNvbnRyb2xDb21wb25lbnQoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudFR5cGUgPSB0aGlzLmNvbXBvbmVudFR5cGU7XG5cbiAgICAgICAgaWYgKGNvbXBvbmVudFR5cGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcnkgPSB0aGlzLmNvbXBvbmVudEZhY3RvcnlSZXNvbHZlci5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShjb21wb25lbnRUeXBlKTtcblxuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRWaWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMuY29tcG9uZW50Vmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoY29tcG9uZW50RmFjdG9yeSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlO1xuXG4gICAgICAgICAgICBjb21wb25lbnQuZm9ybUxheW91dCA9IHRoaXMubGF5b3V0O1xuICAgICAgICAgICAgY29tcG9uZW50Lmdyb3VwID0gdGhpcy5ncm91cDtcbiAgICAgICAgICAgIGNvbXBvbmVudC5sYXlvdXQgPSB0aGlzLmNvbnRyb2xMYXlvdXQ7XG4gICAgICAgICAgICBjb21wb25lbnQubW9kZWwgPSB0aGlzLm1vZGVsO1xuXG4gICAgICAgICAgICBpZiAodGhpcy50ZW1wbGF0ZXMpIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnQudGVtcGxhdGVzID0gdGhpcy50ZW1wbGF0ZXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50U3Vic2NyaXB0aW9ucy5wdXNoKGNvbXBvbmVudC5ibHVyLnN1YnNjcmliZSgoJGV2ZW50OiBhbnkpID0+IHRoaXMub25CbHVyKCRldmVudCkpKTtcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50U3Vic2NyaXB0aW9ucy5wdXNoKGNvbXBvbmVudC5jaGFuZ2Uuc3Vic2NyaWJlKCgkZXZlbnQ6IGFueSkgPT4gdGhpcy5vbkNoYW5nZSgkZXZlbnQpKSk7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFN1YnNjcmlwdGlvbnMucHVzaChjb21wb25lbnQuZm9jdXMuc3Vic2NyaWJlKCgkZXZlbnQ6IGFueSkgPT4gdGhpcy5vbkZvY3VzKCRldmVudCkpKTtcblxuICAgICAgICAgICAgaWYgKGNvbXBvbmVudC5jdXN0b21FdmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21wb25lbnRTdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudC5jdXN0b21FdmVudC5zdWJzY3JpYmUoKCRldmVudDogYW55KSA9PiB0aGlzLm9uQ3VzdG9tRXZlbnQoJGV2ZW50KSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyRm9ybUNvbnRyb2xDb21wb25lbnRSZWYodGhpcy5jb21wb25lbnRSZWYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGRlc3Ryb3lGb3JtQ29udHJvbENvbXBvbmVudCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVmKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWJzY3JpcHRpb24gPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRTdWJzY3JpcHRpb25zID0gW107XG5cbiAgICAgICAgICAgIHRoaXMudW5yZWdpc3RlckZvcm1Db250cm9sQ29tcG9uZW50UmVmKCk7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY3JlYXRlRHluYW1pY0Zvcm1Db250cm9sRXZlbnQoJGV2ZW50OiBhbnksIHR5cGU6IHN0cmluZyk6IER5bmFtaWNGb3JtQ29udHJvbEV2ZW50IHtcbiAgICAgICAgcmV0dXJuIHskZXZlbnQsIGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY29udHJvbDogdGhpcy5jb250cm9sLCBncm91cDogdGhpcy5ncm91cCwgbW9kZWw6IHRoaXMubW9kZWwsIHR5cGV9O1xuICAgIH1cblxuICAgIHVuc3Vic2NyaWJlKCk6IHZvaWQge1xuICAgICAgICAvLyB0aGlzLmNvbXBvbmVudFN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWJzY3JpcHRpb24gPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICAvLyB0aGlzLmNvbXBvbmVudFN1YnNjcmlwdGlvbnMgPSBbXTtcblxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWJzY3JpcHRpb24gPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBbXTtcbiAgICB9XG5cbiAgICBvbkNvbnRyb2xWYWx1ZUNoYW5nZXModmFsdWU6IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tb2RlbCBpbnN0YW5jZW9mIER5bmFtaWNGb3JtVmFsdWVDb250cm9sTW9kZWwgJiYgdGhpcy5tb2RlbC52YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMubW9kZWwudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW9kZWxWYWx1ZVVwZGF0ZXModmFsdWU6IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jb250cm9sLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5jb250cm9sLnNldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW9kZWxEaXNhYmxlZFVwZGF0ZXMoZGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgZGlzYWJsZWQgPyB0aGlzLmNvbnRyb2wuZGlzYWJsZSgpIDogdGhpcy5jb250cm9sLmVuYWJsZSgpO1xuICAgIH1cblxuICAgIG9uTGF5b3V0T3JNb2RlbENoYW5nZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jb250cm9sTGF5b3V0ID0gdGhpcy5sYXlvdXRTZXJ2aWNlLmZpbmRCeU1vZGVsKHRoaXMubW9kZWwsIHRoaXMubGF5b3V0KSA/PyB0aGlzLm1vZGVsLmxheW91dCBhcyBEeW5hbWljRm9ybUNvbnRyb2xMYXlvdXQ7XG4gICAgICAgIHRoaXMua2xhc3MgPSBgJHtBcnJheS5pc0FycmF5KHRoaXMuaG9zdENsYXNzKSA/IHRoaXMuaG9zdENsYXNzLmpvaW4oXCIgXCIpIDogXCJcIn0gJHt0aGlzLmxheW91dFNlcnZpY2UuZ2V0SG9zdENsYXNzKHRoaXMuY29udHJvbExheW91dCl9YDtcbiAgICB9XG5cbiAgICBvbk1vZGVsQ2hhbmdlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRlc3Ryb3lGb3JtQ29udHJvbENvbXBvbmVudCgpO1xuICAgICAgICB0aGlzLmNyZWF0ZUZvcm1Db250cm9sQ29tcG9uZW50KCk7XG4gICAgfVxuXG4gICAgb25Hcm91cE9yTW9kZWxDaGFuZ2UoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsKSB7XG4gICAgICAgICAgICB0aGlzLnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmdyb3VwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sID0gdGhpcy5ncm91cC5nZXQodGhpcy5tb2RlbC5pZCkgYXMgVW50eXBlZEZvcm1Db250cm9sO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKHRoaXMuY29udHJvbC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKHZhbHVlID0+IHRoaXMub25Db250cm9sVmFsdWVDaGFuZ2VzKHZhbHVlKSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLm1vZGVsLmRpc2FibGVkQ2hhbmdlcy5zdWJzY3JpYmUodmFsdWUgPT4gdGhpcy5vbk1vZGVsRGlzYWJsZWRVcGRhdGVzKHZhbHVlKSkpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbCBpbnN0YW5jZW9mIER5bmFtaWNGb3JtVmFsdWVDb250cm9sTW9kZWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtb2RlbCA9IHRoaXMubW9kZWwgYXMgRHluYW1pY0Zvcm1WYWx1ZUNvbnRyb2xNb2RlbDxhbnk+O1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2gobW9kZWwudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWx1ZSA9PiB0aGlzLm9uTW9kZWxWYWx1ZVVwZGF0ZXModmFsdWUpKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLnJlbGF0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goLi4udGhpcy5yZWxhdGlvblNlcnZpY2Uuc3Vic2NyaWJlUmVsYXRpb25zKHRoaXMubW9kZWwsIHRoaXMuZ3JvdXAsIHRoaXMuY29udHJvbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25DaGFuZ2UoJGV2ZW50OiBFdmVudCB8IER5bmFtaWNGb3JtQ29udHJvbEV2ZW50IHwgYW55KTogdm9pZCB7XG4gICAgICAgIGlmICgkZXZlbnQgaW5zdGFuY2VvZiBFdmVudCkgeyAvLyBuYXRpdmUgSFRNTDUgY2hhbmdlIGV2ZW50XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC50eXBlID09PSBEWU5BTUlDX0ZPUk1fQ09OVFJPTF9UWVBFX0lOUFVUKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsIGFzIER5bmFtaWNJbnB1dE1vZGVsO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1vZGVsLmlucHV0VHlwZSA9PT0gRFlOQU1JQ19GT1JNX0NPTlRST0xfSU5QVVRfVFlQRV9GSUxFKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0RWxlbWVudDogYW55ID0gJGV2ZW50LnRhcmdldDtcblxuICAgICAgICAgICAgICAgICAgICBtb2RlbC5maWxlcyA9IGlucHV0RWxlbWVudC5maWxlcyBhcyBGaWxlTGlzdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQodGhpcy5jcmVhdGVEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQsIER5bmFtaWNGb3JtQ29udHJvbEV2ZW50VHlwZS5DaGFuZ2UpKTtcblxuICAgICAgICB9IGVsc2UgaWYgKGlzRHluYW1pY0Zvcm1Db250cm9sRXZlbnQoJGV2ZW50KSkgeyAvLyBldmVudCBieXBhc3NcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoJGV2ZW50KTtcblxuICAgICAgICB9IGVsc2UgeyAvLyBjdXN0b20gbGlicmFyeSB2YWx1ZSBjaGFuZ2UgZXZlbnRcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQodGhpcy5jcmVhdGVEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQsIER5bmFtaWNGb3JtQ29udHJvbEV2ZW50VHlwZS5DaGFuZ2UpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uQmx1cigkZXZlbnQ6IEZvY3VzRXZlbnQgfCBEeW5hbWljRm9ybUNvbnRyb2xFdmVudCB8IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAoaXNEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQpKSB7IC8vIGV2ZW50IGJ5cGFzc1xuICAgICAgICAgICAgdGhpcy5ibHVyLmVtaXQoJGV2ZW50KTtcblxuICAgICAgICB9IGVsc2UgeyAvLyBuYXRpdmUgSFRNTCA1IG9yIFVJIGxpYnJhcnkgYmx1ciBldmVudFxuICAgICAgICAgICAgdGhpcy5faGFzRm9jdXMgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYmx1ci5lbWl0KHRoaXMuY3JlYXRlRHluYW1pY0Zvcm1Db250cm9sRXZlbnQoJGV2ZW50LCBEeW5hbWljRm9ybUNvbnRyb2xFdmVudFR5cGUuQmx1cikpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Gb2N1cygkZXZlbnQ6IEZvY3VzRXZlbnQgfCBEeW5hbWljRm9ybUNvbnRyb2xFdmVudCB8IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAoaXNEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQpKSB7IC8vIGV2ZW50IGJ5cGFzc1xuICAgICAgICAgICAgdGhpcy5mb2N1cy5lbWl0KCRldmVudCk7XG5cbiAgICAgICAgfSBlbHNlIHsgLy8gbmF0aXZlIEhUTUwgNSBvciBVSSBsaWJyYXJ5IGZvY3VzIGV2ZW50XG4gICAgICAgICAgICB0aGlzLl9oYXNGb2N1cyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmZvY3VzLmVtaXQodGhpcy5jcmVhdGVEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQsIER5bmFtaWNGb3JtQ29udHJvbEV2ZW50VHlwZS5Gb2N1cykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25DdXN0b21FdmVudCgkZXZlbnQ6IER5bmFtaWNGb3JtQ29udHJvbEV2ZW50IHwgRHluYW1pY0Zvcm1Db250cm9sQ3VzdG9tRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IHRoaXMuY3VzdG9tRXZlbnQgYXMgRXZlbnRFbWl0dGVyPER5bmFtaWNGb3JtQ29udHJvbEV2ZW50PjtcblxuICAgICAgICBpZiAoaXNEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQpKSB7IC8vIGNoaWxkIGV2ZW50IGJ5cGFzc1xuICAgICAgICAgICAgZW1pdHRlci5lbWl0KCRldmVudCk7XG5cbiAgICAgICAgfSBlbHNlIHsgLy8gbmF0aXZlIFVJIGxpYnJhcnkgY3VzdG9tIGV2ZW50XG4gICAgICAgICAgICBlbWl0dGVyLmVtaXQodGhpcy5jcmVhdGVEeW5hbWljRm9ybUNvbnRyb2xFdmVudCgkZXZlbnQuY3VzdG9tRXZlbnQsICRldmVudC5jdXN0b21FdmVudFR5cGUpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVnaXN0ZXJGb3JtQ29udHJvbENvbXBvbmVudFJlZihyZWY6IENvbXBvbmVudFJlZjxEeW5hbWljRm9ybUNvbnRyb2w+KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQgaW5zdGFuY2VvZiBEeW5hbWljRm9ybUFycmF5R3JvdXBNb2RlbCkge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRTZXJ2aWNlLnJlZ2lzdGVyRm9ybUNvbnRyb2wodGhpcy5tb2RlbCwgcmVmLCB0aGlzLmNvbnRleHQuaW5kZXgpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFNlcnZpY2UucmVnaXN0ZXJGb3JtQ29udHJvbCh0aGlzLm1vZGVsLCByZWYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bnJlZ2lzdGVyRm9ybUNvbnRyb2xDb21wb25lbnRSZWYoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQgaW5zdGFuY2VvZiBEeW5hbWljRm9ybUFycmF5R3JvdXBNb2RlbCkge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRTZXJ2aWNlLnVucmVnaXN0ZXJGb3JtQ29udHJvbCh0aGlzLm1vZGVsLmlkLCB0aGlzLmNvbnRleHQuaW5kZXgpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFNlcnZpY2UudW5yZWdpc3RlckZvcm1Db250cm9sKHRoaXMubW9kZWwuaWQpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19