@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
208 lines • 33.7 kB
JavaScript
import { Inject, Injectable, Optional } from '@angular/core';
import { take } from 'rxjs/operators';
import { TaskHandlingService } from './task-handling-service';
import { NAE_TASK_OPERATIONS } from '../models/task-operations-injection-token';
import { createTaskEventNotification } from '../../task-content/model/task-event-notification';
import { TaskEvent } from '../../task-content/model/task-event';
import { QueuedEvent } from '../../event-queue/model/queued-event';
import { AfterAction } from '../../utility/call-chain/after-action';
import * as i0 from "@angular/core";
import * as i1 from "../../logger/services/logger.service";
import * as i2 from "../../resources/engine-endpoint/task-resource.service";
import * as i3 from "../../snack-bar/services/snack-bar.service";
import * as i4 from "@ngx-translate/core";
import * as i5 from "./task-request-state.service";
import * as i6 from "./task-data.service";
import * as i7 from "../../utility/call-chain/call-chain.service";
import * as i8 from "../../task-content/services/task-event.service";
import * as i9 from "../../event-queue/services/event-queue.service";
import * as i10 from "../../event/services/event.service";
import * as i11 from "../../changed-fields/services/changed-fields.service";
import * as i12 from "./selected-case.service";
import * as i13 from "../../task-content/services/task-content.service";
import * as i14 from "../../actions/services/front-action.service";
/**
* Service that handles the logic of finishing a task.
*/
export class FinishTaskService extends TaskHandlingService {
_log;
_taskResourceService;
_snackBar;
_translate;
_taskState;
_taskDataService;
_callChain;
_taskEvent;
_eventQueue;
_eventService;
_changedFieldsService;
_taskOperations;
_frontActionService;
constructor(_log, _taskResourceService, _snackBar, _translate, _taskState, _taskDataService, _callChain, _taskEvent, _eventQueue, _eventService, _changedFieldsService, _taskOperations, _selectedCaseService, _taskContentService, _frontActionService) {
super(_taskContentService, _selectedCaseService);
this._log = _log;
this._taskResourceService = _taskResourceService;
this._snackBar = _snackBar;
this._translate = _translate;
this._taskState = _taskState;
this._taskDataService = _taskDataService;
this._callChain = _callChain;
this._taskEvent = _taskEvent;
this._eventQueue = _eventQueue;
this._eventService = _eventService;
this._changedFieldsService = _changedFieldsService;
this._taskOperations = _taskOperations;
this._frontActionService = _frontActionService;
}
/**
* Updates the task data to their current state from backend, checks the validity of the data and
* sends a finish request to backend.
*
* Finish request is not sent if the task contains invalid data.
*
* If an update to the data is already in progress waits for it's successful completion and sends the finish request after.
*
* @param afterAction if finish request completes successfully `true` will be emitted into this Subject,
* otherwise `false` will be emitted
*/
validateDataAndFinish(afterAction = new AfterAction()) {
if (this.dataIsEmpty()) {
this._taskDataService.initializeTaskDataFields(this._callChain.create(() => {
if (this._safeTask.dataSize <= 0 ||
(this._taskContentService.validateDynamicEnumField() && this._taskContentService.validateTaskData())) {
this.queueFinishTaskRequest(afterAction);
}
}));
}
else if (this._taskContentService.validateDynamicEnumField() && this._taskContentService.validateTaskData()) {
const finishedTaskId = this._safeTask.stringId;
this._taskDataService.updateTaskDataFields(this._callChain.create(success => {
if (success && this._taskState.isUpdating(finishedTaskId)) {
this._taskDataService.updateSuccess$.pipe(take(1)).subscribe(bool => {
if (bool) {
this.queueFinishTaskRequest(afterAction);
}
});
}
else if (success) {
this.queueFinishTaskRequest(afterAction);
}
}));
}
}
/**
* Sends the finish request to backend and notifies the user about the outcome of the operation via a snack bar message.
*
* Doesn't send any requests if the loading indicator is in it's active state.
* Otherwise sets the indicator to the active state and disables it once the request response is received.
*
* The argument can be used to chain operations together,
* or to execute code conditionally based on the success state of the finish request.
*
* If the task held within the {@link TaskContentService} changes before a response is received, the response will be ignored
* and the `afterAction` will not be executed.
* @param afterAction if finish request completes successfully `true` will be emitted into this Subject,
* otherwise `false` will be emitted
*/
queueFinishTaskRequest(afterAction) {
this._eventQueue.scheduleEvent(new QueuedEvent(() => true, nextEvent => {
this.performFinishRequest(afterAction, nextEvent);
}));
}
/**
* Performs a `finish` request on the task currently stored in the `taskContent` service
* @param afterAction the action that should be performed after the request is processed
* @param nextEvent indicates to the event queue that the next event can be processed
*/
performFinishRequest(afterAction, nextEvent) {
const finishedTaskId = this._safeTask.stringId;
// this is probably no longer necessary because of the event queue
if (this._taskState.isLoading(finishedTaskId)) {
nextEvent.resolve(true);
return;
}
this._taskState.startLoading(finishedTaskId);
this._taskResourceService.finishTask(this._safeTask.stringId).pipe(take(1))
.subscribe((outcomeResource) => {
this._taskState.stopLoading(finishedTaskId);
if (!this.isTaskRelevant(finishedTaskId)) {
this._log.debug('current task changed before the finish response could be received, discarding...');
nextEvent.resolve(false);
return;
}
if (outcomeResource.success) {
this._taskContentService.updateStateData(outcomeResource.outcome);
const changedFieldsMap = this._eventService
.parseChangedFieldsFromOutcomeTree(outcomeResource.outcome);
const frontActions = this._eventService.parseFrontActionsFromOutcomeTree(outcomeResource.outcome);
if (!!changedFieldsMap) {
this._changedFieldsService.emitChangedFields(changedFieldsMap);
}
if (frontActions?.length > 0) {
this._frontActionService.runAll(frontActions);
}
this._taskOperations.reload();
this.completeActions(afterAction, nextEvent, true, outcomeResource.outcome);
this._taskOperations.close();
this._snackBar.openSuccessSnackBar(outcomeResource.outcome.message === undefined
? this._translate.instant('tasks.snackbar.finishTaskSuccess')
: outcomeResource.outcome.message);
}
else if (outcomeResource.error !== undefined) {
if (outcomeResource.error !== '') {
this._snackBar.openErrorSnackBar(outcomeResource.error);
}
if (outcomeResource.outcome !== undefined) {
const changedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(outcomeResource.outcome);
this._changedFieldsService.emitChangedFields(changedFieldsMap);
}
this.completeActions(afterAction, nextEvent, false);
}
}, error => {
this._taskState.stopLoading(finishedTaskId);
this._log.debug('finishing task failed', error);
if (!this.isTaskRelevant(finishedTaskId)) {
this._log.debug('current task changed before the finish error could be received');
nextEvent.resolve(false);
return;
}
this._snackBar.openErrorSnackBar(`${this._translate.instant('tasks.snackbar.finishTask')}
${this._task.title} ${this._translate.instant('tasks.snackbar.failed')}`);
this.completeActions(afterAction, nextEvent, false);
});
}
/**
* Completes all the action streams and sends the notification, with the provided result
*/
completeActions(afterAction, nextEvent, result, outcome) {
this.sendNotification(result, outcome);
afterAction.resolve(result);
nextEvent.resolve(result);
}
/**
* Publishes a finish notification to the {@link TaskEventService}
* @param success whether the finish operation was successful or not
* @param outcome TaskEventOutcome
*/
sendNotification(success, outcome) {
this._taskEvent.publishTaskEvent(createTaskEventNotification(this._safeTask, TaskEvent.FINISH, success, outcome));
}
/**
* Checks data size
* @return boolean whether the task contains data or not
*/
dataIsEmpty() {
return this._safeTask.dataSize <= 0 || !this._safeTask.dataGroups || this._safeTask.dataGroups.length <= 0;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FinishTaskService, deps: [{ token: i1.LoggerService }, { token: i2.TaskResourceService }, { token: i3.SnackBarService }, { token: i4.TranslateService }, { token: i5.TaskRequestStateService }, { token: i6.TaskDataService }, { token: i7.CallChainService }, { token: i8.TaskEventService }, { token: i9.EventQueueService }, { token: i10.EventService }, { token: i11.ChangedFieldsService }, { token: NAE_TASK_OPERATIONS }, { token: i12.SelectedCaseService, optional: true }, { token: i13.TaskContentService }, { token: i14.FrontActionService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FinishTaskService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FinishTaskService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.LoggerService }, { type: i2.TaskResourceService }, { type: i3.SnackBarService }, { type: i4.TranslateService }, { type: i5.TaskRequestStateService }, { type: i6.TaskDataService }, { type: i7.CallChainService }, { type: i8.TaskEventService }, { type: i9.EventQueueService }, { type: i10.EventService }, { type: i11.ChangedFieldsService }, { type: undefined, decorators: [{
type: Inject,
args: [NAE_TASK_OPERATIONS]
}] }, { type: i12.SelectedCaseService, decorators: [{
type: Optional
}] }, { type: i13.TaskContentService }, { type: i14.FrontActionService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluaXNoLXRhc2suc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy1jb3JlL3NyYy9saWIvdGFzay9zZXJ2aWNlcy9maW5pc2gtdGFzay5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFRcEMsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sMkNBQTJDLENBQUM7QUFJOUUsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sa0RBQWtELENBQUM7QUFDN0YsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBSzlELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNqRSxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sdUNBQXVDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRbEU7O0dBRUc7QUFFSCxNQUFNLE9BQU8saUJBQWtCLFNBQVEsbUJBQW1CO0lBRWhDO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDNkI7SUFHN0I7SUFkdEIsWUFBc0IsSUFBbUIsRUFDbkIsb0JBQXlDLEVBQ3pDLFNBQTBCLEVBQzFCLFVBQTRCLEVBQzVCLFVBQW1DLEVBQ25DLGdCQUFpQyxFQUNqQyxVQUE0QixFQUM1QixVQUE0QixFQUM1QixXQUE4QixFQUM5QixhQUEyQixFQUMzQixxQkFBMkMsRUFDZCxlQUErQixFQUMxRCxvQkFBeUMsRUFDckQsbUJBQXVDLEVBQzdCLG1CQUF1QztRQUN6RCxLQUFLLENBQUMsbUJB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U0FBUyxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQy9HLENBQUM7d0dBNUtRLGlCQUFpQiwwWEFhTixtQkFBbUI7NEdBYjlCLGlCQUFpQjs7NEZBQWpCLGlCQUFpQjtrQkFEN0IsVUFBVTs7MEJBY00sTUFBTTsyQkFBQyxtQkFBbUI7OzBCQUMxQixRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7dGFrZX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtMb2dnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9sb2dnZXIvc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtUYXNrQ29udGVudFNlcnZpY2V9IGZyb20gJy4uLy4uL3Rhc2stY29udGVudC9zZXJ2aWNlcy90YXNrLWNvbnRlbnQuc2VydmljZSc7XG5pbXBvcnQge1Rhc2tSZXNvdXJjZVNlcnZpY2V9IGZyb20gJy4uLy4uL3Jlc291cmNlcy9lbmdpbmUtZW5kcG9pbnQvdGFzay1yZXNvdXJjZS5zZXJ2aWNlJztcbmltcG9ydCB7U25hY2tCYXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9zbmFjay1iYXIvc2VydmljZXMvc25hY2stYmFyLnNlcnZpY2UnO1xuaW1wb3J0IHtUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7VGFza1JlcXVlc3RTdGF0ZVNlcnZpY2V9IGZyb20gJy4vdGFzay1yZXF1ZXN0LXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHtUYXNrRGF0YVNlcnZpY2V9IGZyb20gJy4vdGFzay1kYXRhLnNlcnZpY2UnO1xuaW1wb3J0IHtUYXNrSGFuZGxpbmdTZXJ2aWNlfSBmcm9tICcuL3Rhc2staGFuZGxpbmctc2VydmljZSc7XG5pbXBvcnQge05BRV9UQVNLX09QRVJBVElPTlN9IGZyb20gJy4uL21vZGVscy90YXNrLW9wZXJhdGlvbnMtaW5qZWN0aW9uLXRva2VuJztcbmltcG9ydCB7VGFza09wZXJhdGlvbnN9IGZyb20gJy4uL2ludGVyZmFjZXMvdGFzay1vcGVyYXRpb25zJztcbmltcG9ydCB7Q2FsbENoYWluU2VydmljZX0gZnJvbSAnLi4vLi4vdXRpbGl0eS9jYWxsLWNoYWluL2NhbGwtY2hhaW4uc2VydmljZSc7XG5pbXBvcnQge1NlbGVjdGVkQ2FzZVNlcnZpY2V9IGZyb20gJy4vc2VsZWN0ZWQtY2FzZS5zZXJ2aWNlJztcbmltcG9ydCB7Y3JlYXRlVGFza0V2ZW50Tm90aWZpY2F0aW9ufSBmcm9tICcuLi8uLi90YXNrLWNvbnRlbnQvbW9kZWwvdGFzay1ldmVudC1ub3RpZmljYXRpb24nO1xuaW1wb3J0IHtUYXNrRXZlbnR9IGZyb20gJy4uLy4uL3Rhc2stY29udGVudC9tb2RlbC90YXNrLWV2ZW50JztcbmltcG9ydCB7VGFza0V2ZW50U2VydmljZX0gZnJvbSAnLi4vLi4vdGFzay1jb250ZW50L3NlcnZpY2VzL3Rhc2stZXZlbnQuc2VydmljZSc7XG5pbXBvcnQge0ZpbmlzaFRhc2tFdmVudE91dGNvbWV9IGZyb20gJy4uLy4uL2V2ZW50L21vZGVsL2V2ZW50LW91dGNvbWVzL3Rhc2stb3V0Y29tZXMvZmluaXNoLXRhc2stZXZlbnQtb3V0Y29tZSc7XG5pbXBvcnQge0V2ZW50T3V0Y29tZU1lc3NhZ2VSZXNvdXJjZX0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2ludGVyZmFjZS9tZXNzYWdlLXJlc291cmNlJztcbmltcG9ydCB7RXZlbnRRdWV1ZVNlcnZpY2V9IGZyb20gJy4uLy4uL2V2ZW50LXF1ZXVlL3NlcnZpY2VzL2V2ZW50LXF1ZXVlLnNlcnZpY2UnO1xuaW1wb3J0IHtRdWV1ZWRFdmVudH0gZnJvbSAnLi4vLi4vZXZlbnQtcXVldWUvbW9kZWwvcXVldWVkLWV2ZW50JztcbmltcG9ydCB7QWZ0ZXJBY3Rpb259IGZyb20gJy4uLy4uL3V0aWxpdHkvY2FsbC1jaGFpbi9hZnRlci1hY3Rpb24nO1xuaW1wb3J0IHtDaGFuZ2VkRmllbGRzU2VydmljZX0gZnJvbSAnLi4vLi4vY2hhbmdlZC1maWVsZHMvc2VydmljZXMvY2hhbmdlZC1maWVsZHMuc2VydmljZSc7XG5pbXBvcnQge0V2ZW50U2VydmljZX0gZnJvbSAnLi4vLi4vZXZlbnQvc2VydmljZXMvZXZlbnQuc2VydmljZSc7XG5pbXBvcnQge0NoYW5nZWRGaWVsZHNNYXB9IGZyb20gJy4uLy4uL2V2ZW50L3NlcnZpY2VzL2ludGVyZmFjZXMvY2hhbmdlZC1maWVsZHMtbWFwJztcbmltcG9ydCB7VGFza0V2ZW50T3V0Y29tZX0gZnJvbSAnLi4vLi4vZXZlbnQvbW9kZWwvZXZlbnQtb3V0Y29tZXMvdGFzay1vdXRjb21lcy90YXNrLWV2ZW50LW91dGNvbWUnO1xuaW1wb3J0IHtGcm9udEFjdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uL2FjdGlvbnMvc2VydmljZXMvZnJvbnQtYWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtGcm9udEFjdGlvbn0gZnJvbSAnLi4vLi4vZGF0YS1maWVsZHMvbW9kZWxzL2NoYW5nZWQtZmllbGRzJztcblxuLyoqXG4gKiBTZXJ2aWNlIHRoYXQgaGFuZGxlcyB0aGUgbG9naWMgb2YgZmluaXNoaW5nIGEgdGFzay5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZpbmlzaFRhc2tTZXJ2aWNlIGV4dGVuZHMgVGFza0hhbmRsaW5nU2VydmljZSB7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgX2xvZzogTG9nZ2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3Rhc2tSZXNvdXJjZVNlcnZpY2U6IFRhc2tSZXNvdXJjZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9zbmFja0JhcjogU25hY2tCYXJTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdGFza1N0YXRlOiBUYXNrUmVxdWVzdFN0YXRlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3Rhc2tEYXRhU2VydmljZTogVGFza0RhdGFTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfY2FsbENoYWluOiBDYWxsQ2hhaW5TZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdGFza0V2ZW50OiBUYXNrRXZlbnRTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfZXZlbnRRdWV1ZTogRXZlbnRRdWV1ZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9ldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2NoYW5nZWRGaWVsZHNTZXJ2aWNlOiBDaGFuZ2VkRmllbGRzU2VydmljZSxcbiAgICAgICAgICAgICAgICBASW5qZWN0KE5BRV9UQVNLX09QRVJBVElPTlMpIHByb3RlY3RlZCBfdGFza09wZXJhdGlvbnM6IFRhc2tPcGVyYXRpb25zLFxuICAgICAgICAgICAgICAgIEBPcHRpb25hbCgpIF9zZWxlY3RlZENhc2VTZXJ2aWNlOiBTZWxlY3RlZENhc2VTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIF90YXNrQ29udGVudFNlcnZpY2U6IFRhc2tDb250ZW50U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2Zyb250QWN0aW9uU2VydmljZTogRnJvbnRBY3Rpb25TZXJ2aWNlKSB7XG4gICAgICAgIHN1cGVyKF90YXNrQ29udGVudFNlcnZpY2UsIF9zZWxlY3RlZENhc2VTZXJ2aWNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSB0YXNrIGRhdGEgdG8gdGhlaXIgY3VycmVudCBzdGF0ZSBmcm9tIGJhY2tlbmQsIGNoZWNrcyB0aGUgdmFsaWRpdHkgb2YgdGhlIGRhdGEgYW5kXG4gICAgICogc2VuZHMgYSBmaW5pc2ggcmVxdWVzdCB0byBiYWNrZW5kLlxuICAgICAqXG4gICAgICogRmluaXNoIHJlcXVlc3QgaXMgbm90IHNlbnQgaWYgdGhlIHRhc2sgY29udGFpbnMgaW52YWxpZCBkYXRhLlxuICAgICAqXG4gICAgICogSWYgYW4gdXBkYXRlIHRvIHRoZSBkYXRhIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3Mgd2FpdHMgZm9yIGl0J3Mgc3VjY2Vzc2Z1bCBjb21wbGV0aW9uIGFuZCBzZW5kcyB0aGUgZmluaXNoIHJlcXVlc3QgYWZ0ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWZ0ZXJBY3Rpb24gaWYgZmluaXNoIHJlcXVlc3QgY29tcGxldGVzIHN1Y2Nlc3NmdWxseSBgdHJ1ZWAgd2lsbCBiZSBlbWl0dGVkIGludG8gdGhpcyBTdWJqZWN0LFxuICAgICAqIG90aGVyd2lzZSBgZmFsc2VgIHdpbGwgYmUgZW1pdHRlZFxuICAgICAqL1xuICAgIHB1YmxpYyB2YWxpZGF0ZURhdGFBbmRGaW5pc2goYWZ0ZXJBY3Rpb246IEFmdGVyQWN0aW9uID0gbmV3IEFmdGVyQWN0aW9uKCkpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YUlzRW1wdHkoKSkge1xuICAgICAgICAgICAgdGhpcy5fdGFza0RhdGFTZXJ2aWNlLmluaXRpYWxpemVUYXNrRGF0YUZpZWxkcyh0aGlzLl9jYWxsQ2hhaW4uY3JlYXRlKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2FmZVRhc2suZGF0YVNpemUgPD0gMCB8fFxuICAgICAgICAgICAgICAgICAgICAodGhpcy5fdGFza0NvbnRlbnRTZXJ2aWNlLnZhbGlkYXRlRHluYW1pY0VudW1GaWVsZCgpICYmIHRoaXMuX3Rhc2tDb250ZW50U2VydmljZS52YWxpZGF0ZVRhc2tEYXRhKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucXVldWVGaW5pc2hUYXNrUmVxdWVzdChhZnRlckFjdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3Rhc2tDb250ZW50U2VydmljZS52YWxpZGF0ZUR5bmFtaWNFbnVtRmllbGQoKSAmJiB0aGlzLl90YXNrQ29udGVudFNlcnZpY2UudmFsaWRhdGVUYXNrRGF0YSgpKSB7XG4gICAgICAgICAgICBjb25zdCBmaW5pc2hlZFRhc2tJZCA9IHRoaXMuX3NhZmVUYXNrLnN0cmluZ0lkO1xuICAgICAgICAgICAgdGhpcy5fdGFza0RhdGFTZXJ2aWNlLnVwZGF0ZVRhc2tEYXRhRmllbGRzKHRoaXMuX2NhbGxDaGFpbi5jcmVhdGUoc3VjY2VzcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzICYmIHRoaXMuX3Rhc2tTdGF0ZS5pc1VwZGF0aW5nKGZpbmlzaGVkVGFza0lkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFza0RhdGFTZXJ2aWNlLnVwZGF0ZVN1Y2Nlc3MkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKGJvb2wgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChib29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucXVldWVGaW5pc2hUYXNrUmVxdWVzdChhZnRlckFjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZUZpbmlzaFRhc2tSZXF1ZXN0KGFmdGVyQWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhlIGZpbmlzaCByZXF1ZXN0IHRvIGJhY2tlbmQgYW5kIG5vdGlmaWVzIHRoZSB1c2VyIGFib3V0IHRoZSBvdXRjb21lIG9mIHRoZSBvcGVyYXRpb24gdmlhIGEgc25hY2sgYmFyIG1lc3NhZ2UuXG4gICAgICpcbiAgICAgKiBEb2Vzbid0IHNlbmQgYW55IHJlcXVlc3RzIGlmIHRoZSBsb2FkaW5nIGluZGljYXRvciBpcyBpbiBpdCdzIGFjdGl2ZSBzdGF0ZS5cbiAgICAgKiBPdGhlcndpc2Ugc2V0cyB0aGUgaW5kaWNhdG9yIHRvIHRoZSBhY3RpdmUgc3RhdGUgYW5kIGRpc2FibGVzIGl0IG9uY2UgdGhlIHJlcXVlc3QgcmVzcG9uc2UgaXMgcmVjZWl2ZWQuXG4gICAgICpcbiAgICAgKiBUaGUgYXJndW1lbnQgY2FuIGJlIHVzZWQgdG8gY2hhaW4gb3BlcmF0aW9ucyB0b2dldGhlcixcbiAgICAgKiBvciB0byBleGVjdXRlIGNvZGUgY29uZGl0aW9uYWxseSBiYXNlZCBvbiB0aGUgc3VjY2VzcyBzdGF0ZSBvZiB0aGUgZmluaXNoIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgdGFzayBoZWxkIHdpdGhpbiB0aGUge0BsaW5rIFRhc2tDb250ZW50U2VydmljZX0gY2hhbmdlcyBiZWZvcmUgYSByZXNwb25zZSBpcyByZWNlaXZlZCwgdGhlIHJlc3BvbnNlIHdpbGwgYmUgaWdub3JlZFxuICAgICAqIGFuZCB0aGUgYGFmdGVyQWN0aW9uYCB3aWxsIG5vdCBiZSBleGVjdXRlZC5cbiAgICAgKiBAcGFyYW0gYWZ0ZXJBY3Rpb24gaWYgZmluaXNoIHJlcXVlc3QgY29tcGxldGVzIHN1Y2Nlc3NmdWxseSBgdHJ1ZWAgd2lsbCBiZSBlbWl0dGVkIGludG8gdGhpcyBTdWJqZWN0LFxuICAgICAqIG90aGVyd2lzZSBgZmFsc2VgIHdpbGwgYmUgZW1pdHRlZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBxdWV1ZUZpbmlzaFRhc2tSZXF1ZXN0KGFmdGVyQWN0aW9uOiBBZnRlckFjdGlvbik6IHZvaWQge1xuICAgICAgICB0aGlzLl9ldmVudFF1ZXVlLnNjaGVkdWxlRXZlbnQobmV3IFF1ZXVlZEV2ZW50KFxuICAgICAgICAgICAgKCkgPT4gdHJ1ZSxcbiAgICAgICAgICAgIG5leHRFdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtRmluaXNoUmVxdWVzdChhZnRlckFjdGlvbiwgbmV4dEV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBgZmluaXNoYCByZXF1ZXN0IG9uIHRoZSB0YXNrIGN1cnJlbnRseSBzdG9yZWQgaW4gdGhlIGB0YXNrQ29udGVudGAgc2VydmljZVxuICAgICAqIEBwYXJhbSBhZnRlckFjdGlvbiB0aGUgYWN0aW9uIHRoYXQgc2hvdWxkIGJlIHBlcmZvcm1lZCBhZnRlciB0aGUgcmVxdWVzdCBpcyBwcm9jZXNzZWRcbiAgICAgKiBAcGFyYW0gbmV4dEV2ZW50IGluZGljYXRlcyB0byB0aGUgZXZlbnQgcXVldWUgdGhhdCB0aGUgbmV4dCBldmVudCBjYW4gYmUgcHJvY2Vzc2VkXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHBlcmZvcm1GaW5pc2hSZXF1ZXN0KGFmdGVyQWN0aW9uOiBBZnRlckFjdGlvbiwgbmV4dEV2ZW50OiBBZnRlckFjdGlvbikge1xuICAgICAgICBjb25zdCBmaW5pc2hlZFRhc2tJZCA9IHRoaXMuX3NhZmVUYXNrLnN0cmluZ0lkO1xuXG4gICAgICAgIC8vIHRoaXMgaXMgcHJvYmFibHkgbm8gbG9uZ2VyIG5lY2Vzc2FyeSBiZWNhdXNlIG9mIHRoZSBldmVudCBxdWV1ZVxuICAgICAgICBpZiAodGhpcy5fdGFza1N0YXRlLmlzTG9hZGluZyhmaW5pc2hlZFRhc2tJZCkpIHtcbiAgICAgICAgICAgIG5leHRFdmVudC5yZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdGFza1N0YXRlLnN0YXJ0TG9hZGluZyhmaW5pc2hlZFRhc2tJZCk7XG5cbiAgICAgICAgdGhpcy5fdGFza1Jlc291cmNlU2VydmljZS5maW5pc2hUYXNrKHRoaXMuX3NhZmVUYXNrLnN0cmluZ0lkKS5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChvdXRjb21lUmVzb3VyY2U6IEV2ZW50T3V0Y29tZU1lc3NhZ2VSZXNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdGFza1N0YXRlLnN0b3BMb2FkaW5nKGZpbmlzaGVkVGFza0lkKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1Rhc2tSZWxldmFudChmaW5pc2hlZFRhc2tJZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2cuZGVidWcoJ2N1cnJlbnQgdGFzayBjaGFuZ2VkIGJlZm9yZSB0aGUgZmluaXNoIHJlc3BvbnNlIGNvdWxkIGJlIHJlY2VpdmVkLCBkaXNjYXJkaW5nLi4uJyk7XG4gICAgICAgICAgICAgICAgbmV4dEV2ZW50LnJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG91dGNvbWVSZXNvdXJjZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGFza0NvbnRlbnRTZXJ2aWNlLnVwZGF0ZVN0YXRlRGF0YShvdXRjb21lUmVzb3VyY2Uub3V0Y29tZSBhcyBGaW5pc2hUYXNrRXZlbnRPdXRjb21lKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFuZ2VkRmllbGRzTWFwOiBDaGFuZ2VkRmllbGRzTWFwID0gdGhpcy5fZXZlbnRTZXJ2aWNlXG4gICAgICAgICAgICAgICAgICAgIC5wYXJzZUNoYW5nZWRGaWVsZHNGcm9tT3V0Y29tZVRyZWUob3V0Y29tZVJlc291cmNlLm91dGNvbWUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZyb250QWN0aW9uczogQXJyYXk8RnJvbnRBY3Rpb24+ID0gdGhpcy5fZXZlbnRTZXJ2aWNlLnBhcnNlRnJvbnRBY3Rpb25zRnJvbU91dGNvbWVUcmVlKG91dGNvbWVSZXNvdXJjZS5vdXRjb21lKTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiAoISFjaGFuZ2VkRmllbGRzTWFwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoYW5nZWRGaWVsZHNTZXJ2aWNlLmVtaXRDaGFuZ2VkRmllbGRzKGNoYW5nZWRGaWVsZHNNYXApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZnJvbnRBY3Rpb25zPy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2Zyb250QWN0aW9uU2VydmljZS5ydW5BbGwoZnJvbnRBY3Rpb25zKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLl90YXNrT3BlcmF0aW9ucy5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlQWN0aW9ucyhhZnRlckFjdGlvbiwgbmV4dEV2ZW50LCB0cnVlLCBvdXRjb21lUmVzb3VyY2Uub3V0Y29tZSBhcyBGaW5pc2hUYXNrRXZlbnRPdXRjb21lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl90YXNrT3BlcmF0aW9ucy5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NuYWNrQmFyLm9wZW5TdWNjZXNzU25hY2tCYXIob3V0Y29tZVJlc291cmNlLm91dGNvbWUubWVzc2FnZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy5fdHJhbnNsYXRlLmluc3RhbnQoJ3Rhc2tzLnNuYWNrYmFyLmZpbmlzaFRhc2tTdWNjZXNzJylcbiAgICAgICAgICAgICAgICAgICAgOiBvdXRjb21lUmVzb3VyY2Uub3V0Y29tZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3V0Y29tZVJlc291cmNlLmVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0Y29tZVJlc291cmNlLmVycm9yICE9PSAnJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zbmFja0Jhci5vcGVuRXJyb3JTbmFja0JhcihvdXRjb21lUmVzb3VyY2UuZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAob3V0Y29tZVJlc291cmNlLm91dGNvbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFuZ2VkRmllbGRzTWFwID0gdGhpcy5fZXZlbnRTZXJ2aWNlLnBhcnNlQ2hhbmdlZEZpZWxkc0Zyb21PdXRjb21lVHJlZShvdXRjb21lUmVzb3VyY2Uub3V0Y29tZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoYW5nZWRGaWVsZHNTZXJ2aWNlLmVtaXRDaGFuZ2VkRmllbGRzKGNoYW5nZWRGaWVsZHNNYXApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlQWN0aW9ucyhhZnRlckFjdGlvbiwgbmV4dEV2ZW50LCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Rhc2tTdGF0ZS5zdG9wTG9hZGluZyhmaW5pc2hlZFRhc2tJZCk7XG4gICAgICAgICAgICB0aGlzLl9sb2cuZGVidWcoJ2ZpbmlzaGluZyB0YXNrIGZhaWxlZCcsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzVGFza1JlbGV2YW50KGZpbmlzaGVkVGFza0lkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvZy5kZWJ1ZygnY3VycmVudCB0YXNrIGNoYW5nZWQgYmVmb3JlIHRoZSBmaW5pc2ggZXJyb3IgY291bGQgYmUgcmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICBuZXh0RXZlbnQucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9zbmFja0Jhci5vcGVuRXJyb3JTbmFja0JhcihgJHt0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgndGFza3Muc25hY2tiYXIuZmluaXNoVGFzaycpfVxuICAgICAgICAgICAgICR7dGhpcy5fdGFzay50aXRsZX0gJHt0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgndGFza3Muc25hY2tiYXIuZmFpbGVkJyl9YCk7XG4gICAgICAgICAgICB0aGlzLmNvbXBsZXRlQWN0aW9ucyhhZnRlckFjdGlvbiwgbmV4dEV2ZW50LCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBsZXRlcyBhbGwgdGhlIGFjdGlvbiBzdHJlYW1zIGFuZCBzZW5kcyB0aGUgbm90aWZpY2F0aW9uLCB3aXRoIHRoZSBwcm92aWRlZCByZXN1bHRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY29tcGxldGVBY3Rpb25zKGFmdGVyQWN0aW9uOiBBZnRlckFjdGlvbiwgbmV4dEV2ZW50OiBBZnRlckFjdGlvbiwgcmVzdWx0OiBib29sZWFuLCBvdXRjb21lPzogVGFza0V2ZW50T3V0Y29tZSkge1xuICAgICAgICB0aGlzLnNlbmROb3RpZmljYXRpb24ocmVzdWx0LCBvdXRjb21lKTtcbiAgICAgICAgYWZ0ZXJBY3Rpb24ucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICBuZXh0RXZlbnQucmVzb2x2ZShyZXN1bHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyBhIGZpbmlzaCBub3RpZmljYXRpb24gdG8gdGhlIHtAbGluayBUYXNrRXZlbnRTZXJ2aWNlfVxuICAgICAqIEBwYXJhbSBzdWNjZXNzIHdoZXRoZXIgdGhlIGZpbmlzaCBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwgb3Igbm90XG4gICAgICogQHBhcmFtIG91dGNvbWUgVGFza0V2ZW50T3V0Y29tZVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBzZW5kTm90aWZpY2F0aW9uKHN1Y2Nlc3M6IGJvb2xlYW4sIG91dGNvbWU/OiBUYXNrRXZlbnRPdXRjb21lKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3Rhc2tFdmVudC5wdWJsaXNoVGFza0V2ZW50KGNyZWF0ZVRhc2tFdmVudE5vdGlmaWNhdGlvbih0aGlzLl9zYWZlVGFzaywgVGFza0V2ZW50LkZJTklTSCwgc3VjY2Vzcywgb3V0Y29tZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBkYXRhIHNpemVcbiAgICAgKiBAcmV0dXJuIGJvb2xlYW4gd2hldGhlciB0aGUgdGFzayBjb250YWlucyBkYXRhIG9yIG5vdFxuICAgICAqL1xuICAgIHByaXZhdGUgZGF0YUlzRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zYWZlVGFzay5kYXRhU2l6ZSA8PSAwIHx8ICF0aGlzLl9zYWZlVGFzay5kYXRhR3JvdXBzIHx8IHRoaXMuX3NhZmVUYXNrLmRhdGFHcm91cHMubGVuZ3RoIDw9IDA7XG4gICAgfVxufVxuIl19