/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msalRedirectBridge = {}));
})(this, (function (exports) { 'use strict';

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    // Resource delimiter - used for certain cache entries
    const RESOURCE_DELIM = "|";
    const FORWARD_SLASH = "/";
    /**
     * String constants related to AAD Authority
     */
    const AADAuthority = {
        COMMON: "common",
        ORGANIZATIONS: "organizations"};

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    function getDefaultErrorMessage$1(code) {
        return `See https://aka.ms/msal.js.errors#${code} for details`;
    }
    /**
     * General error class thrown by the MSAL.js library.
     */
    class AuthError extends Error {
        constructor(errorCode, errorMessage, suberror) {
            const message = errorMessage ||
                (errorCode ? getDefaultErrorMessage$1(errorCode) : "");
            const errorString = message ? `${errorCode}: ${message}` : errorCode;
            super(errorString);
            Object.setPrototypeOf(this, AuthError.prototype);
            this.errorCode = errorCode || "";
            this.errorMessage = message || "";
            this.subError = suberror || "";
            this.name = "AuthError";
        }
        setCorrelationId(correlationId) {
            this.correlationId = correlationId;
        }
    }

    /*! @azure/msal-common v16.6.2 2026-05-19 */

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * Error thrown when there is an error in configuration of the MSAL.js library.
     */
    class ClientConfigurationError extends AuthError {
        constructor(errorCode) {
            super(errorCode);
            this.name = "ClientConfigurationError";
            Object.setPrototypeOf(this, ClientConfigurationError.prototype);
        }
    }
    function createClientConfigurationError(errorCode) {
        return new ClientConfigurationError(errorCode);
    }

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * @hidden
     */
    class StringUtils {
        /**
         * Check if stringified object is empty
         * @param strObj
         */
        static isEmptyObj(strObj) {
            if (strObj) {
                try {
                    const obj = JSON.parse(strObj);
                    return Object.keys(obj).length === 0;
                }
                catch (e) { }
            }
            return true;
        }
        static startsWith(str, search) {
            return str.indexOf(search) === 0;
        }
        static endsWith(str, search) {
            return (str.length >= search.length &&
                str.lastIndexOf(search) === str.length - search.length);
        }
        /**
         * Parses string into an object.
         *
         * @param query
         */
        static queryStringToObject(query) {
            const obj = {};
            const params = query.split("&");
            const decode = (s) => decodeURIComponent(s.replace(/\+/g, " "));
            params.forEach((pair) => {
                if (pair.trim()) {
                    const [key, value] = pair.split(/=(.+)/g, 2); // Split on the first occurence of the '=' character
                    if (key && value) {
                        obj[decode(key)] = decode(value);
                    }
                }
            });
            return obj;
        }
        /**
         * Trims entries in an array.
         *
         * @param arr
         */
        static trimArrayEntries(arr) {
            return arr.map((entry) => entry.trim());
        }
        /**
         * Removes empty strings from array
         * @param arr
         */
        static removeEmptyStringsFromArray(arr) {
            return arr.filter((entry) => {
                return !!entry;
            });
        }
        /**
         * Attempts to parse a string into JSON
         * @param str
         */
        static jsonParseHelper(str) {
            try {
                return JSON.parse(str);
            }
            catch (e) {
                return null;
            }
        }
    }

    /*! @azure/msal-common v16.6.2 2026-05-19 */

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * ClientAuthErrorMessage class containing string constants used by error codes and messages.
     */
    /**
     * Error thrown when there is an error in the client code running on the browser.
     */
    class ClientAuthError extends AuthError {
        constructor(errorCode, additionalMessage) {
            super(errorCode, additionalMessage);
            this.name = "ClientAuthError";
            Object.setPrototypeOf(this, ClientAuthError.prototype);
        }
    }
    function createClientAuthError(errorCode, additionalMessage) {
        return new ClientAuthError(errorCode, additionalMessage);
    }

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    const authorityUriInsecure = "authority_uri_insecure";
    const urlParseError = "url_parse_error";
    const urlEmptyError = "empty_url_error";

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    const invalidState = "invalid_state";
    const noCryptoObject = "no_crypto_object";

    /*! @azure/msal-common v16.6.2 2026-05-19 */

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * Url object class which can perform various transformations on url strings.
     */
    class UrlString {
        get urlString() {
            return this._urlString;
        }
        constructor(url) {
            this._urlString = url;
            if (!this._urlString) {
                // Throws error if url is empty
                throw createClientConfigurationError(urlEmptyError);
            }
            if (!url.includes("#")) {
                this._urlString = UrlString.canonicalizeUri(url);
            }
        }
        /**
         * Ensure urls are lower case and end with a / character.
         * @param url
         */
        static canonicalizeUri(url) {
            if (url) {
                let lowerCaseUrl = url.toLowerCase();
                if (StringUtils.endsWith(lowerCaseUrl, "?")) {
                    lowerCaseUrl = lowerCaseUrl.slice(0, -1);
                }
                else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
                    lowerCaseUrl = lowerCaseUrl.slice(0, -2);
                }
                if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
                    lowerCaseUrl += "/";
                }
                return lowerCaseUrl;
            }
            return url;
        }
        /**
         * Throws if urlString passed is not a valid authority URI string.
         */
        validateAsUri() {
            // Attempts to parse url for uri components
            let components;
            try {
                components = this.getUrlComponents();
            }
            catch (e) {
                throw createClientConfigurationError(urlParseError);
            }
            // Throw error if URI or path segments are not parseable.
            if (!components.HostNameAndPort || !components.PathSegments) {
                throw createClientConfigurationError(urlParseError);
            }
            // Throw error if uri is insecure.
            if (!components.Protocol ||
                components.Protocol.toLowerCase() !== "https:") {
                throw createClientConfigurationError(authorityUriInsecure);
            }
        }
        /**
         * Given a url and a query string return the url with provided query string appended
         * @param url
         * @param queryString
         */
        static appendQueryString(url, queryString) {
            if (!queryString) {
                return url;
            }
            return url.indexOf("?") < 0
                ? `${url}?${queryString}`
                : `${url}&${queryString}`;
        }
        /**
         * Returns a url with the hash removed
         * @param url
         */
        static removeHashFromUrl(url) {
            return UrlString.canonicalizeUri(url.split("#")[0]);
        }
        /**
         * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
         * @param href The url
         * @param tenantId The tenant id to replace
         */
        replaceTenantPath(tenantId) {
            const urlObject = this.getUrlComponents();
            const pathArray = urlObject.PathSegments;
            if (tenantId &&
                pathArray.length !== 0 &&
                (pathArray[0] === AADAuthority.COMMON ||
                    pathArray[0] === AADAuthority.ORGANIZATIONS)) {
                pathArray[0] = tenantId;
            }
            return UrlString.constructAuthorityUriFromObject(urlObject);
        }
        /**
         * Parses out the components from a url string.
         * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
         */
        getUrlComponents() {
            // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
            const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
            // If url string does not match regEx, we throw an error
            const match = this.urlString.match(regEx);
            if (!match) {
                throw createClientConfigurationError(urlParseError);
            }
            // Url component object
            const urlComponents = {
                Protocol: match[1],
                HostNameAndPort: match[4],
                AbsolutePath: match[5],
                QueryString: match[7],
            };
            let pathSegments = urlComponents.AbsolutePath.split("/");
            pathSegments = pathSegments.filter((val) => val && val.length > 0); // remove empty elements
            urlComponents.PathSegments = pathSegments;
            if (urlComponents.QueryString &&
                urlComponents.QueryString.endsWith("/")) {
                urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1);
            }
            return urlComponents;
        }
        static getDomainFromUrl(url) {
            const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
            const match = url.match(regEx);
            if (!match) {
                throw createClientConfigurationError(urlParseError);
            }
            return match[2];
        }
        static getAbsoluteUrl(relativeUrl, baseUrl) {
            if (relativeUrl[0] === FORWARD_SLASH) {
                const url = new UrlString(baseUrl);
                const baseComponents = url.getUrlComponents();
                return (baseComponents.Protocol +
                    "//" +
                    baseComponents.HostNameAndPort +
                    relativeUrl);
            }
            return relativeUrl;
        }
        static constructAuthorityUriFromObject(urlObject) {
            return new UrlString(urlObject.Protocol +
                "//" +
                urlObject.HostNameAndPort +
                "/" +
                urlObject.PathSegments.join("/"));
        }
    }

    /*! @azure/msal-common v16.6.2 2026-05-19 */
    /**
     * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
     * @param base64Decode
     * @param state
     */
    function parseRequestState(base64Decode, state) {
        if (!base64Decode) {
            throw createClientAuthError(noCryptoObject);
        }
        if (!state) {
            throw createClientAuthError(invalidState);
        }
        try {
            // Split the state between library state and user passed state and decode them separately
            const splitState = state.split(RESOURCE_DELIM);
            const libraryState = splitState[0];
            const userState = splitState.length > 1
                ? splitState.slice(1).join(RESOURCE_DELIM)
                : "";
            const libraryStateString = base64Decode(libraryState);
            const libraryStateObj = JSON.parse(libraryStateString);
            return {
                userRequestState: userState || "",
                libraryState: libraryStateObj,
            };
        }
        catch (e) {
            throw createClientAuthError(invalidState);
        }
    }

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    const noStateInHash = "no_state_in_hash";
    const unableToParseState = "unable_to_parse_state";
    const invalidBase64String = "invalid_base64_string";
    const timedOut = "timed_out";
    const emptyResponse = "empty_response";

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    function getDefaultErrorMessage(code) {
        return `See https://aka.ms/msal.js.errors#${code} for details`;
    }
    /**
     * Browser library error class thrown by the MSAL.js library for SPAs
     */
    class BrowserAuthError extends AuthError {
        constructor(errorCode, subError) {
            super(errorCode, getDefaultErrorMessage(errorCode), subError);
            Object.setPrototypeOf(this, BrowserAuthError.prototype);
            this.name = "BrowserAuthError";
        }
    }
    function createBrowserAuthError(errorCode, subError) {
        return new BrowserAuthError(errorCode, subError);
    }

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    const INTERACTION_TYPE = {
        SIGNOUT: "signout",
    };
    /**
     * Temporary cache keys for MSAL, deleted after any request.
     */
    const TemporaryCacheKeys = {
        ORIGIN_URI: "request.origin",
        URL_HASH: "urlHash",
        REQUEST_PARAMS: "request.params",
        VERIFIER: "code.verifier",
        INTERACTION_STATUS_KEY: "interaction.status",
        NATIVE_REQUEST: "request.native",
    };
    /**
     * API Codes for Telemetry purposes.
     * Before adding a new code you must claim it in the MSAL Telemetry tracker as these number spaces are shared across all MSALs
     * 0-99 Silent Flow
     * 800-899 Auth Code Flow
     * 900-999 Misc
     */
    const ApiId = {
        handleRedirectPromise: 865,
        logout: 961};
    /*
     * Interaction type of the API - used for state and telemetry
     */
    var InteractionType;
    (function (InteractionType) {
        InteractionType["Redirect"] = "redirect";
        InteractionType["Popup"] = "popup";
        InteractionType["Silent"] = "silent";
        InteractionType["None"] = "none";
    })(InteractionType || (InteractionType = {}));

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * Class which exposes APIs to decode base64 strings to plaintext. See here for implementation details:
     * https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
     */
    /**
     * Returns a URL-safe plaintext decoded string from b64 encoded input.
     * @param input
     */
    function base64Decode(input) {
        return new TextDecoder().decode(base64DecToArr(input));
    }
    /**
     * Decodes base64 into Uint8Array
     * @param base64String
     */
    function base64DecToArr(base64String) {
        let encodedString = base64String.replace(/-/g, "+").replace(/_/g, "/");
        switch (encodedString.length % 4) {
            case 0:
                break;
            case 2:
                encodedString += "==";
                break;
            case 3:
                encodedString += "=";
                break;
            default:
                throw createBrowserAuthError(invalidBase64String);
        }
        const binString = atob(encodedString);
        return Uint8Array.from(binString, (m) => m.codePointAt(0) || 0);
    }

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * Extracts and parses the authentication response from URL (hash and/or query string).
     * This is a shared utility used across multiple components in msal-browser.
     *
     * @returns {Object} An object containing the parsed state information and URL parameters.
     * @returns {URLSearchParams} params - The parsed URL parameters from the payload.
     * @returns {string} payload - The combined query string and hash content.
     * @returns {string} urlHash - The original URL hash.
     * @returns {string} urlQuery - The original URL query string.
     * @returns {LibraryStateObject} libraryState - The decoded library state from the state parameter.
     *
     * @throws {AuthError} If no authentication payload is found in the URL.
     * @throws {AuthError} If the state parameter is missing.
     * @throws {AuthError} If the state is missing required 'id' or 'meta' attributes.
     */
    function parseAuthResponseFromUrl() {
        // Extract both hash and query string to support hybrid response format
        const urlHash = window.location.hash;
        const urlQuery = window.location.search;
        // Determine which part contains the auth response by checking for 'state' parameter
        let hasResponseInHash = false;
        let hasResponseInQuery = false;
        let payload = "";
        let params = undefined;
        if (urlHash && urlHash.length > 1) {
            const hashContent = urlHash.charAt(0) === "#" ? urlHash.substring(1) : urlHash;
            const hashParams = new URLSearchParams(hashContent);
            if (hashParams.has("state")) {
                hasResponseInHash = true;
                payload = hashContent;
                params = hashParams;
            }
        }
        if (urlQuery && urlQuery.length > 1) {
            const queryContent = urlQuery.charAt(0) === "?" ? urlQuery.substring(1) : urlQuery;
            const queryParams = new URLSearchParams(queryContent);
            if (queryParams.has("state")) {
                hasResponseInQuery = true;
                payload = queryContent;
                params = queryParams;
            }
        }
        // If response is in both, combine them (hybrid format)
        if (hasResponseInHash && hasResponseInQuery) {
            const queryContent = urlQuery.charAt(0) === "?" ? urlQuery.substring(1) : urlQuery;
            const hashContent = urlHash.charAt(0) === "#" ? urlHash.substring(1) : urlHash;
            payload = `${queryContent}${hashContent}`;
            params = new URLSearchParams(payload);
        }
        if (!payload || !params) {
            throw createBrowserAuthError(emptyResponse);
        }
        const state = params.get("state");
        if (!state) {
            throw createBrowserAuthError(noStateInHash);
        }
        const { libraryState } = parseRequestState(base64Decode, state);
        const { id, meta } = libraryState;
        if (!id || !meta) {
            throw createBrowserAuthError(unableToParseState, "missing_library_state");
        }
        return {
            params,
            payload,
            urlHash,
            urlQuery,
            hasResponseInHash,
            hasResponseInQuery,
            libraryState: {
                id,
                meta,
            },
        };
    }
    /**
     * Gets the homepage url for the current window location.
     */
    function getHomepage() {
        const currentUrl = new UrlString(window.location.href);
        const urlComponents = currentUrl.getUrlComponents();
        return `${urlComponents.Protocol}//${urlComponents.HostNameAndPort}/`;
    }

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    class NavigationClient {
        /**
         * Navigates to other pages within the same web application
         * @param url
         * @param options
         */
        navigateInternal(url, options) {
            return NavigationClient.defaultNavigateWindow(url, options);
        }
        /**
         * Navigates to other pages outside the web application i.e. the Identity Provider
         * @param url
         * @param options
         */
        navigateExternal(url, options) {
            return NavigationClient.defaultNavigateWindow(url, options);
        }
        /**
         * Default navigation implementation invoked by the internal and external functions
         * @param url
         * @param options
         */
        static defaultNavigateWindow(url, options) {
            if (options.noHistory) {
                window.location.replace(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
            }
            else {
                window.location.assign(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
            }
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(createBrowserAuthError(timedOut, "failed_to_redirect"));
                }, options.timeout);
            });
        }
    }

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    const DEFAULT_REDIRECT_TIMEOUT_MS = 30000;

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    const PREFIX = "msal";

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    /**
     * Processes the authentication response from the redirect URL
     * For SSO and popup scenarios broadcasts it to the main frame
     * For redirect scenario navigates to the home page
     *
     * @param {NavigationClient} navigationClient - Optional navigation client for redirect scenario.
     *
     * @returns {Promise<void>} A promise that resolves when the response has been broadcast and cleanup is complete.
     *
     * @throws {AuthError} If no authentication payload is found in the URL (hash or query string).
     * @throws {AuthError} If the state parameter is missing from the redirect URL.
     * @throws {AuthError} If the state is missing required 'id' or 'meta' attributes.
     */
    async function broadcastResponseToMainFrame(navigationClient) {
        let parsedResponse;
        try {
            parsedResponse = parseAuthResponseFromUrl();
        }
        catch (error) {
            // Clear hash and query string before re-throwing parse errors
            if (typeof window.history.replaceState === "function") {
                window.history.replaceState(null, "", `${window.location.origin}${window.location.pathname}`);
            }
            throw error;
        }
        const { payload, urlHash, urlQuery, hasResponseInHash, hasResponseInQuery, libraryState, } = parsedResponse;
        const { id, meta } = libraryState;
        if (meta["interactionType"] === InteractionType.Redirect) {
            const navClient = navigationClient || new NavigationClient();
            let navigateToUrl = "";
            let clientId = "";
            let interactionType = "";
            const interactionKey = `${PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
            /*
             * Retrieve the clientId and original navigation URL from
             * sessionStorage. If sessionStorage access or JSON.parse fails,
             * we fall back to URL-based navigation below.
             */
            try {
                const rawInteractionStatus = window.sessionStorage.getItem(interactionKey);
                const interactionStatus = JSON.parse(rawInteractionStatus || "");
                clientId = interactionStatus.clientId || "";
                interactionType = interactionStatus.type;
                if (clientId) {
                    const originKey = `${PREFIX}.${clientId}.${TemporaryCacheKeys.ORIGIN_URI}`;
                    navigateToUrl = window.sessionStorage.getItem(originKey) || "";
                }
            }
            catch {
                // sessionStorage access or JSON.parse failed
            }
            const navigationOptions = {
                apiId: interactionType === INTERACTION_TYPE.SIGNOUT
                    ? ApiId.logout
                    : ApiId.handleRedirectPromise,
                noHistory: true,
                timeout: DEFAULT_REDIRECT_TIMEOUT_MS,
            };
            /*
             * Cache the auth response payload in sessionStorage under the URL_HASH
             * key, then navigate directly to the origin URL. This replicates what
             * RedirectClient.handleRedirectPromise does when the current page is
             * not the loginRequestUrl: it caches the response and navigates.
             *
             * On the target page, handleRedirectPromise will find no response in
             * the URL but will pick up the cached payload from sessionStorage.
             * This avoids appending the auth response to the URL, which would
             * create malformed URLs for hash-routed SPAs (e.g. /#/route#code=...).
             *
             * If caching fails (clientId unavailable, quota exceeded, storage
             * disabled), we still navigate to the origin/homepage. The target
             * page's handleRedirectPromise will return null and the app can
             * handle re-authentication. Appending auth params to the URL would
             * not help because handleRedirectPromise also relies on
             * sessionStorage to persist tokens.
             */
            if (clientId) {
                try {
                    window.sessionStorage.setItem(`${PREFIX}.${clientId}.${TemporaryCacheKeys.URL_HASH}`, payload);
                }
                catch {
                    // sessionStorage write failed — navigate anyway; handleRedirectPromise will return null
                }
            }
            const url = navigateToUrl || getHomepage();
            // Strip bare trailing "?" (empty query string) to match canonical URL form
            const navigationUrl = url.endsWith("?") ? url.slice(0, -1) : url;
            await navClient.navigateInternal(navigationUrl, navigationOptions);
            // Do NOT clear URL for redirect flow - we're navigating away anyway
            return;
        }
        // Clear only the part(s) containing the auth response from redirect bridge URL
        if (typeof window.history.replaceState === "function") {
            let newUrl = `${window.location.origin}${window.location.pathname}`;
            // Preserve hash if it didn't contain the response
            if (!hasResponseInHash && urlHash) {
                newUrl += urlHash;
            }
            // Preserve query if it didn't contain the response
            if (!hasResponseInQuery && urlQuery) {
                newUrl += urlQuery;
            }
            window.history.replaceState(null, "", newUrl);
        }
        // Send the raw URL payload to the main frame
        const channel = new BroadcastChannel(id);
        channel.postMessage({
            v: 1,
            payload,
        });
        channel.close();
        try {
            window.close();
        }
        catch { }
    }

    exports.broadcastResponseToMainFrame = broadcastResponseToMainFrame;

}));
//# sourceMappingURL=msal-redirect-bridge.js.map
