UNPKG

adal-angular6-wrapper

Version:

Angular 6 ADAL Wrapper. This version is a fork of follwing library for some personal implementation. No Support is available for this version. Original: https://github.com/benbaran/adal-angular4

302 lines (301 loc) 32.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import { bindCallback, timer } from 'rxjs'; import { map } from 'rxjs/operators'; import * as lib from 'adal-angular'; export class AdalService { constructor() { this.context = /** @type {?} */ (null); this.loginRefreshTimer = /** @type {?} */ (null); this.user = { authenticated: false, userName: '', error: '', token: '', profile: {}, loginCached: false }; } /** * @param {?} configOptions * @return {?} */ init(configOptions) { if (!configOptions) { throw new Error('You must set config, when calling init.'); } /** @type {?} */ const existingHash = window.location.hash; /** @type {?} */ 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); window.AuthenticationContext = this.context.constructor; // loginresource is used to set authenticated status 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(); } } /** * @return {?} */ get config() { return this.context.config; } /** * @return {?} */ get userInfo() { return this.user; } /** * @return {?} */ login() { this.context.login(); } /** * @return {?} */ loginInProgress() { return this.context.loginInProgress(); } /** * @return {?} */ logOut() { this.context.logOut(); } /** * @param {?=} removeHash * @return {?} */ handleWindowCallback(removeHash = true) { /** @type {?} */ const hash = window.location.hash; if (this.context.isCallback(hash)) { /** @type {?} */ const requestInfo = this.context.getRequestInfo(hash); this.context.saveTokenFromHash(requestInfo); if (requestInfo.requestType === this.context.REQUEST_TYPE.LOGIN) { this.updateDataFromCache(); this.setupLoginTokenRefreshTimer(); } else if (requestInfo.requestType === this.context.REQUEST_TYPE.RENEW_TOKEN) { this.context.callback = window.parent.callBackMappedToRenewStates[requestInfo.stateResponse]; } if (requestInfo.stateMatch) { if (typeof this.context.callback === 'function') { if (requestInfo.requestType === this.context.REQUEST_TYPE.RENEW_TOKEN) { // Idtoken or Accestoken can be renewed if (requestInfo.parameters['access_token']) { this.context.callback(this.context._getItem(this.context.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']); } else if (requestInfo.parameters['id_token']) { this.context.callback(this.context._getItem(this.context.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']); } else if (requestInfo.parameters['error']) { this.context.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 = ''; } } } } /** * @param {?} resource * @return {?} */ getCachedToken(resource) { return this.context.getCachedToken(resource); } /** * @param {?} resource * @return {?} */ 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]; })); } /** * @return {?} */ 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); } }); })(); } /** * @return {?} */ clearCache() { this.context.clearCache(); } /** * @param {?} resource * @return {?} */ clearCacheForResource(resource) { this.context.clearCacheForResource(resource); } /** * @param {?} message * @return {?} */ info(message) { this.context.info(message); } /** * @param {?} message * @return {?} */ verbose(message) { this.context.verbose(message); } /** * @param {?} url * @return {?} */ getResourceForEndpoint(url) { return this.context.getResourceForEndpoint(url); } /** * @return {?} */ refreshDataFromCache() { this.updateDataFromCache(); } /** * @return {?} */ updateDataFromCache() { /** @type {?} */ const token = this.context.getCachedToken(/** @type {?} */ (this.context.config.loginResource)); this.user.authenticated = token !== null && token.length > 0; /** @type {?} */ 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; } } /** * @return {?} */ refreshLoginToken() { if (!this.user.loginCached) throw ("User not logged in"); this.acquireToken(/** @type {?} */ (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(); }); } /** * @return {?} */ now() { return Math.round(new Date().getTime() / 1000.0); } /** * @return {?} */ get isInCallbackRedirectMode() { return window.location.href.indexOf("#access_token") !== -1 || window.location.href.indexOf("#id_token") !== -1; } ; /** * @return {?} */ setupLoginTokenRefreshTimer() { /** @type {?} */ let exp = this.context._getItem(this.context.CONSTANTS.STORAGE.EXPIRATION_KEY + /** @type {?} */ (this.context.config.loginResource)); /** @type {?} */ let 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.loginRefreshTimer = timer(timerDelay * 1000).subscribe((x) => { this.refreshLoginToken(); }); } } AdalService.decorators = [ { type: Injectable } ]; /** @nocollapse */ AdalService.ctorParameters = () => []; if (false) { /** @type {?} */ AdalService.prototype.context; /** @type {?} */ AdalService.prototype.loginRefreshTimer; /** @type {?} */ AdalService.prototype.user; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYWRhbC1hbmd1bGFyNi13cmFwcGVyLyIsInNvdXJjZXMiOlsiYWRhbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFFQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyQyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUdwQyxNQUFNO0lBZ0JGO3lDQWJtRCxJQUFJO21EQUN0QixJQUFJO29CQUdYO1lBQ3RCLGFBQWEsRUFBRSxLQUFLO1lBQ3BCLFFBQVEsRUFBRSxFQUFFO1lBQ1osS0FBSyxFQUFFLEVBQUU7WUFDVCxLQUFLLEVBQUUsRUFBRTtZQUNULE9BQU8sRUFBRSxFQUFFO1lBQ1gsV0FBVyxFQUFFLEtBQUs7U0FDckI7S0FFZ0I7Ozs7O0lBRVYsSUFBSSxDQUFDLGFBQTBCO1FBQ2xDLEVBQUUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7U0FDOUQ7O1FBR0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7O1FBRTFDLElBQUksV0FBVyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ3ZDLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDZixXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDdkQ7UUFFRCxhQUFhLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQyxXQUFXLElBQUksV0FBVyxDQUFDO1FBQ3JFLGFBQWEsQ0FBQyxxQkFBcUIsR0FB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QUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxjQUFjLHFCQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQSxDQUFDLENBQUM7O1FBR3hILElBQUksVUFBVSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25LLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztZQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqRSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUM5RCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtTQUMzQixDQUFDLENBQUM7Ozs7WUEzT1YsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCJhZGFsLWFuZ3VsYXIuZC50c1wiIC8+XHJcblxyXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBiaW5kQ2FsbGJhY2ssIHRpbWVyIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCAqIGFzIGxpYiBmcm9tICdhZGFsLWFuZ3VsYXInO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgQWRhbFNlcnZpY2Uge1xyXG5cclxuXHJcbiAgICBwcml2YXRlIGNvbnRleHQ6IGFkYWwuQXV0aGVudGljYXRpb25Db250ZXh0ID0gPGFueT5udWxsO1xyXG4gICAgcHJpdmF0ZSBsb2dpblJlZnJlc2hUaW1lciA9IDxhbnk+bnVsbDtcclxuXHJcblxyXG4gICAgcHJpdmF0ZSB1c2VyOiBhZGFsLlVzZXIgPSB7XHJcbiAgICAgICAgYXV0aGVudGljYXRlZDogZmFsc2UsXHJcbiAgICAgICAgdXNlck5hbWU6ICcnLFxyXG4gICAgICAgIGVycm9yOiAnJyxcclxuICAgICAgICB0b2tlbjogJycsXHJcbiAgICAgICAgcHJvZmlsZToge30sXHJcbiAgICAgICAgbG9naW5DYWNoZWQ6IGZhbHNlXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkgeyB9XHJcblxyXG4gICAgcHVibGljIGluaXQoY29uZmlnT3B0aW9uczogYWRhbC5Db25maWcpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIWNvbmZpZ09wdGlvbnMpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbXVzdCBzZXQgY29uZmlnLCB3aGVuIGNhbGxpbmcgaW5pdC4nKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHJlZGlyZWN0IGFuZCBsb2dvdXRfcmVkaXJlY3QgYXJlIHNldCB0byBjdXJyZW50IGxvY2F0aW9uIGJ5IGRlZmF1bHRcclxuICAgICAgICBjb25zdCBleGlzdGluZ0hhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaDtcclxuXHJcbiAgICAgICAgbGV0IHBhdGhEZWZhdWx0ID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgaWYgKGV4aXN0aW5nSGFzaCkge1xyXG4gICAgICAgICAgICBwYXRoRGVmYXVsdCA9IHBhdGhEZWZhdWx0LnJlcGxhY2UoZXhpc3RpbmdIYXNoLCAnJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25maWdPcHRpb25zLnJlZGlyZWN0VXJpID0gY29uZmlnT3B0aW9ucy5yZWRpcmVjdFVyaSB8fCBwYXRoRGVmYXVsdDtcclxuICAgICAgICBjb25maWdPcHRpb25zLnBvc3RMb2dvdXRSZWRpcmVjdFVyaSA9IGNvbmZpZ09wdGlvbnMucG9zdExvZ291dFJlZGlyZWN0VXJpIHx8IHBhdGhEZWZhdWx0O1xyXG5cclxuICAgICAgICAvLyBjcmVhdGUgaW5zdGFuY2Ugd2l0aCBnaXZlbiBjb25maWdcclxuICAgICAgICB0aGlzLmNvbnRleHQgPSBsaWIuaW5qZWN0KGNvbmZpZ09wdGlvbnMpO1xyXG5cclxuICAgICAgICB3aW5kb3cuQXV0aGVudGljYXRpb25Db250ZXh0ID0gdGhpcy5jb250ZXh0LmNvbnN0cnVjdG9yO1xyXG5cclxuICAgICAgICAvLyBsb2dpbnJlc291cmNlIGlzIHVzZWQgdG8gc2V0IGF1dGhlbnRpY2F0ZWQgc3RhdHVzXHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlRGF0YUZyb21DYWNoZSgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy51c2VyLmxvZ2luQ2FjaGVkICYmICF0aGlzLnVzZXIuYXV0aGVudGljYXRlZCAmJiB3aW5kb3cuc2VsZiA9PSB3aW5kb3cudG9wICYmICF0aGlzLmlzSW5DYWxsYmFja1JlZGlyZWN0TW9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hMb2dpblRva2VuKCk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnVzZXIubG9naW5DYWNoZWQgJiYgdGhpcy51c2VyLmF1dGhlbnRpY2F0ZWQgJiYgIXRoaXMubG9naW5SZWZyZXNoVGltZXIgJiYgd2luZG93LnNlbGYgPT0gd2luZG93LnRvcCkge1xyXG4gICAgICAgICAgICB0aGlzLnNldHVwTG9naW5Ub2tlblJlZnJlc2hUaW1lcigpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBjb25maWcoKTogYWRhbC5Db25maWcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY29uZmlnO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgdXNlckluZm8oKTogYWRhbC5Vc2VyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51c2VyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBsb2dpbigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNvbnRleHQubG9naW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbG9naW5JblByb2dyZXNzKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQubG9naW5JblByb2dyZXNzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGxvZ091dCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNvbnRleHQubG9nT3V0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGhhbmRsZVdpbmRvd0NhbGxiYWNrKHJlbW92ZUhhc2g6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xyXG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQuaXNDYWxsYmFjayhoYXNoKSkge1xyXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0SW5mbyA9IHRoaXMuY29udGV4dC5nZXRSZXF1ZXN0SW5mbyhoYXNoKTtcclxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNhdmVUb2tlbkZyb21IYXNoKHJlcXVlc3RJbmZvKTtcclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RJbmZvLnJlcXVlc3RUeXBlID09PSB0aGlzLmNvbnRleHQuUkVRVUVTVF9UWVBFLkxPR0lOKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURhdGFGcm9tQ2FjaGUoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0dXBMb2dpblRva2VuUmVmcmVzaFRpbWVyKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdEluZm8ucmVxdWVzdFR5cGUgPT09IHRoaXMuY29udGV4dC5SRVFVRVNUX1RZUEUuUkVORVdfVE9LRU4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5jYWxsYmFjayA9IHdpbmRvdy5wYXJlbnQuY2FsbEJhY2tNYXBwZWRUb1JlbmV3U3RhdGVzW3JlcXVlc3RJbmZvLnN0YXRlUmVzcG9uc2VdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdEluZm8uc3RhdGVNYXRjaCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmNvbnRleHQuY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVxdWVzdEluZm8ucmVxdWVzdFR5cGUgPT09IHRoaXMuY29udGV4dC5SRVFVRVNUX1RZUEUuUkVORVdfVE9LRU4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWR0b2tlbiBvciBBY2Nlc3Rva2VuIGNhbiBiZSByZW5ld2VkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0SW5mby5wYXJhbWV0ZXJzWydhY2Nlc3NfdG9rZW4nXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmNhbGxiYWNrKHRoaXMuY29udGV4dC5fZ2V0SXRlbSh0aGlzLmNvbnRleHQuQ09OU1RBTlRTLlNUT1JBR0UuRVJST1JfREVTQ1JJUFRJT04pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCByZXF1ZXN0SW5mby5wYXJhbWV0ZXJzWydhY2Nlc3NfdG9rZW4nXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdEluZm8ucGFyYW1ldGVyc1snaWRfdG9rZW4nXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmNhbGxiYWNrKHRoaXMuY29udGV4dC5fZ2V0SXRlbSh0aGlzLmNvbnRleHQuQ09OU1RBTlRTLlNUT1JBR0UuRVJST1JfREVTQ1JJUFRJT04pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCByZXF1ZXN0SW5mby5wYXJhbWV0ZXJzWydpZF90b2tlbiddKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0SW5mby5wYXJhbWV0ZXJzWydlcnJvciddKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuY2FsbGJhY2sodGhpcy5jb250ZXh0Ll9nZXRJdGVtKHRoaXMuY29udGV4dC5DT05TVEFOVFMuU1RPUkFHRS5FUlJPUl9ERVNDUklQVElPTiksIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0Ll9yZW5ld0ZhaWxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSBoYXNoIGZyb20gdXJsXHJcbiAgICAgICAgaWYgKHJlbW92ZUhhc2gpIHtcclxuICAgICAgICAgICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAod2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKCcnLCAnLycsIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSlcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSAnJztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0Q2FjaGVkVG9rZW4ocmVzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuZ2V0Q2FjaGVkVG9rZW4ocmVzb3VyY2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhY3F1aXJlVG9rZW4ocmVzb3VyY2U6IHN0cmluZyk6IE9ic2VydmFibGU8c3RyaW5nIHwgbnVsbD4ge1xyXG4gICAgICAgIHJldHVybiBiaW5kQ2FsbGJhY2s8c3RyaW5nIHwgbnVsbCwgc3RyaW5nIHwgbnVsbD4oKGNhbGxiYWNrKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5hY3F1aXJlVG9rZW4ocmVzb3VyY2UsIChlcnJvcjogc3RyaW5nLCB0b2tlbk91dDogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuZXJyb3IoJ0Vycm9yIHdoZW4gYWNxdWlyaW5nIHRva2VuIGZvciByZXNvdXJjZTogJyArIHJlc291cmNlLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayh0b2tlbk91dCwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pKClcclxuICAgICAgICAgICAgLnBpcGU8c3RyaW5nIHwgbnVsbD4oXHJcbiAgICAgICAgICAgICAgICBtYXAoKHJlc3VsdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzdWx0WzBdICYmIHJlc3VsdFsxXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAocmVzdWx0WzFdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRbMF07XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRVc2VyKCk6IE9ic2VydmFibGU8YWRhbC5Vc2VyIHwgbnVsbD4ge1xyXG4gICAgICAgIHJldHVybiBiaW5kQ2FsbGJhY2s8YWRhbC5Vc2VyIHwgbnVsbD4oKGNhbGxiYWNrKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5nZXRVc2VyKCAoZXJyb3I6IHN0cmluZywgdXNlcj86IGFkYWwuVXNlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmVycm9yKCdFcnJvciB3aGVuIGdldHRpbmcgdXNlcicsIGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodXNlciB8fCBudWxsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY2xlYXJDYWNoZSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXJDYWNoZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBjbGVhckNhY2hlRm9yUmVzb3VyY2UocmVzb3VyY2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhckNhY2hlRm9yUmVzb3VyY2UocmVzb3VyY2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpbmZvKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5pbmZvKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB2ZXJib3NlKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC52ZXJib3NlKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5nZXRSZXNvdXJjZUZvckVuZHBvaW50KHVybCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHB1YmxpYyByZWZyZXNoRGF0YUZyb21DYWNoZSgpIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZURhdGFGcm9tQ2FjaGUoKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVEYXRhRnJvbUNhY2hlKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5jb250ZXh0LmdldENhY2hlZFRva2VuKDxhbnk+dGhpcy5jb250ZXh0LmNvbmZpZy5sb2dpblJlc291cmNlKTtcclxuICAgICAgICB0aGlzLnVzZXIuYXV0aGVudGljYXRlZCA9IHRva2VuICE9PSBudWxsICYmIHRva2VuLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgIGNvbnN0IHVzZXIgPSB0aGlzLmNvbnRleHQuZ2V0Q2FjaGVkVXNlcigpO1xyXG5cclxuICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICB0aGlzLnVzZXIudXNlck5hbWUgPSB1c2VyLnVzZXJOYW1lO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXIucHJvZmlsZSA9IHVzZXIucHJvZmlsZTtcclxuICAgICAgICAgICAgdGhpcy51c2VyLnRva2VuID0gdG9rZW47XHJcbiAgICAgICAgICAgIHRoaXMudXNlci5lcnJvciA9IHRoaXMuY29udGV4dC5nZXRMb2dpbkVycm9yKCk7XHJcbiAgICAgICAgICAgIHRoaXMudXNlci5sb2dpbkNhY2hlZCA9IHRydWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy51c2VyLnVzZXJOYW1lID0gJyc7XHJcbiAgICAgICAgICAgIHRoaXMudXNlci5wcm9maWxlID0ge307XHJcbiAgICAgICAgICAgIHRoaXMudXNlci50b2tlbiA9ICcnO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXIuZXJyb3IgPSB0aGlzLmNvbnRleHQuZ2V0TG9naW5FcnJvcigpO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXIubG9naW5DYWNoZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWZyZXNoTG9naW5Ub2tlbigpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlci5sb2dpbkNhY2hlZCkgdGhyb3cgKFwiVXNlciBub3QgbG9nZ2VkIGluXCIpO1xyXG4gICAgICAgIHRoaXMuYWNxdWlyZVRva2VuKDxhbnk+dGhpcy5jb250ZXh0LmNvbmZpZy5sb2dpblJlc291cmNlKS5zdWJzY3JpYmUoKHRva2VuOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgdGhpcy51c2VyLnRva2VuID0gdG9rZW47XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnVzZXIuYXV0aGVudGljYXRlZCA9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy51c2VyLmF1dGhlbnRpY2F0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51c2VyLmVycm9yID0gJyc7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldHVwTG9naW5Ub2tlblJlZnJlc2hUaW1lcigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgKGVycm9yOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgdGhpcy51c2VyLmF1dGhlbnRpY2F0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy51c2VyLmVycm9yID0gdGhpcy5jb250ZXh0LmdldExvZ2luRXJyb3IoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG5vdygpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMC4wKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldCBpc0luQ2FsbGJhY2tSZWRpcmVjdE1vZGUoKTogYm9vbGVhbiB7XHJcbiAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmRleE9mKFwiI2FjY2Vzc190b2tlblwiKSAhPT0gLTEgfHwgd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZihcIiNpZF90b2tlblwiKSAhPT0gLTE7XHJcbiAgICB9O1xyXG5cclxuICAgIHByaXZhdGUgc2V0dXBMb2dpblRva2VuUmVmcmVzaFRpbWVyKCk6IHZvaWQge1xyXG4gICAgICAgIC8vIEdldCBleHBpcmF0aW9uIG9mIGxvZ2luIHRva2VuXHJcbiAgICAgICAgbGV0IGV4cCA9IHRoaXMuY29udGV4dC5fZ2V0SXRlbSh0aGlzLmNvbnRleHQuQ09OU1RBTlRTLlNUT1JBR0UuRVhQSVJBVElPTl9LRVkgKyA8YW55PnRoaXMuY29udGV4dC5jb25maWcubG9naW5SZXNvdXJjZSk7XHJcblxyXG4gICAgICAgIC8vIEVpdGhlciB3YWl0IHVudGlsIHRoZSByZWZyZXNoIHdpbmRvdyBpcyB2YWxpZCBvciByZWZyZXNoIGluIDEgc2Vjb25kIChtZWFzdXJlZCBpbiBzZWNvbmRzKVxyXG4gICAgICAgIGxldCB0aW1lckRlbGF5ID0gZXhwIC0gdGhpcy5ub3coKSAtICh0aGlzLmNvbnRleHQuY29uZmlnLmV4cGlyZU9mZnNldFNlY29uZHMgfHwgMzAwKSA+IDAgPyBleHAgLSB0aGlzLm5vdygpIC0gKHRoaXMuY29udGV4dC5jb25maWcuZXhwaXJlT2Zmc2V0U2Vjb25kcyB8fCAzMDApIDogMTtcclxuICAgICAgICBpZiAodGhpcy5sb2dpblJlZnJlc2hUaW1lcikgdGhpcy5sb2dpblJlZnJlc2hUaW1lci51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIHRoaXMubG9naW5SZWZyZXNoVGltZXIgPSB0aW1lcih0aW1lckRlbGF5ICogMTAwMCkuc3Vic2NyaWJlKCh4KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaExvZ2luVG9rZW4oKVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH1cclxufVxyXG4iXX0=