UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

282 lines 47 kB
import { Injectable } from '@angular/core'; import { BehaviorSubject, ReplaySubject, Subject } from 'rxjs'; import { FieldTypeResource } from '../model/field-type-resource'; import { DynamicEnumerationField } from '../../data-fields/enumeration-field/models/dynamic-enumeration-field'; import { TaskRefField } from "../../data-fields/task-ref-field/model/task-ref-field"; import * as i0 from "@angular/core"; import * as i1 from "./field-converter.service"; import * as i2 from "../../snack-bar/services/snack-bar.service"; import * as i3 from "@ngx-translate/core"; import * as i4 from "../../logger/services/logger.service"; /** * Acts as a communication interface between the Component that renders Task content and it's parent Component. * Also provides some general functionality that is needed when working with task content. * * Notable example of a parent Component is the {@link AbstractTaskPanelComponent}. * * Notable example of a task content renderer is the {@link AbstractTaskContentComponent}. */ export class TaskContentService { _fieldConverterService; _snackBarService; _translate; _logger; static FRONTEND_ACTIONS_KEY = '_frontend_actions'; static ACTION = 'action'; $shouldCreate; $shouldCreateCounter; _task; _taskDataReloadRequest$; _isExpanding$; _taskFieldsIndex = {}; _referencedTaskAndCaseIds = {}; constructor(_fieldConverterService, _snackBarService, _translate, _logger) { this._fieldConverterService = _fieldConverterService; this._snackBarService = _snackBarService; this._translate = _translate; this._logger = _logger; this.$shouldCreate = new ReplaySubject(1); this.$shouldCreateCounter = new BehaviorSubject(0); this._isExpanding$ = new BehaviorSubject(false); this._task = undefined; this._taskDataReloadRequest$ = new Subject(); } ngOnDestroy() { if (!this.$shouldCreate.closed) { this.$shouldCreate.complete(); } this._taskDataReloadRequest$.complete(); this._isExpanding$.complete(); } /** * Stream that emits every time a data reload is requested. */ get taskDataReloadRequest$() { return this._taskDataReloadRequest$.asObservable(); } get taskFieldsIndex() { return this._taskFieldsIndex; } set taskFieldsIndex(value) { this._taskFieldsIndex = value; } get referencedTaskAndCaseIds() { return this._referencedTaskAndCaseIds; } set referencedTaskAndCaseIds(value) { this._referencedTaskAndCaseIds = value; } /** * Whether the panel that the task content is contained in is currently expanding. * * If the task content is not contained in a panel, `isExpanding` will be always `false`. */ get isExpanding() { return this._isExpanding$.value; } /** * Changes the state of the task content to `expanding`. */ expansionStarted() { this._isExpanding$.next(true); } /** * Changes the state of the task content to `not expanding`. */ expansionFinished() { this._isExpanding$.next(false); } /** * Checks the validity of all data fields in the managed {@link Task}. * * If some of the fields are invalid touches them so their validation errors will appear (if set). * A snackbar will also be displayed to the user, informing them of the fact that the fields are invalid. * @returns whether the task is valid or not */ validateTaskData(taskId) { if (!this._task || !this._task.dataGroups) { return false; } const valid = !this._task.dataGroups.filter(group => !!group.parentTaskId && !!taskId ? group.parentTaskId === taskId : true).some(group => group.fields.some(field => !field.valid && !field.disabled)); const validDisabled = !this._task.dataGroups.filter(group => !!group.parentTaskId && !!taskId ? group.parentTaskId === taskId : true).some(group => group.fields.some(field => !field.validRequired && field.disabled)); if (!valid) { this._snackBarService.openErrorSnackBar(this._translate.instant('tasks.snackbar.invalidData')); this._task.dataGroups.forEach(group => group.fields.forEach(field => field.touch = true)); } if (!validDisabled) { this._snackBarService.openErrorSnackBar(this._translate.instant('tasks.snackbar.missingRequired')); } return valid && validDisabled; } /** * Finds invalid data of task * * @returns array of invalid datafields */ getInvalidTaskData() { const invalidFields = []; this._task.dataGroups.forEach(group => invalidFields.push(...group.fields.filter(field => (!field.valid && !field.disabled) || (!field.validRequired && !field.disabled)))); return invalidFields; } validateDynamicEnumField() { if (!this._task || !this._task.dataGroups) { return false; } const exists = this._task.dataGroups.some(group => group.fields.some(field => field instanceof DynamicEnumerationField)); if (!exists) { return true; } let valid = true; for (const group of this._task.dataGroups) { for (const field of group.fields) { if (field instanceof DynamicEnumerationField) { if (field.choices !== undefined && field.choices.length !== 0 && field.value !== '' && field.value !== undefined) { if (!field.choices.some(choice => choice.key === field.value)) { field.value = ''; if (field.behavior.required) { valid = false; } } } } } } if (!valid) { this._snackBarService.openErrorSnackBar(this._translate.instant('tasks.snackbar.missingRequired')); } return valid; } /** * Changes the blocking state of all fields in the managed Task. * @param blockingState whether the field should be blocked or not */ blockFields(blockingState) { if (this._task && this._task.dataGroups) { this._task.dataGroups.forEach(group => { group.fields.forEach(field => { field.block = blockingState; }); }); } } /** * Clears the assignee, start date and finish date from the managed Task. */ updateStateData(eventOutcome) { if (this._task) { this._task.userId = eventOutcome.task.userId; this._task.startDate = eventOutcome.task.startDate; this._task.finishDate = eventOutcome.task.finishDate; } } /** * Updates the properties of fields in the managed task based on a delta of changes from previous state. * @param chFields object containing the delta of the changes from the previous state */ updateFromChangedFields(chFields) { if (!this._task || !this._task.dataGroups) { return; } const frontendActions = chFields.taskId === this.task.stringId && chFields[TaskContentService.FRONTEND_ACTIONS_KEY]; Object.keys(chFields).forEach(changedField => { if (chFields.taskId === this._task.stringId && this.isFieldInTask(chFields.taskId, changedField)) { this.updateField(chFields, this.taskFieldsIndex[chFields.taskId].fields[changedField], frontendActions); } else if (!!this.getReferencedTaskId(changedField, chFields)) { this.updateField(chFields, this.taskFieldsIndex[this.getReferencedTaskId(changedField, chFields)].fields[changedField], frontendActions, true); } }); this.$shouldCreate.next(this._task.dataGroups); } updateField(chFields, field, frontendActions, referenced = false) { if (this._fieldConverterService.resolveType(field) === FieldTypeResource.TASK_REF) { this._taskDataReloadRequest$.next(frontendActions ? frontendActions : undefined); return; } const updatedField = chFields[field.stringId]; Object.keys(updatedField).forEach(key => { switch (key) { case 'type': // type is just an information, not an update. A field cannot change its type return; // continue - the field does not need updating, since nothing changed case 'value': field.valueWithoutChange(this._fieldConverterService.formatValueFromBackend(field, updatedField[key])); break; case 'behavior': if (!referenced && updatedField.behavior[this._task.transitionId]) { field.behavior = updatedField.behavior[this._task.transitionId]; } else if (referenced) { const taskId = this.getReferencedTaskId(field.stringId, chFields); const taskRef = this.findTaskRefId(taskId, this.taskFieldsIndex[this._task.stringId].fields); const transitionId = this.taskFieldsIndex[taskId].transitionId; if (!!transitionId && transitionId !== '' && updatedField.behavior[transitionId]) field.behavior = taskRef.behavior.editable ? updatedField.behavior[transitionId] : taskRef.behavior; } break; case 'choices': const newChoices = []; if (updatedField.choices instanceof Array) { updatedField.choices.forEach(it => { newChoices.push({ key: it, value: it }); }); } else { Object.keys(updatedField.choices).forEach(choiceKey => { newChoices.push({ key: choiceKey, value: updatedField.choices[choiceKey] }); }); } field.choices = newChoices; field.updateChoice(); break; case 'options': const newOptions = []; Object.keys(updatedField.options).forEach(optionKey => { newOptions.push({ key: optionKey, value: updatedField.options[optionKey] }); }); field.choices = newOptions; field.updateChoice(); break; case 'validations': field.replaceValidations(updatedField.validations.map(it => it)); break; default: field[key] = updatedField[key]; } field.update(); }); } isFieldInTask(taskId, changedField) { return !!taskId && !!this.taskFieldsIndex[taskId] && !!this.taskFieldsIndex[taskId].fields && !!this.taskFieldsIndex[taskId].fields[changedField]; } getReferencedTaskId(changedField, chFields) { return !!this.taskFieldsIndex ? (Object.keys(this.taskFieldsIndex).find(taskId => taskId !== this.task.stringId && taskId === chFields.taskId && Object.keys(this.taskFieldsIndex[taskId].fields)?.includes(changedField)) || Object.keys(this.taskFieldsIndex).find(taskId => taskId !== this.task.stringId && Object.keys(this.taskFieldsIndex[taskId].fields)?.includes(changedField))) : undefined; } findTaskRefId(taskId, fields) { let taskRefId = Object.values(fields).find(f => f instanceof TaskRefField && f.value?.includes(taskId)); if (!taskRefId) { const referencedTaskIds = Object.values(fields).filter(f => f instanceof TaskRefField).map(tr => tr.value); referencedTaskIds.forEach(id => { taskRefId = this.findTaskRefId(taskId, this.taskFieldsIndex[id].fields); if (!!taskRefId) { return taskRefId; } }); } return taskRefId; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskContentService, deps: [{ token: i1.FieldConverterService }, { token: i2.SnackBarService }, { token: i3.TranslateService }, { token: i4.LoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskContentService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskContentService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.FieldConverterService }, { type: i2.SnackBarService }, { type: i3.TranslateService }, { type: i4.LoggerService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1jb250ZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL3Rhc2stY29udGVudC9zZXJ2aWNlcy90YXNrLWNvbnRlbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBRXBELE9BQU8sRUFBQyxlQUFlLEVBQWMsYUFBYSxFQUFFLE9BQU8sRUFBUSxNQUFNLE1BQU0sQ0FBQztBQVNoRixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRCxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxzRUFBc0UsQ0FBQztBQUs3RyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sdURBQXVELENBQUM7Ozs7OztBQUVuRjs7Ozs7OztHQU9HO0FBRUgsTUFBTSxPQUFnQixrQkFBa0I7SUFlSjtJQUNBO0lBQ0E7SUFDQTtJQWhCekIsTUFBTSxDQUFVLG9CQUFvQixHQUFHLG1CQUFtQixDQUFDO0lBQzNELE1BQU0sQ0FBVSxNQUFNLEdBQUcsUUFBUSxDQUFDO0lBRXpDLGFBQWEsQ0FBa0M7SUFDL0Msb0JBQW9CLENBQTBCO0lBQ3BDLEtBQUssQ0FBTztJQUNaLHVCQUF1QixDQUFrQjtJQUN6QyxhQUFhLENBQTJCO0lBQ3hDLGdCQUFnQixHQUV0QixFQUFFLENBQUM7SUFDRyx5QkFBeUIsR0FBd0MsRUFBRSxDQUFDO0lBRTlFLFlBQWdDLHNCQUE2QyxFQUM3QyxnQkFBaUMsRUFDakMsVUFBNEIsRUFDNUIsT0FBc0I7UUFIdEIsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF1QjtRQUM3QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWlCO1FBQ2pDLGVBQVUsR0FBVixVQUFVLENBQWtCO1FBQzVCLFlBQU8sR0FBUCxPQUFPLENBQWU7UUFD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LE9BQU8sU0FBUyxDQUFDO2lCQUNwQjtZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ047UUFDRCxPQUFPLFNBQVMsQ0FBQTtJQUNwQixDQUFDO3dHQXZTaUIsa0JBQWtCOzRHQUFsQixrQkFBa0I7OzRGQUFsQixrQkFBa0I7a0JBRHZDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9uRGVzdHJveX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RhdGFHcm91cH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2ludGVyZmFjZS9kYXRhLWdyb3Vwcyc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgUmVwbGF5U3ViamVjdCwgU3ViamVjdCwgdGltZXJ9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtUYXNrfSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3Rhc2snO1xuaW1wb3J0IHtMb2dnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9sb2dnZXIvc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtTbmFja0JhclNlcnZpY2V9IGZyb20gJy4uLy4uL3NuYWNrLWJhci9zZXJ2aWNlcy9zbmFjay1iYXIuc2VydmljZSc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtFbnVtZXJhdGlvbkZpZWxkLCBFbnVtZXJhdGlvbkZpZWxkVmFsdWV9IGZyb20gJy4uLy4uL2RhdGEtZmllbGRzL2VudW1lcmF0aW9uLWZpZWxkL21vZGVscy9lbnVtZXJhdGlvbi1maWVsZCc7XG5pbXBvcnQge011bHRpY2hvaWNlRmllbGR9IGZyb20gJy4uLy4uL2RhdGEtZmllbGRzL211bHRpY2hvaWNlLWZpZWxkL21vZGVscy9tdWx0aWNob2ljZS1maWVsZCc7XG5pbXBvcnQge0NoYW5nZSwgQ2hhbmdlZEZpZWxkc30gZnJvbSAnLi4vLi4vZGF0YS1maWVsZHMvbW9kZWxzL2NoYW5nZWQtZmllbGRzJztcbmltcG9ydCB7RmllbGRDb252ZXJ0ZXJTZXJ2aWNlfSBmcm9tICcuL2ZpZWxkLWNvbnZlcnRlci5zZXJ2aWNlJztcbmltcG9ydCB7RmllbGRUeXBlUmVzb3VyY2V9IGZyb20gJy4uL21vZGVsL2ZpZWxkLXR5cGUtcmVzb3VyY2UnO1xuaW1wb3J0IHtEeW5hbWljRW51bWVyYXRpb25GaWVsZH0gZnJvbSAnLi4vLi4vZGF0YS1maWVsZHMvZW51bWVyYXRpb24tZmllbGQvbW9kZWxzL2R5bmFtaWMtZW51bWVyYXRpb24tZmllbGQnO1xuaW1wb3J0IHtWYWxpZGF0aW9ufSBmcm9tICcuLi8uLi9kYXRhLWZpZWxkcy9tb2RlbHMvdmFsaWRhdGlvbic7XG5pbXBvcnQge1Rhc2tFdmVudE91dGNvbWV9IGZyb20gJy4uLy4uL2V2ZW50L21vZGVsL2V2ZW50LW91dGNvbWVzL3Rhc2stb3V0Y29tZXMvdGFzay1ldmVudC1vdXRjb21lJztcbmltcG9ydCB7RGF0YUZpZWxkfSBmcm9tICcuLi8uLi9kYXRhLWZpZWxkcy9tb2RlbHMvYWJzdHJhY3QtZGF0YS1maWVsZCc7XG5pbXBvcnQge1Rhc2tGaWVsZHN9IGZyb20gJy4uL21vZGVsL3Rhc2stZmllbGRzJztcbmltcG9ydCB7VGFza1JlZkZpZWxkfSBmcm9tIFwiLi4vLi4vZGF0YS1maWVsZHMvdGFzay1yZWYtZmllbGQvbW9kZWwvdGFzay1yZWYtZmllbGRcIjtcblxuLyoqXG4gKiBBY3RzIGFzIGEgY29tbXVuaWNhdGlvbiBpbnRlcmZhY2UgYmV0d2VlbiB0aGUgQ29tcG9uZW50IHRoYXQgcmVuZGVycyBUYXNrIGNvbnRlbnQgYW5kIGl0J3MgcGFyZW50IENvbXBvbmVudC5cbiAqIEFsc28gcHJvdmlkZXMgc29tZSBnZW5lcmFsIGZ1bmN0aW9uYWxpdHkgdGhhdCBpcyBuZWVkZWQgd2hlbiB3b3JraW5nIHdpdGggdGFzayBjb250ZW50LlxuICpcbiAqIE5vdGFibGUgZXhhbXBsZSBvZiBhIHBhcmVudCBDb21wb25lbnQgaXMgdGhlIHtAbGluayBBYnN0cmFjdFRhc2tQYW5lbENvbXBvbmVudH0uXG4gKlxuICogTm90YWJsZSBleGFtcGxlIG9mIGEgdGFzayBjb250ZW50IHJlbmRlcmVyIGlzIHRoZSB7QGxpbmsgQWJzdHJhY3RUYXNrQ29udGVudENvbXBvbmVudH0uXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUYXNrQ29udGVudFNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBGUk9OVEVORF9BQ1RJT05TX0tFWSA9ICdfZnJvbnRlbmRfYWN0aW9ucyc7XG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBBQ1RJT04gPSAnYWN0aW9uJztcblxuICAgICRzaG91bGRDcmVhdGU6IFJlcGxheVN1YmplY3Q8QXJyYXk8RGF0YUdyb3VwPj47XG4gICAgJHNob3VsZENyZWF0ZUNvdW50ZXI6IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+O1xuICAgIHByb3RlY3RlZCBfdGFzazogVGFzaztcbiAgICBwcm90ZWN0ZWQgX3Rhc2tEYXRhUmVsb2FkUmVxdWVzdCQ6IFN1YmplY3Q8Q2hhbmdlPjtcbiAgICBwcm90ZWN0ZWQgX2lzRXhwYW5kaW5nJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+O1xuICAgIHByb3RlY3RlZCBfdGFza0ZpZWxkc0luZGV4OiB7XG4gICAgICAgIFt0YXNrSWQ6IHN0cmluZ106IFRhc2tGaWVsZHNcbiAgICB9ID0ge307XG4gICAgcHJvdGVjdGVkIF9yZWZlcmVuY2VkVGFza0FuZENhc2VJZHM6IHsgW2Nhc2VJZDogc3RyaW5nXTogQXJyYXk8c3RyaW5nPiB9ID0ge307XG5cbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocHJvdGVjdGVkIF9maWVsZENvbnZlcnRlclNlcnZpY2U6IEZpZWxkQ29udmVydGVyU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9zbmFja0JhclNlcnZpY2U6IFNuYWNrQmFyU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF90cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfbG9nZ2VyOiBMb2dnZXJTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuJHNob3VsZENyZWF0ZSA9IG5ldyBSZXBsYXlTdWJqZWN0PEFycmF5PERhdGFHcm91cD4+KDEpO1xuICAgICAgICB0aGlzLiRzaG91bGRDcmVhdGVDb3VudGVyID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApO1xuICAgICAgICB0aGlzLl9pc0V4cGFuZGluZyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgICAgICAgdGhpcy5fdGFzayA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fdGFza0RhdGFSZWxvYWRSZXF1ZXN0JCA9IG5ldyBTdWJqZWN0PENoYW5nZT4oKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLiRzaG91bGRDcmVhdGUuY2xvc2VkKSB7XG4gICAgICAgICAgICB0aGlzLiRzaG91bGRDcmVhdGUuY29tcGxldGUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90YXNrRGF0YVJlbG9hZFJlcXVlc3QkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX2lzRXhwYW5kaW5nJC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRoZSBUYXNrIG9iamVjdCBpZiBzZXQgYW5kIGB1bmRlZmluZWRgIG90aGVyd2lzZVxuICAgICAqL1xuICAgIHB1YmxpYyBhYnN0cmFjdCBnZXQgdGFzaygpOiBUYXNrIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogU2V0dGluZyBhIFRhc2sgYWxzbyBlbWl0cyBpdCBpbnRvIHRoZSBzdHJlYW0gYWNjZXNzaWJsZSBieSB0aGUgW3Rhc2skXXtAbGluayBUYXNrQ29udGVudFNlcnZpY2UjdGFzayR9IGdldHRlciBtZXRob2QuXG4gICAgICogQHBhcmFtIHRhc2sgdGhlIFRhc2sgdGhhdCBvd25zIHRoZSBjb250ZW50IG1hbmFnZWQgYnkgdGhpcyBzZXJ2aWNlXG4gICAgICovXG4gICAgcHVibGljIGFic3RyYWN0IHNldCB0YXNrKHRhc2s6IFRhc2spO1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIHJldHVybnMgYSB7QGxpbmsgVGFza30gb2JqZWN0IGV2ZXJ5IHRpbWUgdGhpcyBvYmplY3QgaXMgc2V0LlxuICAgICAqXG4gICAgICogVXNlIFt0YXNrXXtAbGluayBUYXNrQ29udGVudFNlcnZpY2UjdGFza30gc2V0dGVyIG1ldGhvZCB0byBzZXQgdGhlIFRhc2suXG4gICAgICovXG4gICAgcHVibGljIGFic3RyYWN0IGdldCB0YXNrJCgpOiBPYnNlcnZhYmxlPFRhc2s+O1xuXG4gICAgLyoqXG4gICAgICogU3RyZWFtIHRoYXQgZW1pdHMgZXZlcnkgdGltZSBhIGRhdGEgcmVsb2FkIGlzIHJlcXVlc3RlZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHRhc2tEYXRhUmVsb2FkUmVxdWVzdCQoKTogT2JzZXJ2YWJsZTxDaGFuZ2U+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rhc2tEYXRhUmVsb2FkUmVxdWVzdCQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG5cbiAgICBnZXQgdGFza0ZpZWxkc0luZGV4KCk6IHsgW3A6IHN0cmluZ106IFRhc2tGaWVsZHMgfSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90YXNrRmllbGRzSW5kZXg7XG4gICAgfVxuXG4gICAgc2V0IHRhc2tGaWVsZHNJbmRleCh2YWx1ZTogeyBbcDogc3RyaW5nXTogVGFza0ZpZWxkcyB9KSB7XG4gICAgICAgIHRoaXMuX3Rhc2tGaWVsZHNJbmRleCA9IHZhbHVlO1xuICAgIH1cblxuICAgIGdldCByZWZlcmVuY2VkVGFza0FuZENhc2VJZHMoKTogeyBbcDogc3RyaW5nXTogQXJyYXk8c3RyaW5nPiB9IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZmVyZW5jZWRUYXNrQW5kQ2FzZUlkcztcbiAgICB9XG5cbiAgICBzZXQgcmVmZXJlbmNlZFRhc2tBbmRDYXNlSWRzKHZhbHVlOiB7IFtwOiBzdHJpbmddOiBBcnJheTxzdHJpbmc+IH0pIHtcbiAgICAgICAgdGhpcy5fcmVmZXJlbmNlZFRhc2tBbmRDYXNlSWRzID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcGFuZWwgdGhhdCB0aGUgdGFzayBjb250ZW50IGlzIGNvbnRhaW5lZCBpbiBpcyBjdXJyZW50bHkgZXhwYW5kaW5nLlxuICAgICAqXG4gICAgICogSWYgdGhlIHRhc2sgY29udGVudCBpcyBub3QgY29udGFpbmVkIGluIGEgcGFuZWwsIGBpc0V4cGFuZGluZ2Agd2lsbCBiZSBhbHdheXMgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGlzRXhwYW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNFeHBhbmRpbmckLnZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoYW5nZXMgdGhlIHN0YXRlIG9mIHRoZSB0YXNrIGNvbnRlbnQgdG8gYGV4cGFuZGluZ2AuXG4gICAgICovXG4gICAgcHVibGljIGV4cGFuc2lvblN0YXJ0ZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2lzRXhwYW5kaW5nJC5uZXh0KHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoYW5nZXMgdGhlIHN0YXRlIG9mIHRoZSB0YXNrIGNvbnRlbnQgdG8gYG5vdCBleHBhbmRpbmdgLlxuICAgICAqL1xuICAgIHB1YmxpYyBleHBhbnNpb25GaW5pc2hlZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5faXNFeHBhbmRpbmckLm5leHQoZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB0aGUgdmFsaWRpdHkgb2YgYWxsIGRhdGEgZmllbGRzIGluIHRoZSBtYW5hZ2VkIHtAbGluayBUYXNrfS5cbiAgICAgKlxuICAgICAqIElmIHNvbWUgb2YgdGhlIGZpZWxkcyBhcmUgaW52YWxpZCB0b3VjaGVzIHRoZW0gc28gdGhlaXIgdmFsaWRhdGlvbiBlcnJvcnMgd2lsbCBhcHBlYXIgKGlmIHNldCkuXG4gICAgICogQSBzbmFja2JhciB3aWxsIGFsc28gYmUgZGlzcGxheWVkIHRvIHRoZSB1c2VyLCBpbmZvcm1pbmcgdGhlbSBvZiB0aGUgZmFjdCB0aGF0IHRoZSBmaWVsZHMgYXJlIGludmFsaWQuXG4gICAgICogQHJldHVybnMgd2hldGhlciB0aGUgdGFzayBpcyB2YWxpZCBvciBub3RcbiAgICAgKi9cbiAgICBwdWJsaWMgdmFsaWRhdGVUYXNrRGF0YSh0YXNrSWQ/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLl90YXNrIHx8ICF0aGlzLl90YXNrLmRhdGFHcm91cHMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWxpZCA9ICF0aGlzLl90YXNrLmRhdGFHcm91cHMuZmlsdGVyKGdyb3VwID0+ICEhZ3JvdXAucGFyZW50VGFza0lkICYmICEhdGFza0lkID8gZ3JvdXAucGFyZW50VGFza0lkID09PSB0YXNrSWQgOiB0cnVlKS5zb21lKGdyb3VwID0+IGdyb3VwLmZpZWxkcy5zb21lKGZpZWxkID0+ICFmaWVsZC52YWxpZCAmJiAhZmllbGQuZGlzYWJsZWQpKTtcbiAgICAgICAgY29uc3QgdmFsaWREaXNhYmxlZCA9ICF0aGlzLl90YXNrLmRhdGFHcm91cHMuZmlsdGVyKGdyb3VwID0+ICEhZ3JvdXAucGFyZW50VGFza0lkICYmICEhdGFza0lkID8gZ3JvdXAucGFyZW50VGFza0lkID09PSB0YXNrSWQgOiB0cnVlKS5zb21lKGdyb3VwID0+IGdyb3VwLmZpZWxkcy5zb21lKGZpZWxkID0+ICFmaWVsZC52YWxpZFJlcXVpcmVkICYmIGZpZWxkLmRpc2FibGVkKSk7XG4gICAgICAgIGlmICghdmFsaWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NuYWNrQmFyU2VydmljZS5vcGVuRXJyb3JTbmFja0Jhcih0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgndGFza3Muc25hY2tiYXIuaW52YWxpZERhdGEnKSk7XG4gICAgICAgICAgICB0aGlzLl90YXNrLmRhdGFHcm91cHMuZm9yRWFjaChncm91cCA9PiBncm91cC5maWVsZHMuZm9yRWFjaChmaWVsZCA9PiBmaWVsZC50b3VjaCA9IHRydWUpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXZhbGlkRGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NuYWNrQmFyU2VydmljZS5vcGVuRXJyb3JTbmFja0Jhcih0aGlzLl90cmFuc2xhdGUuaW5zdGFudCgndGFza3Muc25hY2tiYXIubWlzc2luZ1JlcXVpcmVkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWxpZCAmJiB2YWxpZERpc2FibGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmRzIGludmFsaWQgZGF0YSBvZiB0YXNrXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBhcnJheSBvZiBpbnZhbGlkIGRhdGFmaWVsZHNcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0SW52YWxpZFRhc2tEYXRhKCk6IEFycmF5PERhdGFGaWVsZDxhbnk+PiB7XG4gICAgICAgIGNvbnN0IGludmFsaWRGaWVsZHMgPSBbXTtcbiAgICAgICAgdGhpcy5fdGFzay5kYXRhR3JvdXBzLmZvckVhY2goZ3JvdXAgPT4gaW52YWxpZEZpZWxkcy5wdXNoKC4uLmdyb3VwLmZpZWxkcy5maWx0ZXIoZmllbGQgPT5cbiAgICAgICAgICAgICghZmllbGQudmFsaWQgJiYgIWZpZWxkLmRpc2FibGVkKSB8fCAoIWZpZWxkLnZhbGlkUmVxdWlyZWQgJiYgIWZpZWxkLmRpc2FibGVkKSkpKTtcbiAgICAgICAgcmV0dXJuIGludmFsaWRGaWVsZHM7XG4gICAgfVxuXG4gICAgcHVibGljIHZhbGlkYXRlRHluYW1pY0VudW1GaWVsZCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLl90YXNrIHx8ICF0aGlzLl90YXNrLmRhdGFHcm91cHMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBleGlzdHMgPSB0aGlzLl90YXNrLmRhdGFHcm91cHMuc29tZShncm91cCA9PiBncm91cC5maWVsZHMuc29tZShmaWVsZCA9PiBmaWVsZCBpbnN0YW5jZW9mIER5bmFtaWNFbnVtZXJhdGlvbkZpZWxkKSk7XG4gICAgICAgIGlmICghZXhpc3RzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdmFsaWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHRoaXMuX3Rhc2suZGF0YUdyb3Vwcykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiBncm91cC5maWVsZHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmllbGQgaW5zdGFuY2VvZiBEeW5hbWljRW51bWVyYXRpb25GaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQuY2hvaWNlcyAhPT0gdW5kZWZpbmVkICYmIGZpZWxkLmNob2ljZXMubGVuZ3RoICE9PSAwICYmIGZpZWxkLnZhbHVlICE9PSAnJyAmJiBmaWVsZC52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpZWxkLmNob2ljZXMuc29tZShjaG9pY2UgPT4gY2hvaWNlLmtleSA9PT0gZmllbGQudmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQuYmVoYXZpb3IucmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgdGhpcy5fc25hY2tCYXJTZXJ2aWNlLm9wZW5FcnJvclNuYWNrQmFyKHRoaXMuX3RyYW5zbGF0ZS5pbnN0YW50KCd0YXNrcy5zbmFja2Jhci5taXNzaW5nUmVxdWlyZWQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoYW5nZXMgdGhlIGJsb2NraW5nIHN0YXRlIG9mIGFsbCBmaWVsZHMgaW4gdGhlIG1hbmFnZWQgVGFzay5cbiAgICAgKiBAcGFyYW0gYmxvY2tpbmdTdGF0ZSB3aGV0aGVyIHRoZSBmaWVsZCBzaG91bGQgYmUgYmxvY2tlZCBvciBub3RcbiAgICAgKi9cbiAgICBwdWJsaWMgYmxvY2tGaWVsZHMoYmxvY2tpbmdTdGF0ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fdGFzayAmJiB0aGlzLl90YXNrLmRhdGFHcm91cHMpIHtcbiAgICAgICAgICAgIHRoaXMuX3Rhc2suZGF0YUdyb3Vwcy5mb3JFYWNoKGdyb3VwID0+IHtcbiAgICAgICAgICAgICAgICBncm91cC5maWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLmJsb2NrID0gYmxvY2tpbmdTdGF0ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xlYXJzIHRoZSBhc3NpZ25lZSwgc3RhcnQgZGF0ZSBhbmQgZmluaXNoIGRhdGUgZnJvbSB0aGUgbWFuYWdlZCBUYXNrLlxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGVTdGF0ZURhdGEoZXZlbnRPdXRjb21lOiBUYXNrRXZlbnRPdXRjb21lKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl90YXNrKSB7XG4gICAgICAgICAgICB0aGlzLl90YXNrLnVzZXJJZCA9IGV2ZW50T3V0Y29tZS50YXNrLnVzZXJJZDtcbiAgICAgICAgICAgIHRoaXMuX3Rhc2suc3RhcnREYXRlID0gZXZlbnRPdXRjb21lLnRhc2suc3RhcnREYXRlO1xuICAgICAgICAgICAgdGhpcy5fdGFzay5maW5pc2hEYXRlID0gZXZlbnRPdXRjb21lLnRhc2suZmluaXNoRGF0ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIHByb3BlcnRpZXMgb2YgZmllbGRzIGluIHRoZSBtYW5hZ2VkIHRhc2sgYmFzZWQgb24gYSBkZWx0YSBvZiBjaGFuZ2VzIGZyb20gcHJldmlvdXMgc3RhdGUuXG4gICAgICogQHBhcmFtIGNoRmllbGRzIG9iamVjdCBjb250YWluaW5nIHRoZSBkZWx0YSBvZiB0aGUgY2hhbmdlcyBmcm9tIHRoZSBwcmV2aW91cyBzdGF0ZVxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGVGcm9tQ2hhbmdlZEZpZWxkcyhjaEZpZWxkczogQ2hhbmdlZEZpZWxkcyk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuX3Rhc2sgfHwgIXRoaXMuX3Rhc2suZGF0YUdyb3Vwcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZyb250ZW5kQWN0aW9ucyA9IGNoRmllbGRzLnRhc2tJZCA9PT0gdGhpcy50YXNrLnN0cmluZ0lkICYmIGNoRmllbGRzW1Rhc2tDb250ZW50U2VydmljZS5GUk9OVEVORF9BQ1RJT05TX0tFWV07XG4gICAgICAgIE9iamVjdC5rZXlzKGNoRmllbGRzKS5mb3JFYWNoKGNoYW5nZWRGaWVsZCA9PiB7XG4gICAgICAgICAgICBpZiAoY2hGaWVsZHMudGFza0lkID09PSB0aGlzLl90YXNrLnN0cmluZ0lkICYmIHRoaXMuaXNGaWVsZEluVGFzayhjaEZpZWxkcy50YXNrSWQsIGNoYW5nZWRGaWVsZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZpZWxkKGNoRmllbGRzLCB0aGlzLnRhc2tGaWVsZHNJbmRleFtjaEZpZWxkcy50YXNrSWRdLmZpZWxkc1tjaGFuZ2VkRmllbGRdLCBmcm9udGVuZEFjdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghIXRoaXMuZ2V0UmVmZXJlbmNlZFRhc2tJZChjaGFuZ2VkRmllbGQsIGNoRmllbGRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRmllbGQoY2hGaWVsZHMsIHRoaXMudGFza0ZpZWxkc0luZGV4W3RoaXMuZ2V0UmVmZXJlbmNlZFRhc2tJZChjaGFuZ2VkRmllbGQsIGNoRmllbGRzKV0uZmllbGRzW2NoYW5nZWRGaWVsZF0sIGZyb250ZW5kQWN0aW9ucywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJHNob3VsZENyZWF0ZS5uZXh0KHRoaXMuX3Rhc2suZGF0YUdyb3Vwcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHVwZGF0ZUZpZWxkKGNoRmllbGRzOiBDaGFuZ2VkRmllbGRzLCBmaWVsZDogRGF0YUZpZWxkPGFueT4sIGZyb250ZW5kQWN0aW9uczogQ2hhbmdlLCByZWZlcmVuY2VkOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2ZpZWxkQ29udmVydGVyU2VydmljZS5yZXNvbHZlVHlwZShmaWVsZCkgPT09IEZpZWxkVHlwZVJlc291cmNlLlRBU0tfUkVGKSB7XG4gICAgICAgICAgICB0aGlzLl90YXNrRGF0YVJlbG9hZFJlcXVlc3QkLm5leHQoZnJvbnRlbmRBY3Rpb25zID8gZnJvbnRlbmRBY3Rpb25zIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVwZGF0ZWRGaWVsZCA9IGNoRmllbGRzW2ZpZWxkLnN0cmluZ0lkXTtcbiAgICAgICAgT2JqZWN0LmtleXModXBkYXRlZEZpZWxkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3R5cGUnOlxuICAgICAgICAgICAgICAgICAgICAvLyB0eXBlIGlzIGp1c3QgYW4gaW5mb3JtYXRpb24sIG5vdCBhbiB1cGRhdGUuIEEgZmllbGQgY2Fubm90IGNoYW5nZSBpdHMgdHlwZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIGNvbnRpbnVlIC0gdGhlIGZpZWxkIGRvZXMgbm90IG5lZWQgdXBkYXRpbmcsIHNpbmNlIG5vdGhpbmcgY2hhbmdlZFxuICAgICAgICAgICAgICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWVXaXRob3V0Q2hhbmdlKHRoaXMuX2ZpZWxkQ29udmVydGVyU2VydmljZS5mb3JtYXRWYWx1ZUZyb21CYWNrZW5kKGZpZWxkLCB1cGRhdGVkRmllbGRba2V5XSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdiZWhhdmlvcic6XG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVmZXJlbmNlZCAmJiB1cGRhdGVkRmllbGQuYmVoYXZpb3JbdGhpcy5fdGFzay50cmFuc2l0aW9uSWRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5iZWhhdmlvciA9IHVwZGF0ZWRGaWVsZC5iZWhhdmlvclt0aGlzLl90YXNrLnRyYW5zaXRpb25JZF07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVmZXJlbmNlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFza0lkID0gdGhpcy5nZXRSZWZlcmVuY2VkVGFza0lkKGZpZWxkLnN0cmluZ0lkLCBjaEZpZWxkcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXNrUmVmID0gdGhpcy5maW5kVGFza1JlZklkKHRhc2tJZCwgdGhpcy50YXNrRmllbGRzSW5kZXhbdGhpcy5fdGFzay5zdHJpbmdJZF0uZmllbGRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zaXRpb25JZCA9IHRoaXMudGFza0ZpZWxkc0luZGV4W3Rhc2tJZF0udHJhbnNpdGlvbklkO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhdHJhbnNpdGlvbklkICYmIHRyYW5zaXRpb25JZCAhPT0gJycgJiYgdXBkYXRlZEZpZWxkLmJlaGF2aW9yW3RyYW5zaXRpb25JZF0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuYmVoYXZpb3IgPSB0YXNrUmVmLmJlaGF2aW9yLmVkaXRhYmxlID8gdXBkYXRlZEZpZWxkLmJlaGF2aW9yW3RyYW5zaXRpb25JZF0gOiB0YXNrUmVmLmJlaGF2aW9yO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nob2ljZXMnOlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdDaG9pY2VzOiBBcnJheTxFbnVtZXJhdGlvbkZpZWxkVmFsdWU+ID0gW107XG4gICAgICAgICAgICAgICAgICAgIGlmICh1cGRhdGVkRmllbGQuY2hvaWNlcyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkRmllbGQuY2hvaWNlcy5mb3JFYWNoKGl0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDaG9pY2VzLnB1c2goe2tleTogaXQsIHZhbHVlOiBpdH0gYXMgRW51bWVyYXRpb25GaWVsZFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXModXBkYXRlZEZpZWxkLmNob2ljZXMpLmZvckVhY2goY2hvaWNlS2V5ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDaG9pY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGNob2ljZUtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHVwZGF0ZWRGaWVsZC5jaG9pY2VzW2Nob2ljZUtleV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGFzIEVudW1lcmF0aW9uRmllbGRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAoZmllbGQgYXMgRW51bWVyYXRpb25GaWVsZCB8IE11bHRpY2hvaWNlRmllbGQpLmNob2ljZXMgPSBuZXdDaG9pY2VzO1xuICAgICAgICAgICAgICAgICAgICAoZmllbGQgYXMgRW51bWVyYXRpb25GaWVsZCB8IE11bHRpY2hvaWNlRmllbGQpLnVwZGF0ZUNob2ljZSgpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdvcHRpb25zJzpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh1cGRhdGVkRmllbGQub3B0aW9ucykuZm9yRWFjaChvcHRpb25LZXkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3B0aW9ucy5wdXNoKHtrZXk6IG9wdGlvbktleSwgdmFsdWU6IHVwZGF0ZWRGaWVsZC5vcHRpb25zW29wdGlvbktleV19KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIChmaWVsZCBhcyBFbnVtZXJhdGlvbkZpZWxkIHwgTXVsdGljaG9pY2VGaWVsZCkuY2hvaWNlcyA9IG5ld09wdGlvbnM7XG4gICAgICAgICAgICAgICAgICAgIChmaWVsZCBhcyBFbnVtZXJhdGlvbkZpZWxkIHwgTXVsdGljaG9pY2VGaWVsZCkudXBkYXRlQ2hvaWNlKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3ZhbGlkYXRpb25zJzpcbiAgICAgICAgICAgICAgICAgICAgZmllbGQucmVwbGFjZVZhbGlkYXRpb25zKHVwZGF0ZWRGaWVsZC52YWxpZGF0aW9ucy5tYXAoaXQgPT4gKGl0IGFzIFZhbGlkYXRpb24pKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkW2tleV0gPSB1cGRhdGVkRmllbGRba2V5XTtcblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmllbGQudXBkYXRlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBpc0ZpZWxkSW5UYXNrKHRhc2tJZDogc3RyaW5nLCBjaGFuZ2VkRmllbGQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0YXNrSWRcbiAgICAgICAgICAgICYmICEhdGhpcy50YXNrRmllbGRzSW5kZXhbdGFza0lkXVxuICAgICAgICAgICAgJiYgISF0aGlzLnRhc2tGaWVsZHNJbmRleFt0YXNrSWRdLmZpZWxkc1xuICAgICAgICAgICAgJiYgISF0aGlzLnRhc2tGaWVsZHNJbmRleFt0YXNrSWRdLmZpZWxkc1tjaGFuZ2VkRmllbGRdXG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldFJlZmVyZW5jZWRUYXNrSWQoY2hhbmdlZEZpZWxkOiBzdHJpbmcsIGNoRmllbGRzOiBDaGFuZ2VkRmllbGRzKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy50YXNrRmllbGRzSW5kZXggP1xuICAgICAgICAgICAgKE9iamVjdC5rZXlzKHRoaXMudGFza0ZpZWxkc0luZGV4KS5maW5kKHRhc2tJZCA9PiB0YXNrSWQgIT09IHRoaXMudGFzay5zdHJpbmdJZCAmJiB0YXNrSWQgPT09IGNoRmllbGRzLnRhc2tJZCAmJiBPYmplY3Qua2V5cyh0aGlzLnRhc2tGaWVsZHNJbmRleFt0YXNrSWRdLmZpZWxkcyk/LmluY2x1ZGVzKGNoYW5nZWRGaWVsZCkpXG4gICAgICAgICAgICB8fCBPYmplY3Qua2V5cyh0aGlzLnRhc2tGaWVsZHNJbmRleCkuZmluZCh0YXNrSWQgPT4gdGFza0lkICE9PSB0aGlzLnRhc2suc3RyaW5nSWQgJiYgT2JqZWN0LmtleXModGhpcy50YXNrRmllbGRzSW5kZXhbdGFza0lkXS5maWVsZHMpPy5pbmNsdWRlcyhjaGFuZ2VkRmllbGQpKSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGZpbmRUYXNrUmVmSWQodGFza0lkOiBzdHJpbmcsIGZpZWxkczogeyBbZmllbGRJZDogc3RyaW5nXTogRGF0YUZpZWxkPGFueT59KTogRGF0YUZpZWxkPGFueT4ge1xuICAgICAgICBsZXQgdGFza1JlZklkID0gT2JqZWN0LnZhbHVlcyhmaWVsZHMpLmZpbmQoZiA9PiBmIGluc3RhbmNlb2YgVGFza1JlZkZpZWxkICYmIGYudmFsdWU/LmluY2x1ZGVzKHRhc2tJZCkpO1xuICAgICAgICBpZiAoIXRhc2tSZWZJZCkge1xuICAgICAgICAgICAgY29uc3QgcmVmZXJlbmNlZFRhc2tJZHMgPSBPYmplY3QudmFsdWVzKGZpZWxkcykuZmlsdGVyKGYgPT4gZiBpbnN0YW5jZW9mIFRhc2tSZWZGaWVsZCkubWFwKHRyID0+IHRyLnZhbHVlKTtcbiAgICAgICAgICAgIHJlZmVyZW5jZWRUYXNrSWRzLmZvckVhY2goaWQgPT4ge1xuICAgICAgICAgICAgICAgIHRhc2tSZWZJZCA9IHRoaXMuZmluZFRhc2tSZWZJZCh0YXNrSWQsIHRoaXMudGFza0ZpZWxkc0luZGV4W2lkXS5maWVsZHMpO1xuICAgICAgICAgICAgICAgIGlmICghIXRhc2tSZWZJZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFza1JlZklkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YXNrUmVmSWRcbiAgICB9XG59XG4iXX0=