UNPKG

moh-common-lib

Version:

A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).

274 lines 20.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { AbstractHttpService } from './abstract-api-service'; import { throwError } from 'rxjs'; import * as moment_ from 'moment'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; /** @type {?} */ const moment = moment_; /** @enum {string} */ const SeverityLevels = { INFO: 'info', ERROR: 'error', }; /** @enum {string} */ const CommonLogEvents = { navigation: 'navigation', error: 'error', submission: 'submission', }; export { CommonLogEvents }; /** * @record */ export function CommonLogMessage() { } if (false) { /** * The type of event being logged. * @type {?} */ CommonLogMessage.prototype.event; /* Skipping unhandled member: [key: string]: any;*/ } export class CommonLogger extends AbstractHttpService { /** * @param {?} http */ constructor(http) { super(http); this.http = http; /** * The HTTP Headers which go with each request. These MUST be set if you are * using the logger. Fields include: * * - program (REQUIRED, the application wide code) * - applicationId (REQUIRED, like sessionId) * - request_method (REQUIRED, 'POST') * - logsource: (REQUIRED, window.location.hostname) * - http_x_forwarded_host (REQUIRED, window.location.hostname) * */ this._headers = new HttpHeaders({ request_method: 'POST', logsource: window.location.hostname, http_x_forwarded_host: window.location.hostname }); this.url = null; } /** * @param {?} id * @return {?} */ set applicationId(id) { this._headers = this._headers.set('applicationId', id); } /** * @return {?} */ get applicationId() { return this._headers.get('applicationId'); } /** * @param {?} name * @return {?} */ set programName(name) { this._headers = this._headers.set('program', name); } /** * @return {?} */ get programName() { return this._headers.get('name'); } /** * @param {?} newURL * @return {?} */ setURL(newURL) { this.url = newURL; } /** * @param {?} message * @return {?} */ log(message) { this._log((/** @type {?} */ (message))); } /** * @param {?} errorMessage * @return {?} */ logError(errorMessage) { this._logError((/** @type {?} */ (errorMessage))); } /** * Log a message to Splunk. This is the main way to send logs and * automatically includes meta-data. You do **not** need to subscribe to the * response, as the service already does that. The input object must have an * 'event' property set, everything else is optional. * * Example: * ``` * this.logService.log({ * event: 'submission', * dateObj: new Date() * }); * ``` * @protected * @param {?} message A JavaScript object, nesting is fine, with `event` property * set. * @return {?} */ _log(message) { this.setSeverity(SeverityLevels.INFO); return this._sendLog(message); } /** * @protected * @param {?} errorMessage * @return {?} */ _logError(errorMessage) { this.setSeverity(SeverityLevels.ERROR); return this._sendLog(errorMessage); } /** * Log HTTP errors, e.g. when losing network connectivity or receiving an * error response code. * @param {?} error * @return {?} */ logHttpError(error) { return this._logError({ event: CommonLogEvents.error, message: error.message, errorName: error.name, statusText: error.statusText }); } /** * Internal method to send logs to Splunk, includes meta-data except that's * consistent across all requests, but not specific values like severity * level. * * @private * @param {?} message A JavaScript object or anything that can be toString()'d, * like Date * @return {?} */ _sendLog(message) { // Update headers this.setTimestamp(); this.setTags(message.event); if (this.url === null) { /** @type {?} */ const msg = 'Unable to send logs as URL as not been set via setURL()'; console.error(msg); return throwError(msg); } // Configure request /** @type {?} */ const body = { message: message }; // We call .subscribe() here because we don't care about the response and // we want to ensure that we never forget to call subscribe. return this.post(this.url, body).subscribe(); } /** * @protected * @param {?} error * @return {?} */ handleError(error) { if (error.error instanceof ErrorEvent) { // Client-side / network error occured console.error('An error occured: ', error.error.message); } else { // The backend returned an unsuccessful response code console.error(`Backend returned error code: ${error.status}. Error body: ${error.error}`); } return throwError(error); } /** * Overwrite the inherited httpOptions so we can set responseType to text. * This updates Angular's parsing, and it won't error out due to the server * not responding with JSON. * @protected * @return {?} */ get httpOptions() { return { headers: this._headers, responseType: 'text' }; } // TODO: Remove moment dependency /** * @private * @return {?} */ setTimestamp() { this._headers = this._headers.set('timestamp', moment().toISOString()); } /** * @private * @param {?} severity * @return {?} */ setSeverity(severity) { this._headers = this._headers.set('severity', severity); } /** * The headers are easier to search in splunk, and we aren't using tags, so * repurpose it to event type. * @private * @param {?} message * @return {?} */ setTags(message) { this._headers = this._headers.set('tags', message); } } CommonLogger.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ CommonLogger.ctorParameters = () => [ { type: HttpClient } ]; /** @nocollapse */ CommonLogger.ngInjectableDef = i0.defineInjectable({ factory: function CommonLogger_Factory() { return new CommonLogger(i0.inject(i1.HttpClient)); }, token: CommonLogger, providedIn: "root" }); if (false) { /** * The HTTP Headers which go with each request. These MUST be set if you are * using the logger. Fields include: * * - program (REQUIRED, the application wide code) * - applicationId (REQUIRED, like sessionId) * - request_method (REQUIRED, 'POST') * - logsource: (REQUIRED, window.location.hostname) * - http_x_forwarded_host (REQUIRED, window.location.hostname) * * @type {?} * @protected */ CommonLogger.prototype._headers; /** * @type {?} * @private */ CommonLogger.prototype.url; /** * @type {?} * @protected */ CommonLogger.prototype.http; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tb2gtY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlcy9sb2dnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFxQixXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxPQUFPLE1BQU0sUUFBUSxDQUFDOzs7O01BQzVCLE1BQU0sR0FBRyxPQUFPOzs7SUFHcEIsTUFBTyxNQUFNO0lBQ2IsT0FBUSxPQUFPOzs7O0lBSWYsWUFBYSxZQUFZO0lBQ3pCLE9BQVEsT0FBTztJQUNmLFlBQWEsWUFBWTs7Ozs7O0FBRzNCLHNDQUtDOzs7Ozs7SUFIQyxpQ0FBYzs7O0FBUWhCLE1BQU0sT0FBTyxZQUFhLFNBQVEsbUJBQW1COzs7O0lBb0JuRCxZQUFzQixJQUFnQjtRQUNwQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFEUSxTQUFJLEdBQUosSUFBSSxDQUFZOzs7Ozs7Ozs7Ozs7UUFSNUIsYUFBUSxHQUFnQixJQUFJLFdBQVcsQ0FBQztZQUNoRCxjQUFjLEVBQUUsTUFBTTtZQUN0QixTQUFTLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRO1lBQ25DLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUTtTQUNoRCxDQUFDLENBQUM7UUFFSyxRQUFHLEdBQVcsSUFBSSxDQUFDO0lBSTNCLENBQUM7Ozs7O0lBRUQsSUFBSSxhQUFhLENBQUUsRUFBVTtRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFFLGVBQWUsRUFBRSxFQUFFLENBQUUsQ0FBQztJQUMzRCxDQUFDOzs7O0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBRSxlQUFlLENBQUUsQ0FBQztJQUM5QyxDQUFDOzs7OztJQUVELElBQUksV0FBVyxDQUFFLElBQVk7UUFDM0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBRSxTQUFTLEVBQUUsSUFBSSxDQUFFLENBQUM7SUFDdkQsQ0FBQzs7OztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUUsTUFBTSxDQUFFLENBQUM7SUFDckMsQ0FBQzs7Ozs7SUFFRCxNQUFNLENBQUMsTUFBYztRQUNuQixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztJQUNwQixDQUFDOzs7OztJQUVNLEdBQUcsQ0FBRSxPQUFZO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUUsbUJBQUEsT0FBTyxFQUFvQixDQUFFLENBQUM7SUFDM0MsQ0FBQzs7Ozs7SUFFTSxRQUFRLENBQUUsWUFBaUI7UUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBRSxtQkFBQSxZQUFZLEVBQW9CLENBQUUsQ0FBQztJQUNyRCxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBa0JTLElBQUksQ0FBQyxPQUF5QjtRQUN0QyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEMsQ0FBQzs7Ozs7O0lBRVMsU0FBUyxDQUFDLFlBQThCO1FBQ2hELElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNyQyxDQUFDOzs7Ozs7O0lBTU0sWUFBWSxDQUFDLEtBQXdCO1FBQzFDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNwQixLQUFLLEVBQUUsZUFBZSxDQUFDLEtBQUs7WUFDNUIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSTtZQUNyQixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7Ozs7Ozs7Ozs7SUFVTyxRQUFRLENBQUMsT0FBeUI7UUFDeEMsaUJBQWlCO1FBQ2pCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU1QixJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxFQUFFOztrQkFDYixHQUFHLEdBQUcseURBQXlEO1lBQ3JFLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkIsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDMUI7OztjQUdLLElBQUksR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUU7UUFFakMseUVBQXlFO1FBQ3pFLDREQUE0RDtRQUM1RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUMvQyxDQUFDOzs7Ozs7SUFFUyxXQUFXLENBQUMsS0FBd0I7UUFDNUMsSUFBSSxLQUFLLENBQUMsS0FBSyxZQUFZLFVBQVUsRUFBRTtZQUNyQyxzQ0FBc0M7WUFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzFEO2FBQU07WUFDTCxxREFBcUQ7WUFDckQsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsS0FBSyxDQUFDLE1BQU0sa0JBQWtCLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQzVGO1FBRUQsT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsQ0FBQzs7Ozs7Ozs7SUFPRCxJQUFjLFdBQVc7UUFDdkIsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN0QixZQUFZLEVBQUUsTUFBTTtTQUNyQixDQUFDO0lBQ0osQ0FBQzs7Ozs7O0lBR08sWUFBWTtRQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Ozs7OztJQUVPLFdBQVcsQ0FBQyxRQUF3QjtRQUMxQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxRCxDQUFDOzs7Ozs7OztJQU1PLE9BQU8sQ0FBQyxPQUFlO1FBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3JELENBQUM7OztZQWhLRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7Ozs7WUExQlEsVUFBVTs7Ozs7Ozs7Ozs7Ozs7Ozs7SUF1Q2pCLGdDQUlHOzs7OztJQUVILDJCQUEyQjs7Ozs7SUFFZiw0QkFBMEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgQWJzdHJhY3RIdHRwU2VydmljZSB9IGZyb20gJy4vYWJzdHJhY3QtYXBpLXNlcnZpY2UnO1xyXG5pbXBvcnQgeyB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCAqIGFzIG1vbWVudF8gZnJvbSAnbW9tZW50JztcclxuY29uc3QgbW9tZW50ID0gbW9tZW50XztcclxuXHJcbmVudW0gU2V2ZXJpdHlMZXZlbHMge1xyXG4gIElORk8gPSAnaW5mbycsXHJcbiAgRVJST1IgPSAnZXJyb3InLFxyXG59XHJcblxyXG5leHBvcnQgZW51bSBDb21tb25Mb2dFdmVudHMge1xyXG4gIG5hdmlnYXRpb24gPSAnbmF2aWdhdGlvbicsXHJcbiAgZXJyb3IgPSAnZXJyb3InLFxyXG4gIHN1Ym1pc3Npb24gPSAnc3VibWlzc2lvbidcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21tb25Mb2dNZXNzYWdlIHtcclxuICAvKiogVGhlIHR5cGUgb2YgZXZlbnQgYmVpbmcgbG9nZ2VkLiAqL1xyXG4gIGV2ZW50OiBzdHJpbmc7IC8vIFNob3VsZCBiZSBzdWJjbGFzc2VzIGludG8gbXVsdGlwbGUgc3RyaW5nIGxpdGVyYWxzXHJcbiAgLy8gV2UgYWxsb3cgYW55IG90aGVyIHByb3BlcnRpZXMvdmFsdWVzIGluIHRoZSBpbnRlcmZhY2VcclxuICBba2V5OiBzdHJpbmddOiBhbnk7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIENvbW1vbkxvZ2dlciBleHRlbmRzIEFic3RyYWN0SHR0cFNlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFRoZSBIVFRQIEhlYWRlcnMgd2hpY2ggZ28gd2l0aCBlYWNoIHJlcXVlc3QuICBUaGVzZSBNVVNUIGJlIHNldCBpZiB5b3UgYXJlXHJcbiAgICogdXNpbmcgdGhlIGxvZ2dlci4gIEZpZWxkcyBpbmNsdWRlOlxyXG4gICAqXHJcbiAgICogLSBwcm9ncmFtIChSRVFVSVJFRCwgdGhlIGFwcGxpY2F0aW9uIHdpZGUgY29kZSlcclxuICAgKiAtIGFwcGxpY2F0aW9uSWQgKFJFUVVJUkVELCBsaWtlIHNlc3Npb25JZClcclxuICAgKiAtIHJlcXVlc3RfbWV0aG9kIChSRVFVSVJFRCwgJ1BPU1QnKVxyXG4gICAqIC0gbG9nc291cmNlOiAoUkVRVUlSRUQsIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSlcclxuICAgKiAtIGh0dHBfeF9mb3J3YXJkZWRfaG9zdCAoUkVRVUlSRUQsIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSlcclxuICAgKlxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBfaGVhZGVyczogSHR0cEhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoe1xyXG4gICAgcmVxdWVzdF9tZXRob2Q6ICdQT1NUJyxcclxuICAgIGxvZ3NvdXJjZTogd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lLFxyXG4gICAgaHR0cF94X2ZvcndhcmRlZF9ob3N0OiB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWVcclxuICB9KTtcclxuXHJcbiAgcHJpdmF0ZSB1cmw6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBodHRwOiBIdHRwQ2xpZW50KSB7XHJcbiAgICBzdXBlcihodHRwKTtcclxuICB9XHJcblxyXG4gIHNldCBhcHBsaWNhdGlvbklkKCBpZDogc3RyaW5nICkge1xyXG4gICAgdGhpcy5faGVhZGVycyA9IHRoaXMuX2hlYWRlcnMuc2V0KCAnYXBwbGljYXRpb25JZCcsIGlkICk7XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwbGljYXRpb25JZCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzLmdldCggJ2FwcGxpY2F0aW9uSWQnICk7XHJcbiAgfVxyXG5cclxuICBzZXQgcHJvZ3JhbU5hbWUoIG5hbWU6IHN0cmluZyApIHtcclxuICAgIHRoaXMuX2hlYWRlcnMgPSB0aGlzLl9oZWFkZXJzLnNldCggJ3Byb2dyYW0nLCBuYW1lICk7XHJcbiAgfVxyXG5cclxuICBnZXQgcHJvZ3JhbU5hbWUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5faGVhZGVycy5nZXQoICduYW1lJyApO1xyXG4gIH1cclxuXHJcbiAgc2V0VVJMKG5ld1VSTDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnVybCA9IG5ld1VSTDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBsb2coIG1lc3NhZ2U6IGFueSApIHtcclxuICAgIHRoaXMuX2xvZyggbWVzc2FnZSBhcyBDb21tb25Mb2dNZXNzYWdlICk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbG9nRXJyb3IoIGVycm9yTWVzc2FnZTogYW55ICkge1xyXG4gICAgdGhpcy5fbG9nRXJyb3IoIGVycm9yTWVzc2FnZSBhcyBDb21tb25Mb2dNZXNzYWdlICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2cgYSBtZXNzYWdlIHRvIFNwbHVuay4gVGhpcyBpcyB0aGUgbWFpbiB3YXkgdG8gc2VuZCBsb2dzIGFuZFxyXG4gICAqIGF1dG9tYXRpY2FsbHkgaW5jbHVkZXMgbWV0YS1kYXRhLiBZb3UgZG8gKipub3QqKiBuZWVkIHRvIHN1YnNjcmliZSB0byB0aGVcclxuICAgKiByZXNwb25zZSwgYXMgdGhlIHNlcnZpY2UgYWxyZWFkeSBkb2VzIHRoYXQuIFRoZSBpbnB1dCBvYmplY3QgbXVzdCBoYXZlIGFuXHJcbiAgICogJ2V2ZW50JyBwcm9wZXJ0eSBzZXQsIGV2ZXJ5dGhpbmcgZWxzZSBpcyBvcHRpb25hbC5cclxuICAgKlxyXG4gICAqIEV4YW1wbGU6XHJcbiAgICogYGBgXHJcbiAgICB0aGlzLmxvZ1NlcnZpY2UubG9nKHtcclxuICAgICAgIGV2ZW50OiAnc3VibWlzc2lvbicsXHJcbiAgICAgICBkYXRlT2JqOiBuZXcgRGF0ZSgpXHJcbiAgICB9KTtcclxuICAgIGBgYFxyXG4gICAqIEBwYXJhbSBtZXNzYWdlIEEgSmF2YVNjcmlwdCBvYmplY3QsIG5lc3RpbmcgaXMgZmluZSwgd2l0aCBgZXZlbnRgIHByb3BlcnR5XHJcbiAgICogc2V0LlxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBfbG9nKG1lc3NhZ2U6IENvbW1vbkxvZ01lc3NhZ2UpIHtcclxuICAgIHRoaXMuc2V0U2V2ZXJpdHkoU2V2ZXJpdHlMZXZlbHMuSU5GTyk7XHJcbiAgICByZXR1cm4gdGhpcy5fc2VuZExvZyhtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfbG9nRXJyb3IoZXJyb3JNZXNzYWdlOiBDb21tb25Mb2dNZXNzYWdlKSB7XHJcbiAgICB0aGlzLnNldFNldmVyaXR5KFNldmVyaXR5TGV2ZWxzLkVSUk9SKTtcclxuICAgIHJldHVybiB0aGlzLl9zZW5kTG9nKGVycm9yTWVzc2FnZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2cgSFRUUCBlcnJvcnMsIGUuZy4gd2hlbiBsb3NpbmcgbmV0d29yayBjb25uZWN0aXZpdHkgb3IgcmVjZWl2aW5nIGFuXHJcbiAgICogZXJyb3IgcmVzcG9uc2UgY29kZS5cclxuICAgKi9cclxuICBwdWJsaWMgbG9nSHR0cEVycm9yKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2xvZ0Vycm9yKHtcclxuICAgICAgZXZlbnQ6IENvbW1vbkxvZ0V2ZW50cy5lcnJvcixcclxuICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcclxuICAgICAgZXJyb3JOYW1lOiBlcnJvci5uYW1lLFxyXG4gICAgICBzdGF0dXNUZXh0OiBlcnJvci5zdGF0dXNUZXh0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEludGVybmFsIG1ldGhvZCB0byBzZW5kIGxvZ3MgdG8gU3BsdW5rLCBpbmNsdWRlcyBtZXRhLWRhdGEgZXhjZXB0IHRoYXQnc1xyXG4gICAqIGNvbnNpc3RlbnQgYWNyb3NzIGFsbCByZXF1ZXN0cywgYnV0IG5vdCBzcGVjaWZpYyB2YWx1ZXMgbGlrZSBzZXZlcml0eVxyXG4gICAqIGxldmVsLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIG1lc3NhZ2UgQSBKYXZhU2NyaXB0IG9iamVjdCBvciBhbnl0aGluZyB0aGF0IGNhbiBiZSB0b1N0cmluZygpJ2QsXHJcbiAgICogbGlrZSBEYXRlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfc2VuZExvZyhtZXNzYWdlOiBDb21tb25Mb2dNZXNzYWdlKSB7XHJcbiAgICAvLyBVcGRhdGUgaGVhZGVyc1xyXG4gICAgdGhpcy5zZXRUaW1lc3RhbXAoKTtcclxuICAgIHRoaXMuc2V0VGFncyhtZXNzYWdlLmV2ZW50KTtcclxuXHJcbiAgICBpZiAodGhpcy51cmwgPT09IG51bGwpIHtcclxuICAgICAgICBjb25zdCBtc2cgPSAnVW5hYmxlIHRvIHNlbmQgbG9ncyBhcyBVUkwgYXMgbm90IGJlZW4gc2V0IHZpYSBzZXRVUkwoKSc7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG1zZyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29uZmlndXJlIHJlcXVlc3RcclxuICAgIGNvbnN0IGJvZHkgPSB7IG1lc3NhZ2U6IG1lc3NhZ2UgfTtcclxuXHJcbiAgICAvLyBXZSBjYWxsIC5zdWJzY3JpYmUoKSBoZXJlIGJlY2F1c2Ugd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGUgcmVzcG9uc2UgYW5kXHJcbiAgICAvLyB3ZSB3YW50IHRvIGVuc3VyZSB0aGF0IHdlIG5ldmVyIGZvcmdldCB0byBjYWxsIHN1YnNjcmliZS5cclxuICAgIHJldHVybiB0aGlzLnBvc3QodGhpcy51cmwsIGJvZHkpLnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGhhbmRsZUVycm9yKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgaWYgKGVycm9yLmVycm9yIGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAvLyBDbGllbnQtc2lkZSAvIG5ldHdvcmsgZXJyb3Igb2NjdXJlZFxyXG4gICAgICBjb25zb2xlLmVycm9yKCdBbiBlcnJvciBvY2N1cmVkOiAnLCBlcnJvci5lcnJvci5tZXNzYWdlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybmVkIGFuIHVuc3VjY2Vzc2Z1bCByZXNwb25zZSBjb2RlXHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYEJhY2tlbmQgcmV0dXJuZWQgZXJyb3IgY29kZTogJHtlcnJvci5zdGF0dXN9LiAgRXJyb3IgYm9keTogJHtlcnJvci5lcnJvcn1gKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPdmVyd3JpdGUgdGhlIGluaGVyaXRlZCBodHRwT3B0aW9ucyBzbyB3ZSBjYW4gc2V0IHJlc3BvbnNlVHlwZSB0byB0ZXh0LlxyXG4gICAqIFRoaXMgdXBkYXRlcyBBbmd1bGFyJ3MgcGFyc2luZywgYW5kIGl0IHdvbid0IGVycm9yIG91dCBkdWUgdG8gdGhlIHNlcnZlclxyXG4gICAqIG5vdCByZXNwb25kaW5nIHdpdGggSlNPTi5cclxuICAgKi9cclxuICBwcm90ZWN0ZWQgZ2V0IGh0dHBPcHRpb25zKCk6IGFueSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBoZWFkZXJzOiB0aGlzLl9oZWFkZXJzLFxyXG4gICAgICByZXNwb25zZVR5cGU6ICd0ZXh0J1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIFRPRE86IFJlbW92ZSBtb21lbnQgZGVwZW5kZW5jeVxyXG4gIHByaXZhdGUgc2V0VGltZXN0YW1wKCkge1xyXG4gICAgdGhpcy5faGVhZGVycyA9IHRoaXMuX2hlYWRlcnMuc2V0KCd0aW1lc3RhbXAnLCBtb21lbnQoKS50b0lTT1N0cmluZygpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0U2V2ZXJpdHkoc2V2ZXJpdHk6IFNldmVyaXR5TGV2ZWxzKSB7XHJcbiAgICB0aGlzLl9oZWFkZXJzID0gdGhpcy5faGVhZGVycy5zZXQoJ3NldmVyaXR5Jywgc2V2ZXJpdHkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGhlYWRlcnMgYXJlIGVhc2llciB0byBzZWFyY2ggaW4gc3BsdW5rLCBhbmQgd2UgYXJlbid0IHVzaW5nIHRhZ3MsIHNvXHJcbiAgICogcmVwdXJwb3NlIGl0IHRvIGV2ZW50IHR5cGUuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXRUYWdzKG1lc3NhZ2U6IHN0cmluZyApIHtcclxuICAgIHRoaXMuX2hlYWRlcnMgPSB0aGlzLl9oZWFkZXJzLnNldCgndGFncycsIG1lc3NhZ2UpO1xyXG4gIH1cclxuXHJcbn1cclxuIl19