mdds-angular-composite
Version:
Augular Composite that compose multiple componennt to be a single page
311 lines • 28.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Directive, Input, Output, ViewContainerRef, ViewChildren, ViewChild, ComponentFactoryResolver, QueryList, EventEmitter, } from '@angular/core';
import { Router } from '@angular/router';
export class CompositeDirective {
/**
* @param {?} viewContainerRef
*/
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
}
CompositeDirective.decorators = [
{ type: Directive, args: [{
selector: '[composite-directive]',
},] }
];
/** @nocollapse */
CompositeDirective.ctorParameters = () => [
{ type: ViewContainerRef }
];
if (false) {
/** @type {?} */
CompositeDirective.prototype.viewContainerRef;
}
export class CompositeSubmitDirective {
/**
* @param {?} viewContainerRef
*/
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
}
CompositeSubmitDirective.decorators = [
{ type: Directive, args: [{
selector: '[composite-submit-directive]',
},] }
];
/** @nocollapse */
CompositeSubmitDirective.ctorParameters = () => [
{ type: ViewContainerRef }
];
if (false) {
/** @type {?} */
CompositeSubmitDirective.prototype.viewContainerRef;
}
export class CompositeComponent {
/**
* @param {?} componentFactoryResolver
* @param {?} router
*/
constructor(componentFactoryResolver, router) {
this.componentFactoryResolver = componentFactoryResolver;
this.router = router;
this.totalSteps = 0;
this.stepCompRef = [];
this.stepCompIns = [];
this.stepCompEmitter = [];
this.errorMessages = [];
this.submitting = false;
this.componentEvents = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
if (!this.steps) {
console.warn("No steps defined for CompositeComponent.");
return;
}
this.totalSteps = this.steps.length;
}
/**
* @return {?}
*/
ngAfterViewInit() {
if (!this.compositeDirectives) {
console.warn("No composite directive for CompositeComponent.");
return;
}
setTimeout((/**
* @return {?}
*/
() => {
this.loadAllSteps();
}), 10);
this.componentEvents.emit({
//telling parent we are ready to load steps
stepIndex: undefined,
message: {
type: 'ngAfterViewInit'
},
});
}
/**
* @param {?} index
* @param {?} stepConfig
* @return {?}
*/
reloadStep(index, stepConfig) {
/** @type {?} */
const directive = this.compositeDirectives.toArray()[index];
const { stepTitle, stepComponent, mandatory, preSelectedId, searchObj, disableActionButtions } = stepConfig;
if (!stepComponent)
return; //stop handling this step.
//stop handling this step.
/** @type {?} */
let viewContainerRef = directive.viewContainerRef;
viewContainerRef.clear();
/** @type {?} */
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(stepComponent);
/** @type {?} */
let componentRef = viewContainerRef.createComponent(componentFactory);
// create and insert in one call
/** @type {?} */
let componentInstance = componentRef.instance;
this.stepCompIns[index] = componentInstance;
componentInstance.inputData = {
stepTitle,
preSelectedId,
mandatory,
};
componentInstance.searchObj = searchObj;
componentInstance.disableActionButtions = disableActionButtions;
if (index === 0) {
componentInstance.setFocus();
}
componentInstance.eventEmitter.subscribe((/**
* @param {?} message
* @return {?}
*/
(message) => {
if (message) {
/** @type {?} */
const msg = {
stepIndex: index,
message,
};
this.componentEvents.emit(msg);
}
}));
}
/**
* @return {?}
*/
loadAllSteps() {
for (let index = 0; index < this.compositeDirectives.length; index++) {
if (this.stepCompIns[index])
continue; //already loaded
if (!this.stepConfigs[index])
continue; //no configuration
this.reloadStep(index, this.stepConfigs[index]);
}
;
}
/**
* @return {?}
*/
allActionsReady() {
/** @type {?} */
let ready = true;
for (let [index, step] of this.stepConfigs.entries()) {
this.errorMessages[index] = false; // no error
if (step.mandatory) {
/** @type {?} */
const instance = this.stepCompIns[index];
if (!instance) {
return false;
}
if (instance.actionType === 'selection') {
/** @type {?} */
let value = instance.getSelectedItems();
if (value.length === 0) {
this.errorMessages[index] = true;
ready = false;
return false;
}
}
else if (instance.actionType === 'term') {
if (!instance.isTermChecked()) {
this.errorMessages[index] = true;
return false;
}
}
}
}
return ready;
}
/**
* @return {?}
*/
onSubmit() {
this.submitting = true;
if (!(this.allActionsReady())) {
return;
}
/** @type {?} */
let viewContainerRef = this.compositeSubmitDirective.viewContainerRef;
viewContainerRef.clear();
if (!this.submitCompRef) {
/** @type {?} */
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.submit.compoment);
this.submitCompRef = viewContainerRef.createComponent(componentFactory); // create and insert in one call
}
/** @type {?} */
let componentInstance = this.submitCompRef.instance;
/** @type {?} */
const initData = {};
for (let [index, step] of this.stepConfigs.entries()) {
/** @type {?} */
const instance = this.stepCompIns[index];
/** @type {?} */
let value;
if (instance.actionType === 'selection') {
value = instance.getSelectedItems();
if (value.length === 0) {
value = undefined;
}
else if (!componentInstance.arrayFields.some((/**
* @param {?} x
* @return {?}
*/
x => x[0] === step.submitFieldName))) { //check if the target fields is an array fields. in ['fieldName', 'Field type'] format
value = value[0]; //only get one object
}
}
else if (instance.actionType === 'term') {
value = instance.isTermChecked();
}
initData[step.submitFieldName] = value;
}
componentInstance.id = undefined;
componentInstance.embeddedView = true;
componentInstance.initData = initData;
componentInstance.ngOnInit();
componentInstance.onSubmit();
componentInstance.done.subscribe((/**
* @param {?} value
* @return {?}
*/
(value) => {
if (value) {
this.router.navigateByUrl(this.submit.succeedUrl);
}
}));
}
/**
* @return {?}
*/
onCancel() {
this.router.navigateByUrl(this.submit.cancelUrl);
}
}
CompositeComponent.decorators = [
{ type: Component, args: [{
selector: 'app-composite',
template: "<div>\n <h3 class=\"mt-3\">Class Enrollment:</h3>\n\n <div *ngFor=\"let step of steps; index as idx;\">\n <h4 class=\"mt-3\">{{idx + 1}}. {{step.stepName}}</h4>\n <ng-template composite-directive></ng-template>\n <div class=\"error-message\" *ngIf=\"errorMessages[idx]\">{{step.errorMessage}}</div>\n </div>\n\n <div class=\"action-buttons-center mt-3\">\n <button class=\"btn btn-success\" \n (click)=\"onSubmit()\">Submit</button>\n <button class=\"btn btn-outline-success\" \n type=\"button\" (click)=\"onCancel()\">Cancel</button>\n \n <div *ngIf=\"submitting && !allActionsReady()\" class=\"error-message\">Please check and fix all errors before submitting.</div>\n </div>\n\n <div style=\"display: none;\">\n <ng-template composite-submit-directive></ng-template>\n </div>\n</div>",
styles: [".action-buttons-center{width:100%;float:right;text-align:center;margin-bottom:1.25rem}.action-buttons-center .btn{display:inline-block;margin-left:2.5rem}.error-message{color:#dc3545;margin-top:1rem;font-style:italic}"]
}] }
];
/** @nocollapse */
CompositeComponent.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: Router }
];
CompositeComponent.propDecorators = {
steps: [{ type: Input }],
stepConfigs: [{ type: Input }],
title: [{ type: Input }],
submit: [{ type: Input }],
componentEvents: [{ type: Output }],
compositeDirectives: [{ type: ViewChildren, args: [CompositeDirective,] }],
compositeSubmitDirective: [{ type: ViewChild, args: [CompositeSubmitDirective,] }]
};
if (false) {
/** @type {?} */
CompositeComponent.prototype.steps;
/** @type {?} */
CompositeComponent.prototype.stepConfigs;
/** @type {?} */
CompositeComponent.prototype.title;
/** @type {?} */
CompositeComponent.prototype.submit;
/** @type {?} */
CompositeComponent.prototype.totalSteps;
/** @type {?} */
CompositeComponent.prototype.stepCompRef;
/** @type {?} */
CompositeComponent.prototype.stepCompIns;
/** @type {?} */
CompositeComponent.prototype.stepCompEmitter;
/** @type {?} */
CompositeComponent.prototype.submitCompRef;
/** @type {?} */
CompositeComponent.prototype.errorMessages;
/** @type {?} */
CompositeComponent.prototype.submitting;
/** @type {?} */
CompositeComponent.prototype.componentEvents;
/** @type {?} */
CompositeComponent.prototype.compositeDirectives;
/** @type {?} */
CompositeComponent.prototype.compositeSubmitDirective;
/** @type {?} */
CompositeComponent.prototype.componentFactoryResolver;
/** @type {?} */
CompositeComponent.prototype.router;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9zaXRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL21kZHMtYW5ndWxhci1jb21wb3NpdGUvIiwic291cmNlcyI6WyJjb21wb3NpdGUvY29tcG9zaXRlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFBRSxTQUFTLEVBQ3BCLEtBQUssRUFBRSxNQUFNLEVBRWIsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFDekMsd0JBQXdCLEVBQUUsU0FBUyxFQUNuQyxZQUFZLEdBQ2YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBaUN6QyxNQUFNLE9BQU8sa0JBQWtCOzs7O0lBQzNCLFlBQW1CLGdCQUFrQztRQUFsQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO0lBQUksQ0FBQzs7O1lBSjdELFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsdUJBQXVCO2FBQ3BDOzs7O1lBcENHLGdCQUFnQjs7OztJQXNDSiw4Q0FBeUM7O0FBTXpELE1BQU0sT0FBTyx3QkFBd0I7Ozs7SUFDakMsWUFBbUIsZ0JBQWtDO1FBQWxDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7SUFBSSxDQUFDOzs7WUFKN0QsU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSw4QkFBOEI7YUFDM0M7Ozs7WUEzQ0csZ0JBQWdCOzs7O0lBNkNKLG9EQUF5Qzs7QUFRekQsTUFBTSxPQUFPLGtCQUFrQjs7Ozs7SUEwQjNCLFlBQ1csd0JBQWtELEVBQ2xELE1BQWM7UUFEZCw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELFdBQU0sR0FBTixNQUFNLENBQVE7UUFsQmxCLGVBQVUsR0FBVyxDQUFDLENBQUM7UUFDdkIsZ0JBQVcsR0FBRyxFQUFFLENBQUM7UUFDakIsZ0JBQVcsR0FBRyxFQUFFLENBQUM7UUFDakIsb0JBQWUsR0FBRyxFQUFFLENBQUM7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QUN4Qiw2Q0FBNEI7O0lBQzVCLDJDQUFxQjs7SUFDckIsMkNBQXFDOztJQUNyQyx3Q0FBMEI7O0lBRTFCLDZDQUNpRDs7SUFFakQsaURBQ21EOztJQUNuRCxzREFDbUQ7O0lBRy9DLHNEQUF5RDs7SUFDekQsb0NBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsIERpcmVjdGl2ZSxcbiAgICBJbnB1dCwgT3V0cHV0LFxuICAgIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCxcbiAgICBWaWV3Q29udGFpbmVyUmVmLCBWaWV3Q2hpbGRyZW4sIFZpZXdDaGlsZCxcbiAgICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIFF1ZXJ5TGlzdCxcbiAgICBFdmVudEVtaXR0ZXIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuZXhwb3J0IHR5cGUgY29tcG9zaXRlU3RlcCA9IHtcbiAgICBzdGVwTmFtZTogc3RyaW5nLFxuICAgIGVycm9yTWVzc2FnZTogc3RyaW5nLCAvL21lc3NhZ2VzIGZvciBwb3NzaWJsZSBlcnJvclxufTtcbmV4cG9ydCB0eXBlIGNvbXBvc2l0ZVN0ZXBDb25maWcgPSB7XG4gICAgc3RlcFRpdGxlOiBzdHJpbmcsXG5cbiAgICBzdGVwQ29tcG9uZW50OiBhbnksIFxuICAgIG1hbmRhdG9yeTogYm9vbGVhbixcblxuICAgIC8vIGZvciBsaXN0IHNlbGVjdGlvblxuICAgIHByZVNlbGVjdGVkSWQ6IHN0cmluZyxcbiAgICBtdWx0aVNlbGVjdDogYm9vbGVhbixcbiAgICAvLyBmb3IgZGV0YWlsIHZpZXdcbiAgICBkaXNhYmxlQWN0aW9uQnV0dGlvbnM6IGJvb2xlYW4sXG5cbiAgICAvLyBib3RoIGxpc3QgYW5kIGRldGFpbFxuICAgIHNlYXJjaE9iajogYW55LFxuXG4gICAgc3VibWl0RmllbGROYW1lOiBzdHJpbmcsIC8vbWFwcGluZyB0byB0aGUgZmllbGQgaW4gc3VibWl0IGNvbXBvbmVudHNcbn07XG5leHBvcnQgdHlwZSBzdWJtaXRDb21wb25lbnQgPSB7XG4gICAgY29tcG9tZW50OiBhbnksXG4gICAgc3VjY2VlZFVybDogc3RyaW5nLFxuICAgIGNhbmNlbFVybDogc3RyaW5nLFxuICAgIHJlcXVpcmVDb25maXJtOiBib29sZWFuLFxufVxuXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tjb21wb3NpdGUtZGlyZWN0aXZlXScsXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvc2l0ZURpcmVjdGl2ZSB7XG4gICAgY29uc3RydWN0b3IocHVibGljIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHsgfVxufVxuXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tjb21wb3NpdGUtc3VibWl0LWRpcmVjdGl2ZV0nLFxufSlcbmV4cG9ydCBjbGFzcyBDb21wb3NpdGVTdWJtaXREaXJlY3RpdmUge1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7IH1cbn1cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhcHAtY29tcG9zaXRlJyxcbiAgICB0ZW1wbGF0ZVVybDogJ2NvbXBvc2l0ZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJ2NvbXBvc2l0ZS5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvc2l0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdHtcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzdGVwczogY29tcG9zaXRlU3RlcFtdO1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHN0ZXBDb25maWdzOiBjb21wb3NpdGVTdGVwQ29uZmlnW107XG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgdGl0bGU6IHN0cmluZztcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzdWJtaXQ6IHN1Ym1pdENvbXBvbmVudDtcblxuICAgIHB1YmxpYyB0b3RhbFN0ZXBzOiBudW1iZXIgPSAwO1xuICAgIHB1YmxpYyBzdGVwQ29tcFJlZiA9IFtdO1xuICAgIHB1YmxpYyBzdGVwQ29tcElucyA9IFtdO1xuICAgIHB1YmxpYyBzdGVwQ29tcEVtaXR0ZXIgPSBbXTtcbiAgICBwdWJsaWMgc3VibWl0Q29tcFJlZjtcbiAgICBwdWJsaWMgZXJyb3JNZXNzYWdlczogYm9vbGVhbltdID0gW107XG4gICAgcHVibGljIHN1Ym1pdHRpbmcgPSBmYWxzZTtcblxuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBjb21wb25lbnRFdmVudHMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAgIEBWaWV3Q2hpbGRyZW4oQ29tcG9zaXRlRGlyZWN0aXZlKVxuICAgIGNvbXBvc2l0ZURpcmVjdGl2ZXM6IFF1ZXJ5TGlzdDxDb21wb3NpdGVEaXJlY3RpdmU+O1xuICAgIEBWaWV3Q2hpbGQoQ29tcG9zaXRlU3VibWl0RGlyZWN0aXZlKVxuICAgIGNvbXBvc2l0ZVN1Ym1pdERpcmVjdGl2ZTogQ29tcG9zaXRlU3VibWl0RGlyZWN0aXZlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICAgICAgcHVibGljIHJvdXRlcjogUm91dGVyKSB7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zdGVwcykge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFwiTm8gc3RlcHMgZGVmaW5lZCBmb3IgQ29tcG9zaXRlQ29tcG9uZW50LlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRvdGFsU3RlcHMgPSB0aGlzLnN0ZXBzLmxlbmd0aDtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5jb21wb3NpdGVEaXJlY3RpdmVzKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJObyBjb21wb3NpdGUgZGlyZWN0aXZlIGZvciBDb21wb3NpdGVDb21wb25lbnQuXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IC8vdXNpbmcgYSB0aW1lciB0byB0cmlnZ2VyIHZpZXcgY2hhbmdlcyBpbiBuZXh0IHJvdW5kIG9mIGNoYW5nZSBkZXRlY3Rpb24gdHVybi4gUHJpdmVudCBFeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgICAgICAgICB0aGlzLmxvYWRBbGxTdGVwcygpO1xuICAgICAgICB9LCAxMCk7XG5cbiAgICAgICAgdGhpcy5jb21wb25lbnRFdmVudHMuZW1pdCh7IC8vdGVsbGluZyBwYXJlbnQgd2UgYXJlIHJlYWR5IHRvIGxvYWQgc3RlcHNcbiAgICAgICAgICAgIHN0ZXBJbmRleDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWVzc2FnZToge1xuICAgICAgICAgICAgICAgIHR5cGU6ICduZ0FmdGVyVmlld0luaXQnXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZWxvYWRTdGVwKGluZGV4OiBudW1iZXIsIHN0ZXBDb25maWc6IGNvbXBvc2l0ZVN0ZXBDb25maWcpIHtcbiAgICAgICAgY29uc3QgZGlyZWN0aXZlID0gdGhpcy5jb21wb3NpdGVEaXJlY3RpdmVzLnRvQXJyYXkoKVtpbmRleF07XG4gICAgICAgIGNvbnN0IHsgc3RlcFRpdGxlLCBzdGVwQ29tcG9uZW50LCBtYW5kYXRvcnksIHByZVNlbGVjdGVkSWQsIHNlYXJjaE9iaiwgZGlzYWJsZUFjdGlvbkJ1dHRpb25zfSA9IHN0ZXBDb25maWc7XG5cbiAgICAgICAgaWYgKCFzdGVwQ29tcG9uZW50KSByZXR1cm47IC8vc3RvcCBoYW5kbGluZyB0aGlzIHN0ZXAuXG5cbiAgICAgICAgbGV0IHZpZXdDb250YWluZXJSZWYgPSBkaXJlY3RpdmUudmlld0NvbnRhaW5lclJlZjtcbiAgICAgICAgdmlld0NvbnRhaW5lclJlZi5jbGVhcigpO1xuXG4gICAgICAgIGxldCBjb21wb25lbnRGYWN0b3J5ID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3Rvcnkoc3RlcENvbXBvbmVudCk7XG4gICAgICAgIGxldCBjb21wb25lbnRSZWYgPSB2aWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudChjb21wb25lbnRGYWN0b3J5KTsgLy8gY3JlYXRlIGFuZCBpbnNlcnQgaW4gb25lIGNhbGxcblxuICAgICAgICBsZXQgY29tcG9uZW50SW5zdGFuY2U6IGFueSA9IGNvbXBvbmVudFJlZi5pbnN0YW5jZTtcbiAgICAgICAgdGhpcy5zdGVwQ29tcEluc1tpbmRleF0gPSBjb21wb25lbnRJbnN0YW5jZTtcblxuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5pbnB1dERhdGEgPSB7XG4gICAgICAgICAgICBzdGVwVGl0bGUsXG4gICAgICAgICAgICBwcmVTZWxlY3RlZElkLFxuICAgICAgICAgICAgbWFuZGF0b3J5LFxuICAgICAgICB9O1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5zZWFyY2hPYmogPSBzZWFyY2hPYmo7XG4gICAgICAgIGNvbXBvbmVudEluc3RhbmNlLmRpc2FibGVBY3Rpb25CdXR0aW9ucyA9IGRpc2FibGVBY3Rpb25CdXR0aW9ucztcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5zZXRGb2N1cygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbXBvbmVudEluc3RhbmNlLmV2ZW50RW1pdHRlci5zdWJzY3JpYmUoKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0ge1xuICAgICAgICAgICAgICAgICAgICBzdGVwSW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvbmVudEV2ZW50cy5lbWl0KG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGxvYWRBbGxTdGVwcygpIHtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMuY29tcG9zaXRlRGlyZWN0aXZlcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0ZXBDb21wSW5zW2luZGV4XSkgY29udGludWU7IC8vYWxyZWFkeSBsb2FkZWRcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGVwQ29uZmlnc1tpbmRleF0pIGNvbnRpbnVlOyAvL25vIGNvbmZpZ3VyYXRpb25cbiAgICAgICAgICAgIHRoaXMucmVsb2FkU3RlcChpbmRleCwgdGhpcy5zdGVwQ29uZmlnc1tpbmRleF0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFsbEFjdGlvbnNSZWFkeSgpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IHJlYWR5ID0gdHJ1ZTtcbiAgICAgICAgZm9yKGxldCBbaW5kZXgsIHN0ZXBdIG9mIHRoaXMuc3RlcENvbmZpZ3MuZW50cmllcygpKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZXNbaW5kZXhdID0gZmFsc2U7IC8vIG5vIGVycm9yXG4gICAgICAgICAgICBpZiAoc3RlcC5tYW5kYXRvcnkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuc3RlcENvbXBJbnNbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UuYWN0aW9uVHlwZSA9PT0gJ3NlbGVjdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gaW5zdGFuY2UuZ2V0U2VsZWN0ZWRJdGVtcygpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZXNbaW5kZXhdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlLmFjdGlvblR5cGUgPT09ICd0ZXJtJykge1xuICAgICAgICAgICAgICAgICAgICBpZighaW5zdGFuY2UuaXNUZXJtQ2hlY2tlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZXNbaW5kZXhdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVhZHk7XG4gICAgfVxuXG4gICAgb25TdWJtaXQoKSB7XG4gICAgICAgIHRoaXMuc3VibWl0dGluZyA9IHRydWU7XG4gICAgICAgIGlmICghKHRoaXMuYWxsQWN0aW9uc1JlYWR5KCkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHZpZXdDb250YWluZXJSZWYgPSB0aGlzLmNvbXBvc2l0ZVN1Ym1pdERpcmVjdGl2ZS52aWV3Q29udGFpbmVyUmVmO1xuICAgICAgICB2aWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnN1Ym1pdENvbXBSZWYpIHtcbiAgICAgICAgICAgIGxldCBjb21wb25lbnRGYWN0b3J5ID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkodGhpcy5zdWJtaXQuY29tcG9tZW50KTtcbiAgICAgICAgICAgIHRoaXMuc3VibWl0Q29tcFJlZiA9IHZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudEZhY3RvcnkpOyAvLyBjcmVhdGUgYW5kIGluc2VydCBpbiBvbmUgY2FsbFxuICAgICAgICB9XG4gICAgICAgIGxldCBjb21wb25lbnRJbnN0YW5jZSA9IHRoaXMuc3VibWl0Q29tcFJlZi5pbnN0YW5jZTtcbiAgICAgICAgY29uc3QgaW5pdERhdGEgPSB7fTtcbiAgICAgICAgZm9yKGxldCBbaW5kZXgsIHN0ZXBdIG9mIHRoaXMuc3RlcENvbmZpZ3MuZW50cmllcygpKSB7XG4gICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuc3RlcENvbXBJbnNbaW5kZXhdO1xuICAgICAgICAgICAgbGV0IHZhbHVlO1xuICAgICAgICAgICAgaWYgKGluc3RhbmNlLmFjdGlvblR5cGUgPT09ICdzZWxlY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBpbnN0YW5jZS5nZXRTZWxlY3RlZEl0ZW1zKCk7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFjb21wb25lbnRJbnN0YW5jZS5hcnJheUZpZWxkcy5zb21lKHg9PnhbMF09PT1zdGVwLnN1Ym1pdEZpZWxkTmFtZSkpIHsgLy9jaGVjayBpZiB0aGUgdGFyZ2V0IGZpZWxkcyBpcyBhbiBhcnJheSBmaWVsZHMuIGluIFsnZmllbGROYW1lJywgJ0ZpZWxkIHR5cGUnXSBmb3JtYXRcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZVswXTsgLy9vbmx5IGdldCBvbmUgb2JqZWN0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5hY3Rpb25UeXBlID09PSAndGVybScpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGluc3RhbmNlLmlzVGVybUNoZWNrZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGluaXREYXRhW3N0ZXAuc3VibWl0RmllbGROYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbXBvbmVudEluc3RhbmNlLmlkID0gdW5kZWZpbmVkO1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5lbWJlZGRlZFZpZXcgPSB0cnVlO1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5pbml0RGF0YSA9IGluaXREYXRhO1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5uZ09uSW5pdCgpO1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5vblN1Ym1pdCgpO1xuICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5kb25lLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwodGhpcy5zdWJtaXQuc3VjY2VlZFVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uQ2FuY2VsKCkge1xuICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZUJ5VXJsKHRoaXMuc3VibWl0LmNhbmNlbFVybCk7XG4gICAgfVxufVxuIl19