1(() => { 2 // CTA Clicked 3 window.addEventListener("click", (e) => { 4 const eventName = "CTA Clicked" 5 const $trigger = e.target.closest(`[data-event="${eventName}"]`) 6 if ($trigger) { 7 const $location = $trigger.closest("[data-event-cta-location]") 8 const $ctaContentEl = $trigger.querySelector("[data-event-cta-el]") 9 10 // Remove aria-hidden elements before reading CTA content 11 const $clone = ($ctaContentEl || $trigger).cloneNode(true) 12 $clone.querySelectorAll('[aria-hidden="true"]').forEach($el => $el.remove()) 13 const ctaContent = $clone.innerText 14 15 analytics.track(eventName, { 16 ctaContent, 17 ctaLinkType: $trigger.dataset.eventCtaLinkType || "", // data-event-cta-link-type 18 ctaLocation: $location ? $location.dataset.eventCtaLocation : "" 19 }) 20 } 21 }) 22 23 // Experiment Viewed 24 if (window.optibaseAddActiveVariantsListener) { 25 optibaseAddActiveVariantsListener((variants) => { 26 variants.forEach(variant => { 27 const { userFriendlyTestId, userFriendlyVariantId } = variant 28 29 analytics.track("Experiment Viewed", { 30 // Alternatively use experiment_name and variant_name 31 experimentId: userFriendlyTestId, 32 variantId: userFriendlyVariantId 33 }) 34 }) 35 }) 36 } 37 38 // HubSpot 39 const forms = new Map() 40 const formContextSelector = '[data-event="Form Submitted"]' 41 let hsptEmbedFormCallbacksOnly = false 42 43 window.addEventListener("message", event => { 44 // When form is ready, find the form and read event data attributes that wrap it 45 if (event.data.type === "hsFormCallback" && event.data.eventName === "onFormReady") { 46 const $form = document.querySelector(`[data-form-id="${event.data.id}"]`) 47 if ($form) { 48 if($form.closest('[data-hspt-embed-form-callbacks-only]')) hsptEmbedFormCallbacksOnly = true 49 const $context = $form.closest(formContextSelector) 50 if ($context) { 51 forms.set(event.data.id, { 52 eventName: $context.dataset.eventName, 53 $form, 54 dataset: $context.dataset, 55 }) 56 } 57 } 58 } 59 60 if (event.data.type === "hsFormCallback" && event.data.eventName === "onFormSubmitted") { 61 if (forms.has(event.data.id)) { 62 try { 63 const { eventName } = forms.get(event.data.id) 64 65 // Demo Form Submitted 66 if (eventName === "Demo Form Submitted") { 67 const fields = snakeToCamel(event.data.data.submissionValues) 68 if (fields.countryList) { 69 fields.address = { country: fields.countryList } 70 delete fields.countryList 71 } 72 delete fields.hsContext 73 74 analytics.track(eventName, fields) 75 analytics.identify({ 76 email: fields.email, 77 userIntentResultOutcome: fields.userIntentResultOutcome, 78 regulatoryComplianceRequirementsYesNo: fields.regulatoryComplianceRequirementsYesNo, 79 icpVendorsVr: fields.icpVendorsVr, 80 icpProcessDetailVr: fields.icpProcessDetailVr, 81 }); 82 83 (window.uetq = window.uetq || []).push('event', 'Demo Form Submitted', {}) 84 85 } 86 87 // Resource Requested 88 if (eventName === "Resource Requested") { 89 const { dataset } = forms.get(event.data.id) 90 const { email, jobtitle: title } = event.data.data.submissionValues 91 if(!hsptEmbedFormCallbacksOnly){ 92 analytics.track(eventName, { 93 resourceAssetName: dataset.eventResourceAssetName, 94 }); 95 (window.uetq = window.uetq || []).push('event', 'Resource Requested', {}) 96 } 97 analytics.identify({ email, title }) 98 } 99 100 } catch (error) { 101 console.error(error) 102 } 103 } 104 } 105 }) 106 107 function snakeToCamel(obj) { 108 const newObj = {} 109 Object.entries(obj) 110 .forEach(([key, value]) => { 111 const [first, ...rest] = key.split("_") 112 key = first + rest.map(str => str.charAt(0).toUpperCase() + str.slice(1)).join("") 113 newObj[key] = value 114 }) 115 return newObj 116 } 117})()
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.