/* Minification failed. Returning unminified contents.
(94,33-36): run-time error JS1009: Expected '}': ...
(100,25-27): run-time error JS1006: Expected ')': if
(102,80): run-time error JS1004: Expected ';'
(114,33-36): run-time error JS1009: Expected '}': ...
(133,33-36): run-time error JS1009: Expected '}': ...
(140,22-23): run-time error JS1009: Expected '}': )
(184,37-40): run-time error JS1009: Expected '}': ...
(185,50): run-time error JS1004: Expected ';'
(185,50-51): run-time error JS1195: Expected expression: :
(217,37-40): run-time error JS1009: Expected '}': ...
(258,21-22): run-time error JS1002: Syntax error: }
(259,17-18): run-time error JS1002: Syntax error: }
(294,33-36): run-time error JS1009: Expected '}': ...
(302,17-18): run-time error JS1002: Syntax error: }
(303,13-14): run-time error JS1002: Syntax error: }
(304,9-10): run-time error JS1002: Syntax error: }
(305,5-6): run-time error JS1002: Syntax error: }
(305,6-7): run-time error JS1195: Expected expression: )
(306,1-2): run-time error JS1002: Syntax error: }
 */
/*!
  * Lexpera Popups v5.6.2
  * Copyright 2021-2024 Lexpera
  * For the latest versions and changelogs visit the link below:
  */

// Make an IIFE function variable for popups.
var Popups = function () {
    return {
        clearPopupsUser: function (userName) {
            ClearPopupsUser(userName);
        },
        callGetPopupsWithExcludeList: function (abortRequest = false, ...popupNamesExcludeList) {
            GetPopups(abortRequest = false, ...popupNamesExcludeList);
        },
        popupsReset: function (event) {
            PopupsReset(event);
        }
    };
}();

/**
 * Get banners, modals, and tooltips.
 * 
 * @param {boolean} abortRequest = cancels ajax request before it sends.
 * @param {...string} popupNamesExcludeList = array of strings. Put "Popup Name"" to exclude in certain conditions.
 * @returns
 */
function GetPopups(abortRequest = false, ...popupNamesExcludeList) {

    // Fetch for config.
    let data = {
        url: window.location.pathname,
        sopi: typeof IusInfoUIDocument !== "undefined" ? IusInfoUIDocument.Sopi : null,
        categoryAddress: typeof IusInfoUIDocument !== "undefined" ? IusInfoUIDocument.CategoryAddress : null
    };

    return $.ajax({
        contentType: "application/json; charset=utf-8",
        type: "POST",
        url: "/Popup/GetPopups/",
        data: JSON.stringify(data),
        cache: false,
        beforeSend: function (jqXHR) {
            // Abort request before it sends.
            if (abortRequest) jqXHR.abort();
        },
        success: function (data) {

            // Check if null.
            if (Object.values(JSON.parse(data)).some(d => d !== null)) {

                // Parse for main data.
                var popupData = JSON.parse(data);

                // BANNERS.
                if (popupData.Banners !== null) {

                    // Filter banners from db, local storage, and exclude list.
                    const showBanners = [...FilteredPopups(popupData.Banners, [...popupNamesExcludeList])];

                    // Apply banner config.
                    showBanners.map(b => {
                        // Make sure object keys are enclosed in double quotes "". ex: {"key": "value_is_here"}.
                        let mainBannerConfig = {
                            bannerID: `banner_${b.PopupID}`,
                            popupID: b.PopupID,
                            type: b.BannerType,
                            position: b.Position,
                            content: b.Content,
                            isRecurring: b.IsRecurring,
                            recurringDays: b.RecurringDays,
                            displayDelay: b.DisplayDelay,
                            displayDuration: b.DisplayDuration,
                            zIndex: b.zIndex
                        };

                        // Banner dismiss button config.
                        if (b.DismissButtonConfiguration &&
                            b.DismissButtonConfiguration !== null &&
                            typeof b.DismissButtonConfiguration !== "undefined") {
                            const jsonDismissConfig = JSON.parse(b.DismissButtonConfiguration);
                            const configDismissButton = {
                                buttonDismissText: jsonDismissConfig.buttonDismissText,
                                buttonDismissColor: jsonDismissConfig.buttonDismissColor,
                                buttonDismissBackgroundColor: jsonDismissConfig.buttonDismissBackgroundColor,
                                buttonDismissID: jsonDismissConfig.buttonDismissID,
                                buttonDismissURL: jsonDismissConfig.buttonDismissURL,
                                buttonDismissHidden: jsonDismissConfig.buttonDismissHidden,
                                buttonDismissFunction: jsonDismissConfig.buttonDismissFunction
                            };
                            // Apply to main banner config.
                            mainBannerConfig = {
                                ...mainBannerConfig,
                                ...configDismissButton
                            };
                        }

                        // Banner custom button config.
                        if (b.CustomButtonConfiguration &&
                            b.CustomButtonConfiguration !== null &&
                            typeof b.CustomButtonConfiguration !== "undefined") {
                            const jsonCustomConfig = JSON.parse(b.CustomButtonConfiguration);
                            const configCustomButton = {
                                buttonCustomText: jsonCustomConfig.buttonCustomText,
                                buttonCustomColor: jsonCustomConfig.buttonCustomColor,
                                buttonCustomBackgroundColor: jsonCustomConfig.buttonCustomBackgroundColor,
                                buttonCustomID: jsonCustomConfig.buttonCustomID,
                                buttonCustomURL: jsonCustomConfig.buttonCustomURL,
                                buttonCustomDismissBanner: jsonCustomConfig.buttonCustomDismissBanner,
                                buttonCustomFunction: jsonCustomConfig.buttonCustomFunction
                            };
                            mainBannerConfig = {
                                ...mainBannerConfig,
                                ...configCustomButton
                            };
                        }

                        // Extra banner config.
                        if (b.Configuration &&
                            b.Configuration !== null &&
                            typeof b.Configuration !== "undefined") {
                            const jsonExtraConfig = JSON.parse(b.Configuration);
                            const extraConfig = {
                                color: jsonExtraConfig.color,
                                backgroundColor: jsonExtraConfig.backgroundColor,
                                linkColor: jsonExtraConfig.linkColor,
                                icon: jsonExtraConfig.icon,
                                visible: jsonExtraConfig.visible,
                                onCloseFunction: jsonExtraConfig.onCloseFunction
                            };
                            mainBannerConfig = {
                                ...mainBannerConfig,
                                ...extraConfig
                            };
                        }

                        // Instantiate banners.
                        let docBanner = new LexperaBanner(mainBannerConfig);
                    });
                }

                // MODALS.
                if (popupData.Modals !== null) {

                    // Filter modals from db, local storage, and exclude list.
                    const showModals = [...FilteredPopups(popupData.Modals, [...popupNamesExcludeList])];

                    // Holder for previous modal.
                    let previousModal = null;

                    for (let i = 0; i < showModals.length; i++) {

                        // Store for config.
                        let m = showModals[i];

                        // Skip if there's an existing active modal.
                        // Continue creating instance for those that have target elements.  
                        if ($("body").hasClass("modal-open") && !(m.TargetElement !== null && m.TargetElement.trim().length > 0))
                            continue;
                        else {
                            let mainModalConfig = {
                                modalID: `modal_${m.PopupID}`,
                                popupID: m.PopupID,
                                title: m.Title,
                                content: m.Content,
                                modalSize: m.ModalSize,
                                type: m.ModalType,
                                displayDelay: m.DisplayDelay,
                                displayDuration: m.DisplayDuration,
                                isRecurring: m.IsRecurring,
                                recurringDays: m.RecurringDays,
                                targetElement: m.TargetElement,
                                targetAction: m.TargetAction,
                                visible: false
                            };

                            // Modal action buttons config.
                            if (m.ActionButtonsConfiguration &&
                                m.ActionButtonsConfiguration !== null &&
                                typeof m.ActionButtonsConfiguration !== "undefined") {
                                // Apply to main banner config.
                                mainModalConfig = {
                                    ...mainModalConfig,
                                    actionButtons: m.ActionButtonsConfiguration
                                };
                            }

                            // Extra modal config.
                            if (m.Configuration &&
                                m.Configuration !== null &&
                                typeof m.Configuration !== "undefined") {
                                const jsonExtraConfig = JSON.parse(m.Configuration);
                                const extraConfig = {
                                    additionalClass: jsonExtraConfig.additionalClass,
                                    modalPosition: jsonExtraConfig.modalPosition,
                                    modalHeaderColor: jsonExtraConfig.modalHeaderColor,
                                    modalHeaderBackgroundColor: jsonExtraConfig.modalHeaderBackgroundColor,
                                    modalHeaderHidden: jsonExtraConfig.modalHeaderHidden,
                                    modalHeaderContent: jsonExtraConfig.modalHeaderContent,
                                    modalBodyHidden: jsonExtraConfig.modalBodyHidden,
                                    modalBodyColor: jsonExtraConfig.modalBodyColor,
                                    modalBodyBackgroundColor: jsonExtraConfig.modalBodyBackgroundColor,
                                    HTMLContent: jsonExtraConfig.HTMLContent,
                                    modalFooterColor: jsonExtraConfig.modalFooterColor,
                                    modalFooterBackgroundColor: jsonExtraConfig.modalFooterBackgroundColor,
                                    modalFooterHidden: jsonExtraConfig.modalFooterHidden,
                                    modalFooterContent: jsonExtraConfig.modalFooterContent,
                                    closeButtonColor: jsonExtraConfig.closeButtonColor,
                                    closeButtonText: jsonExtraConfig.closeButtonText,
                                    modalBackdropStatic: jsonExtraConfig.modalBackdropStatic,
                                    destroyOnClose: jsonExtraConfig.destroyOnClose,
                                    onCloseFunction: jsonExtraConfig.onCloseFunction
                                };

                                mainModalConfig = {
                                    ...mainModalConfig,
                                    ...extraConfig
                                };
                            }

                            // Instantiate modals.
                            let docModal = new LexperaModal(mainModalConfig);

                            // Initialize only on valid configuration.
                            // Invalid config ex: not existing targetElements.
                            if (!docModal.isInvalidConfiguration) {
                                // Open next chained modal in list when closing the last shown modal with same targetElement.
                                if (previousModal !== null &&
                                    previousModal.modalParams.targetElement === docModal.modalParams.targetElement) {

                                    // Continue chain if targetElement is existing.
                                    if (isThisDomExisting(previousModal.modalParams.targetElement) || isThisDomExisting(docModal.modalParams.targetElement))
                                        previousModal.onModalCloseExecute(() => docModal.show(m.DisplayDelay));

                                } else if (previousModal !== null &&
                                    previousModal.modalParams.targetElement !== docModal.modalParams.targetElement) {
                                    // Show for different targetElements.

                                    // Clear previous modal pointer.
                                    previousModal = null;

                                    // Skip modals that are triggered with targetAction.
                                    // Don't show if there's an existing active modal.
                                    if (!docModal.modalParams.targetAction && !$("body").hasClass("modal-open"))
                                        docModal.show(m.DisplayDelay);
                                }
                                else {
                                    // Skip modals that are triggered with targetAction.
                                    if (!docModal.modalParams.targetAction)
                                        docModal.show(m.DisplayDelay);
                                }

                                // Change pointer to previous modal.
                                previousModal = docModal;
                            }
                        }
                    }
                }

                // TOOLTIPS.
                if (popupData.Tooltips !== null) {

                    // Filter tooltips from db, local storage, and exclude list.
                    const showTooltips = [...FilteredPopups(popupData.Tooltips, [...popupNamesExcludeList])];

                    // Get first instance of config that has valid steps and DOM to highlight.
                    let t = showTooltips.find(tooltip => hasTooltipsDOMToHighlight(JSON.parse(tooltip.Steps)));

                    if (t !== undefined) {

                        let mainTooltipConfig = {
                            popupID: t.PopupID,
                            targetElement: t.TargetElement,
                            targetAction: t.TargetAction,
                            steps: JSON.parse(t.Steps),
                            configuration: JSON.parse(t.Configuration),
                            isRecurring: t.IsRecurring,
                            recurringDays: t.RecurringDays,
                            displayDelay: t.DisplayDelay,
                            zIndex: t.zIndex
                        };

                        // Extra tooltip config.
                        if (t.Configuration &&
                            t.Configuration !== null &&
                            typeof t.Configuration !== "undefined") {
                            const jsonExtraConfig = JSON.parse(t.Configuration);
                            const extraConfig = {
                                onCloseFunction: jsonExtraConfig.onCloseFunction
                            };

                            mainTooltipConfig = {
                                ...mainTooltipConfig,
                                ...extraConfig
                            };
                        }

                        // Instantiate tooltip.
                        let docTooltip = new LexperaTooltips(mainTooltipConfig);
                    }
                }
            }
        }
    });
}

function PopupCustomAction(popupid, value) {
    $.ajax({
        contentType: "application/json; charset=utf-8",
        type: "POST",
        url: "/Popup/PopupMarketingAction/",
        data: JSON.stringify({ popupID: popupid, value: value }),
        cache: false
    });
}

/**
 * Customizable lexpera banner to show on top or bottom.
 *
 * @param {*} bannerParams = pass objects for customizations.
 * @param {string} bannerParams.position = Placement of banner; default is bottom, "top-sticky" is sticky top, "top" is before the body.
 * @param {string} bannerParams.icon = Change icon. Pass html string or image location path.
 * @param {string} bannerParams.content = Banner message.
 * @param {string} bannerParams.color = Banner text color. Pass css values.
 * @param {string} bannerParams.backgroundColor = Banner background color.
 * @param {integer} bannerParams.zIndex = Alter z-index; Default is 10000 for 5 digits, adjust as needed to place on top of another banner.
 * @param {string} bannerParams.bannerID = ID selector to banner.
 * @param {string} bannerParams.popupID = Custom attribute for popup ID.
 * @param {string} bannerParams.buttonDismissText = Button dismiss text.
 * @param {string} bannerParams.buttonDismissColor = Button dismiss text color.
 * @param {string} bannerParams.buttonDismissBackgroundColor = Button dismiss background color.
 * @param {string} bannerParams.buttonDismissID = ID selector to dimiss button.
 * @param {boolean} bannerParams.buttonDismissHidden = No dismiss button shown.
 * @param {string} bannerParams.buttonDismissURL = Navigate to this url location. Takes precedence over bannerParams.buttonDismissFunction.
 * @param {anonymous_function | string} bannerParams.buttonDismissFunction = Custom click event handler for dismiss button; Pass string of js declarations or pass name of function if without parameters, use anonymous function if with parameters () => callThisFunction(p1, p2, ...); Make sure to pass escaped characters for multi line js ex: \r \n \t
 * @param {string} bannerParams.buttonCustomText = Button custom text.
 * @param {string} bannerParams.buttonCustomColor = Button custom color.
 * @param {string} bannerParams.buttonCustomBackgroundColor = Button custom background color.
 * @param {string} bannerParams.buttonCustomID = ID selector to custom button.
 * @param {string} bannerParams.buttonCustomURL = Navigate to this url location. Takes precedence over bannerParams.buttonCustomFunction. Shows the custom button.
 * @param {boolean} bannerParams.buttonCustomDismissBanner = Dismisses the banner. Updates the data in localStorage and DB. Shows the custom button.
 * @param {anonymous_function | string} bannerParams.buttonCustomFunction = Custom click event handler for custom button. Shows the custom button.
 * @param {string} bannerParams.linkColor = Hyperlinks color.
 * @param {string} bannerParams.type = Banner theme depending on type. Pass "custom" if you want to use color, backgroundColor, and linkColor.
 * @param {boolean} bannerParams.visible = Hide the banner by default.
 * @param {integer} bannerParams.displayDelay = Add delay to attach the banner to DOM. Pass in unit of seconds, ex: 6 will be 6 seconds.
 * @param {integer} bannerParams.displayDuration = Remove the DOM after duration.
 * @param {anonymous_function | string} bannerParams.onCloseFunction = Custom function when the banner gets closed automatically. "displayDuration" is required; Pass string of js declarations or pass name of function if without parameters, use anonymous function if with parameters () => callThisFunction(p1, p2, ...); Make sure to pass escaped characters for multi line js ex: \r \n \t
 * @param {boolean} bannerParams.isRecurring = Flag to check if banner is recurring.
 * @param {integer} bannerParams.recurringDays = Expiration date for the banner to reshow again from localStorage and DB.
 *
 */
