@project-sunbird/sunbird-video-player-v9
Version:
The Video player library is 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 developmen
296 lines • 41.3 kB
JavaScript
import { EventEmitter, Injectable, Optional } from '@angular/core';
import { errorCode, errorMessage } from '@project-sunbird/sunbird-player-sdk-v9';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
import * as _ from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "../sunbird-video-player.service";
import * as i2 from "./util.service";
import * as i3 from "@angular/common/http";
import * as i4 from "@project-sunbird/sunbird-quml-player";
export class ViewerService {
constructor(videoPlayerService, utilService, http, questionCursor) {
this.videoPlayerService = videoPlayerService;
this.utilService = utilService;
this.http = http;
this.questionCursor = questionCursor;
this.endPageSeen = false;
this.timeSpent = '0:0';
this.version = '1.0';
this.playerEvent = new EventEmitter();
this.totalSeekedLength = 0;
this.visitedLength = 0;
this.sidebarMenuEvent = new EventEmitter();
this.isAvailableLocally = false;
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
this.contentMap = {};
this.playerTimeSlots = [];
this.isEndEventRaised = false;
this.playBitStartTime = 0;
this.playBitEndTime = 0;
this.PlayerLoadStartedAt = new Date().getTime();
}
initialize({ context, config, metadata }) {
this.contentName = metadata.name;
this.isAvailableLocally = metadata.isAvailableLocally;
this.streamingUrl = metadata.streamingUrl;
this.artifactUrl = metadata.artifactUrl;
this.mimeType = metadata.streamingUrl ? 'application/x-mpegURL' : metadata.mimeType;
this.artifactMimeType = metadata.mimeType;
this.isAvailableLocally = metadata.isAvailableLocally;
this.traceId = config.traceId;
this.interceptionPoints = metadata.interceptionPoints;
if (context.userData) {
const { userData: { firstName, lastName } } = context;
this.userName = firstName === lastName ? firstName : `${firstName} ${lastName}`;
}
this.metaData = {
actions: [],
volume: [],
playBackSpeeds: [],
totalDuration: 0,
muted: undefined,
currentDuration: undefined,
transcripts: []
};
this.transcripts = metadata.transcripts ? metadata.transcripts : [];
this.showDownloadPopup = false;
this.endPageSeen = false;
if (this.isAvailableLocally) {
const basePath = (metadata.streamingUrl) ? (metadata.streamingUrl) : (metadata.basePath || metadata.baseDir);
this.streamingUrl = `${basePath}/${metadata.artifactUrl}`;
this.mimeType = metadata.mimeType;
}
}
handleTranscriptsData(selectedTranscripts) {
this.metaData.transcripts = selectedTranscripts;
if (!_.isArray(this.transcripts)) {
this.raiseExceptionLog('INVALID_TRANSCRIPT_DATATYPE', 'TRANSCRIPT', new Error('Transcript data should be array'), this.traceId);
return [];
}
else {
_.forEach(this.transcripts, (value) => {
if (!(_.some(this.transcripts, { language: value.language, artifactUrl: value.artifactUrl,
languageCode: value.languageCode, identifier: value.identifier }))) {
this.raiseExceptionLog('TRANSCRIPT_DATA_MISSING', 'TRANSCRIPT', new Error('Transcript object dose not have required fields'), this.traceId);
return [];
}
else if (!_.isEmpty(selectedTranscripts) &&
(_.last(selectedTranscripts) !== 'off' && _.last(selectedTranscripts) === value.languageCode)) {
value.default = true;
}
});
}
return this.transcripts;
}
async getPlayerOptions() {
if (!this.streamingUrl) {
return [{ src: this.artifactUrl, type: this.artifactMimeType }];
}
else {
const data = await this.http.head(this.streamingUrl, { responseType: 'blob' }).toPromise().catch(error => {
// eslint-disable-next-line max-len
this.raiseExceptionLog(errorCode.streamingUrlSupport, errorMessage.streamingUrlSupport, new Error(`Streaming Url Not Supported ${this.streamingUrl}`), this.traceId);
});
if (data) {
return [{ src: this.streamingUrl, type: this.mimeType }];
}
else {
return [{ src: this.artifactUrl, type: this.artifactMimeType }];
}
}
}
getMarkers() {
if (this?.interceptionPoints?.items) {
try {
const interceptionPoints = this.interceptionPoints;
this.showScore = true;
return interceptionPoints.items.map(({ interceptionPoint, identifier, type }) => {
return { time: interceptionPoint, type, identifier, duration: 3 };
});
}
catch (error) {
console.log(error);
this.raiseExceptionLog('CPV2_CONT_INTERCEPTION_PARSE', 'error parsing the inteception points string', error, '');
this.showScore = false;
}
}
return null;
}
getQuestionSet(identifier) {
const content = this.contentMap[identifier];
if (!content) {
if (!this.questionCursor) {
return null;
}
else {
return this.questionCursor.getQuestionSet(identifier)
.pipe(map((response) => {
this.contentMap[identifier] = response.questionSet;
return this.contentMap[identifier];
}));
}
}
else {
return of(content);
}
}
preFetchContent() {
const nextMarker = this.getNextMarker();
if (nextMarker) {
const identifier = nextMarker.identifier;
this.getQuestionSet(nextMarker.identifier);
}
}
getUniqueVisitedLength() {
const uniqSecondsList = [];
for (let slot of this.playerTimeSlots) {
if (slot[0] < slot[1]) {
let sec = slot[0];
while (sec <= slot[1]) {
sec = Math.floor(sec);
if (uniqSecondsList.indexOf(sec) == -1 && sec != 0) {
uniqSecondsList.push(sec);
}
sec += 1;
}
}
}
return uniqSecondsList.length;
}
getVisitedLength() {
const secondsList = [];
for (let slot of this.playerTimeSlots) {
if (slot[0] < slot[1]) {
let sec = slot[0];
while (sec <= slot[1]) {
sec = Math.floor(sec);
if (sec != 0) {
secondsList.push(sec);
}
sec += 1;
}
}
}
return secondsList.length;
}
getNextMarker() {
const currentTime = this.playerInstance.currentTime();
const markersList = this.getMarkers();
if (!markersList) {
return null;
}
return markersList.find(marker => {
const markerTime = marker.time;
return markerTime > currentTime;
});
}
raiseStartEvent(event) {
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
const startEvent = {
eid: 'START',
ver: this.version,
edata: {
type: 'START',
mode: 'play',
duration
},
metaData: this.metaData
};
this.playerEvent.emit(startEvent);
this.videoPlayerService.start(duration);
this.PlayerLoadStartedAt = new Date().getTime();
}
calculateScore() {
this.scoreObtained = Object.values(this.interceptionResponses).reduce((acc, response) => acc + response['score'], 0);
}
raiseEndEvent(isOnPlayInterrupt = false) {
if (!this.isEndEventRaised) {
this.calculateScore();
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
const endEvent = {
eid: 'END',
ver: this.version,
edata: {
type: 'END',
currentTime: this.currentlength,
totalTime: this.totalLength,
duration
},
metaData: this.metaData
};
this.playerEvent.emit(endEvent);
if (isOnPlayInterrupt) {
this.playerTimeSlots.push([this.playBitStartTime, this.currentlength]);
}
this.uniqueVisitedLength = this.getUniqueVisitedLength();
if (this.uniqueVisitedLength > this.totalLength) {
this.uniqueVisitedLength = this.totalLength;
}
this.visitedLength = this.getVisitedLength();
this.timeSpent = this.utilService.getTimeSpentText(this.visitedLength);
this.videoPlayerService.end(duration, this.totalLength, this.currentlength, this.endPageSeen, this.totalSeekedLength, this.visitedLength, this.scoreObtained, this.uniqueVisitedLength);
this.isEndEventRaised = true;
}
}
raiseHeartBeatEvent(type, extraValues) {
if (type === 'REPLAY') {
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
this.playerTimeSlots = [];
this.playBitEndTime = 0;
this.playBitStartTime = 0;
}
const hearBeatEvent = {
eid: 'HEARTBEAT',
ver: this.version,
edata: {
type,
currentPage: 'videostage',
extra: extraValues
},
metaData: this.metaData
};
this.playerEvent.emit(hearBeatEvent);
this.videoPlayerService.heartBeat(hearBeatEvent);
const interactItems = ['PLAY', 'PAUSE', 'EXIT', 'VOLUME_CHANGE', 'DRAG',
'RATE_CHANGE', 'CLOSE_DOWNLOAD', 'DOWNLOAD', 'NAVIGATE_TO_PAGE',
'NEXT', 'OPEN_MENU', 'PREVIOUS', 'CLOSE_MENU', 'DOWNLOAD_MENU', 'DOWNLOAD_POPUP_CLOSE', 'DOWNLOAD_POPUP_CANCEL',
'SHARE', 'REPLAY', 'FORWARD', 'BACKWARD', 'FULLSCREEN', 'NEXT_CONTENT_PLAY', 'TRANSCRIPT_LANGUAGE_OFF',
'TRANSCRIPT_LANGUAGE_SELECTED', 'VIDEO_MARKER_SELECTED'
];
if (interactItems.includes(type)) {
this.videoPlayerService.interact(type.toLowerCase(), 'videostage', extraValues);
}
}
raiseImpressionEvent(pageId, cdata = {}) {
this.videoPlayerService.impression(pageId, cdata);
}
raiseExceptionLog(errorCode, errorType, stacktrace, traceId) {
const exceptionLogEvent = {
eid: 'ERROR',
edata: {
err: errorCode,
errtype: errorType,
requestid: traceId || '',
stacktrace: (stacktrace && stacktrace.toString()) || '',
}
};
this.playerEvent.emit(exceptionLogEvent);
this.videoPlayerService.error(errorCode, errorType, stacktrace);
}
/** @nocollapse */ static { this.ɵfac = function ViewerService_Factory(t) { return new (t || ViewerService)(i0.ɵɵinject(i1.SunbirdVideoPlayerService), i0.ɵɵinject(i2.UtilService), i0.ɵɵinject(i3.HttpClient), i0.ɵɵinject(i4.QuestionCursor, 8)); }; }
/** @nocollapse */ static { this.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: ViewerService, factory: ViewerService.ɵfac, providedIn: 'root' }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewerService, [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], () => [{ type: i1.SunbirdVideoPlayerService }, { type: i2.UtilService }, { type: i3.HttpClient }, { type: i4.QuestionCursor, decorators: [{
type: Optional
}] }], null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdW5iaXJkLXZpZGVvLXBsYXllci9zcmMvbGliL3NlcnZpY2VzL3ZpZXdlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUluRSxPQUFPLEVBQUUsU0FBUyxFQUFHLFlBQVksRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRWxGLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxDQUFDLE1BQU0sV0FBVyxDQUFDOzs7Ozs7QUFLL0IsTUFBTSxPQUFPLGFBQWE7SUFtQ3hCLFlBQW9CLGtCQUE2QyxFQUM3QyxXQUF3QixFQUN4QixJQUFnQixFQUNMLGNBQThCO1FBSHpDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBMkI7UUFDN0MsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNMLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQXBDdEQsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQVd0QyxzQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFFdEIsa0JBQWEsR0FBRyxDQUFDLENBQUM7UUFFbEIscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUUzQyx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFFM0IsMEJBQXFCLEdBQVEsRUFBRSxDQUFDO1FBQ2hDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsa0JB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LEVBQUU7UUFDbEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELGlCQUFpQixDQUFDLFNBQWlCLEVBQUUsU0FBaUIsRUFBRSxVQUFVLEVBQUUsT0FBTztRQUN6RSxNQUFNLGlCQUFpQixHQUFHO1lBQ3hCLEdBQUcsRUFBRSxPQUFPO1lBQ1osS0FBSyxFQUFFO2dCQUNMLEdBQUcsRUFBRSxTQUFTO2dCQUNkLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixTQUFTLEVBQUUsT0FBTyxJQUFJLEVBQUU7Z0JBQ3hCLFVBQVUsRUFBRSxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFO2FBQ3hEO1NBQ0YsQ0FBQztRQUNGLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUcsU0FBUyxFQUFHLFVBQVUsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7aUdBeFRVLGFBQWE7c0dBQWIsYUFBYSxXQUFiLGFBQWEsbUJBRlosTUFBTTs7aUZBRVAsYUFBYTtjQUh6QixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7O3NCQXVDYyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgSW5qZWN0YWJsZSwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFBsYXllckNvbmZpZywgVHJhbnNjcmlwdHMgfSBmcm9tICcuLi9wbGF5ZXJJbnRlcmZhY2VzJztcbmltcG9ydCB7IFN1bmJpcmRWaWRlb1BsYXllclNlcnZpY2UgfSBmcm9tICcuLi9zdW5iaXJkLXZpZGVvLXBsYXllci5zZXJ2aWNlJztcbmltcG9ydCB7IFV0aWxTZXJ2aWNlIH0gZnJvbSAnLi91dGlsLnNlcnZpY2UnO1xuaW1wb3J0IHsgZXJyb3JDb2RlICwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnQHByb2plY3Qtc3VuYmlyZC9zdW5iaXJkLXBsYXllci1zZGstdjknO1xuaW1wb3J0IHsgUXVlc3Rpb25DdXJzb3IgfSBmcm9tICdAcHJvamVjdC1zdW5iaXJkL3N1bmJpcmQtcXVtbC1wbGF5ZXInO1xuaW1wb3J0IHsgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoLWVzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVmlld2VyU2VydmljZSB7XG5cbiAgcHVibGljIGVuZFBhZ2VTZWVuID0gZmFsc2U7XG4gIHB1YmxpYyB0aW1lU3BlbnQgPSAnMDowJztcbiAgcHJpdmF0ZSB2ZXJzaW9uID0gJzEuMCc7XG4gIHB1YmxpYyBwbGF5ZXJFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBwdWJsaWMgY29udGVudE5hbWU6IHN0cmluZztcbiAgcHVibGljIHNob3dEb3dubG9hZFBvcHVwOiBib29sZWFuO1xuICBwdWJsaWMgc3RyZWFtaW5nVXJsOiBzdHJpbmc7XG4gIHB1YmxpYyBtaW1lVHlwZTogc3RyaW5nO1xuICBwdWJsaWMgYXJ0aWZhY3RNaW1lVHlwZTogc3RyaW5nO1xuICBwdWJsaWMgdXNlck5hbWU6IHN0cmluZztcbiAgcHVibGljIG1ldGFEYXRhOiBhbnk7XG4gIHB1YmxpYyBQbGF5ZXJMb2FkU3RhcnRlZEF0OiBudW1iZXI7XG4gIHB1YmxpYyB0b3RhbExlbmd0aDtcbiAgcHVibGljIGN1cnJlbnRsZW5ndGg7XG4gIHB1YmxpYyB0b3RhbFNlZWtlZExlbmd0aCA9IDA7XG4gIHB1YmxpYyBhcnRpZmFjdFVybDtcbiAgcHVibGljIHZpc2l0ZWRMZW5ndGggPSAwO1xuICBwdWJsaWMgdW5pcXVlVmlzaXRlZExlbmd0aDtcbiAgcHVibGljIHNpZGViYXJNZW51RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHVibGljIHRyYWNlSWQ6IHN0cmluZztcbiAgcHVibGljIGlzQXZhaWxhYmxlTG9jYWxseSA9IGZhbHNlO1xuICBwdWJsaWMgaW50ZXJjZXB0aW9uUG9pbnRzOiBhbnk7XG4gIHB1YmxpYyBpbnRlcmNlcHRpb25SZXNwb25zZXM6IGFueSA9IHt9O1xuICBwdWJsaWMgc2hvd1Njb3JlID0gZmFsc2U7XG4gIHB1YmxpYyBzY29yZU9idGFpbmVkOiBhbnkgPSAwO1xuICBwdWJsaWMgbWF4U2NvcmU6IG51bWJlcjtcbiAgcHVibGljIHBsYXllckluc3RhbmNlOiBhbnk7XG4gIHB1YmxpYyBjb250ZW50TWFwID0ge307XG4gIHB1YmxpYyBwbGF5ZXJUaW1lU2xvdHMgPSBbXTtcbiAgcHVibGljIGlzRW5kRXZlbnRSYWlzZWQgPSBmYWxzZTtcbiAgcHVibGljIHRyYW5zY3JpcHRzOiBUcmFuc2NyaXB0cztcbiAgcHVibGljIHBsYXlCaXRTdGFydFRpbWUgPSAwO1xuICBwdWJsaWMgcGxheUJpdEVuZFRpbWUgPSAwO1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHZpZGVvUGxheWVyU2VydmljZTogU3VuYmlyZFZpZGVvUGxheWVyU2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSB1dGlsU2VydmljZTogVXRpbFNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgcHVibGljIHF1ZXN0aW9uQ3Vyc29yOiBRdWVzdGlvbkN1cnNvcikge1xuICAgIHRoaXMuUGxheWVyTG9hZFN0YXJ0ZWRBdCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSh7IGNvbnRleHQsIGNvbmZpZywgbWV0YWRhdGEgfTogUGxheWVyQ29uZmlnKSB7XG4gICAgdGhpcy5jb250ZW50TmFtZSA9IG1ldGFkYXRhLm5hbWU7XG4gICAgdGhpcy5pc0F2YWlsYWJsZUxvY2FsbHkgPSBtZXRhZGF0YS5pc0F2YWlsYWJsZUxvY2FsbHk7XG4gICAgdGhpcy5zdHJlYW1pbmdVcmwgPSBtZXRhZGF0YS5zdHJlYW1pbmdVcmw7XG4gICAgdGhpcy5hcnRpZmFjdFVybCA9IG1ldGFkYXRhLmFydGlmYWN0VXJsO1xuICAgIHRoaXMubWltZVR5cGUgPSBtZXRhZGF0YS5zdHJlYW1pbmdVcmwgPyAnYXBwbGljYXRpb24veC1tcGVnVVJMJyA6IG1ldGFkYXRhLm1pbWVUeXBlO1xuICAgIHRoaXMuYXJ0aWZhY3RNaW1lVHlwZSA9IG1ldGFkYXRhLm1pbWVUeXBlO1xuICAgIHRoaXMuaXNBdmFpbGFibGVMb2NhbGx5ID0gbWV0YWRhdGEuaXNBdmFpbGFibGVMb2NhbGx5O1xuICAgIHRoaXMudHJhY2VJZCA9IGNvbmZpZy50cmFjZUlkO1xuICAgIHRoaXMuaW50ZXJjZXB0aW9uUG9pbnRzID0gbWV0YWRhdGEuaW50ZXJjZXB0aW9uUG9pbnRzO1xuICAgIGlmIChjb250ZXh0LnVzZXJEYXRhKSB7XG4gICAgICBjb25zdCB7IHVzZXJEYXRhOiB7IGZpcnN0TmFtZSwgbGFzdE5hbWUgfSB9ID0gY29udGV4dDtcbiAgICAgIHRoaXMudXNlck5hbWUgPSBmaXJzdE5hbWUgPT09IGxhc3ROYW1lID8gZmlyc3ROYW1lIDogYCR7Zmlyc3ROYW1lfSAke2xhc3ROYW1lfWA7XG4gICAgfVxuICAgIHRoaXMubWV0YURhdGEgPSB7XG4gICAgICBhY3Rpb25zOiBbXG4gICAgICBdLFxuICAgICAgdm9sdW1lOiBbXSxcbiAgICAgIHBsYXlCYWNrU3BlZWRzOiBbXSxcbiAgICAgIHRvdGFsRHVyYXRpb246IDAsXG4gICAgICBtdXRlZDogdW5kZWZpbmVkLFxuICAgICAgY3VycmVudER1cmF0aW9uOiB1bmRlZmluZWQsXG4gICAgICB0cmFuc2NyaXB0czogW11cbiAgICB9O1xuICAgIHRoaXMudHJhbnNjcmlwdHMgPSBtZXRhZGF0YS50cmFuc2NyaXB0cyA/IG1ldGFkYXRhLnRyYW5zY3JpcHRzIDogW107XG4gICAgdGhpcy5zaG93RG93bmxvYWRQb3B1cCA9IGZhbHNlO1xuICAgIHRoaXMuZW5kUGFnZVNlZW4gPSBmYWxzZTtcbiAgICBpZiAodGhpcy5pc0F2YWlsYWJsZUxvY2FsbHkpIHtcbiAgICAgIGNvbnN0IGJhc2VQYXRoID0gKG1ldGFkYXRhLnN0cmVhbWluZ1VybCkgPyAobWV0YWRhdGEuc3RyZWFtaW5nVXJsKSA6IChtZXRhZGF0YS5iYXNlUGF0aCB8fCBtZXRhZGF0YS5iYXNlRGlyKTtcbiAgICAgIHRoaXMuc3RyZWFtaW5nVXJsID0gYCR7YmFzZVBhdGh9LyR7bWV0YWRhdGEuYXJ0aWZhY3RVcmx9YDtcbiAgICAgIHRoaXMubWltZVR5cGUgPSBtZXRhZGF0YS5taW1lVHlwZTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlVHJhbnNjcmlwdHNEYXRhKHNlbGVjdGVkVHJhbnNjcmlwdHMpIHtcbiAgICB0aGlzLm1ldGFEYXRhLnRyYW5zY3JpcHRzID0gc2VsZWN0ZWRUcmFuc2NyaXB0cztcbiAgICBpZiAoIV8uaXNBcnJheSh0aGlzLnRyYW5zY3JpcHRzKSkge1xuICAgICAgdGhpcy5yYWlzZUV4Y2VwdGlvbkxvZygnSU5WQUxJRF9UUkFOU0NSSVBUX0RBVEFUWVBFJywgJ1RSQU5TQ1JJUFQnLCBuZXcgRXJyb3IoJ1RyYW5zY3JpcHQgZGF0YSBzaG91bGQgYmUgYXJyYXknKSwgdGhpcy50cmFjZUlkKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAgICBfLmZvckVhY2godGhpcy50cmFuc2NyaXB0cywgKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICghKF8uc29tZSh0aGlzLnRyYW5zY3JpcHRzLCB7IGxhbmd1YWdlOiB2YWx1ZS5sYW5ndWFnZSwgYXJ0aWZhY3RVcmw6IHZhbHVlLmFydGlmYWN0VXJsICxcbiAgICAgICAgICBsYW5ndWFnZUNvZGU6IHZhbHVlLmxhbmd1YWdlQ29kZSwgaWRlbnRpZmllcjogdmFsdWUuaWRlbnRpZmllcn0pKSkge1xuICAgICAgICAgIHRoaXMucmFpc2VFeGNlcHRpb25Mb2coJ1RSQU5TQ1JJUFRfREFUQV9NSVNTSU5HJywgJ1RSQU5TQ1JJUFQnLFxuICAgICAgICAgICBuZXcgRXJyb3IoJ1RyYW5zY3JpcHQgb2JqZWN0IGRvc2Ugbm90IGhhdmUgcmVxdWlyZWQgZmllbGRzJyksIHRoaXMudHJhY2VJZCk7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9IGVsc2UgaWYgKCFfLmlzRW1wdHkoc2VsZWN0ZWRUcmFuc2NyaXB0cykgJiZcbiAgICAgICAgICAoIF8ubGFzdChzZWxlY3RlZFRyYW5zY3JpcHRzKSAhPT0gJ29mZicgJiYgIF8ubGFzdChzZWxlY3RlZFRyYW5zY3JpcHRzKSA9PT0gdmFsdWUubGFuZ3VhZ2VDb2RlKSkge1xuICAgICAgICAgIHZhbHVlLmRlZmF1bHQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHJhbnNjcmlwdHM7XG4gIH1cbiAgYXN5bmMgZ2V0UGxheWVyT3B0aW9ucygpIHtcbiAgICBpZiAoIXRoaXMuc3RyZWFtaW5nVXJsKSB7XG4gICAgICByZXR1cm4gW3sgc3JjOiB0aGlzLmFydGlmYWN0VXJsLCB0eXBlOiB0aGlzLmFydGlmYWN0TWltZVR5cGUgfV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmh0dHAuaGVhZCh0aGlzLnN0cmVhbWluZ1VybCwgeyByZXNwb25zZVR5cGU6ICdibG9iJyB9KS50b1Byb21pc2UoKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIHRoaXMucmFpc2VFeGNlcHRpb25Mb2coZXJyb3JDb2RlLnN0cmVhbWluZ1VybFN1cHBvcnQgLCBlcnJvck1lc3NhZ2Uuc3RyZWFtaW5nVXJsU3VwcG9ydCAsIG5ldyBFcnJvcihgU3RyZWFtaW5nIFVybCBOb3QgU3VwcG9ydGVkICAke3RoaXMuc3RyZWFtaW5nVXJsfWApLCB0aGlzLnRyYWNlSWQpO1xuICAgICAgfSk7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICByZXR1cm4gW3sgc3JjOiB0aGlzLnN0cmVhbWluZ1VybCwgdHlwZTogdGhpcy5taW1lVHlwZSB9XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbeyBzcmM6IHRoaXMuYXJ0aWZhY3RVcmwsIHR5cGU6IHRoaXMuYXJ0aWZhY3RNaW1lVHlwZSB9XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXRNYXJrZXJzKCkgIHtcbiAgICBpZiAodGhpcz8uaW50ZXJjZXB0aW9uUG9pbnRzPy5pdGVtcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgaW50ZXJjZXB0aW9uUG9pbnRzID0gdGhpcy5pbnRlcmNlcHRpb25Qb2ludHM7XG4gICAgICAgIHRoaXMuc2hvd1Njb3JlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGludGVyY2VwdGlvblBvaW50cy5pdGVtcy5tYXAoKHtpbnRlcmNlcHRpb25Qb2ludCwgaWRlbnRpZmllciwgdHlwZX0pID0+IHtcbiAgICAgICAgcmV0dXJuIHsgdGltZTogaW50ZXJjZXB0aW9uUG9pbnQsIHR5cGUsIGlkZW50aWZpZXIsIGR1cmF0aW9uOiAzIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgICB0aGlzLnJhaXNlRXhjZXB0aW9uTG9nKCdDUFYyX0NPTlRfSU5URVJDRVBUSU9OX1BBUlNFJywgJ2Vycm9yIHBhcnNpbmcgdGhlIGludGVjZXB0aW9uIHBvaW50cyBzdHJpbmcnLCBlcnJvciwgJycpO1xuICAgICAgICB0aGlzLnNob3dTY29yZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG5cbiAgZ2V0UXVlc3Rpb25TZXQoaWRlbnRpZmllcikge1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmNvbnRlbnRNYXBbaWRlbnRpZmllcl07XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICBpZiAoIXRoaXMucXVlc3Rpb25DdXJzb3IpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICByZXR1cm4gdGhpcy5xdWVzdGlvbkN1cnNvci5nZXRRdWVzdGlvblNldChpZGVudGlmaWVyKVxuICAgICAucGlwZShtYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHRoaXMuY29udGVudE1hcFtpZGVudGlmaWVyXSA9IHJlc3BvbnNlLnF1ZXN0aW9uU2V0O1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50TWFwW2lkZW50aWZpZXJdO1xuICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9mKGNvbnRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByZUZldGNoQ29udGVudCgpIHtcbiAgICBjb25zdCBuZXh0TWFya2VyID0gdGhpcy5nZXROZXh0TWFya2VyKCk7XG4gICAgaWYgKG5leHRNYXJrZXIpIHtcbiAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBuZXh0TWFya2VyLmlkZW50aWZpZXI7XG4gICAgICB0aGlzLmdldFF1ZXN0aW9uU2V0KG5leHRNYXJrZXIuaWRlbnRpZmllcik7XG4gICAgfVxuICB9XG5cbiAgZ2V0VW5pcXVlVmlzaXRlZExlbmd0aCgpIHtcbiAgICBjb25zdCB1bmlxU2Vjb25kc0xpc3QgPSBbXTtcbiAgICBmb3IgKGxldCBzbG90IG9mIHRoaXMucGxheWVyVGltZVNsb3RzKSB7XG4gICAgICAgIGlmKHNsb3RbMF0gPCBzbG90WzFdKSB7XG4gICAgICAgICAgbGV0IHNlYyA9IHNsb3RbMF07XG4gICAgICAgICAgd2hpbGUgKCBzZWMgPD0gc2xvdFsxXSkge1xuICAgICAgICAgICAgc2VjID0gTWF0aC5mbG9vcihzZWMpXG4gICAgICAgICAgICBpZih1bmlxU2Vjb25kc0xpc3QuaW5kZXhPZihzZWMpID09IC0xICYmIHNlYyAhPSAwKSB7XG4gICAgICAgICAgICAgIHVuaXFTZWNvbmRzTGlzdC5wdXNoKHNlYylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlYyArPSAxXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgICAgcmV0dXJuIHVuaXFTZWNvbmRzTGlzdC5sZW5ndGg7XG4gIH1cblxuICBnZXRWaXNpdGVkTGVuZ3RoKCkge1xuICAgIGNvbnN0IHNlY29uZHNMaXN0ID0gW107XG4gICAgZm9yIChsZXQgc2xvdCBvZiB0aGlzLnBsYXllclRpbWVTbG90cykge1xuICAgICAgICBpZihzbG90WzBdIDwgc2xvdFsxXSkge1xuICAgICAgICAgIGxldCBzZWMgPSBzbG90WzBdO1xuICAgICAgICAgIHdoaWxlICggc2VjIDw9IHNsb3RbMV0pIHtcbiAgICAgICAgICAgIHNlYyA9IE1hdGguZmxvb3Ioc2VjKVxuICAgICAgICAgICAgaWYoc2VjICE9IDApIHtcbiAgICAgICAgICAgICAgc2Vjb25kc0xpc3QucHVzaChzZWMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWMgKz0gMVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAgIHJldHVybiBzZWNvbmRzTGlzdC5sZW5ndGg7XG4gIH1cblxuICBnZXROZXh0TWFya2VyKCkge1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gdGhpcy5wbGF5ZXJJbnN0YW5jZS5jdXJyZW50VGltZSgpO1xuICAgIGNvbnN0IG1hcmtlcnNMaXN0ID0gdGhpcy5nZXRNYXJrZXJzKCk7XG4gICAgaWYgKCFtYXJrZXJzTGlzdCkgeyByZXR1cm4gbnVsbDsgfVxuXG4gICAgcmV0dXJuIG1hcmtlcnNMaXN0LmZpbmQobWFya2VyID0+IHtcbiAgICAgIGNvbnN0IG1hcmtlclRpbWUgPSBtYXJrZXIudGltZTtcbiAgICAgIHJldHVybiBtYXJrZXJUaW1lID4gY3VycmVudFRpbWU7XG4gICAgfSk7XG4gIH1cblxuICByYWlzZVN0YXJ0RXZlbnQoZXZlbnQpIHtcbiAgICBjb25zdCBkdXJhdGlvbiA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gdGhpcy5QbGF5ZXJMb2FkU3RhcnRlZEF0O1xuICAgIGNvbnN0IHN0YXJ0RXZlbnQgPSB7XG4gICAgICBlaWQ6ICdTVEFSVCcsXG4gICAgICB2ZXI6IHRoaXMudmVyc2lvbixcbiAgICAgIGVkYXRhOiB7XG4gICAgICAgIHR5cGU6ICdTVEFSVCcsXG4gICAgICAgIG1vZGU6ICdwbGF5JyxcbiAgICAgICAgZHVyYXRpb25cbiAgICAgIH0sXG4gICAgICBtZXRhRGF0YTogdGhpcy5tZXRhRGF0YVxuICAgIH07XG4gICAgdGhpcy5wbGF5ZXJFdmVudC5lbWl0KHN0YXJ0RXZlbnQpO1xuICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLnN0YXJ0KGR1cmF0aW9uKTtcbiAgICB0aGlzLlBsYXllckxvYWRTdGFydGVkQXQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgfVxuXG4gIGNhbGN1bGF0ZVNjb3JlKCkge1xuICAgIHRoaXMuc2NvcmVPYnRhaW5lZCA9ICBPYmplY3QudmFsdWVzKHRoaXMuaW50ZXJjZXB0aW9uUmVzcG9uc2VzKS5yZWR1Y2UoXG4gICAgICAoYWNjLCByZXNwb25zZSkgPT4gYWNjICsgcmVzcG9uc2VbJ3Njb3JlJ10gLCAwKTtcbiAgfVxuXG4gIHJhaXNlRW5kRXZlbnQoaXNPblBsYXlJbnRlcnJ1cHQgPSBmYWxzZSkge1xuXG4gICAgaWYgKCF0aGlzLmlzRW5kRXZlbnRSYWlzZWQpIHtcbiAgICAgIHRoaXMuY2FsY3VsYXRlU2NvcmUoKTtcbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLlBsYXllckxvYWRTdGFydGVkQXQ7XG4gICAgICBjb25zdCBlbmRFdmVudCA9IHtcbiAgICAgICAgZWlkOiAnRU5EJyxcbiAgICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICAgIGVkYXRhOiB7XG4gICAgICAgICAgdHlwZTogJ0VORCcsXG4gICAgICAgICAgY3VycmVudFRpbWU6IHRoaXMuY3VycmVudGxlbmd0aCxcbiAgICAgICAgICB0b3RhbFRpbWU6IHRoaXMudG90YWxMZW5ndGgsXG4gICAgICAgICAgZHVyYXRpb25cbiAgICAgICAgfSxcbiAgICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICAgIH07XG4gICAgICB0aGlzLnBsYXllckV2ZW50LmVtaXQoZW5kRXZlbnQpO1xuICAgICAgXG4gICAgICBpZihpc09uUGxheUludGVycnVwdCkge1xuICAgICAgICB0aGlzLnBsYXllclRpbWVTbG90cy5wdXNoKFt0aGlzLnBsYXlCaXRTdGFydFRpbWUsIHRoaXMuY3VycmVudGxlbmd0aF0pO1xuICAgICAgfVxuICAgICAgdGhpcy51bmlxdWVWaXNpdGVkTGVuZ3RoID0gdGhpcy5nZXRVbmlxdWVWaXNpdGVkTGVuZ3RoKCk7XG4gICAgICBpZih0aGlzLnVuaXF1ZVZpc2l0ZWRMZW5ndGggPiB0aGlzLnRvdGFsTGVuZ3RoKSB7XG4gICAgICAgIHRoaXMudW5pcXVlVmlzaXRlZExlbmd0aCA9IHRoaXMudG90YWxMZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLnZpc2l0ZWRMZW5ndGggPSB0aGlzLmdldFZpc2l0ZWRMZW5ndGgoKTtcbiAgICAgIHRoaXMudGltZVNwZW50ID0gdGhpcy51dGlsU2VydmljZS5nZXRUaW1lU3BlbnRUZXh0KHRoaXMudmlzaXRlZExlbmd0aCk7XG4gICAgICBcbiAgICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLmVuZChcbiAgICAgICAgZHVyYXRpb24sXG4gICAgICAgIHRoaXMudG90YWxMZW5ndGgsXG4gICAgICAgIHRoaXMuY3VycmVudGxlbmd0aCxcbiAgICAgICAgdGhpcy5lbmRQYWdlU2VlbixcbiAgICAgICAgdGhpcy50b3RhbFNlZWtlZExlbmd0aCxcbiAgICAgICAgdGhpcy52aXNpdGVkTGVuZ3RoLFxuICAgICAgICB0aGlzLnNjb3JlT2J0YWluZWQsXG4gICAgICAgIHRoaXMudW5pcXVlVmlzaXRlZExlbmd0aFxuICAgICAgKTtcbiAgICAgIHRoaXMuaXNFbmRFdmVudFJhaXNlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cblxuICByYWlzZUhlYXJ0QmVhdEV2ZW50KHR5cGU6IHN0cmluZywgZXh0cmFWYWx1ZXM/KSB7XG4gICAgaWYgKHR5cGUgPT09ICdSRVBMQVknKSB7XG4gICAgICB0aGlzLmludGVyY2VwdGlvblJlc3BvbnNlcyA9IHt9O1xuICAgICAgdGhpcy5zaG93U2NvcmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2NvcmVPYnRhaW5lZCA9IDA7XG4gICAgICB0aGlzLnBsYXllclRpbWVTbG90cyA9IFtdO1xuICAgICAgdGhpcy5wbGF5Qml0RW5kVGltZSA9IDA7XG4gICAgICB0aGlzLnBsYXlCaXRTdGFydFRpbWUgPSAwO1xuICAgIH1cbiAgICBjb25zdCBoZWFyQmVhdEV2ZW50ID0ge1xuICAgICAgZWlkOiAnSEVBUlRCRUFUJyxcbiAgICAgIHZlcjogdGhpcy52ZXJzaW9uLFxuICAgICAgZWRhdGE6IHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgY3VycmVudFBhZ2U6ICd2aWRlb3N0YWdlJyxcbiAgICAgICAgZXh0cmE6IGV4dHJhVmFsdWVzXG4gICAgICB9LFxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICB9O1xuICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChoZWFyQmVhdEV2ZW50KTtcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5oZWFydEJlYXQoaGVhckJlYXRFdmVudCk7XG4gICAgY29uc3QgaW50ZXJhY3RJdGVtcyA9IFsnUExBWScsICdQQVVTRScsICdFWElUJywgJ1ZPTFVNRV9DSEFOR0UnLCAnRFJBRycsXG4gICAgICAnUkFURV9DSEFOR0UnLCAnQ0xPU0VfRE9XTkxPQUQnLCAnRE9XTkxPQUQnLCAnTkFWSUdBVEVfVE9fUEFHRScsXG4gICAgICAnTkVYVCcsICdPUEVOX01FTlUnLCAnUFJFVklPVVMnLCAnQ0xPU0VfTUVOVScsICdET1dOTE9BRF9NRU5VJywgJ0RPV05MT0FEX1BPUFVQX0NMT1NFJywgJ0RPV05MT0FEX1BPUFVQX0NBTkNFTCcsXG4gICAgICAnU0hBUkUnLCAnUkVQTEFZJywgJ0ZPUldBUkQnLCAnQkFDS1dBUkQnLCAnRlVMTFNDUkVFTicsICdORVhUX0NPTlRFTlRfUExBWScsICdUUkFOU0NSSVBUX0xBTkdVQUdFX09GRicsXG4gICAgICAnVFJBTlNDUklQVF9MQU5HVUFHRV9TRUxFQ1RFRCcsICdWSURFT19NQVJLRVJfU0VMRUNURUQnXG4gICAgXTtcbiAgICBpZiAoaW50ZXJhY3RJdGVtcy5pbmNsdWRlcyh0eXBlKSkge1xuICAgICAgdGhpcy52aWRlb1BsYXllclNlcnZpY2UuaW50ZXJhY3QodHlwZS50b0xvd2VyQ2FzZSgpLCAndmlkZW9zdGFnZScsIGV4dHJhVmFsdWVzKTtcbiAgICB9XG4gIH1cblxuICByYWlzZUltcHJlc3Npb25FdmVudChwYWdlSWQ6IHN0cmluZywgY2RhdGE6IGFueSA9IHt9KSB7XG4gICAgdGhpcy52aWRlb1BsYXllclNlcnZpY2UuaW1wcmVzc2lvbihwYWdlSWQsIGNkYXRhKTtcbiAgfVxuXG4gIHJhaXNlRXhjZXB0aW9uTG9nKGVycm9yQ29kZTogc3RyaW5nLCBlcnJvclR5cGU6IHN0cmluZywgc3RhY2t0cmFjZSwgdHJhY2VJZCkge1xuICAgIGNvbnN0IGV4Y2VwdGlvbkxvZ0V2ZW50ID0ge1xuICAgICAgZWlkOiAnRVJST1InLFxuICAgICAgZWRhdGE6IHtcbiAgICAgICAgZXJyOiBlcnJvckNvZGUsXG4gICAgICAgIGVycnR5cGU6IGVycm9yVHlwZSxcbiAgICAgICAgcmVxdWVzdGlkOiB0cmFjZUlkIHx8ICcnLFxuICAgICAgICBzdGFja3RyYWNlOiAoc3RhY2t0cmFjZSAmJiBzdGFja3RyYWNlLnRvU3RyaW5nKCkpIHx8ICcnLFxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5wbGF5ZXJFdmVudC5lbWl0KGV4Y2VwdGlvbkxvZ0V2ZW50KTtcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5lcnJvcihlcnJvckNvZGUgLCBlcnJvclR5cGUgLCBzdGFja3RyYWNlKTtcbiAgfVxuXG59XG4iXX0=