@auth0/angular-jwt
Version:
JSON Web Token helper library for Angular
130 lines • 17.7 kB
JavaScript
// tslint:disable:no-bitwise
import { Injectable, Inject } from '@angular/core';
import { JWT_OPTIONS } from './jwtoptions.token';
import * as i0 from "@angular/core";
export class JwtHelperService {
constructor(config = null) {
this.tokenGetter = (config && config.tokenGetter) || function () { };
}
urlBase64Decode(str) {
let output = str.replace(/-/g, '+').replace(/_/g, '/');
switch (output.length % 4) {
case 0: {
break;
}
case 2: {
output += '==';
break;
}
case 3: {
output += '=';
break;
}
default: {
throw new Error('Illegal base64url string!');
}
}
return this.b64DecodeUnicode(output);
}
// credits for decoder goes to https://github.com/atk
b64decode(str) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let output = '';
str = String(str).replace(/=+$/, '');
if (str.length % 4 === 1) {
throw new Error(`'atob' failed: The string to be decoded is not correctly encoded.`);
}
for (
// initialize result and counters
let bc = 0, bs, buffer, idx = 0;
// get next character
(buffer = str.charAt(idx++));
// character found in table? initialize bit storage and add its ascii value;
~buffer &&
((bs = bc % 4 ? bs * 64 + buffer : buffer),
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4)
? (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6))))
: 0) {
// try to find character in table (0-63, not found => -1)
buffer = chars.indexOf(buffer);
}
return output;
}
b64DecodeUnicode(str) {
return decodeURIComponent(Array.prototype.map
.call(this.b64decode(str), (c) => {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
})
.join(''));
}
decodeToken(token = this.tokenGetter()) {
if (token instanceof Promise) {
return token.then(t => this._decodeToken(t));
}
return this._decodeToken(token);
}
_decodeToken(token) {
if (!token || token === '') {
return null;
}
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error(`The inspected token doesn't appear to be a JWT. Check to make sure it has three parts and see https://jwt.io for more.`);
}
const decoded = this.urlBase64Decode(parts[1]);
if (!decoded) {
throw new Error('Cannot decode the token.');
}
return JSON.parse(decoded);
}
getTokenExpirationDate(token = this.tokenGetter()) {
if (token instanceof Promise) {
return token.then(t => this._getTokenExpirationDate(t));
}
return this._getTokenExpirationDate(token);
}
_getTokenExpirationDate(token) {
let decoded;
decoded = this.decodeToken(token);
if (!decoded || !decoded.hasOwnProperty('exp')) {
return null;
}
const date = new Date(0);
date.setUTCSeconds(decoded.exp);
return date;
}
isTokenExpired(token = this.tokenGetter(), offsetSeconds) {
if (token instanceof Promise) {
return token.then(t => this._isTokenExpired(t, offsetSeconds));
}
return this._isTokenExpired(token, offsetSeconds);
}
_isTokenExpired(token, offsetSeconds) {
if (!token || token === '') {
return true;
}
const date = this.getTokenExpirationDate(token);
offsetSeconds = offsetSeconds || 0;
if (date === null) {
return false;
}
return !(date.valueOf() > new Date().valueOf() + offsetSeconds * 1000);
}
getAuthScheme(authScheme, request) {
if (typeof authScheme === 'function') {
return authScheme(request);
}
return authScheme;
}
}
JwtHelperService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: JwtHelperService, deps: [{ token: JWT_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable });
JwtHelperService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: JwtHelperService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: JwtHelperService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [JWT_OPTIONS]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiand0aGVscGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWp3dC9zcmMvbGliL2p3dGhlbHBlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLDRCQUE0QjtBQUU1QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7O0FBR2pELE1BQU0sT0FBTyxnQkFBZ0I7SUFHM0IsWUFBaUMsU0FBYyxJQUFJO1FBQ2pELElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLGNBQWEsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFTSxlQUFlLENBQUMsR0FBVztRQUNoQyxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZELFFBQVEsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDekIsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDTixNQUFNO2FBQ1A7WUFDRCxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNOLE1BQU0sSUFBSSxJQUFJLENBQUM7Z0JBQ2YsTUFBTTthQUNQO1lBQ0QsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDTixNQUFNLElBQUksR0FBRyxDQUFDO2dCQUNkLE1BQU07YUFDUDtZQUNELE9BQU8sQ0FBQyxDQUFDO2dCQUNQLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQzthQUM5QztTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELHFEQUFxRDtJQUM3QyxTQUFTLENBQUMs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UUFFdEIsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLEtBQUssRUFBRSxFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsYUFBYSxHQUFHLGFBQWEsSUFBSSxDQUFDLENBQUM7UUFFbkMsSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFO1lBQ2pCLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVNLGFBQWEsQ0FDbEIsVUFBeUMsRUFDekMsT0FBeUI7UUFFekIsSUFBSSxPQUFPLFVBQVUsS0FBSyxVQUFVLEVBQUU7WUFDcEMsT0FBTyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDNUI7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDOzs4R0EzS1UsZ0JBQWdCLGtCQUdQLFdBQVc7a0hBSHBCLGdCQUFnQjs0RkFBaEIsZ0JBQWdCO2tCQUQ1QixVQUFVOzswQkFJSSxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbi8vIHRzbGludDpkaXNhYmxlOm5vLWJpdHdpc2VcblxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBKV1RfT1BUSU9OUyB9IGZyb20gJy4vand0b3B0aW9ucy50b2tlbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBKd3RIZWxwZXJTZXJ2aWNlIHtcbiAgdG9rZW5HZXR0ZXI6ICgpID0+IHN0cmluZyB8IFByb21pc2U8c3RyaW5nPjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KEpXVF9PUFRJT05TKSBjb25maWc6IGFueSA9IG51bGwpIHtcbiAgICB0aGlzLnRva2VuR2V0dGVyID0gKGNvbmZpZyAmJiBjb25maWcudG9rZW5HZXR0ZXIpIHx8IGZ1bmN0aW9uICgpIHt9O1xuICB9XG5cbiAgcHVibGljIHVybEJhc2U2NERlY29kZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IG91dHB1dCA9IHN0ci5yZXBsYWNlKC8tL2csICcrJykucmVwbGFjZSgvXy9nLCAnLycpO1xuICAgIHN3aXRjaCAob3V0cHV0Lmxlbmd0aCAlIDQpIHtcbiAgICAgIGNhc2UgMDoge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICBvdXRwdXQgKz0gJz09JztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDM6IHtcbiAgICAgICAgb3V0cHV0ICs9ICc9JztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSWxsZWdhbCBiYXNlNjR1cmwgc3RyaW5nIScpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5iNjREZWNvZGVVbmljb2RlKG91dHB1dCk7XG4gIH1cblxuICAvLyBjcmVkaXRzIGZvciBkZWNvZGVyIGdvZXMgdG8gaHR0cHM6Ly9naXRodWIuY29tL2F0a1xuICBwcml2YXRlIGI2NGRlY29kZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY2hhcnMgPVxuICAgICAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JztcbiAgICBsZXQgb3V0cHV0ID0gJyc7XG5cbiAgICBzdHIgPSBTdHJpbmcoc3RyKS5yZXBsYWNlKC89KyQvLCAnJyk7XG5cbiAgICBpZiAoc3RyLmxlbmd0aCAlIDQgPT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCdhdG9iJyBmYWlsZWQ6IFRoZSBzdHJpbmcgdG8gYmUgZGVjb2RlZCBpcyBub3QgY29ycmVjdGx5IGVuY29kZWQuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKFxuICAgICAgLy8gaW5pdGlhbGl6ZSByZXN1bHQgYW5kIGNvdW50ZXJzXG4gICAgICBsZXQgYmMgPSAwLCBiczogYW55LCBidWZmZXI6IGFueSwgaWR4ID0gMDtcbiAgICAgIC8vIGdldCBuZXh0IGNoYXJhY3RlclxuICAgICAgKGJ1ZmZlciA9IHN0ci5jaGFyQXQoaWR4KyspKTtcbiAgICAgIC8vIGNoYXJhY3RlciBmb3VuZCBpbiB0YWJsZT8gaW5pdGlhbGl6ZSBiaXQgc3RvcmFnZSBhbmQgYWRkIGl0cyBhc2NpaSB2YWx1ZTtcbiAgICAgIH5idWZmZXIgJiZcbiAgICAgICgoYnMgPSBiYyAlIDQgPyBicyAqIDY0ICsgYnVmZmVyIDogYnVmZmVyKSxcbiAgICAgIC8vIGFuZCBpZiBub3QgZmlyc3Qgb2YgZWFjaCA0IGNoYXJhY3RlcnMsXG4gICAgICAvLyBjb252ZXJ0IHRoZSBmaXJzdCA4IGJpdHMgdG8gb25lIGFzY2lpIGNoYXJhY3RlclxuICAgICAgYmMrKyAlIDQpXG4gICAgICAgID8gKG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSAmIChicyA+PiAoKC0yICogYmMpICYgNikpKSlcbiAgICAgICAgOiAwXG4gICAgKSB7XG4gICAgICAvLyB0cnkgdG8gZmluZCBjaGFyYWN0ZXIgaW4gdGFibGUgKDAtNjMsIG5vdCBmb3VuZCA9PiAtMSlcbiAgICAgIGJ1ZmZlciA9IGNoYXJzLmluZGV4T2YoYnVmZmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuXG4gIHByaXZhdGUgYjY0RGVjb2RlVW5pY29kZShzdHI6IGFueSkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoXG4gICAgICBBcnJheS5wcm90b3R5cGUubWFwXG4gICAgICAgIC5jYWxsKHRoaXMuYjY0ZGVjb2RlKHN0ciksIChjOiBhbnkpID0+IHtcbiAgICAgICAgICByZXR1cm4gJyUnICsgKCcwMCcgKyBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpKS5zbGljZSgtMik7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcnKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZGVjb2RlVG9rZW48VCA9IGFueT4odG9rZW46IHN0cmluZyk6IFQgfCBudWxsO1xuICBwdWJsaWMgZGVjb2RlVG9rZW48VCA9IGFueT4odG9rZW46IFByb21pc2U8c3RyaW5nPik6IFByb21pc2U8VCB8IG51bGw+O1xuICBwdWJsaWMgZGVjb2RlVG9rZW48VCA9IGFueT4oKTogbnVsbCB8IFQgfCBQcm9taXNlPFQgfCBudWxsPjtcbiAgcHVibGljIGRlY29kZVRva2VuPFQgPSBhbnk+KHRva2VuOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gPSB0aGlzLnRva2VuR2V0dGVyKCkpOiBudWxsIHwgVCB8IFByb21pc2U8VCB8IG51bGw+IHtcbiAgICBpZiAodG9rZW4gaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICByZXR1cm4gdG9rZW4udGhlbih0ID0+IHRoaXMuX2RlY29kZVRva2VuKHQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlVG9rZW4odG9rZW4pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZGVjb2RlVG9rZW48VCA9IGFueT4odG9rZW46IHN0cmluZyk6IG51bGwgfCBUICB7XG4gICAgaWYgKCF0b2tlbiB8fCB0b2tlbiA9PT0gJycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnRzID0gdG9rZW4uc3BsaXQoJy4nKTtcblxuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSBpbnNwZWN0ZWQgdG9rZW4gZG9lc24ndCBhcHBlYXIgdG8gYmUgYSBKV1QuIENoZWNrIHRvIG1ha2Ugc3VyZSBpdCBoYXMgdGhyZWUgcGFydHMgYW5kIHNlZSBodHRwczovL2p3dC5pbyBmb3IgbW9yZS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY29kZWQgPSB0aGlzLnVybEJhc2U2NERlY29kZShwYXJ0c1sxXSk7XG4gICAgaWYgKCFkZWNvZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBkZWNvZGUgdGhlIHRva2VuLicpO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnBhcnNlKGRlY29kZWQpO1xuICB9XG5cbiAgcHVibGljIGdldFRva2VuRXhwaXJhdGlvbkRhdGUodG9rZW46IHN0cmluZyk6IERhdGUgfCBudWxsO1xuICBwdWJsaWMgZ2V0VG9rZW5FeHBpcmF0aW9uRGF0ZSh0b2tlbjogUHJvbWlzZTxzdHJpbmc+KTogUHJvbWlzZTxEYXRlIHwgbnVsbD47XG4gIHB1YmxpYyBnZXRUb2tlbkV4cGlyYXRpb25EYXRlKCk6IG51bGwgfCBEYXRlIHwgUHJvbWlzZTxEYXRlIHwgbnVsbD47XG4gIHB1YmxpYyBnZXRUb2tlbkV4cGlyYXRpb25EYXRlKFxuICAgIHRva2VuOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gPSB0aGlzLnRva2VuR2V0dGVyKClcbiAgKTogRGF0ZSB8IG51bGwgfCBQcm9taXNlPERhdGUgfCBudWxsPiB7XG4gICAgaWYgKHRva2VuIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIHRva2VuLnRoZW4odCA9PiB0aGlzLl9nZXRUb2tlbkV4cGlyYXRpb25EYXRlKHQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZ2V0VG9rZW5FeHBpcmF0aW9uRGF0ZSh0b2tlbik7XG4gIH1cblxuICBwcml2YXRlIF9nZXRUb2tlbkV4cGlyYXRpb25EYXRlKHRva2VuOiBzdHJpbmcpOiBEYXRlIHwgbnVsbCB7XG4gICAgbGV0IGRlY29kZWQ6IGFueTtcbiAgICBkZWNvZGVkID0gdGhpcy5kZWNvZGVUb2tlbih0b2tlbik7XG5cbiAgICBpZiAoIWRlY29kZWQgfHwgIWRlY29kZWQuaGFzT3duUHJvcGVydHkoJ2V4cCcpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoMCk7XG4gICAgZGF0ZS5zZXRVVENTZWNvbmRzKGRlY29kZWQuZXhwKTtcblxuICAgIHJldHVybiBkYXRlO1xuICB9XG5cbiAgcHVibGljIGlzVG9rZW5FeHBpcmVkKHRva2VuPzogdW5kZWZpbmVkLCBvZmZzZXRTZWNvbmRzPzogbnVtYmVyKTogYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj47XG4gIHB1YmxpYyBpc1Rva2VuRXhwaXJlZCh0b2tlbjogc3RyaW5nIHwgbnVsbCwgb2Zmc2V0U2Vjb25kcz86IG51bWJlcik6IGJvb2xlYW47XG4gIHB1YmxpYyBpc1Rva2VuRXhwaXJlZCh0b2tlbjogUHJvbWlzZTxzdHJpbmc+LCBvZmZzZXRTZWNvbmRzPzogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPjtcbiAgcHVibGljIGlzVG9rZW5FeHBpcmVkKFxuICAgIHRva2VuOiB1bmRlZmluZWQgfCBudWxsIHwgc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+ID0gdGhpcy50b2tlbkdldHRlcigpLFxuICAgIG9mZnNldFNlY29uZHM/OiBudW1iZXJcbiAgKTogYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0b2tlbiBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgIHJldHVybiB0b2tlbi50aGVuKHQgPT4gdGhpcy5faXNUb2tlbkV4cGlyZWQodCwgb2Zmc2V0U2Vjb25kcykpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9pc1Rva2VuRXhwaXJlZCh0b2tlbiwgb2Zmc2V0U2Vjb25kcyk7XG4gIH1cblxuICBwcml2YXRlIF9pc1Rva2VuRXhwaXJlZChcbiAgICB0b2tlbjogc3RyaW5nIHwgbnVsbCxcbiAgICBvZmZzZXRTZWNvbmRzPzogbnVtYmVyXG4gICk6IGJvb2xlYW4ge1xuICAgIGlmICghdG9rZW4gfHwgdG9rZW4gPT09ICcnKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZGF0ZSA9IHRoaXMuZ2V0VG9rZW5FeHBpcmF0aW9uRGF0ZSh0b2tlbik7XG4gICAgb2Zmc2V0U2Vjb25kcyA9IG9mZnNldFNlY29uZHMgfHwgMDtcblxuICAgIGlmIChkYXRlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuICEoZGF0ZS52YWx1ZU9mKCkgPiBuZXcgRGF0ZSgpLnZhbHVlT2YoKSArIG9mZnNldFNlY29uZHMgKiAxMDAwKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRBdXRoU2NoZW1lKFxuICAgIGF1dGhTY2hlbWU6IEZ1bmN0aW9uIHwgc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PGFueT5cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIGF1dGhTY2hlbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBhdXRoU2NoZW1lKHJlcXVlc3QpO1xuICAgIH1cblxuICAgIHJldHVybiBhdXRoU2NoZW1lO1xuICB9XG59XG4iXX0=