PageSourceSearch

https://www.brighthorizons.com/dist/js/corporate/bh_analytics_event_handler.js?20260924082835

js brighthorizons.com collected 2026-09-24 08:29:02 UTC 29,054 bytes, 645 lines download raw bytes

1//Get Cookie value here
2let GBCookieValue = "b4init";
3
4//Adding app insights here
5
6function isC0002CookieOptedIn() {
7    const activeGroups = document.defaultView['OnetrustActiveGroups'];
8    return activeGroups !== null && activeGroups !== undefined && activeGroups.includes('C0002');
9}
10
11// Azure Application Insights Integration
12function setupAppInsights() {
13    var appInsightsConfig = {
14        nonProd: {
15            instrumentationKey: "11d2accb-21ad-4848-a409-d99ed488aa12",
16            connectionString: "InstrumentationKey=11d2accb-21ad-4848-a409-d99ed488aa12;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/;ApplicationId=af029cbe-32b3-4c7d-8788-3fe9c083c03d"
17        },
18        prod: {
19            instrumentationKey: "c9b0ed3e-a8a5-4042-8c2d-a663efafa72a",
20            connectionString: "InstrumentationKey=c9b0ed3e-a8a5-4042-8c2d-a663efafa72a;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/;ApplicationId=4c409c11-9f40-4dd2-aff7-85766940763b"
21        }
22    };
23
24    var _appInsightsInstances = {
25        nonProd: null,
26        prod: null
27    };
28
29    var _isSdkLoaded = false;
30    var _isSdkLoading = false;
31
32    function getInstanceKey(isProd) {
33        return "prod";
34        //return isProd === true ? "prod" : "nonProd";
35    }
36
37    function getConfigByFlag(isProd) {
38        return appInsightsConfig.prod;
39        //return isProd === true ? appInsightsConfig.prod : appInsightsConfig.nonProd;
40    }
41
42    function createAppInsightsInstance(connectionString, isProd) {
43        var snippet = window.Microsoft && window.Microsoft.ApplicationInsights;
44        if (!snippet) {
45            return null;
46        }
47
48        var selectedConfig = getConfigByFlag(isProd);
49        var config = {
50            connectionString: connectionString || selectedConfig.connectionString,
51            enableAutoRouteTracking: true,
52            disableFetchTracking: false,
53            enableResponseHeaderTracking: true
54        };
55
56        var instance = new snippet.ApplicationInsights({ config: config });
57        instance.addTelemetryInitializer(function (envelope) {
58            envelope.tags = envelope.tags || {};
59            envelope.tags["ai.cloud.role"] = "BH-Corporate-Frontend";
60            envelope.tags["ai.cloud.roleInstance"] = window.location.hostname;
61
62            if (!envelope || envelope.baseType !== "RemoteDependencyData") {
63                return;
64            }
65
66            var baseData = envelope.data && envelope.data.baseData;
67            if (!baseData) {
68                return;
69            }
70
71            baseData.properties = baseData.properties || {};
72
73            var responseHeaders = baseData.properties.responseHeaders;
74            var cfRayHeader = null;
75
76            if (responseHeaders) {
77                if (typeof responseHeaders === "string") {
78                    try {
79                        responseHeaders = JSON.parse(responseHeaders);
80                    } catch (e) {
81                        responseHeaders = null;
82                    }
83                }
84
85                if (responseHeaders) {
86                    cfRayHeader = responseHeaders["cf-ray"] || responseHeaders["CF-RAY"] || responseHeaders["Cf-Ray"] || null;
87                }
88            }
89
90            if (cfRayHeader) {
91                baseData.properties.cfRay = cfRayHeader;
92            }
93        });
94
95        instance.loadAppInsights();
96        instance.trackPageView();
97        return instance;
98    }
99
100    /**
101     * Initializes Application Insights SDK.
102     * @param {string} connectionString - Optional App Insights connection string override
103     * @param {boolean} isProd - Optional target environment. true => prod, false => non-prod
104     */
105    function initAppInsights(connectionString, isProd) {
106        try {
107            if (!isC0002CookieOptedIn()) {
108                console.log("Application Insights initialization skipped - C0002 consent not granted.");
109                return;
110            }
111
112            var instanceKey = getInstanceKey(isProd);
113            if (_appInsightsInstances[instanceKey]) {
114                return;
115            }
116
117            if (_isSdkLoaded) {
118                _appInsightsInstances[instanceKey] = createAppInsightsInstance(connectionString, isProd);
119                if (!_appInsightsInstances.nonProd) {
120                    _appInsightsInstances.nonProd = createAppInsightsInstance(null, false);
121                }
122                if (!_appInsightsInstances.prod) {
123                    _appInsightsInstances.prod = createAppInsightsInstance(null, true);
124                }
125                //window.appInsights = _appInsightsInstances.nonProd;
126                return;
127            }
128
129            if (_isSdkLoading) {
130                return;
131            }
132
133            _isSdkLoading = true;
134            var sdkScript = document.createElement("script");
135            sdkScript.src = "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js";
136            sdkScript.crossOrigin = "anonymous";
137            sdkScript.onload = function () {
138                try {
139                    _isSdkLoaded = true;
140                    _isSdkLoading = false;
141
142                    _appInsightsInstances.nonProd = _appInsightsInstances.nonProd || createAppInsightsInstance(null, false);
143                    _appInsightsInstances.prod = _appInsightsInstances.prod || createAppInsightsInstance(null, true);
144
145                    //window.appInsights = _appInsightsInstances.nonProd;
146                    logTime("Application Insights initialized");
147                } catch (e) {
148                    console.warn("Application Insights initialization failed:", e);
149                }
150            };
151            sdkScript.onerror = function () {
152                _isSdkLoading = false;
153                console.error("Failed to load Application Insights SDK.");
154            };
155            document.head.appendChild(sdkScript);
156        } catch (e) {
157            console.warn("Application Insights setup failed:", e);
158        }
159    }
160
161    /**
162     * Logs a trace message to Azure Application Insights.
163     * @param {string} message - The trace message to log.
164     * @param {object} [customProperties] - Optional custom properties (key-value pairs).
165     * @param {number}
165 [severityLevel] - Optional severity: 0=Verbose, 1=Information, 2=Warning, 3=Error, 4=Critical
166     * @param {boolean} [isProd=false] - Optional target environment. true => prod, false => non-prod
167     */
168    function logToAppInsights(message, customProperties, severityLevel, isProd) {
169        try {
170            if (!isC0002CookieOptedIn()) {
171                return;
172            }
173
174            var instanceKey = getInstanceKey(isProd);
175            var instance = _appInsightsInstances[instanceKey];
176
177            if (!instance) {
178                initAppInsights(null, isProd);
179                console.warn("App Insights not initialized. Trace: " + message);
180                return;
181            }
182
183            instance.trackTrace({
184                message: message,
185                severityLevel: severityLevel !== undefined ? severityLevel : 1,
186                properties: customProperties || {}
187            });
188        } catch (e) {
189            console.warn("logToAppInsights error: " + e.message);
190        }
191    }
192
193    // Expose globally
194    window.initAppInsights = initAppInsights;
195    window.logToAppInsights = logToAppInsights;
196}
197
198// CRITICAL: Block client-side URL redirects immediately at script load time.
199// All URL redirect experiments are handled server-side by GrowthBookExperimentProcessor.
200// This MUST be set before the GrowthBook auto SDK script loads to prevent any race condition.
201window.growthbook_config = window.growthbook_config || {};
202window.growthbook_config.navigate = function (url) {
203    console.log("GB navigate blocked (handled server-side): " + url);
204};
205
206// CRITICAL: Extract server-assigned gbuuid from gbtls cookie IMMEDIATELY at script load.
207// The server sets gbtls with the authoritative gb_id used for experiment bucketing.
208// We must capture this BEFORE gbuuidHandler() runs (via OneTrust callbacks) and deletes
209// the gbuuid cookie. This value is used later to ensure gbuuid stays consistent.
210(function () {
211    try {
212        var match = document.cookie.match(/(^| )gbtls=([^;
212]+)/);
213        if (match) {
214            var gbtls = JSON.parse(decodeURIComponent(match[2]));
215            if (gbtls && gbtls.event && gbtls.event.gb_id) {
216                window._gbServerUserId = gbtls.event.gb_id;
217                try { localStorage.setItem('_gbServerUserId', gbtls.event.gb_id); } catch (e) { }
218            }
219        }
220        // Fallback: restore from localStorage if gbtls was already cleared (e.g. page reload)
221        if (!window._gbServerUserId) {
222            try {
223                var stored = localStorage.getItem('_gbServerUserId');
224                if (stored) window._gbServerUserId = stored;
225            } catch (e) { }
226        }
227    } catch (e) { }
228})();
229
230// GBUUID
231/**
232 * There are cases when using feature flags client side where the 3rd party identifiers used for assignment will be slow to load, and may cause flickering as some of the DOM rerenders. 
233 * In these cases, generating your own identifier will make sure that features are assigned correctly when GrowthBook loads. 
234 * This id that is generated will typically align one to one with the other identifiers, and does not need to be passed outside the SDK (though can be useful for debugging to pass this value in the trackingCallback).
235 * 
236 * The code below can be used to generate a unique user id and save it in a cookie for the maximum amount of time allowed.
237 * This id will be unique to the browser and not the user, so if a user switches devices, they will have a different id.
238 */
239function gbuuidHandler() {
240    // Check if the OneTrustOptInValues is available
241    const hasOneTrustOptInValues = !(
242        document.defaultView['OnetrustActiveGroups'] === null || document.defaultView['OnetrustActiveGroups'] === undefined
243    );
244    // Check if the OneTrustOptInValues is available
245    if (hasOneTrustOptInValues) {
246        const hasC0002Consent = isC0002CookieOptedIn();
247        console.log("hasC0002CookieOptedIn===>", hasC0002Consent);
248        if (hasC0002Consent) {
249            const COOKIE_NAME = "bhgbuuid";
250            const COOKIE_DAYS = 400; // 400 days is the max cookie duration for browsers
251
252            // use the browsers crypto.randomUUID if set
253            const genUUID = () => {
254                if (window?.crypto?.randomUUID) return window.crypto.randomUUID();
255                return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
256                    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
257                );
258            };
259            const getCookie = (name) => {
260                let value = `; ${document.cookie}`;
261                let parts = value.split(`; ${name}=`);
262                if (parts.length === 2) {
263                    let existing = parts.pop().split(';').shift();
264                    // Clean corrupted values from legacy server-side bug (e.g., "UUID&SameSite=Lax")
265                    if (existing && existing.indexOf('&') !== -1) {
266                        existing = existing.split('&')[0];
267                    }
268                    return existing;
269                }
270            };
271            const setCookie = (name, value) => {
272                var d = new Date();
273                d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * COOKIE_DAYS);
274                var hostParts = window.location.hostname.split('.');
275                var domain = hostParts.length >= 2 ? '.' + hostParts.slice(-2).join('.') : '';
276                var ck = name + "=" + value + ";path=/;expires=" + d.toGMTString();
277                if (domain) ck += ";domain=" + domain;
278                if (window.location.protocol === 'https:') ck += ";Secure";
279                ck += ";SameSite=Lax";
280                document.cookie = ck;
281            };
282            logTime("BHGBUUID function executed");
283            // get the existing UUID from cookie if set, otherwise create one and store it in the cookie
284            let existing = getCookie(COOKIE_NAME);
285
286            if (existing) return existing;
287            // If the server assigned a gbuuid for an experiment, reuse it instead of
288            // generating a new one. This prevents gb_id/gbuuid mismatches.
289            const uuid = window._gbServerUserId || genUUID();
290            setCookie(COOKIE_NAME, uuid);
291        } else {
292            // delete the cookie if the user has not opted in —
293            // BUT preserve it if a server-side experiment is active (gbtls cookie present).
294            // The server needs a stable gbuuid for experiment bucketing; deleting it here
295            // would cause a new UUID to be generated later, breaking gb_id consistency.
296            if (!window._gbServerUserId) {
297                clearCookieAcrossDomains("bhgbuuid");
298            }
299        }
300    }
301}
302// End GBUUID
303
304/**
305 * This script will be used to update all the analytics with the latest consent value from OneTrust
306 * This OptanonWrapper will be called from the OneTrust wrapper script
307 */
308function OptanonWrapper() {
309    // Call userConsentHandler method to update the analytics with the latest consent value from OneTrust
310    userConsentHandler(OnetrustActiveGroups);
311    //OneTrust Cookies On Consent Listener to update the Cookie consent manager  
312    OneTrust.OnConsentChanged(function (e) {
313        console.log("BH Analytics OnConsentChanged change called", this);
314        userConsentHandler(e);
315    });
316    this.document.dispatchEvent(new CustomEvent('onetrust-loaded'));
317    window.onetrustInit = true;
318}
319/**
320 * This method will be called from the OptanonWrapper method to update the analytics with the latest consent value from OneTrust
321 * This method will be called on page load and OnConsentChanged event from OneTrust
322 * @param {*} activeGropups - OnetrustActiveGroups value
323 */
324function userConsentHandler(activeGropups) {
325    // Check if the OneTrustOptInValues is available
326    const hasOneTrustOptInValues = !(
327        document.defaultView['OnetrustActiveGroups'] === null || document.defaultView['OnetrustActiveGroups'] === undefined
328    );
329    // Get the new OneTrustActiveGroups value
330    const newOneTrustActiveGroups = document.defaultView['OnetrustActiveGroups'].toString();
331
332    // Check if the OneTrustOptInValues is available
333    if (hasOneTrustOptInValues) {
334        // Get the old OneTrustActiveGroups value from the localStorage
335        let oldList = localStorage.getItem('BHOnetrustActiveGroupsOld');
336        // Save the latest OneTrustActiveGroups value in the localStorage
337        localStorage.setItem('BHOnetrustActiveGroupsOld', newOneTrustActiveGroups);
338        // Check if the newOneTrustActiveGroups value is different from the old value
339        if (oldList) {
340            // Split the old value to an array
341            oldList = oldList.split(',');
342            oldList.forEach((item) => {
343                // Check if the newOneTrustActiveGroups value is different from the old value
344                if (newOneTrustActiveGroups?.includes(item)) {
345                    // There is no change in the consent value
346                } else {
347                    // There is a change in the consent value
348                    // Reload the page if the consent value is changed
349                    if (item !== 'C0001') {
350                        window?.location?.reload();
351                    }
352                }
353            });
354        }
355        // call the gbuuidHandler method to generate the unique user id and save it in a cookie
356        gbuuidHandler();
357
358        if (isC0002CookieOptedIn()) {
359            initAppInsights();
360        }
361    }
362}
363// End OneTrust Consent Management
364
365// GrowthBook Integration
366/**
367 * This function will inject the GrowthBook script into the head of the document
368 */
369function injectGrowthBookScript() {
370    logTime("Injecting GrowthBook script");
371
372    const clientKeyEl = document.getElementById("gbClientKey");
373    if (!clientKeyEl) {
374        console.warn("gbClientKey element not found.");
375        return;
376    }
377
378    const script = document.createElement("script");
379    script.setAttribute("data-api-host", "https://cdn.growthbook.io");
380    script.setAttribute("data-client-key", clientKeyEl.value);
381    script.src = "https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/auto.min.js";
382    script.setAttribute("data-no-auto-cookies", "");
383    script.setAttribute("data-no-auto-redirect", "");
384    script.async = true;
385    script.onload = () => {
386        console.log("GrowthBook script loaded successfully.")
387        // logToAppInsights("GrowthBook Script on loaded before update", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1);
388        //         // 1. Read your custom cookie
389        // //const id = getCookieValue("bhgbuuid");
390        // //if (id) { 
391        //     // 2. Set it as the GrowthBook user ID
392        //   //  window.growthbook_config.attributes.id = GBCookieValue;
393        // //}
394        // console.log("GrowthBook custom ID set:", GBCookieValue);
395        // logToAppInsights("GrowthBook Script loaded", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1);
396    };
397    script.onerror = () => {
398        console.error("Failed to load GrowthBook script.");
399    };
400    document?.head?.appendChild(script);
401}
402
403// Function to get cookie value by name
404function getCookieValue(name) {
405    const regex = new RegExp(`(^| )${name}=([^;]+)`);
406    const match = document.cookie.match(regex);
407    if (match) {
408        var val = match[2];
409        // Clean corrupted values from legacy server-side bug (e.g., "UUID&SameSite=Lax")
410        if (name === 'bhgbuuid' && val && val.indexOf('&') !== -1) {
411            val = val.split('&')[0];
412        }
413        return val;
414    }
415}
416
417function clearCookieAcrossDomains(name) {
418    document.cookie = name + "=;path=/;max-age=0";
419
420    var host = window.location.hostname;
421    if (!host) return;
422
423    var hostParts = host.split('.');
424    for (var i = 0; i <= hostParts.length - 2; i++) {
425        var domainParts = hostParts.slice(i);
426        if (domainParts.length >= 2) {
427            document.cookie = name + "=;path=/;max-age=0;domain=." + domainParts.join('.');
428        }
429    }
430}
431
432// Initialize GrowthBook
433function initializeGrowthbook(options = {}) {
434    if (window._gbInitialized) {
435        logTime("GrowthBook already initialized, skipping");
436        return;
437    }
438    window._gbInitialized = true;
439
440    window.gbRecordEvent = function (eventParams) {
441        if (!eventParams || !eventParams.experiment_id || !eventParams.variation_id) {
442            logTime("gbRecordEvent: skipping dataLayer push - missing required fields");
443            return;
444        }
445        logTime("GrowthBook Experiment started event triggered");
446        window.dataLayer = window.dataLayer || [];
447        window.dataLayer.push({
448            event: "experiment_started",
449            experiment_name: eventParams.experiment_id,
450            experiment_variation: eventParams.variation_id,
451            gb_id: eventParams.gb_id || "",
452            test_platform: "growthbook-js",
453            anonymous: "true",
454        });
455    };
456    // Read gbtls cookie (set server-side by GrowthBookExperimentProcessor for URL redirect experiments)
457    // and push experiment tracking event to dataLayer
458    (function () {
459        try {
460            const hasC0002Consent = isC0002CookieOptedIn();
461            console.log("hasC0002CookieOptedIn===>", hasC0002Consent);
462            if (hasC0002Consent) {
463                const urlParams = new URLSearchParams(window.location.search);
464                const featureFlag = urlParams.get('featureFlag');
465                var siteUrl = window.location.hostname;
466                var currentUrl = window.location.pathname;
467                if (featureFlag) {
468                    var apiURL = "https:" + "/api/corporate/GetFeatureFlag/FeatureFlagData?featureFlag=" + featureFlag 
468+ "&currentUrl=" + currentUrl;
469                    fetch(apiURL, {
470                        method: 'GET',
471                        headers: {
472                            'Content-Type': 'application/json'
473                        }
474                    })
475                        .then(response => {
476                            if (!response.ok) {
477                                console.log('response:', response);
478                            }
479
480                            return response.json();
481                        })
482                        .then(data => {
483                            console.log('Success:', data.message);
484                            if (data.message) {
485                                logTime("GrowthBook Experiment present");
486                                var gbtls = JSON.parse(decodeURIComponent(data.message));
487                                if (gbtls.event && gbtls.event.experiment_id && gbtls.event.variation_id && gbtls.date && new Date().getTime() - gbtls.date < 60000) {
488                                    logTime("Logging redirectUrl GrowthBook exp event");
489                                    // Restore gbuuid cookie to match the server-assigned ID used for experiment
490                                    // bucketing. gbuuidHandler() may have deleted the cookie before OneTrust C0002
491                                    // consent was granted, so we re-set it here from the authoritative server value.
492                                    // This ensures gb_id in the experiment_started event matches the gbuuid cookie,
493                                    // and prevents gbuuidHandler from generating a different UUID later.
494                                    if (gbtls.event.gb_id) {
495                                        var _hp = window.location.hostname.split('.');
496                                        var _dm = _hp.length >= 2 ? '.' + _hp.slice(-2).join('.') : '';
497                                        var _ex = new Date();
498                                        _ex.setTime(_ex.getTime() + 24 * 60 * 60 * 1000 * 400);
499                                        var _ck = "bhgbuuid=" + gbtls.event.gb_id + ";path=/;expires=" + _ex.toGMTString();
500                                        if (_dm) _ck += ";domain=" + _dm;
501                                        if (window.location.protocol === 'https:') _ck += ";Secure";
502                                        _ck += ";SameSite=Lax";
503                                        document.cookie = _ck;
504                                        try { localStorage.setItem('_gbServerUserId', gbtls.event.gb_id); } catch (e) { }
505                                    }
506
507                                    window.gbRecordEvent(gbtls.event);
508                                }
509                            }
510
511                        })
512                        .catch(error => {
513                            console.error('Error calling FeatureFlagData API:', error);
514                        });
515                }
516            }
517        } catch (e) {
518            // ignore errors
519        }
520    })();
521    window.growthbook_config = window.growthbook_config || {};
522    logToAppInsights("initializeGrowthbook function before setting attributes", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1);
523    window.growthbook_config.uuidCookieName = "bhgbuuid";
524    window.growthbook_config.attributes = {
525        //id: GBCookieValue, // user ID or other targeting attributes
526        url: window.location.href,
527        path: window.location.pathname
528    };
529    logToAppInsights("initializeGrowthbook function after setting attributes", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1);
530
531    // navigate override is already set at the top of this file (before any SDK loads)
532
533    window.growthbook_config.trackingCallback = function (experiment, result) {
534        // Skip URL redirect experiments — these are tracked via gbtls cookie set by server-side processor.
535        // The auto SDK still evaluates them (shouldRun is not supported), but we don't track them here.
536        if ("urlPatterns" in experiment && experiment.urlPatterns && experiment.urlPatterns.length > 0) {
537            logTime("GB trackingCallback -> Skipping redirect experiment (tracked server-side via gbtls cookie): " + experiment.key);
538            return;
539        }
540        console.log("testing");
541        console.log(result);
542        console.log(experiment);
543        logToAppInsights("GB trackingCallback function before GA ", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1);
544
545        logTime("GB Tracking callback for: " + experiment.key);
546        var eventParams = {
547            experiment_id: experiment.key,
548            variation_id: result.key,
549            gb_id: result.hashValue
550        };
551        //getCookieValue("bhgbuuid") - old value for gb_id
552        window.gbRecordEvent(eventParams);
553        logToAppInsights("GB trackingCallback function after GA", { growthbook_config_id: GBCookieValue, details: JSON.stringify(window.growthbook_config.attributes) }, 1, true);
554        logToAppInsights("GB trackingCallback function into GA", { GA_cookie: JSON.stringify(window.gaGlobal), details: JSON.stringify(eventParams) }, 1);
555        if (window?.clarity) {
556            console.log('Clarity set for experiment:', experiment.key, 'variation:', result.key);
557            clarity("set", experiment.key, result.key);
558        }
559        else {
560            console.log('Clarity NOT FOUND for experiment:', experiment.key, 'variation:', result.key);
561        }
562    };
563    injectGrowthBookScript();
564}
565
566// Custom page view function
567function customPageView() {
568    dataLayer.push({
569        event: 'page_view',
570        page_location: window.location.href,
571        page_referrer: document.referrer
572    });
573    logTime("Custom page view pushed");
574    // Initialize GBUUID
575    //gbuuidHandler();
576    //cookie shoule be there anyway
577    // Initialize GrowthBook
578    initializeGrowthbook();
579}
580
581// Function to check if required events are present in dataLayer
582function hasRequiredEvents() {
583    var foundOneTrust = false;
584    var foundOptanon = false;
585
586    for (var i = 0; i < window.dataLayer.length; i++) {
587        var eventName = window.dataLayer[i].event;
588        if (eventName === 'OneTrustGroupsUpdated') {
589            foundOneTrust = true;
590        }
591        if (eventName === 'OptanonLoaded') {
592            foundOptanon = true;
593        }
594    }
595
596    return foundOneTrust && foundOptanon;
597}
598
599// Function to push custom page view when required events are present
600var retryCount = 0;
601var maxRetries = 10;
602function pushCustomPageViewWhenReady() {
603    logTime("Checking for required events");
604
605    if (hasRequiredEvents()) {
606        logTime("OneTrustGroupsUpdated and OptanonLoaded events found");
607        customPageView();
608    } else {
609        retryCount++;
610        logTime("OneTrustGroupsUpdated and/or OptanonLoaded events not found");
611        if (retryCount < maxRetries) {
612            logTime("Retrying for OneTrust events... Attempt " + retryCount);
613            setTimeout(pushCustomPageViewWhenReady, 100);
614        } else {
615            logTime("Max retries reached. Giving up.");
616            // Even if the events are not found, we can still push the custom page view
617            customPageView();
618        }
619    }
620}
621
622
623
624
625function logTime(message) {
626    var now = new Date();
627    var hours = now.getHours();
628    var minutes = now.getMinutes();
629    var seconds = now.getSeconds();
630    var milliseconds = now.getMilliseconds();
631    console.log(message + ' at ' + hours + 'h ' + minutes + 'm ' + seconds + 's ' + milliseconds + 'ms');
632}
633
634setupAppInsights();
635initAppInsights();
636
637// Wait for the DOM to be fully loaded
638$(document).ready(function () {
639    logTime("Document is ready");
640    window.dataLayer = window.dataLayer || [];
641    GBCookieValue = getCookieValue("bhgbuuid");
642    pushCustomPageViewWhenReady();
643    logToAppInsights("GA global cookie value", { cookieValue: JSON.stringify(window.gaGlobal) }, 1);
644    logToAppInsights("GrowthBook global cookie value", { cookieValue: GBCookieValue }, 1);
645});

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.