1// Contains functions for tracking data used by GA and GTAG 2 3// WOO EVENTS 4 5FP.fns.send_ga4_evt = ( nr, evt_name, data )=>{ 6 if ( ! evt_name ) return; 7 // add fp_ prefix if the first char is a number 8 if ( !isNaN( evt_name.charAt(0) ) ) evt_name = 'fp_' + evt_name; 9 // trim the name to max 40 chars 10 evt_name = evt_name.substring(0, 40); 11 gtag( 'event', evt_name, data); 12 if ( fp.main.debug ) console.log('[FP] GA4 #' + nr + ' event: ' + evt_name, data); 13}; 14 15function fupi_gtools_woo_footer(){ 16 17 fp.woo.gtg = {}; 18 19 let gads_enabled = fp.loaded.includes('gads'), 20 ga41_enabled = fp.loaded.includes('ga41'), 21 ga42_enabled = fp.loaded.includes('ga42'); 22 23 ecommerce_event_send_to = []; 24 25 if ( ga41_enabled ) ecommerce_event_send_to.push( fp.ga41.id2 || fp.ga41.id ); 26 if ( ga42_enabled ) ecommerce_event_send_to.push( fp.ga42.id2 || fp.ga42.id ); 27 if ( gads_enabled ) ecommerce_event_send_to.push( fp.gads.id2 || fp.gads.id ); 28 29 // Helpers 30 31 function add_categories( item, prod ){ 32 if ( prod.categories && prod.categories.length > 0 ) { 33 prod.categories.forEach( ( cat, i ) => { 34 if ( i == 0) { 35 item['item_category'] = cat; 36 } else { 37 item['item_category' + ( i + 1 )] = cat; 38 } 39 } ); 40 }; 41 42 return item; 43 }; 44 45 function add_brand( item, prod ){ 46 if ( prod.brand && prod.brand.length > 0 ) item['item_brand'] = prod.brand[0]; 47 return item; 48 }; 49 50 function add_list_name( item, prod ){ 51 if ( prod.list_name ) item['item_list_name'] = prod.list_name; 52 return item; 53 } 54 55 function add_index( item, prod ){ 56 if ( prod.index ) item['index'] = prod.index; 57 return item; 58 } 59 60 // TRACK IMPRESSIONS 61 62 function track_woo_impress() { 63 64 if ( typeof gtag === 'undefined' ) return; 65 66 let teasers_arr = [], 67 single_arr = [], 68 value = 0; 69 70 // for each product list 71 for ( let [ list_name, item_ids ] of Object.entries( fpdata.woo.lists ) ) { 72 73 let start_index = 1; 74 75 // track only items that were not tracked before 76 if ( fp.woo.gtg[list_name] ) { 77 item_ids = item_ids.filter( id => ! fp.woo.gtg[list_name].includes(id) ); 78 start_index = fp.woo.gtg[list_name].length + 1; 79 } else { 80 fp.woo.gtg[list_name] = []; 81 }; 82 83 item_ids.forEach( ( id, i ) => { 84 85 let prod = fpdata.woo.products[id], 86 prod_id = FP.fns.get_woo_prod_id( prod ), 87 item = { 88 'item_id' : prod_id, 89 'id' : prod_id, 90 'item_name': FP.fns.get_woo_prod_name(prod), 91 'item_list_name' : list_name, 92 'index' : i + start_index, 93 'price' : prod.price, 94 }; 95 96 if ( gads_enabled ) item['google_business_vertical'] = fp.gads.business_type; 97 98 item = add_brand( item, prod ); 99 item = add_categories( item, prod ); 100 101 if ( list_name == 'single' ) { 102 value += prod.price; 103 single_arr.push( item ); 104 } else { 105 teasers_arr.push( item ); 106 } 107 }); 108 109 // prevent double tracking in case the next teasers are added dynamically 110 fp.woo.gtg[list_name].push(...item_ids); 111 }; 112 113 if ( teasers_arr.length > 0 ) { 114 115 let payload_o = { 116 'items' : teasers_arr, 117 'currency' : fpdata.woo.currency, 118 }; 119 120 gtag( 'event', 'view_item_list', payload_o ); 121 if ( fp.main.debug ) console.log( '[FP] GA4/GAds view_item_list event:', payload_o ); 122 }; 123 124 if ( single_arr.length > 0 ) { 125 126 let impress_evt_name = 'view_item'; 127 if ( fp.woo?.force_item_view_on_url && fp.woo?.force_item_view_on_url.some( url_part => document.location.href.includes(url_part) ) ) { 128 impress_evt_name = 'view_item_list'; 129 } 130 131 let payload_o = { 132 'items' : single_arr, 133 'currency' : fpdata.woo.currency, 134 'value' : value, 135 // 'send_to' : ecommerce_event_send_to 136 }; 137 138 gtag( 'event', impress_evt_name, payload_o ); 139 if ( fp.main.debug ) console.log( '[FP] GA4/GAds ' + impress_evt_name + ' event:', payload_o ); 140 } 141 }; 142 143 if ( ! ( fp.woo.dont_track_views_after_refresh && fpdata.refreshed ) ){ 144 track_woo_impress(); 145 FP.addAction( ['woo_impress'], track_woo_impress ); 146 } 147 148 // TRACK DEFAULT VARIANT VIEW 149 // TRACK VARIANT VIEWS 150 151 function woo_variant_view( variant_id ){ 152 153 if (typeof gtag === 'undefined' || !fpdata.woo.products[variant_id]) return; 154 155 let prod = fpdata.woo.products[variant_id], 156 prod_id = FP.fns.get_woo_prod_id(prod), 157 item = { 158 'item_id': prod_id, 159 'id' : prod_id, 160 'item_name': FP.fns.get_woo_prod_name(prod), 161 'item_list_name' : 'single', 162 'price': prod.price 163 }; 164 165 item = add_brand(item, prod); 166 item = add_categories(item, prod); 167 168 if ( gads_enabled ) item['google_business_vertical'] = fp.gads.business_type; 169 170 let payload_o = { 171 'items': [item], 172 'currency': fpdata.woo.currency, 173 'value': prod.price, 174 // 'send_to' : ecommerce_event_send_to 175 }; 176 177 gtag('event', 'view_item', payload_o); 178 if (fp.main.debug) console.log('[FP] GA4/GAds view_item event:', payload_o); 179 } 180 181 FP.addAction( ['woo_variant_view'], woo_variant_view ); 182 FP.addAction( ['woo_def_variant_view'], woo_variant_view ); 183 184 // TRACK TEASER CLICKS 185 // TRACK ADD TO CART / REMOVE FROM CART 186 // TRACK ADD TO WISHLIST 187 188 function track_items( data, event_name ){ 189 190 if ( typeof gtag === 'undefined' ) return; 191 192 let products_data = data.products, 193 event_value = data.value, 194 items_a = [], 195 send_event_to_gads = event_name == 'add_to_cart' && gads_enabled && fp.gads.woo_add_to_cart_conv_id; 196 197 if ( ! send_event_to_gads && ! ga41_enabled ) return; 198 199 products_data.forEach( prod_a => { 200 201 let prod = prod_a[0], 202 prod_id = FP.fns.get_woo_prod_id( prod ), 203 qty = prod_a[1] || prod.qty || 1, 204 item = { 205 'item_id' : prod_id, 206 'id' : prod_id, 207 'item_name' : FP.fns.get_woo_prod_name( prod ), 208 'price' : prod.price, 209 'quantity' : qty, 210 }; 211 212 item = add_index(item, prod); 213 item = add_list_name(item, prod); 214 item = add_brand(item, prod); 215 item = add_categories(item, prod); 216 217 if ( send_event_to_gads ) item['google_business_vertical'] = fp.gads.business_type; 218 219 items_a.push( item ); 220 } ); 221 222 if ( items_a.length == 0 ) return false; 223 224 let payload_o = { 225 'items' : items_a, 226 'value' : event_value, 227 'currency' : fpdata.woo.currency, 228 // 'send_to' : ecommerce_event_send_to 229 }; 230 231 gtag( 'event', event_name, payload_o ); 232 if ( fp.main.debug ) console.log( '[FP] GA4/GAds ' + event_name + ' event: ', payload_o ); 233 234 // GADS Conversion event 235 if ( send_event_to_gads ) { 236 let payload_gads = {...payload_o}; 237 payload_gads['send_to'] = ( fp.gads.id2 || fp.gads.id ) + '/' + fp.gads.woo_add_to_cart_conv_id; 238 gtag('event', 'conversion', payload_gads ); 239 if ( fp.main.debug ) console.log('[FP] GAds add_to_cart conversion', payload_gads); 240 } 241 } 242 243 FP.addAction( ['woo_teaser_click'], data => { 244 track_items( data, 'select_item' ); 245 } ); 246 247 FP.addAction( ['woo_add_to_cart'], data =>{ 248 track_items( data, 'add_to_cart' ); 249 } ); 250 251 if ( fp.woo.cart_to_track ) track_items( fp.woo.cart_to_track, 'add_to_cart' ); // when ATC is tracked in cart 252 253 FP.addAction( ['woo_add_to_wishlist'], data => { 254 track_items( data, 'add_to_wishlist'); 255 } ); 256 257 FP.addAction( ['woo_remove_from_cart'], data => { 258 track_items( data, 'remove_from_cart' ); 259 } ); 260 261 // TRACK CHECKOUT 262 // TRACK ORDER 263 264 function track_cart( type ){ // type can be either "checkout" or "order" 265 266 // Early returns 267 268 if ( typeof gtag === 'undefined' ) return; 269 270 let ga4_server_tracking = ga41_enabled && fp.main.is_pro && fp.ga41.server_side && fp.ga41.adv_orders; 271 272 if ( type == 'order' && ga4_server_tracking ) { 273 if ( fp.main.debug ) console.log( '[FP] GA4 purchase event is tracked by the server-side script' ); 274 if ( ! fp.loaded.includes('gads') ) return; 275 } 276 277 // Vars 278
279 let items_type = fp.woo.variable_tracking_method == 'track_parents' ? 'joined_items' : 'items', 280 items_a = [], 281 cart = type == 'checkout' ? fpdata.woo.cart : fpdata.woo.order, 282 event_name = type == 'checkout' ? 'begin_checkout' : 'purchase', 283 gads_conv_id = false; 284 285 if ( gads_enabled ) { 286 if ( type == 'checkout' && fp.gads.woo_checkout_conv_id ) { 287 gads_conv_id = fp.gads.woo_checkout_conv_id; 288 } else if ( type == 'order' && fp.gads.woo_conv_id ) { 289 gads_conv_id = fp.gads.woo_conv_id; 290 } 291 } 292 293 if ( type == 'order' && ga4_server_tracking && ! gads_conv_id ) { 294 return; 295 } 296 297 // Get items 298 299 for ( const id in cart[items_type] ) { 300 301 let prod = cart[items_type][id], 302 prod_id = FP.fns.get_woo_prod_id(prod), 303 item = { 304 'item_id' : prod_id, 305 'id' : prod_id, 306 'item_name' : FP.fns.get_woo_prod_name(prod), 307 'price' : prod.price, 308 'quantity' : prod.qty, 309 }; 310 311 item = add_brand(item, prod); 312 item = add_categories(item, prod); 313 314 if ( gads_enabled ) item['google_business_vertical'] = fp.gads.business_type; 315 316 items_a.push( item ); 317 } 318 319 if ( items_a.length == 0 ) return false; 320 321 let payload_o = { 322 'items' : items_a, 323 'value' : cart.value, 324 'currency' : fpdata.woo.currency, 325 'send_to' : ecommerce_event_send_to 326 }; 327 328 let console_text = '[FP] GA4/GAds'; 329 330 if ( cart.coupons && cart.coupons.length > 0 ) payload_o['coupon'] = cart.coupons.join(','); 331 332 if ( type == 'order' ) { 333 334 payload_o['transaction_id'] = fpdata.woo.order.id; 335 payload_o['tax'] = fpdata.woo.order.tax || 0; 336 payload_o['shipping'] = fpdata.woo.order.shipping || 0; 337 338 // Send purchase event only to GAds if GA4 is tracked by the server 339 if ( ga4_server_tracking && gads_enabled && gads_conv_id ) { 340 payload_o['send_to'] = ( fp.gads.id2 || fp.gads.id ); 341 console_text = '[FP] GAds'; 342 } 343 } 344 345 gtag( 'event', event_name, payload_o ); 346 if ( fp.main.debug ) console.log( console_text + ' ' + event_name + ' event: ', payload_o ); 347 348 // GADS Conversion event 349 if ( ! gads_enabled || ! gads_conv_id ) return; 350 351 let payload_gads = {...payload_o}; 352 353 payload_gads['send_to'] = ( fp.gads.id2 || fp.gads.id ) + '/' + gads_conv_id; // we set it again in case it was not set before 354 gtag('event', 'conversion', payload_gads ); 355 if ( fp.main.debug ) console.log('[FP] GAds ' + event_name + ' conversion', payload_gads); 356 } 357 358 // track order 359 if ( fp.woo.order_data_ready ) { 360 track_cart('order'); 361 } 362 363 // track the start of checkout (except when the whole page or its part is refreshed) 364 if ( ! fpdata.refreshed ) { 365 if ( fp.woo.checkout_data_ready ) { 366 if ( fp.ga41 ) fp.ga41.woo_checkout_tracked = true; 367 if ( fp.gads ) fp.gads.woo_checkout_tracked = true; 368 track_cart('checkout'); 369 } else { 370 document.addEventListener( 'fupi_woo_checkout_data_ready', ()=>{ 371 if ( ( fp.ga41 && ! fp.ga41.woo_checkout_tracked ) || ( fp.gads && ! fp.gads.woo_checkout_tracked ) ) { 372 if ( fp.ga41 ) fp.ga41.woo_checkout_tracked = true; 373 if ( fp.gads ) fp.gads.woo_checkout_tracked = true; 374 track_cart('checkout'); 375 } 376 }) 377 }; 378 } 379 380 FP.loaded('gtools_woo_footer'); 381}; 382 383// STANDARD EVENTS 384 385function fupi_ga4_footer(nr){ 386 387 if ( ! fp.loaded.includes('ga4' + nr) ) return; 388 389 let _ga = fp['ga4' + nr]; 390 391 // TRACK SCROLL 392 393 if ( _ga.track_scroll_method && _ga.track_scroll ) { 394 395 _ga.track_scroll = FP.formatScrollPoints( _ga.track_scroll ); 396 397 FP.addAction( ['scroll', 'active_time_tick'], function(){ 398 399 if ( typeof gtag === 'undefined' ) return; 400 401 if ( 402 _ga.track_scroll.length > 0 && 403 fpdata.activity.total >= fp.track.track_scroll_time && 404 fpdata.scrolled.current_px >= fp.track.track_scroll_min 405 ){ 406 var reachedPoint = FP.isScrollTracked( _ga.track_scroll ); 407 408 if ( reachedPoint ) { 409 // remove reached scroll points from array 410 _ga.track_scroll = _ga.track_scroll.filter( function( point ){ return point > reachedPoint } ); 411 412 var evt_name = 'scrolled_' + reachedPoint, 413 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 414 415 if ( _ga.track_scroll_method == 'params' ) { 416 evt_name = 'scroll'; 417 data['percent_scrolled'] = reachedPoint; 418 }; 419 420 FP.fns.send_ga4_evt( nr, evt_name, data ); 421 } 422 } 423 } ); 424 } 425 426 // TRACK VIEWS OF ELEMENTS 427 // for performance: waits 250ms for dynamically generated content to finish 428 429 FP.fns['ga4' + nr + '_observe_inters'] = ( newly_added_els = false ) => { 430 431 let send_el_view_evt = ( el, nr ) => { 432 433 if ( typeof gtag === 'undefined' ) return; 434 435 let evt_name = el.dataset['ga4' + nr + '_view'], 436 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 437 438 if ( _ga.track_views_method == 'params' ) { 439 data['viewed_element'] = evt_name; 440 evt_name = 'element_view'; 441 }; 442 443 FP.fns.send_ga4_evt( nr, evt_name, data ); 444 }; 445 446 FP.intersectionObserver( newly_added_els, _ga.track_views, 'ga4' + nr, send_el_view_evt, true, nr ); 447 } 448 449 if ( _ga.track_views_method && _ga.track_views ) setTimeout( ()=>{ 450 FP.fns['ga4' + nr + '_observe_inters'](); 451 FP.addAction( ['dom_modified'], FP.fns['ga4' + nr + '_observe_inters'] ); 452 }, 250 ); // wait for any dynamically generated content 453 454 // TRACK AFFILIATE LINKS 455 456 if ( _ga.track_affil_method && _ga.track_affiliate ) { 457 458 FP.addAction( ['click'], function(){ 459 460 if ( typeof gtag === 'undefined' ) return; 461 462 var trackedAffLink = FP.getTrackedAffiliateLink( _ga.track_affiliate ); 463 464 if ( ! trackedAffLink ) return; 465 466 var evt_name = trackedAffLink, 467 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 468 469 if ( _ga.track_affil_method == 'params' ) { 470 evt_name = 'affiliate_link_click'; 471 data['affiliate_link_click'] = trackedAffLink; 472 }; 473 474 FP.fns.send_ga4_evt( nr, evt_name, data ); 475 } ); 476 } 477 478 // TRACK CLICKS ON EMAIL AND TEL LINKS 479 480 if ( _ga.track_email_tel ) { 481 FP.addAction( ['click'], function(){ 482 483 if ( typeof gtag === 'undefined' ) return; 484 485 if ( fpdata.clicked.link && ( fpdata.clicked.link.is_email || fpdata.clicked.link.is_tel ) ) { 486 487 var link_type = fpdata.clicked.link.is_email ? 'email' : 'tel', 488 evt_name = link_type + '_click_' + ( fpdata.clicked.link.safe_email || fpdata.clicked.link.safe_tel ), 489 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 490 491 if ( _ga.track_email_tel == 'params' ){ 492 evt_name = link_type + '_link_click' 493 data['contact_click'] = fpdata.clicked.link.safe_email || fpdata.clicked.link.safe_tel; 494 } 495 496 FP.fns.send_ga4_evt( nr, evt_name, data ); 497 } 498 } ); 499 } 500 501 // TRACK FORM SUBMITS 502 503 if ( _ga.track_forms_method && _ga.track_forms ) { 504 505 FP.addAction( ['form_submit'], function(){ 506 507 if ( typeof gtag === 'undefined' ) return; 508 509 var submittedForm = FP.getSubmittedForm( _ga.track_forms ); 510 511 if ( submittedForm ){ 512 513 var evt_name = submittedForm, 514 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 515 516 if ( _ga.track_forms_method == 'params' ){ 517 evt_name = 'form_submit'; 518 data['submitted_form'] = submittedForm; 519 } 520 521 FP.fns.send_ga4_evt( nr, evt_name, data ); 522 } 523 }) 524 } 525 526 // TRACK CLICKS ON PAGE ELEMENTS 527 528 if ( _ga.track_elems_method && _ga.track_elems ) { 529 530 FP.addAction( ['click'], function(){ 531 532 if ( typeof gtag === 'undefined' ) return; 533 534 var trackedElName = FP.getClickTarget( _ga.track_elems ); 535 536 if ( trackedElName ) { 537 538 var evt_name = trackedElName, 539 data = { 'send_to': fp['ga4' + nr].id2 || fp['ga4' + nr].id }; 540 541 if ( _ga.track_elems_method == 'params' ){ 542 evt_name = 'element_click', 543 data['element_click'] = trackedElName; 544 } 545 546 FP.fns.send_ga4_evt( nr, evt_name, data ); 547 } 548 }) 549 } 550 551 /* <fs_premium_only> */ 552
553 if ( fp.main.is_pro ) { 554 555 // TRACK ENGAGEMENT 556 // sends current for total calculations 557 if ( _ga.track_engagement ) { 558 FP.addAction( ['page_in_blur'], function (){ 559 560 var data = { 561 'send_to': _ga.id2 || _ga.id, 562 'user_engagement_time' : fpdata.activity.current, 563 }; 564 565 if ( typeof gtag !== 'undefined' ) gtag( 'event', 'user_engagement_time', data); 566 if ( fp.main.debug ) console.log('[FP] GA4 #' + nr + ' event: user_engagement_time', data); 567 } ); 568 } 569 } 570 /* </fs_premium_only> */ 571 572 FP.loaded('ga4' + nr + '_footer'); 573}; 574 575function fupi_gads_footer(){ 576 577 // TRACK EMAIL LINKS 578 579 if ( fp.gads.track_email ) { 580 FP.addAction( ['click'], function(){ 581 if ( fpdata.clicked.link && fpdata.clicked.link.is_email ) { 582 gtag( 'event', 'conversion', {'send_to': ( fp.gads.id2 || fp.gads.id ) + '/' + fp.gads.track_email } ); 583 if ( fp.main.debug ) console.log('[FP] GAds conversion event: email link click', ( fp.gads.id2 || fp.gads.id ) + '/' + fp.gads.track_email ); 584 } 585 } ); 586 } 587 588 // TRACK TEL LINKS 589 590 if ( fp.gads.track_tel ) { 591 FP.addAction( ['click'], function(){ 592 if ( fpdata.clicked.link && fpdata.clicked.link.is_tel ) { 593 gtag( 'event', 'conversion', {'send_to': ( fp.gads.id2 || fp.gads.id ) + '/' + fp.gads.track_tel } ); 594 if ( fp.main.debug ) console.log('[FP] GAds conversion event: tel link click', ( fp.gads.id2 || fp.gads.id ) + '/' + fp.gads.track_tel ); 595 } 596 } ); 597 } 598 599 // TRACK VIEWS OF ELEMENTS 600 // for performance: waits 250ms for dynamically generated content to finish 601 602 FP.fns.gads_observe_inters = ( newly_added_els = false ) => { 603 604 let send_el_view_evt = el => { 605 606 if ( typeof gtag === 'undefined' ) return; 607 608 gtag( 'event', 'conversion', {'send_to': ( fp.gads.id2 || fp.gads.id ) + '/' + el.dataset['gads_view'] } ); 609 610 if ( fp.main.debug ) console.log('[FP] GAds conversion event: element view', ( fp.gads.id2 || fp.gads.id ) + '/' + el.dataset['gads_view'] ); 611 }; 612 613 FP.intersectionObserver( newly_added_els, fp.gads.track_views, 'gads', send_el_view_evt, true); 614 } 615 616 if ( fp.gads.track_views ) setTimeout( ()=>{ 617 FP.fns.gads_observe_inters(); 618 FP.addAction( ['dom_modified'], FP.fns.gads_observe_inters ); 619 }, 250 ); 620 621 // TRACK AFFILIATE LINKS 622 623 if ( fp.gads.track_affiliate ) { 624 FP.addAction( ['click'], function(){ 625 var trackedAffLink_convID = FP.getTrackedAffiliateLink( fp.gads.track_affiliate ); 626 if ( trackedAffLink_convID ) { 627 gtag( 'event', 'conversion', {'send_to' : ( fp.gads.id2 || fp.gads.id ) + '/' + trackedAffLink_convID }); 628 if ( fp.main.debug ) console.log('[FP] GAds conversion event: affiliate click', ( fp.gads.id2 || fp.gads.id ) + '/' + trackedAffLink_convID ); 629 } 630 } ); 631 } 632 633 // TRACK FORM SUBMITS 634 635 if ( fp.gads.track_forms ) { 636 FP.addAction( ['form_submit'], function(){ 637 var submittedForm_convID = FP.getSubmittedForm( fp.gads.track_forms ); 638 if ( submittedForm_convID ){ 639 gtag( 'event', 'conversion', {'send_to' : ( fp.gads.id2 || fp.gads.id ) + '/' + submittedForm_convID } ); 640 if ( fp.main.debug ) console.log('[FP] GAds conversion event: form submit', ( fp.gads.id2 || fp.gads.id ) + '/' + submittedForm_convID); 641 } 642 }) 643 } 644 645 // TRACK CLICKS ON PAGE ELEMENTS 646 647 if ( fp.gads.track_elems ) { 648 FP.addAction( ['click'], function(){ 649 var trackedEl_convID = FP.getClickTarget( fp.gads.track_elems ); 650 if ( trackedEl_convID ) { 651 gtag( 'event', 'conversion', { 'send_to' : ( fp.gads.id2 || fp.gads.id ) + '/' + trackedEl_convID } ); 652 if ( fp.main.debug ) console.log('[FP] GAds conversion event: element click', ( fp.gads.id2 || fp.gads.id ) + '/' + trackedEl_convID ); 653 } 654 }) 655 } 656 657 FP.loaded('gads_footer'); 658}; 659 660function fupi_ga41_footer(){ 661 fupi_ga4_footer( 1 ); 662}; 663 664function fupi_ga42_footer(){ 665 fupi_ga4_footer( 2 ); 666}; 667 668FP.load('ga41_footer', 'fupi_ga41_footer', ['ga41_config', 'footer_helpers']); 669FP.load('ga42_footer', 'fupi_ga42_footer', ['ga42_config', 'footer_helpers']); 670FP.load('gads_footer', 'fupi_gads_footer', ['gads_config', 'footer_helpers']);
671FP.load('gtools_woo_footer', 'fupi_gtools_woo_footer', ['gtag_config','woo', 'footer_helpers']);
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.