ngx-mat-lib
Version:
A bunch of utilities and components to use in your Angular 7+ apps!
257 lines (256 loc) • 32 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Injectable } from "@angular/core";
import { HttpResponse, HttpEventType } from "@angular/common/http";
import { XmatLib, XmatRestVerbs } from "../models/index";
import { XmatConstantsService } from "./xmat-constants.service";
import { XmatMocksListService } from "./xmat-mocks-list.service";
import { tap, switchMap } from "rxjs/operators";
import { Observable, timer } from "rxjs";
import { each } from "lodash";
export class XmatMockService {
/**
* @param {?} _xmatConstants
* @param {?} _xmatMocksList
*/
constructor(_xmatConstants, _xmatMocksList) {
this._xmatConstants = _xmatConstants;
this._xmatMocksList = _xmatMocksList;
this._defaultResponseBody = { data: void 0, message: "forbidden" };
this._fileEndings = this._xmatConstants.mocksEndings;
this._mocks = {};
this._ds = this._xmatConstants.ds;
this._fileNameSpace = this._xmatConstants.fileNameSpace;
this._mocksBaseUrl = this._xmatConstants.mocksBaseUrl;
this._paramsPlaceholder = this._xmatConstants.paramsPlaceholder;
this._qm = "?";
this._queryUrlParam = this._xmatConstants.queryUrlParam;
this._restBaseUrl = this._xmatConstants.restBaseUrl;
// Override these from extended class
this._defaultMockDelay = 2500;
this._logEnabled = true;
/** @type {?} */
const mocks = this._xmatMocksList.get();
each(mocks, (mock) => {
this._pushMockHandler(mock);
});
}
/**
* @param {?} request
* @param {?} next
* @return {?}
*/
intercept(request, next) {
if (!!XmatLib.restTimes[request.url]) {
/** @type {?} */
const startTime = XmatLib.restTimes[request.url];
/** @type {?} */
const finalTime = Date.now();
if (this._logEnabled) {
console.info(`XmatMock: interceptor fired after ${(finalTime - startTime)} ms`);
XmatLib.restTimes[request.url] = startTime;
}
}
/** @type {?} */
const urlParts = request.url.split(this._qm);
/** @type {?} */
const mockKey = request.method + urlParts[0];
// Checks for non parametric URL
if (this._mockExists(mockKey)) {
this._logEnabled && console.info(`XmatMock: found mock with key ${mockKey}`);
return this._mocks[mockKey](request, next, [], urlParts[1]);
}
/** @type {?} */
const urlParams = this._extractUrlParams(urlParts[0]);
if (Array.isArray(urlParams)) {
/** @type {?} */
const serviceName = urlParts[0].substr(this._restBaseUrl.length).split(this._ds).shift();
/** @type {?} */
const serviceBase = request.method + this._restBaseUrl + serviceName;
/** @type {?} */
let j = urlParams.length;
while (--j >= 0) {
/** @type {?} */
const paramsBak = urlParams.slice();
paramsBak[j] = this._paramsPlaceholder;
/** @type {?} */
let mixedKey = [serviceBase].concat(paramsBak).join(this._ds);
if (this._mockExists(mixedKey)) {
this._logEnabled && console.info(`XmatMock: found mock with key ${mixedKey}`);
return this._mocks[mixedKey](request, next, urlParams.slice(j), urlParts[1]);
}
/** @type {?} */
let k = j;
while (--k >= 0) {
/** @type {?} */
const paramsBakBak = paramsBak.slice();
paramsBakBak[k] = this._paramsPlaceholder;
mixedKey = [serviceBase].concat(paramsBakBak).join(this._ds);
if (this._mockExists(mixedKey)) {
this._logEnabled && console.info(`XmatMock: found mock with key ${mixedKey}`);
return this._mocks[mixedKey](request, next, urlParams.slice(k), urlParts[1]);
}
}
}
}
return next.handle(request);
}
/**
* @param {?} serviceUrl
* @return {?}
*/
_extractUrlParams(serviceUrl) {
/** *
* E.G. serviceUrl = "/rest/cd/property-store/5/id";
* cleanUrl = "property-store/5/id"
* urlParamsList = [
* "property-store",
* "5",
* "id"
* ]
@type {?} */
const cleanUrl = serviceUrl.replace(this._restBaseUrl, "");
/** @type {?} */
const urlParamsList = cleanUrl.split(this._ds);
urlParamsList.shift();
// If true it means there was at least one param
if (urlParamsList.length > 0) {
return urlParamsList;
}
return void 0;
}
/**
* @param {?} mockKey
* @return {?}
*/
_mockExists(mockKey) {
return !!this._mocks[mockKey] && typeof this._mocks[mockKey] === typeof this._xmatConstants.noop;
}
/**
* @param {?} serviceUrl
* @param {?} methodKey
* @param {?=} fileSuffix
* @param {?=} status
* @return {?}
*/
_generateJsonUrl(serviceUrl, methodKey, fileSuffix = "", status = this._fileEndings.ok) {
/** @type {?} */
const serviceKey = serviceUrl.substr(this._restBaseUrl.length).split(this._ds + this._paramsPlaceholder)[0];
/** @type {?} */
const serviceFolder = serviceKey.split(this._ds)[0];
/** @type {?} */
const fileName = serviceKey.split(this._ds).join(this._fileNameSpace);
return this._mocksBaseUrl + serviceFolder + this._ds + methodKey + fileName + fileSuffix + status;
}
/**
* @param {?} mock
* @return {?}
*/
_pushMockHandler(mock) {
/**
* TODO: Possible evolution: custom callback in mock object
*/
!!mock.status || (mock.status = 200);
!!mock.body || (mock.body = this._defaultResponseBody);
/** @type {?} */
const mockKey = mock.method + mock.url;
this._mocks[mockKey] = (request, next, params = [], queryString) => {
if (mock.status !== 200) {
return new Observable(observer => {
/** @type {?} */
const customResponse = new HttpResponse({ status: mock.status, body: mock.body });
observer.error(customResponse);
observer.complete();
});
}
/** @type {?} */
let mockRequest;
if (!!mock.customUrl) {
if (this._logEnabled) {
console.info(`XmatMock: calling ${mock.customUrl}`);
}
/** @type {?} */
const url = mock.customUrl.replace(this._paramsPlaceholder, params.join(this._ds));
mockRequest = request.clone({
url: url + (!!queryString ? this._qm + queryString : ""),
method: mock.customMethod ? mock.customMethod : url.indexOf(".json") >= 0 ? XmatRestVerbs.GET : request.method
});
}
else {
/** @type {?} */
let fileNameSuffix = "";
each(params, (param) => {
fileNameSuffix += this._fileNameSpace + param;
});
/** @type {?} */
const ending = mock.result === false ? this._fileEndings.ko : this._fileEndings.ok;
/** @type {?} */
const methodKey = `${XmatRestVerbs[request.method]}-`;
/** @type {?} */
const url = this._generateJsonUrl(mock.url, methodKey, fileNameSuffix, ending);
/** @type {?} */
const queriedUrl = this._generateJsonUrl(mock.url, methodKey, this._fileNameSpace + this._queryUrlParam, ending);
mockRequest = request.clone({
url: request.urlWithParams.indexOf(this._queryUrlParam) > 0 ? queriedUrl : url,
method: XmatRestVerbs.GET
});
}
if (this._logEnabled) {
console.info(`XmatMock: calling ${mockRequest.url}`);
}
typeof mock.timeout === typeof 0 && mock.timeout >= 0 || (mock.timeout = this._defaultMockDelay);
/** @type {?} */
const delay = timer(mock.timeout);
/** @type {?} */
const start = XmatLib.restTimes[request.url] || Date.now();
return delay.pipe(switchMap(() => next.handle(mockRequest)), tap((event) => {
if (event.type === HttpEventType.Response) {
/** @type {?} */
const elapsed = Date.now() - start;
!!this._logEnabled && console.log(`XmatMock: request for mocked ${request.urlWithParams} took ${elapsed} ms.`);
}
}));
};
}
}
XmatMockService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
XmatMockService.ctorParameters = () => [
{ type: XmatConstantsService },
{ type: XmatMocksListService }
];
if (false) {
/** @type {?} */
XmatMockService.prototype._defaultResponseBody;
/** @type {?} */
XmatMockService.prototype._fileEndings;
/** @type {?} */
XmatMockService.prototype._mocks;
/** @type {?} */
XmatMockService.prototype._ds;
/** @type {?} */
XmatMockService.prototype._fileNameSpace;
/** @type {?} */
XmatMockService.prototype._mocksBaseUrl;
/** @type {?} */
XmatMockService.prototype._paramsPlaceholder;
/** @type {?} */
XmatMockService.prototype._qm;
/** @type {?} */
XmatMockService.prototype._queryUrlParam;
/** @type {?} */
XmatMockService.prototype._restBaseUrl;
/** @type {?} */
XmatMockService.prototype._defaultMockDelay;
/** @type {?} */
XmatMockService.prototype._logEnabled;
/** @type {?} */
XmatMockService.prototype._xmatConstants;
/** @type {?} */
XmatMockService.prototype._xmatMocksList;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1hdC1tb2NrLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtbWF0LWxpYi8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlcy94bWF0LW1vY2suc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBS0gsWUFBWSxFQUNaLGFBQWEsRUFDaEIsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QixPQUFPLEVBRUgsT0FBTyxFQUdQLGFBQWEsRUFDaEIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUM5RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUUvRCxPQUFPLEVBQUMsR0FBRyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxVQUFVLEVBQUUsS0FBSyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFHNUIsTUFBTSxPQUFPLGVBQWU7Ozs7O0lBa0J4QixZQUFzQixjQUFvQyxFQUNwQyxjQUFvQztRQURwQyxtQkFBYyxHQUFkLGNBQWMsQ0FBc0I7UUFDcEMsbUJBQWMsR0FBZCxjQUFjLENBQXNCO1FBakIxRCw0QkFBb0QsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBQyxDQUFDO1FBQ3pGLG9CQUF5QixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQztRQUMxRCxjQUF1QyxFQUFFLENBQUM7UUFFMUMsV0FBeUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7UUFDaEQsc0JBQW9DLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDO1FBQ3RFLHFCQUEyQyxJQUFJLENBQUMsY0FBYyxDQUFDLFlB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QUM7b0JBQ25DLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLE9BQU8sQ0FBQyxhQUFhLFNBQVMsT0FBTyxNQUFNLENBQUMsQ0FBQztpQkFDbEg7YUFDSixDQUFDLENBQUMsQ0FBQztTQUNYLENBQUM7S0FDTDs7O1lBdEtKLFVBQVU7Ozs7WUFQSCxvQkFBb0I7WUFDcEIsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgICBIdHRwRXZlbnQsXG4gICAgSHR0cEludGVyY2VwdG9yLFxuICAgIEh0dHBIYW5kbGVyLFxuICAgIEh0dHBSZXF1ZXN0LFxuICAgIEh0dHBSZXNwb25zZSxcbiAgICBIdHRwRXZlbnRUeXBlXG59IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xuLy9cbmltcG9ydCB7XG4gICAgWG1hdEdlbmVyaWNPYmplY3QsXG4gICAgWG1hdExpYixcbiAgICBYbWF0TW9jayxcbiAgICBYbWF0TW9ja3NDYWxsYmFja3MsXG4gICAgWG1hdFJlc3RWZXJic1xufSBmcm9tIFwiLi4vbW9kZWxzL2luZGV4XCI7XG5pbXBvcnQge1htYXRDb25zdGFudHNTZXJ2aWNlfSBmcm9tIFwiLi94bWF0LWNvbnN0YW50cy5zZXJ2aWNlXCI7XG5pbXBvcnQge1htYXRNb2Nrc0xpc3RTZXJ2aWNlfSBmcm9tIFwiLi94bWF0LW1vY2tzLWxpc3Quc2VydmljZVwiO1xuLy9cbmltcG9ydCB7dGFwLCBzd2l0Y2hNYXB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCB0aW1lcn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7ZWFjaH0gZnJvbSBcImxvZGFzaFwiO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgWG1hdE1vY2tTZXJ2aWNlIGltcGxlbWVudHMgSHR0cEludGVyY2VwdG9yIHtcblxuICAgIHByb3RlY3RlZCBfZGVmYXVsdFJlc3BvbnNlQm9keTogWG1hdEdlbmVyaWNPYmplY3QgPSB7ZGF0YTogdm9pZCAwLCBtZXNzYWdlOiBcImZvcmJpZGRlblwifTtcbiAgICBwcm90ZWN0ZWQgX2ZpbGVFbmRpbmdzID0gdGhpcy5feG1hdENvbnN0YW50cy5tb2Nrc0VuZGluZ3M7XG4gICAgcHJvdGVjdGVkIF9tb2NrczogWG1hdE1vY2tzQ2FsbGJhY2tzID0ge307XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2RzID0gdGhpcy5feG1hdENvbnN0YW50cy5kcztcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2ZpbGVOYW1lU3BhY2UgPSB0aGlzLl94bWF0Q29uc3RhbnRzLmZpbGVOYW1lU3BhY2U7XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9tb2Nrc0Jhc2VVcmw6IHN0cmluZyA9IHRoaXMuX3htYXRDb25zdGFudHMubW9ja3NCYXNlVXJsO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfcGFyYW1zUGxhY2Vob2xkZXIgPSB0aGlzLl94bWF0Q29uc3RhbnRzLnBhcmFtc1BsYWNlaG9sZGVyO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfcW06IHN0cmluZyA9IFwiP1wiO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfcXVlcnlVcmxQYXJhbSA9IHRoaXMuX3htYXRDb25zdGFudHMucXVlcnlVcmxQYXJhbTtcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3Jlc3RCYXNlVXJsOiBzdHJpbmcgPSB0aGlzLl94bWF0Q29uc3RhbnRzLnJlc3RCYXNlVXJsO1xuXG4gICAgLy8gT3ZlcnJpZGUgdGhlc2UgZnJvbSBleHRlbmRlZCBjbGFzc1xuICAgIHByb3RlY3RlZCBfZGVmYXVsdE1vY2tEZWxheTogbnVtYmVyID0gMjUwMDtcbiAgICBwcm90ZWN0ZWQgX2xvZ0VuYWJsZWQ6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIF94bWF0Q29uc3RhbnRzOiBYbWF0Q29uc3RhbnRzU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3htYXRNb2Nrc0xpc3Q6IFhtYXRNb2Nrc0xpc3RTZXJ2aWNlKSB7XG5cbiAgICAgICAgY29uc3QgbW9ja3MgPSB0aGlzLl94bWF0TW9ja3NMaXN0LmdldCgpO1xuICAgICAgICBlYWNoKG1vY2tzLCAobW9jaykgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcHVzaE1vY2tIYW5kbGVyKG1vY2spO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBIZXJlIHRoZSBtYWdpYyBoYXBwZW5zXG4gICAgaW50ZXJjZXB0KHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgICAgICBpZiAoISFYbWF0TGliLnJlc3RUaW1lc1tyZXF1ZXN0LnVybF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IFhtYXRMaWIucmVzdFRpbWVzW3JlcXVlc3QudXJsXTtcbiAgICAgICAgICAgIGNvbnN0IGZpbmFsVGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fbG9nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhgWG1hdE1vY2s6IGludGVyY2VwdG9yIGZpcmVkIGFmdGVyICR7KGZpbmFsVGltZSAtIHN0YXJ0VGltZSl9IG1zYCk7XG4gICAgICAgICAgICAgICAgWG1hdExpYi5yZXN0VGltZXNbcmVxdWVzdC51cmxdID0gc3RhcnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFNlcGFyYXRlIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSByZXN0XG4gICAgICAgIGNvbnN0IHVybFBhcnRzID0gcmVxdWVzdC51cmwuc3BsaXQodGhpcy5fcW0pO1xuICAgICAgICBjb25zdCBtb2NrS2V5ID0gcmVxdWVzdC5tZXRob2QgKyB1cmxQYXJ0c1swXTtcblxuICAgICAgICAvLyBDaGVja3MgZm9yIG5vbiBwYXJhbWV0cmljIFVSTFxuICAgICAgICBpZiAodGhpcy5fbW9ja0V4aXN0cyhtb2NrS2V5KSkge1xuICAgICAgICAgICAgdGhpcy5fbG9nRW5hYmxlZCAmJiBjb25zb2xlLmluZm8oYFhtYXRNb2NrOiBmb3VuZCBtb2NrIHdpdGgga2V5ICR7bW9ja0tleX1gKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vY2tzW21vY2tLZXldKHJlcXVlc3QsIG5leHQsIFtdLCB1cmxQYXJ0c1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gdGhpcy5fZXh0cmFjdFVybFBhcmFtcyh1cmxQYXJ0c1swXSk7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHVybFBhcmFtcykpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcnZpY2VOYW1lID0gdXJsUGFydHNbMF0uc3Vic3RyKHRoaXMuX3Jlc3RCYXNlVXJsLmxlbmd0aCkuc3BsaXQodGhpcy5fZHMpLnNoaWZ0KCk7XG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlQmFzZSA9IHJlcXVlc3QubWV0aG9kICsgdGhpcy5fcmVzdEJhc2VVcmwgKyBzZXJ2aWNlTmFtZTtcbiAgICAgICAgICAgIGxldCBqID0gdXJsUGFyYW1zLmxlbmd0aDtcbiAgICAgICAgICAgIHdoaWxlICgtLWogPj0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtc0JhayA9IHVybFBhcmFtcy5zbGljZSgpO1xuICAgICAgICAgICAgICAgIHBhcmFtc0Jha1tqXSA9IHRoaXMuX3BhcmFtc1BsYWNlaG9sZGVyO1xuICAgICAgICAgICAgICAgIGxldCBtaXhlZEtleSA9IFtzZXJ2aWNlQmFzZV0uY29uY2F0KHBhcmFtc0Jhaykuam9pbih0aGlzLl9kcyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX21vY2tFeGlzdHMobWl4ZWRLZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvZ0VuYWJsZWQgJiYgY29uc29sZS5pbmZvKGBYbWF0TW9jazogZm91bmQgbW9jayB3aXRoIGtleSAke21peGVkS2V5fWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9ja3NbbWl4ZWRLZXldKHJlcXVlc3QsIG5leHQsIHVybFBhcmFtcy5zbGljZShqKSwgdXJsUGFydHNbMV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgayA9IGo7XG4gICAgICAgICAgICAgICAgd2hpbGUgKC0tayA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtc0Jha0JhayA9IHBhcmFtc0Jhay5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNCYWtCYWtba10gPSB0aGlzLl9wYXJhbXNQbGFjZWhvbGRlcjtcbiAgICAgICAgICAgICAgICAgICAgbWl4ZWRLZXkgPSBbc2VydmljZUJhc2VdLmNvbmNhdChwYXJhbXNCYWtCYWspLmpvaW4odGhpcy5fZHMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbW9ja0V4aXN0cyhtaXhlZEtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvZ0VuYWJsZWQgJiYgY29uc29sZS5pbmZvKGBYbWF0TW9jazogZm91bmQgbW9jayB3aXRoIGtleSAke21peGVkS2V5fWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vY2tzW21peGVkS2V5XShyZXF1ZXN0LCBuZXh0LCB1cmxQYXJhbXMuc2xpY2UoayksIHVybFBhcnRzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXF1ZXN0KTtcblxuICAgIH1cblxuICAgIC8vIFByaXZhdGUgbWV0aG9kc1xuICAgIHByb3RlY3RlZCBfZXh0cmFjdFVybFBhcmFtcyhzZXJ2aWNlVXJsOiBzdHJpbmcpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEUuRy4gc2VydmljZVVybCA9IFwiL3Jlc3QvY2QvcHJvcGVydHktc3RvcmUvNS9pZFwiO1xuICAgICAgICAgKiBjbGVhblVybCA9IFwicHJvcGVydHktc3RvcmUvNS9pZFwiXG4gICAgICAgICAqIHVybFBhcmFtc0xpc3QgPSBbXG4gICAgICAgICAqICAgICAgXCJwcm9wZXJ0eS1zdG9yZVwiLFxuICAgICAgICAgKiAgICAgIFwiNVwiLFxuICAgICAgICAgKiAgICAgIFwiaWRcIlxuICAgICAgICAgKiBdXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBjbGVhblVybCA9IHNlcnZpY2VVcmwucmVwbGFjZSh0aGlzLl9yZXN0QmFzZVVybCwgXCJcIik7XG4gICAgICAgIGNvbnN0IHVybFBhcmFtc0xpc3QgPSBjbGVhblVybC5zcGxpdCh0aGlzLl9kcyk7XG4gICAgICAgIHVybFBhcmFtc0xpc3Quc2hpZnQoKTtcbiAgICAgICAgLy8gSWYgdHJ1ZSBpdCBtZWFucyB0aGVyZSB3YXMgYXQgbGVhc3Qgb25lIHBhcmFtXG4gICAgICAgIGlmICh1cmxQYXJhbXNMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB1cmxQYXJhbXNMaXN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2b2lkIDA7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9tb2NrRXhpc3RzKG1vY2tLZXkpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fbW9ja3NbbW9ja0tleV0gJiYgdHlwZW9mIHRoaXMuX21vY2tzW21vY2tLZXldID09PSB0eXBlb2YgdGhpcy5feG1hdENvbnN0YW50cy5ub29wO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfZ2VuZXJhdGVKc29uVXJsKHNlcnZpY2VVcmw6IHN0cmluZywgbWV0aG9kS2V5OiBzdHJpbmcsIGZpbGVTdWZmaXg6IHN0cmluZyA9IFwiXCIsIHN0YXR1czogc3RyaW5nID0gdGhpcy5fZmlsZUVuZGluZ3Mub2spIHtcbiAgICAgICAgY29uc3Qgc2VydmljZUtleSA9IHNlcnZpY2VVcmwuc3Vic3RyKHRoaXMuX3Jlc3RCYXNlVXJsLmxlbmd0aCkuc3BsaXQodGhpcy5fZHMgKyB0aGlzLl9wYXJhbXNQbGFjZWhvbGRlcilbMF07XG4gICAgICAgIGNvbnN0IHNlcnZpY2VGb2xkZXIgPSBzZXJ2aWNlS2V5LnNwbGl0KHRoaXMuX2RzKVswXTtcbiAgICAgICAgY29uc3QgZmlsZU5hbWUgPSBzZXJ2aWNlS2V5LnNwbGl0KHRoaXMuX2RzKS5qb2luKHRoaXMuX2ZpbGVOYW1lU3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9ja3NCYXNlVXJsICsgc2VydmljZUZvbGRlciArIHRoaXMuX2RzICsgbWV0aG9kS2V5ICsgZmlsZU5hbWUgKyBmaWxlU3VmZml4ICsgc3RhdHVzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfcHVzaE1vY2tIYW5kbGVyKG1vY2s6IFhtYXRNb2NrKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUT0RPOiBQb3NzaWJsZSBldm9sdXRpb246IGN1c3RvbSBjYWxsYmFjayBpbiBtb2NrIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgISFtb2NrLnN0YXR1cyB8fCAobW9jay5zdGF0dXMgPSAyMDApO1xuICAgICAgICAhIW1vY2suYm9keSB8fCAobW9jay5ib2R5ID0gdGhpcy5fZGVmYXVsdFJlc3BvbnNlQm9keSk7XG4gICAgICAgIGNvbnN0IG1vY2tLZXkgPSBtb2NrLm1ldGhvZCArIG1vY2sudXJsO1xuICAgICAgICB0aGlzLl9tb2Nrc1ttb2NrS2V5XSA9IChyZXF1ZXN0OiBIdHRwUmVxdWVzdDxhbnk+LCBuZXh0OiBIdHRwSGFuZGxlciwgcGFyYW1zOiBzdHJpbmdbXSA9IFtdLCBxdWVyeVN0cmluZz86IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiA9PiB7XG4gICAgICAgICAgICBpZiAobW9jay5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1c3RvbVJlc3BvbnNlID0gbmV3IEh0dHBSZXNwb25zZSh7c3RhdHVzOiBtb2NrLnN0YXR1cywgYm9keTogbW9jay5ib2R5fSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGN1c3RvbVJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG1vY2tSZXF1ZXN0O1xuICAgICAgICAgICAgaWYgKCEhbW9jay5jdXN0b21VcmwpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbG9nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oYFhtYXRNb2NrOiBjYWxsaW5nICR7bW9jay5jdXN0b21Vcmx9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIElmIHBhcmFtcyBwbGFjZWhvbGRlciBpcyBpbiBjdXN0b20gVVJMLCBwYXJhbXMgYXJlIGNvbmNhdCB0byB1cmwgd2l0aCBzbGFzaGVzXG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gbW9jay5jdXN0b21VcmwucmVwbGFjZSh0aGlzLl9wYXJhbXNQbGFjZWhvbGRlciwgcGFyYW1zLmpvaW4odGhpcy5fZHMpKTtcbiAgICAgICAgICAgICAgICBtb2NrUmVxdWVzdCA9IHJlcXVlc3QuY2xvbmUoe1xuICAgICAgICAgICAgICAgICAgICB1cmw6IHVybCArICghIXF1ZXJ5U3RyaW5nID8gdGhpcy5fcW0gKyBxdWVyeVN0cmluZyA6IFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IG1vY2suY3VzdG9tTWV0aG9kID8gbW9jay5jdXN0b21NZXRob2QgOiB1cmwuaW5kZXhPZihcIi5qc29uXCIpID49IDAgPyBYbWF0UmVzdFZlcmJzLkdFVCA6IHJlcXVlc3QubWV0aG9kXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgZmlsZU5hbWVTdWZmaXggPSBcIlwiO1xuICAgICAgICAgICAgICAgIGVhY2gocGFyYW1zLCAocGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWVTdWZmaXggKz0gdGhpcy5fZmlsZU5hbWVTcGFjZSArIHBhcmFtO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZGluZyA9IG1vY2sucmVzdWx0ID09PSBmYWxzZSA/IHRoaXMuX2ZpbGVFbmRpbmdzLmtvIDogdGhpcy5fZmlsZUVuZGluZ3Mub2s7XG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kS2V5ID0gYCR7WG1hdFJlc3RWZXJic1tyZXF1ZXN0Lm1ldGhvZF19LWA7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpcy5fZ2VuZXJhdGVKc29uVXJsKG1vY2sudXJsLCBtZXRob2RLZXksIGZpbGVOYW1lU3VmZml4LCBlbmRpbmcpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHF1ZXJpZWRVcmwgPSB0aGlzLl9nZW5lcmF0ZUpzb25VcmwobW9jay51cmwsIG1ldGhvZEtleSwgdGhpcy5fZmlsZU5hbWVTcGFjZSArIHRoaXMuX3F1ZXJ5VXJsUGFyYW0sIGVuZGluZyk7XG4gICAgICAgICAgICAgICAgbW9ja1JlcXVlc3QgPSByZXF1ZXN0LmNsb25lKHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiByZXF1ZXN0LnVybFdpdGhQYXJhbXMuaW5kZXhPZih0aGlzLl9xdWVyeVVybFBhcmFtKSA+IDAgPyBxdWVyaWVkVXJsIDogdXJsLFxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IFhtYXRSZXN0VmVyYnMuR0VUXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5fbG9nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhgWG1hdE1vY2s6IGNhbGxpbmcgJHttb2NrUmVxdWVzdC51cmx9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0eXBlb2YgbW9jay50aW1lb3V0ID09PSB0eXBlb2YgMCAmJiBtb2NrLnRpbWVvdXQgPj0gMCB8fCAobW9jay50aW1lb3V0ID0gdGhpcy5fZGVmYXVsdE1vY2tEZWxheSk7XG4gICAgICAgICAgICBjb25zdCBkZWxheSA9IHRpbWVyKG1vY2sudGltZW91dCk7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IFhtYXRMaWIucmVzdFRpbWVzW3JlcXVlc3QudXJsXSB8fCBEYXRlLm5vdygpO1xuICAgICAgICAgICAgcmV0dXJuIGRlbGF5LnBpcGUoc3dpdGNoTWFwKCgpID0+IG5leHQuaGFuZGxlKG1vY2tSZXF1ZXN0KSksXG4gICAgICAgICAgICAgICAgdGFwKChldmVudDogSHR0cFJlc3BvbnNlPGFueT4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSBEYXRlLm5vdygpIC0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAhIXRoaXMuX2xvZ0VuYWJsZWQgJiYgY29uc29sZS5sb2coYFhtYXRNb2NrOiByZXF1ZXN0IGZvciBtb2NrZWQgJHtyZXF1ZXN0LnVybFdpdGhQYXJhbXN9IHRvb2sgJHtlbGFwc2VkfSBtcy5gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXX0=