class LexperaBanner {
    constructor(bannerParams) {
        // CONSTANTS.
        const COLOR_LEXPERA_BLUE = "#2F7A8E";
        const COLOR_LEXPERA_GRAY = "#4E6066";
        const COLOR_LEXPERA_LIGHTBLUE = "#17A2B8";
        const COLOR_BLACK = "#000000";
        const COLOR_DEFAULT_LINKS = "#E0AD58";
        const COLOR_SUCCESS = "#28A745";
        const COLOR_SUCCESS_LINKS = "#FFC107";
        const COLOR_DANGER = "#DC3545";
        const COLOR_DANGER_LINKS = "WHEAT";
        const COLOR_DANGER_ANALOGOUS = "#DC7935";
        const COLOR_WARNING = "#FFC107";
        const COLOR_WARNING_LINKS = "#17A2B8";
        const COLOR_WARNING_ANALOGOUS = "#FF4507";
        const ACTION_TYPE_HIDE = "hide";
        const ACTION_TYPE_DISMISS = "dismiss";
        const POPUP_TYPE_BANNER = "BANNER";
        const TEXT_DO_NOT_SHOW_AGAIN = "Don't show again";
        const SLASH = "/";

        // Build base HTML.
        const markup = `
		<div class="banner-icon">
			<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle"
				viewBox="0 0 16 16">
				<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
				<path
					d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
			</svg>
		</div>
		<div class="banner-content">
			<span></span>
		</div>
		<div class="banner-buttons">
			<button class="btn btn-sm" lb-custom hidden>Custom Button</button>
			<button class="btn btn-sm" lb-dismiss>Kapat</button>
		</div>
		`;

        // Create virtual wrapper.
        let virtualDIV = document.createElement("div");

        // Assign class for wrapper.
        virtualDIV.className = "lexpera-banner";

        // Transform to jQuery Object.
        this.banner = $(virtualDIV);

        // Default CSS for banner.
        this.banner.css({
            cssText: `
		position: fixed;
		bottom: 0;
		left: 0;
		min-height: max-content;
		background-color: ${COLOR_LEXPERA_BLUE};
		width: 100%;
		display: flex;
		align-items: center;
		padding: 6px 8px 12px;
		box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.3);
		z-index: 10000;
		color: white;
		`,
        });

        // Append HTML body from markup.
        virtualDIV.innerHTML = markup;

        // Extract elements for styling and customizations.
        let iconContainer = this.banner.children(".banner-icon");
        let icon = iconContainer.children();
        let messageContainer = this.banner.children(".banner-content");
        let messageContent = messageContainer.find("span");
        let buttonContainer = this.banner.children(".banner-buttons");
        let buttons = buttonContainer.find("button");
        let btnDismiss = buttonContainer.find("[lb-dismiss]");
        let btnCustom = buttonContainer.find("[lb-custom]");

        // Default configurations.

        // Default css.
        const DefaultCSS = () => {
            this.banner.css({
                "flex-direction": "column",
            });

            iconContainer.css({
                cssText: `
			align-self: flex-start;
			padding-bottom: 8px;
			min-width: 65px;
			`,
            });

            icon.css({
                cssText: `
			width: 1rem;
			height: 1rem;
			`,
            });

            messageContainer.css({
                cssText: `
			flex: 1;
			align-self: flex-start;
			margin-bottom: 1rem;
			word-break: break-word;
			overflow-wrap: break-word;
			`,
            });

            buttonContainer.css({
                cssText: `
			display: flex;
			align-self: flex-end;
			`,
            });

            buttons
                .css({
                    cssText: `
			margin-left: 8px; 
			margin-right: 8px; 
			font-size: 0.75rem;
			border-radius: 0;
			color: white;
			`,
                })
                .addClass("btn-sm");

            btnDismiss.css({
                "background-color": COLOR_LEXPERA_GRAY,
            });

            btnCustom.css({
                "background-color": COLOR_LEXPERA_LIGHTBLUE,
            });

            // Hover effects.
            buttons
                .on("mouseenter", (event) => {
                    // Prevent bubbling.
                    event.stopImmediatePropagation();
                    // Apply css.
                    $(event.target).css("filter", "brightness(1.1)");
                })
                .on("mouseleave", (event) => {
                    // Prevent bubbling.
                    event.stopImmediatePropagation();
                    // Remove css.
                    $(event.target).css("filter", "");
                });

            // Don't use cssText, so padding for earlier declarations
            // can be overridden.
            this.banner.children("div").css({
                "padding-left": "12px",
                "padding-right": "12px",
            });

            // Responsive.
            if (window.innerWidth >= 768) {
                this.banner.css({
                    "flex-direction": "row",
                    padding: "12px 6px 12px",
                });

                iconContainer.css({
                    "align-self": "center",
                    "padding-bottom": "",
                });

                icon.css({
                    width: "2rem",
                    height: "2rem",
                });

                messageContainer.css({
                    "align-self": "center",
                    "margin-bottom": "",
                });

                buttonContainer.css({
                    "align-self": "center",
                });

                buttons
                    .css({
                        "font-size": "0.9rem",
                    })
                    .removeClass("btn-sm");
            }
        };

        // Customizations.
        const ApplyCustomizations = (bannerParams) => {
            // Parameters for customizations are present.
            if (bannerParams) {
                // Placement of banner.
                if (bannerParams.position) {
                    switch (bannerParams.position.toLowerCase()) {
                        case "top-sticky":
                            this.banner.css({
                                top: "0",
                                bottom: "",
                            });
                            break;
                        case "top":
                            this.banner.css({
                                position: "",
                            });
                        default:
                            break;
                    }
                }

                // Icon.
                if (bannerParams.icon) {
                    // Determine icon size.
                    let iconSize;

                    // Use passed html.
                    if (containsHTML(bannerParams.icon)) {
                        // Replace DOM.
                        iconContainer.html(bannerParams.icon);

                        // Adjust icon size according to viewport.
                        iconSize = window.innerWidth >= 768 ? "2rem" : "1rem";

                        // Apply icon css.
                        iconContainer.children().css({
                            width: iconSize,
                            height: iconSize,
                            "font-size": iconSize,
                        });
                    } else {
                        // Adjust icon size according to viewport.
                        iconSize = window.innerWidth >= 768 ? 100 : 50;

                        // Use image src.
                        iconContainer.html(`
							<img src="${bannerParams.icon}" alt="Banner Icon" class="img-fluid" width="${iconSize}" height="${iconSize}">
						`);
                    }
                }

                // Banner message.
                if (bannerParams.content && bannerParams.content.trim().length > 0)
                    messageContent.html(bannerParams.content.trim());

                // Default Hyperlink color and hover effect.
                messageContainer
                    .find("a")
                    .css({
                        color: COLOR_DEFAULT_LINKS,
                    })
                    .on("mouseenter", (event) => {
                        $(event.target).css("text-decoration", "underline");
                    })
                    .on("mouseleave", (event) => {
                        $(event.target).css("text-decoration", "");
                    });

                // Text Color.
                if (bannerParams.color)
                    messageContent.css({
                        color: bannerParams.color,
                    });

                // Background color.
                if (bannerParams.backgroundColor)
                    this.banner.css({
                        backgroundColor: bannerParams.backgroundColor,
                    });

                // Z-index.
                if (bannerParams.zIndex)
                    this.banner.css({
                        zIndex: abs(bannerParams.zIndex),
                    });

                // ID selector to banner.
                if (bannerParams.bannerID) {
                    if (
                        typeof bannerParams.bannerID === "string" &&
                        isNaN(bannerParams.bannerID) &&
                        bannerParams.bannerID.trim().length > 0
                    )
                        // Assign ID.
                        this.banner.attr("id", bannerParams.bannerID);
                }

                // Custom attribute popup id.
                if (bannerParams.popupID && !isNaN(bannerParams.popupID))
                    this.banner.attr("popup-id", abs(bannerParams.popupID));

                // Button dismiss text.
                if (
                    bannerParams.buttonDismissText &&
                    bannerParams.buttonDismissText.trim().length > 0
                )
                    btnDismiss.text(bannerParams.buttonDismissText.trim());

                // Button dismiss text color.
                if (bannerParams.buttonDismissColor)
                    btnDismiss.css({
                        color: bannerParams.buttonDismissColor,
                    });

                // Button dismiss background color.
                if (bannerParams.buttonDismissBackgroundColor)
                    btnDismiss.css({
                        backgroundColor: bannerParams.buttonDismissBackgroundColor,
                    });

                // ID selector to dimiss button.
                if (bannerParams.buttonDismissID)
                    btnDismiss.attr("id", bannerParams.buttonDismissID);

                // No dismiss button shown.
                if (bannerParams.buttonDismissHidden === true) btnDismiss.remove();

                // Click event for dismiss button.
                btnDismiss.on("click", (event) => {
                    // Prevent bubbling.
                    event.stopImmediatePropagation();

                    // Declarations.
                    let expireDay, actionType;

                    // Get expiration day from parameters or set to max.
                    // Action type of popup.
                    if (bannerParams.isRecurring && bannerParams.recurringDays) {
                        expireDay = abs(bannerParams.recurringDays);
                        actionType = ACTION_TYPE_HIDE;
                    } else {
                        expireDay = null;
                        actionType = ACTION_TYPE_DISMISS;
                    }

                    if (!bannerParams.buttonDismissHidden && bannerParams.popupID) {
                        // Set expiration date for this popup in local storage.
                        setExpiringPopup(
                            abs(bannerParams.popupID),
                            POPUP_TYPE_BANNER,
                            expireDay
                        );

                        // Update dismiss banner table.
                        // Handle Popup Action Ajax Call.
                        $.ajax({
                            type: "POST",
                            url: "/Popup/HandlePopupActionAsync/",
                            data: {
                                popupID: abs(bannerParams.popupID),
                                actionType: actionType,
                                days: expireDay,
                                popupType: POPUP_TYPE_BANNER
                            },
                            error: (err) => console.log(`ERROR: ${err}`),
                        });
                    }

                    if (
                        bannerParams.buttonDismissURL &&
                        bannerParams.buttonDismissURL.trim().length > 0
                    )
                        // Navigate.
                        window.location.href =
                            window.location.origin +
                            SLASH +
                            bannerParams.buttonDismissURL;
                    else {
                        // Custom function.
                        if (bannerParams.buttonDismissFunction) {
                            if (
                                typeof bannerParams.buttonDismissFunction ===
                                "function"
                            )
                                // Call the passed function.
                                bannerParams.buttonDismissFunction();
                            else if (
                                typeof bannerParams.buttonDismissFunction ===
                                "string" &&
                                bannerParams.buttonDismissFunction.length > 0
                            ) {
                                // Delete DOM.
                                $(event.target)
                                    .parents(".lexpera-banner")
                                    .remove();
                                // Execute string js declarations like eval.

                                // Create new function.
                                let virtualFunction = new Function(
                                    bannerParams.buttonDismissFunction
                                );
                                // Call virtual function.
                                virtualFunction();
                            }
                        }
                    }

                    // Delete DOM.
                    $(event.target).parents(".lexpera-banner").remove();
                });

                // Button custom text.
                if (
                    bannerParams.buttonCustomText &&
                    bannerParams.buttonCustomText.trim().length > 0
                )
                    btnCustom.text(bannerParams.buttonCustomText.trim());

                // Button custom text color.
                if (bannerParams.buttonCustomColor)
                    btnCustom.css({
                        color: bannerParams.buttonCustomColor,
                    });

                // Button custom background color.
                if (bannerParams.buttonCustomBackgroundColor)
                    btnCustom.css({
                        backgroundColor: bannerParams.buttonCustomBackgroundColor,
                    });

                // ID selector to custom button.
                if (bannerParams.buttonCustomID)
                    btnCustom.attr("id", bannerParams.buttonCustomID);

                // Show custom button.
                if (
                    bannerParams.buttonCustomFunction ||
                    (bannerParams.buttonCustomURL &&
                        bannerParams.buttonCustomURL.trim().length > 0) ||
                    (bannerParams.buttonCustomDismissBanner &&
                        bannerParams.buttonCustomDismissBanner === true)
                ) {
                    // Remove attribute hidden.
                    btnCustom.attr("hidden", false);

                    // Change text of custom button.
                    if (bannerParams.buttonCustomDismissBanner)
                        btnCustom.text(TEXT_DO_NOT_SHOW_AGAIN);

                    // Custom click event handler for custom button.
                    btnCustom.on("click", (event) => {
                        // Prevent bubbling.
                        event.stopImmediatePropagation();

                        if (bannerParams.buttonCustomURL)
                            // Navigate.
                            window.location.href =
                                window.location.origin +
                                SLASH +
                                bannerParams.buttonCustomURL;
                        else if (bannerParams.buttonCustomFunction) {
                            if (
                                typeof bannerParams.buttonCustomFunction ===
                                "function"
                            ) {
                                // Call the passed function.
                                bannerParams.buttonCustomFunction();
                            } else if (
                                typeof bannerParams.buttonCustomFunction ===
                                "string" &&
                                bannerParams.buttonCustomFunction.length > 0
                            ) {
                                // Execute string js declarations like eval.

                                // Create new function.
                                let virtualFunction = new Function(
                                    bannerParams.buttonCustomFunction
                                );
                                // Call virtual function.
                                virtualFunction();
                            }
                        } else if (bannerParams.buttonCustomDismissBanner) {
                            // Declarations.
                            let expireDay = null,
                                actionType = ACTION_TYPE_DISMISS;

                            if (bannerParams.popupID) {
                                // Set expiration date for this popup in local storage.
                                setExpiringPopup(
                                    abs(bannerParams.popupID),
                                    POPUP_TYPE_BANNER,
                                    expireDay
                                );

                                // Update dismiss banner table.
                                // Handle Popup Action Ajax Call.
                                $.ajax({
                                    type: "POST",
                                    url: "/Popup/HandlePopupActionAsync/",
                                    data: {
                                        popupID: abs(bannerParams.popupID),
                                        actionType: actionType,
                                        days: expireDay,
                                        popupType: POPUP_TYPE_BANNER
                                    },
                                    error: (err) =>
                                        console.log(`ERROR: ${err}`),
                                });
                            }
                        }

                        // Delete DOM.
                        $(event.target).parents(".lexpera-banner").remove();
                    });
                }

                // Hyperlinks color.
                if (bannerParams.linkColor) {
                    // Hyperlink color.
                    messageContainer.find("a").css({
                        color: bannerParams.linkColor,
                    });
                }

                // Banner theme depending on type.
                if (bannerParams.type) {
                    switch (bannerParams.type.toLowerCase()) {
                        case "success":
                            // Background color.
                            this.banner.css({
                                backgroundColor: COLOR_SUCCESS,
                            });

                            // Hyperlink color.
                            messageContainer.find("a").css({
                                color: COLOR_SUCCESS_LINKS,
                            });

                            // Buttons background color.
                            btnDismiss.css({
                                backgroundColor: COLOR_LEXPERA_BLUE,
                            });

                            btnCustom.css({
                                backgroundColor: COLOR_BLACK,
                            });
                            break;
                        case "danger":
                            this.banner.css({
                                backgroundColor: COLOR_DANGER,
                            });

                            // Hyperlink color.
                            messageContainer.find("a").css({
                                color: COLOR_DANGER_LINKS,
                            });

                            // Buttons background color.
                            btnDismiss.css({
                                backgroundColor: COLOR_DANGER_ANALOGOUS,
                            });

                            btnCustom.css({
                                backgroundColor: COLOR_BLACK,
                            });
                            break;
                        case "warning":
                            this.banner.css({
                                backgroundColor: COLOR_WARNING,
                            });

                            // Hyperlink color.
                            messageContainer.find("a").css({
                                color: COLOR_WARNING_LINKS,
                            });

                            // Icon color.
                            iconContainer.children().css({
                                color: COLOR_BLACK,
                            });

                            // Text color.
                            messageContent.css({
                                color: COLOR_BLACK,
                            });

                            // Buttons background color.
                            btnDismiss.css({
                                backgroundColor: COLOR_WARNING_ANALOGOUS,
                            });

                            btnCustom.css({
                                backgroundColor: COLOR_BLACK,
                            });
                            break;
                        default:
                            break;
                    }
                }

                // Hide the banner.
                if (bannerParams.visible === false) this.banner.hide();

                // Add delay to attach the banner to DOM.
                if (bannerParams.displayDelay) {
                    window.setTimeout(() => {
                        // Attach html to body.
                        AttachVirtualDIV(bannerParams.position);
                    }, abs(bannerParams.displayDelay) * 1000);
                } else {
                    // Attach html to body.
                    AttachVirtualDIV(bannerParams.position);
                }

                // Remove the DOM after duration.
                if (bannerParams.displayDuration) {
                    HideAfterDuration(bannerParams.displayDuration);
                }
            }
        };

        // Method of attaching DOM to body.
        const AttachVirtualDIV = (position) => {
            if (position && position.toLowerCase() === "top")
                $("body").prepend(virtualDIV);
            else $("body").append(virtualDIV);

            // Remove the last banner instantiated if limit has been reached.
            if (LexperaBanner.maxInstancesReached()) {
                $(this.banner).remove();
                throw "Error: You can only create up to 2 banners at the same time";
            }
        };

        // Hide banner after duration.
        const HideAfterDuration = (duration) => {
            let totalDuration = abs(duration);

            // Display delay is present.
            if (bannerParams.displayDelay)
                totalDuration = abs(bannerParams.displayDelay) + abs(duration);

            if (duration) {
                window.setTimeout(() => {
                    // Call custom function before automatic DOM removal.
                    if (bannerParams.onCloseFunction) {
                        if (typeof bannerParams.onCloseFunction === "function")
                            // Call the passed function.
                            bannerParams.onCloseFunction();
                        else if (
                            typeof bannerParams.onCloseFunction === "string" &&
                            bannerParams.onCloseFunction.length > 0
                        ) {
                            // Execute string js declarations like eval.

                            // Create new function.
                            let virtualFunction = new Function(
                                bannerParams.onCloseFunction
                            );
                            // Call virtual function.
                            virtualFunction();
                        }
                    }
                    // Remove DOM.
                    this.banner.remove();
                }, totalDuration * 1000);
            }
        };

        // Banner defaults and customizations.
        const Initialize = (bannerParams) => {
            if (bannerParams && Object.keys(bannerParams).length > 0) {
                // Call default styles.
                DefaultCSS();

                // Apply customizations.
                ApplyCustomizations(bannerParams);
            } else return;
        };

        // To avoid duplicates of same banner.
        if (!isThisDomExisting(`#${bannerParams.bannerID}`))
            // Initialize banner.
            Initialize(bannerParams);
    }

    // Hide banner.
    hide() {
        this.banner.css({
            display: "none",
        });
    }

    // Show banner.
    show() {
        this.banner.css({
            display: "flex",
        });
    }

    // Remove banner completely.
    destroy() {
        $(this.banner).remove();
    }

    // Counts instances of class.
    static maxInstancesReached() {
        if (!this.numOfCreatedInstances) this.numOfCreatedInstances = 0;

        return ++this.numOfCreatedInstances > 2;
    }
}

/**
 * Customizable lexpera modal.
 * Minimum requirement of bootstrap v4.
 *
 * @param {*} modalParams = pass objects for customizations.
 * @param {string} modalParams.modalID = ID selector to modal.
 * @param {string} modalParams.popupID = Custom attribute for popup ID.
 * @param {string} modalParams.additionalClass = Add class to popup.
 * @param {string} modalParams.title = Modal title.
 * @param {string} modalParams.content = Modal body content.
 * @param {string} modalParams.type = Modal theme depending on type.
 * @param {string} modalParams.modalSize = Modal size. Options: "small", "large", "extra-large".
 * @param {string} modalParams.modalPosition = Modal position. Options: "top", default is center.
 * @param {string} modalParams.modalHeaderColor = Modal header color.
 * @param {string} modalParams.modalHeaderBackgroundColor = Modal header background color.
 * @param {boolean} modalParams.modalHeaderHidden = Hide modal header.
 * @param {string} modalParams.modalHeaderContent = Modal header content.
 * @param {boolean} modalParams.modalBodyHidden = Hide modal body.
 * @param {string} modalParams.modalBodyColor = Modal body color.
 * @param {string} modalParams.modalBodyBackgroundColor = Modal body background color.
 * @param {string} modalParams.modalFooterColor = Modal footer color.
 * @param {string} modalParams.modalFooterBackgroundColor = Modal footer background color.
 * @param {boolean} modalParams.modalFooterHidden = Hide modal footer.
 * @param {string} modalParams.modalFooterContent = Modal footer content.
 * @param {string} modalParams.closeButtonColor = Close button color.
 * @param {string} modalParams.closeButtonText = Custom designed close button with text.
 * @param {array | string} modalParams.actionButtons = Dynamic custom buttons and configuration.
 * @param {string} modalParams.HTMLContent = Pass HTML content for modal body. Overwrites modalParams.content and modalParams.modalHeaderContent.
 * @param {boolean} modalParams.visible = Hide the modal by default.
 * @param {integer} modalParams.displayDelay = Add delay to attach the modal to DOM. Pass in unit of seconds, ex: 6 will be 6 seconds.
 * @param {integer} modalParams.displayDuration = Hide the DOM after duration.
 * @param {boolean} modalParams.isRecurring = Flag to check if modal is recurring.
 * @param {integer} modalParams.recurringDays = Expiration date for the modal to reshow again from localStorage and DB.
 * @param {string} modalParams.targetElement = Selector for a javascript event to interact with.
 * @param {string} modalParams.targetAction = Pass javascript events to trigger modal showing. Visit this site for a reference of events "https://www.w3schools.com/jsref/dom_obj_event.asp"
 * @param {boolean} modalParams.modalBackdropStatic = Makes modal backdrop dismissable only by clicking on "X" button.
 * @param {boolean} modalParams.destroyOnClose = Remove modal on close.
 * @param {anonymous_function | string} modalParams.onCloseFunction = Custom event handler that triggers upon modal close (clicking "X" button); Pass string of js declarations or pass name of function if without parameters, use anonymous function if with parameters () => callThisFunction(p1, p2, ...); Make sure to pass escaped characters for multi line js ex: \r \n \t
 *
 */
