@brionmario-experimental/asgardeo-auth-spa
Version:
Asgardeo Auth SPA SDK to be used in Single-Page Applications.
430 lines • 375 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).AsgardeoAuth={})}(this,(function(e){"use strict";function t(e,t,l,i){return new(l||(l=Promise))((function(n,o){function d(e){try{a(i.next(e))}catch(e){o(e)}}function c(e){try{a(i.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?n(e.value):(t=e.value,t instanceof l?t:new l((function(e){e(t)}))).then(d,c)}a((i=i.apply(e,t||[])).next())}))}function l(e,t,l,i){return new(l||(l=Promise))((function(n,o){function d(e){try{a(i.next(e))}catch(e){o(e)}}function c(e){try{a(i.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?n(e.value):(t=e.value,t instanceof l?t:new l((function(e){e(t)}))).then(d,c)}a((i=i.apply(e,t||[])).next())}))}e.ResponseMode=void 0,function(e){e.formPost="form_post",e.query="query",e.direct="direct"}(e.ResponseMode||(e.ResponseMode={}));e.Stores=void 0,function(e){e.ConfigData="config_data",e.OIDCProviderMetaData="oidc_provider_meta_data",e.SessionData="session_data",e.TemporaryData="temporary_data"}(e.Stores||(e.Stores={}));const i="refresh_token_timer",n=["RS256","RS512","RS384","PS256"],o="code",d="session_state",c="sign_out_url",a="sign_out_success",s="state";var Z;!function(e){e.Include="include",e.SameOrigin="same-origin",e.Omit="omit"}(Z||(Z={}));class r{constructor(e,t,l){this.message=l,this.name=t,this.code=e,Object.setPrototypeOf(this,new.target.prototype)}}class u{constructor(){}static filterClaimsFromIDTokenPayload(e){const t=Object.assign({},e);null==t||delete t.iss,null==t||delete t.aud,null==t||delete t.exp,null==t||delete t.iat,null==t||delete t.acr,null==t||delete t.amr,null==t||delete t.azp,null==t||delete t.auth_time,null==t||delete t.nonce,null==t||delete t.c_hash,null==t||delete t.at_hash,null==t||delete t.nbf,null==t||delete t.isk,null==t||delete t.sid;const l={};return Object.entries(t).forEach((([e,t])=>{const i=e.split("_").map(((e,t)=>0===t?e:[e[0].toUpperCase(),...e.slice(1)].join(""))).join("");l[i]=t})),l}static getTokenRequestHeaders(){return{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"}}static generateStateParamForRequestCorrelation(e,t){const l=parseInt(e.split("#")[1]);return t?`${t}_request_${l}`:`request_${l}`}static extractPKCEKeyFromStateParam(e){return`pkce_code_verifier#${parseInt(e.split("request_")[1])}`}}u.getTenantDomainFromIdTokenPayload=(e,t="@")=>{const l=e.sub.split(t);return l.length>2?l[l.length-1]:""};class b{constructor(e,t){this._dataLayer=e,this._config=()=>l(this,void 0,void 0,(function*(){return yield this._dataLayer.getConfigData()})),this._oidcProviderMetaData=()=>l(this,void 0,void 0,(function*(){return yield this._dataLayer.getOIDCProviderMetaData()})),this._cryptoHelper=t}resolveEndpoints(e){return l(this,void 0,void 0,(function*(){const t={},l=yield this._config();return l.endpoints&&Object.keys(l.endpoints).forEach((e=>{const i=e.replace(/[A-Z]/g,(e=>`_${e.toLowerCase()}`));t[i]=(null==l?void 0:l.endpoints)?l.endpoints[e]:""})),Object.assign(Object.assign({},e),t)}))}resolveEndpointsExplicitly(){return l(this,void 0,void 0,(function*(){const e={},t=yield this._config();if(!t.endpoints||!["authorization_endpoint","end_session_endpoint","jwks_uri","check_session_iframe","revocation_endpoint","token_endpoint","issuer","userinfo_endpoint"].every((e=>!!t.endpoints&&Object.keys(t.endpoints).some((t=>t.replace(/[A-Z]/g,(e=>`_${e.toLowerCase()}`))===e)))))throw new r("JS-AUTH_HELPER-REE-NF01","Required endpoints missing","Some or all of the required endpoints are missing in the object passed to the `endpoints` attribute of the`AuthConfig` object.");return t.endpoints&&Object.keys(t.endpoints).forEach((l=>{const i=l.replace(/[A-Z]/g,(e=>`_${e.toLowerCase()}`));e[i]=(null==t?void 0:t.endpoints)?t.endpoints[l]:""})),Object.assign({},e)}))}resolveEndpointsByBaseURL(){return l(this,void 0,void 0,(function*(){const e={},t=yield this._config(),l=t.baseUrl;if(!l)throw new r("JS-AUTH_HELPER_REBO-NF01","Base URL not defined.","Base URL is not defined in AuthClient config.");t.endpoints&&Object.keys(t.endpoints).forEach((l=>{const i=l.replace(/[A-Z]/g,(e=>`_${e.toLowerCase()}`));e[i]=(null==t?void 0:t.endpoints)?t.endpoints[l]:""}));const i={authorization_endpoint:`${l}/oauth2/authorize`,end_session_endpoint:`${l}/oidc/logout`,issuer:`${l}/oauth2/token`,jwks_uri:`${l}/oauth2/jwks`,check_session_iframe:`${l}/oidc/checksession`,revocation_endpoint:`${l}/oauth2/revoke`,token_endpoint:`${l}/oauth2/token`,userinfo_endpoint:`${l}/oauth2/userinfo`};return Object.assign(Object.assign({},i),e)}))}validateIdToken(e){var t;return l(this,void 0,void 0,(function*(){const l=(yield this._dataLayer.getOIDCProviderMetaData()).jwks_uri,i=yield this._config();if(!l||0===l.trim().length)throw new r("JS_AUTH_HELPER-VIT-NF01","JWKS endpoint not found.","No JWKS endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the JWKS endpoint passed to the SDK is empty.");let n;try{n=yield fetch(l,{credentials:i.sendCookiesInRequests?Z.Include:Z.SameOrigin})}catch(l){throw new r("JS-AUTH_HELPER-VIT-NE02","Request to jwks endpoint failed.",null!=l?l:"The request sent to get the jwks from the server failed.")}if(200!==n.status||!n.ok)throw new r("JS-AUTH_HELPER-VIT-HE03",`Invalid response status received for jwks request (${n.statusText}).`,yield n.json());const o=(yield this._oidcProviderMetaData()).issuer,{keys:d}=yield n.json(),c=yield this._cryptoHelper.getJWKForTheIdToken(e.split(".")[0],d);return this._cryptoHelper.isValidIdToken(e,c,(yield this._config()).clientID,null!=o?o:"",this._cryptoHelper.decodeIDToken(e).sub,(yield this._config()).clockTolerance,null===(t=(yield this._config()).validateIDTokenIssuer)||void 0===t||t)}))}getAuthenticatedUserInfo(e){var t,l,i,n;const o=this._cryptoHelper.decodeIDToken(e),d=u.getTenantDomainFromIdTokenPayload(o),c=null!==(t=null==o?void 0:o.username)&&void 0!==t?t:"",a=null!==(l=o.given_name)&&void 0!==l?l:"",s=null!==(i=o.family_name)&&void 0!==i?i:"",Z=a&&s?`${a} ${s}`:a||s||"",r=null!==(n=o.preferred_username)&&void 0!==n?n:Z;return Object.assign({displayName:r,tenantDomain:d,username:c},u.filterClaimsFromIDTokenPayload(o))}replaceCustomGrantTemplateTags(e,t){var i;return l(this,void 0,void 0,(function*(){let l="openid";const n=yield this._config(),o=yield this._dataLayer.getSessionData(t);return n.scope&&n.scope.length>0&&(n.scope.includes("openid")||n.scope.push("openid"),l=n.scope.join(" ")),e.replace("{{token}}",o.access_token).replace("{{username}}",this.getAuthenticatedUserInfo(o.id_token).username).replace("{{scope}}",l).replace("{{clientID}}",n.clientID).replace("{{clientSecret}}",null!==(i=n.clientSecret)&&void 0!==i?i:"")}))}clearUserSessionData(e){return l(this,void 0,void 0,(function*(){yield this._dataLayer.removeTemporaryData(e),yield this._dataLayer.removeSessionData(e)}))}handleTokenResponse(e,t){return l(this,void 0,void 0,(function*(){if(200!==e.status||!e.ok)throw new r("JS-AUTH_HELPER-HTR-NE01",`Invalid response status received for token request (${e.statusText}).`,yield e.json());const i=yield e.json();if(i.created_at=(new Date).getTime(),(yield this._config()).validateIDToken)return this.validateIdToken(i.id_token).then((()=>l(this,void 0,void 0,(function*(){yield this._dataLayer.setSessionData(i,t);const e={accessToken:i.access_token,createdAt:i.created_at,expiresIn:i.expires_in,idToken:i.id_token,refreshToken:i.refresh_token,scope:i.scope,tokenType:i.token_type};return Promise.resolve(e)}))));{const e={accessToken:i.access_token,createdAt:i.created_at,expiresIn:i.expires_in,idToken:i.id_token,refreshToken:i.refresh_token,scope:i.scope,tokenType:i.token_type};return yield this._dataLayer.setSessionData(i,t),Promise.resolve(e)}}))}generatePKCEKey(e){var t;return l(this,void 0,void 0,(function*(){const l=yield this._dataLayer.getTemporaryData(e),i=[];Object.keys(l).forEach((e=>{e.startsWith("pkce_code_verifier")&&i.push(e)}));const n=i.sort().pop();return`pkce_code_verifier#${parseInt(null!==(t=null==n?void 0:n.split("#")[1])&&void 0!==t?t:"-1")+1}`}))}}class h{constructor(e){this._cryptoUtils=e}getCodeVerifier(){return this._cryptoUtils.base64URLEncode(this._cryptoUtils.generateRandomBytes(32))}getCodeChallenge(e){return this._cryptoUtils.base64URLEncode(this._cryptoUtils.hashSha256(e))}getJWKForTheIdToken(e,t){const l=JSON.parse(this._cryptoUtils.base64URLDecode(e));for(const e of t)if(l.kid===e.kid)return e;throw new r("JS-CRYPTO_UTIL-GJFTIT-IV01","kid not found.","Failed to find the 'kid' specified in the id_token. 'kid' found in the header : "+l.kid+", Expected values: "+t.map((e=>e.kid)).join(", "))}isValidIdToken(e,t,l,i,o,d,c){return this._cryptoUtils.verifyJwt(e,t,n,l,i,o,d,c).then((e=>e?Promise.resolve(!0):Promise.reject(new r("JS-CRYPTO_HELPER-IVIT-IV01","Invalid ID token.","ID token validation returned false"))))}decodeIDToken(e){try{const t=this._cryptoUtils.base64URLDecode(e.split(".")[1]);return JSON.parse(t)}catch(e){throw new r("JS-CRYPTO_UTIL-DIT-IV01","Decoding ID token failed.",e)}}}class m{constructor(e,t){this._cryptoUtils=t,this._cryptoHelper=new h(t),this._authenticationHelper=new b(e,this._cryptoHelper),this._dataLayer=e,this._config=()=>l(this,void 0,void 0,(function*(){return yield this._dataLayer.getConfigData()})),this._oidcProviderMetaData=()=>l(this,void 0,void 0,(function*(){return yield this._dataLayer.getOIDCProviderMetaData()}))}getAuthorizationURLParams(e,t){var i,n,o;return l(this,void 0,void 0,(function*(){const l=yield this._config(),d=new Map;d.set("response_type","code"),d.set("client_id",l.clientID),l.clientSecret&&l.clientSecret.trim().length>0&&d.set("client_secret",l.clientSecret);let c="openid";l.scope&&l.scope.length>0&&(l.scope.includes("openid")||l.scope.push("openid"),c=l.scope.join(" ")),d.set("scope",c),d.set("redirect_uri",l.signInRedirectURL),l.responseMode&&d.set("response_mode",l.responseMode);const a=yield this._authenticationHelper.generatePKCEKey(t);if(l.enablePKCE){const e=null===(i=this._cryptoHelper)||void 0===i?void 0:i.getCodeVerifier(),l=null===(n=this._cryptoHelper)||void 0===n?void 0:n.getCodeChallenge(e);yield this._dataLayer.setTemporaryDataParameter(a,e,t),d.set("code_challenge_method","S256"),d.set("code_challenge",l)}l.prompt&&d.set("prompt",l.prompt);const s=e;if(s)for(const[e,t]of Object.entries(s))""!=e&&""!=t&&"state"!==e&&d.set(e,t.toString());return d.set("state",u.generateStateParamForRequestCorrelation(a,s?null===(o=s.state)||void 0===o?void 0:o.toString():"")),d}))}getAuthorizationURL(e,t){return l(this,void 0,void 0,(function*(){const l=yield this._dataLayer.getOIDCProviderMetaDataParameter("authorization_endpoint");if(!l||0===l.trim().length)throw new r("JS-AUTH_CORE-GAU-NF01","No authorization endpoint found.","No authorization endpoint was found in the OIDC provider meta data from the well-known endpoint or the authorization endpoint passed to the SDK is empty.");const i=new URL(l),n=yield this.getAuthorizationURLParams(e,t);for(const[e,t]of n.entries())i.searchParams.append(e,t);return i.toString()}))}requestAccessToken(e,t,i,n,o){return l(this,void 0,void 0,(function*(){const l=(yield this._oidcProviderMetaData()).token_endpoint,d=yield this._config();if(!l||0===l.trim().length)throw new r("JS-AUTH_CORE-RAT1-NF01","Token endpoint not found.","No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the token endpoint passed to the SDK is empty.");t&&(yield this._dataLayer.setSessionDataParameter("session_state",t,n));const c=new URLSearchParams;c.set("client_id",d.clientID),d.clientSecret&&d.clientSecret.trim().length>0&&c.set("client_secret",d.clientSecret);const a=e;let s;c.set("code",a),c.set("grant_type","authorization_code"),c.set("redirect_uri",d.signInRedirectURL),(null==o?void 0:o.params)&&Object.entries(o.params).forEach((([e,t])=>{c.append(e,t)})),d.enablePKCE&&(c.set("code_verifier",`${yield this._dataLayer.getTemporaryDataParameter(u.extractPKCEKeyFromStateParam(i),n)}`),yield this._dataLayer.removeTemporaryDataParameter(u.extractPKCEKeyFromStateParam(i),n));try{s=yield fetch(l,{body:c,credentials:d.sendCookiesInRequests?Z.Include:Z.SameOrigin,headers:new Headers(u.getTokenRequestHeaders()),method:"POST"})}catch(l){throw new r("JS-AUTH_CORE-RAT1-NE02","Requesting access token failed",null!=l?l:"The request to get the access token from the server failed.")}if(!s.ok)throw new r("JS-AUTH_CORE-RAT1-HE03",`Requesting access token failed with ${s.statusText}`,yield s.json());return yield this._authenticationHelper.handleTokenResponse(s,n)}))}refreshAccessToken(e){return l(this,void 0,void 0,(function*(){const t=(yield this._oidcProviderMetaData()).token_endpoint,l=yield this._config(),i=yield this._dataLayer.getSessionData(e);if(!i.refresh_token)throw new r("JS-AUTH_CORE-RAT2-NF01","No refresh token found.","There was no refresh token found. Asgardeo doesn't return a refresh token if the refresh token grant is not enabled.");if(!t||0===t.trim().length)throw new r("JS-AUTH_CORE-RAT2-NF02","No refresh token endpoint found.","No refresh token endpoint was in the OIDC provider meta data returned by the well-known endpoint or the refresh token endpoint passed to the SDK is empty.");const n=[];let o;n.push(`client_id=${l.clientID}`),n.push(`refresh_token=${i.refresh_token}`),n.push("grant_type=refresh_token"),l.clientSecret&&l.clientSecret.trim().length>0&&n.push(`client_secret=${l.clientSecret}`);try{o=yield fetch(t,{body:n.join("&"),credentials:l.sendCookiesInRequests?Z.Include:Z.SameOrigin,headers:new Headers(u.getTokenRequestHeaders()),method:"POST"})}catch(t){throw new r("JS-AUTH_CORE-RAT2-NR03","Refresh access token request failed.",null!=t?t:"The request to refresh the access token failed.")}if(!o.ok)throw new r("JS-AUTH_CORE-RAT2-HE04",`Refreshing access token failed with ${o.statusText}`,yield o.json());return this._authenticationHelper.handleTokenResponse(o,e)}))}revokeAccessToken(e){return l(this,void 0,void 0,(function*(){const t=(yield this._oidcProviderMetaData()).revocation_endpoint,l=yield this._config();if(!t||0===t.trim().length)throw new r("JS-AUTH_CORE-RAT3-NF01","No revoke access token endpoint found.","No revoke access token endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the revoke access token endpoint passed to the SDK is empty.");const i=[];let n;i.push(`client_id=${l.clientID}`),i.push(`token=${(yield this._dataLayer.getSessionData(e)).access_token}`),i.push("token_type_hint=access_token");try{n=yield fetch(t,{body:i.join("&"),credentials:l.sendCookiesInRequests?Z.Include:Z.SameOrigin,headers:new Headers(u.getTokenRequestHeaders()),method:"POST"})}catch(t){throw new r("JS-AUTH_CORE-RAT3-NE02","The request to revoke access token failed.",null!=t?t:"The request sent to revoke the access token failed.")}if(200!==n.status||!n.ok)throw new r("JS-AUTH_CORE-RAT3-HE03",`Invalid response status received for revoke access token request (${n.statusText}).`,yield n.json());return this._authenticationHelper.clearUserSessionData(e),Promise.resolve(n)}))}requestCustomGrant(e,t){return l(this,void 0,void 0,(function*(){const i=yield this._oidcProviderMetaData(),n=yield this._config();let o;if(o=e.tokenEndpoint&&0!==e.tokenEndpoint.trim().length?e.tokenEndpoint:i.token_endpoint,!o||0===o.trim().length)throw new r("JS-AUTH_CORE-RCG-NF01","Token endpoint not found.","No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the token endpoint passed to the SDK is empty.");const d=yield Promise.all(Object.entries(e.data).map((([e,i])=>l(this,void 0,void 0,(function*(){const l=yield this._authenticationHelper.replaceCustomGrantTemplateTags(i,t);return`${e}=${l}`})))));let c=Object.assign({},u.getTokenRequestHeaders());e.attachToken&&(c=Object.assign(Object.assign({},c),{Authorization:`Bearer ${(yield this._dataLayer.getSessionData(t)).access_token}`}));const a={body:d.join("&"),credentials:n.sendCookiesInRequests?Z.Include:Z.SameOrigin,headers:new Headers(c),method:"POST"};let s;try{s=yield fetch(o,a)}catch(e){throw new r("JS-AUTH_CORE-RCG-NE02","The custom grant request failed.",null!=e?e:"The request sent to get the custom grant failed.")}if(200!==s.status||!s.ok)throw new r("JS-AUTH_CORE-RCG-HE03",`Invalid response status received for the custom grant request. (${s.statusText})`,yield s.json());return e.returnsSession?this._authenticationHelper.handleTokenResponse(s,t):Promise.resolve(yield s.json())}))}getBasicUserInfo(e){return l(this,void 0,void 0,(function*(){const t=yield this._dataLayer.getSessionData(e),l=this._authenticationHelper.getAuthenticatedUserInfo(null==t?void 0:t.id_token);let i={allowedScopes:t.scope,sessionState:t.session_state};return Object.keys(l).forEach((e=>{void 0!==l[e]&&""!==l[e]&&null!==l[e]||delete l[e]})),i=Object.assign(Object.assign({},i),l),i}))}getDecodedIDToken(e){return l(this,void 0,void 0,(function*(){const t=(yield this._dataLayer.getSessionData(e)).id_token;return this._cryptoHelper.decodeIDToken(t)}))}getCryptoHelper(){return l(this,void 0,void 0,(function*(){return this._cryptoHelper}))}getIDToken(e){return l(this,void 0,void 0,(function*(){return(yield this._dataLayer.getSessionData(e)).id_token}))}getOIDCProviderMetaData(e){return l(this,void 0,void 0,(function*(){const t=yield this._config();if(!e&&(yield this._dataLayer.getTemporaryDataParameter("op_config_initiated")))return Promise.resolve();const l=t.wellKnownEndpoint;if(l){let e;try{if(e=yield fetch(l),200!==e.status||!e.ok)throw new Error}catch(t){throw new r("JS-AUTH_CORE-GOPMD-HE01","Invalid well-known response","The well known endpoint response has been failed with an error.")}return yield this._dataLayer.setOIDCProviderMetaData(yield this._authenticationHelper.resolveEndpoints(yield e.json())),yield this._dataLayer.setTemporaryDataParameter("op_config_initiated",!0),Promise.resolve()}if(t.baseUrl){try{yield this._dataLayer.setOIDCProviderMetaData(yield this._authenticationHelper.resolveEndpointsByBaseURL())}catch(t){throw new r("JS-AUTH_CORE-GOPMD-IV02","Resolving endpoints failed.",null!=t?t:"Resolving endpoints by base url failed.")}return yield this._dataLayer.setTemporaryDataParameter("op_config_initiated",!0),Promise.resolve()}return yield this._dataLayer.setOIDCProviderMetaData(yield this._authenticationHelper.resolveEndpointsExplicitly()),yield this._dataLayer.setTemporaryDataParameter("op_config_initiated",!0),Promise.resolve()}))}getOIDCServiceEndpoints(){var e,t,i,n,o,d,c,a,s,Z;return l(this,void 0,void 0,(function*(){const l=yield this._oidcProviderMetaData();return{authorizationEndpoint:null!==(e=l.authorization_endpoint)&&void 0!==e?e:"",checkSessionIframe:null!==(t=l.check_session_iframe)&&void 0!==t?t:"",endSessionEndpoint:null!==(i=l.end_session_endpoint)&&void 0!==i?i:"",introspectionEndpoint:null!==(n=l.introspection_endpoint)&&void 0!==n?n:"",issuer:null!==(o=l.issuer)&&void 0!==o?o:"",jwksUri:null!==(d=l.jwks_uri)&&void 0!==d?d:"",registrationEndpoint:null!==(c=l.registration_endpoint)&&void 0!==c?c:"",revocationEndpoint:null!==(a=l.revocation_endpoint)&&void 0!==a?a:"",tokenEndpoint:null!==(s=l.token_endpoint)&&void 0!==s?s:"",userinfoEndpoint:null!==(Z=l.userinfo_endpoint)&&void 0!==Z?Z:""}}))}getSignOutURL(e){var t,i,n;return l(this,void 0,void 0,(function*(){const l=null===(t=yield this._oidcProviderMetaData())||void 0===t?void 0:t.end_session_endpoint,o=yield this._config();if(!l||0===l.trim().length)throw new r("JS-AUTH_CORE-GSOU-NF01","Sign-out endpoint not found.","No sign-out endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the sign-out endpoint passed to the SDK is empty.");const d=null!==(i=null==o?void 0:o.signOutRedirectURL)&&void 0!==i?i:null==o?void 0:o.signInRedirectURL;if(!d||0===d.trim().length)throw new r("JS-AUTH_CORE-GSOU-NF03","No sign-out redirect URL found.","The sign-out redirect URL cannot be found or the URL passed to the SDK is empty. No sign-in redirect URL has been found either. ");const c=new URLSearchParams;if(c.set("post_logout_redirect_uri",d),o.sendIdTokenInLogoutRequest){const t=null===(n=yield this._dataLayer.getSessionData(e))||void 0===n?void 0:n.id_token;if(!t||0===t.trim().length)throw new r("JS-AUTH_CORE-GSOU-NF02","ID token not found.","No ID token could be found. Either the session information is lost or you have not signed in.");c.set("id_token_hint",t)}else c.set("client_id",o.clientID);return c.set("state","sign_out_success"),`${l}?${c.toString()}`}))}clearUserSessionData(e){return l(this,void 0,void 0,(function*(){yield this._authenticationHelper.clearUserSessionData(e)}))}getAccessToken(e){var t;return l(this,void 0,void 0,(function*(){return null===(t=yield this._dataLayer.getSessionData(e))||void 0===t?void 0:t.access_token}))}getCreatedAt(e){var t;return l(this,void 0,void 0,(function*(){return null===(t=yield this._dataLayer.getSessionData(e))||void 0===t?void 0:t.created_at}))}getExpiresIn(e){var t;return l(this,void 0,void 0,(function*(){return null===(t=yield this._dataLayer.getSessionData(e))||void 0===t?void 0:t.expires_in}))}isAuthenticated(e){return l(this,void 0,void 0,(function*(){const t=Boolean(yield this.getAccessToken(e)),l=yield this.getCreatedAt(e),i=yield this.getExpiresIn(e);if(!i)return!1;const n=1e3*parseInt(i),o=(new Date).getTime();return t&&l+n>o}))}getPKCECode(e,t){return l(this,void 0,void 0,(function*(){return yield this._dataLayer.getTemporaryDataParameter(u.extractPKCEKeyFromStateParam(e),t)}))}setPKCECode(e,t,i){return l(this,void 0,void 0,(function*(){return yield this._dataLayer.setTemporaryDataParameter(u.extractPKCEKeyFromStateParam(t),e,i)}))}updateConfig(e){return l(this,void 0,void 0,(function*(){yield this._dataLayer.setConfigData(e),yield this.getOIDCProviderMetaData(!0)}))}}class I{constructor(e,t){this._id=e,this._store=t}setDataInBulk(e,t){var i;return l(this,void 0,void 0,(function*(){const l=null!==(i=yield this._store.getData(e))&&void 0!==i?i:null,n=l&&JSON.parse(l),o=Object.assign(Object.assign({},n),t),d=JSON.stringify(o);yield this._store.setData(e,d)}))}setValue(e,t,i){var n;return l(this,void 0,void 0,(function*(){const l=null!==(n=yield this._store.getData(e))&&void 0!==n?n:null,o=l&&JSON.parse(l),d=Object.assign(Object.assign({},o),{[t]:i}),c=JSON.stringify(d);yield this._store.setData(e,c)}))}removeValue(e,t){var i;return l(this,void 0,void 0,(function*(){const l=null!==(i=yield this._store.getData(e))&&void 0!==i?i:null,n=l&&JSON.parse(l),o=Object.assign({},n);delete o[t];const d=JSON.stringify(o);yield this._store.setData(e,d)}))}_resolveKey(e,t){return t?`${e}-${this._id}-${t}`:`${e}-${this._id}`}isLocalStorageAvailable(){try{const e="__ASGARDEO_AUTH_CORE_LOCAL_STORAGE_TEST__";return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}setConfigData(t){return l(this,void 0,void 0,(function*(){yield this.setDataInBulk(this._resolveKey(e.Stores.ConfigData),t)}))}setOIDCProviderMetaData(t){return l(this,void 0,void 0,(function*(){this.setDataInBulk(this._resolveKey(e.Stores.OIDCProviderMetaData),t)}))}setTemporaryData(t,i){return l(this,void 0,void 0,(function*(){this.setDataInBulk(this._resolveKey(e.Stores.TemporaryData,i),t)}))}setSessionData(t,i){return l(this,void 0,void 0,(function*(){this.setDataInBulk(this._resolveKey(e.Stores.SessionData,i),t)}))}setCustomData(e,t,i){return l(this,void 0,void 0,(function*(){this.setDataInBulk(this._resolveKey(e,i),t)}))}getConfigData(){var t;return l(this,void 0,void 0,(function*(){return JSON.parse(null!==(t=yield this._store.getData(this._resolveKey(e.Stores.ConfigData)))&&void 0!==t?t:null)}))}getOIDCProviderMetaData(){var t;return l(this,void 0,void 0,(function*(){return JSON.parse(null!==(t=yield this._store.getData(this._resolveKey(e.Stores.OIDCProviderMetaData)))&&void 0!==t?t:null)}))}getTemporaryData(t){var i;return l(this,void 0,void 0,(function*(){return JSON.parse(null!==(i=yield this._store.getData(this._resolveKey(e.Stores.TemporaryData,t)))&&void 0!==i?i:null)}))}getSessionData(t){var i;return l(this,void 0,void 0,(function*(){return JSON.parse(null!==(i=yield this._store.getData(this._resolveKey(e.Stores.SessionData,t)))&&void 0!==i?i:null)}))}getCustomData(e,t){var i;return l(this,void 0,void 0,(function*(){return JSON.parse(null!==(i=yield this._store.getData(this._resolveKey(e,t)))&&void 0!==i?i:null)}))}setSessionStatus(e){this.isLocalStorageAvailable()&&localStorage.setItem("asgardeo-session-active",e)}getSessionStatus(){var e;return this.isLocalStorageAvailable()&&null!==(e=localStorage.getItem("asgardeo-session-active"))&&void 0!==e?e:""}removeSessionStatus(){this.isLocalStorageAvailable()&&localStorage.removeItem("asgardeo-session-active")}removeConfigData(){return l(this,void 0,void 0,(function*(){yield this._store.removeData(this._resolveKey(e.Stores.ConfigData))}))}removeOIDCProviderMetaData(){return l(this,void 0,void 0,(function*(){yield this._store.removeData(this._resolveKey(e.Stores.OIDCProviderMetaData))}))}removeTemporaryData(t){return l(this,void 0,void 0,(function*(){yield this._store.removeData(this._resolveKey(e.Stores.TemporaryData,t))}))}removeSessionData(t){return l(this,void 0,void 0,(function*(){yield this._store.removeData(this._resolveKey(e.Stores.SessionData,t))}))}getConfigDataParameter(t){return l(this,void 0,void 0,(function*(){const l=yield this._store.getData(this._resolveKey(e.Stores.ConfigData));return l&&JSON.parse(l)[t]}))}getOIDCProviderMetaDataParameter(t){return l(this,void 0,void 0,(function*(){const l=yield this._store.getData(this._resolveKey(e.Stores.OIDCProviderMetaData));return l&&JSON.parse(l)[t]}))}getTemporaryDataParameter(t,i){return l(this,void 0,void 0,(function*(){const l=yield this._store.getData(this._resolveKey(e.Stores.TemporaryData,i));return l&&JSON.parse(l)[t]}))}getSessionDataParameter(t,i){return l(this,void 0,void 0,(function*(){const l=yield this._store.getData(this._resolveKey(e.Stores.SessionData,i));return l&&JSON.parse(l)[t]}))}setConfigDataParameter(t,i){return l(this,void 0,void 0,(function*(){yield this.setValue(this._resolveKey(e.Stores.ConfigData),t,i)}))}setOIDCProviderMetaDataParameter(t,i){return l(this,void 0,void 0,(function*(){yield this.setValue(this._resolveKey(e.Stores.OIDCProviderMetaData),t,i)}))}setTemporaryDataParameter(t,i,n){return l(this,void 0,void 0,(function*(){yield this.setValue(this._resolveKey(e.Stores.TemporaryData,n),t,i)}))}setSessionDataParameter(t,i,n){return l(this,void 0,void 0,(function*(){yield this.setValue(this._resolveKey(e.Stores.SessionData,n),t,i)}))}removeConfigDataParameter(t){return l(this,void 0,void 0,(function*(){yield this.removeValue(this._resolveKey(e.Stores.ConfigData),t)}))}removeOIDCProviderMetaDataParameter(t){return l(this,void 0,void 0,(function*(){yield this.removeValue(this._resolveKey(e.Stores.OIDCProviderMetaData),t)}))}removeTemporaryDataParameter(t,i){return l(this,void 0,void 0,(function*(){yield this.removeValue(this._resolveKey(e.Stores.TemporaryData,i),t)}))}removeSessionDataParameter(t,i){return l(this,void 0,void 0,(function*(){yield this.removeValue(this._resolveKey(e.Stores.SessionData,i),t)}))}}const G={clockTolerance:300,enablePKCE:!0,responseMode:e.ResponseMode.query,scope:["openid"],sendCookiesInRequests:!0,validateIDToken:!0,validateIDTokenIssuer:!0};class p{
/**
* This is the constructor method that returns an instance of the .
*
* @param store - The store object.
*
* @example
* ```
* const _store: Store = new DataStore();
* const auth = new AsgardeoAuthClient<CustomClientConfig>(_store);
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#constructor}
*
* @preserve
*/
constructor(){}
/**
*
* This method initializes the SDK with the config data.
*
* @param config - The config object to initialize with.
*
* @example
* const config = \{
* signInRedirectURL: "http://localhost:3000/sign-in",
* clientID: "client ID",
* baseUrl: "https://localhost:9443"
* \}
*
* await auth.initialize(config);
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#initialize}
*
* @preserve
*/initialize(e,t,i,n){var o,d,c;return l(this,void 0,void 0,(function*(){const l=e.clientID;p._instanceID?p._instanceID+=1:p._instanceID=0,n&&(p._instanceID=n),this._dataLayer=new I(l?`instance_${p._instanceID}-${l}`:`instance_${p._instanceID}`,t),this._authenticationCore=new m(this._dataLayer,i),p._authenticationCore=new m(this._dataLayer,i),yield this._dataLayer.setConfigData(Object.assign(Object.assign(Object.assign({},G),e),{scope:[...null!==(o=G.scope)&&void 0!==o?o:[],...null!==(c=null===(d=e.scope)||void 0===d?void 0:d.filter((e=>{var t;return!(null===(t=null==G?void 0:G.scope)||void 0===t?void 0:t.includes(e))})))&&void 0!==c?c:[]]}))}))}
/**
* This method returns the `DataLayer` object that allows you to access authentication data.
*
* @returns - The `DataLayer` object.
*
* @example
* ```
* const data = auth.getDataLayer();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getDataLayer}
*
* @preserve
*/getDataLayer(){return this._dataLayer}
/**
* This method returns the `instanceID` variable of the given instance.
*
* @returns - The `instanceID` number.
*
* @example
* ```
* const instanceId = auth.getInstanceID();
* ```
*
* @preserve
*/getInstanceID(){return p._instanceID}
/**
* This is an async method that returns a Promise that resolves with the authorization URL parameters.
*
* @param config - (Optional) A config object to force initialization and pass
* custom path parameters such as the `fidp` parameter.
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A promise that resolves with the authorization URL parameters.
*
* @example
* ```
* auth.getAuthorizationURLParams().then((params)=>{
* // console.log(params);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAuthorizationURLParams}
*
* @preserve
*/getAuthorizationURLParams(e,t){return l(this,void 0,void 0,(function*(){const l=Object.assign({},e);return null==l||delete l.forceInit,(yield this._dataLayer.getTemporaryDataParameter("op_config_initiated"))?this._authenticationCore.getAuthorizationURLParams(l,t):this._authenticationCore.getOIDCProviderMetaData(null==e?void 0:e.forceInit).then((()=>this._authenticationCore.getAuthorizationURLParams(l,t)))}))}
/**
* This is an async method that returns a Promise that resolves with the authorization URL.
*
* @param config - (Optional) A config object to force initialization and pass
* custom path parameters such as the fidp parameter.
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A promise that resolves with the authorization URL.
*
* @example
* ```
* auth.getAuthorizationURL().then((url)=>{
* // console.log(url);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAuthorizationURL}
*
* @preserve
*/getAuthorizationURL(e,t){return l(this,void 0,void 0,(function*(){const l=Object.assign({},e);return null==l||delete l.forceInit,(yield this._dataLayer.getTemporaryDataParameter("op_config_initiated"))?this._authenticationCore.getAuthorizationURL(l,t):this._authenticationCore.getOIDCProviderMetaData(null==e?void 0:e.forceInit).then((()=>this._authenticationCore.getAuthorizationURL(l,t)))}))}
/**
* This is an async method that sends a request to obtain the access token and returns a Promise
* that resolves with the token and other relevant data.
*
* @param authorizationCode - The authorization code.
* @param sessionState - The session state.
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the token response.
*
* @example
* ```
* auth.requestAccessToken(authCode, sessionState).then((token)=>{
* // console.log(token);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#requestAccessToken}
*
*
* @preserve
*/requestAccessToken(e,t,i,n,o){return l(this,void 0,void 0,(function*(){return(yield this._dataLayer.getTemporaryDataParameter("op_config_initiated"))?this._authenticationCore.requestAccessToken(e,t,i,n,o):this._authenticationCore.getOIDCProviderMetaData(!1).then((()=>this._authenticationCore.requestAccessToken(e,t,i,n,o)))}))}
/**
* This method returns the sign-out URL.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* **This doesn't clear the authentication data.**
*
* @returns - A Promise that resolves with the sign-out URL.
*
* @example
* ```
* const signOutUrl = await auth.getSignOutURL();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getSignOutURL}
*
* @preserve
*/getSignOutURL(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getSignOutURL(e)}))}
/**
* This method returns OIDC service endpoints that are fetched from the `.well-known` endpoint.
*
* @returns - A Promise that resolves with an object containing the OIDC service endpoints.
*
* @example
* ```
* const endpoints = await auth.getOIDCServiceEndpoints();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getOIDCServiceEndpoints}
*
* @preserve
*/getOIDCServiceEndpoints(){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getOIDCServiceEndpoints()}))}
/**
* This method decodes the payload of the ID token and returns it.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the decoded ID token payload.
*
* @example
* ```
* const decodedIdToken = await auth.getDecodedIDToken();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getDecodedIDToken}
*
* @preserve
*/getDecodedIDToken(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getDecodedIDToken(e)}))}
/**
* This method returns the ID token.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the ID token.
*
* @example
* ```
* const idToken = await auth.getIDToken();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getIDToken}
*
* @preserve
*/getIDToken(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getIDToken(e)}))}
/**
* This method returns the basic user information obtained from the ID token.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with an object containing the basic user information.
*
* @example
* ```
* const userInfo = await auth.getBasicUserInfo();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getBasicUserInfo}
*
* @preserve
*/getBasicUserInfo(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getBasicUserInfo(e)}))}
/**
* This method returns the crypto helper object.
*
* @returns - A Promise that resolves with a CryptoHelper object.
*
* @example
* ```
* const cryptoHelper = await auth.CryptoHelper();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getCryptoHelper}
*
* @preserve
*/getCryptoHelper(){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getCryptoHelper()}))}
/**
* This method revokes the access token.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* **This method also clears the authentication data.**
*
* @returns - A Promise that returns the response of the revoke-access-token request.
*
* @example
* ```
* auth.revokeAccessToken().then((response)=>{
* // console.log(response);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#revokeAccessToken}
*
* @preserve
*/revokeAccessToken(e){return this._authenticationCore.revokeAccessToken(e)}
/**
* This method refreshes the access token and returns a Promise that resolves with the new access
* token and other relevant data.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the token response.
*
* @example
* ```
* auth.refreshAccessToken().then((response)=>{
* // console.log(response);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#refreshAccessToken}
*
* @preserve
*/refreshAccessToken(e){return this._authenticationCore.refreshAccessToken(e)}
/**
* This method returns the access token.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the access token.
*
* @example
* ```
* const accessToken = await auth.getAccessToken();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getAccessToken}
*
* @preserve
*/getAccessToken(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getAccessToken(e)}))}
/**
* This method sends a custom-grant request and returns a Promise that resolves with the response
* depending on the config passed.
*
* @param config - A config object containing the custom grant configurations.
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with the response depending
* on your configurations.
*
* @example
* ```
* const config = {
* attachToken: false,
* data: {
* client_id: "{{clientID}}",
* grant_type: "account_switch",
* scope: "{{scope}}",
* token: "{{token}}",
* },
* id: "account-switch",
* returnResponse: true,
* returnsSession: true,
* signInRequired: true
* }
*
* auth.requestCustomGrant(config).then((response)=>{
* // console.log(response);
* }).catch((error)=>{
* // console.error(error);
* });
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#requestCustomGrant}
*
* @preserve
*/requestCustomGrant(e,t){return this._authenticationCore.requestCustomGrant(e,t)}
/**
* This method returns if the user is authenticated or not.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @returns - A Promise that resolves with `true` if the user is authenticated, `false` otherwise.
*
* @example
* ```
* await auth.isAuthenticated();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isAuthenticated}
*
* @preserve
*/isAuthenticated(e){return l(this,void 0,void 0,(function*(){return this._authenticationCore.isAuthenticated(e)}))}
/**
* This method returns the PKCE code generated during the generation of the authentication URL.
*
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
* @param state - The state parameter that was passed in the authentication URL.
*
* @returns - A Promise that resolves with the PKCE code.
*
* @example
* ```
* const pkce = await getPKCECode();
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#getPKCECode}
*
* @preserve
*/getPKCECode(e,t){return l(this,void 0,void 0,(function*(){return this._authenticationCore.getPKCECode(e,t)}))}
/**
* This method sets the PKCE code to the data store.
*
* @param pkce - The PKCE code.
* @param state - The state parameter that was passed in the authentication URL.
* @param userID - (Optional) A unique ID of the user to be authenticated. This is useful in multi-user
* scenarios where each user should be uniquely identified.
*
* @example
* ```
* await auth.setPKCECode("pkce_code")
* ```
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#setPKCECode}
*
* @preserve
*/setPKCECode(e,t,i){return l(this,void 0,void 0,(function*(){yield this._authenticationCore.setPKCECode(e,t,i)}))}
/**
* This method returns if the sign-out is successful or not.
*
* @param signOutRedirectUrl - The URL to which the user has been redirected to after signing-out.
*
* **The server appends path parameters to the `signOutRedirectURL` and these path parameters
* are required for this method to function.**
*
* @returns - `true` if successful, `false` otherwise.
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#isSignOutSuccessful}
*
* @preserve
*/static isSignOutSuccessful(e){const t=new URL(e),l=t.searchParams.get("state"),i=Boolean(t.searchParams.get("error"));return!!l&&"sign_out_success"===l&&!i}
/**
* This method returns if the sign-out has failed or not.
*
* @param signOutRedirectUrl - The URL to which the user has been redirected to after signing-out.
*
* **The server appends path parameters to the `signOutRedirectURL` and these path parameters
* are required for this method to function.**
*
* @returns - `true` if successful, `false` otherwise.
*
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#didSignOutFail}
*
* @preserve
*/static didSignOutFail(e){const t=new URL(e),l=t.searchParams.get("state"),i=Boolean(t.searchParams.get("error"));return!!l&&"sign_out_success"===l&&i}
/**
* This method updates the configuration that was passed into the constructor when instantiating this class.
*
* @param config - A config object to update the SDK configurations with.
*
* @example
* ```
* const config = {
* signInRedirectURL: "http://localhost:3000/sign-in",
* clientID: "client ID",
* baseUrl: "https://localhost:9443"
* }
*
* await auth.updateConfig(config);
* ```
* {@link https://github.com/asgardeo/asgardeo-auth-js-sdk/tree/master#updateConfig}
*
* @preserve
*/updateConfig(e){return l(this,void 0,void 0,(function*(){yield this._authenticationCore.updateConfig(e)}))}static clearUserSessionData(e){return l(this,void 0,void 0,(function*(){yield this._authenticationCore.clearUserSessionData(e)}))}}function g(e,t,l){var i=void 0===t?null:t,n=function(e,t){var l=atob(e);if(t){for(var i=new Uint8Array(l.length),n=0,o=l.length;n<o;++n)i[n]=l.charCodeAt(n);return String.fromCharCode.apply(null,new Uint16Array(i.buffer))}return l}(e,void 0!==l&&l),o=n.indexOf("\n",10)+1,d=n.substring(o)+(i?"//# sourceMappingURL="+i:""),c=new Blob([d],{type:"application/javascript"});return URL.createObjectURL(c)}var X,y,V,W,C=(X="Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwp2YXIgd29ya2VyX2NvZGU9ZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gZShlLHQsbixyKXtyZXR1cm4gbmV3KG58fChuPVByb21pc2UpKSgoZnVuY3Rpb24oaSxvKXtmdW5jdGlvbiBzKGUpe3RyeXtjKHIubmV4dChlKSl9Y2F0Y2goZSl7byhlKX19ZnVuY3Rpb24gYShlKXt0cnl7YyhyLnRocm93KGUpKX1jYXRjaChlKXtvKGUpfX1mdW5jdGlvbiBjKGUpe3ZhciB0O2UuZG9uZT9pKGUudmFsdWUpOih0PWUudmFsdWUsdCBpbnN0YW5jZW9mIG4/dDpuZXcgbigoZnVuY3Rpb24oZSl7ZSh0KX0pKSkudGhlbihzLGEpfWMoKHI9ci5hcHBseShlLHR8fFtdKSkubmV4dCgpKX0pKX1mdW5jdGlvbiB0KGUsdCxuLHIpe3JldHVybiBuZXcobnx8KG49UHJvbWlzZSkpKChmdW5jdGlvbihpLG8pe2Z1bmN0aW9uIHMoZSl7dHJ5e2Moci5uZXh0KGUpKX1jYXRjaChlKXtvKGUpfX1mdW5jdGlvbiBhKGUpe3RyeXtjKHIudGhyb3coZSkpfWNhdGNoKGUpe28oZSl9fWZ1bmN0aW9uIGMoZSl7dmFyIHQ7ZS5kb25lP2koZS52YWx1ZSk6KHQ9ZS52YWx1ZSx0IGluc3RhbmNlb2Ygbj90Om5ldyBuKChmdW5jdGlvbihlKXtlKHQpfSkpKS50aGVuKHMsYSl9Yygocj1yLmFwcGx5KGUsdHx8W10pKS5uZXh0KCkpfSkpfXZhciBuOyFmdW5jdGlvbihlKXtlLmZvcm1Qb3N0PSJmb3JtX3Bvc3QiLGUucXVlcnk9InF1ZXJ5IixlLmRpcmVjdD0iZGlyZWN0In0obnx8KG49e30pKTt2YXIgcjshZnVuY3Rpb24oZSl7ZS5Db25maWdEYXRhPSJjb25maWdfZGF0YSIsZS5PSURDUHJvdmlkZXJNZXRhRGF0YT0ib2lkY19wcm92aWRlcl9tZXRhX2RhdGEiLGUuU2Vzc2lvbkRhdGE9InNlc3Npb25fZGF0YSIsZS5UZW1wb3JhcnlEYXRhPSJ0ZW1wb3JhcnlfZGF0YSJ9KHJ8fChyPXt9KSk7Y29uc3QgaT0icmVmcmVzaF90b2tlbl90aW1lciIsbz1bIlJTMjU2IiwiUlM1MTIiLCJSUzM4NCIsIlBTMjU2Il0scz0ic2lnbl9vdXRfdXJsIjt2YXIgYTshZnVuY3Rpb24oZSl7ZS5JbmNsdWRlPSJpbmNsdWRlIixlLlNhbWVPcmlnaW49InNhbWUtb3JpZ2luIixlLk9taXQ9Im9taXQifShhfHwoYT17fSkpO2NsYXNzIGN7Y29uc3RydWN0b3IoZSx0LG4pe3RoaXMubWVzc2FnZT1uLHRoaXMubmFtZT10LHRoaXMuY29kZT1lLE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLG5ldy50YXJnZXQucHJvdG90eXBlKX19Y2xhc3MgdXtjb25zdHJ1Y3Rvcigpe31zdGF0aWMgZmlsdGVyQ2xhaW1zRnJvbUlEVG9rZW5QYXlsb2FkKGUpe2NvbnN0IHQ9T2JqZWN0LmFzc2lnbih7fSxlKTtudWxsPT10fHxkZWxldGUgdC5pc3MsbnVsbD09dHx8ZGVsZXRlIHQuYXVkLG51bGw9PXR8fGRlbGV0ZSB0LmV4cCxudWxsPT10fHxkZWxldGUgdC5pYXQsbnVsbD09dHx8ZGVsZXRlIHQuYWNyLG51bGw9PXR8fGRlbGV0ZSB0LmFtcixudWxsPT10fHxkZWxldGUgdC5henAsbnVsbD09dHx8ZGVsZXRlIHQuYXV0aF90aW1lLG51bGw9PXR8fGRlbGV0ZSB0Lm5vbmNlLG51bGw9PXR8fGRlbGV0ZSB0LmNfaGFzaCxudWxsPT10fHxkZWxldGUgdC5hdF9oYXNoLG51bGw9PXR8fGRlbGV0ZSB0Lm5iZixudWxsPT10fHxkZWxldGUgdC5pc2ssbnVsbD09dHx8ZGVsZXRlIHQuc2lkO2NvbnN0IG49e307cmV0dXJuIE9iamVjdC5lbnRyaWVzKHQpLmZvckVhY2goKChbZSx0XSk9Pntjb25zdCByPWUuc3BsaXQoIl8iKS5tYXAoKChlLHQpPT4wPT09dD9lOltlWzBdLnRvVXBwZXJDYXNlKCksLi4uZS5zbGljZSgxKV0uam9pbigiIikpKS5qb2luKCIiKTtuW3JdPXR9KSksbn1zdGF0aWMgZ2V0VG9rZW5SZXF1ZXN0SGVhZGVycygpe3JldHVybntBY2NlcHQ6ImFwcGxpY2F0aW9uL2pzb24iLCJDb250ZW50LVR5cGUiOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQifX1zdGF0aWMgZ2VuZXJhdGVTdGF0ZVBhcmFtRm9yUmVxdWVzdENvcnJlbGF0aW9uKGUsdCl7Y29uc3Qgbj1wYXJzZUludChlLnNwbGl0KCIjIilbMV0pO3JldHVybiB0P2Ake3R9X3JlcXVlc3RfJHtufWA6YHJlcXVlc3RfJHtufWB9c3RhdGljIGV4dHJhY3RQS0NFS2V5RnJvbVN0YXRlUGFyYW0oZSl7cmV0dXJuYHBrY2VfY29kZV92ZXJpZmllciMke3BhcnNlSW50KGUuc3BsaXQoInJlcXVlc3RfIilbMV0pfWB9fXUuZ2V0VGVuYW50RG9tYWluRnJvbUlkVG9rZ