1/* 2flareai_tag_manager.js is a library script called by platform-specific script flareai_script.js 3*/ 4// GLOBAL VARIABLES 5var flareAIAPIURL = "https://flareai.co/flare_api/index.php"; 6var flareAIAPIResponseTimeout = 300000; // timeout is set to 5 mins 7var flareAIReferrerChannelLocalStorageName = "flareAIReferrerChannel"; 8var flareAIUTMParametersLocalStorageName = "flareAIUTMParameters"; 9var flareAIUserIdLocalStorageName = "flareAIUserId"; 10 11// Define an array to store pageviews with timestamps 12var pageviewsWithTimestamps = []; 13var flareAICustomerJourneyLocalStorageName = "flareAICustomerJourney"; 14 15// UTM PARAMETER DEFINITIONS 16var flareaiGoogleSearchUTM = "utm_source=google&utm_medium=google_search&utm_campaign=flareai_google_search&utm_id=flareai_utm_id"; 17var flareaiBingSearchUTM = "utm_source=bing&utm_medium=bing_search&utm_campaign=flareai_bing_search&utm_id=flareai_utm_id"; 18var flareaiDuckDuckGoSearchUTM = "utm_source=duckduckgo&utm_medium=duckduckgo_search&utm_campaign=flareai_duckduckgo_search&utm_id=flareai_utm_id"; 19// console.log("document.referrer: "+document.referrer); 20// console.log("window.location.search: "+window.location.search); 21 22// LOCAL FUNCTIONS 23// Function to get the userId from localStorage or set it if not exists 24function getFlareAIUserIDFromLocalStorage() { 25 var flareAIUserId = localStorage.getItem('flareAIUserId'); 26 27 // If userId does not exist, create and set it 28 if (!flareAIUserId) { 29 setFlareAIUserIDInLocalStorage(); 30 flareAIUserId = localStorage.getItem('flareAIUserId'); // Retrieve the newly set userId 31 } 32 33 return flareAIUserId; 34} 35 36// Function to set the userId in localStorage 37function setFlareAIUserIDInLocalStorage() { 38 var flareAIUserId = 'user_' + Date.now() + '_' + Math.random().toString(36).substring(2); 39 localStorage.setItem('flareAIUserId', flareAIUserId); 40} 41 42// get flareAIUTMParameters from localStorage 43function getFlareAIUTMParametersFromLocalStorage() { 44var flareAIUTMParameters = localStorage.getItem('flareAIUTMParameters'); 45 46// If flareAIUTMParameters does not exist, create and set it 47if (!flareAIUTMParameters) { 48 setFlareAIUTMParametersInLocalStorage(); 49 flareAIUTMParameters = localStorage.getItem('flareAIUTMParameters'); // Retrieve the newly set flareAIUTMParameters 50} 51 52return flareAIUTMParameters; 53} // getFlareAIUTMParametersFromLocalStorage 54 55// Function to set the flareAIUTMParameters in localStorage 56function setFlareAIUTMParametersInLocalStorage() { 57var urlParams = new URLSearchParams(window.location.search); 58 59var utmId = urlParams.get('utm_id'); 60 61if (utmId !== 'flareai_utm_id') { 62return; 63} 64 65var flareAIUTMParameters = {}; 66 67[ 68'utm_id', 69'utm_source', 70'utm_medium', 71'utm_campaign', 72'utm_term', 73'utm_content' 74].forEach(function (key) { 75if (urlParams.has(key)) { 76 flareAIUTMParameters[key] = urlParams.get(key); 77} 78}); 79 80localStorage.setItem('flareAIUTMParameters', JSON.stringify(flareAIUTMParameters)); 81 82} // setFlareAIUTMParametersInLocalStorage 83 84// Example usage 85var flareAIUserId = getFlareAIUserIDFromLocalStorage(); 86console.log('flareAIUserId', flareAIUserId); 87 88setFlareAIUTMParametersInLocalStorage(); 89var flareAIUTMParameters = getFlareAIUTMParametersFromLocalStorage(); 90// console.log('flareAIUTMParameters', flareAIUTMParameters); 91 92// ------------------------ 93// Function to track pageviews with timestamps 94// ------------------------ 95function trackPageviewWithTimestamp() { 96var flareAICustomerJourney = localStorage.getItem(flareAICustomerJourneyLocalStorageName); 97if ( typeof(flareAICustomerJourney) != "undefined" && flareAICustomerJourney != null ) { 98 pageviewsWithTimestamps = JSON.parse(flareAICustomerJourney); 99} 100 101// Get the current page URL 102var currentPage = window.location.href; 103var referrer = document.referrer || ""; 104 105// Get the current date and time 106var timestamp = new Date().toLocaleString(); 107 108// Create an object to store pageview and timestamp 109var pageviewInfo = { 110 page: currentPage, 111 referrer: referrer, 112 timestamp: timestamp 113}; 114 115// Add the object to the pageviewsWithTimestamps array 116pageviewsWithTimestamps.push(pageviewInfo); 117// console.log(pageviewsWithTimestamps); 118 119// Store the updated array in local storage
120localStorage.setItem(flareAICustomerJourneyLocalStorageName, JSON.stringify(pageviewsWithTimestamps)); 121 122// Log the pageview with timestamp to the console (or send to your analytics system) 123// console.log("Pageview: " + currentPage + " at " + timestamp); 124} // trackPageviewWithTimestamp 125 126 127// FUNCTION: Get value of a specified key (key=value pair) from URL 128function getParameterValueByKeyFromURL(key, url) { 129if ( !url ) var url = window.location.href; 130key = key.replace(/[\[\]]/g, "\\$&"); 131var regex = new RegExp("[?&]" + key + "(=([^&#]*)|&|#|$)"), 132 results = regex.exec(url); 133if (!results) return ''; 134else if (!results[2]) return ''; 135else return decodeURIComponent(results[2].replace(/\+/g, " ")); 136} // getParameterValueByKeyFromURL 137 138 139function getFilenameFromUrl(url) { 140// Create a new URL object 141var parsedUrl = new URL(url); 142// Get the pathname from the URL 143var pathname = parsedUrl.pathname; 144// Extract the filename from the pathname 145var filename = pathname.substring(pathname.lastIndexOf('/') + 1); 146return filename; 147} // getFilenameFromUrl 148 149function getBlogArticleTitle() { 150return (function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 151 var blogArticleTitle = ""; 152 153 var metaPropertyOGTitleObject = $('meta[property="og:title"]'); 154 if (metaPropertyOGTitleObject.length > 0) { 155 blogArticleTitle = metaPropertyOGTitleObject.attr('content'); 156 } else { 157 blogArticleTitle = $('title').text(); 158 } 159 160 return blogArticleTitle; 161})(jQuery); 162} // getBlogArticleTitle 163 164 165function getBlogArticleDescription() { 166return (function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 167 var blogArticleDescription = ""; 168 var metaPropertyOGDescriptionObject = $('meta[property="og:description"]'); // <meta property="og:description" content="Machine Learning Models for Content Generation" /> 169 if (metaPropertyOGDescriptionObject.length > 0) { 170 blogArticleDescription = metaPropertyOGDescriptionObject.attr('content'); 171 } 172 173 if ( blogArticleDescription == "" ) { 174 var metaNameDescriptionObject = $('meta[name="description"]'); // <meta name="description" content="Tennis - New Tech Tennis - Win with New Tech Tennis"/> 175 if (metaNameDescriptionObject.length > 0) { 176 blogArticleDescription = metaNameDescriptionObject.attr('content'); 177 } 178 } 179 180 return blogArticleDescription; 181})(jQuery); 182} // getBlogArticleDescription 183 184 185function getBlogArticleMainImageURL() { 186return (function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 187 var blogArticleMainImageURL = ""; 188 189 var metaPropertyOGImageObject = $('meta[property="og:image"]'); // <meta property="og:image" content="https://www.studiolabs.com/wp-content/uploads/2025/01/flare_content_17501.jpg" /> 190 if (metaPropertyOGImageObject.length > 0) { 191 blogArticleMainImageURL = metaPropertyOGImageObject.attr('content'); 192 } 193 194 return blogArticleMainImageURL; 195})(jQuery); 196} // getBlogArticleMainImageURL 197 198 199function getBlogArticleURL() { 200var blogArticleURL = ""; 201var blogArticleURL = window.location.href; 202if ( blogArticleURL.includes('?') ) { 203 var blogArticleURLArray = blogArticleURL.split('?'); 204 blogArticleURL = blogArticleURLArray[0]; 205} 206 207return blogArticleURL; 208} // getBlogArticleURL 209 210 211function getBlogArticlePublishedDate() { 212return (function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 213 var blogArticleDatePublished = ""; 214 215 var metaPropertyArticlePublishedTimeObject = $('meta[property="article:published_time"]'); // <meta property="article:published_time" content="2025-01-12T12:00:00+00:00" /> 216 if (metaPropertyArticlePublishedTimeObject.length > 0) { 217 blogArticleDatePublished = metaPropertyArticlePublishedTimeObject.attr('content'); 218 } 219 220 if ( blogArticleDatePublished == "" ) { 221 var metaPropertyArticleModifiedTimeObject = $('meta[property="article:modified_time"]'); // <meta property="article:modified_time" content="2024-12-11T07:31:50+00:00" /> 222 if (metaPropertyArticleModifiedTimeObject.length > 0) { 223 blogArticleDatePublished = metaPropertyArticleModifiedTimeObject.attr('content'); 224 } 225 } 226 227 return blogArticleDatePublished; 228})(jQuery); 229} // getBlogArticlePublishedDate 230 231 232function getBlogArticleModifiedDate() {
233return (function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 234 var blogArticleDateModified = ""; 235 236 var metaPropertyArticleModifiedTimeObject = $('meta[property="article:modified_time"]'); // <meta property="article:modified_time" content="2024-12-11T07:31:50+00:00" /> 237 if (metaPropertyArticleModifiedTimeObject.length > 0) { 238 blogArticleDateModified = metaPropertyArticleModifiedTimeObject.attr('content'); 239 } 240 241 if ( blogArticleDateModified == "" ) { 242 var metaPropertyArticlePublishedTimeObject = $('meta[property="article:published_time"]'); // <meta property="article:published_time" content="2025-01-12T12:00:00+00:00" /> 243 if (metaPropertyArticlePublishedTimeObject.length > 0) { 244 blogArticleDateModified = metaPropertyArticlePublishedTimeObject.attr('content'); 245 } 246 } 247 248 return blogArticleDateModified; 249})(jQuery); 250} // getBlogArticleModifiedDate 251 252 253function getBlogArticleDataArray() { 254// console.log('in getBlogArticleDataArray'); 255var blogArticleDataArray = []; 256 257blogArticleDataArray['filename'] = filename; 258 259var blogArticleTitle = getBlogArticleTitle(); 260// console.log('blogArticleTitle: '+blogArticleTitle); 261blogArticleDataArray['blogArticleTitle'] = blogArticleTitle; 262 263var blogArticleDescription = getBlogArticleDescription(); 264// console.log('blogArticleDescription: '+blogArticleDescription); 265blogArticleDataArray['blogArticleDescription'] = blogArticleDescription; 266 267var blogArticleMainImageURL = getBlogArticleMainImageURL(); 268// console.log('blogArticleMainImageURL: '+blogArticleMainImageURL); 269blogArticleDataArray['blogArticleMainImageURL'] = blogArticleMainImageURL; 270 271var blogArticleURL = getBlogArticleURL(); 272blogArticleDataArray['blogArticleURL'] = blogArticleURL; 273 274// var blogArticleDatePublished = new Date(dateText).toISOString(); // Convert to ISO 8601 format 275var blogArticleDatePublished = getBlogArticlePublishedDate(); 276blogArticleDataArray['blogArticleDatePublished'] = blogArticleDatePublished; 277 278var blogArticleDateModified = getBlogArticleModifiedDate(); 279blogArticleDataArray['blogArticleDateModified'] = blogArticleDateModified; 280 281// console.log(blogArticleDataArray); 282return blogArticleDataArray; 283} // getBlogArticleDataArray 284 285 286function addSEOOptimizedNewsArticleStructuredData() { 287(function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 288 try { 289 // console.log('$(script#flareAINewsArticleStructuredData).length: '+$('script#flareAINewsArticleStructuredData').length); 290 if ( $('script#flareAINewsArticleStructuredData').length == 0 ) { // no script#flareAINewsArticleStructuredData exists 291 var NewsArticleStructuredData = { 292 "@context": "https://schema.org", 293 "@type": "NewsArticle", 294 "headline": blogArticleDataArray['blogArticleTitle'], 295 "datePublished": blogArticleDataArray['blogArticleDatePublished'], 296 "dateModified": blogArticleDataArray['blogArticleDateModified'], 297 "author": { 298 "@type": "Person", 299 "name": "XXX_"+newsArticleAuthorName, 300 "url": newsArticleAuthorURL 301 }, 302 "publisher": { 303 "@type": "Organization", 304 "name": organizationName, 305 "logo": { 306 "@type": "ImageObject", 307 "url": organizationLogoURL, 308 "width": 600, 309 "height": 60 310 } 311 }, 312 "description": blogArticleDataArray['blogArticleDescription'], 313 "articleBody": blogArticleDataArray['blogArticleDescription'], 314 "mainEntityOfPage": { 315 "@type": "WebPage", 316 "@id": blogArticleDataArray['blogArticleURL'] 317 }, 318 "image": { 319 "@type": "ImageObject", 320 "url": blogArticleDataArray['blogArticleMainImageURL'], 321 "height": 800, 322 "width": 1200 323 } 324 }; 325 // console.log(NewsArticleStructuredData); 326 327 var scriptTag = $('<script>', { 328 type: 'application/ld+json', 329 id: 'flareAINewsArticleStructuredData', // Add the ID attribute here 330 html: JSON.stringify(NewsArticleStructuredData) 331 }); 332 // console.log('scriptTag: '+scriptTag); 333 $('head').append(scriptTag); 334 } // no script#flareAINewsArticleStructuredData exists 335 } catch (error) { 336 console.error("An error occurred in flareAINewsArticleStructuredData:", error.message); 337 } 338})(jQuery); 339} // addSEOOptimizedNewsArticleStructuredData 340 341 342function addSEOOptimizedFAQPageStructuredData(){
343(function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 344// console.log('in addSEOOptimizedFAQPageStructuredData'); 345try { 346 if ( $('script#flareAIFAQPageStructuredData').length == 0 ) { // no script#flareAIFAQPageStructuredData exists 347 // Initialize an empty array to hold the question-answer pairs 348 var faqArray = []; 349 350 $('h3.flareAIFAQ_Question').each(function () { 351 var question = $(this).text(); 352 var answer = $(this).next('p.flareAIFAQ_Answer').text(); 353 354 faqArray.push({ 355 question: question.trim(), 356 answer: answer.trim() 357 }); 358 }); 359 360 // Log the resulting array to the console 361 // console.log(faqArray); 362 if (faqArray.length > 0) { // faqArray is not empty 363 // Initialize an empty array for JSON-LD format 364 var faqJsonLd = { 365 "@context": "https://schema.org", 366 "@type": "FAQPage", 367 "mainEntity": [] 368 }; 369 370 // Iterate over the faqArray and add each question-answer pair to the JSON-LD 371 $.each(faqArray, function(index, faq) { 372 if ( faq.answer != "" ) { 373 faqJsonLd.mainEntity.push({ 374 "@type": "Question", 375 "name": faq.question, 376 "acceptedAnswer": { 377 "@type": "Answer", 378 "text": faq.answer 379 } 380 }); 381 } 382 }); 383 384 // Convert the faqJsonLd object to a JSON string 385 var faqJsonLdScriptTag = JSON.stringify(faqJsonLd, null, 2); 386 387 // Create a <script> element to insert the JSON-LD into the DOM 388 $('<script>', { 389 type: 'application/ld+json', 390 id: 'flareAIFAQPageStructuredData', // Add the ID attribute here 391 html: faqJsonLdScriptTag 392 }).appendTo('head'); 393 } // faqArray is not empty 394 } // no script#flareAIFAQPageStructuredData exists 395} catch (error) { 396 console.error("An error occurred in flareAIFAQPageStructuredData:", error.message); 397} 398})(jQuery); 399} // addSEOOptimizedFAQPageStructuredData 400 401 402/* 403Record form submitted data. Both for no-iframe and iframe. In the case of iframe thisFormObject is null 404*/ 405function fDST(thisFormObject = null, flareAIAPIURL, flareAIAPIResponseTimeout, fDSTPostData, conversionType="Confirmed Conversion") { 406(function($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 407 // console.log('in fDST') 408 // console.log('in fDST fDSTPostData', fDSTPostData); 409 410 if ( domainName == "jupiterchev.com" ) { 411 return; 412 } 413 414 // initialize 415 var isAllRequiredFieldsFilledTrueOrFalse = true; 416 var fDSTAttributesArray = {}; 417 var formDataArray = {}; 418 var excludedFields = ['g-recaptcha-response', 'g-recaptcha-hidden', 'hs_context', 'state_87', 'input_captcha_prefix_8']; // Add field names to exclude 419 420 if ( thisFormObject !== null) { // no-iframe 421 // console.log("IN NO-IFRAME"); 422 var requiredFields = []; 423 // Find all the required fields within this form 424 thisFormObject.find("[required]").each(function () { 425 var fieldName = $(this).attr("name"); 426 requiredFields.push(fieldName); 427 }); 428 // console.log('requiredFields', requiredFields); 429 430 // Example: Log the required fields array to the console 431 // console.log("Form submitted. Required fields: ", requiredFields); 432 433 // CHECK FOR ALL REQUIRED FIELDS IN THE FOR ARE FILLED OR NOT 434 requiredFields.forEach(function (fieldName) { 435 var input = thisFormObject.find(`[name="${fieldName}"]`); 436 var value = input.val().trim(); 437 if (!value) { // required fiels valued is empty 438 isAllRequiredFieldsFilledTrueOrFalse = false; 439 } // required fiels valued is empty 440 }); 441 // console.log('isAllRequiredFieldsFilledTrueOrFalse', isAllRequiredFieldsFilledTrueOrFalse); 442 443 var formDataArray = {}; 444 if ( 445 fDSTPostData.hasOwnProperty('fDSTAttributesArray') && 446 fDSTPostData['fDSTAttributesArray'] 447 ) { 448 fDSTAttributesArray = fDSTPostData['fDSTAttributesArray']; 449 delete fDSTPostData['fDSTAttributesArray']; 450 } 451 452 thisFormObject.find('input, select, textarea').each(function (index) { // loop each form field 453 var field = $(this); 454 var fieldName = 455 field.attr('name') || 456 field.attr('id') || 457 'field_' + index; 458 459 if ($.inArray(fieldName, excludedFields) === -1) { 460 if (field.is(':checkbox')) { 461 formDataArray[fieldName] = field.is(':checked') ? field.val() : ''; 462 } 463 else if (field.is(':radio')) { 464 if (field.is(':checked')) { 465 formDataArray[fieldName] = field.val(); 466 } 467 } 468 else { 469 formDataArray[fieldName] = field.val(); 470 } 471 } 472 }); // loop each form field 473 } else { // iframe 474 // console.log("IN IFRAME"); 475 // console.log('fDSTPostData: ', fDSTPostData); 476 /* 477 EXAMPLE: fDSTPostData = {"firstname": "test3 first name",
478 "lastname": "test3 last name", 479 "mobilephone": "+11888888888" 480 }; 481 */ 482 if ( fDSTPostData.hasOwnProperty('fDSTAttributesArray') && fDSTPostData['fDSTAttributesArray'] ) { 483 // console.log("fDSTPostData['fDSTAttributesArray'] exists:", fDSTPostData['fDSTAttributesArray']); 484 formData = fDSTPostData['fDSTAttributesArray']; 485 delete fDSTPostData['fDSTAttributesArray']; // This will remove the key from the fDSTPostData object entirely. 486 487 // Loop through key-value pairs in submissionValues 488 Object.entries(formData).forEach(function([key, value]) { 489 // console.log(key, value); 490 // console.log("key: ", key); 491 if ($.inArray(key, excludedFields) === -1) { // key not in excludedFields 492 // console.log("ADDED key: ", key); 493 formDataArray[key] = value; 494 } // key not in excludedFields 495 }); 496 } 497 } // no-iframe OR iframe 498 499 // COMMON TO IFRAME AND NON IFRAME DATA SAVING 500 if ( isAllRequiredFieldsFilledTrueOrFalse == true ) { // all required fields are filled 501 502 fDSTAttributesArray['formDataArray'] = formDataArray; 503 fDSTAttributesArray['formDataLandingPageURL'] = window.location.href; 504 fDSTAttributesArray['landingPageURL'] = ""; 505 fDSTAttributesArray['flareAIUserId'] = flareAIUserId; 506 fDSTAttributesArray['conversionType'] = conversionType; 507 var flareAICustomerOrderJourney = []; 508 var flareAICustomerJourney = localStorage.getItem(flareAICustomerJourneyLocalStorageName); 509 if ( typeof(flareAICustomerJourney) != "undefined" && flareAICustomerJourney != null ) { 510 flareAICustomerOrderJourney = JSON.parse(flareAICustomerJourney); 511 fDSTAttributesArray['landingPageURL'] = flareAICustomerOrderJourney[0]['page']; 512 } 513 fDSTAttributesArray['flareAICustomerOrderJourney'] = flareAICustomerOrderJourney; 514 // console.log("Form submitted with data:", fDSTAttributesArray); 515 516 var fDSTAttributesJSON = JSON.stringify(fDSTAttributesArray); 517 // console.log("fDSTAttributesJSON: "+fDSTAttributesJSON); 518 fDSTPostData['fDSTAttributesJSON'] = fDSTAttributesJSON; 519 // console.log("fDSTPostData", fDSTPostData); 520 if (navigator.sendBeacon) { // browser supports beacon 521 // console.log('browser supports beacon'); 522 var fDSTPostDataForSendBeacon = new FormData(); 523 for (var key in fDSTPostData) { // each element 524 if (fDSTPostData.hasOwnProperty(key)) { 525 fDSTPostDataForSendBeacon.append(key, fDSTPostData[key]); 526 } 527 } // each element 528 fDSTPostDataForSendBeacon.append('requestType', 'sendBeacon'); // used to avaoid CORB Warning message displayed in console 529 // console.log("fDSTPostData", fDSTPostDataForSendBeacon) 530 var resultFDST = navigator.sendBeacon(flareAIAPIURL, fDSTPostDataForSendBeacon); 531 if (resultFDST) { 532 // console.log('Successfully queued fDST!'); 533 if ( conversionType == "Confirmed Conversion" ) { 534 localStorage.clear(); 535 flareAIUserId = getFlareAIUserIDFromLocalStorage(); 536 // console.log('flareAIUserId', flareAIUserId); 537 } 538 } else { 539 // console.log('Failure queing fDST'); 540 } 541 } else { // No Beacon support 542 // console.log('browser don\'t supports beacon'); 543 $.ajax({ 544 url: flareAIAPIURL, 545 type: "POST", 546 data: fDSTPostData, 547 timeout: flareAIAPIResponseTimeout, 548 }).done( function(resultResponsePost) { 549 // console.log('resultResponsePost: '+JSON.stringify(resultResponsePost)); 550 if ( conversionType == "Confirmed Conversion" ) { 551 localStorage.clear(); 552 flareAIUserId = getFlareAIUserIDFromLocalStorage(); 553 // console.log('flareAIUserId', flareAIUserId); 554 } 555 }).fail(function(jqueryXMLHttpRequest, jqueryHttpRequestTextStatus) { 556 // console.log( "Request failed in error: " + jqueryHttpRequestTextStatus ); 557 }).always(function() { 558 }); 559 } // browser supports beacon OR No Beacon support 560 } // all required fields are filled 561})(jQuery); 562 563} // fDST 564 565 566function isURLAttributableToFlare() { 567jQuery(function ($) { // This pattern is called a jQuery IIFE (Immediately Invoked Function Expression) and ensures $ always refers to jQuery inside that scope. 568 var referrer = document.referrer || ""; 569 var referrerDomain = ""; 570 571 try { 572 if (referrer !== "") { 573 referrerDomain = new URL(referrer).hostname.toLowerCase(); 574 } 575 } catch (err) { 576 // console.log("Invalid referrer:", referrer); 577 } 578 // console.log("referrer:", referrer); 579 // console.log("referrerDomain:", referrerDomain); 580 581 var isSearchEngineReferrer = 582 referrerDomain.indexOf("google") !== -1 || 583 referrerDomain.indexOf("bing") !== -1 || 584 referrerDomain.indexOf("yahoo") !== -1 || 585 referrerDomain.indexOf("duckduckgo") !== -1; 586 // console.log('isSearchEngineReferrer', isSearchEngineReferrer); 587 588 if (isSearchEngineReferrer) { 589 var isURLAttributableToFlarePostData = { 590 operation: 'get', 591 object: 'isURLAttributableToFlare', 592 applicationServiceId: 5, 593 domainName: domainName, 594 url: window.location.href, 595 referrerDomain: referrerDomain 596 }; 597 // console.log('isURLAttributableToFlarePostData', isURLAttributableToFlarePostData); 598 $.ajax({
599 url: flareAIAPIURL, 600 type: "POST", 601 data: isURLAttributableToFlarePostData, 602 timeout: flareAIAPIResponseTimeout, 603 }).done( function(resultResponsePost) { 604 // console.log('resultResponsePost: '+JSON.stringify(resultResponsePost)); 605 if (resultResponsePost.result != false) { 606 // {"result":{"utmSource":"flareai_always_on_seo_agent","utmCampaign":"ZmxhcmVBSSB0cmFja2luZyAoZmxhcmVpX3V0bV9pZCkgZXhpc3RzLiBHcm93dGggaW4gcGFnZSByYW5raW5nIChBdmVyYWdlIG9yZ2FuaWMgcG9zaXRpb24gLSBBT1ApIDE1IHRvIDUgb24gWWFob28u"}} 607 608 var currentURL = new URL(window.location.href); 609 var flareAIUTMParameters = {}; 610 if (!currentURL.searchParams.has("utm_id")) { 611 currentURL.searchParams.set("utm_id", "flareai_utm_id"); 612 } 613 flareAIUTMParameters["utm_id"] = "flareai_utm_id"; 614 615 if ( resultResponsePost.result.utmSource) { 616 flareAIUTMParameters["utm_source"] = resultResponsePost.result.utmSource; 617 if (!currentURL.searchParams.has("utm_source")) { 618 currentURL.searchParams.set("utm_source", resultResponsePost.result.utmSource); 619 } 620 } 621 622 if ( resultResponsePost.result.utmCampaign) { 623 flareAIUTMParameters["utm_campaign"] = resultResponsePost.result.utmCampaign; 624 if (!currentURL.searchParams.has("utm_campaign")) { 625 currentURL.searchParams.set("utm_campaign", resultResponsePost.result.utmCampaign); 626 } 627 } 628 629 // SET LS 630 localStorage.setItem('flareAIUTMParameters', JSON.stringify(flareAIUTMParameters)); 631 632 window.history.replaceState({}, "", currentURL.toString()); 633 // console.log("Updated URL:", currentURL.toString()); 634 } 635 }).fail(function(jqueryXMLHttpRequest, jqueryHttpRequestTextStatus) { 636 // console.log( "Request failed in error: " + jqueryHttpRequestTextStatus ); 637 }).always(function() { 638 }); 639 } 640}); // End of JQuery Wrapper 641} // isURLAttributableToFlare 642 643if (typeof window_url == 'undefined') { 644 var window_url = window.location.href; 645} 646// console.log('window_url: '+window_url); 647if (window_url.endsWith("/")) { 648 window_url = window_url.slice(0, -1); 649} 650var filename = getFilenameFromUrl(window_url) 651// console.log('filename 1: '+filename); 652 653// ADD flareAI CSS 654var styleElement = document.createElement("style"); 655styleElement.type = "text/css"; 656styleElement.innerHTML = ` 657 .flareAICTAParagraph { 658 padding: 15px 20px; 659 box-shadow: 5px 5px 10px rgba(0,0,0,0.3); 660 transition: box-shadow 0.3s ease; 661 } 662 .flareAICTAParagraph:hover { 663 box-shadow: 8px 8px 15px rgba(0,0,0,0.4); 664 } 665`; 666document.head.appendChild(styleElement); 667 668 669trackPageviewWithTimestamp(); 670isURLAttributableToFlare(); 671 672// FAQ STRUCTURED DATA 673// console.log('calling addSEOOptimizedFAQPageStructuredData'); 674if (typeof jQuery != 'undefined') { // jquery not currently loaded 675 addSEOOptimizedFAQPageStructuredData(); 676} 677 678// JQUERY TRIGGER FUNCTIONS 679 680/* 681GET EARNED CLICK AS CONVERSION 682*/ 683document.addEventListener('click', function(event) { 684 // console.log('Click event'); 685 686 var clickedElement = null; 687 var link = null; 688 689 if (event.target && event.target.closest) { 690 clickedElement = event.target.closest('a, button, [role="button"]'); 691 link = event.target.closest('a'); 692 } 693 694 var clickedText = ""; 695 if (clickedElement !== null && clickedElement.textContent) { 696 clickedText = clickedElement.textContent.trim().toLowerCase(); 697 } 698 699 var eventId = ""; 700 var eventName = ""; 701 702 if (link !== null && link.pathname == '/cart') { 703 eventId = "flareAIGAEvent_Cart_Click"; 704 eventName = "Cart Click"; 705 } else if (clickedText.indexOf('add to cart') !== -1) { 706 eventId = "flareAIGAEvent_Add_To_Cart_Click"; 707 eventName = "Add To Cart Click"; 708 } else if (clickedText.indexOf('check out') !== -1) { 709 eventId = "flareAIGAEvent_Check_Out_Click"; 710 eventName = "Check Out Click"; 711 } else if (clickedText.indexOf('continue shopping') !== -1) { 712 eventId = "flareAIGAEvent_Continue_Shopping_Click"; 713 eventName = "Continue shopping Click"; 714 } else if (clickedText.indexOf('buy it now') !== -1) { 715 eventId = "flareAIGAEvent_Buy it now_Click"; 716 eventName = "Buy it now Click"; 717 } 718 719 720 if (eventId === "" && eventName === "") { 721 return; 722 } 723 724 var currentURL = new URL(window.location.href); 725 if (!currentURL.searchParams.has("ref") && typeof getFlareAIUserIDFromLocalStorage === "function") { 726 var flareAIUserId = getFlareAIUserIDFromLocalStorage(); 727 console.log('flareAIUserId', flareAIUserId); 728 729 if (flareAIUserId) { 730 currentURL.searchParams.set("ref", flareAIUserId); 731 window.history.replaceState({}, "", currentURL.toString()); 732 } 733 } 734 735 var fDSTPostData = { 736 'operation': 'post', 737 'object': 'flarefDST', 738 'applicationServiceId': 5, 739 'eventId': eventId, 740 'eventName': eventName, 741 'domainName': domainName 742 }; 743 744 try { 745 fDST(null, flareAIAPIURL, flareAIAPIResponseTimeout, fDSTPostData, "Potential Conversion"); 746 } catch (err) { 747 // console.error("flareAI LOG in fDST: " + err.message); 748 } 749});
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.