1(function () { 2 "use strict"; 3 4 var NZ_TZ = "Pacific/Auckland"; 5 var LOBBY_OPEN_MINUTES_BEFORE_START = 5; 6 7 function apiBase() { 8 var w = window; 9 if (w.__EGG_ACADEMY_API_BASE__ && typeof w.__EGG_ACADEMY_API_BASE__ === "string") { 10 return String(w.__EGG_ACADEMY_API_BASE__).replace(/\/$/, ""); 11 } 12 if (w.EggSite && typeof w.EggSite.getEggAcademyApiBase === "function") { 13 return w.EggSite.getEggAcademyApiBase(); 14 } 15 var host = w.location.hostname; 16 if (host === "localhost" || host === "127.0.0.1") return "http://localhost:3000"; 17 return "https://egg.ac"; 18 } 19 20 function formatNzDateTime(iso) { 21 try { 22 return new Date(iso).toLocaleString("en-NZ", { 23 timeZone: NZ_TZ, 24 weekday: "long", 25 day: "numeric", 26 month: "long", 27 hour: "numeric", 28 minute: "2-digit", 29 hour12: true, 30 }); 31 } catch (e) { 32 return iso; 33 } 34 } 35 36 function formatNzTime(iso) { 37 try { 38 return new Date(iso).toLocaleString("en-NZ", { 39 timeZone: NZ_TZ, 40 hour: "numeric", 41 minute: "2-digit", 42 hour12: true, 43 }); 44 } catch (e2) { 45 return iso; 46 } 47 } 48 49 function lobbyOpensAtFromStart(startAtIso) { 50 var startMs = new Date(startAtIso).getTime(); 51 if (!Number.isFinite(startMs)) { 52 return null; 53 } 54 return new Date( 55 startMs - LOBBY_OPEN_MINUTES_BEFORE_START * 60 * 1000, 56 ); 57 } 58 59 function resolveSessionLobbyState(session) { 60 var lobbyOpensAt = lobbyOpensAtFromStart(session.startAt); 61 var joinOpen = 62 typeof session.joinOpen === "boolean" 63 ? session.joinOpen 64 : (function () { 65 var lobbyOpensMs = lobbyOpensAt ? lobbyOpensAt.getTime() : NaN; 66 var now = Date.now(); 67 return Number.isFinite(lobbyOpensMs) && now >= lobbyOpensMs; 68 })(); 69 return { 70 lobbyLabel: lobbyOpensAt ? formatNzTime(lobbyOpensAt.toISOString()) : "", 71 joinOpen: joinOpen, 72 }; 73 } 74 75 function formatComeBackAt(iso) { 76 try { 77 var d = new Date(iso); 78 var time = d.toLocaleString("en-NZ", { 79 timeZone: NZ_TZ, 80 hour: "numeric", 81 minute: "2-digit", 82 hour12: true, 83 }); 84 var date = d.toLocaleString("en-NZ", { 85 timeZone: NZ_TZ, 86 weekday: "long", 87 day: "numeric", 88 month: "long", 89 }); 90 return time + ", " + date; 91 } catch (e) { 92 return iso; 93 } 94 } 95 96 function escapeHtml(value) { 97 return String(value || "") 98 .replace(/&/g, "&") 99 .replace(/</g, "<") 100 .replace(/>/g, ">") 101 .replace(/"/g, """); 102 } 103 104 function bindDisabledJoinHint(card) { 105 var wrap = card.querySelector(".hs-info-session__join-wrap"); 106 var trigger = card.querySelector("[data-open-day-join-hint-trigger]"); 107 var popover = card.querySelector("[data-open-day-join-hint]"); 108 if (!wrap || !trigger || !popover) return; 109 110 var hoverUi = window.matchMedia("(hover: hover) and (pointer: fine)").matches; 111 112 function hideHint() { 113 popover.hidden = true; 114 trigger.setAttribute("aria-expanded", "false"); 115 } 116 117 function showHint() { 118 if (!popover.textContent.trim()) return; 119 popover.hidden = false; 120 trigger.setAttribute("aria-expanded", "true"); 121 } 122 123 trigger.addEventListener("click", function (ev) { 124 ev.preventDefault(); 125 ev.stopPropagation(); 126 if (hoverUi) return; 127 if (popover.hidden) showHint(); 128 else hideHint(); 129 }); 130 131 if (hoverUi) { 132 wrap.addEventListener("mouseenter", showHint); 133 wrap.addEventListener("mouseleave", hideHint); 134 wrap.addEventListener("focusin", showHint); 135 wrap.addEventListener("focusout", function (ev) { 136 if (!wrap.contains(ev.relatedTarget)) hideHint(); 137 }); 138 } 139 140 document.addEventListener("click", function (ev) { 141 if (!wrap.contains(ev.target)) hideHint(); 142 }); 143 144 document.addEventListener("keydown", function (ev) { 145 if (ev.key === "Escape") hideHint(); 146 }); 147 } 148 149 function bindReminderForm(card, session) { 150 var form = card.querySelector("[data-open-day-reminder-form]"); 151 if (!form || !window.fetch) return; 152 var phoneInp = form.querySelector("[data-open-day-reminder-phone]"); 153 var submitBtn = form.querySelector("[data-open-day-reminder-submit]"); 154 var statusEl = form.querySelector("[data-open-day-reminder-status]"); 155 156 form.addEventListener("submit", function (ev) { 157 ev.preventDefault(); 158 if (!phoneInp || !submitBtn) return; 159 var phone = String(phoneInp.value || "").trim(); 160 if (!phone || phone.replace(/\D/g, "").length < 7) { 161 if (statusEl) { 162 statusEl.textContent = "Enter a valid phone number."; 163 statusEl.hidden = false;
164 } 165 return; 166 } 167 submitBtn.disabled = true; 168 fetch(apiBase() + "/api/public/eggsite/open-day-session-reminder", { 169 method: "POST", 170 headers: { "Content-Type": "application/json" }, 171 body: JSON.stringify({ slotId: session.id, phone: phone }), 172 }) 173 .then(function (res) { 174 return res.json().then(function (body) { 175 return { ok: res.ok, body: body }; 176 }); 177 }) 178 .then(function (result) { 179 if (!result.ok) { 180 throw new Error((result.body && result.body.error) || "Could not save reminder"); 181 } 182 if (statusEl) { 183 statusEl.textContent = 184 "Reminder saved -- we will text you about an hour before start. No marketing list."; 185 statusEl.hidden = false; 186 } 187 submitBtn.disabled = false; 188 }) 189 .catch(function (err) { 190 submitBtn.disabled = false; 191 if (statusEl) { 192 statusEl.textContent = err.message || "Could not save reminder"; 193 statusEl.hidden = false; 194 } 195 }); 196 }); 197 } 198
199 function renderSessionCard(session) { 200 var card = document.createElement("article"); 201 card.className = 202 "hs-info-session hs-info-session--ticket-stub odl-session-panel odl-session-panel--layout-05"; 203 card.setAttribute("data-session-id", session.id); 204 205 var whenLabel = formatNzDateTime(session.startAt); 206 var lobbyState = resolveSessionLobbyState(session); 207 var lobbyOpensAt = lobbyOpensAtFromStart(session.startAt); 208 var joinOpen = lobbyState.joinOpen; 209 var ended = Boolean(session.ended) && !joinOpen; 210 var joinUrl = session.joinUrl || "#"; 211 var comeBackTitle = 212 lobbyOpensAt && !joinOpen && !ended 213 ? "Come back at " + formatComeBackAt(lobbyOpensAt.toISOString()) 214 : "Join opens shortly before the session starts."; 215 216 var joinHtml = ended 217 ? '<p class="hs-info-session__ended">This Open Day has ended.</p>' 218 : joinOpen 219 ? '<a class="btn btn-primary hs-info-session__join" href="' + 220 escapeHtml(joinUrl) + 221 '" rel="noopener noreferrer" title="Join the Open Day tour">' + 222 "Join the tour</a>" 223 : '<div class="hs-info-session__join-wrap">' + 224 '<button type="button" class="btn btn-primary hs-info-session__join hs-info-session__join--disabled" aria-disabled="true" aria-expanded="false" aria-controls="open-day-join-hint-' + 225 escapeHtml(session.id) + 226 '" data-open-day-join-hint-trigger>Join the tour</button>' + 227 '<p class="hs-info-session__join-popover" id="open-day-join-hint-' + 228 escapeHtml(session.id) + 229 '" data-open-day-join-hint hidden role="status">' + 230 escapeHtml(comeBackTitle) + 231 "</p></div>"; 232 233 card.innerHTML = 234 '<div class="hs-info-session__when-block">' + 235 '<div class="hs-info-session__head">' + 236 '<h3 class="eg-slim-h4 hs-info-session__when">' + 237 escapeHtml(whenLabel) + 238 " NZ</h3>" + 239 "</div>" + 240 "</div>" + 241 '<div class="hs-info-session__join-block">' + 242 '<div class="hs-info-session__actions">' + 243 joinHtml + 244 "</div>" + 245 "</div>" + 246 '<form class="hs-info-session__reminder hs-info-session__reminder-block" data-open-day-reminder-form>' + 247 '<p class="hs-info-session__reminder-label">Want a text reminder 1 hour before?</p>' + 248 '<div class="hs-info-session__reminder-row">' + 249 '<input type="tel" class="hs-info-session__reminder-phone" placeholder="021 123 4567" autocomplete="tel" inputmode="tel" maxlength="40" data-open-day-reminder-phone required />' + 250 '<button type="submit" class="btn btn-secondary hs-info-session__reminder-btn" data-open-day-reminder-submit>Remind Me</button>' + 251 "</div>" + 252 '<p class="hs-info-session__reminder-status" data-open-day-reminder-status hidden></p>' + 253 "</form>"; 254 255 bindReminderForm(card, session); 256 bindDisabledJoinHint(card); 257 return card; 258 } 259 260 function initOpenDaySessions() { 261 var roots = document.querySelectorAll("[data-open-day-root]"); 262 if (!roots.length || !window.fetch) return; 263 264 roots.forEach(function (root) { 265 if (root.hidden) return; 266 if (root.getAttribute("data-open-day-static") === "true") return; 267 var listEl = root.querySelector("[data-open-day-sessions-list]"); 268 var emptyEl = root.querySelector("[data-open-day-sessions-empty]"); 269 var loadingEl = root.querySelector("[data-open-day-sessions-loading]"); 270 if (!listEl) return; 271 272 fetch(apiBase() + "/api/public/eggsite/open-day-sessions") 273 .then(function (res) { 274 return res.json(); 275 }) 276 .then(function (payload) { 277 if (loadingEl) loadingEl.hidden = true; 278 var sessions = (payload && payload.sessions) || []; 279 if (!sessions.length) { 280 root.hidden = true; 281 root.setAttribute("hidden", ""); 282 return; 283 } 284 root.hidden = false; 285 root.removeAttribute("hidden"); 286 if (emptyEl) emptyEl.hidden = true; 287 for (var i = 0; i < sessions.length; i++) { 288 listEl.appendChild(renderSessionCard(sessions[i])); 289 } 290 }) 291 .catch(function () { 292 if (loadingEl) loadingEl.hidden = true; 293 if (emptyEl) { 294 emptyEl.textContent = 295 "Could not load Open Day times right now. Refresh the page or contact us."; 296 emptyEl.hidden = false;
297 } 298 }); 299 }); 300 } 301 302 function init() { 303 initOpenDaySessions(); 304 } 305 306 if (document.readyState === "loading") { 307 document.addEventListener("DOMContentLoaded", init); 308 } else { 309 init(); 310 } 311})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.