class LexperaModal {
    constructor(modalParams) {
        // CONSTANTS.
        const COLOR_LEXPERA_BLUE = "#2F7A8E";
        const COLOR_WHITE = "#FFFFFF";
        const COLOR_RED = "#FF0000";
        const COLOR_SUCCESS = "#28A745";
        const COLOR_DANGER = "#DC3545";
        const COLOR_WARNING = "#FFC107";
        const COLOR_INFO = "#17A2B8";
        const COLOR_DARK = "#343A40";
        const COLOR_MODAL_OVERLAY = "rgba(213,213,213, 0.5)";
        const COLOR_MODAL_HEADER = "#EAE6D6";
        const COLOR_MODAL_BODY = "#F4F2E9";
        const ACTION_TYPE_HIDE = "hide";
        const ACTION_TYPE_DISMISS = "dismiss";
        const POPUP_TYPE_MODAL = "MODAL";
        const WARNING_MESSAGE_TARGET_ELEMENT =
            "Please provide valid configuration for targetElement and targetAction to initialize modal properly.";
        const MAX_CLOSE_BUTTON_TEXT_LENGTH = 100;
        const SLASH = "/";

        // Build base HTML.
        const markup = `
			<div class="modal fade lexpera-modal" tabindex="-1" data-keyboard="false" aria-hidden="true">
				<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
					<div class="modal-content">
						<div class="modal-header">
							<h5 class="modal-title">
							</h5>
							<button type="button" class="close" data-dismiss="modal" aria-label="Close">
								<span aria-hidden="true">&times;</span>
							</button>
						</div>
						<div class="modal-body">
						</div>
						<div class="modal-footer">
						</div>
					</div>
				</div>
			</div>
			`;

        // Create virtual wrapper.
        let parentVirtualWrapper = document.createElement("div");

        // Append HTML body from markup.
        parentVirtualWrapper.innerHTML = markup;

        // Extract elements for styling and customizations.
        this.modal = $(parentVirtualWrapper).children(".lexpera-modal");
        let modalDialog = this.modal.find(".modal-dialog");
        let modalContent = this.modal.find(".modal-content");
        let modalHeader = this.modal.find(".modal-header");
        let modalTitle = this.modal.find(".modal-title");
        let modalBody = this.modal.find(".modal-body");
        let modalFooter = this.modal.find(".modal-footer");
        let buttons = this.modal.find("button");
        let btnModalClose = buttons.filter((b) =>
            $(buttons[b]).hasClass("close")
        );
        let select = this.modal.find("select");

        // Default configurations.

        // Default css.
        const DefaultCSS = () => {
            this.modal.css({
                "background-color": COLOR_MODAL_OVERLAY,
            });

            modalHeader.css({
                "background-color": COLOR_MODAL_HEADER,
                "border-bottom": 0,
                "border-radius": 0,
            });

            modalContent.css({
                "border-radius": 0,
                border: 0,
            });

            modalBody.css({
                "background-color": COLOR_MODAL_BODY,
            });

            modalFooter.css({
                "background-color": COLOR_MODAL_BODY,
                "border-top": 0,
                "border-radius": 0,
                "justify-content": "center",
            });

            buttons.css({
                "border-radius": 0,
            });

            btnModalClose.css({
                color: COLOR_LEXPERA_BLUE,
                "text-shadow": "none",
            });

            // On focus of button modal close.
            btnModalClose.on("focus", () => {
                btnModalClose.css({
                    "box-shadow": "none",
                    outline: "none",
                });
            });

            select.css({
                "border-radius": 0,
            });
        };

        // Customizations.
        const ApplyCustomizations = (modalParams) => {
            // Parameters for customizations are present.
            if (modalParams) {
                // ID selector to modal.
                if (modalParams.modalID) {
                    if (
                        typeof modalParams.modalID === "string" &&
                        isNaN(modalParams.modalID) &&
                        modalParams.modalID.trim().length > 0
                    )
                        // Assign ID.
                        this.modal.attr("id", modalParams.modalID);
                }

                // Custom attribute popup id.
                if (modalParams.popupID && !isNaN(modalParams.popupID))
                    this.modal.attr("popup-id", abs(modalParams.popupID));

                // Add class.
                if (modalParams.additionalClass) {
                    if (
                        typeof modalParams.additionalClass === "string" &&
                        modalParams.additionalClass.trim().length > 0
                    )
                        this.modal.addClass(modalParams.additionalClass);
                }

                // Modal title.
                if (modalParams.title && modalParams.title.trim().length > 0)
                    modalTitle.html(modalParams.title.trim());

                // Modal body content.
                if (modalParams.content && modalParams.content.trim().length > 0)
                    modalBody.html(modalParams.content.trim());

                // Modal sizes.
                if (modalParams.modalSize) {
                    switch (modalParams.modalSize.toLowerCase()) {
                        case "small": {
                            // Clear existing size classes.
                            modalDialog
                                .removeClass("modal-sm modal-lg modal-xl")
                                .addClass("modal-sm");
                            break;
                        }
                        case "large": {
                            // Clear existing size classes.
                            modalDialog
                                .removeClass("modal-sm modal-lg modal-xl")
                                .addClass("modal-lg");
                            break;
                        }
                        case "extra-large": {
                            // Clear existing size classes.
                            modalDialog
                                .removeClass("modal-sm modal-lg modal-xl")
                                .addClass("modal-xl");
                            break;
                        }
                        default: {
                            // Clear existing size classes.
                            modalDialog.removeClass(
                                "modal-sm modal-lg modal-xl"
                            );
                            break;
                        }
                    }
                }

                // Modal position.
                if (modalParams.modalPosition) {
                    switch (modalParams.modalPosition.toLowerCase()) {
                        case "top": {
                            modalDialog.css({
                                "justify-content": "flex-start",
                            });
                            break;
                        }
                        default:
                            break;
                    }
                }

                // Modal header color.
                if (modalParams.modalHeaderColor) {
                    modalHeader.css({
                        color: modalParams.modalHeaderColor,
                    });
                }

                // Modal header background color.
                if (modalParams.modalHeaderBackgroundColor) {
                    modalHeader.css({
                        "background-color": modalParams.modalHeaderBackgroundColor,
                    });
                }

                // Hide modal header.
                if (
                    modalParams.modalHeaderHidden &&
                    modalParams.modalHeaderHidden === true
                ) {
                    // Hide.
                    modalHeader.hide();

                    // Relocate dismiss button.
                    RelocateModalClose();
                }

                // Modal header content.
                if (
                    modalParams.modalHeaderContent &&
                    modalParams.modalHeaderContent.trim().length > 0
                ) {
                    // Relocate dismiss button.
                    RelocateModalClose();

                    // Apply html.
                    modalHeader.html(modalParams.modalHeaderContent.trim());
                }

                // Hide modal body.
                if (modalParams.modalBodyHidden && modalParams.modalBodyHidden === true) {
                    // Hide.
                    modalBody.hide();
                }

                // Modal body color.
                if (modalParams.modalBodyColor) {
                    let modBodyFooter = this.modal.find(
                        ".modal-content, .modal-body, .modal-footer"
                    );

                    modBodyFooter.css({
                        color: modalParams.modalBodyColor,
                    });
                }

                // Modal body background color.
                if (modalParams.modalBodyBackgroundColor) {
                    let modBodyFooter = this.modal.find(
                        ".modal-content, .modal-body, .modal-footer"
                    );

                    modBodyFooter.css({
                        "background-color": modalParams.modalBodyBackgroundColor,
                    });
                }

                // Modal footer color.
                if (modalParams.modalFooterColor) {
                    modalFooter.css({
                        color: modalParams.modalFooterColor,
                    });
                }

                // Modal footer background color.
                if (modalParams.modalFooterBackgroundColor) {
                    modalFooter.css({
                        "background-color": modalParams.modalFooterBackgroundColor,
                    });
                }

                // Hide modal footer.
                if (
                    modalParams.modalFooterHidden &&
                    modalParams.modalFooterHidden === true
                ) {
                    // Hide.
                    modalFooter.hide();
                }

                // Modal theme depending on type.
                if (modalParams.type) {
                    // Apply to all these modal elements.
                    let modalElements = this.modal.find(
                        ".modal-content, .modal-header, .modal-body, .modal-footer"
                    );

                    switch (modalParams.type.toLowerCase()) {
                        case "success":
                            modalElements.css({
                                backgroundColor: COLOR_SUCCESS,
                            });

                            // Adjust color of modal header.
                            modalHeader.css("filter", "hue-rotate(-10deg)");
                            break;
                        case "danger":
                            modalElements.css({
                                backgroundColor: COLOR_DANGER,
                            });

                            // Adjust color of modal body content and footer.
                            modalBody.css("filter", "hue-rotate(-15deg)");
                            modalFooter.css("filter", "hue-rotate(-15deg)");
                            break;
                        case "warning":
                            modalElements.css({
                                backgroundColor: COLOR_WARNING,
                            });

                            // Adjust color of modal header.
                            modalHeader.css("filter", "hue-rotate(-10deg)");
                            break;
                        case "info":
                            modalElements.css({
                                backgroundColor: COLOR_INFO,
                            });

                            // Adjust color of modal header.
                            modalHeader.css("filter", "hue-rotate(-10deg)");
                            break;
                        case "dark":
                            modalElements.css({
                                backgroundColor: COLOR_DARK,
                            });

                            // Color.
                            modalElements.css("color", COLOR_WHITE);
                            // Adjust color of modal header.
                            modalHeader.css("filter", "hue-rotate(-70deg)");
                            break;
                        default:
                            break;
                    }
                }

                // Dynamic custom buttons and configuration.
                if (modalParams.actionButtons) {
                    // Get array config.
                    let btnConfig =
                        Array.isArray(modalParams.actionButtons) &&
                            modalParams.actionButtons.length
                            ? [...modalParams.actionButtons]
                            : JSON.parse(modalParams.actionButtons);

                    // Create button container element.
                    let virtualButtonContainer = document.createElement("div");

                    // Assign class for container.
                    virtualButtonContainer.className = "lm-action-buttons";

                    // Iterate through array to create buttons and config.
                    btnConfig.map((btnParams) => {
                        // Create element.
                        let virtualButton = document.createElement("button");

                        // Add bootstrap btn class.
                        $(virtualButton).addClass("btn");

                        // Default button css.
                        $(virtualButton)
                            .css({
                                cssText: `
						margin-left: 8px; 
						margin-right: 8px; 
						font-size: 0.75rem;
						border-radius: 0;
						color: white;
						background-color: #4E6066;
						`,
                            })
                            .addClass("btn-sm");

                        // Hover effects.
                        $(virtualButton)
                            .on("mouseenter", (event) => {
                                // Prevent bubbling.
                                event.stopImmediatePropagation();
                                // Apply css.
                                $(event.target).css(
                                    "filter",
                                    "brightness(1.1)"
                                );
                            })
                            .on("mouseleave", (event) => {
                                // Prevent bubbling.
                                event.stopImmediatePropagation();
                                // Remove css.
                                $(event.target).css("filter", "");
                            });

                        // Responsive.
                        if (window.innerWidth >= 768) {
                            $(virtualButton)
                                .css({
                                    "font-size": "0.9rem",
                                })
                                .removeClass("btn-sm");
                        }

                        // Button ID.
                        if (btnParams.actionButtonID) {
                            if (
                                typeof btnParams.actionButtonID === "string" &&
                                isNaN(btnParams.actionButtonID) &&
                                btnParams.actionButtonID.trim().length > 0
                            )
                                // Assign ID.
                                $(virtualButton).attr(
                                    "id",
                                    btnParams.actionButtonID
                                );
                        }

                        // Button Text.
                        $(virtualButton).text(
                            btnParams.actionButtonText || "Cstm Button"
                        );

                        // Button color.
                        if (btnParams.actionButtonColor)
                            $(virtualButton).css({
                                color: btnParams.actionButtonColor,
                            });

                        // Button background color.
                        if (btnParams.actionButtonBackgroundColor)
                            $(virtualButton).css({
                                "background-color":
                                    btnParams.actionButtonBackgroundColor,
                            });

                        // Click handler.
                        $(virtualButton).on("click", () => {
                            if (
                                btnParams.actionButtonURL &&
                                btnParams.actionButtonURL.trim().length > 0
                            )
                                // Navigate.
                                window.location.href =
                                    window.location.origin +
                                    SLASH +
                                    btnParams.actionButtonURL;
                            // Pass custom function.
                            else if (btnParams.actionButtonFunction) {
                                if (
                                    typeof btnParams.actionButtonFunction ===
                                    "function"
                                )
                                    // Call the passed function.
                                    btnParams.actionButtonFunction();
                                else if (
                                    typeof btnParams.actionButtonFunction ===
                                    "string" &&
                                    btnParams.actionButtonFunction.length > 0
                                ) {
                                    // Execute string js declarations like eval.

                                    // Create new function.
                                    let virtualFunction = new Function(
                                        btnParams.actionButtonFunction
                                    );
                                    // Call virtual function.
                                    virtualFunction();
                                }
                            }
                        });

                        // Append button to button container.
                        $(virtualButton).appendTo(virtualButtonContainer);
                    });

                    // Attach to modal footer.
                    modalFooter.append(virtualButtonContainer);
                }

                // Apply HTML to modal body.
                if (
                    modalParams.HTMLContent &&
                    modalParams.HTMLContent.trim().length > 0
                ) {
                    // Relocate dismiss button.
                    RelocateModalClose();

                    // Detach modal footer.
                    if (modalParams.actionButtons || modalParams.modalFooterContent) {
                        // Modal footer.
                        let modFoot = modalFooter;

                        // Detach footer.
                        var detModFoot = modFoot.detach();

                        if (!modalParams.modalFooterBackgroundColor) {
                            // Clear default css.
                            modFoot.css({
                                "background-color": "",
                            });
                        }
                    }

                    // Apply html.
                    modalContent.html(modalParams.HTMLContent);

                    // Bootstrap event on show.
                    this.modal.on("show.bs.modal", function (event) {
                        // Reappend detached modal footer to modal content body.
                        if (modalParams.actionButtons || modalParams.modalFooterContent)
                            detModFoot.appendTo(modalContent);
                    });
                }

                // Footer content.
                if (
                    modalParams.modalFooterContent &&
                    modalParams.modalFooterContent.trim().length > 0
                ) {
                    // Create footer content container element.
                    let footerContentContainer = document.createElement("div");

                    // Assign class for container.
                    footerContentContainer.className = "lm-footer-content";

                    // Apply CSS for footer content container.
                    $(footerContentContainer).css({
                        cssText: `
							flex: 1;
							margin-right: auto;
							`,
                    });

                    // Apply content.
                    $(footerContentContainer).html(modalParams.modalFooterContent);

                    // Attach to modal footer as first child element.
                    modalFooter.prepend(footerContentContainer);
                }

                // Close button color.
                if (modalParams.closeButtonColor) {
                    btnModalClose.css({
                        color: modalParams.closeButtonColor,
                    });
                }

                // Close button text.
                if (modalParams.closeButtonText &&
                    modalParams.closeButtonText.trim().length > 0) {

                    // Trim text if exceeds max length.
                    if (modalParams.closeButtonText.trim().length > MAX_CLOSE_BUTTON_TEXT_LENGTH) {
                        modalParams.closeButtonText = modalParams.closeButtonText.trim().substring(0, MAX_CLOSE_BUTTON_TEXT_LENGTH);
                    }

                    // Create base close button markup.
                    let closeButtonMarkup = `
						<div>
							<span>${modalParams.closeButtonText.trim()}</span>
							<span aria-hidden="true">×</span>
						</div>
						`;

                    // Change html.
                    btnModalClose.html(closeButtonMarkup);

                    // Apply css.
                    btnModalClose.css({
                        position: "fixed",
                        right: "10px",
                        top: "2px",
                        color: "rgb(255, 0, 0)",
                        textShadow: "none",
                        boxShadow: "none",
                        outline: "none",
                        transform: "none"
                    });

                    let btnModalCloseBody = btnModalClose.find("div");
                    // 1st span close button text.
                    let btnModalCloseText = btnModalClose.find("span").eq(0);
                    // 2nd span close button "X".
                    let btnModalCloseButton = btnModalClose.find("span").eq(1);

                    // Close button body css.
                    btnModalCloseBody.css({
                        backgroundColor: "red",
                        padding: "4px 40px 6px 10px",
                        borderRadius: "12px",
                        color: "white",
                        display: "inline-flex",
                        justifyContent: "center",
                        alignItems: "center"
                    });

                    // Close button text css.
                    btnModalCloseText.css("font-size", "12px");

                    // Close button "X" css.
                    btnModalCloseButton.css({
                        color: "white",
                        position: "fixed",
                        backgroundColor: "#2f7a8e",
                        right: "20px",
                        top: "0",
                        paddingRight: "3px",
                        paddingLeft: "3px",
                        height: "36px",
                        fontSize: "34px",
                        display: "flex",
                        alignItems: "center"
                    });

                }

                // Hide modal on button dismiss click.
                btnModalClose.on("click", () => {
                    HideModal();
                });

                // Show modal on targetElement.
                // Triggered by targetAction js DOM events.
                if (
                    modalParams.targetElement &&
                    modalParams.targetAction &&
                    isThisDomExisting(modalParams.targetElement)
                ) {
                    $(`body`).on(
                        `${modalParams.targetAction}`,
                        `${modalParams.targetElement}`,
                        () => {
                            // Show if no attribute "lexpera-modal-dismissed" present.
                            if (
                                !$(`${modalParams.targetElement}`)[0].hasAttribute(
                                    "lexpera-modal-dismissed"
                                )
                            ) {
                                // Show modal.
                                this.modal.modal("show");

                                // Hide modal after duration.
                                HideAfterDuration(modalParams.displayDuration);
                            }
                        }
                    );
                } else {
                    // Add delay to show modal or show right away.
                    if (modalParams.displayDelay) {
                        window.setTimeout(() => {
                            // Show modal
                            ShowModal(modalParams.visible);
                        }, abs(modalParams.displayDelay) * 1000);
                    } else {
                        // Show modal
                        ShowModal(modalParams.visible);
                    }

                    // Hide modal after duration.
                    HideAfterDuration(modalParams.displayDuration);
                }

                // On modal hide, destroy modal.
                this.modal.on("hidden.bs.modal", function (event) {
                    if (modalParams.destroyOnClose && modalParams.destroyOnClose === true)
                        $(event.target).detach();
                });

                // Modal backdrop dismissable only by clicking on "X" button.
                if (
                    modalParams.modalBackdropStatic &&
                    modalParams.modalBackdropStatic === true
                ) {
                    this.modal.on("show.bs.modal", function (event) {
                        // Set to static backdrop.
                        if (isLegacyBootstrap()) {
                            if ($(this).data("bs.modal").options)
                                $(this).data("bs.modal").options.backdrop = "static";
                        } else {
                            if ($(this).data("bs.modal")._config)
                                $(this).data("bs.modal")._config.backdrop = "static";
                        }
                    });

                    // Emulate the backdrop static effect of enlarging the modal.
                    $("body").on("click", (event) => {
                        let htmlBody = $(event.currentTarget);

                        if (htmlBody.hasClass("modal-open")) {
                            // Apply css.
                            this.modal.css({
                                transform: "scale(1.02)",
                                transition: "all 0.2s",
                            });

                            // Clean css.
                            setTimeout(() => {
                                this.modal.css("transform", "");
                            }, 110);
                        }
                    });
                }
            }
        };

        // Show modal depending on modalParams.visible.
        const ShowModal = (visible) => {
            // Show modal by default. Otherwise hide on demand.
            if (
                visible === undefined ||
                typeof visible !== "boolean" ||
                visible !== false
            )
                this.modal.modal("show");
        };

        // Hide modal after duration.
        const HideAfterDuration = (duration) => {
            let totalDuration = abs(duration);

            // Display delay is present and target element is not existing.
            if (
                (!modalParams.targetAction ||
                    !isThisDomExisting(modalParams.targetElement)) &&
                modalParams.displayDelay
            )
                totalDuration = abs(modalParams.displayDelay) + abs(duration);

            if (duration) {
                window.setTimeout(() => {
                    HideModal();
                }, totalDuration * 1000);
            }
        };

        // Hide the modal and perform sets of actions.
        const HideModal = () => {
            // Declarations.
            let expireDay, actionType;

            // Get expiration day from parameters or set to max.
            // Action type of popup.
            if (modalParams.isRecurring && modalParams.recurringDays) {
                expireDay = abs(modalParams.recurringDays);
                actionType = ACTION_TYPE_HIDE;
            } else {
                expireDay = null;
                actionType = ACTION_TYPE_DISMISS;
            }

            if (modalParams.popupID) {
                // Set expiration date for this popup in local storage.
                setExpiringPopup(
                    abs(modalParams.popupID),
                    POPUP_TYPE_MODAL,
                    expireDay
                );

                // Set attribute for target element to not show again on js DOM event action.
                if (
                    modalParams.targetElement &&
                    modalParams.targetAction &&
                    isThisDomExisting(modalParams.targetElement)
                )
                    $(`${modalParams.targetElement}`).attr(
                        "lexpera-modal-dismissed",
                        true
                    );

                // Update dismiss modal table.
                // Handle Popup Action Ajax Call.
                $.ajax({
                    type: "POST",
                    url: "/Popup/HandlePopupActionAsync/",
                    data: {
                        popupID: abs(modalParams.popupID),
                        actionType: actionType,
                        days: expireDay,
                        popupType: POPUP_TYPE_MODAL
                    },
                    error: (err) => console.log(`ERROR: ${err}`),
                });
            }

            // Custom function.
            if (modalParams.onCloseFunction) {
                if (typeof modalParams.onCloseFunction === "function")
                    // Call the passed function.
                    modalParams.onCloseFunction();
                else if (
                    typeof modalParams.onCloseFunction === "string" &&
                    modalParams.onCloseFunction.length > 0
                ) {
                    // Execute string js declarations like eval.

                    // Create new function.
                    let virtualFunction = new Function(modalParams.onCloseFunction);
                    // Call virtual function.
                    virtualFunction();
                }
            }

            // Hide programmatically.
            this.modal.modal("hide");
        };

        // Relocate modal close button.
        const RelocateModalClose = () => {
            // Get button close.
            let btnX = btnModalClose;
            // Detach close button from DOM.
            let detBtnX = btnX.detach();

            // Apply new CSS.
            btnX.css({
                cssText: `
						position: fixed;
						right: 8px;
						top: 4px;
						color: ${COLOR_RED};
						transform: scale(1.5);
						text-shadow: none;
						`,
            });

            // Bootstrap event on show.
            this.modal.on("show.bs.modal", function (event) {
                // Reappend to DOM .modal.fade.
                detBtnX.appendTo(event.target);
            });
        };

        // Modal defaults and customizations.
        const Initialize = (modalParams) => {
            if (modalParams && Object.keys(modalParams).length > 0) {
                // Initialize only when targetElement is existing or no targetElement and action provided.
                if (
                    (!modalParams.targetElement && !modalParams.targetAction) ||
                    isThisDomExisting(modalParams.targetElement)
                ) {
                    // Call default styles.
                    DefaultCSS();

                    // Apply customizations.
                    ApplyCustomizations(modalParams);

                    // Reference the parameters in this class.
                    this.modalParams = modalParams;

                    // Attach DOM to HTML body.
                    $("body").append(parentVirtualWrapper);

                    // Remove parent wrapper.
                    this.modal.unwrap();
                } else {
                    // Throw warning message.
                    console.warn(WARNING_MESSAGE_TARGET_ELEMENT);
                    // Set flag to invalid configuration.
                    this.isInvalidConfiguration = true;
                }
            } else return;
        };

        // Initialize modal.
        Initialize(modalParams);
    }

    // Hide modal.
    hide(duration) {
        if (duration && !isNaN(duration)) {
            window.setTimeout(() => {
                this.modal.modal("hide");
            }, Number(duration) * 1000);
        } else this.modal.modal("hide");
    }

    // Show modal.
    show(duration) {
        if (duration && !isNaN(duration)) {
            window.setTimeout(() => {
                this.modal.modal("show");
            }, Number(duration) * 1000);
        } else this.modal.modal("show");
    }

    // Remove modal completely.
    destroy() {
        // Delete instance and data elements.
        this.modal.modal("dispose");

        // Remove completely.
        this.modal.remove();
        $(".modal-backdrop").remove();

        // Remove defined styles and classes from body.
        $("body").removeClass("modal-open").css("padding-right", "");
    }

    // Executes function body on modal instance button close.
    onModalCloseExecute(fnBody) {
        let btnInstanceClose = this.modal.find("button.close");

        btnInstanceClose.on("click", function () {
            if (typeof fnBody === "function") {
                // Call the passed function.
                fnBody();
            } else if (typeof fnBody === "string" && fnBody > 0) {
                // Create new function.
                let virtualFunction = new Function(fnBody);
                // Call virtual function.
                virtualFunction();
            }
        });
    }
}

/**
 * Executes Driver.js with/without customizations.
 * Driver.js must be installed.
 * Visit link for customizations and step definitions. "https://github.com/kamranahmedse/driver.js/blob/cce1e72b05c0bd60fe5f7b9f7dc054449e91612d/readme.md"
 *
 * @param {*} tooltipsParams = pass objects for customizations.
 * @param {integer} tooltipsParams.zIndex = Alter z-index; Default is 11000 for 5 digits.
 * @param {string} tooltipsParams.popupID = Custom attribute for popup ID.
 * @param {string} tooltipsParams.targetElement = Selector for a javascript event to interact with.
 * @param {string} tooltipsParams.targetAction = Pass javascript events to trigger driver.js. Visit this site for a reference of events "https://www.w3schools.com/jsref/dom_obj_event.asp"
 * @param {array | object} tooltipsParams.steps = Array of step definitions. "https://github.com/kamranahmedse/driver.js/blob/cce1e72b05c0bd60fe5f7b9f7dc054449e91612d/readme.md#step-definition"
 * @param {object} tooltipsParams.configuration = Driver.js option definitions. "https://github.com/kamranahmedse/driver.js/blob/cce1e72b05c0bd60fe5f7b9f7dc054449e91612d/readme.md#driver-definition". Do not pass javascript code.
 * @param {integer} tooltipsParams.displayDelay = Add delay to start driver js. Pass in unit of seconds, ex: 6 will be 6 seconds.
 * @param {anonymous_function | string} tooltipsParams.onCloseFunction = Custom event handler that triggers upon Driver.js close; Pass string of js declarations or pass name of function if without parameters, use anonymous function if with parameters () => callThisFunction(p1, p2, ...); Make sure to pass escaped characters for multi line js ex: \r \n \t
 * @param {boolean} tooltipsParams.isRecurring = Flag to check if tooltips is recurring.
 * @param {integer} tooltipsParams.recurringDays = Expiration date for the tooltips to reshow again from localStorage and DB.
 *
 */
class LexperaTooltips {
    constructor(tooltipsParams) {
        // CONSTANTS.
        const ACTION_TYPE_HIDE = "hide";
        const ACTION_TYPE_DISMISS = "dismiss";
        const POPUP_TYPE_TOOLTIP = "TOOLTIP";
        const SLASH = "/";

        // Reference driver in constructor.
        var driver = this.driver;

        // Execute driver.js with/without config.
        const ExecuteDriverJS = (tooltipsParams) => {
            // Checks if tooltipsParams.steps is an object or array.
            // Also checks tooltipsParams.steps if it has any highlightable element.
            if (
                tooltipsParams.steps &&
                hasTooltipsDOMToHighlight(tooltipsParams.steps) &&
                (Object.prototype.toString.call(tooltipsParams.steps) ===
                    "[object Object]" ||
                    Object.prototype.toString.call(tooltipsParams.steps) ===
                    "[object Array]")
            ) {
                // Driver.js instance with option config.
                if (tooltipsParams.configuration)
                    driver = new Driver(tooltipsParams.configuration);
                // Normal Driver.js instance.
                else driver = new Driver();
            } else return;

            // Set array.
            let steps = [];

            // Copy array.
            if (Array.isArray(tooltipsParams.steps) && tooltipsParams.steps.length >= 1)
                steps = [...tooltipsParams.steps];
            // Push object into array.
            else steps.push(tooltipsParams.steps);

            // Define the steps for introduction.
            driver.defineSteps(steps);

            // Start the tooltips.
            if (tooltipsParams.displayDelay && !isNaN(tooltipsParams.displayDelay)) {
                setTimeout(() => {
                    driver.start();
                }, abs(tooltipsParams.displayDelay) * 1000);
            } else driver.start();

            // Default css.
            DefaultCSS();

            // Define customizations.
            ApplyCustomizations(tooltipsParams);
        };

        // Default css.
        const DefaultCSS = () => {
            // Extract elements for styling and customizations.
            this.overlay = $(driver.document).find("#driver-page-overlay");

            // Keep zIndex to 11000+ to keep above LexperaBanner and LexperaModal zIndex.
            this.overlay.css({
                cssText: `
			z-index: 11000 !important;
			`,
            });
        };

        // Customizations.
        const ApplyCustomizations = (tooltipsParams) => {
            if (tooltipsParams) {
                // Z-index.
                if (tooltipsParams.zIndex) {
                    this.overlay.css({
                        cssText: `
					z-index: ${abs(tooltipsParams.zIndex)} !important;
					`,
                    });
                }

                // Some elements need to be "readied" before DOM manipulation.
                $(driver.document).ready(() => {
                    // Custom attribute popup id.
                    if (tooltipsParams.popupID && !isNaN(tooltipsParams.popupID))
                        this.overlay.attr("popup-id", abs(tooltipsParams.popupID));

                    // Refresh parameters.
                    referenceParameters();

                    // Hide the tooltips and perform sets of actions.
                    $("body").on(
                        "click",
                        ".driver-popover-footer button",
                        function (event) {
                            // Fech parameters.
                            let dataParams = $("body").data(
                                "lexpera-tooltips-tooltipsParams"
                            );

                            // Indicator for button close and last step.
                            let btnClose = $(event.target).hasClass(
                                "driver-close-btn"
                            );
                            let btnDone = $(event.target).hasClass(
                                "driver-next-btn"
                            );
                            let lastStep =
                                dataParams.driver.hasNextStep() === false;

                            // Trigger only on close and last step of tooltips.
                            if (btnClose || (btnDone && lastStep)) {
                                // Prevent bubbling.
                                event.stopImmediatePropagation();

                                // Declarations.
                                let expireDay, actionType;

                                // Get expiration day from parameters or set to max.
                                // Action type of popup.
                                if (
                                    dataParams.isRecurring &&
                                    dataParams.recurringDays &&
                                    !lastStep
                                ) {
                                    expireDay = abs(dataParams.recurringDays);
                                    actionType = ACTION_TYPE_HIDE;
                                } else {
                                    expireDay = null;
                                    actionType = ACTION_TYPE_DISMISS;
                                }

                                if (dataParams.popupID) {
                                    // Set expiration date for this popup in local storage.
                                    setExpiringPopup(
                                        abs(dataParams.popupID),
                                        POPUP_TYPE_TOOLTIP,
                                        expireDay
                                    );

                                    // Set attribute for target element to not show again on js DOM event action.
                                    if (
                                        dataParams.targetElement &&
                                        dataParams.targetAction &&
                                        isThisDomExisting(dataParams.targetElement)
                                    )
                                        $(`${dataParams.targetElement}`).attr(
                                            "lexpera-tooltips-dismissed",
                                            true
                                        );

                                    // Update tooltips table.
                                    // Handle Popup Action Ajax Call.
                                    $.ajax({
                                        type: "POST",
                                        url: "/Popup/HandlePopupActionAsync/",
                                        data: {
                                            popupID: abs(dataParams.popupID),
                                            actionType: actionType,
                                            days: expireDay,
                                            popupType: POPUP_TYPE_TOOLTIP
                                        },
                                        error: (err) =>
                                            console.log(`ERROR: ${err}`),
                                    });
                                }

                                // Custom function.
                                if (dataParams.onCloseFunction) {
                                    if (
                                        typeof dataParams.onCloseFunction ===
                                        "function"
                                    )
                                        // Call the passed function.
                                        dataParams.onCloseFunction();
                                    else if (
                                        typeof dataParams.onCloseFunction ===
                                        "string" &&
                                        dataParams.onCloseFunction.length > 0
                                    ) {
                                        // Execute string js declarations like eval.

                                        // Create new function.
                                        let virtualFunction = new Function(
                                            dataParams.onCloseFunction
                                        );
                                        // Call virtual function.
                                        virtualFunction();
                                    }
                                }

                                // Clear driver.js.
                                dataParams.driver.reset();
                            }
                        }
                    );
                });
            }
        };

        // Store parameters as reference to class and data.
        const referenceParameters = () => {
            // Add instance of driver.js to parameters.
            tooltipsParams.driver = driver;

            // Reference the parameters in this class.
            this.tooltipsParams = tooltipsParams;

            // Store the parameters into data.
            $("body").data("lexpera-tooltips-tooltipsParams", tooltipsParams);
        };

        // Tooltips defaults and customizations.
        const Initialize = (tooltipsParams) => {
            if (tooltipsParams && Object.keys(tooltipsParams).length > 0) {
                // Show tooltips on targetElement.
                // Triggered by targetAction js DOM events.
                if (tooltipsParams.targetElement
                    && tooltipsParams.targetAction
                    && tooltipsParams.targetElement.length
                    && tooltipsParams.targetAction.length) {
                    $("body").on(
                        `${tooltipsParams.targetAction}`,
                        `${tooltipsParams.targetElement}`,
                        (event) => {
                            // For driver.js to bind properly.
                            event.stopPropagation();

                            // Show if no attribute "lexpera-tooltips-dismissed" present.
                            if (
                                !$(`${tooltipsParams.targetElement}`)[0].hasAttribute(
                                    "lexpera-tooltips-dismissed"
                                )
                            )
                                // Execute driver.js.
                                ExecuteDriverJS(tooltipsParams);
                        }
                    );
                } else {
                    // One instance allowed at a time if no target element and action provided.
                    if (!LexperaTooltips.maxInstancesReached())
                        // Execute driver.js.
                        ExecuteDriverJS(tooltipsParams);
                }

                // Refresh parameters.
                referenceParameters();
            } else return;
        };

        // Initialize tooltips.
        Initialize(tooltipsParams);
    }

    // Return Driver.js instance if no target element and action provided.
    // See link for Driver.js methods. "https://github.com/kamranahmedse/driver.js#api-methods"
    // Check first for targetElement before using any driver.js methods.
    // Ex: let lt = new LexperaTooltips(); if (!targetElement) lt.getDriverInstance().moveNext().
    getDriverInstance() {
        if (this.tooltipsParams && this.tooltipsParams.driver) return this.tooltipsParams.driver;
    }

    // Counts instances of class.
    static maxInstancesReached() {
        if (!this.numOfCreatedInstances) this.numOfCreatedInstances = 0;

        return ++this.numOfCreatedInstances > 1;
    }
}

/**
 * COMMON FUNCTIONS
 */

/**
 * Check if passed string is HTML.
 * 
 * @param {string} str
 * @returns
 */
const containsHTML = (str) => /<[a-z][\s\S]*>/i.test(str);

/**
 * Return absolute number.
 * 
 * @param {number} digit
 * @returns
 */
const abs = (digit) => Math.abs(Number(digit));

/**
 * Check if DOM is present on the page.
 * 
 * @param {any} selector
 * @returns
 */
const isThisDomExisting = (selector) => $(selector).length > 0;

/**
 * Checks passed object/array for lexpera tooltips steps if it has any highlightable element.
 * 
 * @param {any} steps
 * @returns
 */
const hasTooltipsDOMToHighlight = (steps) => {
    let result = false;

    // Array.
    if (Array.isArray(steps))
        result = steps.some((el) => isThisDomExisting(el.element));
    else {
        // Check if DOM existing for "element" object property.
        if (steps.hasOwnProperty("element"))
            result = isThisDomExisting(steps["element"]);
    }

    return result;
};

/**
 * Checks if bootstrap is at version 3.
 * 
 * @returns
 */
const isLegacyBootstrap = () => Number($.fn.tooltip.Constructor.VERSION.at(0)) === 3;

/**
 * Set expire days for dismissed popups in local storage.
 * 
 * @param {number} key = Popup ID.
 * @param {string} type = banner, modal, tooltips.
 * @param {number} expiryDays = days before reshowing popup.
 * @returns
 */
const setExpiringPopup = (key, type, expiryDays) => {
    // For Object key.
    const POPUP_KEY = `popup_${key}`;

    // Declare date.
    let expiryDate = new Date();

    // Set expiration date.
    expiryDays !== null
        ? expiryDate.setDate(expiryDate.getDate() + Number(expiryDays))
        : (expiryDate = new Date("9999-12-31 23:59:59.997"));

    // Instantiate array.
    let arr = [];

    // Instantiate object.
    let obj = {};

    // Set key with expiration date.
    obj[POPUP_KEY] = {
        type: type,
        expiration: expiryDate,
    };

    // Fetch expired popups.
    let expiredPopup = localStorage["popups.expiringPopup"]
        ? JSON.parse(localStorage["popups.expiringPopup"])
        : null;

    // Add popup to array if localstorage key is existing, otherwise create new.
    if (expiredPopup && expiredPopup.length > 0) {
        // Check if key is already existing.
        const hasExistingKey = expiredPopup.some((el) =>
            el.hasOwnProperty(POPUP_KEY)
        );

        // Add new item if not existing.
        if (!hasExistingKey) {
            expiredPopup.push(obj);
            localStorage["popups.expiringPopup"] = JSON.stringify(expiredPopup);
        }

        return false;
    } else {
        arr.push(obj);
        localStorage["popups.expiringPopup"] = JSON.stringify(arr);
    }
};

/**
 * Returns popupID list of dismissed popups.
 * Removes popup on local storage if already expired.
 * 
 * @returns
 */
const GetLSPopups = () => {
    // Array holder.
    let popups = [];

    // Check if key existing.
    if (localStorage["popups.expiringPopup"]) {
        // Parse local storage data.
        var expiredPopups = JSON.parse(localStorage["popups.expiringPopup"]);

        // Return unexpired popups.
        const dismissedList = expiredPopups.filter((el) => {
            var now = new Date();
            if (now < Date.parse(Object.values(el)[0].expiration)) return true;
        });

        // Update values and push to array holder.
        if (dismissedList.length > 0) {
            localStorage["popups.expiringPopup"] = JSON.stringify(dismissedList);

            dismissedList.map((item) => {
                // Extract popupID from key.
                let key = Object.keys(item)[0].split("_").pop();
                popups.push(Number(key));
            });
        }
        // Remove localStorage key.
        else localStorage.removeItem("popups.expiringPopup");
    }

    return popups;
};

/**
 * Removes popup on local storage by type provided.
 * 
 * @param {string} type = banner, modal, tooltip.
 */
const ClearLSPopupsByType = (type) => {

    // Check if valid popup type.
    const validPopupType = ["banner", "modal", "tooltip"]
        .some(t => t === type.toLowerCase());

    // Check if key existing.
    if (localStorage["popups.expiringPopup"] && type && typeof type === "string" && validPopupType) {
        // Parse local storage data.
        var expiredPopups = JSON.parse(localStorage["popups.expiringPopup"]);

        // Exclude from list by type provided.
        const filteredList = expiredPopups.filter(
            (el) =>
                Object.values(el)[0].type.toLowerCase() !== type.toLowerCase()
        );

        // Update values of local storage.
        if (filteredList.length > 0)
            localStorage["popups.expiringPopup"] = JSON.stringify(filteredList);
        // Remove localStorage key.
        else localStorage.removeItem("popups.expiringPopup");
    }
};

/**
 * Returns filtered popups to show.
 * Pass array of objects to filter from.
 * 
 * @param {array} list = list from db, filters out by Popup "PopupID".
 * @param {array} excludeList = custom list passed, filters out by Popup "Name".
 * @returns
 */

