@fdot/edms-api-lib
Version:
The edms-api-lib package wraps service calls to FDOT EDMS API. ## Installation `npm install @fdot/edms-api-lib --save`
388 lines (374 loc) • 50.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('rxjs'), require('rxjs/operators'), require('fine-uploader/lib/core')) :
typeof define === 'function' && define.amd ? define('@fdot/edms-api-lib', ['exports', '@angular/core', '@angular/common/http', 'rxjs', 'rxjs/operators', 'fine-uploader/lib/core'], factory) :
(factory((global.fdot = global.fdot || {}, global.fdot['edms-api-lib'] = {}),global.ng.core,global.ng.common.http,global.rxjs,global.rxjs.operators,global.FineUploaderCore));
}(this, (function (exports,i0,i1,rxjs,operators,FineUploaderCore) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var Config = /** @class */ (function () {
function Config(host, apiKey, uploadChunkSize, uploadChunkThreshold) {
this.host = host;
this.apiKey = apiKey;
this.uploadChunkSize = uploadChunkSize;
this.uploadChunkThreshold = uploadChunkThreshold;
}
return Config;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var EdmsService = /** @class */ (function () {
function EdmsService(httpClient, config) {
this.httpClient = httpClient;
this.config = config;
this.defaultPropertyMap = {};
if (!config) {
throw Error('Call EdmsApiLibModule with for root passing in the config object');
}
this.headers = { 'Ocp-Apim-Subscription-Key': config.apiKey };
this.httpOptions = { headers: new i1.HttpHeaders(this.headers) };
}
/**
* @param {?} authTokenInputs
* @return {?}
*/
EdmsService.prototype.getAuthToken = /**
* @param {?} authTokenInputs
* @return {?}
*/
function (authTokenInputs) {
var _this = this;
/** @type {?} */
var url = this.config.host + "/api/authenticationToken";
/** @type {?} */
var body = {
server: authTokenInputs.server,
library: authTokenInputs.library,
userId: authTokenInputs.userId,
password: authTokenInputs.password
};
return this.httpClient.post(url, body, this.httpOptions)
.pipe(operators.map(function (response) {
_this.token = response;
return response;
}));
};
/**
* @return {?}
*/
EdmsService.prototype.getBusinessAreas = /**
* @return {?}
*/
function () {
if (!this.token)
return rxjs.throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
var url = this.config.host + "/api/businessAreas?authenticationToken=" + this.token;
return this.httpClient.get(url, this.httpOptions)
.pipe(operators.map(function (response) {
return response;
}));
};
/**
* @param {?} businessArea
* @return {?}
*/
EdmsService.prototype.getDocumentGroupsByBusinessArea = /**
* @param {?} businessArea
* @return {?}
*/
function (businessArea) {
if (!this.token)
return rxjs.throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
var url = this.config.host + "/api/businessArea/" + businessArea.SystemId + "/documentGroups?authenticationToken=" + this.token;
return this.httpClient.get(url, this.httpOptions)
.pipe(operators.map(function (response) {
return response;
}));
};
/**
* @param {?} documentGroup
* @return {?}
*/
EdmsService.prototype.getDocumentTypesByDocumentGroup = /**
* @param {?} documentGroup
* @return {?}
*/
function (documentGroup) {
if (!this.token)
return rxjs.throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
var url = this.config.host + "/api/documentGroup/" + documentGroup.SystemId + "/documentTypes?authenticationToken=" + this.token;
return this.httpClient.get(url, this.httpOptions)
.pipe(operators.map(function (response) {
return response;
}));
};
/**
* @return {?}
*/
EdmsService.prototype.getDefaultPropertyData = /**
* @return {?}
*/
function () {
var _this = this;
if (!this.token)
return rxjs.throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
var cachedValue = this.defaultPropertyMap[this.token];
if (cachedValue) {
return rxjs.of(__assign({}, cachedValue));
}
/** @type {?} */
var url = this.config.host + "/api/defaultPropertyData?authenticationToken=" + this.token;
return this.httpClient.get(url, this.httpOptions)
.pipe(operators.map(function (response) {
_this.defaultPropertyMap[_this.token] = __assign({}, response);
return response;
}));
};
/**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
EdmsService.prototype.addNewDocument = /**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
function (file, documentMetadata) {
if (!this.token)
return rxjs.throwError("Please call Get Auth Token before making additional calls to establish a security token");
if (file.size < this.config.uploadChunkThreshold) {
return this.uploadDocumentWithOneRequest(file, documentMetadata);
}
else {
return this.uploadDocumentInSimultaneousChunks(file, documentMetadata);
}
};
/**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
EdmsService.prototype.uploadDocumentInSimultaneousChunks = /**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
function (file, documentMetadata) {
var _this = this;
return rxjs.Observable.create(function (observer) {
/** @type {?} */
var completeCallback = function (id, name, document, xhr) {
if (xhr.status != 200) {
observer.error(xhr.response);
}
else {
observer.next(document);
observer.complete();
}
};
/** @type {?} */
var chunkingSuccessOptions = {
endpoint: _this.config.host + "/api/chunkComplete?authenticationToken=" + _this.token,
jsonPayload: true,
params: function (fileId) {
return {
documentMetadata: documentMetadata,
id: fineUploaderBasic.getUuid(fileId),
totalParts: 3
};
}
};
/** @type {?} */
var chunkingOptions = {
enabled: true,
partSize: _this.config.uploadChunkSize,
concurrent: { enabled: true },
paramNames: {
partIndex: "partIndex",
totalParts: "totalParts"
},
success: chunkingSuccessOptions
};
/** @type {?} */
var requestOptions = {
customHeaders: _this.headers,
endpoint: _this.config.host + "/api/chunkNewDocument?authenticationToken=" + _this.token,
filenameParam: 'filename',
forceMultipart: true,
omitDefaultParams: false,
paramsInBody: true,
uuidName: "id",
inputName: "file"
};
/** @type {?} */
var callbackOptions = {
onComplete: function (id, name, responseJSON, xhr) { return completeCallback(id, name, responseJSON, xhr); },
onError: function (id, name, errorReason, xhr) {
debugger;
console.log(JSON.stringify(xhr));
}
};
/** @type {?} */
var options = {
maxConnections: 6,
multiple: false,
chunking: chunkingOptions,
request: requestOptions,
callbacks: callbackOptions,
autoUpload: false,
debug: true
};
/** @type {?} */
var fineUploaderBasic = new FineUploaderCore.FineUploaderBasic(options);
fineUploaderBasic.addFiles([file]);
fineUploaderBasic.uploadStoredFiles();
});
};
/**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
EdmsService.prototype.uploadDocumentWithOneRequest = /**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
function (file, documentMetadata) {
/** @type {?} */
var url = this.config.host + "/api/addNewDocument?authenticationToken=" + this.token;
/** @type {?} */
var formData = new FormData();
formData.append('file', file, file.name);
formData.append("metadata", JSON.stringify(documentMetadata));
return this.httpClient.post(url, formData, this.httpOptions).pipe(operators.map(function (response) {
return response;
}));
};
/**
* @param {?} docId
* @return {?}
*/
EdmsService.prototype.getDocumentDownloadUrl = /**
* @param {?} docId
* @return {?}
*/
function (docId) {
return this.config.host + "/api/document/" + docId + "?subscription-key=" + this.config.apiKey + "&authenticationToken=" + this.token;
};
EdmsService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
EdmsService.ctorParameters = function () {
return [
{ type: i1.HttpClient },
{ type: Config, decorators: [{ type: i0.Inject, args: ['config',] }] }
];
};
/** @nocollapse */ EdmsService.ngInjectableDef = i0.defineInjectable({ factory: function EdmsService_Factory() { return new EdmsService(i0.inject(i1.HttpClient), i0.inject("config")); }, token: EdmsService, providedIn: "root" });
return EdmsService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var AuthTokenInputs = /** @class */ (function () {
function AuthTokenInputs() {
}
return AuthTokenInputs;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var UploadOptions = /** @class */ (function () {
function UploadOptions() {
}
return UploadOptions;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var EdmsApiLibModule = /** @class */ (function () {
function EdmsApiLibModule() {
}
/**
* @param {?} config
* @return {?}
*/
EdmsApiLibModule.forRoot = /**
* @param {?} config
* @return {?}
*/
function (config) {
return {
ngModule: EdmsApiLibModule,
providers: [
{ provide: 'config', useValue: config },
{ provide: 'EdmsService', useValue: EdmsService }
]
};
};
EdmsApiLibModule.decorators = [
{ type: i0.NgModule, args: [{
imports: [
i1.HttpClientModule
],
declarations: [],
exports: []
},] }
];
return EdmsApiLibModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.EdmsService = EdmsService;
exports.AuthTokenInputs = AuthTokenInputs;
exports.Config = Config;
exports.UploadOptions = UploadOptions;
exports.EdmsApiLibModule = EdmsApiLibModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmRvdC1lZG1zLWFwaS1saWIudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm5nOi8vQGZkb3QvZWRtcy1hcGktbGliL2xpYi9tb2RlbHMvQ29uZmlnLnRzIiwibmc6Ly9AZmRvdC9lZG1zLWFwaS1saWIvbGliL3NlcnZpY2VzL0VkbXNTZXJ2aWNlLnRzIiwibmc6Ly9AZmRvdC9lZG1zLWFwaS1saWIvbGliL21vZGVscy9BdXRoVG9rZW5JbnB1dHMudHMiLCJuZzovL0BmZG90L2VkbXMtYXBpLWxpYi9saWIvbW9kZWxzL1VwbG9hZE9wdGlvbnMudHMiLCJuZzovL0BmZG90L2VkbXMtYXBpLWxpYi9saWIvZWRtcy1hcGktbGliLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxyXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxyXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXHJcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXHJcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXHJcblxyXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcclxuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDApXHJcbiAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgZXhwb3J0cykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAoIWV4cG9ydHMuaGFzT3duUHJvcGVydHkocCkpIGV4cG9ydHNbcF0gPSBtW3BdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XHJcbiAgICByZXN1bHQuZGVmYXVsdCA9IG1vZDtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcbiIsImV4cG9ydCBjbGFzcyBDb25maWcge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGhvc3Q6IHN0cmluZyxcclxuICAgICAgICBwdWJsaWMgYXBpS2V5OiBzdHJpbmcsXHJcbiAgICAgICAgcHVibGljIHVwbG9hZENodW5rU2l6ZTogbnVtYmVyLFxyXG4gICAgICAgIHB1YmxpYyB1cGxvYWRDaHVua1RocmVzaG9sZCkge1xyXG4gICAgfVxyXG59IiwiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBIZWFkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5cclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgb2YgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL21vZGVscy9Db25maWcnO1xyXG5pbXBvcnQgeyBBdXRoVG9rZW5JbnB1dHMgfSBmcm9tICcuLi9tb2RlbHMvQXV0aFRva2VuSW5wdXRzJztcclxuaW1wb3J0IHsgQnVzaW5lc3NBcmVhIH0gZnJvbSAnLi4vbW9kZWxzL0J1c2luZXNzQXJlYSc7XHJcbmltcG9ydCB7IERvY3VtZW50RGF0YSB9IGZyb20gJy4uL21vZGVscy9Eb2N1bWVudERhdGEnO1xyXG5pbXBvcnQgeyBEb2N1bWVudEdyb3VwIH0gZnJvbSAnLi4vbW9kZWxzL0RvY3VtZW50R3JvdXAnO1xyXG5pbXBvcnQgeyBEb2N1bWVudFByb3BlcnR5IH0gZnJvbSAnLi4vbW9kZWxzL0RvY3VtZW50UHJvcGVydHknO1xyXG5pbXBvcnQgeyBEb2N1bWVudFR5cGUgfSBmcm9tICcuLi9tb2RlbHMvRG9jdW1lbnRUeXBlJztcclxuXHJcbmltcG9ydCAqIGFzIEZpbmVVcGxvYWRlckNvcmUgZnJvbSAnZmluZS11cGxvYWRlci9saWIvY29yZSc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFZG1zU2VydmljZSB7XHJcbiAgcHJpdmF0ZSBoZWFkZXJzO1xyXG4gIHByaXZhdGUgaHR0cE9wdGlvbnM7XHJcblxyXG4gIHByaXZhdGUgdG9rZW46IHN0cmluZztcclxuICBwcml2YXRlIGRlZmF1bHRQcm9wZXJ0eU1hcDogeyBbdG9rZW46IHN0cmluZ106IERvY3VtZW50UHJvcGVydHlbXTsgfSA9IHt9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIEBJbmplY3QoJ2NvbmZpZycpIHByaXZhdGUgY29uZmlnOiBDb25maWcpIHtcclxuICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgIHRocm93IEVycm9yKCdDYWxsIEVkbXNBcGlMaWJNb2R1bGUgd2l0aCBmb3Igcm9vdCBwYXNzaW5nIGluIHRoZSBjb25maWcgb2JqZWN0Jyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmhlYWRlcnMgPSB7ICdPY3AtQXBpbS1TdWJzY3JpcHRpb24tS2V5JzogY29uZmlnLmFwaUtleSB9O1xyXG4gICAgdGhpcy5odHRwT3B0aW9ucyA9IHsgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHRoaXMuaGVhZGVycykgfTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRBdXRoVG9rZW4oYXV0aFRva2VuSW5wdXRzOiBBdXRoVG9rZW5JbnB1dHMpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2F1dGhlbnRpY2F0aW9uVG9rZW5gO1xyXG4gICAgY29uc3QgYm9keSA9IHtcclxuICAgICAgc2VydmVyOiBhdXRoVG9rZW5JbnB1dHMuc2VydmVyLFxyXG4gICAgICBsaWJyYXJ5OiBhdXRoVG9rZW5JbnB1dHMubGlicmFyeSxcclxuICAgICAgdXNlcklkOiBhdXRoVG9rZW5JbnB1dHMudXNlcklkLFxyXG4gICAgICBwYXNzd29yZDogYXV0aFRva2VuSW5wdXRzLnBhc3N3b3JkXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5wb3N0PHN0cmluZz4odXJsLCBib2R5LCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIHRoaXMudG9rZW4gPSByZXNwb25zZTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0QnVzaW5lc3NBcmVhcygpOiBPYnNlcnZhYmxlPEJ1c2luZXNzQXJlYVtdPiB7XHJcbiAgICBpZiAoIXRoaXMudG9rZW4pIHJldHVybiB0aHJvd0Vycm9yKFwiUGxlYXNlIGNhbGwgR2V0IEF1dGggVG9rZW4gYmVmb3JlIG1ha2luZyBhZGRpdGlvbmFsIGNhbGxzIHRvIGVzdGFibGlzaCBhIHNlY3VyaXR5IHRva2VuXCIpO1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2J1c2luZXNzQXJlYXM/YXV0aGVudGljYXRpb25Ub2tlbj0ke3RoaXMudG9rZW59YDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxCdXNpbmVzc0FyZWFbXT4odXJsLCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBCdXNpbmVzc0FyZWFbXSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudEdyb3Vwc0J5QnVzaW5lc3NBcmVhKGJ1c2luZXNzQXJlYTogQnVzaW5lc3NBcmVhKTogT2JzZXJ2YWJsZTxEb2N1bWVudEdyb3VwW10+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvYnVzaW5lc3NBcmVhLyR7YnVzaW5lc3NBcmVhLlN5c3RlbUlkfS9kb2N1bWVudEdyb3Vwcz9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5nZXQ8RG9jdW1lbnRHcm91cFtdPih1cmwsIHRoaXMuaHR0cE9wdGlvbnMpXHJcbiAgICAgIC5waXBlKG1hcChcclxuICAgICAgICAocmVzcG9uc2U6IERvY3VtZW50R3JvdXBbXSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudFR5cGVzQnlEb2N1bWVudEdyb3VwKGRvY3VtZW50R3JvdXA6IERvY3VtZW50R3JvdXApOiBPYnNlcnZhYmxlPERvY3VtZW50VHlwZVtdPiB7XHJcbiAgICBpZiAoIXRoaXMudG9rZW4pIHJldHVybiB0aHJvd0Vycm9yKFwiUGxlYXNlIGNhbGwgR2V0IEF1dGggVG9rZW4gYmVmb3JlIG1ha2luZyBhZGRpdGlvbmFsIGNhbGxzIHRvIGVzdGFibGlzaCBhIHNlY3VyaXR5IHRva2VuXCIpO1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2RvY3VtZW50R3JvdXAvJHtkb2N1bWVudEdyb3VwLlN5c3RlbUlkfS9kb2N1bWVudFR5cGVzP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxEb2N1bWVudFR5cGVbXT4odXJsLCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoKHJlc3BvbnNlOiBEb2N1bWVudEdyb3VwKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0RGVmYXVsdFByb3BlcnR5RGF0YSgpOiBPYnNlcnZhYmxlPERvY3VtZW50UHJvcGVydHlbXT4ge1xyXG4gICAgaWYgKCF0aGlzLnRva2VuKSByZXR1cm4gdGhyb3dFcnJvcihcIlBsZWFzZSBjYWxsIEdldCBBdXRoIFRva2VuIGJlZm9yZSBtYWtpbmcgYWRkaXRpb25hbCBjYWxscyB0byBlc3RhYmxpc2ggYSBzZWN1cml0eSB0b2tlblwiKTtcclxuICAgIHZhciBjYWNoZWRWYWx1ZSA9IHRoaXMuZGVmYXVsdFByb3BlcnR5TWFwW3RoaXMudG9rZW5dO1xyXG4gICAgaWYgKGNhY2hlZFZhbHVlKSB7XHJcbiAgICAgIHJldHVybiBvZih7IC4uLmNhY2hlZFZhbHVlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9kZWZhdWx0UHJvcGVydHlEYXRhP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxEb2N1bWVudFByb3BlcnR5W10+KHVybCwgdGhpcy5odHRwT3B0aW9ucylcclxuICAgICAgLnBpcGUobWFwKFxyXG4gICAgICAgIChyZXNwb25zZTogRG9jdW1lbnRQcm9wZXJ0eVtdKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmRlZmF1bHRQcm9wZXJ0eU1hcFt0aGlzLnRva2VuXSA9IHsgLi4ucmVzcG9uc2UgfTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9XHJcbiAgICAgICkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZE5ld0RvY3VtZW50KGZpbGU6IEZpbGUsIGRvY3VtZW50TWV0YWRhdGE6IERvY3VtZW50RGF0YSk6IE9ic2VydmFibGU8RG9jdW1lbnQ+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcblxyXG4gICAgaWYgKGZpbGUuc2l6ZSA8IHRoaXMuY29uZmlnLnVwbG9hZENodW5rVGhyZXNob2xkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnVwbG9hZERvY3VtZW50V2l0aE9uZVJlcXVlc3QoZmlsZSwgZG9jdW1lbnRNZXRhZGF0YSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMudXBsb2FkRG9jdW1lbnRJblNpbXVsdGFuZW91c0NodW5rcyhmaWxlLCBkb2N1bWVudE1ldGFkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwbG9hZERvY3VtZW50SW5TaW11bHRhbmVvdXNDaHVua3MoZmlsZTogRmlsZSwgZG9jdW1lbnRNZXRhZGF0YTogRG9jdW1lbnREYXRhKTogT2JzZXJ2YWJsZTxEb2N1bWVudD4ge1xyXG5cclxuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShvYnNlcnZlciA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbXBsZXRlQ2FsbGJhY2sgPSAoaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nLCBkb2N1bWVudDogRG9jdW1lbnQsIHhocjogWE1MSHR0cFJlcXVlc3QpOiB2b2lkID0+IHtcclxuICAgICAgICBpZiAoeGhyLnN0YXR1cyAhPSAyMDApIHtcclxuICAgICAgICAgIG9ic2VydmVyLmVycm9yKHhoci5yZXNwb25zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIubmV4dChkb2N1bWVudCk7XHJcbiAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBjaHVua2luZ1N1Y2Nlc3NPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLlN1Y2Nlc3NPcHRpb25zID0ge1xyXG4gICAgICAgIGVuZHBvaW50OiBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvY2h1bmtDb21wbGV0ZT9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gLFxyXG4gICAgICAgIGpzb25QYXlsb2FkOiB0cnVlLFxyXG4gICAgICAgIHBhcmFtczogZnVuY3Rpb24gKGZpbGVJZDogbnVtYmVyKSB7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkb2N1bWVudE1ldGFkYXRhLFxyXG4gICAgICAgICAgICBpZDogZmluZVVwbG9hZGVyQmFzaWMuZ2V0VXVpZChmaWxlSWQpLFxyXG4gICAgICAgICAgICB0b3RhbFBhcnRzOiAzXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY2h1bmtpbmdPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLkNodW5raW5nT3B0aW9ucyA9IHtcclxuICAgICAgICBlbmFibGVkOiB0cnVlLFxyXG4gICAgICAgIHBhcnRTaXplOiB0aGlzLmNvbmZpZy51cGxvYWRDaHVua1NpemUsXHJcbiAgICAgICAgY29uY3VycmVudDogeyBlbmFibGVkOiB0cnVlIH0sXHJcbiAgICAgICAgcGFyYW1OYW1lczoge1xyXG4gICAgICAgICAgcGFydEluZGV4OiBcInBhcnRJbmRleFwiLFxyXG4gICAgICAgICAgdG90YWxQYXJ0czogXCJ0b3RhbFBhcnRzXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN1Y2Nlc3M6IGNodW5raW5nU3VjY2Vzc09wdGlvbnNcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciByZXF1ZXN0T3B0aW9uczogRmluZVVwbG9hZGVyQ29yZS5SZXF1ZXN0T3B0aW9ucyA9IHtcclxuICAgICAgICBjdXN0b21IZWFkZXJzOiB0aGlzLmhlYWRlcnMsXHJcbiAgICAgICAgZW5kcG9pbnQ6IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9jaHVua05ld0RvY3VtZW50P2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWAsXHJcbiAgICAgICAgZmlsZW5hbWVQYXJhbTogJ2ZpbGVuYW1lJyxcclxuICAgICAgICBmb3JjZU11bHRpcGFydDogdHJ1ZSxcclxuICAgICAgICBvbWl0RGVmYXVsdFBhcmFtczogZmFsc2UsXHJcbiAgICAgICAgcGFyYW1zSW5Cb2R5OiB0cnVlLFxyXG4gICAgICAgIHV1aWROYW1lOiBcImlkXCIsXHJcbiAgICAgICAgaW5wdXROYW1lOiBcImZpbGVcIlxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY2FsbGJhY2tPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLkNvcmVFdmVudHMgPSB7XHJcbiAgICAgICAgb25Db21wbGV0ZTogKGlkOiBudW1iZXIsIG5hbWU6IHN0cmluZywgcmVzcG9uc2VKU09OOiBhbnksIHhocjogWE1MSHR0cFJlcXVlc3QpID0+IGNvbXBsZXRlQ2FsbGJhY2soaWQsIG5hbWUsIHJlc3BvbnNlSlNPTiwgeGhyKSxcclxuICAgICAgICBvbkVycm9yOiAoaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nLCBlcnJvclJlYXNvbjogc3RyaW5nLCB4aHI6IFhNTEh0dHBSZXF1ZXN0KSA9PiB7XHJcbiAgICAgICAgICBkZWJ1Z2dlcjtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHhocikpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIG9wdGlvbnM6IEZpbmVVcGxvYWRlckNvcmUuQ29yZU9wdGlvbnMgPSB7XHJcbiAgICAgICAgbWF4Q29ubmVjdGlvbnM6IDYsXHJcbiAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxyXG4gICAgICAgIGNodW5raW5nOiBjaHVua2luZ09wdGlvbnMsXHJcbiAgICAgICAgcmVxdWVzdDogcmVxdWVzdE9wdGlvbnMsXHJcbiAgICAgICAgY2FsbGJhY2tzOiBjYWxsYmFja09wdGlvbnMsXHJcbiAgICAgICAgYXV0b1VwbG9hZDogZmFsc2UsXHJcbiAgICAgICAgZGVidWc6IHRydWVcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBmaW5lVXBsb2FkZXJCYXNpYyA9IG5ldyBGaW5lVXBsb2FkZXJDb3JlLkZpbmVVcGxvYWRlckJhc2ljKG9wdGlvbnMpO1xyXG5cclxuICAgICAgZmluZVVwbG9hZGVyQmFzaWMuYWRkRmlsZXMoW2ZpbGVdKTtcclxuICAgICAgZmluZVVwbG9hZGVyQmFzaWMudXBsb2FkU3RvcmVkRmlsZXMoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGxvYWREb2N1bWVudFdpdGhPbmVSZXF1ZXN0KGZpbGU6IEZpbGUsIGRvY3VtZW50TWV0YWRhdGE6IERvY3VtZW50RGF0YSk6IE9ic2VydmFibGU8RG9jdW1lbnQ+IHtcclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9hZGROZXdEb2N1bWVudD9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XHJcbiAgICBmb3JtRGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlLCBmaWxlLm5hbWUpO1xyXG4gICAgZm9ybURhdGEuYXBwZW5kKFwibWV0YWRhdGFcIiwgSlNPTi5zdHJpbmdpZnkoZG9jdW1lbnRNZXRhZGF0YSkpO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQucG9zdDxEb2N1bWVudD4odXJsLCBmb3JtRGF0YSwgdGhpcy5odHRwT3B0aW9ucykucGlwZShtYXAoXHJcbiAgICAgIChyZXNwb25zZTogRG9jdW1lbnQpID0+IHtcclxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudERvd25sb2FkVXJsKGRvY0lkOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9kb2N1bWVudC8ke2RvY0lkfT9zdWJzY3JpcHRpb24ta2V5PSR7dGhpcy5jb25maWcuYXBpS2V5fSZhdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gIH1cclxufSIsImV4cG9ydCBjbGFzcyBBdXRoVG9rZW5JbnB1dHMge1xyXG4gICAgc2VydmVyOiBzdHJpbmc7XHJcbiAgICBsaWJyYXJ5OiBzdHJpbmc7XHJcbiAgICB1c2VySWQ6IHN0cmluZztcclxuICAgIHBhc3N3b3JkOiBzdHJpbmc7XHJcbn0iLCJleHBvcnQgY2xhc3MgVXBsb2FkT3B0aW9ucyB7XHJcbiAgICBjaHVua1RocmVzaG9sZDogbnVtYmVyO1xyXG4gICAgY2h1bmtTaXplOiBudW1iZXI7XHJcblxyXG59IiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL21vZGVscy9Db25maWcnO1xyXG5pbXBvcnQgeyBFZG1zU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvRWRtc1NlcnZpY2UnO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBpbXBvcnRzOiBbXHJcbiAgICBIdHRwQ2xpZW50TW9kdWxlXHJcbiAgXSxcclxuICBkZWNsYXJhdGlvbnM6IFtdLFxyXG4gIGV4cG9ydHM6IFtdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFZG1zQXBpTGliTW9kdWxlIHtcclxuICBzdGF0aWMgZm9yUm9vdChjb25maWc6IENvbmZpZyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbmdNb2R1bGU6IEVkbXNBcGlMaWJNb2R1bGUsXHJcbiAgICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHsgcHJvdmlkZTogJ2NvbmZpZycsIHVzZVZhbHVlOiBjb25maWcgfSxcclxuICAgICAgICB7IHByb3ZpZGU6ICdFZG1zU2VydmljZScsIHVzZVZhbHVlOiBFZG1zU2VydmljZSB9XHJcbiAgICAgIF1cclxuICAgIH07XHJcbiAgfVxyXG59Il0sIm5hbWVzIjpbIkh0dHBIZWFkZXJzIiwibWFwIiwidGhyb3dFcnJvciIsIm9mIiwiT2JzZXJ2YWJsZSIsIkZpbmVVcGxvYWRlckNvcmUuRmluZVVwbG9hZGVyQmFzaWMiLCJJbmplY3RhYmxlIiwiSHR0cENsaWVudCIsIkluamVjdCIsIk5nTW9kdWxlIiwiSHR0cENsaWVudE1vZHVsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7Ozs7Ozs7Ozs7Ozs7O0FBY0EsSUFlTyxJQUFJLFFBQVEsR0FBRztRQUNsQixRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxrQkFBa0IsQ0FBQztZQUMzQyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDakQsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakIsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDO29CQUFFLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNoRjtZQUNELE9BQU8sQ0FBQyxDQUFDO1NBQ1osQ0FBQTtRQUNELE9BQU8sUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFBOzs7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