{"version":3,"file":"host.es5.min.js","names":["GEC","gec","loginFrame","GBEUtils","com","globalbettingexchange","base","weHaveAlreadyJumpedMainContentDivToLeft","openToteboardPopups","isContestAccount","GAP_BETWEEN_ELEMENTS","$","window","load","click","contentWindow","call","html","frames","toteboardTemplatesFrame","document","getElementById","innerHTML","initGoogleAnalytics","deleteSessionCookieUsedByClassicSite","serverData","promosAPIEnable","isNoDeepLinkInURL","isNewStyleContestAccount","sessionStorage","sessionToken","modules","renderPromoCarousel","promosAPIURL","promosAPICachePeriodInSeconds","initHeaderAndFooter","centreAndDisplayMainPanel","populateHeaderAndFooterFromAPI","location","pathname","applicationPath","windowWidth","width","mainPanelWidth","leftPos","css","concat","showPromoCarousel","show","hidePromoCarousel","hide","isPromoCarouselVisible","is","menuDataFallback","menuAPIURL","indexOf","menuDataFallback_Test","menuDataFallback_Prod","menuData","nowTimestamp","Date","getTime","Number","menuDataTimestamp","menuAPICachePeriodInSeconds","console","log","JSON","parse","renderHeaderAndFooterMenus","timeout","setTimeout","get","dataFromAPI","fail","xhr","status","error","always","stringify","clearTimeout","menuDataToRender","renderTopMenu","ex","renderFooterMenu","setTopMenuCurrentlySelectedMenuLabel","currentlySelectedMenuLabel","getAboutContestUrlFromMenuData","aboutContestsUrl","filter","menu","api_slug","forEach","items","item","value","key","link","deleteUserSpecificCookiesSharedWithMarketingSite","googleAnalyticsEnable","i","s","o","g","r","a","m","q","push","arguments","l","createElement","getElementsByTagName","async","src","parentNode","insertBefore","ga","googleAnalyticsTrackingId","setIsContestAccount","isContest","getIsContestAccount","allowDraggingOfMainSiteContent","draggable","containment","axis","cursor","iframeFix","ready","mouseenter","children","addClass","mouseleave","removeClass","onTimingOut","undefined","callGEPFunction","functionName","param1","param2","param3","param4","param5","param6","param7","routeChangeFunction","route","app_router","navigate","switchSiteLogoToContestLogo","entryName","text","notifyContestUserLoggedIn","changeFragmentIdFunction","trigger","replace","sameSiteValueForCookies","setSameSiteNoneOnCookies","deleteCookie","createSessionCookieUsedByClassicSite","setCookie","unescape","getSession","goToClassicSite","href","classicSiteUrl","contestSession","determineWhetherToShowPromoCarousel","renderLoggedInPromoCarousel","loggedInFunction","getGEC","session","ignore","warn","getUserContext","cohort","wageringCohort","protectedPageExample","loggedOutFunction","userInitiated","contestEntryName","reload","setFooterHeight","height","contents","find","prop","loginPanelAndGEPLoaded","activateFunction","maskHeader","promoCarouselHeight","unmaskHeader","isSiteInIframe","self","top","e","showPushReconnectingMessage","showPushConnectionReestablishedMessage","toteboardPopups","popupArray","POPUP_HEADER_HEIGHT","popupPreferredWidth","popupPreferredHeight","init","maxNumberOfOpenPopups","length","popup","position","addPopupToArray","popupToAdd","each","index","getPositionOfPopup","removePopupFromArray","popupToRemove","getCount","countNonUndefinedPopups","total","element","reduce","offset","left","updatePopupPositions","sortPopupArrayFromTopToBottomOfDocument","popupsToSort","sort","b","getPopupPositions","map","getPreferredPositionToUse","preferredPositions","preferredPositionToUse","getPopupFurthestDownThePage","cloneOfPopupArray","slice","getDefaultPopupPosition","popupWidth","popupHeight","widthOfMainDiv","xPosOfRightEdgeOfMainDiv","yPosOfTopEdgeOfMainDiv","documentWidth","documentHeight","my","at","of","collision","lastPopup","topOfLastPopup","heightOfLastPopup","bottomOfLastPopup","getNextToteboardPopupPosition","hidePopups","closest","showPopups","makeSurePopupsAreInView","rightEdgeOfPopup","jumpMainContentDivToLeft","openPopup","params","defaultWidth","minWidth","maxWidth","defaultHeight","minHeight","maxHeight","generateToteboardContent","onCloseToteboardPopup","remove","newToteboardPopup","dialog","title","resizable","closeOnEscape","open","event","target","dragStop","ui","resizeStop","size","close","scrollToBottomOfDocument","animate","scrollTop","resize","removeQueryStringFromURL","url","split","history","replaceState","displayCountdownTime","$element","currentValue","doCountdown","countdownTime","countdownInterval","setInterval","clearInterval","displayWaitCountdown","waitTimeInSeconds","messageText","pleaseWaitDialog","modal","dialogClass","parent","requestRecaptcha","requestLocationOnLogin","create","clearPasswordField","preventDefault","theDialog","recaptchtaId","grecaptcha","render","recaptchaSitekey","callback","reCAPTCHAToken","reset","doLoginPart3_callEstablishUserSession","showLoginPrompt","signupMessage","topMessage","onSuccessMethod","showLoginPromptNewStyle","scrollTo","loginOrUpgradeDialog","focus","changeFragmentId","append","bind","routeChanged","attr","keyup","keyCode","ENTER","eq","doLogin","username","val","password","onSuccess","logonToPushIfPushEnabled","showModalDialog","dialogText","onClickLinkInText","modalDialog","autoOpen","blur","first","end"],"sources":["host.js"],"sourcesContent":["/*global\r\n$,\r\ndocument,\r\ncom,\r\nwindow,\r\nsetTimeout,\r\napp_router,\r\nunescape,\r\nprotectedPageExample,\r\nconsole,\r\nglobalVersion,\r\nnavigator,\r\nlocalStorage,\r\nGEC,\r\nserverData,\r\nga,\r\ngrecaptcha,\r\nmenuDataFallback_Test,\r\nmenuDataFallback_Prod,\r\nmodules\r\n*/\r\n\r\nvar GEC = gec;\r\n\r\nvar gec = null,\r\n loginFrame,\r\n GBEUtils = com.globalbettingexchange.base,\r\n weHaveAlreadyJumpedMainContentDivToLeft = false,\r\n openToteboardPopups = [],\r\n isContestAccount = false;\r\n\r\nconst GAP_BETWEEN_ELEMENTS = 6;\r\n\r\n$(window).load(function () {\r\n\r\n \"use strict\";\r\n\r\n $(\".partner-otherpage-link\").click(function () {\r\n\r\n loginFrame = $(\"#loginFrame\")[0].contentWindow;\r\n loginFrame.call(\"showDefaultContent\");\r\n loginFrame.call(\"gepSession.recordInteraction\");\r\n\r\n });\r\n\r\n $(\"#EJStemplates\").html(window.frames.toteboardTemplatesFrame.document.getElementById(\"EJStemplates\").innerHTML);\r\n\r\n initGoogleAnalytics();\r\n\r\n deleteSessionCookieUsedByClassicSite();\r\n\r\n if (serverData.promosAPIEnable && isNoDeepLinkInURL() && !isNewStyleContestAccount()) {\r\n\r\n // Site has been loaded with no deeplink, so we will display promo carousel\r\n\r\n if (!sessionStorage.sessionToken) {\r\n // User is not already logged in, so display promo carousel immediately (otherwise wait until user is logged in, then display logged in carousel)\r\n modules.renderPromoCarousel(document.getElementById(\"promoCarousel\"), serverData.promosAPIURL, false, serverData.promosAPICachePeriodInSeconds, function () {\r\n initHeaderAndFooter();\r\n });\r\n }\r\n } else {\r\n initHeaderAndFooter();\r\n }\r\n\r\n});\r\n\r\nfunction initHeaderAndFooter() {\r\n \"use strict\";\r\n\r\n centreAndDisplayMainPanel();\r\n populateHeaderAndFooterFromAPI();\r\n}\r\n\r\nfunction isNoDeepLinkInURL() {\r\n \"use strict\";\r\n\r\n return (window.location.pathname === serverData.applicationPath ||\r\n window.location.pathname === serverData.applicationPath + \"/\");\r\n}\r\n\r\nfunction centreAndDisplayMainPanel() {\r\n \"use strict\";\r\n\r\n const windowWidth = $(window).width();\r\n const mainPanelWidth = $(\".draggableMainPanel\").width();\r\n const leftPos = (windowWidth - mainPanelWidth) / 2;\r\n $(\".draggableMainPanel\").css(\"left\", `${leftPos}px`);\r\n $(\".draggableOuter\").css(\"visibility\", \"visible\");\r\n}\r\n\r\nfunction showPromoCarousel() {\r\n \"use strict\";\r\n\r\n $(\"#promoCarousel\").show();\r\n}\r\n\r\nfunction hidePromoCarousel() {\r\n \"use strict\";\r\n\r\n $(\"#promoCarousel\").hide();\r\n}\r\n\r\nfunction isPromoCarouselVisible() {\r\n \"use strict\";\r\n\r\n return $(\"#promoCarousel\").is(\":visible\");\r\n}\r\n\r\nfunction menuDataFallback() {\r\n \"use strict\";\r\n\r\n if (serverData.menuAPIURL.indexOf(\".ft-nyrabets.com\") > -1) {\r\n return menuDataFallback_Test;\r\n }\r\n return menuDataFallback_Prod;\r\n}\r\n\r\nlet menuData;\r\n\r\nfunction populateHeaderAndFooterFromAPI() {\r\n \"use strict\";\r\n\r\n if (sessionStorage.menuData) {\r\n const nowTimestamp = (new Date()).getTime();\r\n\r\n if (nowTimestamp < Number(sessionStorage.menuDataTimestamp) + (serverData.menuAPICachePeriodInSeconds * 1000)) {\r\n console.log(`menu cache is < ${serverData.menuAPICachePeriodInSeconds} seconds old, use it!`);\r\n menuData = JSON.parse(sessionStorage.menuData);\r\n renderHeaderAndFooterMenus(menuData);\r\n return;\r\n }\r\n console.log(`menu cache is > ${serverData.menuAPICachePeriodInSeconds} seconds old, ignore it and make fresh API call`);\r\n }\r\n\r\n const timeout = setTimeout(function () {\r\n renderHeaderAndFooterMenus(menuDataFallback());\r\n }, 3000);\r\n\r\n $.get(serverData.menuAPIURL, function(dataFromAPI) {\r\n menuData = dataFromAPI;\r\n }).fail(function(xhr, status, error) {\r\n console.error(\"Error getting menu JSON from \" + serverData.menuAPIURL);\r\n console.error(\"Status: \" + status);\r\n console.error(\"Error: \" + error);\r\n menuData = menuDataFallback();\r\n }).always(function () {\r\n if (serverData.menuAPICachePeriodInSeconds > 0) {\r\n sessionStorage.menuData = JSON.stringify(menuData);\r\n sessionStorage.menuDataTimestamp = (new Date()).getTime();\r\n }\r\n clearTimeout(timeout);\r\n renderHeaderAndFooterMenus(menuData);\r\n });\r\n}\r\n\r\nfunction renderHeaderAndFooterMenus(menuDataToRender) {\r\n \"use strict\";\r\n\r\n try {\r\n modules.renderTopMenu(document.getElementById(\"topMenu\"), menuDataToRender, \"Bet\");\r\n } catch (ex) {\r\n console.error(\"Error rendering top menu from API data\");\r\n console.error(ex);\r\n console.error(\"Rendering static fallback menu instead...\");\r\n modules.renderTopMenu(document.getElementById(\"topMenu\"), menuDataFallback(), \"Bet\");\r\n }\r\n\r\n try {\r\n modules.renderFooterMenu(document.getElementById(\"footerMenu\"), menuDataToRender);\r\n } catch (ex) {\r\n console.error(\"Error rendering footer menus from API data\");\r\n console.error(ex);\r\n console.error(\"Rendering static fallback menu instead...\");\r\n modules.renderFooterMenu(document.getElementById(\"footerMenu\"), menuDataFallback());\r\n }\r\n\r\n}\r\n\r\nfunction setTopMenuCurrentlySelectedMenuLabel(currentlySelectedMenuLabel) {\r\n \"use strict\";\r\n\r\n modules.setTopMenuCurrentlySelectedMenuLabel(document.getElementById(\"topMenu\"), currentlySelectedMenuLabel);\r\n}\r\n\r\nfunction getAboutContestUrlFromMenuData() {\r\n \"use strict\";\r\n\r\n let aboutContestsUrl = \"https://racing.nyrabets.com/contests\"; // fallback URL\r\n try {\r\n // Get URL from Contests item in main desktop menu (we assume it is always there)\r\n menuData.filter((menu) => menu.api_slug === \"main\").forEach(function (menu) {\r\n menu.items.filter((item) => item.value.key === \"contests\").forEach(function (item) {\r\n aboutContestsUrl = item.value.link;\r\n });\r\n });\r\n } catch (ex) {\r\n console.error(\"Error parsing menu data\");\r\n console.error(ex);\r\n }\r\n return aboutContestsUrl;\r\n}\r\n\r\nfunction deleteUserSpecificCookiesSharedWithMarketingSite() {\r\n \"use strict\";\r\n\r\n try {\r\n $('#loginFrame')[0].contentWindow.deleteUserSpecificCookiesSharedWithMarketingSite();\r\n } catch (error) {\r\n // Login iframe probably not loaded yet - try again after a short delay\r\n setTimeout(function () {\r\n deleteUserSpecificCookiesSharedWithMarketingSite();\r\n }, 50);\r\n }\r\n}\r\n\r\nfunction initGoogleAnalytics() {\r\n \"use strict\";\r\n\r\n if (serverData.googleAnalyticsEnable) {\r\n /* eslint-disable */\r\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\r\n (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\r\n m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\r\n })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');\r\n /* eslint-enable */\r\n\r\n ga('create', serverData.googleAnalyticsTrackingId, 'auto');\r\n ga('send', 'pageview');\r\n }\r\n}\r\n\r\n\r\nfunction setIsContestAccount(isContest) {\r\n \"use strict\";\r\n\r\n isContestAccount = isContest;\r\n}\r\n\r\nfunction getIsContestAccount() {\r\n \"use strict\";\r\n\r\n return isContestAccount;\r\n}\r\n\r\nfunction allowDraggingOfMainSiteContent() {\r\n \"use strict\";\r\n\r\n const windowWidth = $(window).width();\r\n const mainPanelWidth = $(\".draggableMainPanel\").width();\r\n const leftPos = (windowWidth - mainPanelWidth) / 2;\r\n $(\".draggableMainPanel\").css(\"left\", `${leftPos}px`);\r\n $(\".draggableMainPanel\").draggable({\r\n containment: \".draggableOuter\",\r\n //handle: \".dragMainDivIconNew\",\r\n axis: \"x\",\r\n cursor: \"ew-resize\",\r\n iframeFix: true\r\n });\r\n\r\n}\r\n\r\n$(document).ready(function () {\r\n\r\n \"use strict\";\r\n\r\n // On hovering over a main menu item, display subitems\r\n $('ul.navbar li').mouseenter(function () {\r\n $(this).children('ul.subnav').show();\r\n $(this).children('a').addClass(\"selected\");\r\n });\r\n\r\n // On leaving a main menu item, or its sub-items, hide the sub-item list\r\n $('ul.navbar li').mouseleave(function () {\r\n $(this).children('ul.subnav').hide();\r\n $(this).children('a').removeClass(\"selected\");\r\n });\r\n\r\n // On clicking a main menu item or sub-item, hide all sub-items\r\n $('ul.navbar a').click(function () {\r\n $('ul.subnav').hide();\r\n $(this).removeClass(\"selected\");\r\n });\r\n});\r\n\r\n\r\nfunction onTimingOut() {\r\n\r\n \"use strict\";\r\n\r\n return undefined;\r\n\r\n}\r\n\r\nfunction callGEPFunction(functionName, param1, param2, param3, param4, param5, param6, param7) {\r\n\r\n \"use strict\";\r\n\r\n try {\r\n $(\"#loginFrame\")[0].contentWindow.call(functionName, param1, param2, param3, param4, param5, param6, param7);\r\n } catch (error) {\r\n setTimeout(function () {\r\n callGEPFunction(functionName, param1, param2, param3, param4, param5, param6, param7);\r\n }, 50);\r\n }\r\n}\r\n\r\n/** Change the route as specified, bringing the user to the relevant page\r\n * Useful for pages for which we don't support deep-linking\r\n */\r\nfunction routeChangeFunction(route) {\r\n \"use strict\";\r\n\r\n app_router.navigate(route, true);\r\n}\r\n\r\nfunction switchSiteLogoToContestLogo(entryName) {\r\n \"use strict\";\r\n\r\n if (entryName !== \"\") {\r\n $(\".contestEntryName\").text(entryName);\r\n $(\".contestEntryNameOuter\").show();\r\n }\r\n}\r\n\r\nfunction notifyContestUserLoggedIn(entryName) {\r\n \"use strict\";\r\n\r\n switchSiteLogoToContestLogo(entryName);\r\n}\r\n\r\n/** Change the fragmentId in the URL as specified, but do NOT change page */\r\nfunction changeFragmentIdFunction(route) {\r\n \"use strict\";\r\n\r\n app_router.navigate(route, {\r\n trigger: false,\r\n replace: true\r\n });\r\n}\r\n\r\nfunction sameSiteValueForCookies() {\r\n \"use strict\";\r\n\r\n if (serverData.setSameSiteNoneOnCookies) {\r\n return \"None\";\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction deleteSessionCookieUsedByClassicSite() {\r\n \"use strict\";\r\n\r\n GBEUtils.deleteCookie(\"sessionToken\");\r\n}\r\n\r\nfunction createSessionCookieUsedByClassicSite() {\r\n \"use strict\";\r\n\r\n GBEUtils.setCookie(\"sessionToken\", unescape(\"dummyTabGuid~\" + gec.getSession()), undefined, sameSiteValueForCookies());\r\n}\r\n\r\nfunction goToClassicSite() {\r\n \"use strict\";\r\n\r\n createSessionCookieUsedByClassicSite();\r\n window.location.href = serverData.classicSiteUrl;\r\n}\r\n\r\nfunction isNewStyleContestAccount() {\r\n \"use strict\";\r\n\r\n return isContestAccount || sessionStorage.contestSession || window.location.href.indexOf(\"contestAccount=\") !== -1;\r\n}\r\n\r\nfunction determineWhetherToShowPromoCarousel() {\r\n \"use strict\";\r\n\r\n if (serverData.promosAPIEnable && !isNewStyleContestAccount()) {\r\n if (sessionStorage.sessionToken) {\r\n // User loaded site already logged in\r\n // Whether or not we show the carousel depends on whether there's a deeplink or not\r\n if (isNoDeepLinkInURL()) {\r\n renderLoggedInPromoCarousel();\r\n }\r\n } else {\r\n // User has just logged in\r\n // If carousel currently shown, then update it to show only promos relevant for logged in users\r\n if (isPromoCarouselVisible()) {\r\n renderLoggedInPromoCarousel();\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\nfunction renderLoggedInPromoCarousel() {\r\n \"use strict\";\r\n\r\n modules.renderPromoCarousel(document.getElementById(\"promoCarousel\"), serverData.promosAPIURL, true, serverData.promosAPICachePeriodInSeconds, function () {\r\n initHeaderAndFooter();\r\n });\r\n}\r\n\r\nfunction loggedInFunction() {\r\n\r\n \"use strict\";\r\n\r\n determineWhetherToShowPromoCarousel();\r\n\r\n gec = $(\"#loginFrame\")[0].contentWindow.getGEC();\r\n\r\n const session = gec.getSession();\r\n\r\n $(\"#myAccount\").show();\r\n\r\n if (isContestAccount) {\r\n try {\r\n sessionStorage.contestSession = unescape(session);\r\n } catch (ignore) {\r\n console.error(\"Error setting sessionStorage.contestSession\"); // (this can happen in Safari Private Browing mode)\r\n }\r\n } else {\r\n try {\r\n sessionStorage.sessionToken = session;\r\n } catch (ex) {\r\n console.warn(ex);\r\n }\r\n }\r\n\r\n if (gec.getUserContext() !== null) {\r\n if (gec.getUserContext().cohort !== undefined\r\n && gec.getUserContext().cohort !== null) {\r\n GBEUtils.setCookie(\"cohort\", unescape(gec.getUserContext().cohort), 999999, sameSiteValueForCookies());\r\n }\r\n\r\n if (gec.getUserContext().wageringCohort !== undefined\r\n && gec.getUserContext().wageringCohort !== null) {\r\n GBEUtils.setCookie(\"wageringCohort\", unescape(gec.getUserContext().wageringCohort), 999999, sameSiteValueForCookies());\r\n } else if (gec.getUserContext().cohort !== undefined\r\n && gec.getUserContext().cohort !== null) {\r\n GBEUtils.setCookie(\"wageringCohort\", unescape(gec.getUserContext().cohort), 999999, sameSiteValueForCookies());\r\n }\r\n }\r\n\r\n if (protectedPageExample !== null) {\r\n window.location = protectedPageExample;\r\n }\r\n\r\n}\r\n\r\n//called by the login iframe when user clicks Sing Out or session expired - delete any cookies and refresh page here\r\nfunction loggedOutFunction(userInitiated) {\r\n\r\n \"use strict\";\r\n\r\n $(\"#myAccount\").hide();\r\n\r\n if (isContestAccount) {\r\n try {\r\n delete sessionStorage.contestSession;\r\n delete sessionStorage.contestEntryName;\r\n } catch (ignore) {\r\n console.error(\"Exception deleting sessionStorage items\");\r\n }\r\n } else {\r\n try {\r\n delete sessionStorage.sessionToken;\r\n } catch (ex) {\r\n console.warn(ex);\r\n }\r\n }\r\n\r\n GBEUtils.deleteCookie(\"hideBalance-NYRAPlus\");\r\n\r\n // If deeplinked to page that requires login, remove deeplink hash from URL\r\n if (window.location.href.indexOf(\"deposit\") > -1) {\r\n changeFragmentIdFunction(\"\");\r\n }\r\n\r\n if (userInitiated) {\r\n window.location.reload(true);\r\n\r\n } else {\r\n window.location = \"../\";\r\n }\r\n}\r\n\r\n// eslint-disable-next-line vars-on-top\r\nvar protectedPageExample = null;\r\n\r\n// Set the height of the footer iframe to be the same height as the content within it\r\nfunction setFooterHeight() {\r\n\r\n \"use strict\";\r\n\r\n // Do in try/catch in case footer content is on different domain or not yet loaded\r\n try {\r\n $(\".footerIframe\").height(\r\n $(\".footerIframe\").contents().find(\"body\").prop(\"scrollHeight\")\r\n );\r\n } catch (ignore) {\r\n // ignore error\r\n }\r\n}\r\n\r\nfunction loginPanelAndGEPLoaded() {\r\n\r\n \"use strict\";\r\n\r\n // eslint-disable-next-line no-shadow\r\n var loginFrame;\r\n\r\n $(\"#loginstatusPanel\").show();\r\n loginFrame = $(\"#loginFrame\")[0].contentWindow;\r\n gec = loginFrame.getGEC();\r\n\r\n if ((protectedPageExample !== null) && (gec.getSession() === null)) {\r\n $(\"#fragment\").show();\r\n loginFrame.call(\"requiresLogin\", \"This area requires log in!\");\r\n }\r\n\r\n // GEP has loaded, so now safe to show the footer\r\n if ($(\"#fragment\").is(\":visible\")) {\r\n\r\n $(\".footer\").show();\r\n\r\n // Re-do setting of footer height because...\r\n // Height should have been set on load of the footer, but while the footer has \"display:none\"\r\n // some browsers (IE, Firefox) return the height as 0! So have to re-do setting of the height\r\n // after showing the footer, to accommodate those browsers.\r\n setFooterHeight();\r\n }\r\n}\r\n\r\nfunction activateFunction() {\r\n \"use strict\";\r\n\r\n return undefined;\r\n}\r\n\r\nfunction maskHeader() {\r\n \"use strict\";\r\n\r\n $(\".header-mask\").show();\r\n\r\n const promoCarouselHeight = $(\"#promoCarousel\").is(\":visible\") ? $(\"#promoCarousel\").height() : 0;\r\n $(\".header-mask\").height($(\".header.headermenu-from-api\").height() + promoCarouselHeight);\r\n}\r\n\r\nfunction unmaskHeader() {\r\n \"use strict\";\r\n\r\n $(\".header-mask\").hide();\r\n}\r\n\r\n// Check if site is hosted within an iframe\r\nfunction isSiteInIframe() {\r\n\r\n \"use strict\";\r\n\r\n try {\r\n return window.self !== window.top;\r\n } catch (e) {\r\n return true;\r\n }\r\n}\r\n\r\n\r\nfunction showPushReconnectingMessage() {\r\n \"use strict\";\r\n\r\n $(\".pushConnectionStatus .reconnecting\").show();\r\n}\r\n\r\nfunction showPushConnectionReestablishedMessage() {\r\n \"use strict\";\r\n\r\n $(\".pushConnectionStatus .reconnecting\").hide();\r\n $(\".pushConnectionStatus .reestablished\").show();\r\n setTimeout(function () {\r\n $(\".pushConnectionStatus .reestablished\").hide();\r\n }, 2000);\r\n}\r\n\r\nconst toteboardPopups = (function () {\r\n \"use strict\";\r\n\r\n const popupArray = [];\r\n\r\n const POPUP_HEADER_HEIGHT = 23;\r\n\r\n let popupPreferredWidth;\r\n let popupPreferredHeight;\r\n\r\n function init(maxNumberOfOpenPopups) {\r\n\r\n // Make sure not already initialised\r\n if (popupArray.length === maxNumberOfOpenPopups) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < maxNumberOfOpenPopups; i = i + 1) {\r\n // Each element in the array consists of { popup, position } so we can keep track of positions of\r\n // popups that have been closed, so next time the user opens a popup, it can be opened in the same place\r\n popupArray.push({\r\n popup: undefined,\r\n position: undefined\r\n });\r\n }\r\n }\r\n\r\n function addPopupToArray(popupToAdd) {\r\n // Add to first available slot\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup === undefined) {\r\n popupArray[index] = {\r\n popup: popupToAdd,\r\n position: getPositionOfPopup(popupToAdd)\r\n };\r\n return false; // exit $.each loop\r\n }\r\n });\r\n }\r\n\r\n function removePopupFromArray(popupToRemove) {\r\n // Remove popup from array, but leave position set\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup === popupToRemove) {\r\n popupArray[index].popup = undefined;\r\n return false; // exit $.each loop\r\n }\r\n });\r\n }\r\n\r\n function getCount() {\r\n const countNonUndefinedPopups = (total, element) => (element.popup !== undefined ? total + 1 : total);\r\n return popupArray.reduce(countNonUndefinedPopups, 0);\r\n }\r\n\r\n function getPositionOfPopup(popup) {\r\n if (popup === undefined) {\r\n return undefined;\r\n }\r\n return {\r\n top: $(popup).offset().top - POPUP_HEADER_HEIGHT,\r\n left: $(popup).offset().left\r\n };\r\n }\r\n\r\n function updatePopupPositions() {\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup) {\r\n popup.position = getPositionOfPopup(popup.popup);\r\n }\r\n });\r\n }\r\n\r\n function sortPopupArrayFromTopToBottomOfDocument(popupsToSort) {\r\n popupsToSort.sort(function (a, b) {\r\n if (a.position !== undefined && b.position === undefined) {\r\n return -1;\r\n }\r\n if (a.position === undefined && b.position !== undefined) {\r\n return 1;\r\n }\r\n if (a.position === undefined && b.position === undefined) {\r\n return 0;\r\n }\r\n return a.position.top - b.position.top;\r\n });\r\n }\r\n\r\n function getPopupPositions() {\r\n // Return positions of all open popups, sorted from top to bottom on screen\r\n updatePopupPositions();\r\n sortPopupArrayFromTopToBottomOfDocument(popupArray);\r\n return popupArray.map((popup) => (\r\n popup.position === undefined ? undefined : popup.position\r\n ));\r\n }\r\n\r\n function getPreferredPositionToUse(preferredPositions) {\r\n let preferredPositionToUse;\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup === undefined\r\n && preferredPositions.length > index\r\n && preferredPositions[index] !== undefined\r\n && preferredPositions[index] !== null) {\r\n\r\n preferredPositionToUse = preferredPositions[index];\r\n return false; // exit $.each loop\r\n }\r\n });\r\n return preferredPositionToUse;\r\n }\r\n\r\n function getPopupFurthestDownThePage() {\r\n let cloneOfPopupArray = popupArray.slice(0);\r\n cloneOfPopupArray = cloneOfPopupArray.filter((popup) => popup.popup !== undefined);\r\n sortPopupArrayFromTopToBottomOfDocument(cloneOfPopupArray);\r\n if (cloneOfPopupArray.length > 0) {\r\n return $(cloneOfPopupArray[cloneOfPopupArray.length - 1].popup);\r\n }\r\n return undefined;\r\n }\r\n\r\n function getDefaultPopupPosition(popupWidth, popupHeight) {\r\n\r\n const widthOfMainDiv = $(\".bodyWrapper\").width();\r\n const xPosOfRightEdgeOfMainDiv = $(\".bodyWrapper\").offset().left + widthOfMainDiv;\r\n const yPosOfTopEdgeOfMainDiv = $(\".bodyWrapper\").offset().top + $(\".header\").height();\r\n const documentWidth = $(document).width();\r\n const documentHeight = $(document).height();\r\n\r\n if (getCount() === 0) {\r\n\r\n // No popups current exist\r\n\r\n // If there is sufficient space on page to right of main div,\r\n // position popup just to the right of main div\r\n if (xPosOfRightEdgeOfMainDiv + GAP_BETWEEN_ELEMENTS + popupWidth + GAP_BETWEEN_ELEMENTS\r\n < documentWidth) {\r\n\r\n // X position: position it horizontally immediately right of the main content frame\r\n // Y position: position it vertically in line with the top of the main content frame\r\n return {\r\n my: \"left top\",\r\n at: \"left+\" + (xPosOfRightEdgeOfMainDiv + GAP_BETWEEN_ELEMENTS)\r\n + \" top+\" + yPosOfTopEdgeOfMainDiv,\r\n of: document,\r\n collision: \"none\"\r\n };\r\n }\r\n\r\n } else {\r\n\r\n // Popups currently exist\r\n // Position new popup relative to popup furthest from the top of the page\r\n // (comparing the top edge of each popup)\r\n\r\n const lastPopup = getPopupFurthestDownThePage();\r\n if (lastPopup !== undefined) {\r\n\r\n const topOfLastPopup = lastPopup.offset().top;\r\n const heightOfLastPopup = lastPopup.height();\r\n const bottomOfLastPopup = topOfLastPopup + heightOfLastPopup;\r\n\r\n if (bottomOfLastPopup + GAP_BETWEEN_ELEMENTS + popupHeight < documentHeight) {\r\n\r\n if (xPosOfRightEdgeOfMainDiv + GAP_BETWEEN_ELEMENTS + popupWidth + GAP_BETWEEN_ELEMENTS\r\n < documentWidth) {\r\n\r\n // X position: a few pixels to the right of main div\r\n // Y position: a few pixels below last popup\r\n return {\r\n my: \"left top\",\r\n at: \"left+\" + (xPosOfRightEdgeOfMainDiv + GAP_BETWEEN_ELEMENTS)\r\n + \" top+\" + (bottomOfLastPopup + GAP_BETWEEN_ELEMENTS),\r\n of: document,\r\n collision: \"none\"\r\n };\r\n }\r\n\r\n // X position: a few pixels from top right of document\r\n // Y position: a few pixels below last popup\r\n return {\r\n my: \"right top\",\r\n at: \"right-\" + GAP_BETWEEN_ELEMENTS\r\n + \" top+\" + (bottomOfLastPopup + GAP_BETWEEN_ELEMENTS),\r\n of: document,\r\n collision: \"none\"\r\n };\r\n }\r\n } else {\r\n console.warn(\"lastPopup is undefined - this should never happen!\");\r\n }\r\n }\r\n\r\n // Default position if all else fails...\r\n\r\n // X position: a few pixels from top right of document, offset a little for each instance, so they don't exactly overlap\r\n // Y position: in line with top of main div, offset a little for each instance, so they don't exactly overlap\r\n return {\r\n my: \"right top\",\r\n at: \"right-\" + (GAP_BETWEEN_ELEMENTS * (getCount() + 1))\r\n + \" top+\" + (yPosOfTopEdgeOfMainDiv + (GAP_BETWEEN_ELEMENTS * (getCount() + 1))),\r\n of: document,\r\n collision: \"none\"\r\n };\r\n\r\n }\r\n\r\n function getNextToteboardPopupPosition(popupWidth, popupHeight) {\r\n\r\n const preferredPositions = getPopupPositions();\r\n\r\n let preferredPositionToUse;\r\n\r\n if (preferredPositions !== undefined) {\r\n preferredPositionToUse = getPreferredPositionToUse(preferredPositions);\r\n if (preferredPositionToUse !== undefined) {\r\n\r\n // Make sure that popup will not be off the right of the page (partially or fully)\r\n let leftPos = preferredPositionToUse.left;\r\n if (leftPos + popupWidth > $(window).width()) {\r\n leftPos = $(window).width() - popupWidth - GAP_BETWEEN_ELEMENTS;\r\n }\r\n\r\n return {\r\n my: \"left top\",\r\n at: \"left+\" + leftPos + \" top+\" + preferredPositionToUse.top,\r\n of: document,\r\n collision: \"none\"\r\n };\r\n }\r\n }\r\n\r\n return getDefaultPopupPosition(popupWidth, popupHeight);\r\n }\r\n\r\n function hidePopups() {\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup !== undefined) {\r\n $(popup.popup).closest(\".ui-dialog\").hide();\r\n }\r\n });\r\n }\r\n\r\n function showPopups() {\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup !== undefined) {\r\n $(popup.popup).closest(\".ui-dialog\").show();\r\n }\r\n });\r\n }\r\n\r\n function makeSurePopupsAreInView() {\r\n $.each(popupArray, function (index, popup) {\r\n if (popup.popup !== undefined) {\r\n const rightEdgeOfPopup = $(popup.popup).offset().left + $(popup.popup).width();\r\n const windowWidth = $(window).width();\r\n\r\n if (rightEdgeOfPopup > windowWidth) {\r\n $(popup.popup).closest(\".ui-dialog\").css(\"left\", windowWidth - $(popup.popup).width() - GAP_BETWEEN_ELEMENTS);\r\n }\r\n }\r\n });\r\n }\r\n\r\n function jumpMainContentDivToLeft() {\r\n\r\n $(\".draggableMainPanel\").css(\"left\", \"4px\");\r\n weHaveAlreadyJumpedMainContentDivToLeft = true;\r\n }\r\n\r\n function openPopup(params) {\r\n\r\n const width = popupPreferredWidth ? popupPreferredWidth : params.defaultWidth;\r\n const minWidth = params.minWidth;\r\n const maxWidth = params.maxWidth;\r\n const height = popupPreferredHeight ? popupPreferredHeight : params.defaultHeight;\r\n const minHeight = params.minHeight;\r\n const maxHeight = params.maxHeight;\r\n const generateToteboardContent = params.generateToteboardContent;\r\n const onCloseToteboardPopup = params.onCloseToteboardPopup;\r\n\r\n // Remove base tag from document (if still present).\r\n // It's no longer needed once the site has loaded, and it will interfere with use of jQuery UI tabs,\r\n $('base').remove();\r\n\r\n // Only jump the main div left when opening popup for first time in this browser session\r\n if (!weHaveAlreadyJumpedMainContentDivToLeft) {\r\n jumpMainContentDivToLeft();\r\n }\r\n\r\n const newToteboardPopup = $(\"
${messageText.replace(\"%ESTIMATED_TIME_REMAINING%\", \"\")}
Please check the box below to continue