const FilteredPopups = (list, excludeList) => {
    // Fetch local storage dismissed IDs list.
    let ls = [...GetLSPopups()];

    // Declare empty array.
    let filteredPopups = [];

    if (list && list.length) {
        // Filter popups to show.
        // PopupID key is case-sensitive.
        filteredPopups = [...list].filter(
            (p) => !ls.find((lsKey) => lsKey === p["PopupID"])
        );

        // Filter out with excludelist.
        if (excludeList && excludeList.length) {
            filteredPopups = [...filteredPopups].filter(
                (p) => !excludeList.find((exl) => exl.toLowerCase() === p["Name"].toLowerCase())
            );
        }
    }

    return filteredPopups;
};

/**
 * Clear localStorage popups.expiringPopup if a different user is logging in.
 * Pass in user model ParentUserName from server for checking user.
 * Preferably insert code in Layout.cshtml script.
 * 
 * @param {string} userName
 * @returns
 */
const ClearPopupsUser = (userName) => {
    // Exit code if username is same as localStorage["popups.userName"].
    if (!userName
        || (userName !== undefined
            && userName === localStorage["popups.userName"])) return false;

    // If logged in with a different user, remove localStorage for popups.
    if (localStorage["popups.userName"]
        && localStorage["popups.userName"] !== userName) {

        // Replace key in localStorage.
        localStorage["popups.userName"] = userName;

        // Clear popups in localStorage.
        localStorage.removeItem("popups.expiringPopup");
    } else
        // Add key in localStorage if not existing.
        localStorage["popups.userName"] = userName;
};

/**
 * Clear popups by type in database and localStorage.
 * @param {any} event
 */
