UNPKG

adal-angular4

Version:
233 lines 31.5 kB
import { __decorate } from "tslib"; // tslint:disable-next-line: no-reference /// <reference path="adal-angular.d.ts" /> import { Injectable, NgZone } from '@angular/core'; import { bindCallback, timer } from 'rxjs'; import { map } from 'rxjs/operators'; import * as lib from 'adal-angular'; import * as i0 from "@angular/core"; let AdalService = class AdalService { constructor(ngZone) { this.ngZone = ngZone; this.context = null; this.loginRefreshTimer = null; this.user = { authenticated: false, userName: '', error: '', token: '', profile: {}, loginCached: false }; } init(configOptions) { if (!configOptions) { throw new Error('You must set config, when calling init.'); } // redirect and logout_redirect are set to current location by default const existingHash = window.location.hash; let pathDefault = window.location.href; if (existingHash) { pathDefault = pathDefault.replace(existingHash, ''); } configOptions.redirectUri = configOptions.redirectUri || pathDefault; configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault; // create instance with given config this.context = lib.inject(configOptions); this.updateDataFromCache(); if (this.user.loginCached && !this.user.authenticated && window.self === window.top && !this.isInCallbackRedirectMode) { this.refreshLoginToken(); } else if (this.user.loginCached && this.user.authenticated && !this.loginRefreshTimer && window.self === window.top) { this.setupLoginTokenRefreshTimer(); } } get config() { return this.context.config; } get userInfo() { return this.user; } login() { this.context.login(); } loginInProgress() { return this.context.loginInProgress(); } logOut() { this.context.logOut(); } handleWindowCallback(removeHash = true) { const hash = window.location.hash; if (this.context.isCallback(hash)) { let isPopup = false; if (this.context._openedWindows.length > 0 && this.context._openedWindows[this.context._openedWindows.length - 1].opener && this.context._openedWindows[this.context._openedWindows.length - 1].opener._adalInstance) { this.context = this.context._openedWindows[this.context._openedWindows.length - 1].opener._adalInstance; isPopup = true; } else if (window.parent && window.parent._adalInstance) { this.context = window.parent._adalInstance; } const requestInfo = this.context.getRequestInfo(hash); this.context.saveTokenFromHash(requestInfo); const callback = this.context._callBackMappedToRenewStates[requestInfo.stateResponse] || this.context.callback; if (requestInfo.requestType === this.context.REQUEST_TYPE.LOGIN) { this.updateDataFromCache(); this.setupLoginTokenRefreshTimer(); } if (requestInfo.stateMatch) { if (typeof callback === 'function') { if (requestInfo.requestType === this.context.REQUEST_TYPE.RENEW_TOKEN) { // Idtoken or Accestoken can be renewed if (requestInfo.parameters.access_token) { callback(this.context._getItem(this.context.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters.access_token); } else if (requestInfo.parameters.id_token) { callback(this.context._getItem(this.context.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters.id_token); } else if (requestInfo.parameters.error) { callback(this.context._getItem(this.context.CONSTANTS.STORAGE.ERROR_DESCRIPTION), null); this.context._renewFailed = true; } } } } } // Remove hash from url if (removeHash) { if (window.location.hash) { if (window.history.replaceState) { window.history.replaceState('', '/', window.location.pathname); } else { window.location.hash = ''; } } } } getCachedToken(resource) { return this.context.getCachedToken(resource); } acquireToken(resource) { return bindCallback((callback) => { this.context.acquireToken(resource, (error, tokenOut) => { if (error) { this.context.error('Error when acquiring token for resource: ' + resource, error); callback(null, error); } else { callback(tokenOut, null); } }); })() .pipe(map((result) => { if (!result[0] && result[1]) { throw (result[1]); } return result[0]; })); } getUser() { return bindCallback((callback) => { this.context.getUser((error, user) => { if (error) { this.context.error('Error when getting user', error); callback(null); } else { callback(user || null); } }); })(); } clearCache() { this.context.clearCache(); } clearCacheForResource(resource) { this.context.clearCacheForResource(resource); } info(message) { this.context.info(message); } verbose(message) { this.context.verbose(message); } getResourceForEndpoint(url) { return this.context.getResourceForEndpoint(url); } refreshDataFromCache() { this.updateDataFromCache(); } updateDataFromCache() { const token = this.context.getCachedToken(this.context.config.loginResource); this.user.authenticated = token !== null && token.length > 0; const user = this.context.getCachedUser(); if (user) { this.user.userName = user.userName; this.user.profile = user.profile; this.user.token = token; this.user.error = this.context.getLoginError(); this.user.loginCached = true; } else { this.user.userName = ''; this.user.profile = {}; this.user.token = ''; this.user.error = this.context.getLoginError(); this.user.loginCached = false; } } refreshLoginToken() { if (!this.user.loginCached) { throw new Error('User not logged in'); } this.acquireToken(this.context.config.loginResource).subscribe((token) => { this.user.token = token; if (this.user.authenticated === false) { this.user.authenticated = true; this.user.error = ''; window.location.reload(); } else { this.setupLoginTokenRefreshTimer(); } }, (error) => { this.user.authenticated = false; this.user.error = this.context.getLoginError(); }); } now() { return Math.round(new Date().getTime() / 1000.0); } get isInCallbackRedirectMode() { return window.location.href.indexOf('#access_token') !== -1 || window.location.href.indexOf('#id_token') !== -1; } setupLoginTokenRefreshTimer() { // Get expiration of login token const exp = this.context._getItem(this.context.CONSTANTS.STORAGE.EXPIRATION_KEY + this.context.config.loginResource); // Either wait until the refresh window is valid or refresh in 1 second (measured in seconds) const timerDelay = exp - this.now() - (this.context.config.expireOffsetSeconds || 300) > 0 ? exp - this.now() - (this.context.config.expireOffsetSeconds || 300) : 1; if (this.loginRefreshTimer) { this.loginRefreshTimer.unsubscribe(); } this.ngZone.runOutsideAngular(() => { this.loginRefreshTimer = timer(timerDelay * 1000).subscribe((x) => { this.refreshLoginToken(); }); }); } }; AdalService.ctorParameters = () => [ { type: NgZone } ]; AdalService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AdalService_Factory() { return new AdalService(i0.ɵɵinject(i0.NgZone)); }, token: AdalService, providedIn: "root" }); AdalService = __decorate([ Injectable({ providedIn: 'root' }) ], AdalService); export { AdalService }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYWRhbC1hbmd1bGFyNC8iLCJzb3VyY2VzIjpbImxpYi9hZGFsLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHlDQUF5QztBQUN6QywwQ0FBMEM7QUFDMUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDOztBQUtwQyxJQUFhLFdBQVcsR0FBeEIsTUFBYSxXQUFXO0lBZXRCLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBYjFCLFlBQU8sR0FBK0IsSUFBVyxDQUFDO1FBQ2xELHNCQUFpQixHQUFHLElBQVcsQ0FBQztRQUdoQyxTQUFJLEdBQWM7WUFDeEIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsUUFBUSxFQUFFLEVBQUU7WUFDWixLQUFLLEVBQUUsRUFBRTtZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsT0FBTyxFQUFFLEVBQUU7WUFDWCxXQUFXLEVBQUUsS0FBSztTQUNuQixDQUFDO0lBRW9DLENBQUM7SUFFaEMsSUFBSSxDQUFDLGFBQTBCO1FBQ3BDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1NBQzVEO1FBRUQsc0VBQXNFO1FBQ3RFLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBRTFDLElBQUksV0FBVyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ3ZDLElBQUksWUFBWSxFQUFFO1lBQ2hCLFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLFlBQVks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R0FDVyxXQUFXLENBNlF2QjtTQTdRWSxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1yZWZlcmVuY2Vcbi8vLyA8cmVmZXJlbmNlIHBhdGg9XCJhZGFsLWFuZ3VsYXIuZC50c1wiIC8+XG5pbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGJpbmRDYWxsYmFjaywgdGltZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCAqIGFzIGxpYiBmcm9tICdhZGFsLWFuZ3VsYXInO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBBZGFsU2VydmljZSB7XG5cbiAgcHJpdmF0ZSBjb250ZXh0OiBhZGFsLkF1dGhlbnRpY2F0aW9uQ29udGV4dCA9IG51bGwgYXMgYW55O1xuICBwcml2YXRlIGxvZ2luUmVmcmVzaFRpbWVyID0gbnVsbCBhcyBhbnk7XG5cblxuICBwcml2YXRlIHVzZXI6IGFkYWwuVXNlciA9IHtcbiAgICBhdXRoZW50aWNhdGVkOiBmYWxzZSxcbiAgICB1c2VyTmFtZTogJycsXG4gICAgZXJyb3I6ICcnLFxuICAgIHRva2VuOiAnJyxcbiAgICBwcm9maWxlOiB7fSxcbiAgICBsb2dpbkNhY2hlZDogZmFsc2VcbiAgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5nWm9uZTogTmdab25lKSB7IH1cblxuICBwdWJsaWMgaW5pdChjb25maWdPcHRpb25zOiBhZGFsLkNvbmZpZyk6IHZvaWQge1xuICAgIGlmICghY29uZmlnT3B0aW9ucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbXVzdCBzZXQgY29uZmlnLCB3aGVuIGNhbGxpbmcgaW5pdC4nKTtcbiAgICB9XG5cbiAgICAvLyByZWRpcmVjdCBhbmQgbG9nb3V0X3JlZGlyZWN0IGFyZSBzZXQgdG8gY3VycmVudCBsb2NhdGlvbiBieSBkZWZhdWx0XG4gICAgY29uc3QgZXhpc3RpbmdIYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2g7XG5cbiAgICBsZXQgcGF0aERlZmF1bHQgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcbiAgICBpZiAoZXhpc3RpbmdIYXNoKSB7XG4gICAgICBwYXRoRGVmYXVsdCA9IHBhdGhEZWZhdWx0LnJlcGxhY2UoZXhpc3RpbmdIYXNoLCAnJyk7XG4gICAgfVxuXG4gICAgY29uZmlnT3B0aW9ucy5yZWRpcmVjdFVyaSA9IGNvbmZpZ09wdGlvbnMucmVkaXJlY3RVcmkgfHwgcGF0aERlZmF1bHQ7XG4gICAgY29uZmlnT3B0aW9ucy5wb3N0TG9nb3V0UmVkaXJlY3RVcmkgPSBjb25maWdPcHRpb25zLnBvc3RMb2dvdXRSZWRpcmVjdFVyaSB8fCBwYXRoRGVmYXVsdDtcblxuICAgIC8vIGNyZWF0ZSBpbnN0YW5jZSB3aXRoIGdpdmVuIGNvbmZpZ1xuICAgIHRoaXMuY29udGV4dCA9IGxpYi5pbmplY3QoY29uZmlnT3B0aW9ucyk7XG5cbiAgICB0aGlzLnVwZGF0ZURhdGFGcm9tQ2FjaGUoKTtcblxuICAgIGlmICh0aGlzLnVzZXIubG9naW5DYWNoZWQgJiYgIXRoaXMudXNlci5hdXRoZW50aWNhdGVkICYmIHdpbmRvdy5zZWxmID09PSB3aW5kb3cudG9wICYmICF0aGlzLmlzSW5DYWxsYmFja1JlZGlyZWN0TW9kZSkge1xuICAgICAgdGhpcy5yZWZyZXNoTG9naW5Ub2tlbigpO1xuICAgIH0gZWxzZSBpZiAodGhpcy51c2VyLmxvZ2luQ2FjaGVkICYmIHRoaXMudXNlci5hdXRoZW50aWNhdGVkICYmICF0aGlzLmxvZ2luUmVmcmVzaFRpbWVyICYmIHdpbmRvdy5zZWxmID09PSB3aW5kb3cudG9wKSB7XG4gICAgICB0aGlzLnNldHVwTG9naW5Ub2tlblJlZnJlc2hUaW1lcigpO1xuICAgIH1cblxuICB9XG5cbiAgcHVibGljIGdldCBjb25maWcoKTogYWRhbC5Db25maWcge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQuY29uZmlnO1xuICB9XG5cbiAgcHVibGljIGdldCB1c2VySW5mbygpOiBhZGFsLlVzZXIge1xuICAgIHJldHVybiB0aGlzLnVzZXI7XG4gIH1cblxuICBwdWJsaWMgbG9naW4oKTogdm9pZCB7XG4gICAgdGhpcy5jb250ZXh0LmxvZ2luKCk7XG4gIH1cblxuICBwdWJsaWMgbG9naW5JblByb2dyZXNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQubG9naW5JblByb2dyZXNzKCk7XG4gIH1cblxuICBwdWJsaWMgbG9nT3V0KCk6IHZvaWQge1xuICAgIHRoaXMuY29udGV4dC5sb2dPdXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVXaW5kb3dDYWxsYmFjayhyZW1vdmVIYXNoOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgIGNvbnN0IGhhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaDtcbiAgICBpZiAodGhpcy5jb250ZXh0LmlzQ2FsbGJhY2soaGFzaCkpIHtcbiAgICAgIGxldCBpc1BvcHVwID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLmNvbnRleHQuX29wZW5lZFdpbmRvd3MubGVuZ3RoID4gMFxuICAgICAgICAmJiB0aGlzLmNvbnRleHQuX29wZW5lZFdpbmRvd3NbdGhpcy5jb250ZXh0Ll9vcGVuZWRXaW5kb3dzLmxlbmd0aCAtIDFdLm9wZW5lclxuICAgICAgICAmJiB0aGlzLmNvbnRleHQuX29wZW5lZFdpbmRvd3NbdGhpcy5jb250ZXh0Ll9vcGVuZWRXaW5kb3dzLmxlbmd0aCAtIDFdLm9wZW5lci5fYWRhbEluc3RhbmNlKSB7XG5cbiAgICAgICAgdGhpcy5jb250ZXh0ID0gdGhpcy5jb250ZXh0Ll9vcGVuZWRXaW5kb3dzW3RoaXMuY29udGV4dC5fb3BlbmVkV2luZG93cy5sZW5ndGggLSAxXS5vcGVuZXIuX2FkYWxJbnN0YW5jZTtcbiAgICAgICAgaXNQb3B1cCA9IHRydWU7XG5cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHdpbmRvdy5wYXJlbnQgJiYgd2luZG93LnBhcmVudC5fYWRhbEluc3RhbmNlKSB7XG5cbiAgICAgICAgdGhpcy5jb250ZXh0ID0gd2luZG93LnBhcmVudC5fYWRhbEluc3RhbmNlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXF1ZXN0SW5mbyA9IHRoaXMuY29udGV4dC5nZXRSZXF1ZXN0SW5mbyhoYXNoKTtcblxuICAgICAgdGhpcy5jb250ZXh0LnNhdmVUb2tlbkZyb21IYXNoKHJlcXVlc3RJbmZvKTtcblxuICAgICAgY29uc3QgY2FsbGJhY2sgPSB0aGlzLmNvbnRleHQuX2NhbGxCYWNrTWFwcGVkVG9SZW5ld1N0YXRlc1tyZXF1ZXN0SW5mby5zdGF0ZVJlc3BvbnNlXSB8fCB0aGlzLmNvbnRleHQuY2FsbGJhY2s7XG5cbiAgICAgIGlmIChyZXF1ZXN0SW5mby5yZXF1ZXN0VHlwZSA9PT0gdGhpcy5jb250ZXh0LlJFUVVFU1RfVFlQRS5MT0dJTikge1xuICAgICAgICB0aGlzLnVwZGF0ZURhdGFGcm9tQ2FjaGUoKTtcbiAgICAgICAgdGhpcy5zZXR1cExvZ2luVG9rZW5SZWZyZXNoVGltZXIoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVlc3RJbmZvLnN0YXRlTWF0Y2gpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGlmIChyZXF1ZXN0SW5mby5yZXF1ZXN0VHlwZSA9PT0gdGhpcy5jb250ZXh0LlJFUVVFU1RfVFlQRS5SRU5FV19UT0tFTikge1xuICAgICAgICAgICAgLy8gSWR0b2tlbiBvciBBY2Nlc3Rva2VuIGNhbiBiZSByZW5ld2VkXG4gICAgICAgICAgICBpZiAocmVxdWVzdEluZm8ucGFyYW1ldGVycy5hY2Nlc3NfdG9rZW4pIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb250ZXh0Ll9nZXRJdGVtKHRoaXMuY29udGV4dC5DT05TVEFOVFMuU1RPUkFHRS5FUlJPUl9ERVNDUklQVElPTilcbiAgICAgICAgICAgICAgICAsIHJlcXVlc3RJbmZvLnBhcmFtZXRlcnMuYWNjZXNzX3Rva2VuKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdEluZm8ucGFyYW1ldGVycy5pZF90b2tlbikge1xuICAgICAgICAgICAgICBjYWxsYmFjayh0aGlzLmNvbnRleHQuX2dldEl0ZW0odGhpcy5jb250ZXh0LkNPTlNUQU5UUy5TVE9SQUdFLkVSUk9SX0RFU0NSSVBUSU9OKVxuICAgICAgICAgICAgICAgICwgcmVxdWVzdEluZm8ucGFyYW1ldGVycy5pZF90b2tlbik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3RJbmZvLnBhcmFtZXRlcnMuZXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5jb250ZXh0Ll9nZXRJdGVtKHRoaXMuY29udGV4dC5DT05TVEFOVFMuU1RPUkFHRS5FUlJPUl9ERVNDUklQVElPTiksIG51bGwpO1xuICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuX3JlbmV3RmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgaGFzaCBmcm9tIHVybFxuICAgIGlmIChyZW1vdmVIYXNoKSB7XG4gICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhhc2gpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSkge1xuICAgICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSgnJywgJy8nLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gJyc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2FjaGVkVG9rZW4ocmVzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQuZ2V0Q2FjaGVkVG9rZW4ocmVzb3VyY2UpO1xuICB9XG5cbiAgcHVibGljIGFjcXVpcmVUb2tlbihyZXNvdXJjZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgcmV0dXJuIGJpbmRDYWxsYmFjazxzdHJpbmcgfCBudWxsLCBzdHJpbmcgfCBudWxsPigoY2FsbGJhY2spID0+IHtcbiAgICAgIHRoaXMuY29udGV4dC5hY3F1aXJlVG9rZW4ocmVzb3VyY2UsIChlcnJvcjogc3RyaW5nLCB0b2tlbk91dDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuY29udGV4dC5lcnJvcignRXJyb3Igd2hlbiBhY3F1aXJpbmcgdG9rZW4gZm9yIHJlc291cmNlOiAnICsgcmVzb3VyY2UsIGVycm9yKTtcbiAgICAgICAgICBjYWxsYmFjayhudWxsLCBlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FsbGJhY2sodG9rZW5PdXQsIG51bGwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KSgpXG4gICAgICAucGlwZTxzdHJpbmcgfCBudWxsPihcbiAgICAgICAgbWFwKChyZXN1bHQpID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdFswXSAmJiByZXN1bHRbMV0pIHtcbiAgICAgICAgICAgIHRocm93IChyZXN1bHRbMV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZXN1bHRbMF07XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG5cbiAgcHVibGljIGdldFVzZXIoKTogT2JzZXJ2YWJsZTxhZGFsLlVzZXIgfCBudWxsPiB7XG4gICAgcmV0dXJuIGJpbmRDYWxsYmFjazxhZGFsLlVzZXIgfCBudWxsPigoY2FsbGJhY2spID0+IHtcbiAgICAgIHRoaXMuY29udGV4dC5nZXRVc2VyKChlcnJvcjogc3RyaW5nLCB1c2VyPzogYWRhbC5Vc2VyKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuY29udGV4dC5lcnJvcignRXJyb3Igd2hlbiBnZXR0aW5nIHVzZXInLCBlcnJvcik7XG4gICAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FsbGJhY2sodXNlciB8fCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSkoKTtcbiAgfVxuXG4gIHB1YmxpYyBjbGVhckNhY2hlKCk6IHZvaWQge1xuICAgIHRoaXMuY29udGV4dC5jbGVhckNhY2hlKCk7XG4gIH1cblxuICBwdWJsaWMgY2xlYXJDYWNoZUZvclJlc291cmNlKHJlc291cmNlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRleHQuY2xlYXJDYWNoZUZvclJlc291cmNlKHJlc291cmNlKTtcbiAgfVxuXG4gIHB1YmxpYyBpbmZvKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29udGV4dC5pbmZvKG1lc3NhZ2UpO1xuICB9XG5cbiAgcHVibGljIHZlcmJvc2UobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jb250ZXh0LnZlcmJvc2UobWVzc2FnZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmVzb3VyY2VGb3JFbmRwb2ludCh1cmw6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQuZ2V0UmVzb3VyY2VGb3JFbmRwb2ludCh1cmwpO1xuICB9XG5cblxuICBwdWJsaWMgcmVmcmVzaERhdGFGcm9tQ2FjaGUoKSB7XG4gICAgdGhpcy51cGRhdGVEYXRhRnJvbUNhY2hlKCk7XG5cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRGF0YUZyb21DYWNoZSgpOiB2b2lkIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuY29udGV4dC5nZXRDYWNoZWRUb2tlbih0aGlzLmNvbnRleHQuY29uZmlnLmxvZ2luUmVzb3VyY2UgYXMgYW55KTtcbiAgICB0aGlzLnVzZXIuYXV0aGVudGljYXRlZCA9IHRva2VuICE9PSBudWxsICYmIHRva2VuLmxlbmd0aCA+IDA7XG5cbiAgICBjb25zdCB1c2VyID0gdGhpcy5jb250ZXh0LmdldENhY2hlZFVzZXIoKTtcblxuICAgIGlmICh1c2VyKSB7XG4gICAgICB0aGlzLnVzZXIudXNlck5hbWUgPSB1c2VyLnVzZXJOYW1lO1xuICAgICAgdGhpcy51c2VyLnByb2ZpbGUgPSB1c2VyLnByb2ZpbGU7XG4gICAgICB0aGlzLnVzZXIudG9rZW4gPSB0b2tlbjtcbiAgICAgIHRoaXMudXNlci5lcnJvciA9IHRoaXMuY29udGV4dC5nZXRMb2dpbkVycm9yKCk7XG4gICAgICB0aGlzLnVzZXIubG9naW5DYWNoZWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVzZXIudXNlck5hbWUgPSAnJztcbiAgICAgIHRoaXMudXNlci5wcm9maWxlID0ge307XG4gICAgICB0aGlzLnVzZXIudG9rZW4gPSAnJztcbiAgICAgIHRoaXMudXNlci5lcnJvciA9IHRoaXMuY29udGV4dC5nZXRMb2dpbkVycm9yKCk7XG4gICAgICB0aGlzLnVzZXIubG9naW5DYWNoZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlZnJlc2hMb2dpblRva2VuKCk6IHZvaWQge1xuXG4gICAgaWYgKCF0aGlzLnVzZXIubG9naW5DYWNoZWQpIHtcblxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLmFjcXVpcmVUb2tlbih0aGlzLmNvbnRleHQuY29uZmlnLmxvZ2luUmVzb3VyY2UgYXMgYW55KS5zdWJzY3JpYmUoKHRva2VuOiBzdHJpbmcpID0+IHtcblxuICAgICAgdGhpcy51c2VyLnRva2VuID0gdG9rZW47XG5cbiAgICAgIGlmICh0aGlzLnVzZXIuYXV0aGVudGljYXRlZCA9PT0gZmFsc2UpIHtcblxuICAgICAgICB0aGlzLnVzZXIuYXV0aGVudGljYXRlZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy51c2VyLmVycm9yID0gJyc7XG5cbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuXG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIHRoaXMuc2V0dXBMb2dpblRva2VuUmVmcmVzaFRpbWVyKCk7XG4gICAgICB9XG4gICAgfSwgKGVycm9yOiBzdHJpbmcpID0+IHtcblxuICAgICAgdGhpcy51c2VyLmF1dGhlbnRpY2F0ZWQgPSBmYWxzZTtcblxuICAgICAgdGhpcy51c2VyLmVycm9yID0gdGhpcy5jb250ZXh0LmdldExvZ2luRXJyb3IoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbm93KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwLjApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgaXNJbkNhbGxiYWNrUmVkaXJlY3RNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmRleE9mKCcjYWNjZXNzX3Rva2VuJykgIT09IC0xIHx8IHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoJyNpZF90b2tlbicpICE9PSAtMTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBMb2dpblRva2VuUmVmcmVzaFRpbWVyKCk6IHZvaWQge1xuICAgIC8vIEdldCBleHBpcmF0aW9uIG9mIGxvZ2luIHRva2VuXG4gICAgY29uc3QgZXhwID0gdGhpcy5jb250ZXh0Ll9nZXRJdGVtKHRoaXMuY29udGV4dC5DT05TVEFOVFMuU1RPUkFHRS5FWFBJUkFUSU9OX0tFWSArICh0aGlzLmNvbnRleHQuY29uZmlnLmxvZ2luUmVzb3VyY2UgYXMgYW55KSk7XG5cbiAgICAvLyBFaXRoZXIgd2FpdCB1bnRpbCB0aGUgcmVmcmVzaCB3aW5kb3cgaXMgdmFsaWQgb3IgcmVmcmVzaCBpbiAxIHNlY29uZCAobWVhc3VyZWQgaW4gc2Vjb25kcylcbiAgICBjb25zdCB0aW1lckRlbGF5ID0gZXhwIC0gdGhpcy5ub3coKSAtICh0aGlzLmNvbnRleHQuY29uZmlnLmV4cGlyZU9mZnNldFNlY29uZHMgfHwgMzAwKSA+IDBcbiAgICAgID8gZXhwIC0gdGhpcy5ub3coKSAtICh0aGlzLmNvbnRleHQuY29uZmlnLmV4cGlyZU9mZnNldFNlY29uZHMgfHwgMzAwKSA6IDE7XG5cbiAgICBpZiAodGhpcy5sb2dpblJlZnJlc2hUaW1lcikgeyB0aGlzLmxvZ2luUmVmcmVzaFRpbWVyLnVuc3Vic2NyaWJlKCk7IH1cblxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblxuICAgICAgdGhpcy5sb2dpblJlZnJlc2hUaW1lciA9IHRpbWVyKHRpbWVyRGVsYXkgKiAxMDAwKS5zdWJzY3JpYmUoKHgpID0+IHtcblxuICAgICAgICB0aGlzLnJlZnJlc2hMb2dpblRva2VuKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuIl19