UNPKG

@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
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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