function PopupsReset(event) {
    // #popupsResetForm must be present DOM.
    if (isThisDomExisting("#popupsResetForm")) {
        // Prevent reload of form.
        event.preventDefault();

        // Store checkbox value into an array.
        let popupTypes = [...$('#popupsResetForm :checked')].map(cbox => cbox.value);

        // Check if valid array.
        if (popupTypes && popupTypes.length) {

            // Clear popups in localstorage.
            popupTypes.map(popup => ClearLSPopupsByType(popup));

            // Clear popups in db by type.
            $.ajax({
                type: "POST",
                url: "/Popup/HandlePopupDeleteAsync/",
                beforeSend: function () {
                    // Show spinner.
                    $('#btnPopupsReset #loaderIndicator').show();
                },
                data: { popupTypes },
                complete: function () {
                    // Hide spinner.
                    $('#btnPopupsReset #loaderIndicator').hide();
                },
                error: (err) => console.log(`ERROR: ${err}`)
            });
        }
    }
};
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Driver=e():t.Driver=e()}(window,function(){return function(t){var e={};function n(o){if(e[o])return e[o].exports;var i=e[o]={i:o,l:!1,exports:{}};return t[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(o,i,function(e){return t[e]}.bind(null,i));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist/",n(n.s=57)}([function(t,e,n){var o=n(2),i=n(11),r=n(4),s=n(13),a=n(22),c=function(t,e,n){var u,l,h,f,p=t&c.F,d=t&c.G,v=t&c.S,y=t&c.P,g=t&c.B,m=d?o:v?o[e]||(o[e]={}):(o[e]||{}).prototype,b=d?i:i[e]||(i[e]={}),w=b.prototype||(b.prototype={});for(u in d&&(n=e),n)h=((l=!p&&m&&void 0!==m[u])?m:n)[u],f=g&&l?a(h,o):y&&"function"==typeof h?a(Function.call,h):h,m&&s(m,u,h,t&c.U),b[u]!=h&&r(b,u,f),y&&w[u]!=h&&(w[u]=h)};o.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,e,n){var o=n(17)("wks"),i=n(14),r=n(2).Symbol,s="function"==typeof r;(t.exports=function(t){return o[t]||(o[t]=s&&r[t]||(s?r:i)("Symbol."+t))}).store=o},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,n){var o=n(5),i=n(16);t.exports=n(6)?function(t,e,n){return o.f(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var o=n(12),i=n(35),r=n(21),s=Object.defineProperty;e.f=n(6)?Object.defineProperty:function(t,e,n){if(o(t),e=r(e,!0),o(n),i)try{return s(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){t.exports=!n(7)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var o=n(39),i=n(24);t.exports=function(t){return o(i(t))}},function(t,e,n){var o=n(0);o(o.S+o.F*!n(6),"Object",{defineProperty:n(5).f})},function(t,e){var n=t.exports={version:"2.6.9"};"number"==typeof __e&&(__e=n)},function(t,e,n){var o=n(3);t.exports=function(t){if(!o(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){var o=n(2),i=n(4),r=n(8),s=n(14)("src"),a=n(59),c=(""+a).split("toString");n(11).inspectSource=function(t){return a.call(t)},(t.exports=function(t,e,n,a){var u="function"==typeof n;u&&(r(n,"name")||i(n,"name",e)),t[e]!==n&&(u&&(r(n,s)||i(n,s,t[e]?""+t[e]:c.join(String(e)))),t===o?t[e]=n:a?t[e]?t[e]=n:i(t,e,n):(delete t[e],i(t,e,n)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[s]||a.call(this)})},function(t,e){var n=0,o=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+o).toString(36))}},function(t,e,n){var o=n(45),i=n(28);t.exports=Object.keys||function(t){return o(t,i)}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var o=n(11),i=n(2),r=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(t.exports=function(t,e){return r[t]||(r[t]=void 0!==e?e:{})})("versions",[]).push({version:o.version,mode:n(18)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(t,e){t.exports=!1},function(t,e,n){var o=n(24);t.exports=function(t){return Object(o(t))}},function(t,e,n){"use strict";var o=n(2),i=n(8),r=n(6),s=n(0),a=n(13),c=n(62).KEY,u=n(7),l=n(17),h=n(26),f=n(14),p=n(1),d=n(43),v=n(44),y=n(63),g=n(42),m=n(12),b=n(3),w=n(19),x=n(9),S=n(21),O=n(16),k=n(30),P=n(67),E=n(49),N=n(47),j=n(5),L=n(15),T=E.f,C=j.f,_=P.f,M=o.Symbol,H=o.JSON,B=H&&H.stringify,F=p("_hidden"),I=p("toPrimitive"),R={}.propertyIsEnumerable,A=l("symbol-registry"),z=l("symbols"),D=l("op-symbols"),V=Object.prototype,W="function"==typeof M&&!!N.f,q=o.QObject,G=!q||!q.prototype||!q.prototype.findChild,K=r&&u(function(){return 7!=k(C({},"a",{get:function(){return C(this,"a",{value:7}).a}})).a})?function(t,e,n){var o=T(V,e);o&&delete V[e],C(t,e,n),o&&t!==V&&C(V,e,o)}:C,U=function(t){var e=z[t]=k(M.prototype);return e._k=t,e},Y=W&&"symbol"==typeof M.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof M},J=function(t,e,n){return t===V&&J(D,e,n),m(t),e=S(e,!0),m(n),i(z,e)?(n.enumerable?(i(t,F)&&t[F][e]&&(t[F][e]=!1),n=k(n,{enumerable:O(0,!1)})):(i(t,F)||C(t,F,O(1,{})),t[F][e]=!0),K(t,e,n)):C(t,e,n)},X=function(t,e){m(t);for(var n,o=y(e=x(e)),i=0,r=o.length;r>i;)J(t,n=o[i++],e[n]);return t},Q=function(t){var e=R.call(this,t=S(t,!0));return!(this===V&&i(z,t)&&!i(D,t))&&(!(e||!i(this,t)||!i(z,t)||i(this,F)&&this[F][t])||e)},$=function(t,e){if(t=x(t),e=S(e,!0),t!==V||!i(z,e)||i(D,e)){var n=T(t,e);return!n||!i(z,e)||i(t,F)&&t[F][e]||(n.enumerable=!0),n}},Z=function(t){for(var e,n=_(x(t)),o=[],r=0;n.length>r;)i(z,e=n[r++])||e==F||e==c||o.push(e);return o},tt=function(t){for(var e,n=t===V,o=_(n?D:x(t)),r=[],s=0;o.length>s;)!i(z,e=o[s++])||n&&!i(V,e)||r.push(z[e]);return r};W||(a((M=function(){if(this instanceof M)throw TypeError("Symbol is not a constructor!");var t=f(arguments.length>0?arguments[0]:void 0),e=function(n){this===V&&e.call(D,n),i(this,F)&&i(this[F],t)&&(this[F][t]=!1),K(this,t,O(1,n))};return r&&G&&K(V,t,{configurable:!0,set:e}),U(t)}).prototype,"toString",function(){return this._k}),E.f=$,j.f=J,n(48).f=P.f=Z,n(29).f=Q,N.f=tt,r&&!n(18)&&a(V,"propertyIsEnumerable",Q,!0),d.f=function(t){return U(p(t))}),s(s.G+s.W+s.F*!W,{Symbol:M});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)p(et[nt++]);for(var ot=L(p.store),it=0;ot.length>it;)v(ot[it++]);s(s.S+s.F*!W,"Symbol",{for:function(t){return i(A,t+="")?A[t]:A[t]=M(t)},keyFor:function(t){if(!Y(t))throw TypeError(t+" is not a symbol!");for(var e in A)if(A[e]===t)return e},useSetter:function(){G=!0},useSimple:function(){G=!1}}),s(s.S+s.F*!W,"Object",{create:function(t,e){return void 0===e?k(t):X(k(t),e)},defineProperty:J,defineProperties:X,getOwnPropertyDescriptor:$,getOwnPropertyNames:Z,getOwnPropertySymbols:tt});var rt=u(function(){N.f(1)});s(s.S+s.F*rt,"Object",{getOwnPropertySymbols:function(t){return N.f(w(t))}}),H&&s(s.S+s.F*(!W||u(function(){var t=M();return"[null]"!=B([t])||"{}"!=B({a:t})||"{}"!=B(Object(t))})),"JSON",{stringify:function(t){for(var e,n,o=[t],i=1;arguments.length>i;)o.push(arguments[i++]);if(n=e=o[1],(b(e)||void 0!==t)&&!Y(t))return g(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!Y(e))return e}),o[1]=e,B.apply(H,o)}}),M.prototype[I]||n(4)(M.prototype,I,M.prototype.valueOf),h(M,"Symbol"),h(Math,"Math",!0),h(o.JSON,"JSON",!0)},function(t,e,n){var o=n(3);t.exports=function(t,e){if(!o(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!o(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!o(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!o(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var o=n(37);t.exports=function(t,e,n){if(o(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,o){return t.call(e,n,o)};case 3:return function(n,o,i){return t.call(e,n,o,i)}}return function(){return t.apply(e,arguments)}}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){t.exports=function(t){if(null==t)throw TypeError("Can't call method on  "+t);return t}},function(t,e,n){"use strict";var o=n(7);t.exports=function(t,e){return!!t&&o(function(){e?t.call(null,function(){},1):t.call(null)})}},function(t,e,n){var o=n(5).f,i=n(8),r=n(1)("toStringTag");t.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,r)&&o(t,r,{configurable:!0,value:e})}},function(t,e,n){var o=n(17)("keys"),i=n(14);t.exports=function(t){return o[t]||(o[t]=i(t))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var o=n(12),i=n(65),r=n(28),s=n(27)("IE_PROTO"),a=function(){},c=function(){var t,e=n(36)("iframe"),o=r.length;for(e.style.display="none",n(66).appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write("<script>document.F=Object<\/script>"),t.close(),c=t.F;o--;)delete c.prototype[r[o]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(a.prototype=o(t),n=new a,a.prototype=null,n[s]=t):n=c(),void 0===e?n:i(n,e)}},function(t,e,n){"use strict";var o=n(68),i=n(69),r=n(32),s=n(9);t.exports=n(70)(Array,"Array",function(t,e){this._t=s(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,i(1)):i(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])},"values"),r.Arguments=r.Array,o("keys"),o("values"),o("entries")},function(t,e){t.exports={}},function(t,e,n){n(44)("asyncIterator")},function(t,e,n){"use strict";var o=n(0),i=n(38)(0),r=n(25)([].forEach,!0);o(o.P+o.F*!r,"Array",{forEach:function(t){return i(this,t,arguments[1])}})},function(t,e,n){t.exports=!n(6)&&!n(7)(function(){return 7!=Object.defineProperty(n(36)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var o=n(3),i=n(2).document,r=o(i)&&o(i.createElement);t.exports=function(t){return r?i.createElement(t):{}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){var o=n(22),i=n(39),r=n(19),s=n(40),a=n(60);t.exports=function(t,e){var n=1==t,c=2==t,u=3==t,l=4==t,h=6==t,f=5==t||h,p=e||a;return function(e,a,d){for(var v,y,g=r(e),m=i(g),b=o(a,d,3),w=s(m.length),x=0,S=n?p(e,w):c?p(e,0):void 0;w>x;x++)if((f||x in m)&&(y=b(v=m[x],x,g),t))if(n)S[x]=y;else if(y)switch(t){case 3:return!0;case 5:return v;case 6:return x;case 2:S.push(v)}else if(l)return!1;return h?-1:u||l?l:S}}},function(t,e,n){var o=n(23);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==o(t)?t.split(""):Object(t)}},function(t,e,n){var o=n(41),i=Math.min;t.exports=function(t){return t>0?i(o(t),9007199254740991):0}},function(t,e){var n=Math.ceil,o=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?o:n)(t)}},function(t,e,n){var o=n(23);t.exports=Array.isArray||function(t){return"Array"==o(t)}},function(t,e,n){e.f=n(1)},function(t,e,n){var o=n(2),i=n(11),r=n(18),s=n(43),a=n(5).f;t.exports=function(t){var e=i.Symbol||(i.Symbol=r?{}:o.Symbol||{});"_"==t.charAt(0)||t in e||a(e,t,{value:s.f(t)})}},function(t,e,n){var o=n(8),i=n(9),r=n(46)(!1),s=n(27)("IE_PROTO");t.exports=function(t,e){var n,a=i(t),c=0,u=[];for(n in a)n!=s&&o(a,n)&&u.push(n);for(;e.length>c;)o(a,n=e[c++])&&(~r(u,n)||u.push(n));return u}},function(t,e,n){var o=n(9),i=n(40),r=n(64);t.exports=function(t){return function(e,n,s){var a,c=o(e),u=i(c.length),l=r(s,u);if(t&&n!=n){for(;u>l;)if((a=c[l++])!=a)return!0}else for(;u>l;l++)if((t||l in c)&&c[l]===n)return t||l||0;return!t&&-1}}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var o=n(45),i=n(28).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return o(t,i)}},function(t,e,n){var o=n(29),i=n(16),r=n(9),s=n(21),a=n(8),c=n(35),u=Object.getOwnPropertyDescriptor;e.f=n(6)?u:function(t,e){if(t=r(t),e=s(e,!0),c)try{return u(t,e)}catch(t){}if(a(t,e))return i(!o.f.call(t,e),t[e])}},function(t,e,n){for(var o=n(31),i=n(15),r=n(13),s=n(2),a=n(4),c=n(32),u=n(1),l=u("iterator"),h=u("toStringTag"),f=c.Array,p={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},d=i(p),v=0;v<d.length;v++){var y,g=d[v],m=p[g],b=s[g],w=b&&b.prototype;if(w&&(w[l]||a(w,l,f),w[h]||a(w,h,g),c[g]=f,m))for(y in o)w[y]||r(w,y,o[y],!0)}},function(t,e,n){"use strict";var o=n(73),i={};i[n(1)("toStringTag")]="z",i+""!="[object z]"&&n(13)(Object.prototype,"toString",function(){return"[object "+o(this)+"]"},!0)},function(t,e,n){var o=n(19),i=n(15);n(74)("keys",function(){return function(t){return i(o(t))}})},function(t,e,n){"use strict";var o=n(0),i=n(38)(2);o(o.P+o.F*!n(25)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,e,n){var o=n(0);o(o.P,"Function",{bind:n(75)})},function(t,e,n){var o=n(0);o(o.S,"Object",{create:n(30)})},function(t,e,n){var o=n(0);o(o.S,"Object",{setPrototypeOf:n(81).set})},function(t,e,n){n(58),t.exports=n(82)},function(t,e){},function(t,e,n){t.exports=n(17)("native-function-to-string",Function.toString)},function(t,e,n){var o=n(61);t.exports=function(t,e){return new(o(t))(e)}},function(t,e,n){var o=n(3),i=n(42),r=n(1)("species");t.exports=function(t){var e;return i(t)&&("function"!=typeof(e=t.constructor)||e!==Array&&!i(e.prototype)||(e=void 0),o(e)&&null===(e=e[r])&&(e=void 0)),void 0===e?Array:e}},function(t,e,n){var o=n(14)("meta"),i=n(3),r=n(8),s=n(5).f,a=0,c=Object.isExtensible||function(){return!0},u=!n(7)(function(){return c(Object.preventExtensions({}))}),l=function(t){s(t,o,{value:{i:"O"+ ++a,w:{}}})},h=t.exports={KEY:o,NEED:!1,fastKey:function(t,e){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!r(t,o)){if(!c(t))return"F";if(!e)return"E";l(t)}return t[o].i},getWeak:function(t,e){if(!r(t,o)){if(!c(t))return!0;if(!e)return!1;l(t)}return t[o].w},onFreeze:function(t){return u&&h.NEED&&c(t)&&!r(t,o)&&l(t),t}}},function(t,e,n){var o=n(15),i=n(47),r=n(29);t.exports=function(t){var e=o(t),n=i.f;if(n)for(var s,a=n(t),c=r.f,u=0;a.length>u;)c.call(t,s=a[u++])&&e.push(s);return e}},function(t,e,n){var o=n(41),i=Math.max,r=Math.min;t.exports=function(t,e){return(t=o(t))<0?i(t+e,0):r(t,e)}},function(t,e,n){var o=n(5),i=n(12),r=n(15);t.exports=n(6)?Object.defineProperties:function(t,e){i(t);for(var n,s=r(e),a=s.length,c=0;a>c;)o.f(t,n=s[c++],e[n]);return t}},function(t,e,n){var o=n(2).document;t.exports=o&&o.documentElement},function(t,e,n){var o=n(9),i=n(48).f,r={}.toString,s="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return s&&"[object Window]"==r.call(t)?function(t){try{return i(t)}catch(t){return s.slice()}}(t):i(o(t))}},function(t,e,n){var o=n(1)("unscopables"),i=Array.prototype;null==i[o]&&n(4)(i,o,{}),t.exports=function(t){i[o][t]=!0}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){"use strict";var o=n(18),i=n(0),r=n(13),s=n(4),a=n(32),c=n(71),u=n(26),l=n(72),h=n(1)("iterator"),f=!([].keys&&"next"in[].keys()),p=function(){return this};t.exports=function(t,e,n,d,v,y,g){c(n,e,d);var m,b,w,x=function(t){if(!f&&t in P)return P[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",O="values"==v,k=!1,P=t.prototype,E=P[h]||P["@@iterator"]||v&&P[v],N=E||x(v),j=v?O?x("entries"):N:void 0,L="Array"==e&&P.entries||E;if(L&&(w=l(L.call(new t)))!==Object.prototype&&w.next&&(u(w,S,!0),o||"function"==typeof w[h]||s(w,h,p)),O&&E&&"values"!==E.name&&(k=!0,N=function(){return E.call(this)}),o&&!g||!f&&!k&&P[h]||s(P,h,N),a[e]=N,a[S]=p,v)if(m={values:O?N:x("values"),keys:y?N:x("keys"),entries:j},g)for(b in m)b in P||r(P,b,m[b]);else i(i.P+i.F*(f||k),e,m);return m}},function(t,e,n){"use strict";var o=n(30),i=n(16),r=n(26),s={};n(4)(s,n(1)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=o(s,{next:i(1,n)}),r(t,e+" Iterator")}},function(t,e,n){var o=n(8),i=n(19),r=n(27)("IE_PROTO"),s=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),o(t,r)?t[r]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?s:null}},function(t,e,n){var o=n(23),i=n(1)("toStringTag"),r="Arguments"==o(function(){return arguments}());t.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Object(t),i))?n:r?o(e):"Object"==(s=o(e))&&"function"==typeof e.callee?"Arguments":s}},function(t,e,n){var o=n(0),i=n(11),r=n(7);t.exports=function(t,e){var n=(i.Object||{})[t]||Object[t],s={};s[t]=e(n),o(o.S+o.F*r(function(){n(1)}),"Object",s)}},function(t,e,n){"use strict";var o=n(37),i=n(3),r=n(76),s=[].slice,a={};t.exports=Function.bind||function(t){var e=o(this),n=s.call(arguments,1),c=function(){var o=n.concat(s.call(arguments));return this instanceof c?function(t,e,n){if(!(e in a)){for(var o=[],i=0;i<e;i++)o[i]="a["+i+"]";a[e]=Function("F,a","return new F("+o.join(",")+")")}return a[e](t,n)}(e,o.length,o):r(e,o,t)};return i(e.prototype)&&(c.prototype=e.prototype),c}},function(t,e){t.exports=function(t,e,n){var o=void 0===n;switch(e.length){case 0:return o?t():t.call(n);case 1:return o?t(e[0]):t.call(n,e[0]);case 2:return o?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return o?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return o?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},function(t,e,n){"use strict";n(78)("trim",function(t){return function(){return t(this,3)}})},function(t,e,n){var o=n(0),i=n(24),r=n(7),s=n(79),a="["+s+"]",c=RegExp("^"+a+a+"*"),u=RegExp(a+a+"*$"),l=function(t,e,n){var i={},a=r(function(){return!!s[t]()||"​"!="​"[t]()}),c=i[t]=a?e(h):s[t];n&&(i[n]=c),o(o.P+o.F*a,"String",i)},h=l.trim=function(t,e){return t=String(i(t)),1&e&&(t=t.replace(c,"")),2&e&&(t=t.replace(u,"")),t};t.exports=l},function(t,e){t.exports="\t\n\v\f\r   ᠎             　\u2028\u2029\ufeff"},function(t,e,n){"use strict";var o=n(0),i=n(46)(!1),r=[].indexOf,s=!!r&&1/[1].indexOf(1,-0)<0;o(o.P+o.F*(s||!n(25)(r)),"Array",{indexOf:function(t){return s?r.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,e,n){var o=n(3),i=n(12),r=function(t,e){if(i(t),!o(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,o){try{(o=n(22)(Function.call,n(49).f(Object.prototype,"__proto__").set,2))(t,[]),e=!(t instanceof Array)}catch(t){e=!0}return function(t,n){return r(t,n),e?t.__proto__=n:o(t,n),t}}({},!1):void 0),check:r}},function(t,e,n){"use strict";n.r(e);n(34),n(20),n(50),n(31),n(51),n(52),n(10),n(53),n(54);var o=.75,i=10,r=!0,s=!0,a=!0,c=!1,u="driver-highlighted-element-stage",l='<div id="'.concat("driver-page-overlay",'"></div>'),h='<div id="'.concat(u,'"></div>');n(33),n(77);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var p=function(t){var e=document.createElement("div");return e.innerHTML=t.trim(),e.firstChild},d=function t(e,n){if(arguments.length>2&&void 0!==arguments[2]&&arguments[2]){for(var o=["","-webkit-","-ms-","moz-","-o-"],i=0;i<o.length;i++){var r=t(e,o[i]+n);if(r)return r}return""}var s="";return e.currentStyle?s=e.currentStyle[n]:document.defaultView&&document.defaultView.getComputedStyle&&(s=document.defaultView.getComputedStyle(e,null).getPropertyValue(n)),s&&s.toLowerCase?s.toLowerCase():s},v=function(t){return t&&"object"===f(t)&&"nodeType"in t};function y(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}var g=function(){function t(e,n,o){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.options=e,this.highlightedElement=null,this.lastHighlightedElement=null,this.hideTimer=null,this.window=n,this.document=o,this.removeNode=this.removeNode.bind(this)}var e,n,o;return e=t,(n=[{key:"attachNode",value:function(){var t=this.document.getElementById("driver-page-overlay");t||(t=p(l),document.body.appendChild(t)),this.node=t,this.node.style.opacity="0",this.options.animate||this.node.parentElement&&this.node.parentElement.removeChild(this.node)}},{key:"highlight",value:function(t){t&&t.node?t.isSame(this.highlightedElement)||(this.window.clearTimeout(this.hideTimer),t.onHighlightStarted(),this.highlightedElement&&!this.highlightedElement.isSame(this.lastHighlightedElement)&&this.highlightedElement.onDeselected(),t.getCalculatedPosition().canHighlight()&&(this.lastHighlightedElement=this.highlightedElement,this.highlightedElement=t,this.show(),this.highlightedElement.onHighlighted())):console.warn("Invalid element to highlight. Must be an instance of `Element`")}},{key:"show",value:function(){var t=this;this.node&&this.node.parentElement||(this.attachNode(),window.setTimeout(function(){t.node.style.opacity="".concat(t.options.opacity),t.node.style.position="fixed",t.node.style.left="0",t.node.style.top="0",t.node.style.bottom="0",t.node.style.right="0"}))}},{key:"getHighlightedElement",value:function(){return this.highlightedElement}},{key:"getLastHighlightedElement",value:function(){return this.lastHighlightedElement}},{key:"clear",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.options.onReset&&this.options.onReset(this.highlightedElement),this.highlightedElement){this.highlightedElement.onDeselected(!0)}this.highlightedElement=null,this.lastHighlightedElement=null,this.node&&(this.window.clearTimeout(this.hideTimer),this.options.animate&&!t?(this.node.style.opacity="0",this.hideTimer=this.window.setTimeout(this.removeNode,300)):this.removeNode())}},{key:"removeNode",value:function(){this.node&&this.node.parentElement&&this.node.parentElement.removeChild(this.node)}},{key:"refresh",value:function(){this.highlightedElement&&(this.highlightedElement.showPopover(),this.highlightedElement.showStage())}}])&&y(e.prototype,n),o&&y(e,o),t}();n(80);function m(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}var b=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.left,o=void 0===n?0:n,i=e.top,r=void 0===i?0:i,s=e.right,a=void 0===s?0:s,c=e.bottom,u=void 0===c?0:c;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.left=o,this.right=a,this.top=r,this.bottom=u}var e,n,o;return e=t,(n=[{key:"canHighlight",value:function(){return this.left<this.right&&this.top<this.bottom}}])&&m(e.prototype,n),o&&m(e,o),t}();function w(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}var x=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.node,o=e.options,i=e.popover,r=e.stage,s=e.overlay,a=e.window,c=e.document;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.node=n,this.document=c,this.window=a,this.options=o,this.overlay=s,this.popover=i,this.stage=r,this.animationTimeout=null}var e,n,o;return e=t,(n=[{key:"isInView",value:function(){for(var t=this.node.offsetTop,e=this.node.offsetLeft,n=this.node.offsetWidth,o=this.node.offsetHeight,i=this.node;i.offsetParent;)t+=(i=i.offsetParent).offsetTop,e+=i.offsetLeft;return t>=this.window.pageYOffset&&e>=this.window.pageXOffset&&t+o<=this.window.pageYOffset+this.window.innerHeight&&e+n<=this.window.pageXOffset+this.window.innerWidth}},{key:"scrollManually",value:function(){var t=this.node.getBoundingClientRect().top+this.window.pageYOffset-this.window.innerHeight/2;this.window.scrollTo(0,t)}},{key:"bringInView",value:function(){if(this.node&&!this.isInView())if(this.node.scrollIntoView)try{this.node.scrollIntoView(this.options.scrollIntoViewOptions||{behavior:"instant",block:"center"})}catch(t){this.scrollManually()}else this.scrollManually()}},{key:"getCalculatedPosition",value:function(){var t=this.document.body,e=this.document.documentElement,n=this.window,o=this.window.pageYOffset||e.scrollTop||t.scrollTop,i=n.pageXOffset||e.scrollLeft||t.scrollLeft,r=this.node.getBoundingClientRect();return new b({top:r.top+o,left:r.left+i,right:r.left+i+r.width,bottom:r.top+o+r.height})}},{key:"getPopover",value:function(){return this.popover}},{key:"onDeselected",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.hidePopover(),t&&this.hideStage(),this.removeHighlightClasses(),this.window.clearTimeout(this.animationTimeout),this.options.onDeselected&&this.options.onDeselected(this)}},{key:"isSame",value:function(t){return!(!t||!t.node)&&t.node===this.node}},{key:"onHighlightStarted",value:function(){this.options.onHighlightStarted&&this.options.onHighlightStarted(this)}},{key:"onHighlighted",value:function(){this.isInView()||this.bringInView(),this.showPopover(),this.showStage(),this.addHighlightClasses(),this.options.onHighlighted&&this.options.onHighlighted(this)}},{key:"removeHighlightClasses",value:function(){this.node.classList.remove("driver-highlighted-element"),this.node.classList.remove("driver-position-relative");for(var t=this.document.querySelectorAll(".".concat("driver-fix-stacking")),e=0;e<t.length;e++)t[e].classList.remove("driver-fix-stacking")}},{key:"addHighlightClasses",value:function(){this.node.classList.add("driver-highlighted-element"),this.canMakeRelative()&&this.node.classList.add("driver-position-relative"),this.fixStackingContext()}},{key:"fixStackingContext",value:function(){for(var t=this.node.parentNode;t&&t.tagName&&"body"!==t.tagName.toLowerCase();){var e=d(t,"z-index"),n=parseFloat(d(t,"opacity")),o=d(t,"transform",!0),i=d(t,"transform-style",!0),r=d(t,"transform-box",!0),s=d(t,"filter",!0),a=d(t,"perspective",!0);(/[0-9]+/.test(e)||n<1||o&&"none"!==o||i&&"flat"!==i||r&&"border-box"!==r||s&&"none"!==s||a&&"none"!==a)&&t.classList.add("driver-fix-stacking"),t=t.parentNode}}},{key:"canMakeRelative",value:function(){var t=this.getStyleProperty("position");return-1===["absolute","fixed","relative"].indexOf(t)}},{key:"getStyleProperty",value:function(t){return d(this.node,t)}},{key:"showStage",value:function(){this.stage.show(this.getCalculatedPosition())}},{key:"getNode",value:function(){return this.node}},{key:"hideStage",value:function(){this.stage.hide()}},{key:"hidePopover",value:function(){this.popover&&this.popover.hide()}},{key:"showPopover",value:function(){var t=this;if(this.popover){var e=this.getCalculatedPosition(),n=300;this.options.animate&&this.overlay.lastHighlightedElement||(n=0),this.animationTimeout=this.window.setTimeout(function(){t.popover.show(e)},n)}}},{key:"getFullPageSize",value:function(){var t=this.document.body,e=this.document.documentElement;return{height:Math.max(t.scrollHeight,t.offsetHeight,e.scrollHeight,e.offsetHeight),width:Math.max(t.scrollWidth,t.offsetWidth,e.scrollWidth,e.offsetWidth)}}},{key:"getSize",value:function(){return{height:Math.max(this.node.scrollHeight,this.node.offsetHeight),width:Math.max(this.node.scrollWidth,this.node.offsetWidth)}}}])&&w(e.prototype,n),o&&w(e,o),t}();n(55),n(56);function S(t){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function O(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function k(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function P(t,e){return!e||"object"!==S(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function E(t){return(E=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function N(t,e){return(N=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}var j=function(t){function e(t,n,o){var i;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),(i=P(this,E(e).call(this))).options=function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),o.forEach(function(e){O(t,e,n[e])})}return t}({isFirst:!0,isLast:!0,totalCount:1,currentIndex:0,offset:0,showButtons:!0,closeBtnText:"Close",doneBtnText:"Done",startBtnText:"Next &rarr;",nextBtnText:"Next &rarr;",prevBtnText:"&larr; Previous"},t),i.window=n,i.document=o,i}var n,o,i;return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&N(t,e)}(e,x),n=e,(o=[{key:"attachNode",value:function(){var t=this.document.getElementById("driver-popover-item");t&&t.parentElement.removeChild(t),t=p(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return'\n  <div id="'.concat("driver-popover-item",'" class="').concat(t,'">\n    <div class="').concat("driver-popover-tip",'"></div>\n    <div class="').concat("driver-popover-title",'">Popover Title</div>\n    <div class="').concat("driver-popover-description",'">Popover Description</div>\n    <div class="driver-clearfix ').concat("driver-popover-footer",'">\n      <button class="').concat("driver-close-btn",'">Close</button>\n      <span class="driver-btn-group ').concat("driver-navigation-btns",'">\n        <button class="').concat("driver-prev-btn",'">&larr; Previous</button>\n        <button class="').concat("driver-next-btn",'">Next &rarr;</button>\n      </span>\n    </div>\n  </div>')}(this.options.className)),document.body.appendChild(t),this.node=t,this.tipNode=t.querySelector(".".concat("driver-popover-tip")),this.titleNode=t.querySelector(".".concat("driver-popover-title")),this.descriptionNode=t.querySelector(".".concat("driver-popover-description")),this.footerNode=t.querySelector(".".concat("driver-popover-footer")),this.nextBtnNode=t.querySelector(".".concat("driver-next-btn")),this.prevBtnNode=t.querySelector(".".concat("driver-prev-btn")),this.closeBtnNode=t.querySelector(".".concat("driver-close-btn"))}},{key:"getTitleNode",value:function(){return this.titleNode}},{key:"getDescriptionNode",value:function(){return this.descriptionNode}},{key:"hide",value:function(){this.node&&(this.node.style.display="none")}},{key:"setInitialState",value:function(){this.node.style.display="block",this.node.style.left="0",this.node.style.top="0",this.node.style.bottom="",this.node.style.right="",this.node.querySelector(".".concat("driver-popover-tip")).className="driver-popover-tip"}},{key:"show",value:function(t){switch(this.attachNode(),this.setInitialState(),this.titleNode.innerHTML=this.options.title,this.descriptionNode.innerHTML=this.options.description||"",this.renderFooter(),this.options.position){case"left":case"left-top":this.positionOnLeft(t);break;case"left-center":this.positionOnLeftCenter(t);break;case"left-bottom":this.positionOnLeftBottom(t);break;case"right":case"right-top":this.positionOnRight(t);break;case"right-center":this.positionOnRightCenter(t);break;case"right-bottom":this.positionOnRightBottom(t);break;case"top":case"top-left":this.positionOnTop(t);break;case"top-center":this.positionOnTopCenter(t);break;case"top-right":this.positionOnTopRight(t);break;case"bottom":case"bottom-left":this.positionOnBottom(t);break;case"bottom-center":this.positionOnBottomCenter(t);break;case"bottom-right":this.positionOnBottomRight(t);break;case"mid-center":this.positionOnMidCenter(t);break;case"auto":default:this.autoPosition(t)}this.bringInView()}},{key:"renderFooter",value:function(){this.nextBtnNode.innerHTML=this.options.nextBtnText,this.prevBtnNode.innerHTML=this.options.prevBtnText,this.closeBtnNode.innerHTML=this.options.closeBtnText;var t=this.options.totalCount&&1!==this.options.totalCount;this.options.showButtons?(t?(this.nextBtnNode.style.display="inline-block",this.prevBtnNode.style.display="inline-block",this.closeBtnNode.classList.remove("driver-close-only-btn")):(this.nextBtnNode.style.display="none",this.prevBtnNode.style.display="none",this.closeBtnNode.classList.add("driver-close-only-btn")),this.footerNode.style.display="block",this.options.isFirst?(this.prevBtnNode.classList.add("driver-disabled"),this.nextBtnNode.innerHTML=this.options.startBtnText):this.prevBtnNode.classList.remove("driver-disabled"),this.options.isLast?this.nextBtnNode.innerHTML=this.options.doneBtnText:this.nextBtnNode.innerHTML=this.options.nextBtnText):this.footerNode.style.display="none"}},{key:"positionOnLeft",value:function(t){var e=this.getSize().width,n=this.options.padding+10;this.node.style.left="".concat(t.left-e-n,"px"),this.node.style.top="".concat(t.top+this.options.offset-this.options.padding,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("right")}},{key:"positionOnLeftBottom",value:function(t){var e=this.getSize(),n=e.width,o=this.options.padding+10;this.node.style.left="".concat(t.left-n-o,"px"),this.node.style.top="".concat(t.bottom+this.options.padding+this.options.offset-e.height,"px"),this.node.style.bottom="",this.node.style.right="",this.tipNode.classList.add("right","position-bottom")}},{key:"positionOnLeftCenter",value:function(t){var e=this.getSize(),n=e.width,o=e.height/2,i=this.options.padding+10,r=(t.bottom-t.top)/2,s=t.top-o+r+this.options.offset;this.node.style.left="".concat(t.left-n-i,"px"),this.node.style.top="".concat(s,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("right","position-center")}},{key:"positionOnRight",value:function(t){var e=this.options.padding+10;this.node.style.left="".concat(t.right+e,"px"),this.node.style.top="".concat(t.top+this.options.offset-this.options.padding,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("left")}},{key:"positionOnRightCenter",value:function(t){var e=this.getSize(),n=this.options.padding+10,o=e.height/2,i=(t.bottom-t.top)/2,r=t.top-o+i+this.options.offset;this.node.style.left="".concat(t.right+n,"px"),this.node.style.top="".concat(r,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("left","position-center")}},{key:"positionOnRightBottom",value:function(t){var e=this.options.padding+10,n=this.getSize();this.node.style.left="".concat(t.right+e,"px"),this.node.style.top="".concat(t.bottom+this.options.padding+this.options.offset-n.height,"px"),this.node.style.bottom="",this.node.style.right="",this.tipNode.classList.add("left","position-bottom")}},{key:"positionOnTop",value:function(t){var e=this.getSize().height,n=this.options.padding+10;this.node.style.top="".concat(t.top-e-n,"px"),this.node.style.left="".concat(t.left-this.options.padding+this.options.offset,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("bottom")}},{key:"positionOnTopCenter",value:function(t){var e=this.getSize(),n=e.height,o=e.width/2,i=this.options.padding+10,r=this.options.offset+t.left+(t.right-t.left)/2;this.node.style.top="".concat(t.top-n-i,"px"),this.node.style.left="".concat(r-o-this.options.padding,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("bottom","position-center")}},{key:"positionOnTopRight",value:function(t){var e=this.getSize(),n=e.height,o=this.options.padding+10;this.node.style.top="".concat(t.top-n-o,"px"),this.node.style.left="".concat(t.right+this.options.padding+this.options.offset-e.width,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("bottom","position-right")}},{key:"positionOnBottom",value:function(t){var e=this.options.padding+10;this.node.style.top="".concat(t.bottom+e,"px"),this.node.style.left="".concat(t.left-this.options.padding+this.options.offset,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("top")}},{key:"positionOnBottomCenter",value:function(t){var e=this.getSize().width/2,n=this.options.padding+10,o=this.options.offset+t.left+(t.right-t.left)/2;this.node.style.top="".concat(t.bottom+n,"px"),this.node.style.left="".concat(o-e-this.options.padding,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("top","position-center")}},{key:"positionOnBottomRight",value:function(t){var e=this.getSize(),n=this.options.padding+10;this.node.style.top="".concat(t.bottom+n,"px"),this.node.style.left="".concat(t.right+this.options.padding+this.options.offset-e.width,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("top","position-right")}},{key:"positionOnMidCenter",value:function(t){var e=this.getSize(),n=e.height,o=e.width/2,i=n/2,r=(t.bottom-t.top)/2,s=t.top-i+r+this.options.offset,a=this.options.offset+t.left+(t.right-t.left)/2;this.node.style.top="".concat(s,"px"),this.node.style.left="".concat(a-o-this.options.padding,"px"),this.node.style.right="",this.node.style.bottom="",this.tipNode.classList.add("mid-center")}},{key:"autoPosition",value:function(t){var e=this.getFullPageSize(),n=this.getSize(),o=e.height,i=n.height,r=this.options.padding+10;t.bottom+i+r>=o?this.positionOnTop(t):this.positionOnBottom(t)}}])&&k(n.prototype,o),i&&k(n,i),e}();function L(t){return(L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function T(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function C(t,e){return!e||"object"!==L(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function _(t){return(_=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function M(t,e){return(M=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}var H=function(t){function e(t,n,o){var i;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),(i=C(this,_(e).call(this))).options=t,i.window=n,i.document=o,i}var n,o,i;return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&M(t,e)}(e,x),n=e,(o=[{key:"attachNode",value:function(){var t=this.document.getElementById(u);t||(t=p(h),document.body.appendChild(t)),this.node=t,this.options.animate?this.node.classList.remove("driver-stage-no-animation"):this.node.classList.add("driver-stage-no-animation")}},{key:"hide",value:function(){this.node&&this.node.parentElement&&this.node.parentElement.removeChild(this.node)}},{key:"setInitialStyle",value:function(){this.node.style.display="block",this.node.style.left="0",this.node.style.top="0",this.node.style.bottom="",this.node.style.right=""}},{key:"show",value:function(t){this.attachNode(),this.setInitialStyle();var e=2*this.options.padding,n=t.right-t.left+e,o=t.bottom-t.top+e;this.node.style.display="block",this.node.style.position="absolute",this.node.style.width="".concat(n,"px"),this.node.style.height="".concat(o,"px"),this.node.style.top="".concat(t.top-e/2,"px"),this.node.style.left="".concat(t.left-e/2,"px"),this.node.style.backgroundColor=this.options.stageBackground}}])&&T(n.prototype,o),i&&T(n,i),e}();function B(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter(function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable}))),o.forEach(function(e){F(t,e,n[e])})}return t}function F(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function I(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}n.d(e,"default",function(){return R});var R=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.options=B({animate:r,opacity:o,padding:i,scrollIntoViewOptions:null,allowClose:s,keyboardControl:a,overlayClickNext:c,stageBackground:"#ffffff",onHighlightStarted:function(){return null},onHighlighted:function(){return null},onDeselected:function(){return null},onReset:function(){return null},onNext:function(){return null},onPrevious:function(){return null}},e),this.document=document,this.window=window,this.isActivated=!1,this.steps=[],this.currentStep=0,this.currentMovePrevented=!1,this.overlay=new g(this.options,window,document),this.onResize=this.onResize.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onClick=this.onClick.bind(this),this.moveNext=this.moveNext.bind(this),this.movePrevious=this.movePrevious.bind(this),this.preventMove=this.preventMove.bind(this),this.bind()}var e,n,u;return e=t,(n=[{key:"getSteps",value:function(){return this.steps}},{key:"setSteps",value:function(t){this.steps=t}},{key:"bind",value:function(){this.window.addEventListener("resize",this.onResize,!1),this.window.addEventListener("keyup",this.onKeyUp,!1),"ontouchstart"in document.documentElement?this.window.addEventListener("touchstart",this.onClick,!1):this.window.addEventListener("click",this.onClick,!1)}},{key:"onClick",value:function(t){if(this.isActivated&&this.hasHighlightedElement()){t.stopPropagation();var e=this.overlay.getHighlightedElement(),n=this.document.getElementById("driver-popover-item"),o=e.node.contains(t.target),i=n&&n.contains(t.target);if(o||i||!this.options.overlayClickNext)if(o||i||!this.options.allowClose){var r=t.target.classList.contains("driver-next-btn"),s=t.target.classList.contains("driver-prev-btn");t.target.classList.contains("driver-close-btn")?this.reset():r?this.handleNext():s&&this.handlePrevious()}else this.reset();else this.handleNext()}}},{key:"onResize",value:function(){this.isActivated&&this.refresh()}},{key:"refresh",value:function(){this.overlay.refresh()}},{key:"onKeyUp",value:function(t){if(this.isActivated&&this.options.keyboardControl)if(27!==t.keyCode){var e=this.getHighlightedElement();e&&e.popover&&(39===t.keyCode?this.handleNext():37===t.keyCode&&this.handlePrevious())}else this.reset()}},{key:"movePrevious",value:function(){var t=this.steps[this.currentStep-1];t?(this.overlay.highlight(t),this.currentStep-=1):this.reset()}},{key:"preventMove",value:function(){this.currentMovePrevented=!0}},{key:"handleNext",value:function(){this.currentMovePrevented=!1;var t=this.steps[this.currentStep];t&&t.options&&t.options.onNext&&t.options.onNext(this.overlay.highlightedElement),this.currentMovePrevented||this.moveNext()}},{key:"handlePrevious",value:function(){this.currentMovePrevented=!1;var t=this.steps[this.currentStep];t&&t.options&&t.options.onPrevious&&t.options.onPrevious(this.overlay.highlightedElement),this.currentMovePrevented||this.movePrevious()}},{key:"moveNext",value:function(){var t=this.steps[this.currentStep+1];t?(this.overlay.highlight(t),this.currentStep+=1):this.reset()}},{key:"hasNextStep",value:function(){return!!this.steps[this.currentStep+1]}},{key:"hasPreviousStep",value:function(){return!!this.steps[this.currentStep-1]}},{key:"reset",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.currentStep=0,this.isActivated=!1,this.overlay.clear(t)}},{key:"hasHighlightedElement",value:function(){var t=this.overlay.getHighlightedElement();return t&&t.node}},{key:"getHighlightedElement",value:function(){return this.overlay.getHighlightedElement()}},{key:"getLastHighlightedElement",value:function(){return this.overlay.getLastHighlightedElement()}},{key:"defineSteps",value:function(t){this.steps=[];for(var e=0;e<t.length;e++){var n=this.prepareElementFromStep(t[e],t,e);n&&this.steps.push(n)}}},{key:"prepareElementFromStep",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=B({},this.options),i=t,r="string"!=typeof t&&!v(t);if(!t||r&&!t.element)throw new Error("Element is required in step ".concat(n));r&&(i=t.element,o=B({},this.options,t));var s=v(i)?i:this.document.querySelector(i);if(!s)return console.warn("Element to highlight ".concat(i," not found")),null;var a=null;if(o.popover&&o.popover.title){var c=[this.options.className,o.popover.className].filter(function(t){return t}).join(" "),u=B({},o,o.popover,{className:c,totalCount:e.length,currentIndex:n,isFirst:0===n,isLast:0===e.length||n===e.length-1});a=new j(u,this.window,this.document)}var l=B({},o),h=new H(l,this.window,this.document);return new x({node:s,options:o,popover:a,stage:h,overlay:this.overlay,window:this.window,document:this.document})}},{key:"start",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;if(!this.steps||0===this.steps.length)throw new Error("There are no steps defined to iterate");this.isActivated=!0,this.currentStep=t,this.overlay.highlight(this.steps[t])}},{key:"highlight",value:function(t){this.isActivated=!0;var e=this.prepareElementFromStep(t);e&&this.overlay.highlight(e)}}])&&I(e.prototype,n),u&&I(e,u),t}()}]).default});
//# sourceMappingURL=driver.min.js.map;
