PageSourceSearch

https://www.northonline.com.au/etc.clientlibs/northonline-editable…s.lc-3304a8da9d51f2e4df4f9ab874a8e96b-lc.js

js northonline.com.au collected 2026-10-09 00:31:16 UTC 68,094 bytes, 2,177 lines download raw bytes

1try {
2  var digitalData = {};
3  window.lists = digitalData;
4  let adobeDataLayerState = adobeDataLayer?.getState();
5  let adobeDataLayerSiteData = adobeDataLayerState?.page?.siteData || {};
6
7  /*  constants
8  .   dom selectors
9  .   components
10  .   type track of events
11  .*/
12
13  let isIntialLoad = false;
14  const selectors = {
15    accordion: ".accordion",
16    home: "home",
17    searchParam: "search#stq",
18    header: ".header",
19    footer: ".footer",
20    finepPintBlock: ".fineprintblock",
21    dataCmpDataLayer: "data-cmp-data-layer",
22    notifications: "aem-notifications",
23    pageCollectionBlock: ".pagecollectionblock",
24    productCard: ".product-card",
25    sideModal:
26      ".amp-sidemodal:not(#login-side-modal.amp-sidemodal.login-modal)",
27    sectionContainer: ".sectioncontainer",
28    socialShare: ".social-share",
29    table: ".amp-table",
30    tabs: ".tabs",
31    teaserBlock: ".teaser-block",
32    twoColContainer: ".twocolcontainer ",
33    wayfindingBlock: ".wayfinding-block",
34    inclusionBlock: ".inclusionsblock",
35    processBlock: ".processBlock",
36    leadCaptureBlock: ".leadcaptureblock",
37    calculatorBlock: ".calculatorblock",
38    featuredGridBlock: ".featured-grid-block",
39    productGridBlock: ".product-grid-block",
40    lrMediaBlock: ".mediablock",
41    productCards: ".cmp-product-card",
42    headerBanner: ".header-banner",
43    articleBanner: ".article-banner",
44    ctaBanner: ".ctabanner",
45    linkList: ".linklist",
46    editorialGrid: ".editorialgrid",
47    tileGridBlock: ".tilegridblock",
48    bentoTileGrid: ".bentotilegrid",
49    productHighlightBlock: ".product-block",
50    testimonialBlock: ".testimonial .testimonial-block",
51    windowBanner: ".windowbanner",
52    appPromotionBanner: ".apppromotionbanner",
53    breadcrumb: ".breadcrumb",
54    loginPopup: "#login-side-modal.amp-sidemodal.login-modal",
55    multiColumnTextBlock: ".multi-column-text-block",
56    homepageBanner: ".homepage-banner",
57    ootbTab: ".cmp-tabs__tab",
58    sideModalCloseBtn: ".amp-sidemodal-close",
59    form: ".cmp-form form",
60    searchBtn: "search-btn",
61    searchCloseBtn: "search-close-btn",
62    adaptiveRadioBtn: "input.cmp-adaptiveform-radiobutton__option__widget",
63    adaptivePanel: '[data-cmp-is="adaptiveFormPanel"]',
64    businessFormPanel: '[data-panel-name="business_vertical_form_panel"]',
65    adaptiveFormcontainer: '[data-cmp-is="adaptiveFormContainer"]',
66    JoinNowBack: ".join-now-wizard__container__content__back",
67    joinNowGetApp: ".wizard-thank-you__get-app",
68    superContinueWebRadioBtn: "super_web_app-radio",
69    joinNowGetStartedBtn: '[data-btn-name="get_started_button"]',
70    formSubmitBtn: '[data-btn-name="submit_bussiness_form"]',
71  };
72
73  const components = {
74    accordion: "accordion",
75    header: "header",
76    finepPintBlock: "fine-print-block",
77    footer: "footer",
78    notifications: "notifications",
79    pageCollectionBlock: "page-collection-block",
80    productCard: "product-card",
81    sectionContainer: "section-container",
82    sideModal: "side-modal",
83    socialShare: "social-share",
84    table: "table",
85    tabs: "tabs",
86    teaserBlock: "teaser-block",
87    twoColContainer: "two-column-container",
88    wayfindingBlock: "wayfinding-block",
89    inclusionBlock: "inclusions-block",
90    processBlock: "process-block",
91    leadCaptureBlock: "lead-capture-block",
92    calculatorBlock: "calculator-block",
93    featuredGridBlock: "featured-grid-block",
94    productGridBlock: "product-grid-block",
95    lrMediaBlock: "lr-media-block",
96    headerBanner: "header-banner",
97    articleBanner: "article-banner",
98    ctaBanner: "cta-banner",
99    linkList: "link-list",
100    overlay: ".overlay--tooltip",
101    editorialGrid: "editorial-grid",
102    tileGridBlock: "tile-grid-block",
103    bentoTileGrid: "bento-tile-grid",
104    productHighlightBlock: "product-highlight-block",
105    testimonialBlock: "testimonial-block",
106    windowBanner: "window-banner",
107    appPromotionBanner: "app-promotion-banner",
108    breadcrumb: "breadcrumb",
109    loginPopup: "login-popup",
110    multiColumnTextBlock: "multi-column-text-block",
111    homepageBanner: "homepage-banner",
112    form: "form",
113    businessFormPanel: "business-vertical-form-panel",
114    joinNowGetApp: "thank-you-panel",
115    joinNowGetStartedBtn: "thank-you-panel",
116    JoinNowBackButton: "join-now-back-btn",
117  };
118
119  const trackType = {
120    pageLoad: "pageload",
121    click: "click-tracking",
122  };
123
124  // Helper methods for Page Informations
125  const getSectionLevels = () => {
126    const sections = getAdobePageValue().split(":");
127    return {
128      primarySection: sections[0] || "",
129      subSection1: sections[1] || "",
130      subSection2: sections.length > 2 ? sections.slice(2).join("/") : "",
131    };
132  };
133
134  const getSearchTerm = () => {
135    const url = new URL(window.location.href);
136    return url.pathname.includes("/search") && url.href.includes("#stq=")
137      ? url.href.split("=")[1]
138      : "";
139  };
140
141  const splitString = (value, delimiter) => {
142    let splitedParts = value.split(delimiter);
143    return splitedParts;
144  };
145
146  const pageNameCleanUp = (s_pagename) => {
147    s_pagename = s_pagename.replace(new RegExp(/content\:amp\:/g), " "); // remove content:amp prefix
148    s_pagename = s_pagename.replace(new RegExp(/-/g), " "); // replace dashes with spaces
149    s_pagename = s_pagename.replace(new RegExp(/_/g), " "); // replace underscores with spaces
150    s_pagename = s_pagename.replace(new RegExp(/\%20/g), " ");
150 // replace html spaces with spaces
151    s_pagename = s_pagename.replace(new RegExp(/\%26/g), "&"); // replace html ampersand with ampersand
152    s_pagename = s_pagename.replace(new RegExp(/\::/g), ":"); // replace double colon with a single colon
153    s_pagename = s_pagename.replace(new RegExp(/\.html/g), ""); // drop .html
154    s_pagename = s_pagename.replace(new RegExp(/\.htm/g), ""); // drop .htm
155    s_pagename = s_pagename.replace(new RegExp(/\.aspx/g), ""); // drop .aspx
156    s_pagename = s_pagename.replace(new RegExp(/\.php/g), ""); // drop .php
157
158    return s_pagename;
159  };
160
161  const getAdobePageValue = () => {
162    s_pagename = document.location.pathname; // capture the current pathname
163
164    // set pagename
165    s_pagename = s_pagename.replace(new RegExp(/\//g), ":"); // replace "/" with ":"
166    s_pagename = s_pagename.slice(1); // remove preceding ":" if required
167    if (s_pagename.slice(-1) == "/") {
168      // ends with "/"
169      s_pagename = s_pagename.slice(0, -1); // remove end "/"
170    }
171    s_pagename = s_pagename.toLowerCase(); // set to lowercase if required
172
173    if (s_pagename == "") {
174      s_pagename = "home"; // if it's the homepage default to "home"
175    }
176    if (document.getElementsByTagName("title")[0] != null) {
177      var title = document.getElementsByTagName("title")[0].innerHTML;
178      if (title && title.startsWith("500")) {
179        title = "500";
180        s_pagename = title + ":" + s_pagename;
181      }
182
183      if (title && title.startsWith("404")) {
184        title = "404";
185        s_pagename = title + ":" + s_pagename;
186      }
187    }
188
189    // clean pagename
190    if (s_pagename) s_pagename = pageNameCleanUp(s_pagename);
191
192    return s_pagename;
193  };
194
195  const getPreviousPage = () => {
196    const referrer = document.referrer;
197    if (!referrer) return "";
198    const path = new URL(referrer).pathname
199      .replace(/^\/|\/$/g, "")
200      .split("/")
201      .pop();
202    return path ? path.replace(/\.[^/.]+$/, "") : "home";
203  };
204
205  const getFormsName = () => {
206    let forms = document.querySelectorAll(selectors.form);
207    let formNames = "";
208    formNames = Array.from(forms)
209      .filter((form) => form.hasAttribute("name"))
210      .map((form) => form.getAttribute("name"))
211      .join(", ");
212
213    return formNames;
214  };
215
216  const getCalculatorName = () => {
217    return Array.from(document.querySelectorAll("[data-calculator-name]"))
218      .map((element) => element.getAttribute("data-calculator-name"))
219      .join(",");
220  };
221
222  const getPageData = () => ({
223    section: getSectionLevels(),
224    pageInfo: {
225      pageName: getAdobePageValue().split(":").pop(),
226      pageURL: window.location.href,
227      previousPage: getPreviousPage(),
228      referrerURL: document.referrer || "",
229      site: adobeDataLayerSiteData?.siteBrand || "",
230      formName: getFormsName(),
231      searchTerm: getSearchTerm(),
232      calculatorName: getCalculatorName(),
233      formSearch: "",
234    },
235  });
236
237  const getSiteData = () => ({
238    environment: adobeDataLayerSiteData?.environment || "",
239    siteBrand: adobeDataLayerSiteData?.siteBrand || "",
240    siteDomain: adobeDataLayerSiteData?.siteDomain || "",
241    deviceType: getDeviceType(),
242    browserType: getBrowser(),
243  });
244
245  const getUserData = () => ({
246    profile: {
247      userStatus: "",
248      userID: "",
249      ECID: _satellite?.getVisitorId()?._fields?.MCMID?.toString() || "",
250      ampEmployee: "",
251      returningUser: "",
252    },
253  });
254
255  const getAdobeData = () => ({
256    launch: {
257      propertyName: adobeDataLayerSiteData?.launchProperty || "",
258    },
259  });
260
261  const getBrowser = () => {
262    const { userAgent, vendor } = navigator;
263    if (/Edg/.test(userAgent)) return "Edge";
264    if (/Chrome/.test(userAgent) && /Google Inc/.test(vendor)) return "Chrome";
265    if (/Firefox/.test(userAgent)) return "Firefox";
266    if (/Safari/.test(userAgent) && /Apple Computer/.test(vendor))
267      return "Safari";
268    if (/OPR|Opera/.test(userAgent)) return "Opera";
269    if (/Trident/.test(userAgent)) return "Internet Explorer";
270    return "Unknown";
271  };
272
273  const getDeviceType = () =>
274    /Mobi|Android/i.test(navigator.userAgent)
275      ? "Mobile"
276      : /Tablet|iPad/i.test(navigator.userAgent)
277      ? "Tablet"
278      : "Desktop";
279
280  // Helper method for Transforming text
281  const transformText = (text) =>
282    text
283      ?.toLowerCase()
284      .replace(/\s+/g, " ")
285      .replace(/[\n\r]/g, "")
286      .replace(/ /g, "")
287      .trim() || "";
288
289  const track = () => {
290    // console.log("digital-interaction", JSON.stringify(digitalData.interaction));
291    if (_satellite) _satellite?.track(digitalData.event);
292  };
293
294  //Datalayer for Generic Page Load
295  window.addEventListener("load", async () => {
296    digitalData.event = trackType.pageLoad;
297    digitalData.page = getPageData();
298    digitalData.site = getSiteData();
299    digitalData.user = getUserData();
300    digitalData.adobe = getAdobeData();
301    // console.log("digital-page-info", JSON.stringify(digitalData));
302    track();
303  });
304
305  // <----------- click events ------------>
306  const getComponentName = (element) => {
307    let dataLayerValue = getDataLayerAttribute(element);
308    if (dataLayerValue) {
309      let parts = dataLayerValue["@type"]?.split("/") || "";
310      return parts[parts.length - 1];
311    } else {
312      return "text";
313    }
314  };
315
316  const isElementFromTextCmp = (element) => {
317    return (
318      (element.closest("p").length > 0 ||
319        element.closest("span").length > 0 ||
320        element.closest("li").length > 0) &&
321      !element.attr("class")
322    );
323  };
324
325  const getDataLayerAttribute = (element, isParent = true, isootb = false) => {
326    let dataLayerElement = isParent
327      ? element.closest(`[${selectors.dataCmpDataLayer}]`)
328      : element.is(`[${selectors.dataCmpDataLayer}]`)
329      ? element
330      : [];
331    if (dataLayerElement.length > 0) {
332      let dataLayerValue = JSON.parse(
333        dataLayerElement.attr(selectors.dataCmpDataLayer)
334      );
335      if (isootb) {
336        return dataLayerValue;
337      } else {
338        return Object.values(dataLayerValue)[0];
339      }
340    } else {
341      return null;
342    }
343  };
344
345  const getHeaderLinkData = (element) => {
346    let componentName = components.header;
347    let parentSpan = element
348      .closest("li")
349      .parent()
350      .closest("li")
351      .find("span:first");
352
353    let logo = element.find("img");
354    let linkText = "";
355    let title = "";
356
357    if (parentSpan.length > 0) {
358      linkText = `click-${
359        digitalData.page.pageInfo.pageName
360      }-${componentName}:${parentSpan.text()}:${transformText(
361        element.text().trim()
362      )}`;
363    } else if (logo.length > 0) {
364      linkText = `click-${
365        digitalData.page.pageInfo.pageName
366      }-${componentName}:${logo.attr("alt")}`;
367    } else if (element.attr("id") === selectors.searchBtn) {
368      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:search:open`;
369    } else if (element.attr("id") === selectors.searchCloseBtn) {
370      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:search:close`;
371    } else {
372      linkText = `click-${
373        digitalData.page.pageInfo.pageName
374      }-${componentName}:${transformText(element.text().trim())}`;
375    }
376
377    digitalData.interaction = {
378      linkText: linkText,
379      componentName: componentName,
380      linkClicked: element.attr("href") || "",
381      fileDownloaded: "",
382      videoName: "",
383      videoInteraction: "",
384    };
385  };
386
387  const getFooterLinkData = (element) => {
388    let componentName = components.footer;
389    let span = element.find("span");
390    let icon = element.find("i");
391    let img = element.find("img");
392    let linkText = "";
393    let title = "";
394
395    let dataLayerAttribute = getDataLayerAttribute(element);
396    if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
397      title = dataLayerAttribute["dc:title"] || "";
398    } else if (span.length > 0) {
399      title = transformText(span.text());
400    } else if (icon.length > 0) {
401      let iconClass = icon
402        .attr("class")
403        .split(" ")
404        .find((cls) => cls.startsWith("icon-"));
405
406      if (iconClass) {
407        title = iconClass.replace("icon-", "");
408      }
409    } else if (img.length > 0) {
410      title = img.attr("alt");
411    }
412
413    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${
414      title || ""
415    }`;
416
417    digitalData.interaction = {
418      linkText: linkText,
419      componentName: componentName,
420      linkClicked: element.attr("href") || "",
421      fileDownloaded: "",
422      videoName: "",
423      videoInteraction: "",
424    };
425  };
426
427  const isFileLink = (url) => {
428    if (url) {
429      let isPdf = url.endsWith(".pdf");
430      let isExcel =
431        url.endsWith(".xls") || url.endsWith(".xlsx") || url.endsWith(".csv");
432
433      return isPdf || isExcel;
434    } else {
435      return false;
436    }
437  };
438
439  const createFormBody = (form) => {
440    const piiPattern = /name|email|phone|mobile/i;
441    formDataObj = {};
442
443    const maskValue = (value) => {
444      if (value.includes("@")) {
445        const [local, domain] = value.split("@");
446        return local[0] + "****" + local.slice(-1) + "@" + domain;
447      } else if (!isNaN(value)) {
448        return value.slice(0, 2) + "****" + value.slice(-2);
449      } else {
450        return value[0] + "****" + value.slice(-1);
451      }
452    };
453
454    const getSelectedValue = (select) => {
455      let selectedValue = select.querySelector(".selected-value")?.textContent;
456      let fieldName =
457        $(element)
458          .closest(".cmp-dropdown")
459          .find(".cmp-form-item__headline")
460          .text()
461          .toLowerCase() || "";
462      return { name: fieldName, value: transformText(selectedValue) };
463    };
464
465    for (const element of form.elements) {
466      if (
467        (element.tagName === "INPUT" || element.tagName === "TEXTAREA") &&
468        element.name &&
469        element.type !== "hidden" &&
470        element.id !== "g-recaptcha-response" &&
471        !element.classList.contains("cmp-options__radio")
472      ) {
473        if (piiPattern.test(element.name)) {
474          formDataObj[element.name] = maskValue(element.value);
475        } else {
476          formDataObj[element.name] = element.value;
477        }
478      } else if (element.classList.contains("cmp-dropdown__toggle")) {
479        let selectedValue = getSelectedValue(element);
480        formDataObj[selectedValue.name] = selectedValue.value;
481      }
482    }
483
484    return formDataObj;
485  };
486
487  const getTextContentFromElements = (element) => {
488    return Array.from(element[0].childNodes).find((x) => x.nodeType === 3)
489      ?.textContent;
490  };
491
492  // capture components events
493  const getLinkData = (
494    element,
495    componentName = "",
496    getHeadlineFromDcTitle = false,
497    getLabelFromTitle = true
498  ) => {
499    if (!componentName) {
500      componentName = getComponentName(element);
501    }
502
503    let dataLayerAttribute = getDataLayerAttribute(element);
504    let textElement = element.find("span, p");
505
506    let fileDownloaded = "";
507    let linkText = "";
508    let title = "";
509    let img = element.find("img");
510    let componentTitle = "";
511    let linkClicked = "";
512
513    // if a tag is wrapper under p tag
514    if (isElementFromTextCmp(element)) {
515      title = getTextContentFromElements(element) || "";
516    } else {
517      if (
518        getLabelFromTitle &&
519        dataLayerAttribute &&
520        dataLayerAttribute["xdm:text"]
521      ) {
522        title = dataLayerAttribute["xdm:text"] || "";
523      } else if (
524        getLabelFromTitle &&
525        dataLayerAttribute &&
526        dataLayerAttribute["dc:title"]
527      ) {
528        title = dataLayerAttribute["dc:title"] || "";
529      } else if (textElement.length > 0) {
530        title = textElement.first().text() || "";
531      } else if (img.length > 0) {
532        title = img.attr("alt") || "";
533      } else {
534        title = element.text() || "";
535      }
536    }
537
538    if (componentName === components.sideModal) {
539      //is element is X close button
540      let closeEl = element.closest(selectors.sideModalCloseBtn);
541      if (closeEl.length > 0) {
542        title = "close";
543      }
544    }
545
546    title = transformText(title);
547
548    if (element.attr("download") !== undefined) {
549      fileDownloaded =
550        element.attr("download") !== ""
551          ? element.attr("download")
552          : element.attr("href");
553
554      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}:download`;
555    } else if (
556      getHeadlineFromDcTitle &&
557      dataLayerAttribute &&
558      dataLayerAttribute["dc:title"]
559    ) {
560      componentTitle = transformText(dataLayerAttribute["dc:title"] || "");
561      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}:${title}`;
562    } else {
563      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
564    }
565
566    if (componentTitle) {
567      componentName += `:${componentTitle}`;
568    }
569
570    linkClicked = element.attr("href") || "";
571    if (linkClicked === "/") {
572      linkClicked = window.location.origin;
573    }
574
575    digitalData.event = trackType.click;
576    digitalData.interaction = {
577      linkText: linkText,
578      componentName: componentName || "",
579      linkClicked: linkClicked,
580      fileDownloaded: fileDownloaded || "",
581      videoName: "",
582      videoInteraction: "",
583    };
584  };
585
586  const getAdaptiveBtnData = (element, componentName = "") => {
587    if (!componentName) {
588      componentName = getComponentName(element);
589    }
590
591    let dataLayerAttribute = getDataLayerAttribute(element);
592    let fileDownloaded = "";
593    let linkText = "";
594    let title = "";
595    let linkClicked = "";
596    let stacksession = sessionStorage.getItem("panelStack");
597    let stack = stacksession ? JSON.parse(stacksession) : [];
598    let isSuperSelected = stack.find((x) =>
599      x.selectedItem.toLowerCase().includes("amp super")
600    );
601
602    if (componentName === components.JoinNowBackButton) {
603      let topofStack = stack.length > 0 ? stack[stack.length - 1] : null;
604      if (topofStack) {
605        componentName = topofStack.panelName || "";
606      }
607    } else if (isSuperSelected) {
608      if (componentName === components.businessFormPanel) {
609        linkClicked = "";
610      }
611    } else {
612      linkClicked = sessionStorage.getItem("joinNowRedirectURL") || "";
613    }
614
615    // if a tag is wrapper under p tag
616    if (dataLayerAttribute && dataLayerAttribute["xdm:text"]) {
617      title = dataLayerAttribute["xdm:text"] || "";
618    } else if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
619      title = dataLayerAttribute["dc:title"] || "";
620    } else {
621      title = getTextContentFromElements(element) || "";
622    }
623
624    title = transformText(title);
625    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
626
627    digitalData.event = trackType.click;
628    digitalData.interaction = {
629      linkText: linkText,
630      componentName: componentName || "",
631      linkClicked: linkClicked,
632      fileDownloaded: fileDownloaded || "",
633      videoName: "",
634      videoInteraction: "",
635    };
636  };
637
638  const getAdaptivePanelName = (element) => {
639    let panel = element.closest('[data-cmp-is="adaptiveFormPanel"]');
640    if (panel.length > 0) {
641      return (panelName = panel.attr("data-panel-name"));
642    }
643    return "";
644  };
645
646  const getAdaptiveRadioBtnData = (element, panelName = "") => {
647    if (!panelName) {
648      panelName = getAdaptivePanelName(element);
649    }
650    let dataLayerElement = element.closest(`[${selectors.dataCmpDataLayer}]`);
651
652    let dataLayerAttribute = JSON.parse(
653      dataLayerElement.attr(selectors.dataCmpDataLayer)
654    );
655
656    let fileDownloaded = "";
657    let linkText = "";
658    let title = "";
659    let linkClicked = "";
660    if (
661      dataLayerAttribute &&
662      dataLayerAttribute["enum"] &&
663      dataLayerAttribute["enumNames"]
664    ) {
665      title = element.attr("value") || "";
666    }
667
668    title = transformText(title).replaceAll("_", " ");
669    linkText = `click-${digitalData.page.pageInfo.pageName}-${panelName}:${title}`;
670
671    if (element.attr("data-attr-name") === selectors.superContinueWebRadioBtn) {
672      linkClicked = sessionStorage.getItem("joinNowRedirectURL") || "";
673    }
674
675    digitalData.event = trackType.click;
676    digitalData.interaction = {
677      linkText: linkText,
678      componentName: panelName || "",
679      linkClicked: linkClicked,
680      fileDownloaded: fileDownloaded || "",
681      videoName: "",
682      videoInteraction: "",
683    };
684  };
685
686  const getFormData = (element) => {
687    componentName =
688      element.closest("form").attr("name") ??
689      element.closest("form").attr("id");
690    let dataLayerAttribute = getDataLayerAttribute(element);
691    let textElement = element.find("span, p");
692    let linkText = "";
693    let title = "";
694    let formDataObj = {};
695
696    // if a tag is wrapper under p tag
697    if (isElementFromTextCmp(element)) {
698      title = getTextContentFromElements(element) || "";
699    } else {
700      if (dataLayerAttribute && dataLayerAttribute["xdm:text"]) {
701        title = dataLayerAttribute["xdm:text"] || "";
702      } else if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
703        title = dataLayerAttribute["dc:title"] || "";
704      } else if (textElement.length > 0) {
705        title = textElement.first().text() || "";
706      } else {
707        title = getTextContentFromElements(element) || "";
708      }
709    }
710
711    title = transformText(title);
712    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
713
714    let formEl = element.closest(selectors.form);
715    if (formEl.length > 0) {
716      // Commented for now - As data already passed through AEP
717      // formDataObj = createFormBody(formEl[0]);
718    }
719
720    digitalData.event = trackType.click;
721    digitalData.interaction = {
722      linkText: linkText,
723      componentName: componentName || "",
724      linkClicked: element.attr("href") || "",
725      fileDownloaded: "",
726      videoName: "",
727      videoInteraction: "",
728    };
729
730    digitalData.interaction = Object.assign(
731      {},
732      digitalData.interaction,
733      formDataObj
734    );
735  };
736
737  const getHomePageBannerData = (
738    element,
739    getHeadlineFromDcTitle = false,
740    getLabelFromTitle = true
741  ) => {
742    componentName = components.homepageBanner;
743
744    let dataLayerAttribute = getDataLayerAttribute(element);
745    let textElement = element.find("span, p");
746
747    let fileDownloaded = "";
748    let linkText = "";
749    let title = "";
750    let img = element.find("img");
751    let componentHeadline = "";
752    let componentTitle = "";
753    let selectedTab = "";
754
755    if (element.hasClass("swiper-previous")) {
756      title = "previous";
757    } else if (element.hasClass("swiper-next")) {
758      title = "next";
759    } else {
760      if (
761        getLabelFromTitle &&
762        dataLayerAttribute &&
763        dataLayerAttribute["xdm:text"]
764      ) {
765        title = dataLayerAttribute["xdm:text"] || "";
766      } else if (
767        getLabelFromTitle &&
768        dataLayerAttribute &&
769        dataLayerAttribute["dc:title"]
770      ) {
771        title = dataLayerAttribute["dc:title"] || "";
772      } else if (textElement.length > 0) {
773        title = textElement.first().text() || "";
774      } else if (img.length > 0) {
775        title = img.attr("alt") || "";
776      } else {
777        title = element.text() || "";
778      }
779    }
780
781    title = transformText(title);
782
783    if (getHeadlineFromDcTitle) {
784      let attr = element
785        .closest(selectors.homepageBanner)
786        .find(`[${selectors.dataCmpDataLayer}]`);
787      if (attr.length > 0) {
788        let dataLayerValue = JSON.parse(attr.attr(selectors.dataCmpDataLayer));
789        componentHeadline = transformText(
790          Object.values(dataLayerValue)[0]["dc:title"]
791        );
792      }
793
794      let wayfindingBlock = element.closest(selectors.wayfindingBlock);
795      if (wayfindingBlock.length > 0) {
796        let wayfindingBlockEl = wayfindingBlock.closest(
797          `[${selectors.dataCmpDataLayer}]`
798        );
799
800        let wayfindingBlockAttributes =
801          getDataLayerAttribute(wayfindingBlockEl);
802        componentTitle = wayfindingBlockAttributes["dc:title"];
803      } else {
804        let component = element.closest(selectors.homepageBanner);
805        selectedTab = Array.from(component.find(selectors.ootbTab))
806          .filter((e) => e.getAttribute("aria-selected") === "true")
807          .map((el) => el.getAttribute("data-tab-title"))
808          .join("");
809
810        if (element.closest(selectors.ootbTab).length > 0) {
811          title = selectedTab;
812        } else {
813          title = `${selectedTab}:${title}`;
814        }
815      }
816
817      if (componentTitle) {
818        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentHeadline}:${componentTitle}:${title}`;
819      } else {
820        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentHeadline}:${title}`;
821      }
822    } else {
823      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
824    }
825
826    if (componentHeadline) {
827      componentName += `:${componentHeadline}`;
828    }
829
830    digitalData.event = trackType.click;
831    digitalData.interaction = {
832      linkText: linkText,
833      componentName: componentName || "",
834      linkClicked: element.attr("href") || "",
835      fileDownloaded: fileDownloaded || "",
836      videoName: "",
837      videoInteraction: "",
838    };
839  };
840
841  const getBentoGridData = (
842    element,
843    componentName = "",
844    getHeadlineFromDcTitle = false,
845    getLabelFromTitle = true
846  ) => {
847    if (!componentName) {
848      componentName = getComponentName(element);
849    }
850
851    let dataLayerAttribute = getDataLayerAttribute(element);
852    let textElement = element.find("span, p");
853
854    let fileDownloaded = "";
855    let linkText = "";
856    let title = "";
857    let img = element.find("img");
858    let componentTitle = "";
859
860    // if a tag is wrapper under p tag
861    if (
862      getLabelFromTitle &&
863      dataLayerAttribute &&
864      dataLayerAttribute["dc:title"]
865    ) {
866      title = dataLayerAttribute["dc:title"] || "";
867    } else if (textElement.length > 0) {
868      title = textElement.first().text() || "";
869    } else if (img.length > 0) {
870      title = img.attr("alt") || "";
871    } else {
872      title = element.text() || "";
873    }
874
875    title = transformText(title);
876
877    componentTitle = transformText(dataLayerAttribute["dc:title"] || "");
878    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
879
880    if (componentTitle) {
881      componentName += `:${componentTitle}`;
882    }
883
884    digitalData.event = trackType.click;
885    digitalData.interaction = {
886      linkText: linkText,
887      componentName: componentName || "",
888      linkClicked: element.attr("href") || "",
889      fileDownloaded: fileDownloaded || "",
890      videoName: "",
891      videoInteraction: "",
892    };
893  };
894
895  const getCTABannerData = (
896    element,
897    componentName = "",
898    getHeadlineFromDcTitle = false,
899    getLabelFromTitle = true
900  ) => {
901    if (!componentName) {
902      componentName = getComponentName(element);
903    }
904
905    let dataLayerAttribute = getDataLayerAttribute(element);
906    let textElement = element.find("span, p");
907
908    let fileDownloaded = "";
909    let linkText = "";
910    let title = ":";
911    let img = element.find("img");
912    let componentTitle = "";
913
914    // if a tag is wrapper under p tag
915    if (isElementFromTextCmp(element)) {
916      title += getTextContentFromElements(element) || "";
917    } else {
918      if (
919        getLabelFromTitle &&
920        dataLayerAttribute &&
921        dataLayerAttribute["xdm:text"]
922      ) {
923        title += dataLayerAttribute["xdm:text"] || "";
924      } else if (
925        getLabelFromTitle &&
926        dataLayerAttribute &&
927        dataLayerAttribute["dc:title"]
928      ) {
929        title += dataLayerAttribute["dc:title"] || "";
930      } else if (textElement.length > 0) {
931        title += textElement.first().text() || "";
932      } else if (img.length > 0) {
933        title += img.attr("alt") || "";
934      } else {
935        title += element.text() || "";
936      }
937    }
938
939    title += transformText(title);
940
941    if (element.hasClass("cta-headline")) {
942      title = "";
943    }
944
945    if (element.attr("download") !== undefined) {
946      fileDownloaded =
947        element.attr("download") !== ""
948          ? element.attr("download")
949          : element.attr("href");
950
951      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}:download`;
952    } else if (
953      getHeadlineFromDcTitle &&
954      dataLayerAttribute &&
955      dataLayerAttribute["dc:title"]
956    ) {
957      componentTitle = transformText(dataLayerAttribute["dc:title"] || "");
958      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}`;
959    } else {
960      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}`;
961    }
962
963    if (componentTitle) {
964      componentName += `:${componentTitle}`;
965    }
966
967    digitalData.event = trackType.click;
968    digitalData.interaction = {
969      linkText: linkText,
970      componentName: componentName || "",
971      linkClicked: element.attr("href") || "",
972      fileDownloaded: fileDownloaded || "",
973      videoName: "",
974      videoInteraction: "",
975    };
976  };
977
978  const getEditorialGridData = (
979    element,
980    componentName = "",
981    getHeadlineFromDcTitle = false,
982    getLabelFromTitle = true
983  ) => {
984    if (!componentName) {
985      componentName = getComponentName(element);
986    }
987
988    let dataLayerAttribute = getDataLayerAttribute(element);
989    let textElement = element.find("span, p");
990
991    let fileDownloaded = "";
992    let linkText = "";
993    let title = "";
994    let img = element.find("img");
995    let componentTitle = "";
996
997    // if a tag is wrapper under p tag
998    if (isElementFromTextCmp(element)) {
999      title = getTextContentFromElements(element) || "";
1000    } else {
1001      if (
1002        getLabelFromTitle &&
1003        dataLayerAttribute &&
1004        dataLayerAttribute["xdm:text"]
1005      ) {
1006        title = dataLayerAttribute["xdm:text"] || "";
1007      } else if (
1008        getLabelFromTitle &&
1009        dataLayerAttribute &&
1010        dataLayerAttribute["dc:title"]
1011      ) {
1012        title = dataLayerAttribute["dc:title"] || "";
1013      } else if (textElement.length > 0) {
1014        title = textElement.first().text() || "";
1015      } else if (img.length > 0) {
1016        title = img.attr("alt") || "";
1017      } else {
1018        title = element.text() || "";
1019      }
1020    }
1021
1022    if (componentName === components.sideModal) {
1023      //is element is X close button
1024      let closeEl = element.closest(selectors.sideModalCloseBtn);
1025      if (closeEl.length > 0) {
1026        title = "close";
1027      }
1028    }
1029
1030    title = transformText(title);
1031
1032    isGridLinks = () => {
1033      let desktopEl =
1034        element.closest(".editorial-grid__tile--desktop").length > 0;
1035      let mobileEl =
1036        element.closest(".editorial-grid__tile--mobile").length > 0;
1037      return desktopEl || mobileEl;
1038    };
1039
1040    if (element.attr("download") !== undefined) {
1041      fileDownloaded =
1042        element.attr("download") !== ""
1043          ? element.attr("download")
1044          : element.attr("href");
1045
1046      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}:download`;
1047    } else if (getHeadlineFromDcTitle && isGridLinks()) {
1048      let parentElement = element
1049        .closest(`[${selectors.dataCmpDataLayer}]`)
1050        .parent()
1051        .closest(`[${selectors.dataCmpDataLayer}]`);
1052
1053      if (parentElement.length > 0) {
1054        let parentDataLayerAttribute = getDataLayerAttribute(parentElement);
1055
1056        if (parentDataLayerAttribute)
1057          componentTitle = transformText(
1058            parentDataLayerAttribute["dc:title"] || ""
1059          );
1060      }
1061      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}:${title}`;
1062    } else if (
1063      getHeadlineFromDcTitle &&
1064      dataLayerAttribute &&
1065      dataLayerAttribute["dc:title"]
1066    ) {
1067      componentTitle = transformText(dataLayerAttribute["dc:title"] || "");
1068      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}:${title}`;
1069    } else {
1070      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
1071    }
1072
1073    if (componentTitle) {
1074      componentName += `:${componentTitle}`;
1075    }
1076
1077    digitalData.event = trackType.click;
1078    digitalData.interaction = {
1079      linkText: linkText,
1080      componentName: componentName || "",
1081      linkClicked: element.attr("href") || "",
1082      fileDownloaded: fileDownloaded || "",
1083      videoName: "",
1084      videoInteraction: "",
1085    };
1086  };
1087
1088  const getProductHighlightBlockData = (
1089    element,
1090    componentName = components.productHighlightBlock,
1091    getHeadlineFromDcTitle = false
1092  ) => {
1093    if (!componentName) {
1094      componentName = getComponentName(element);
1095    }
1096
1097    let dataLayerAttribute = getDataLayerAttribute(element);
1098    let textElement = element.find("span, p");
1099    let fileDownloaded = "";
1100    let linkText = "";
1101    let title = ":";
1102    let img = element.find("img");
1103    let componentTitle = "";
1104    let parentTitle = "";
1105
1106    let topLevelDataLayerEl = element
1107      .closest(selectors.productHighlightBlock)
1108      .find(`[${selectors.dataCmpDataLayer}]`);
1109
1110    if (topLevelDataLayerEl.length > 0) {
1111      let topLevelDataLayer = getDataLayerAttribute(topLevelDataLayerEl);
1112      if (topLevelDataLayer && topLevelDataLayer["dc:title"]) {
1113        parentTitle = transformText(topLevelDataLayer["dc:title"]);
1114      }
1115    }
1116
1117    if (getHeadlineFromDcTitle) {
1118      let parentElement;
1119      if (isElementFromTextCmp(element)) {
1120        parentElement = element.closest(`[${selectors.dataCmpDataLayer}]`);
1121      } else {
1122        parentElement = element
1123          .closest(`[${selectors.dataCmpDataLayer}]`)
1124          .parent()
1125          .closest(`[${selectors.dataCmpDataLayer}]`);
1126      }
1127      if (
1128        parentElement.length > 0 &&
1129        topLevelDataLayerEl[0] !== parentElement[0]
1130      ) {
1131        let attribute = getDataLayerAttribute(parentElement);
1132        if (attribute && attribute["dc:title"])
1133          if (parentTitle) {
1134            componentTitle =
1135              parentTitle + ":" + transformText(attribute["dc:title"]);
1136          } else {
1137            componentTitle = transformText(attribute["dc:title"]);
1138          }
1139      } else {
1140        componentTitle = parentTitle;
1141      }
1142    }
1143
1144    if (isElementFromTextCmp(element)) {
1145      title += transformText(getTextContentFromElements(element)) || "";
1146    } else {
1147      if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1148        title += dataLayerAttribute["dc:title"] || "";
1149      } else if (textElement.length > 0) {
1150        title += transformText(textElement.first().text()) || "";
1151      } else if (img.length > 0) {
1152        title += img.attr("alt") || "";
1153      } else {
1154        title += transformText(element.text()) || "";
1155      }
1156    }
1157
1158    if (
1159      element.attr("download") !== undefined ||
1160      isFileLink(element.attr("href"))
1161    ) {
1162      fileDownloaded = !element.attr("download")
1163        ? element.attr("href")
1164        : element.attr("download");
1165      if (componentTitle) {
1166        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}:download`;
1167      } else {
1168        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}:download`;
1169      }
1170    } else if (getHeadlineFromDcTitle && componentTitle) {
1171      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}`;
1172    } else {
1173      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}`;
1174    }
1175
1176    if (componentTitle) {
1177      componentName += `:${componentTitle}`;
1178    }
1179
1180    digitalData.event = trackType.click;
1181    digitalData.interaction = {
1182      linkText: linkText,
1183      componentName: componentName || "",
1184      linkClicked: element.attr("href") || "",
1185      fileDownloaded: fileDownloaded || "",
1186      videoName: "",
1187      videoInteraction: "",
1188    };
1189  };
1190
1191  const getBlockComponentsData = (
1192    element,
1193    componentName = "",
1194    getHeadlineFromDcTitle = false
1195  ) => {
1196    if (!componentName) {
1197      componentName = getComponentName(element);
1198    }
1199
1200    let dataLayerAttribute = getDataLayerAttribute(element);
1201    let textElement = element.find("span, p");
1202
1203    let fileDownloaded = "";
1204    let linkText = "";
1205    let title = ":";
1206    let img = element.find("img");
1207    let componentTitle = "";
1208
1209    if (getHeadlineFromDcTitle) {
1210      let parentElement;
1211      if (isElementFromTextCmp(element)) {
1212        parentElement = element.closest(`[${selectors.dataCmpDataLayer}]`);
1213      } else {
1214        parentElement = element
1215          .closest(`[${selectors.dataCmpDataLayer}]`)
1216          .parent()
1217          .closest(`[${selectors.dataCmpDataLayer}]`);
1218      }
1219      if (parentElement.length > 0) {
1220        let attribute = getDataLayerAttribute(parentElement);
1221        if (attribute && attribute["dc:title"])
1222          componentTitle = transformText(attribute["dc:title"]) || "";
1223      }
1224    }
1225
1226    if (isElementFromTextCmp(element)) {
1227      title += transformText(getTextContentFromElements(element)) || "";
1228    } else {
1229      if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1230        title += dataLayerAttribute["dc:title"] || "";
1231      } else if (textElement.length > 0) {
1232        title += transformText(textElement.first().text()) || "";
1233      } else if (img.length > 0) {
1234        title += img.attr("alt") || "";
1235      } else {
1236        title += transformText(element.text()) || "";
1237      }
1238    }
1239
1240    if (
1241      componentName === components.pageCollectionBlock &&
1242      element.closest(".amp-btn-secondary").length === 0
1243    ) {
1244      // read tab tile if available
1245      let activeButton = element
1246        .closest(selectors.pageCollectionBlock)
1247        .find(".cmp-tag__container button.--tab-active");
1248      let tab = activeButton.closest(".cmp-tag__container.width-max");
1249
1250      if (tab.length > 0) {
1251        let tabDataLayerAttribute = getDataLayerAttribute(tab);
1252        componentTitle += `:${tabDataLayerAttribute["dc:title"]}`;
1253      }
1254
1255      if (element.closest(".cmp-tag__container").length > 0) {
1256        title = "";
1257      }
1258    }
1259
1260    if (
1261      element.attr("download") !== undefined ||
1262      isFileLink(element.attr("href"))
1263    ) {
1264      fileDownloaded = !element.attr("download")
1265        ? element.attr("href")
1266        : element.attr("download");
1267      if (componentTitle) {
1268        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}:download`;
1269      } else {
1270        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}:download`;
1271      }
1272    } else if (getHeadlineFromDcTitle && componentTitle) {
1273      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}`;
1274    } else {
1275      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}`;
1276    }
1277
1278    if (componentTitle) {
1279      componentName += `:${componentTitle}`;
1280    }
1281
1282    digitalData.event = trackType.click;
1283    digitalData.interaction = {
1284      linkText: linkText,
1285      componentName: componentName || "",
1286      linkClicked: element.attr("href") || "",
1287      fileDownloaded: fileDownloaded || "",
1288      videoName: "",
1289      videoInteraction: "",
1290    };
1291  };
1292
1293  const getTileGridData = (
1294    element,
1295    componentName = "",
1296    getHeadlineFromDcTitle = false
1297  ) => {
1298    if (!componentName) {
1299      componentName = getComponentName(element);
1300    }
1301
1302    let dataLayerAttribute = getDataLayerAttribute(element);
1303    let textElement = element.find("span, p");
1304
1305    let fileDownloaded = "";
1306    let linkText = "";
1307    let title = ":";
1308    let img = element.find("img");
1309    let componentTitle = "";
1310    let isElementFromRTE =
1311      (element.closest("p").length > 0 || element.closest("span").length > 0) &&
1312      !element.attr("class");
1313
1314    if (getHeadlineFromDcTitle) {
1315      let attr = element
1316        .closest(selectors.tileGridBlock)
1317        .find(`[${selectors.dataCmpDataLayer}]`);
1318      if (attr.length > 0) {
1319        let dataLayerValue = JSON.parse(attr.attr(selectors.dataCmpDataLayer));
1320        componentTitle = transformText(
1321          Object.values(dataLayerValue)[0]["dc:title"]
1322        );
1323      }
1324    }
1325
1326    if (isElementFromRTE) {
1327      title += transformText(element.text()) || "";
1328    } else {
1329      if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1330        title += dataLayerAttribute["dc:title"] || "";
1331      } else if (textElement.length > 0) {
1332        title += transformText(textElement.first().text()) || "";
1333      } else if (img.length > 0) {
1334        title += img.attr("alt") || "";
1335      } else {
1336        title += transformText(element.text()) || "";
1337      }
1338    }
1339
1340    if (
1341      element.attr("download") !== undefined ||
1342      isFileLink(element.attr("href"))
1343    ) {
1344      fileDownloaded = !element.attr("download")
1345        ? element.attr("href")
1346        : element.attr("download");
1347      if (componentTitle) {
1348        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}:download`;
1349      } else {
1350        linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}:download`;
1351      }
1352    } else if (getHeadlineFromDcTitle && componentTitle) {
1353      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${componentTitle}${title}`;
1354    } else {
1355      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}${title}`;
1356    }
1357
1358    if (componentTitle) {
1359      componentName += `:${componentTitle}`;
1360    }
1361
1362    digitalData.event = trackType.click;
1363    digitalData.interaction = {
1364      linkText: linkText,
1365      componentName: componentName || "",
1366      linkClicked: element.attr("href") || "",
1367      fileDownloaded: fileDownloaded || "",
1368      videoName: "",
1369      videoInteraction: "",
1370    };
1371  };
1372
1373  const getProductCardData = (
1374    element,
1375    componentName = "",
1376    isPopupTriggered = false,
1377    isBlock = false
1378  ) => {
1379    if (!componentName) {
1380      componentName = getComponentName(element);
1381    }
1382
1383    let dataLayerAttribute = getDataLayerAttribute(element);
1384
1385    let elementDataLayerAttribute = getDataLayerAttribute(element, false);
1386
1387    let linkText = "";
1388    let title = "";
1389    let componentTitle = "";
1390
1391    //reading the link/button text
1392    if (element.closest(".cmp-product-card__header__top").length > 0) {
1393      let urlParts = splitString(element.attr("href"), "/");
1394      title = urlParts[urlParts.length - 1] || "";
1395      title = pageNameCleanUp(title);
1396    } else if (
1397      elementDataLayerAttribute &&
1398      elementDataLayerAttribute["xdm:text"]
1399    ) {
1400      title = elementDataLayerAttribute["xdm:text"] || "";
1401    } else if (element.is("button") || element.is("a")) {
1402      title =
1403        element.attr("data-cta-label") ||
1404        element.contents().text().trim() ||
1405        "";
1406    } else {
1407      title = element.contents().text().trim();
1408    }
1409
1410    //read block component header title
1411    if (isBlock) {
1412      let parentElement = element
1413        .closest(selectors.productCards)
1414        .parent()
1415        .closest(`[${selectors.dataCmpDataLayer}]`);
1416
1417      if (parentElement.length > 0) {
1418        let parentDataLayerAttribute = getDataLayerAttribute(parentElement);
1419        if (parentDataLayerAttribute["dc:title"])
1420          componentTitle =
1421            transformText(parentDataLayerAttribute["dc:title"]) || "";
1422        if (componentTitle) {
1423          componentName += `:${componentTitle}`;
1424        }
1425      }
1426    }
1427
1428    if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1429      componentTitle = transformText(dataLayerAttribute["dc:title"]) || "";
1430      linkText = `click-${
1431        digitalData.page.pageInfo.pageName
1432      }-${componentName}:${componentTitle}:${transformText(title)}`;
1433    } else {
1434      linkText = `click-${
1435        digitalData.page.pageInfo.pageName
1436      }-${componentName}:${transformText(title)}`;
1437    }
1438
1439    if (isPopupTriggered) {
1440      let isOpen = element.attr("aria-describedby")?.length > 0;
1441      linkText += `:${isOpen ? "open" : "close"}`;
1442    }
1443
1444    if (componentTitle) {
1445      componentName += `:${componentTitle}`;
1446    }
1447
1448    if (element.closest(".cmp-product-card__toogle-show").length > 0) {
1449      let showLess = element.find(".toogle-show.--more.--none");
1450      linkText += showLess.length > 0 ? ":open" : ":close";
1451    }
1452
1453    digitalData.event = trackType.click;
1454    digitalData.interaction = {
1455      linkText: linkText,
1456      componentName: componentName || "",
1457      linkClicked: element.attr("href") || "",
1458      fileDownloaded: "",
1459      videoName: "",
1460      videoInteraction: "",
1461    };
1462  };
1463
1464  const getSocialShareData = (element) => {
1465    componentName = components.socialShare;
1466    let li = element.find("li");
1467
1468    digitalData.event = trackType.click;
1469    let linkText = "";
1470
1471    if (li.length > 0) {
1472      let socialMediaType = li.attr("data-social-media");
1473      linkText = `click-${
1474        digitalData.page.pageInfo.pageName
1475      }-${componentName}:${transformText(socialMediaType)}`;
1476    }
1477
1478    digitalData.interaction = {
1479      linkText: linkText,
1480      linkClicked: element.attr("href") || "",
1481      componentName: componentName,
1482      fileDownloaded: "",
1483      videoName: "",
1484      videoInteraction: "",
1485    };
1486  };
1487
1488  const getTwoColContainerData = (element) => {
1489    componentName = components.twoColContainer;
1490    let span = element.find("span");
1491    let img = element.find("img");
1492    let dataLayerAttribute = getDataLayerAttribute(element);
1493    digitalData.event = trackType.click;
1494    let linkText = "";
1495    let title = "";
1496    let componentTitle = "";
1497    if (isElementFromTextCmp(element)) {
1498      title = getTextContentFromElements(element) || "";
1499    } else {
1500      if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1501        title = dataLayerAttribute["dc:title"] || "";
1502      } else if (span.length > 0) {
1503        title = transformText(span.first().text()) || "";
1504      } else if (img.length > 0) {
1505        title = transformText(img.attr("alt")) || "";
1506      }
1507    }
1508
1509    let parentElement = element
1510      .closest(selectors.twoColContainer)
1511      .find(`[${selectors.dataCmpDataLayer}]`);
1512    if (parentElement.length > 0) {
1513      let parentDataLayerAttribute = getDataLayerAttribute(parentElement);
1514      if (parentDataLayerAttribute["dc:title"]) {
1515        componentTitle = transformText(parentDataLayerAttribute["dc:title"]);
1516        if (componentTitle) {
1517          componentName = `${getComponentName(
1518            parentElement
1519          )}:${componentTitle}`;
1520        }
1521      }
1522    }
1523
1524    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
1525
1526    digitalData.interaction = {
1527      linkText: linkText,
1528      linkClicked: element.attr("href") || "",
1529      componentName: componentName,
1530      videoName: "",
1531      videoInteraction: "",
1532      fileDownloaded: "",
1533    };
1534  };
1535
1536  const getOotbComponentData = (element, componentName = "") => {
1537    let span = element.find("span");
1538    let img = element.find("img");
1539    let dataLayerAttribute = getDataLayerAttribute(element);
1540    digitalData.event = trackType.click;
1541    let linkText = "";
1542    let title = "";
1543    let componentTitle = "";
1544    if (!componentName) {
1545      componentName = getComponentName(element);
1546    }
1547
1548    if (isElementFromTextCmp(element)) {
1549      title = getTextContentFromElements(element);
1550    } else {
1551      if (
1552        dataLayerAttribute &&
1553        (dataLayerAttribute["dc:title"] || dataLayerAttribute["xdm:text"])
1554      ) {
1555        title =
1556          dataLayerAttribute["xdm:text"] ||
1557          dataLayerAttribute["dc:title"] ||
1558          "";
1559      } else if (span.length > 0) {
1560        title = transformText(span.first().text()) || "";
1561      } else if (img.length > 0) {
1562        title = transformText(img.attr("alt")) || "";
1563      }
1564    }
1565
1566    let parentElement = element
1567      .closest(`[${selectors.dataCmpDataLayer}]`)
1568      .parent()
1569      .closest(`[${selectors.dataCmpDataLayer}]`);
1570    if (parentElement.length > 0) {
1571      let parentDataLayerAttribute = getDataLayerAttribute(parentElement, true);
1572      if (parentDataLayerAttribute["dc:title"])
1573        componentTitle =
1574          transformText(parentDataLayerAttribute["dc:title"]) || "";
1575      if (componentTitle) {
1576        componentName = `${getComponentName(parentElement)}:${componentTitle}`;
1577      }
1578    }
1579
1580    linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
1581
1582    digitalData.interaction = {
1583      linkText: linkText,
1584      linkClicked: element.attr("href") || "",
1585      componentName: componentName,
1586      videoName: "",
1587      videoInteraction: "",
1588      fileDownloaded: "",
1589    };
1590  };
1591
1592  const getAccordionData = (element) => {
1593    let componentName = components.accordion;
1594    let span = element.find("span");
1595    let dataLayerAttribute = getDataLayerAttribute(element);
1596    digitalData.event = trackType.click;
1597    digitalData.interaction = {
1598      videoName: "",
1599      videoInteraction: "",
1600      fileDownloaded: "",
1601      linkText: "",
1602      linkClicked: "",
1603      componentName: "",
1604    };
1605
1606    let title = "";
1607    if (dataLayerAttribute && dataLayerAttribute["dc:title"]) {
1608      title = dataLayerAttribute["dc:title"] || "";
1609    } else {
1610      title = span.text();
1611    }
1612
1613    // has parent component
1614    let parentElement = element
1615      .closest(selectors.accordion)
1616      .parent()
1617      .closest(`[${selectors.dataCmpDataLayer}]`);
1618    if (parentElement.length > 0) {
1619      let parentDataLayerAttribute = getDataLayerAttribute(parentElement);
1620      if (parentDataLayerAttribute["dc:title"])
1621        componentTitle =
1622          transformText(parentDataLayerAttribute["dc:title"]) || "";
1623      if (componentTitle) {
1624        componentName = `${getComponentName(
1625          parentElement
1626        )}:${componentTitle}:${componentName}`;
1627      } else {
1628        componentName = `${getComponentName(parentElement)}:${componentName}`;
1629      }
1630    }
1631
1632    digitalData.interaction.linkText = `click-${
1633      digitalData.page.pageInfo.pageName
1634    }-${componentName}:${transformText(title)}:${
1635      element.attr("aria-expanded") === "false" ? "open" : "close"
1636    }`;
1637
1638    digitalData.interaction.componentName = componentName;
1639  };
1640
1641  // for video components click events
1642  const getVideoData = (element) => {
1643    isPaused = element[0].paused;
1644    let dataLayerValue = getDataLayerAttribute(element);
1645    let componentName = getComponentName(element);
1646    let title = "";
1647
1648    if (dataLayerValue) title = transformText(dataLayerValue["dc:title"]) || "";
1649
1650    digitalData.event = trackType.click;
1651    digitalData.interaction = {
1652      linkText: `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}:videoComponent`,
1653      componentName: componentName || "",
1654      linkClicked: dataLayerValue["videoUrl"],
1655      videoName: dataLayerValue["videoUrl"],
1656      videoInteraction: isPaused ? "play" : "pause",
1657      fileDownloaded: "",
1658    };
1659
1660    track();
1661  };
1662
1663  // for notifications
1664  const getNotifcationsData = (element) => {
1665    let componentName = components.notifications;
1666    let aemNotification = $(selectors.notifications);
1667    let notificationTitle = aemNotification.find(
1668      ".amp-notifications__item-content-text__title"
1669    );
1670    let span = element.find("span");
1671
1672    if (notificationTitle.length > 0) {
1673      componentName += `:${transformText(notificationTitle.text())}`;
1674    }
1675    digitalData.event = trackType.click;
1676    digitalData.interaction = {
1677      videoName: "",
1678      videoInteraction: "",
1679      fileDownloaded: "",
1680      linkText: "",
1681      linkClicked: "",
1682      componentName: componentName,
1683    };
1684
1685    if (element.is("i.icon-close")) {
1686      digitalData.interaction.linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:close`;
1687    } else if (element.is("li.amp-notifications__carousel-dots--dot")) {
1688      digitalData.interaction.linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:panComponent`;
1689    } else if (element.is("button,a") && span.length > 0) {
1690      digitalData.interaction.linkText = `click-${
1691        digitalData.page.pageInfo.pageName
1692      }-${componentName}:${transformText(span.first().text()) || ""}`;
1693    }
1694
1695    if (element.attr("href")) {
1696      digitalData.interaction.linkClicked = element.attr("href");
1697    }
1698
1699    track();
1700  };
1701
1702  const getLoginPopupData = (
1703    element,
1704    componentName = "",
1705    getHeadlineFromDcTitle = false,
1706    getLabelFromTitle = true
1707  ) => {
1708    if (!componentName) {
1709      componentName = getComponentName(element);
1710    }
1711
1712    let dataLayerAttribute = getDataLayerAttribute(element);
1713    let textElement = element.find("span, p");
1714
1715    let fileDownloaded = "";
1716    let linkText = "";
1717    let title = "";
1718    let img = element.find("img");
1719    let componentTitle = "";
1720    let closeEl = element.closest(selectors.sideModalCloseBtn);
1721    let selectedTabTitle = "";
1722
1723    let component = element.closest(selectors.loginPopup);
1724    if (component.length > 0) {
1725      let tabs = component.find(".login-modal__content--tab-button");
1726      if (tabs.length > 0) {
1727        const activeTab = Array.from(tabs).filter((tab) =>
1728          tab.classList.contains("active")
1729        );
1730        // Check if an active tab exists
1731        if (activeTab.length > 0) {
1732          selectedTabTitle = activeTab
1733            .map((tab) => {
1734              const compAttr = getDataLayerAttribute($(tab));
1735
1736              const inActiveTabs = Array.from(tabs)
1737                .filter((tab) => !tab.classList.contains("active"))
1738                .map((tab) => getDataLayerAttribute($(tab))["dc:title"])
1739                .join("");
1740
1741              return inActiveTabs &&
1742                element.closest(".login-modal__content--tab-button").length > 0
1743                ? `${inActiveTabs}:${compAttr["dc:title"]}`
1744                : `${compAttr["dc:title"]}`;
1745            })
1746            .join("");
1747        }
1748      }
1749    }
1750
1751    // if a tag is wrapper under p tag
1752    //is element is X close button
1753    if (closeEl.length > 0) {
1754      title = "close";
1755    } else if (isElementFromTextCmp(element)) {
1756      title = getTextContentFromElements(element) || "";
1757    } else {
1758      if (
1759        getLabelFromTitle &&
1760        dataLayerAttribute &&
1761        dataLayerAttribute["dc:title"]
1762      ) {
1763        title = dataLayerAttribute["dc:title"] || "";
1764      } else if (textElement.length > 0) {
1765        title = textElement.first().text() || "";
1766      } else if (img.length > 0) {
1767        title = img.attr("alt") || "";
1768      } else {
1769        title = element.text() || "";
1770      }
1771    }
1772
1773    if (element.closest(".login-modal__content--tab-button").length > 0) {
1774      title = `${selectedTabTitle}`;
1775    } else {
1776      title = `${selectedTabTitle}:${title}`;
1777    }
1778
1779    title = transformText(title);
1780
1781    if (element.attr("download") !== undefined) {
1782      fileDownloaded =
1783        element.attr("download") !== ""
1784          ? element.attr("download")
1785          : element.attr("href");
1786
1787      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}:download`;
1788    } else {
1789      linkText = `click-${digitalData.page.pageInfo.pageName}-${componentName}:${title}`;
1790    }
1791
1792    if (componentTitle) {
1793      componentName += `:${componentTitle}`;
1794    }
1795
1796    digitalData.event = trackType.click;
1797    digitalData.interaction = {
1798      linkText: linkText,
1799      componentName: componentName || "",
1800      linkClicked: element.attr("href") || "",
1801      fileDownloaded: fileDownloaded || "",
1802      videoName: "",
1803      videoInteraction: "",
1804    };
1805  };
1806
1807  const handlers = [
1808    { selectors: selectors.accordion, handler: getAccordionData },
1809    { selectors: selectors.header, handler: getHeaderLinkData },
1810    { selectors: selectors.footer, handler: getFooterLinkData },
1811    {
1812      selectors: selectors.homepageBanner,
1813      handler: (el) => getHomePageBannerData(el, true),
1814    },
1815    {
1816      selectors: selectors.businessFormPanel,
1817      handler: (el) => getAdaptiveBtnData(el, components.businessFormPanel),
1818    },
1819    {
1820      selectors: selectors.JoinNowBack,
1821      handler: (el) => getAdaptiveBtnData(el, components.JoinNowBackButton),
1822    },
1823    {
1824      selectors: selectors.joinNowGetApp,
1825      handler: (el) => getAdaptiveBtnData(el, components.joinNowGetApp),
1826    },
1827    {
1828      selectors: selectors.joinNowGetStartedBtn,
1829      handler: (el) => getAdaptiveBtnData(el, components.joinNowGetStartedBtn),
1830    },
1831    {
1832      selectors: selectors.finepPintBlock,
1833      handler: (el) => getLinkData(el, components.finepPintBlock),
1834    },
1835    {
1836      selectors: selectors.table,
1837      handler: (el) => getLinkData(el, components.table),
1838    },
1839    {
1840      selectors: selectors.socialShare,
1841      handler: getSocialShareData,
1842    },
1843    {
1844      selectors: selectors.loginPopup,
1845      handler: (el) => getLoginPopupData(el, components.loginPopup, true),
1846    },
1847    {
1848      selectors: selectors.linkList,
1849      handler: (el) =>
1849 getBlockComponentsData(el, components.linkList, true),
1850    },
1851    {
1852      selectors: selectors.form,
1853      handler: (el) => getFormData(el),
1854    },
1855    {
1856      selectors: selectors.twoColContainer,
1857      handler: (el) => getTwoColContainerData(el),
1858    },
1859    {
1860      selectors: selectors.wayfindingBlock,
1861      handler: (el) =>
1862        getBlockComponentsData(el, components.wayfindingBlock, true),
1863    },
1864    {
1865      selectors: selectors.teaserBlock,
1866      handler: (el) => getBlockComponentsData(el, components.teaserBlock, true),
1867    },
1868    {
1869      selectors: selectors.productCard,
1870      handler: (el) => getProductCardData(el),
1871    },
1872    {
1873      selectors: selectors.pageCollectionBlock,
1874      handler: (el) =>
1875        getBlockComponentsData(el, components.pageCollectionBlock, true),
1876    },
1877    {
1878      selectors: selectors.inclusionBlock,
1879      handler: (el) => getLinkData(el, components.inclusionBlock, true),
1880    },
1881    {
1882      selectors: selectors.processBlock,
1883      handler: (el) => getLinkData(el, components.processBlock, true),
1884    },
1885    {
1886      selectors: selectors.leadCaptureBlock,
1887      handler: (el) =>
1888        getBlockComponentsData(el, components.leadCaptureBlock, true),
1889    },
1890    {
1891      selectors: selectors.calculatorBlock,
1892      handler: (el) => getLinkData(el, components.calculatorBlock, true),
1893    },
1894    {
1895      selectors: selectors.featuredGridBlock,
1896      handler: (el) =>
1897        getProductCardData(el, components.featuredGridBlock, false, true),
1898    },
1899    {
1900      selectors: selectors.productGridBlock,
1901      handler: (el) =>
1902        getProductCardData(el, components.productGridBlock, false, true),
1903    },
1904    {
1905      selectors: selectors.lrMediaBlock,
1906      handler: (el) => getLinkData(el, components.lrMediaBlock, true),
1907    },
1908    {
1909      selectors: selectors.headerBanner,
1910      handler: (el) => getLinkData(el, components.headerBanner, true),
1911    },
1912    {
1913      selectors: selectors.articleBanner,
1914      handler: (el) => getLinkData(el, components.articleBanner, true),
1915    },
1916    {
1917      selectors: selectors.editorialGrid,
1918      handler: (el) => getEditorialGridData(el, components.editorialGrid, true),
1919    },
1920    {
1921      selectors: selectors.sideModal,
1922      handler: (el) => getLinkData(el, components.sideModal, false),
1923    },
1924    {
1925      selectors: selectors.ctaBanner,
1926      handler: (el) => getCTABannerData(el, components.ctaBanner, true),
1927    },
1928    {
1929      selectors: selectors.tileGridBlock,
1930      handler: (el) => getTileGridData(el, components.tileGridBlock, true),
1931    },
1932    {
1933      selectors: selectors.bentoTileGrid,
1934      handler: (el) => getBentoGridData(el, components.bentoTileGrid, true),
1935    },
1936    {
1937      selectors: selectors.productHighlightBlock,
1938      handler: (el) =>
1939        getProductHighlightBlockData(
1940          el,
1941          components.productHighlightBlock,
1942          true
1943        ),
1944    },
1945    {
1946      selectors: selectors.testimonialBlock,
1947      handler: (el) =>
1948        getBlockComponentsData(el, components.testimonialBlock, true),
1949    },
1950    {
1951      selectors: selectors.windowBanner,
1952      handler: (el) =>
1953        getBlockComponentsData(el, components.windowBanner, true),
1954    },
1955    {
1956      selectors: selectors.appPromotionBanner,
1957      handler: (el) => getLinkData(el, components.appPromotionBanner, true),
1958    },
1959    {
1960      selectors: selectors.breadcrumb,
1961      handler: (el) => getLinkData(el, components.breadcrumb, false),
1962    },
1963    {
1964      selectors: selectors.multiColumnTextBlock,
1965      handler: (el) =>
1966        getOotbComponentData(el, components.multiColumnTextBlock, false),
1967    },
1968  ];
1969
1970  const addNotificationsListener = () => {
1971    $(
1972      `${selectors.notifications} a,${selectors.notifications} button,${selectors.notifications} i.icon-close,${selectors.notifications} li.amp-notifications__carousel-dots--dot`
1973    ).on("click", function () {
1974      let element = $(this);
1975      getNotifcationsData(element);
1976    });
1977  };
1978
1979  const notificationsObserver = (element) => {
1980    // if found then add listener through the mutation observer
1981    const observer = new MutationObserver((mutationList) => {
1982      for (const mutation of mutationList) {
1983        if (mutation.type === "childList") {
1984          mutation.addedNodes.forEach((node) => {
1985            if (node.nodeType === Node.ELEMENT_NODE) {
1986              addNotificationsListener();
1987            }
1988          });
1989        }
1990      }
1991    });
1992
1993    const config = { childList: true, subtree: true };
1994    observer.observe(element, config);
1995    addNotificationsListener();
1996  };
1997
1998  // Side Modal -- Starts
1999  const sendSideModalData = (element, componentName, isOpened) => {
2000    let status = isOpened ? "open" : "close";
2001    let innerComponent = element.find(`[${selectors.dataCmpDataLayer}]`);
2002    digitalData.event = trackType.click;
2003    digitalData.interaction = {
2004      linkText: "",
2005      linkClicked: element.attr("href") || "",
2006      componentName: componentName,
2007      videoName: "",
2008      videoInteraction: "",
2009      fileDownloaded: "",
2010    };
2011
2012    if (innerComponent.length > 0) {
2013      let innerComponentDataValue = JSON.parse(
2014        innerComponent.attr(selectors.dataCmpDataLayer)
2015      );
2016
2017      let componentInfo = Object.values(innerComponentDataValue)[0];
2018      let componentTitle = componentInfo["dc:title"] || "";
2019
2020      digitalData.interaction.linkText = `click-${
2021        digitalData.page.pageInfo.pageName
2022      }-${componentName}:${transformText(componentTitle.trim())}:${status}`;
2023    }
2024
2025    track();
2026  };
2027
2028  const observerOptions = {
2029    root: null, // Use the viewport as the default root
2030    threshold: [0, 1], // Trigger when component is fully visible (0 = top visible, 1 = fully visible)
2031  };
2032
2033  const sideModalObserverCb = (entries, observer) => {
2034    entries.forEach((entry) => {
2035      if (!isIntialLoad) return;
2036      let element = $(entry.target);
2037      if (entry.isIntersecting && entry.intersectionRatio === 1) {
2038        sendSideModalData(element, components.sideModal, true);
2039      } else if (!entry.isIntersecting && entry.intersectionRatio === 0) {
2040        sendSideModalData(element, components.sideModal, false);
2041      }
2042    });
2043  };
2044
2045  const sideModalObserver = new IntersectionObserver(
2046    sideModalObserverCb,
2047    observerOptions
2048  );
2049
2050  const loginPopupObserverCb = (entries, observer) => {
2051    entries.forEach((entry) => {
2052      if (!isIntialLoad) return;
2053      let element = $(entry.target);
2054      if (entry.isIntersecting && entry.intersectionRatio === 1) {
2055        sendSideModalData(element, components.loginPopup, true);
2056      } else if (!entry.isIntersecting && entry.intersectionRatio === 0) {
2057        sendSideModalData(element, components.loginPopup, false);
2058      }
2059    });
2060  };
2061
2062  const loginPopupObserver = new IntersectionObserver(
2063    loginPopupObserverCb,
2064    observerOptions
2065  );
2066  //Side Modal -- Ends
2067
2068  $(document).ready(function () {
2069    waitForElement = (
2070      selector,
2071      callback,
2072      timeout = 100000,
2073      fallback = null
2074    ) => {
2075      let maxCount = timeout;
2076      const checkExist = setInterval(() => {
2077        maxCount = 10;
2078        const element = document.querySelector(selector);
2079        if (element !== null) {
2080          clearInterval(checkExist);
2081          callback(element);
2082        } else if (maxCount <= 0) {
2083          clearInterval(checkExist);
2084          if (fallback != null) {
2085            fallback();
2086          } else {
2087            timeOutReached();
2088          }
2089        }
2090      }, 10);
2091    };
2092
2093    // Click listner on Anchor tag with href
2094    $("a, button").on("click", function () {
2095      let element = $(this);
2096
2097      if (element.closest(selectors.form).length > 0) {
2098        let btnType = element.attr("type");
2099        if (btnType === "button") return;
2100      }
2101
2102      if (element.attr("data-btn-name")?.includes("submit")) {
2103        if (guideBridge.getFormModel().validate().length > 0) return;
2104      }
2105
2106      const matchHandler = handlers.find(
2107        (h) => element.closest(h.selectors).length > 0
2108      );
2109      if (matchHandler) {
2110        matchHandler.handler(element);
2111      } else {
2112        getLinkData(element);
2113      }
2114
2115      digitalData.event = trackType.click;
2116      track();
2117    });
2118
2119    $("video").on("click", function () {
2120      let element = $(this);
2121      getVideoData(element);
2122    });
2123
2124    $('span[data-bs-trigger="click"]').on("click", function () {
2125      setTimeout(() => {
2126        let element = $(this);
2127        getProductCardData(element, components.productCard, true);
2128        digitalData.event = trackType.click;
2129        track();
2130      }, 10);
2131    });
2132
2133    $(`${selectors.tabs} li${selectors.ootbTab}`).on("click", function () {
2134      getOotbComponentData($(this), components.tabs, true);
2135      digitalData.event = trackType.click;
2136      track();
2137    });
2138
2139    $(`${selectors.homepageBanner} li${selectors.ootbTab}`).on(
2140      "click",
2141      function () {
2142        getHomePageBannerData($(this), true);
2143        digitalData.event = trackType.click;
2144        track();
2145      }
2146    );
2147
2148    $(`${selectors.adaptiveRadioBtn}`).on("click", function () {
2149      let element = $(this);
2150      getAdaptiveRadioBtnData(element);
2151
2152      digitalData.event = trackType.click;
2153      track();
2154    });
2155
2156    waitForElement(selectors.notifications, (element) => {
2157      notificationsObserver(element);
2158    });
2159
2160    // get all side modals and adding IntersectionObserver
2161    let sideModalElements = document.querySelectorAll(selectors.sideModal);
2162    sideModalElements.forEach((element) => {
2163      sideModalObserver.observe(element);
2164    });
2165
2166    let loginPopupElements = document.querySelectorAll(selectors.loginPopup);
2167    loginPopupElements.forEach((element) => {
2168      loginPopupObserver.observe(element);
2169    });
2170
2171    setTimeout(() => {
2172      isIntialLoad = true;
2173    }, 500);
2174  });
2175} catch (error) {
2176  console.log("Error in Digital data layer", error);
2177}

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.