@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`
306 lines (297 loc) • 31 kB
JavaScript
import { Injectable, Inject, NgModule, defineInjectable, inject } from '@angular/core';
import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
import { Observable, throwError, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { FineUploaderBasic } from 'fine-uploader/lib/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class Config {
/**
* @param {?} host
* @param {?} apiKey
* @param {?} uploadChunkSize
* @param {?} uploadChunkThreshold
*/
constructor(host, apiKey, uploadChunkSize, uploadChunkThreshold) {
this.host = host;
this.apiKey = apiKey;
this.uploadChunkSize = uploadChunkSize;
this.uploadChunkThreshold = uploadChunkThreshold;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class EdmsService {
/**
* @param {?} httpClient
* @param {?} config
*/
constructor(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 HttpHeaders(this.headers) };
}
/**
* @param {?} authTokenInputs
* @return {?}
*/
getAuthToken(authTokenInputs) {
/** @type {?} */
const url = `${this.config.host}/api/authenticationToken`;
/** @type {?} */
const body = {
server: authTokenInputs.server,
library: authTokenInputs.library,
userId: authTokenInputs.userId,
password: authTokenInputs.password
};
return this.httpClient.post(url, body, this.httpOptions)
.pipe(map((response) => {
this.token = response;
return response;
}));
}
/**
* @return {?}
*/
getBusinessAreas() {
if (!this.token)
return throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
const url = `${this.config.host}/api/businessAreas?authenticationToken=${this.token}`;
return this.httpClient.get(url, this.httpOptions)
.pipe(map((response) => {
return response;
}));
}
/**
* @param {?} businessArea
* @return {?}
*/
getDocumentGroupsByBusinessArea(businessArea) {
if (!this.token)
return throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
const url = `${this.config.host}/api/businessArea/${businessArea.SystemId}/documentGroups?authenticationToken=${this.token}`;
return this.httpClient.get(url, this.httpOptions)
.pipe(map((response) => {
return response;
}));
}
/**
* @param {?} documentGroup
* @return {?}
*/
getDocumentTypesByDocumentGroup(documentGroup) {
if (!this.token)
return throwError("Please call Get Auth Token before making additional calls to establish a security token");
/** @type {?} */
const url = `${this.config.host}/api/documentGroup/${documentGroup.SystemId}/documentTypes?authenticationToken=${this.token}`;
return this.httpClient.get(url, this.httpOptions)
.pipe(map((response) => {
return response;
}));
}
/**
* @return {?}
*/
getDefaultPropertyData() {
if (!this.token)
return 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 of(Object.assign({}, cachedValue));
}
/** @type {?} */
const url = `${this.config.host}/api/defaultPropertyData?authenticationToken=${this.token}`;
return this.httpClient.get(url, this.httpOptions)
.pipe(map((response) => {
this.defaultPropertyMap[this.token] = Object.assign({}, response);
return response;
}));
}
/**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
addNewDocument(file, documentMetadata) {
if (!this.token)
return 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 {?}
*/
uploadDocumentInSimultaneousChunks(file, documentMetadata) {
return Observable.create(observer => {
/** @type {?} */
const completeCallback = (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,
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: (id, name, responseJSON, xhr) => completeCallback(id, name, responseJSON, xhr),
onError: (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 FineUploaderBasic(options);
fineUploaderBasic.addFiles([file]);
fineUploaderBasic.uploadStoredFiles();
});
}
/**
* @param {?} file
* @param {?} documentMetadata
* @return {?}
*/
uploadDocumentWithOneRequest(file, documentMetadata) {
/** @type {?} */
const url = `${this.config.host}/api/addNewDocument?authenticationToken=${this.token}`;
/** @type {?} */
const formData = new FormData();
formData.append('file', file, file.name);
formData.append("metadata", JSON.stringify(documentMetadata));
return this.httpClient.post(url, formData, this.httpOptions).pipe(map((response) => {
return response;
}));
}
/**
* @param {?} docId
* @return {?}
*/
getDocumentDownloadUrl(docId) {
return `${this.config.host}/api/document/${docId}?subscription-key=${this.config.apiKey}&authenticationToken=${this.token}`;
}
}
EdmsService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
EdmsService.ctorParameters = () => [
{ type: HttpClient },
{ type: Config, decorators: [{ type: Inject, args: ['config',] }] }
];
/** @nocollapse */ EdmsService.ngInjectableDef = defineInjectable({ factory: function EdmsService_Factory() { return new EdmsService(inject(HttpClient), inject("config")); }, token: EdmsService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class AuthTokenInputs {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class UploadOptions {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class EdmsApiLibModule {
/**
* @param {?} config
* @return {?}
*/
static forRoot(config) {
return {
ngModule: EdmsApiLibModule,
providers: [
{ provide: 'config', useValue: config },
{ provide: 'EdmsService', useValue: EdmsService }
]
};
}
}
EdmsApiLibModule.decorators = [
{ type: NgModule, args: [{
imports: [
HttpClientModule
],
declarations: [],
exports: []
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { EdmsService, AuthTokenInputs, Config, UploadOptions, EdmsApiLibModule };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmRvdC1lZG1zLWFwaS1saWIuanMubWFwIiwic291cmNlcyI6WyJuZzovL0BmZG90L2VkbXMtYXBpLWxpYi9saWIvbW9kZWxzL0NvbmZpZy50cyIsIm5nOi8vQGZkb3QvZWRtcy1hcGktbGliL2xpYi9zZXJ2aWNlcy9FZG1zU2VydmljZS50cyIsIm5nOi8vQGZkb3QvZWRtcy1hcGktbGliL2xpYi9tb2RlbHMvQXV0aFRva2VuSW5wdXRzLnRzIiwibmc6Ly9AZmRvdC9lZG1zLWFwaS1saWIvbGliL21vZGVscy9VcGxvYWRPcHRpb25zLnRzIiwibmc6Ly9AZmRvdC9lZG1zLWFwaS1saWIvbGliL2VkbXMtYXBpLWxpYi5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIENvbmZpZyB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgaG9zdDogc3RyaW5nLFxyXG4gICAgICAgIHB1YmxpYyBhcGlLZXk6IHN0cmluZyxcclxuICAgICAgICBwdWJsaWMgdXBsb2FkQ2h1bmtTaXplOiBudW1iZXIsXHJcbiAgICAgICAgcHVibGljIHVwbG9hZENodW5rVGhyZXNob2xkKSB7XHJcbiAgICB9XHJcbn0iLCJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEhlYWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcblxyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBvZiB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWxzL0NvbmZpZyc7XHJcbmltcG9ydCB7IEF1dGhUb2tlbklucHV0cyB9IGZyb20gJy4uL21vZGVscy9BdXRoVG9rZW5JbnB1dHMnO1xyXG5pbXBvcnQgeyBCdXNpbmVzc0FyZWEgfSBmcm9tICcuLi9tb2RlbHMvQnVzaW5lc3NBcmVhJztcclxuaW1wb3J0IHsgRG9jdW1lbnREYXRhIH0gZnJvbSAnLi4vbW9kZWxzL0RvY3VtZW50RGF0YSc7XHJcbmltcG9ydCB7IERvY3VtZW50R3JvdXAgfSBmcm9tICcuLi9tb2RlbHMvRG9jdW1lbnRHcm91cCc7XHJcbmltcG9ydCB7IERvY3VtZW50UHJvcGVydHkgfSBmcm9tICcuLi9tb2RlbHMvRG9jdW1lbnRQcm9wZXJ0eSc7XHJcbmltcG9ydCB7IERvY3VtZW50VHlwZSB9IGZyb20gJy4uL21vZGVscy9Eb2N1bWVudFR5cGUnO1xyXG5cclxuaW1wb3J0ICogYXMgRmluZVVwbG9hZGVyQ29yZSBmcm9tICdmaW5lLXVwbG9hZGVyL2xpYi9jb3JlJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIEVkbXNTZXJ2aWNlIHtcclxuICBwcml2YXRlIGhlYWRlcnM7XHJcbiAgcHJpdmF0ZSBodHRwT3B0aW9ucztcclxuXHJcbiAgcHJpdmF0ZSB0b2tlbjogc3RyaW5nO1xyXG4gIHByaXZhdGUgZGVmYXVsdFByb3BlcnR5TWFwOiB7IFt0b2tlbjogc3RyaW5nXTogRG9jdW1lbnRQcm9wZXJ0eVtdOyB9ID0ge307XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaHR0cENsaWVudDogSHR0cENsaWVudCwgQEluamVjdCgnY29uZmlnJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZykge1xyXG4gICAgaWYgKCFjb25maWcpIHtcclxuICAgICAgdGhyb3cgRXJyb3IoJ0NhbGwgRWRtc0FwaUxpYk1vZHVsZSB3aXRoIGZvciByb290IHBhc3NpbmcgaW4gdGhlIGNvbmZpZyBvYmplY3QnKTtcclxuICAgIH1cclxuICAgIHRoaXMuaGVhZGVycyA9IHsgJ09jcC1BcGltLVN1YnNjcmlwdGlvbi1LZXknOiBjb25maWcuYXBpS2V5IH07XHJcbiAgICB0aGlzLmh0dHBPcHRpb25zID0geyBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnModGhpcy5oZWFkZXJzKSB9O1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldEF1dGhUb2tlbihhdXRoVG9rZW5JbnB1dHM6IEF1dGhUb2tlbklucHV0cyk6IE9ic2VydmFibGU8c3RyaW5nPiB7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvYXV0aGVudGljYXRpb25Ub2tlbmA7XHJcbiAgICBjb25zdCBib2R5ID0ge1xyXG4gICAgICBzZXJ2ZXI6IGF1dGhUb2tlbklucHV0cy5zZXJ2ZXIsXHJcbiAgICAgIGxpYnJhcnk6IGF1dGhUb2tlbklucHV0cy5saWJyYXJ5LFxyXG4gICAgICB1c2VySWQ6IGF1dGhUb2tlbklucHV0cy51c2VySWQsXHJcbiAgICAgIHBhc3N3b3JkOiBhdXRoVG9rZW5JbnB1dHMucGFzc3dvcmRcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LnBvc3Q8c3RyaW5nPih1cmwsIGJvZHksIHRoaXMuaHR0cE9wdGlvbnMpXHJcbiAgICAgIC5waXBlKG1hcChcclxuICAgICAgICAocmVzcG9uc2U6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgdGhpcy50b2tlbiA9IHJlc3BvbnNlO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRCdXNpbmVzc0FyZWFzKCk6IE9ic2VydmFibGU8QnVzaW5lc3NBcmVhW10+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvYnVzaW5lc3NBcmVhcz9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0PEJ1c2luZXNzQXJlYVtdPih1cmwsIHRoaXMuaHR0cE9wdGlvbnMpXHJcbiAgICAgIC5waXBlKG1hcChcclxuICAgICAgICAocmVzcG9uc2U6IEJ1c2luZXNzQXJlYVtdKSA9PiB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldERvY3VtZW50R3JvdXBzQnlCdXNpbmVzc0FyZWEoYnVzaW5lc3NBcmVhOiBCdXNpbmVzc0FyZWEpOiBPYnNlcnZhYmxlPERvY3VtZW50R3JvdXBbXT4ge1xyXG4gICAgaWYgKCF0aGlzLnRva2VuKSByZXR1cm4gdGhyb3dFcnJvcihcIlBsZWFzZSBjYWxsIEdldCBBdXRoIFRva2VuIGJlZm9yZSBtYWtpbmcgYWRkaXRpb25hbCBjYWxscyB0byBlc3RhYmxpc2ggYSBzZWN1cml0eSB0b2tlblwiKTtcclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9idXNpbmVzc0FyZWEvJHtidXNpbmVzc0FyZWEuU3lzdGVtSWR9L2RvY3VtZW50R3JvdXBzP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxEb2N1bWVudEdyb3VwW10+KHVybCwgdGhpcy5odHRwT3B0aW9ucylcclxuICAgICAgLnBpcGUobWFwKFxyXG4gICAgICAgIChyZXNwb25zZTogRG9jdW1lbnRHcm91cFtdKSA9PiB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldERvY3VtZW50VHlwZXNCeURvY3VtZW50R3JvdXAoZG9jdW1lbnRHcm91cDogRG9jdW1lbnRHcm91cCk6IE9ic2VydmFibGU8RG9jdW1lbnRUeXBlW10+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvZG9jdW1lbnRHcm91cC8ke2RvY3VtZW50R3JvdXAuU3lzdGVtSWR9L2RvY3VtZW50VHlwZXM/YXV0aGVudGljYXRpb25Ub2tlbj0ke3RoaXMudG9rZW59YDtcclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0PERvY3VtZW50VHlwZVtdPih1cmwsIHRoaXMuaHR0cE9wdGlvbnMpXHJcbiAgICAgIC5waXBlKG1hcCgocmVzcG9uc2U6IERvY3VtZW50R3JvdXApID0+IHtcclxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREZWZhdWx0UHJvcGVydHlEYXRhKCk6IE9ic2VydmFibGU8RG9jdW1lbnRQcm9wZXJ0eVtdPiB7XHJcbiAgICBpZiAoIXRoaXMudG9rZW4pIHJldHVybiB0aHJvd0Vycm9yKFwiUGxlYXNlIGNhbGwgR2V0IEF1dGggVG9rZW4gYmVmb3JlIG1ha2luZyBhZGRpdGlvbmFsIGNhbGxzIHRvIGVzdGFibGlzaCBhIHNlY3VyaXR5IHRva2VuXCIpO1xyXG4gICAgdmFyIGNhY2hlZFZhbHVlID0gdGhpcy5kZWZhdWx0UHJvcGVydHlNYXBbdGhpcy50b2tlbl07XHJcbiAgICBpZiAoY2FjaGVkVmFsdWUpIHtcclxuICAgICAgcmV0dXJuIG9mKHsgLi4uY2FjaGVkVmFsdWUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2RlZmF1bHRQcm9wZXJ0eURhdGE/YXV0aGVudGljYXRpb25Ub2tlbj0ke3RoaXMudG9rZW59YDtcclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0PERvY3VtZW50UHJvcGVydHlbXT4odXJsLCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBEb2N1bWVudFByb3BlcnR5W10pID0+IHtcclxuICAgICAgICAgIHRoaXMuZGVmYXVsdFByb3BlcnR5TWFwW3RoaXMudG9rZW5dID0geyAuLi5yZXNwb25zZSB9O1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH1cclxuICAgICAgKSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkTmV3RG9jdW1lbnQoZmlsZTogRmlsZSwgZG9jdW1lbnRNZXRhZGF0YTogRG9jdW1lbnREYXRhKTogT2JzZXJ2YWJsZTxEb2N1bWVudD4ge1xyXG4gICAgaWYgKCF0aGlzLnRva2VuKSByZXR1cm4gdGhyb3dFcnJvcihcIlBsZWFzZSBjYWxsIEdldCBBdXRoIFRva2VuIGJlZm9yZSBtYWtpbmcgYWRkaXRpb25hbCBjYWxscyB0byBlc3RhYmxpc2ggYSBzZWN1cml0eSB0b2tlblwiKTtcclxuXHJcbiAgICBpZiAoZmlsZS5zaXplIDwgdGhpcy5jb25maWcudXBsb2FkQ2h1bmtUaHJlc2hvbGQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMudXBsb2FkRG9jdW1lbnRXaXRoT25lUmVxdWVzdChmaWxlLCBkb2N1bWVudE1ldGFkYXRhKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy51cGxvYWREb2N1bWVudEluU2ltdWx0YW5lb3VzQ2h1bmtzKGZpbGUsIGRvY3VtZW50TWV0YWRhdGEpO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBsb2FkRG9jdW1lbnRJblNpbXVsdGFuZW91c0NodW5rcyhmaWxlOiBGaWxlLCBkb2N1bWVudE1ldGFkYXRhOiBEb2N1bWVudERhdGEpOiBPYnNlcnZhYmxlPERvY3VtZW50PiB7XHJcblxyXG4gICAgcmV0dXJuIE9ic2VydmFibGUuY3JlYXRlKG9ic2VydmVyID0+IHtcclxuICAgICAgY29uc3QgY29tcGxldGVDYWxsYmFjayA9IChpZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGRvY3VtZW50OiBEb2N1bWVudCwgeGhyOiBYTUxIdHRwUmVxdWVzdCk6IHZvaWQgPT4ge1xyXG4gICAgICAgIGlmICh4aHIuc3RhdHVzICE9IDIwMCkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoeGhyLnJlc3BvbnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5uZXh0KGRvY3VtZW50KTtcclxuICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIGNodW5raW5nU3VjY2Vzc09wdGlvbnM6IEZpbmVVcGxvYWRlckNvcmUuU3VjY2Vzc09wdGlvbnMgPSB7XHJcbiAgICAgICAgZW5kcG9pbnQ6IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9jaHVua0NvbXBsZXRlP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWAsXHJcbiAgICAgICAganNvblBheWxvYWQ6IHRydWUsXHJcbiAgICAgICAgcGFyYW1zOiBmdW5jdGlvbiAoZmlsZUlkOiBudW1iZXIpIHtcclxuICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGRvY3VtZW50TWV0YWRhdGEsXHJcbiAgICAgICAgICAgIGlkOiBmaW5lVXBsb2FkZXJCYXNpYy5nZXRVdWlkKGZpbGVJZCksXHJcbiAgICAgICAgICAgIHRvdGFsUGFydHM6IDNcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBjaHVua2luZ09wdGlvbnM6IEZpbmVVcGxvYWRlckNvcmUuQ2h1bmtpbmdPcHRpb25zID0ge1xyXG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXHJcbiAgICAgICAgcGFydFNpemU6IHRoaXMuY29uZmlnLnVwbG9hZENodW5rU2l6ZSxcclxuICAgICAgICBjb25jdXJyZW50OiB7IGVuYWJsZWQ6IHRydWUgfSxcclxuICAgICAgICBwYXJhbU5hbWVzOiB7XHJcbiAgICAgICAgICBwYXJ0SW5kZXg6IFwicGFydEluZGV4XCIsXHJcbiAgICAgICAgICB0b3RhbFBhcnRzOiBcInRvdGFsUGFydHNcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc3VjY2VzczogY2h1bmtpbmdTdWNjZXNzT3B0aW9uc1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIHJlcXVlc3RPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLlJlcXVlc3RPcHRpb25zID0ge1xyXG4gICAgICAgIGN1c3RvbUhlYWRlcnM6IHRoaXMuaGVhZGVycyxcclxuICAgICAgICBlbmRwb2ludDogYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2NodW5rTmV3RG9jdW1lbnQ/YXV0aGVudGljYXRpb25Ub2tlbj0ke3RoaXMudG9rZW59YCxcclxuICAgICAgICBmaWxlbmFtZVBhcmFtOiAnZmlsZW5hbWUnLFxyXG4gICAgICAgIGZvcmNlTXVsdGlwYXJ0OiB0cnVlLFxyXG4gICAgICAgIG9taXREZWZhdWx0UGFyYW1zOiBmYWxzZSxcclxuICAgICAgICBwYXJhbXNJbkJvZHk6IHRydWUsXHJcbiAgICAgICAgdXVpZE5hbWU6IFwiaWRcIixcclxuICAgICAgICBpbnB1dE5hbWU6IFwiZmlsZVwiXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBjYWxsYmFja09wdGlvbnM6IEZpbmVVcGxvYWRlckNvcmUuQ29yZUV2ZW50cyA9IHtcclxuICAgICAgICBvbkNvbXBsZXRlOiAoaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nLCByZXNwb25zZUpTT046IGFueSwgeGhyOiBYTUxIdHRwUmVxdWVzdCkgPT4gY29tcGxldGVDYWxsYmFjayhpZCwgbmFtZSwgcmVzcG9uc2VKU09OLCB4aHIpLFxyXG4gICAgICAgIG9uRXJyb3I6IChpZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGVycm9yUmVhc29uOiBzdHJpbmcsIHhocjogWE1MSHR0cFJlcXVlc3QpID0+IHtcclxuICAgICAgICAgIGRlYnVnZ2VyO1xyXG4gICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoeGhyKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgb3B0aW9uczogRmluZVVwbG9hZGVyQ29yZS5Db3JlT3B0aW9ucyA9IHtcclxuICAgICAgICBtYXhDb25uZWN0aW9uczogNixcclxuICAgICAgICBtdWx0aXBsZTogZmFsc2UsXHJcbiAgICAgICAgY2h1bmtpbmc6IGNodW5raW5nT3B0aW9ucyxcclxuICAgICAgICByZXF1ZXN0OiByZXF1ZXN0T3B0aW9ucyxcclxuICAgICAgICBjYWxsYmFja3M6IGNhbGxiYWNrT3B0aW9ucyxcclxuICAgICAgICBhdXRvVXBsb2FkOiBmYWxzZSxcclxuICAgICAgICBkZWJ1ZzogdHJ1ZVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIGZpbmVVcGxvYWRlckJhc2ljID0gbmV3IEZpbmVVcGxvYWRlckNvcmUuRmluZVVwbG9hZGVyQmFzaWMob3B0aW9ucyk7XHJcblxyXG4gICAgICBmaW5lVXBsb2FkZXJCYXNpYy5hZGRGaWxlcyhbZmlsZV0pO1xyXG4gICAgICBmaW5lVXBsb2FkZXJCYXNpYy51cGxvYWRTdG9yZWRGaWxlcygpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwbG9hZERvY3VtZW50V2l0aE9uZVJlcXVlc3QoZmlsZTogRmlsZSwgZG9jdW1lbnRNZXRhZGF0YTogRG9jdW1lbnREYXRhKTogT2JzZXJ2YWJsZTxEb2N1bWVudD4ge1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2FkZE5ld0RvY3VtZW50P2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICBjb25zdCBmb3JtRGF0YTogRm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcclxuICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGZpbGUsIGZpbGUubmFtZSk7XHJcbiAgICBmb3JtRGF0YS5hcHBlbmQoXCJtZXRhZGF0YVwiLCBKU09OLnN0cmluZ2lmeShkb2N1bWVudE1ldGFkYXRhKSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5wb3N0PERvY3VtZW50Pih1cmwsIGZvcm1EYXRhLCB0aGlzLmh0dHBPcHRpb25zKS5waXBlKG1hcChcclxuICAgICAgKHJlc3BvbnNlOiBEb2N1bWVudCkgPT4ge1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldERvY3VtZW50RG93bmxvYWRVcmwoZG9jSWQ6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2RvY3VtZW50LyR7ZG9jSWR9P3N1YnNjcmlwdGlvbi1rZXk9JHt0aGlzLmNvbmZpZy5hcGlLZXl9JmF1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgfVxyXG59IiwiZXhwb3J0IGNsYXNzIEF1dGhUb2tlbklucHV0cyB7XHJcbiAgICBzZXJ2ZXI6IHN0cmluZztcclxuICAgIGxpYnJhcnk6IHN0cmluZztcclxuICAgIHVzZXJJZDogc3RyaW5nO1xyXG4gICAgcGFzc3dvcmQ6IHN0cmluZztcclxufSIsImV4cG9ydCBjbGFzcyBVcGxvYWRPcHRpb25zIHtcclxuICAgIGNodW5rVGhyZXNob2xkOiBudW1iZXI7XHJcbiAgICBjaHVua1NpemU6IG51bWJlcjtcclxuXHJcbn0iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vbW9kZWxzL0NvbmZpZyc7XHJcbmltcG9ydCB7IEVkbXNTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9FZG1zU2VydmljZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGltcG9ydHM6IFtcclxuICAgIEh0dHBDbGllbnRNb2R1bGVcclxuICBdLFxyXG4gIGRlY2xhcmF0aW9uczogW10sXHJcbiAgZXhwb3J0czogW11cclxufSlcclxuZXhwb3J0IGNsYXNzIEVkbXNBcGlMaWJNb2R1bGUge1xyXG4gIHN0YXRpYyBmb3JSb290KGNvbmZpZzogQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBuZ01vZHVsZTogRWRtc0FwaUxpYk1vZHVsZSxcclxuICAgICAgcHJvdmlkZXJzOiBbXHJcbiAgICAgICAgeyBwcm92aWRlOiAnY29uZmlnJywgdXNlVmFsdWU6IGNvbmZpZyB9LFxyXG4gICAgICAgIHsgcHJvdmlkZTogJ0VkbXNTZXJ2aWNlJywgdXNlVmFsdWU6IEVkbXNTZXJ2aWNlIH1cclxuICAgICAgXVxyXG4gICAgfTtcclxuICB9XHJcbn0iXSwibmFtZXMiOlsiRmluZVVwbG9hZGVyQ29yZS5GaW5lVXBsb2FkZXJCYXNpYyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBOzs7Ozs7O0lBQ0ksWUFDVyxNQUNBLFFBQ0EsaUJBQ0E7UUFIQSxTQUFJLEdBQUosSUFBSTtRQUNKLFdBQU0sR0FBTixNQUFNO1FBQ04sb0JBQWUsR0FBZixlQUFlO1FBQ2YseUJBQW9CLEdBQXBCLG9CQUFvQjtLQUM5QjtDQUNKOzs7Ozs7QUNQRDs7Ozs7SUE0QkUsWUFBb0IsVUFBc0IsRUFBNEIsTUFBYztRQUFoRSxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQTRCLFdBQU0sR0FBTixNQUFNLENBQVE7a0NBRmIsRUFBRTtRQUd2RSxJQUFJ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