UNPKG

@tekdi/sunbird-quml-player

Version:

The QuML player library components are powered by Angular. This player is primarily designed to be used on Sunbird consumption platforms (mobile app, web portal, offline desktop app) to drive reusability and maintainability, hence reducing the redundant d

321 lines 45.4 kB
import { EventEmitter, Injectable } from '@angular/core'; import { eventName, TelemetryType } from '../../telemetry-constants'; import * as _ from 'lodash-es'; import { forkJoin, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../../quml-library.service"; import * as i2 from "../../util-service"; import * as i3 from "../../quml-question-cursor.service"; import * as i4 from "../transformation-service/transformation.service"; export class ViewerService { constructor(qumlLibraryService, utilService, questionCursor, transformationService) { this.qumlLibraryService = qumlLibraryService; this.utilService = utilService; this.questionCursor = questionCursor; this.transformationService = transformationService; this.qumlPlayerEvent = new EventEmitter(); this.qumlQuestionEvent = new EventEmitter(); this.version = '1.0'; this.timeSpent = '0:0'; this.isAvailableLocally = false; this.isSectionsAvailable = false; this.sectionQuestions = []; } initialize(config, threshold, questionIds, parentConfig) { this.qumlLibraryService.initializeTelemetry(config, parentConfig); this.identifiers = _.cloneDeep(questionIds); this.parentIdentifier = config.metadata.identifier; this.threshold = threshold; this.rotation = 0; this.totalNumberOfQuestions = config.metadata.childNodes.length || 0; this.qumlPlayerStartTime = this.qumlPlayerLastPageTime = new Date().getTime(); this.currentQuestionIndex = 1; this.contentName = config.metadata.name; this.isAvailableLocally = parentConfig.isAvailableLocally; this.isSectionsAvailable = parentConfig?.isSectionsAvailable; this.src = config.metadata.artifactUrl || ''; this.questionSetId = config.metadata.identifier; /* istanbul ignore else */ if (config?.context?.userData) { const firstName = config.context.userData?.firstName ?? ''; const lastName = config.context.userData?.lastName ?? ''; this.userName = firstName + ' ' + lastName; } this.metaData = { pagesHistory: [], totalPages: 0, duration: 0, rotation: [], progressBar: [], questions: [], questionIds: [], lastQuestionId: '', }; this.loadingProgress = 0; this.endPageSeen = false; } raiseStartEvent(currentQuestionIndex) { this.currentQuestionIndex = currentQuestionIndex; const duration = new Date().getTime() - this.qumlPlayerStartTime; const startEvent = { eid: 'START', ver: this.version, edata: { type: 'START', currentIndex: this.currentQuestionIndex, duration }, metaData: this.metaData }; this.qumlPlayerEvent.emit(startEvent); this.qumlPlayerLastPageTime = this.qumlPlayerStartTime = new Date().getTime(); this.qumlLibraryService.start(duration); } raiseEndEvent(currentQuestionIndex, endPageSeen, score) { this.metaData.questions = this.sectionQuestions; const duration = new Date().getTime() - this.qumlPlayerStartTime; const endEvent = { eid: 'END', ver: this.version, edata: { type: 'END', currentPage: currentQuestionIndex, totalPages: this.totalNumberOfQuestions, duration }, metaData: this.metaData }; this.qumlPlayerEvent.emit(endEvent); this.timeSpent = this.utilService.getTimeSpentText(this.qumlPlayerStartTime); this.qumlLibraryService.end(duration, currentQuestionIndex, this.totalNumberOfQuestions, this.totalNumberOfQuestions, endPageSeen, score); } raiseHeartBeatEvent(type, telemetryType, pageId, nextContentId) { const hearBeatEvent = { eid: 'HEARTBEAT', ver: this.version, edata: { type, questionIndex: this.currentQuestionIndex, }, metaData: this.metaData }; if (type === eventName.nextContentPlay && nextContentId) { hearBeatEvent.edata.nextContentId = nextContentId; } if (this.isSectionsAvailable) { hearBeatEvent.edata.sectionId = this.questionSetId; } this.qumlPlayerEvent.emit(hearBeatEvent); if (TelemetryType.interact === telemetryType) { this.qumlLibraryService.interact(type.toLowerCase(), pageId); } else if (TelemetryType.impression === telemetryType) { this.qumlLibraryService.impression(pageId); } } raiseAssesEvent(questionData, index, pass, score, resValues, duration) { const assessEvent = { item: questionData, index: index, pass: pass, score: score, resvalues: resValues, duration: duration }; this.qumlPlayerEvent.emit(assessEvent); this.qumlLibraryService.startAssesEvent(assessEvent); } raiseResponseEvent(identifier, qType, optionSelected) { const responseEvent = { target: { id: identifier, ver: this.version, type: qType }, values: [{ optionSelected }] }; this.qumlPlayerEvent.emit(responseEvent); this.qumlLibraryService.response(identifier, this.version, qType, optionSelected); } raiseSummaryEvent(currentQuestionIndex, endpageseen, score, summaryObj) { let timespent = new Date().getTime() - this.qumlPlayerStartTime; timespent = Number(((timespent % 60000) / 1000).toFixed(2)); const eData = { type: "content", mode: "play", starttime: this.qumlPlayerStartTime, endtime: new Date().getTime(), timespent, pageviews: this.totalNumberOfQuestions, interactions: summaryObj.correct + summaryObj.wrong + summaryObj.partial, extra: [{ id: "progress", value: ((currentQuestionIndex / this.totalNumberOfQuestions) * 100).toFixed(0).toString() }, { id: "endpageseen", value: endpageseen.toString() }, { id: "score", value: score.toString() }, { id: "correct", value: summaryObj.correct.toString() }, { id: "incorrect", value: summaryObj.wrong.toString() }, { id: "partial", value: summaryObj.partial.toString() }, { id: "skipped", value: summaryObj.skipped.toString() }] }; const summaryEvent = { eid: 'QUML_SUMMARY', ver: this.version, edata: eData, metaData: this.metaData }; this.qumlPlayerEvent.emit(summaryEvent); this.qumlLibraryService.summary(eData); } raiseExceptionLog(errorCode, errorType, stacktrace, traceId) { const exceptionLogEvent = { eid: "ERROR", edata: { err: errorCode, errtype: errorType, requestid: traceId || '', stacktrace: stacktrace || '', } }; this.qumlPlayerEvent.emit(exceptionLogEvent); this.qumlLibraryService.error(stacktrace, { err: errorCode, errtype: errorType }); } getSectionQuestionData(sectionChildren, questionIdArr) { const availableQuestions = []; let questionsIdNotHavingCompleteData = []; if (_.isEmpty(sectionChildren)) { questionsIdNotHavingCompleteData = questionIdArr; } else { const foundQuestions = sectionChildren.filter(child => questionIdArr.includes(child.identifier)); for (const question of foundQuestions) { if (_.has(question, 'body')) { availableQuestions.push(question); } else { questionsIdNotHavingCompleteData.push(question.identifier); } } } if (!_.isEmpty(questionsIdNotHavingCompleteData)) { return this.fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData); } else { const allQuestions$ = of({ questions: availableQuestions, count: availableQuestions.length }); return allQuestions$; } } fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData) { return this.questionCursor.getQuestions(questionsIdNotHavingCompleteData, this.parentIdentifier).pipe(switchMap((questionData) => { const fetchedQuestions = questionData.questions; const allQuestions = _.concat(availableQuestions, fetchedQuestions); return of({ questions: allQuestions, count: allQuestions.length }); })); } getQuestions(currentIndex, index) { const sectionChildren = this.sectionConfig?.metadata?.children; let indentifersForQuestions; if (currentIndex !== undefined && index) { indentifersForQuestions = this.identifiers.splice(currentIndex, index); } else if (!currentIndex && !index) { indentifersForQuestions = this.identifiers.splice(0, this.threshold); } if (!_.isEmpty(indentifersForQuestions)) { let requests; const chunkArray = _.chunk(indentifersForQuestions, 10); _.forEach(chunkArray, (value) => { requests = this.getSectionQuestionData(sectionChildren, value); }); forkJoin(requests).subscribe(questions => { _.forEach(questions, (value) => { const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(value); this.qumlQuestionEvent.emit(transformedquestionsList); }); }, (error) => { this.qumlQuestionEvent.emit({ error: error }); }); } } getQuestion() { const sectionChildren = this.sectionConfig?.metadata?.children; if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); const fetchedQuestion = _.find(sectionChildren, (question) => _.includes(questionIdentifier, question.identifier)); if (_.has(fetchedQuestion, 'body')) { const fetchedQuestionData = { questions: [fetchedQuestion], count: 1 }; const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); this.qumlQuestionEvent.emit(transformedquestionsList); } else { this.questionCursor.getQuestion(questionIdentifier[0]).subscribe((question) => { const fetchedQuestionData = question; const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); this.qumlQuestionEvent.emit(transformedquestionsList); }, (error) => { this.qumlQuestionEvent.emit({ error: error }); }); } } } generateMaxAttemptEvents(currentattempt, maxLimitExceeded, isLastAttempt) { return { eid: 'exdata', ver: this.version, edata: { type: 'exdata', currentattempt, maxLimitExceeded, isLastAttempt }, metaData: this.metaData }; } updateSectionQuestions(id, questions) { const index = this.sectionQuestions.findIndex(section => section.id === id); if (index > -1) { this.sectionQuestions[index].questions = questions; } else { this.sectionQuestions.push({ id, questions }); } } getSectionQuestions(id) { return this.sectionQuestions.find(section => section.id === id)?.questions || []; } pauseVideo() { const videoElements = Array.from(document.getElementsByTagName('video')); videoElements.forEach((element) => element.pause()); const audioElements = Array.from(document.getElementsByTagName('audio')); audioElements.forEach((element) => element.pause()); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewerService, deps: [{ token: i1.QumlLibraryService }, { token: i2.UtilService }, { token: i3.QuestionCursor }, { token: i4.TransformationService }], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewerService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewerService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i1.QumlLibraryService }, { type: i2.UtilService }, { type: i3.QuestionCursor }, { type: i4.TransformationService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9xdW1sLWxpYnJhcnkvc3JjL2xpYi9zZXJ2aWNlcy92aWV3ZXItc2VydmljZS92aWV3ZXItc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUt6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXJFLE9BQU8sS0FBSyxDQUFDLE1BQU0sV0FBVyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBSzNDLE1BQU0sT0FBTyxhQUFhO0lBeUJ4QixZQUNTLGtCQUFzQyxFQUN0QyxXQUF3QixFQUN4QixjQUE4QixFQUM5QixxQkFBNEM7UUFINUMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQTVCOUMsb0JBQWUsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQzFDLHNCQUFpQixHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFVbkQsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBTWxCLHVCQUFrQixHQUFHLEtBQUssQ0FBQztRQUMzQix3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFHNUIscUJBQWdCLEdBQUcsRUFBRSxDQUFDO0lBT2xCLENBQUM7SUFFTCxVQUFVLENBQUMsTUFBd0IsRUFBRSxTQUFpQixFQUFFLFdBQXFCLEVBQUUsWUFBMkI7UUFDeEcs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LENBQThCLENBQUMsQ0FBQztRQUN0RyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBeUIsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDeEUsQ0FBQztrSUFuVlUsYUFBYTtzSUFBYixhQUFhLGNBRlosTUFBTTs7NEZBRVAsYUFBYTtrQkFIekIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFdmVudEVtaXR0ZXIsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElQYXJlbnRDb25maWcsIFF1bWxQbGF5ZXJDb25maWcgfSBmcm9tICcuLi8uLi9xdW1sLWxpYnJhcnktaW50ZXJmYWNlJztcbmltcG9ydCB7IFF1bWxMaWJyYXJ5U2VydmljZSB9IGZyb20gJy4uLy4uL3F1bWwtbGlicmFyeS5zZXJ2aWNlJztcbmltcG9ydCB7IFV0aWxTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vdXRpbC1zZXJ2aWNlJztcbmltcG9ydCB7IFRyYW5zZm9ybWF0aW9uU2VydmljZSB9IGZyb20gJy4uL3RyYW5zZm9ybWF0aW9uLXNlcnZpY2UvdHJhbnNmb3JtYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBldmVudE5hbWUsIFRlbGVtZXRyeVR5cGUgfSBmcm9tICcuLi8uLi90ZWxlbWV0cnktY29uc3RhbnRzJztcbmltcG9ydCB7IFF1ZXN0aW9uQ3Vyc29yIH0gZnJvbSAnLi4vLi4vcXVtbC1xdWVzdGlvbi1jdXJzb3Iuc2VydmljZSc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBmb3JrSm9pbiwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVmlld2VyU2VydmljZSB7XG4gIHB1YmxpYyBxdW1sUGxheWVyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHVibGljIHF1bWxRdWVzdGlvbkV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIHpvb206IHN0cmluZztcbiAgcm90YXRpb246IG51bWJlcjtcbiAgcXVtbFBsYXllclN0YXJ0VGltZTogbnVtYmVyO1xuICBxdW1sUGxheWVyTGFzdFBhZ2VUaW1lOiBudW1iZXI7XG4gIHRvdGFsTnVtYmVyT2ZRdWVzdGlvbnM6IG51bWJlcjtcbiAgY3VycmVudFF1ZXN0aW9uSW5kZXg6IG51bWJlcjtcbiAgY29udGVudE5hbWU6IHN0cmluZztcbiAgc3JjOiBzdHJpbmc7XG4gIHVzZXJOYW1lOiBzdHJpbmc7XG4gIHZlcnNpb24gPSAnMS4wJztcbiAgdGltZVNwZW50ID0gJzA6MCc7XG4gIG1ldGFEYXRhOiBhbnk7XG4gIGxvYWRpbmdQcm9ncmVzczogbnVtYmVyO1xuICBlbmRQYWdlU2VlbjogYm9vbGVhbjtcbiAgaWRlbnRpZmllcnM6IGFueTtcbiAgdGhyZXNob2xkOiBudW1iZXI7XG4gIGlzQXZhaWxhYmxlTG9jYWxseSA9IGZhbHNlO1xuICBpc1NlY3Rpb25zQXZhaWxhYmxlID0gZmFsc2U7XG4gIHF1ZXN0aW9uU2V0SWQ6IHN0cmluZztcbiAgcGFyZW50SWRlbnRpZmllcjogc3RyaW5nO1xuICBzZWN0aW9uUXVlc3Rpb25zID0gW107XG4gIHNlY3Rpb25Db25maWc6YW55O1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcXVtbExpYnJhcnlTZXJ2aWNlOiBRdW1sTGlicmFyeVNlcnZpY2UsXG4gICAgcHVibGljIHV0aWxTZXJ2aWNlOiBVdGlsU2VydmljZSxcbiAgICBwdWJsaWMgcXVlc3Rpb25DdXJzb3I6IFF1ZXN0aW9uQ3Vyc29yLFxuICAgIHB1YmxpYyB0cmFuc2Zvcm1hdGlvblNlcnZpY2U6IFRyYW5zZm9ybWF0aW9uU2VydmljZVxuICApIHsgfVxuXG4gIGluaXRpYWxpemUoY29uZmlnOiBRdW1sUGxheWVyQ29uZmlnLCB0aHJlc2hvbGQ6IG51bWJlciwgcXVlc3Rpb25JZHM6IHN0cmluZ1tdLCBwYXJlbnRDb25maWc6IElQYXJlbnRDb25maWcpIHtcbiAgICB0aGlzLnF1bWxMaWJyYXJ5U2VydmljZS5pbml0aWFsaXplVGVsZW1ldHJ5KGNvbmZpZywgcGFyZW50Q29uZmlnKTtcbiAgICB0aGlzLmlkZW50aWZpZXJzID0gXy5jbG9uZURlZXAocXVlc3Rpb25JZHMpO1xuICAgIHRoaXMucGFyZW50SWRlbnRpZmllciA9IGNvbmZpZy5tZXRhZGF0YS5pZGVudGlmaWVyO1xuICAgIHRoaXMudGhyZXNob2xkID0gdGhyZXNob2xkO1xuICAgIHRoaXMucm90YXRpb24gPSAwO1xuICAgIHRoaXMudG90YWxOdW1iZXJPZlF1ZXN0aW9ucyA9IGNvbmZpZy5tZXRhZGF0YS5jaGlsZE5vZGVzLmxlbmd0aCB8fCAwO1xuICAgIHRoaXMucXVtbFBsYXllclN0YXJ0VGltZSA9IHRoaXMucXVtbFBsYXllckxhc3RQYWdlVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIHRoaXMuY3VycmVudFF1ZXN0aW9uSW5kZXggPSAxO1xuICAgIHRoaXMuY29udGVudE5hbWUgPSBjb25maWcubWV0YWRhdGEubmFtZTtcbiAgICB0aGlzLmlzQXZhaWxhYmxlTG9jYWxseSA9IHBhcmVudENvbmZpZy5pc0F2YWlsYWJsZUxvY2FsbHk7XG4gICAgdGhpcy5pc1NlY3Rpb25zQXZhaWxhYmxlID0gcGFyZW50Q29uZmlnPy5pc1NlY3Rpb25zQXZhaWxhYmxlO1xuICAgIHRoaXMuc3JjID0gY29uZmlnLm1ldGFkYXRhLmFydGlmYWN0VXJsIHx8ICcnO1xuICAgIHRoaXMucXVlc3Rpb25TZXRJZCA9IGNvbmZpZy5tZXRhZGF0YS5pZGVudGlmaWVyO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoY29uZmlnPy5jb250ZXh0Py51c2VyRGF0YSkge1xuICAgICAgY29uc3QgZmlyc3ROYW1lID0gY29uZmlnLmNvbnRleHQudXNlckRhdGE/LmZpcnN0TmFtZSA/PyAnJztcbiAgICAgIGNvbnN0IGxhc3ROYW1lID0gY29uZmlnLmNvbnRleHQudXNlckRhdGE/Lmxhc3ROYW1lID8/ICcnO1xuICAgICAgdGhpcy51c2VyTmFtZSA9IGZpcnN0TmFtZSArICcgJyArIGxhc3ROYW1lO1xuICAgIH1cbiAgICB0aGlzLm1ldGFEYXRhID0ge1xuICAgICAgcGFnZXNIaXN0b3J5OiBbXSxcbiAgICAgIHRvdGFsUGFnZXM6IDAsXG4gICAgICBkdXJhdGlvbjogMCxcbiAgICAgIHJvdGF0aW9uOiBbXSxcbiAgICAgIHByb2dyZXNzQmFyOiBbXSxcbiAgICAgIHF1ZXN0aW9uczogW10sXG4gICAgICBxdWVzdGlvbklkczogW10sXG4gICAgICBsYXN0UXVlc3Rpb25JZDogJycsXG4gICAgfTtcbiAgICB0aGlzLmxvYWRpbmdQcm9ncmVzcyA9IDA7XG4gICAgdGhpcy5lbmRQYWdlU2VlbiA9IGZhbHNlO1xuICB9XG5cbiAgcmFpc2VTdGFydEV2ZW50KGN1cnJlbnRRdWVzdGlvbkluZGV4KSB7XG4gICAgdGhpcy5jdXJyZW50UXVlc3Rpb25JbmRleCA9IGN1cnJlbnRRdWVzdGlvbkluZGV4O1xuICAgIGNvbnN0IGR1cmF0aW9uID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLnF1bWxQbGF5ZXJTdGFydFRpbWU7XG4gICAgY29uc3Qgc3RhcnRFdmVudDogYW55ID0ge1xuICAgICAgZWlkOiAnU1RBUlQnLFxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICBlZGF0YToge1xuICAgICAgICB0eXBlOiAnU1RBUlQnLFxuICAgICAgICBjdXJyZW50SW5kZXg6IHRoaXMuY3VycmVudFF1ZXN0aW9uSW5kZXgsXG4gICAgICAgIGR1cmF0aW9uXG4gICAgICB9LFxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICB9O1xuXG4gICAgdGhpcy5xdW1sUGxheWVyRXZlbnQuZW1pdChzdGFydEV2ZW50KTtcbiAgICB0aGlzLnF1bWxQbGF5ZXJMYXN0UGFnZVRpbWUgPSB0aGlzLnF1bWxQbGF5ZXJTdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICB0aGlzLnF1bWxMaWJyYXJ5U2VydmljZS5zdGFydChkdXJhdGlvbik7XG4gIH1cblxuICByYWlzZUVuZEV2ZW50KGN1cnJlbnRRdWVzdGlvbkluZGV4LCBlbmRQYWdlU2Vlbiwgc2NvcmUpIHtcbiAgICB0aGlzLm1ldGFEYXRhLnF1ZXN0aW9ucyA9IHRoaXMuc2VjdGlvblF1ZXN0aW9ucztcbiAgICBjb25zdCBkdXJhdGlvbiA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gdGhpcy5xdW1sUGxheWVyU3RhcnRUaW1lO1xuICAgIGNvbnN0IGVuZEV2ZW50OiBhbnkgPSB7XG4gICAgICBlaWQ6ICdFTkQnLFxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICBlZGF0YToge1xuICAgICAgICB0eXBlOiAnRU5EJyxcbiAgICAgICAgY3VycmVudFBhZ2U6IGN1cnJlbnRRdWVzdGlvbkluZGV4LFxuICAgICAgICB0b3RhbFBhZ2VzOiB0aGlzLnRvdGFsTnVtYmVyT2ZRdWVzdGlvbnMsXG4gICAgICAgIGR1cmF0aW9uXG4gICAgICB9LFxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICB9O1xuXG4gICAgdGhpcy5xdW1sUGxheWVyRXZlbnQuZW1pdChlbmRFdmVudCk7XG4gICAgdGhpcy50aW1lU3BlbnQgPSB0aGlzLnV0aWxTZXJ2aWNlLmdldFRpbWVTcGVudFRleHQodGhpcy5xdW1sUGxheWVyU3RhcnRUaW1lKTtcbiAgICB0aGlzLnF1bWxMaWJyYXJ5U2VydmljZS5lbmQoZHVyYXRpb24sIGN1cnJlbnRRdWVzdGlvbkluZGV4LCB0aGlzLnRvdGFsTnVtYmVyT2ZRdWVzdGlvbnMsIHRoaXMudG90YWxOdW1iZXJPZlF1ZXN0aW9ucywgZW5kUGFnZVNlZW4sIHNjb3JlKTtcbiAgfVxuXG4gIHJhaXNlSGVhcnRCZWF0RXZlbnQodHlwZTogc3RyaW5nLCB0ZWxlbWV0cnlUeXBlOiBzdHJpbmcsIHBhZ2VJZDogbnVtYmVyIHwgc3RyaW5nLCBuZXh0Q29udGVudElkPzogc3RyaW5nKSB7XG4gICAgY29uc3QgaGVhckJlYXRFdmVudDogYW55ID0ge1xuICAgICAgZWlkOiAnSEVBUlRCRUFUJyxcbiAgICAgIHZlcjogdGhpcy52ZXJzaW9uLFxuICAgICAgZWRhdGE6IHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgcXVlc3Rpb25JbmRleDogdGhpcy5jdXJyZW50UXVlc3Rpb25JbmRleCxcbiAgICAgIH0sXG4gICAgICBtZXRhRGF0YTogdGhpcy5tZXRhRGF0YVxuICAgIH07XG5cbiAgICBpZiAodHlwZSA9PT0gZXZlbnROYW1lLm5leHRDb250ZW50UGxheSAmJiBuZXh0Q29udGVudElkKSB7XG4gICAgICBoZWFyQmVhdEV2ZW50LmVkYXRhLm5leHRDb250ZW50SWQgPSBuZXh0Q29udGVudElkO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU2VjdGlvbnNBdmFpbGFibGUpIHtcbiAgICAgIGhlYXJCZWF0RXZlbnQuZWRhdGEuc2VjdGlvbklkID0gdGhpcy5xdWVzdGlvblNldElkO1xuICAgIH1cblxuICAgIHRoaXMucXVtbFBsYXllckV2ZW50LmVtaXQoaGVhckJlYXRFdmVudCk7XG4gICAgaWYgKFRlbGVtZXRyeVR5cGUuaW50ZXJhY3QgPT09IHRlbGVtZXRyeVR5cGUpIHtcbiAgICAgIHRoaXMucXVtbExpYnJhcnlTZXJ2aWNlLmludGVyYWN0KHR5cGUudG9Mb3dlckNhc2UoKSwgcGFnZUlkKTtcbiAgICB9IGVsc2UgaWYgKFRlbGVtZXRyeVR5cGUuaW1wcmVzc2lvbiA9PT0gdGVsZW1ldHJ5VHlwZSkge1xuICAgICAgdGhpcy5xdW1sTGlicmFyeVNlcnZpY2UuaW1wcmVzc2lvbihwYWdlSWQpO1xuICAgIH1cblxuICB9XG5cbiAgcmFpc2VBc3Nlc0V2ZW50KHF1ZXN0aW9uRGF0YSwgaW5kZXg6IG51bWJlciwgcGFzczogc3RyaW5nLCBzY29yZSwgcmVzVmFsdWVzLCBkdXJhdGlvbjogbnVtYmVyKSB7XG4gICAgY29uc3QgYXNzZXNzRXZlbnQgPSB7XG4gICAgICBpdGVtOiBxdWVzdGlvbkRhdGEsXG4gICAgICBpbmRleDogaW5kZXgsXG4gICAgICBwYXNzOiBwYXNzLFxuICAgICAgc2NvcmU6IHNjb3JlLFxuICAgICAgcmVzdmFsdWVzOiByZXNWYWx1ZXMsXG4gICAgICBkdXJhdGlvbjogZHVyYXRpb25cbiAgICB9XG4gICAgdGhpcy5xdW1sUGxheWVyRXZlbnQuZW1pdChhc3Nlc3NFdmVudCk7XG4gICAgdGhpcy5xdW1sTGlicmFyeVNlcnZpY2Uuc3RhcnRBc3Nlc0V2ZW50KGFzc2Vzc0V2ZW50KTtcbiAgfVxuXG4gIHJhaXNlUmVzcG9uc2VFdmVudChpZGVudGlmaWVyLCBxVHlwZSwgb3B0aW9uU2VsZWN0ZWQpIHtcbiAgICBjb25zdCByZXNwb25zZUV2ZW50ID0ge1xuICAgICAgdGFyZ2V0OiB7XG4gICAgICAgIGlkOiBpZGVudGlmaWVyLFxuICAgICAgICB2ZXI6IHRoaXMudmVyc2lvbixcbiAgICAgICAgdHlwZTogcVR5cGVcbiAgICAgIH0sXG4gICAgICB2YWx1ZXM6IFt7XG4gICAgICAgIG9wdGlvblNlbGVjdGVkXG4gICAgICB9XVxuICAgIH1cbiAgICB0aGlzLnF1bWxQbGF5ZXJFdmVudC5lbWl0KHJlc3BvbnNlRXZlbnQpO1xuICAgIHRoaXMucXVtbExpYnJhcnlTZXJ2aWNlLnJlc3BvbnNlKGlkZW50aWZpZXIsIHRoaXMudmVyc2lvbiwgcVR5cGUsIG9wdGlvblNlbGVjdGVkKTtcbiAgfVxuXG4gIHJhaXNlU3VtbWFyeUV2ZW50KGN1cnJlbnRRdWVzdGlvbkluZGV4LCBlbmRwYWdlc2Vlbiwgc2NvcmUsIHN1bW1hcnlPYmopIHtcbiAgICBsZXQgdGltZXNwZW50ID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLnF1bWxQbGF5ZXJTdGFydFRpbWU7XG4gICAgdGltZXNwZW50ID0gTnVtYmVyKCgodGltZXNwZW50ICUgNjAwMDApIC8gMTAwMCkudG9GaXhlZCgyKSlcbiAgICBjb25zdCBlRGF0YSA9IHtcbiAgICAgIHR5cGU6IFwiY29udGVudFwiLFxuICAgICAgbW9kZTogXCJwbGF5XCIsXG4gICAgICBzdGFydHRpbWU6IHRoaXMucXVtbFBsYXllclN0YXJ0VGltZSxcbiAgICAgIGVuZHRpbWU6IG5ldyBEYXRlKCkuZ2V0VGltZSgpLFxuICAgICAgdGltZXNwZW50LFxuICAgICAgcGFnZXZpZXdzOiB0aGlzLnRvdGFsTnVtYmVyT2ZRdWVzdGlvbnMsXG4gICAgICBpbnRlcmFjdGlvbnM6IHN1bW1hcnlPYmouY29ycmVjdCArIHN1bW1hcnlPYmoud3JvbmcgKyBzdW1tYXJ5T2JqLnBhcnRpYWwsXG4gICAgICBleHRyYTogW3tcbiAgICAgICAgaWQ6IFwicHJvZ3Jlc3NcIixcbiAgICAgICAgdmFsdWU6ICgoY3VycmVudFF1ZXN0aW9uSW5kZXggLyB0aGlzLnRvdGFsTnVtYmVyT2ZRdWVzdGlvbnMpICogMTAwKS50b0ZpeGVkKDApLnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwiZW5kcGFnZXNlZW5cIixcbiAgICAgICAgdmFsdWU6IGVuZHBhZ2VzZWVuLnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwic2NvcmVcIixcbiAgICAgICAgdmFsdWU6IHNjb3JlLnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwiY29ycmVjdFwiLFxuICAgICAgICB2YWx1ZTogc3VtbWFyeU9iai5jb3JyZWN0LnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwiaW5jb3JyZWN0XCIsXG4gICAgICAgIHZhbHVlOiBzdW1tYXJ5T2JqLndyb25nLnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwicGFydGlhbFwiLFxuICAgICAgICB2YWx1ZTogc3VtbWFyeU9iai5wYXJ0aWFsLnRvU3RyaW5nKClcbiAgICAgIH0sIHtcbiAgICAgICAgaWQ6IFwic2tpcHBlZFwiLFxuICAgICAgICB2YWx1ZTogc3VtbWFyeU9iai5za2lwcGVkLnRvU3RyaW5nKClcbiAgICAgIH1dXG4gICAgfTtcbiAgICBjb25zdCBzdW1tYXJ5RXZlbnQgPSB7XG4gICAgICBlaWQ6ICdRVU1MX1NVTU1BUlknLFxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICBlZGF0YTogZURhdGEsXG4gICAgICBtZXRhRGF0YTogdGhpcy5tZXRhRGF0YVxuICAgIH07XG4gICAgdGhpcy5xdW1sUGxheWVyRXZlbnQuZW1pdChzdW1tYXJ5RXZlbnQpO1xuICAgIHRoaXMucXVtbExpYnJhcnlTZXJ2aWNlLnN1bW1hcnkoZURhdGEpO1xuICB9XG5cbiAgcmFpc2VFeGNlcHRpb25Mb2coZXJyb3JDb2RlOiBzdHJpbmcsIGVycm9yVHlwZTogc3RyaW5nLCBzdGFja3RyYWNlLCB0cmFjZUlkKSB7XG4gICAgY29uc3QgZXhjZXB0aW9uTG9nRXZlbnQgPSB7XG4gICAgICBlaWQ6IFwiRVJST1JcIixcbiAgICAgIGVkYXRhOiB7XG4gICAgICAgIGVycjogZXJyb3JDb2RlLFxuICAgICAgICBlcnJ0eXBlOiBlcnJvclR5cGUsXG4gICAgICAgIHJlcXVlc3RpZDogdHJhY2VJZCB8fCAnJyxcbiAgICAgICAgc3RhY2t0cmFjZTogc3RhY2t0cmFjZSB8fCAnJyxcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5xdW1sUGxheWVyRXZlbnQuZW1pdChleGNlcHRpb25Mb2dFdmVudClcbiAgICB0aGlzLnF1bWxMaWJyYXJ5U2VydmljZS5lcnJvcihzdGFja3RyYWNlLCB7IGVycjogZXJyb3JDb2RlLCBlcnJ0eXBlOiBlcnJvclR5cGUgfSk7XG4gIH1cblxuICBnZXRTZWN0aW9uUXVlc3Rpb25EYXRhKHNlY3Rpb25DaGlsZHJlbiwgcXVlc3Rpb25JZEFycikge1xuICAgIGNvbnN0IGF2YWlsYWJsZVF1ZXN0aW9ucyA9IFtdO1xuICAgIGxldCBxdWVzdGlvbnNJZE5vdEhhdmluZ0NvbXBsZXRlRGF0YSA9IFtdO1xuICAgIGlmIChfLmlzRW1wdHkoc2VjdGlvbkNoaWxkcmVuKSkge1xuICAgICAgcXVlc3Rpb25zSWROb3RIYXZpbmdDb21wbGV0ZURhdGEgPSBxdWVzdGlvbklkQXJyO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmb3VuZFF1ZXN0aW9ucyA9IHNlY3Rpb25DaGlsZHJlbi5maWx0ZXIoY2hpbGQgPT4gcXVlc3Rpb25JZEFyci5pbmNsdWRlcyhjaGlsZC5pZGVudGlmaWVyKSk7XG4gICAgICBmb3IgKGNvbnN0IHF1ZXN0aW9uIG9mIGZvdW5kUXVlc3Rpb25zKSB7XG4gICAgICAgIGlmIChfLmhhcyhxdWVzdGlvbiwgJ2JvZHknKSkge1xuICAgICAgICAgIGF2YWlsYWJsZVF1ZXN0aW9ucy5wdXNoKHF1ZXN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVzdGlvbnNJZE5vdEhhdmluZ0NvbXBsZXRlRGF0YS5wdXNoKHF1ZXN0aW9uLmlkZW50aWZpZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzRW1wdHkocXVlc3Rpb25zSWROb3RIYXZpbmdDb21wbGV0ZURhdGEpKSB7XG4gICAgICByZXR1cm4gdGhpcy5mZXRjaEluY29tcGxldGVRdWVzdGlvbnNEYXRhKGF2YWlsYWJsZVF1ZXN0aW9ucywgcXVlc3Rpb25zSWROb3RIYXZpbmdDb21wbGV0ZURhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhbGxRdWVzdGlvbnMkID0gb2YoeyBxdWVzdGlvbnM6IGF2YWlsYWJsZVF1ZXN0aW9ucywgY291bnQ6IGF2YWlsYWJsZVF1ZXN0aW9ucy5sZW5ndGggfSk7XG4gICAgICByZXR1cm4gYWxsUXVlc3Rpb25zJDtcbiAgICB9XG4gIH1cblxuICBmZXRjaEluY29tcGxldGVRdWVzdGlvbnNEYXRhKGF2YWlsYWJsZVF1ZXN0aW9ucywgcXVlc3Rpb25zSWROb3RIYXZpbmdDb21wbGV0ZURhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVzdGlvbkN1cnNvci5nZXRRdWVzdGlvbnMocXVlc3Rpb25zSWROb3RIYXZpbmdDb21wbGV0ZURhdGEsIHRoaXMucGFyZW50SWRlbnRpZmllcikucGlwZShcbiAgICAgIHN3aXRjaE1hcCgocXVlc3Rpb25EYXRhOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgZmV0Y2hlZFF1ZXN0aW9ucyA9IHF1ZXN0aW9uRGF0YS5xdWVzdGlvbnM7XG4gICAgICAgIGNvbnN0IGFsbFF1ZXN0aW9ucyA9IF8uY29uY2F0KGF2YWlsYWJsZVF1ZXN0aW9ucywgZmV0Y2hlZFF1ZXN0aW9ucyk7XG4gICAgICAgIHJldHVybiBvZih7IHF1ZXN0aW9uczogYWxsUXVlc3Rpb25zLCBjb3VudDogYWxsUXVlc3Rpb25zLmxlbmd0aCB9KTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG5cbiAgZ2V0UXVlc3Rpb25zKGN1cnJlbnRJbmRleD86IG51bWJlciwgaW5kZXg/OiBudW1iZXIpIHtcbiAgICBjb25zdCBzZWN0aW9uQ2hpbGRyZW4gPSB0aGlzLnNlY3Rpb25Db25maWc/Lm1ldGFkYXRhPy5jaGlsZHJlbjtcbiAgICBsZXQgaW5kZW50aWZlcnNGb3JRdWVzdGlvbnM7XG4gICAgaWYgKGN1cnJlbnRJbmRleCAhPT0gdW5kZWZpbmVkICYmIGluZGV4KSB7XG4gICAgICBpbmRlbnRpZmVyc0ZvclF1ZXN0aW9ucyA9IHRoaXMuaWRlbnRpZmllcnMuc3BsaWNlKGN1cnJlbnRJbmRleCwgaW5kZXgpO1xuICAgIH0gZWxzZSBpZiAoIWN1cnJlbnRJbmRleCAmJiAhaW5kZXgpIHtcbiAgICAgIGluZGVudGlmZXJzRm9yUXVlc3Rpb25zID0gdGhpcy5pZGVudGlmaWVycy5zcGxpY2UoMCwgdGhpcy50aHJlc2hvbGQpO1xuICAgIH1cbiAgICBpZiAoIV8uaXNFbXB0eShpbmRlbnRpZmVyc0ZvclF1ZXN0aW9ucykpIHtcbiAgICAgIGxldCByZXF1ZXN0czogYW55O1xuICAgICAgY29uc3QgY2h1bmtBcnJheSA9IF8uY2h1bmsoaW5kZW50aWZlcnNGb3JRdWVzdGlvbnMsIDEwKTtcbiAgICAgIF8uZm9yRWFjaChjaHVua0FycmF5LCAodmFsdWUpID0+IHtcbiAgICAgICAgcmVxdWVzdHMgPSB0aGlzLmdldFNlY3Rpb25RdWVzdGlvbkRhdGEoc2VjdGlvbkNoaWxkcmVuLCB2YWx1ZSlcbiAgICAgIH0pO1xuICAgICAgZm9ya0pvaW4ocmVxdWVzdHMpLnN1YnNjcmliZShxdWVzdGlvbnMgPT4ge1xuICAgICAgICBfLmZvckVhY2gocXVlc3Rpb25zLCAodmFsdWUpID0+IHtcbiAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZHF1ZXN0aW9uc0xpc3QgPSB0aGlzLnRyYW5zZm9ybWF0aW9uU2VydmljZS5nZXRUcmFuc2Zvcm1lZFF1ZXN0aW9uTWV0YWRhdGEodmFsdWUpO1xuICAgICAgICAgIHRoaXMucXVtbFF1ZXN0aW9uRXZlbnQuZW1pdCh0cmFuc2Zvcm1lZHF1ZXN0aW9uc0xpc3QpO1xuICAgICAgICB9KTtcbiAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnF1bWxRdWVzdGlvbkV2ZW50LmVtaXQoe1xuICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UXVlc3Rpb24oKSB7XG4gICAgY29uc3Qgc2VjdGlvbkNoaWxkcmVuID0gdGhpcy5zZWN0aW9uQ29uZmlnPy5tZXRhZGF0YT8uY2hpbGRyZW47XG4gICAgaWYgKHRoaXMuaWRlbnRpZmllcnMubGVuZ3RoKSB7XG4gICAgICBsZXQgcXVlc3Rpb25JZGVudGlmaWVyID0gdGhpcy5pZGVudGlmaWVycy5zcGxpY2UoMCwgdGhpcy50aHJlc2hvbGQpO1xuICAgICAgY29uc3QgZmV0Y2hlZFF1ZXN0aW9uID0gXy5maW5kKHNlY3Rpb25DaGlsZHJlbiwgKHF1ZXN0aW9uKSA9PiBfLmluY2x1ZGVzKHF1ZXN0aW9uSWRlbnRpZmllciwgcXVlc3Rpb24uaWRlbnRpZmllcikpO1xuXG4gICAgICBpZiAoXy5oYXMoZmV0Y2hlZFF1ZXN0aW9uLCAnYm9keScpKSB7XG4gICAgICAgIGNvbnN0IGZldGNoZWRRdWVzdGlvbkRhdGEgPSB7cXVlc3Rpb25zOiBbZmV0Y2hlZFF1ZXN0aW9uXSwgY291bnQ6IDEgfTtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRxdWVzdGlvbnNMaXN0ID0gdGhpcy50cmFuc2Zvcm1hdGlvblNlcnZpY2UuZ2V0VHJhbnNmb3JtZWRRdWVzdGlvbk1ldGFkYXRhKGZldGNoZWRRdWVzdGlvbkRhdGEpO1xuICAgICAgICB0aGlzLnF1bWxRdWVzdGlvbkV2ZW50LmVtaXQodHJhbnNmb3JtZWRxdWVzdGlvbnNMaXN0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucXVlc3Rpb25DdXJzb3IuZ2V0UXVlc3Rpb24ocXVlc3Rpb25JZGVudGlmaWVyWzBdKS5zdWJzY3JpYmUoKHF1ZXN0aW9uKSA9PiB7XG4gICAgICAgICAgY29uc3QgZmV0Y2hlZFF1ZXN0aW9uRGF0YSA9IHF1ZXN0aW9uO1xuICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkcXVlc3Rpb25zTGlzdCA9IHRoaXMudHJhbnNmb3JtYXRpb25TZXJ2aWNlLmdldFRyYW5zZm9ybWVkUXVlc3Rpb25NZXRhZGF0YShmZXRjaGVkUXVlc3Rpb25EYXRhKTtcbiAgICAgICAgICB0aGlzLnF1bWxRdWVzdGlvbkV2ZW50LmVtaXQodHJhbnNmb3JtZWRxdWVzdGlvbnNMaXN0KTtcbiAgICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5xdW1sUXVlc3Rpb25FdmVudC5lbWl0KHtcbiAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZW5lcmF0ZU1heEF0dGVtcHRFdmVudHMoY3VycmVudGF0dGVtcHQ6IG51bWJlciwgbWF4TGltaXRFeGNlZWRlZDogYm9vbGVhbiwgaXNMYXN0QXR0ZW1wdDogYm9vbGVhbikge1xuICAgIHJldHVybiB7XG4gICAgICBlaWQ6ICdleGRhdGEnLFxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICBlZGF0YToge1xuICAgICAgICB0eXBlOiAnZXhkYXRhJyxcbiAgICAgICAgY3VycmVudGF0dGVtcHQsXG4gICAgICAgIG1heExpbWl0RXhjZWVkZWQsXG4gICAgICAgIGlzTGFzdEF0dGVtcHRcbiAgICAgIH0sXG4gICAgICBtZXRhRGF0YTogdGhpcy5tZXRhRGF0YVxuICAgIH07XG4gIH1cblxuICB1cGRhdGVTZWN0aW9uUXVlc3Rpb25zKGlkOiBzdHJpbmcsIHF1ZXN0aW9ucykge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5zZWN0aW9uUXVlc3Rpb25zLmZpbmRJbmRleChzZWN0aW9uID0+IHNlY3Rpb24uaWQgPT09IGlkKTtcbiAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgdGhpcy5zZWN0aW9uUXVlc3Rpb25zW2luZGV4XS5xdWVzdGlvbnMgPSBxdWVzdGlvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VjdGlvblF1ZXN0aW9ucy5wdXNoKHsgaWQsIHF1ZXN0aW9ucyB9KTtcbiAgICB9XG4gIH1cblxuICBnZXRTZWN0aW9uUXVlc3Rpb25zKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5zZWN0aW9uUXVlc3Rpb25zLmZpbmQoc2VjdGlvbiA9PiBzZWN0aW9uLmlkID09PSBpZCk/LnF1ZXN0aW9ucyB8fCBbXTtcbiAgfVxuXG4gIHBhdXNlVmlkZW8oKSB7XG4gICAgY29uc3QgdmlkZW9FbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3ZpZGVvJykgYXMgSFRNTENvbGxlY3Rpb25PZjxFbGVtZW50Pik7XG4gICAgdmlkZW9FbGVtZW50cy5mb3JFYWNoKChlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50KSA9PiBlbGVtZW50LnBhdXNlKCkpO1xuXG4gICAgY29uc3QgYXVkaW9FbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2F1ZGlvJykgYXMgSFRNTENvbGxlY3Rpb25PZjxFbGVtZW50Pik7XG4gICAgYXVkaW9FbGVtZW50cy5mb3JFYWNoKChlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50KSA9PiBlbGVtZW50LnBhdXNlKCkpO1xuICB9XG59XG4iXX0=