1(function ($) { 2 "use strict"; // Start of use strict 3 /* 4 - To Top 5 - Navbar 6 - Collapse hide show for mobile 7 - Background image 8 - Testimonial** 9 - Owl carousel** 10 - Select 2** 11 - Toggle password 12 - Tooltip 13 */ 14 15 16 /* 17 var w = window.innerWidth; 18 var isMobile = false; 19 if (w <= 600){ 20 isMobile = true; 21 } 22 */ 23 24 /*------------------------------------------- 25 To Top 26 --------------------------------------------- */ 27 $('body').append('<div id="toTop" class="btn-top"><i class="fa-solid fa-arrow-up"></i></div>'); 28 $(window).scroll(function () { 29 if ($(this).scrollTop() !== 0) { 30 $('#toTop').fadeIn(); 31 } else { 32 $('#toTop').fadeOut(); 33 } 34 }); 35 $('#toTop').on('click', function () { 36 $("html, body").animate({ 37 scrollTop: 0 38 }, 600); 39 return false; 40 }); 41 /*------------------------------------------- 42 Navbar 43 --------------------------------------------- */ 44 //navbar add remove calss 45 /* 46 var header = $(".navbar-transfarent"); 47 $(window).scroll(function () { 48 var scroll = $(window).scrollTop(); 49 if (scroll >= 1) { 50 header.removeClass('navbar-transfarent').addClass("navbar-bg"); 51 } else { 52 header.removeClass("navbar-bg").addClass('navbar-transfarent'); 53 } 54 }); 55 */ 56 57 // Navbar collapse hide 58 $(".navbar-collapse .collapse-close").on("click", function () { 59 $(".navbar-collapse").collapse("hide"); 60 }); 61 // navbar toggle icon 62 $('#nav-icon').click(function () { 63 $(this).toggleClass('open'); 64 }); 65 66 67 68 /*------------------------------------------- 69 Background image 70 --------------------------------------------- */ 71 if ($('.js-bg-image').length) { 72 $(".js-bg-image").css("backgroundImage", function () { 73 if ($(this).data("image-src")){ 74 var bg = "url(" + $(this).data("image-src") + ")"; 75 //console.log(bg); 76 return bg; 77 } 78 }); 79 } 80 81 82 /*------------------------------------------------- 83 Header carousel 84 ------------------------------------------------ */ 85 /*setTimeout(async function(){ 86 if ($('.header-carousel').length && !isMobile) { 87 $('#header-carousel').append('<img class="h-100 object-fit-cover" src="/assets/images/header/lg-06.750.webp" width="822" height="370" alt="Canada">') 88 var headerOwl = $(".header-carousel"); 89 headerOwl.owlCarousel({ 90 loop: true, 91 margin: 10, 92 items: 1, 93 nav: false, 94 dots: false, 95 autoplay: true, 96 animateOut: 'fadeOut' 97 }) 98 } 99 }, 5000);*/ 100 101 102 103 /*------------------------------------------- 104 Toggle password 105 --------------------------------------------- */ 106 if ($('.toggle-password').length) { 107 $(".toggle-password").click(function () { 108 $(this).toggleClass("fa-eye fa-eye-slash"); 109 var input = $($(this).attr("data-bs-toggle")); 110 if (input.attr("type") == "password") { 111 input.attr("type", "text"); 112 } else { 113 input.attr("type", "password"); 114 } 115 }); 116 } 117 118 /*------------------------------------------- 119 For Text Fields with a CLEAR option 120 --------------------------------------------- */ 121 if ($('.toggle-clearfield').length) { 122 $(".toggle-clearfield").click(function () { 123 $($(this).attr("data-bs-toggle")).val("").trigger("change"); 124 $($(this).attr("data-bs-toggle")).focus(); 125 }); 126 } 127 128 /*------------------------------------------- 129 Update Label on Range Slider as it is adjusted 130 --------------------------------------------- */ 131 if ($('.range-slider').length) { 132 $(".range-slider").change(function () { 133 $($(this).attr("data-label-target")).html($(this).attr("data-label-format").replace("#Value#", $(this).val())); 134 }); 135 $('.range-slider').on('input', function() { 136 $($(this).attr("data-label-target")).html($(this).attr("data-label-format").replace("#Value#", $(this).val())); 137 }); 138 } 139 140 141 /*------------------------------------------- 142 Tooltip 143 --------------------------------------------- */ 144 const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]') 145 const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)) 146 147})(jQuery); 148 149$(document).ready(function() { 150 // ===== MOBILE DROPDOWN NAVIGATION ===== 151 var $mobileSelect = $('#mobileJumpSelect'); 152 153 if ($mobileSelect.length) { 154 $mobileSelect.on('change', function() { 155 var selectedValue = $(this).val(); 156 157 if (selectedValue && selectedValue !== '#top') { 158 var targetId = selectedValue.substring(1); 159 var $targetElement = $('#' + targetId); 160 161 if ($targetElement.length) { 162 var navHeight = 130; 163 var elementPosition = $targetElement.offset().top; 164 var offsetPosition = elementPosition - navHeight; 165 166 $('html, body').animate({ 167 scrollTop: offsetPosition 168 }, 500); // 500ms smooth scroll 169 } 170 171 // Reset dropdown after navigation (optional - currently commented out) 172 /*setTimeout(function() { 173 $mobileSelect.val('#top'); 174 }, 500);*/ 175 } 176 }); 177 } 178 179 // ===== ACTIVE STATE TRACKING ===== 180 // Highlight active section as user scrolls 181 var $sections = $('section[id]');
182 var $navLinks = $('.jump-link'); 183 184 // Only run if we have sections and nav links 185 if ($sections.length && $navLinks.length) { 186 187 function highlightActiveSection() { 188 var scrollPosition = $(window).scrollTop() + 150; // Offset for sticky nav 189 var currentSection = ''; 190 191 $sections.each(function() { 192 var $section = $(this); 193 var sectionTop = $section.offset().top; 194 var sectionHeight = $section.outerHeight(); 195 196 if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) { 197 currentSection = $section.attr('id'); 198 } 199 }); 200 201 // Update active state 202 $navLinks.removeClass('active'); 203 204 if (currentSection) { 205 $navLinks.each(function() { 206 var $link = $(this); 207 if ($link.attr('data-target') === currentSection) { 208 $link.addClass('active'); 209 } 210 }); 211 } 212 } 213 214 // Throttle scroll event for performance 215 var scrollTimeout; 216 217 $(window).on('scroll', function() { 218 if (scrollTimeout) { 219 window.cancelAnimationFrame(scrollTimeout); 220 } 221 scrollTimeout = window.requestAnimationFrame(highlightActiveSection); 222 }); 223 224 // Initial check 225 highlightActiveSection(); 226 } 227 228 229 /* FOR PRODUCT PAGES - FULL SIZE IMAGE MODAL */ 230 if ($('#imageModal').length){ 231 $('#imageModal').on('show.bs.modal', function (event) { 232 var trigger = $(event.relatedTarget); 233 var imageSrc = trigger.data('bs-image-src'); 234 if (imageSrc=="$(this).src"){ 235 var imageSrc = trigger[0].currentSrc; 236 } 237 $('#modalImage').attr('src', imageSrc); 238 239 $(document).on('click', '[data-bs-dismiss="modal"]', function (e) { 240 e.preventDefault(); 241 $('#imageModal').modal('hide'); 242 }); 243 244 $('.modal-backdrop').on('click', function () { 245 e.preventDefault(); 246 console.log('Clicked outside the modal!'); 247 // Add your desired logic here, like closing the modal or triggering another action 248 $(this).closest('.modal').modal('hide'); // Optional: hide the modal 249 }); 250 }); 251 } 252 253 254 255 /* ATTRIBUTION CLASS CHECK */ 256 if ($('body').hasClass('attribution')) { 257 //--> Attribution Source on Copy 258 $("body").bind('copy', function (e) { 259 if (typeof window.getSelection == "undefined") return; //IE8 or earlier... 260 261 var body_element = document.getElementsByTagName('body')[0]; 262 var selection = window.getSelection(); 263 264 //if the selection is short let's not annoy our users 265 if (("" + selection).length < 100) return; 266 267 //create a div outside of the visible area 268 var newdiv = document.createElement('div'); 269 newdiv.style.position = 'absolute'; 270 newdiv.style.left = '-99999px'; 271 body_element.appendChild(newdiv); 272 newdiv.appendChild(selection.getRangeAt(0).cloneContents()); 273 274 //we need a <pre> tag workaround 275 //otherwise the text inside "pre" loses all the line breaks! 276 if (selection.getRangeAt(0).commonAncestorContainer.nodeName == "PRE") { 277 newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>"; 278 } 279 280 if (document.querySelector("link[rel='canonical']").href != ""){ 281 var loc = document.querySelector("link[rel='canonical']").href; 282 }else{ 283 var loc = document.location.href; 284 } 285 newdiv.innerHTML += "<br><br>Read more: " + loc + "" 286 287 selection.selectAllChildren(newdiv); 288 window.setTimeout(function () { body_element.removeChild(newdiv); }, 200); 289 }); 290 } 291 292 /* LOAD ANALYTICS */ 293 if (!$('body').hasClass('sans-analytics')){ 294 setTimeout(function(){ 295 window.dataLayer = window.dataLayer || []; 296 ldScript("https://www.googletagmanager.com/gtag/js?i
296d=G-KQH9L3XD61", true, false, 'anonymous', function(){ 297 function gtag(){dataLayer.push(arguments);} 298 gtag('js', new Date()); 299 gtag('config', 'G-KQH9L3XD61'); 300 gtag('config', 'AW-1069464368'); 301 }); 302 }, 750); 303 } 304 305 /* ADS INITIATORS */ 306 if ($('body').hasClass('ads')) { 307 (adsbygoogle = window.adsbygoogle || []).push({}); 308 //--> Load Ads 309 setTimeout(async function(){ 310 //ldScript("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6449469715038723"); 311 }, 10000); 312 313 } 314 if ($('body').hasClass('zcads-man')) { 315 ads.load(); 316 } 317 if ($('body').hasClass('zcads-side')) { 318 //--> Load Siderail Ads 319 //setTimeout(async function(){ 320 //--> Height/Top was 124, now 215 321 if (window.innerWidth>=800){ 322 $('<div/>', { 323 id: 'SideRailRight', 324 style: 'width:160px;height:600px;position:fixed;top:215px;right:0px;z-index:10;background-colorZZ:rgb(46, 116, 214);' 325 }).appendTo('body'); 326 $("#SideRailRight").html("<ins class='adsbygoogle' style='display:block' data-ad-client='ca-pub-6449469715038723' data-ad-slot='4031697971' data-ad-format='auto' data-full-width-responsive='true'></ins>"); 327 328 329 $('<div/>', { 330 id: 'SideRailLeft', 331 style: 'width:160px;height:600px;position:fixed;top:215px;left:0px;z-index:10;background-colorZZ:rgb(46, 116, 214);' 332 }).appendTo('body'); 333 $("#SideRailLeft").html("<ins class='adsbygoogle' style='display:block' data-ad-client='ca-pub-6449469715038723' data-ad-slot='4504796104' data-ad-format='auto' data-full-width-responsive='true'></ins>"); 334 } 335 ads.init(); 336 //}, 500); 337 } 338 if ($('body').hasClass('zcads-anchor')) { 339 //--> Load Siderail Ads 340 //setTimeout(async function(){ 341 if (window.innerWidth<600 || window.innerHeight<600){ 342 //--> Small Anchor 343 $('body').append('<div id="ad-anchor" class="anchor-small anchor-anim" align="center"><ins id="the-anchor-ad" class="adsbygoogle" data-ad-slot="8832151401" style="display:inline-block;width:300px;height:50px"></ins></div>'); 344 $("#toTop").addClass("btn-top-small"); 345 ads.forceSmall(); 346 }else{ 347 //--> Large Anchor 348 //$('body').append('<div class="anchor" id="anchor-large" align="center"><ins class="adsbygoogle" data-ad-slot="2458314741" style="display:inline-block;width:1024px;height:90px"></ins></div>'); 349 //--> Responsive version 350 $('body').append('<div id="ad-anchor" class="anchor anchor-anim" align="center"><a id="anchor-toggle" class="" href="javascript:ads.collapse()"><svg style="bottom: 0px !important; left: 0% !important; display: block !important; width: 80px !important; height: 30px !important; margin-bottom: -4px; pointer-events: initial !important;"><defs><filter id="dropShadowTop" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feComponentTransfer in="SourceAlpha" result="TransferredAlpha"><feFuncR type="discrete" tableValues="0.5"></feFuncR><feFuncG type="discrete" tableValues="0.5"></feFuncG><feFuncB type="discrete" tableValues="0.5"></feFuncB></feComponentTransfer><feGaussianBlur in="TransferredAlpha" stdDeviation="2"></feGaussianBlur><feOffset dx="0" dy="0" result="offsetblur"></feOffset><feMerge><feMergeNode></feMergeNode><feMergeNode in="SourceGraphic"></feMergeNode></feMerge></filter></defs><path d="M10,26 L10,6 A6,6 0 0,1 16,1 L60,1 A6,6 0 0,1 66,6 L66,20 66,26 Z" stroke="#FAFAFA" stroke-width="1" fill="#FAFAFA" style="filter: url("#dropShadowTop");"></path><g class="down" stroke="#616161" stroke-width="2px" stroke-linecap="square"><line x1="32" y1="12" x2="38" y2="18"></line><line x1="38" y1="18" x2="44" y2="12"></line></g></svg></a><ins id="the-anchor-ad" class="adsbygoogle" data-ad-slot="2347683853" data-ad-format="horizontal" data-full-width-responsive="true" style="display:block;width:100%;"></ins></div>'); 351 $("#toTop").addClass("btn-top-large");
352 //console.log("anchor-large"); 353 354 } 355 //--> responseive version 356 //$('body').append('<div class="anchor" style="" align="center"><ins class="adsbygoogle" data-ad-slot="2347683853" data-ad-format="horizontal" data-full-width-responsive="true" style="display:inline-block;width:100%;max-height:90px;"></ins></div>'); 357 ads.init(); 358 //}, 100); 359 } 360 if ($('body').hasClass('zccta-mobile')) { 361 if (window.innerWidth < 768) { 362 //--> Phase 1: Load ad anchor (same as zcads-anchor mobile path) 363 $('body').append('<div id="ad-anchor" class="anchor-small anchor-anim" align="center"><ins id="the-anchor-ad" class="adsbygoogle" data-ad-slot="8832151401" style="display:inline-block;width:300px;height:50px"></ins></div>'); 364 $("#toTop").addClass("btn-top-small"); 365 ads.forceSmall(); 366 ads.init(); 367 368 //--> Phase 2: Append CTA bar (hidden until scroll trigger) 369 $('body').append( 370 '<div class="sticky-mobile-cta" style="display:none">' + 371 '<div class="container">' + 372 '<div class="sticky-inner">' + 373 '<div class="sticky-price">' + 374 'ZIP Code API' + 375 '<small>Free Tier · 250 lookups/mo</small>' + 376 '</div>' + 377 '<a href="/zip-code-api.asp?utm_source=zipdetail&utm_medium=cta&utm_content=mobile-sticky" class="btn btn-primary btn-sm sticky-cta-btn">' + 378 'Start Free <i class="fa-solid fa-arrow-right"></i>' + 379 '</a>' + 380 '</div>' + 381 '</div>' + 382 '</div>' 383 ); 384 $('body').css('padding-bottom', '70px'); 385 386 //--> Phase 3: One-way swap â once #popovertime is in view, CTA replaces ad permanently 387 var popTarget = document.getElementById('popovertime'); 388 if (popTarget && 'IntersectionObserver' in window) { 389 var ctaSwapObserver = new IntersectionObserver(function(entries, observer) { 390 if (entries[0].isIntersecting) { 391 $('#ad-anchor').remove(); 392 $('.sticky-mobile-cta').show(); 393 observer.disconnect(); 394 } 395 }, { threshold: 0.1 }); 396 ctaSwapObserver.observe(popTarget); 397 } 398 } 399 } 400 if ($('body').hasClass('zcads-anchor-small')) { 401 //--> Load Siderail Ads 402 //setTimeout(async function(){ 403 if (window.innerWidth<600 || window.innerHeight<600){ 404 //--> Small Anchor 405 $('body').append('<div id="ad-anchor" class="anchor-small anchor-anim" align="center"><ins id="the-anchor-ad" class="adsbygoogle" data-ad-slot="8832151401" style="display:inline-block;width:300px;height:50px"></ins></div>'); 406 //console.log("anchor-small"); 407 $("#toTop").addClass("btn-top-small"); 408 ads.forceSmall(); 409 } 410 //--> responseive version 411 //$('body').append('<div class="anchor" style="" align="center"><ins class="adsbygoogle" data-ad-slot="2347683853" data-ad-format="horizontal" data-full-width-responsive="true" style="display:inline-block;width:100%;max-height:90px;"></ins></div>'); 412 ads.init(); 413 //}, 100); 414 } 415}); 416 417 418var ads = { 419 loaded:false, 420 resized:false, 421 collapsed:false, 422 forceSmallCount:0, 423 init: function(){ 424 if (!this.resized){ 425 this.resized = true; 426 if (document.getElementById("SideRailRight") || document.getElementById("SideRailAdLeft")){ 427 this.resize(); 428 window.onresize = ads.resize; 429 } 430 this.load(); 431 } 432 }, 433 resize: function(){ 434 var w = window.innerWidth; 435 //var h = window.innerHeight; 436 //var ah = (h-600)/2; 437 438 //console.log("ads.resize: " + w + " / " + h + " [" + ah + "]"); 439 //-->
439 Position height of ad unit 440 //document.getElementById("SideRailRight").style.top = ah + "px"; 441 //document.getElementById("SideRailLeft").style.top = ah + "px"; 442 //--> Hide ad unit if page < 1200px 443 if (w < 1300){ 444 document.getElementById("SideRailRight").style.display = "none"; 445 document.getElementById("SideRailLeft").style.display = "none"; 446 //document.getElementById("div-gpt-ad-1742871822358-0").style.display = "none"; 447 //document.getElementById("SideRailLeft").style.position = "relative"; 448 }else{ 449 document.getElementById("SideRailRight").style.display = ""; 450 document.getElementById("SideRailLeft").style.display = ""; 451 //document.getElementById("div-gpt-ad-1742871822358-0").style.display = ""; 452 //document.getElementById("SideRailLeft").style.position = "fixed"; 453 } 454 }, 455 load: function(){ 456 if (!this.loaded){ 457 this.loaded = true; 458 setTimeout(async function(){ 459 $("ins").each(function(index) { 460 (adsbygoogle = window.adsbygoogle || []).push({}); 461 }); 462 ldScript("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6449469715038723"); 463 }, 5000); 464 } 465 }, 466 collapse: function(){ 467 //console.log("this.collapsed: " + this.collapsed); 468 //console.log($("#the-anchor-ad")); 469 if (this.collapsed){ 470 this.collapsed = false; 471 $("#anchor-toggle").removeClass("chevron-invert"); 472 $("#ad-anchor").css("bottom", "-4px"); 473 //console.log($('#the-anchor-ad').height()) 474 //console.log("Remove Class"); 475 }else{ 476 this.collapsed = true; 477 $("#anchor-toggle").addClass("chevron-invert"); 478 $("#ad-anchor").css("bottom", "-" + $('#the-anchor-ad').height() + "px"); 479 //console.log($('#the-anchor-ad').height()) 480 //console.log("Add Class"); 481 } 482 }, 483 forceSmall: function(){ 484 this.forceSmallCount++; 485 setTimeout(async function(){ 486 /*console.log("Forced small"); 487 if ($("#ad-anchor")){ 488 $("#ad-anchor").height(50); 489 $("#ad-anchor").css("overflow", "hidden"); 490 if ($("#the-anchor-ad")){ 491 $("#the-anchor-ad").height(50); 492 $("#the-anchor-ad").css("overflow", "hidden"); 493 } 494 if (this.forceSmallCount<5){ 495 ads.forceSmall(); 496 } 497 }*/ 498 //console.log("Height: " + $("#ad-anchor").height()); 499 if ($("#ad-anchor").height() > 75){ 500 $("#ad-anchor").hide(); 501 } 502 }, 5000); 503 } 504} 505 506/* FOR PRODUCT PAGES */ 507var cart = { 508 prodAdd: function(id) { 509 if (id.find(":selected").val() == '') { 510 //alert("You must select a User Level or License Type to purchase."); 511 512 this.content = "You must select a User Level or License Type to purchase."; 513 this.color = copy.red; 514 if (!$("#toast-cart-alert").length){ 515 var d = document.createElement('div'); 516 d.innerHTML = '<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center w-100 py-4 px-5"><div class="toast-container position-fixed top-50 start-50 translate-middle p-5" id="toast-placement"><div id="toast-cart-alert" class="toast align-items-center text-white border-0 fade p2 aligncenter shadow-md hide" role="alert" aria-live="assertive" aria-atomic="true" data-bs-animation="true" data-bs-autohide="true" data-bs-delay="5000" style="backrgound-color:' + this.color + '"><div class="d-flex"><div class="toast-body" id="toast-cart-alert-content"><i class="fa-solid fa-triangle-exclamation"></i> You must select a User Level or License Type to purchase.</div><button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button></div></div></div></div>' 517 document.getElementsByTagName('body')[0].appendChild(d); 518 } 519 520 if (this.color){$("#toast-cart-alert").css({"background-color":this.color});} 521 $("#toast-cart-alert-content").html(this.content); 522 $("#toast-cart-alert").css({"background-color":this.color}); 523 524 var toast = bootstrap.Toast.getOrCreateInstance($("#toast-cart-alert")) 525 toast.show(); 526 } else { 527 id[0].form.submit(); 528 } 529 } 530} 531 532/* CURRENT TIME */ 533var timer = { 534 //time: config.time, 535 time: "", 536 hour: 0, 537 on: true, 538 init: function(){ 539 var currentDate = new Date(); 540 timer.hour = currentDate.getHours(); 541 timer.showClocks(); 542 }, 543 showClocks: function(){ 544 var d2 = new Date(timer.time); 545 $('.localTime').each(function(){ 546 if ($(this).attr('tz')=="-1"){ 547 $(this).html("--"); 548 if ($('.localTime').length <= 1){ 549 timer.turnOff(); 550 } 551 }else{ 552 var d = new Date(timer.time); 553 d.setHours(d.getHours() + timer.tzNumberMod($(this).attr('tz'))); 554 $(this).html(d.toLocaleTimeString()); 555 } 556 }) 557 var currentDate = new Date(); 558 timer.time = d2.setMinutes(currentDate.getMinutes()); 559 timer.time = d2.setSeconds(currentDate.getSeconds()); 560 if (currentDate.getHours() > timer.hour){ 561 //console.log('Changing the Hour: ' + currentDate.getHours() + ' > ' + timer.hour); 562 timer.time = d2.setHours(d2.getHours() + 1); 563 timer.hour++; 564 } 565 566 //--> Start it again in 1 second 567 if (timer.on){ 568 window.setTimeout('timer.showClocks()', 1000); 569 } 570 }, 571 tzNumberMod: function(tz){ 572 if (tz == "4"){ 573 tzMod = 1; 574 }else if (tz == "5"){ 575 tzMod = 0; 576 }else if (tz == "6"){ 577 tzMod = -1; 578 }else if (tz == "7"){ 579 tzMod = -2; 580 }else if (tz == "8"){ 581 tzMod = -3; 582 }else if (tz == "9"){ 583 tzMod = -4; 584 }else if (tz == "10"){ 585 tzMod = -5; 586 }else if (tz == "11"){ 587 tzMod = -6; 588 }else if (tz == "13"){ 589 tzMod = -7; 590 }else if (tz == "14"){ 591 tzMod = -5; 592 }else if (tz == "15"){ 593 tzMod = -4; 594 }else if (tz == "16"){ 595 tzMod = -6; 596 }else{ 597 tzMod = 0; 598 } 599 return tzMod; 600 }, 601 turnOff: function(){ 602 timer.on = false; 603 } 604} 605 606/* COPY TO CLIPBOARD + TOAST ALERTS */ 607var copy = { 608 title: "",content: "",color: "#2e74d6", 609 blue: "#2E74D6",red:"#B30000",green:"#4D8316", 610 do: function(text, config) { 611 if (config){ 612 this.color = this.blue; 613 if (config.color=="red"){this.color = this.red} 614 if (config.color=="green"){this.color = this.green} 615 if (config.title){this.title = config.title} 616 if (config.content){this.content = config.content} 617 }else{ 618 this.content = "<i class='fa-solid fa-circle-check'></i> Link has been copied to your clipboard. Thanks for sharing!"; 619 this.color = this.blue 620 } 621 622 console.log(text); 623 console.log(this.color); 624 625 if (!navigator.clipboard) { 626 copy.fallbackCopyTextToClipboard(text); 627 return; 628 } 629 navigator.clipboard.writeText(text).then(function() { 630 copy.notice(); 631 }, function(err) {
632 this.title = "Error!";this.content="<i class='fa-solid fa-bug'></i> Unfortunately we encountered an error copying the information. Please select and copy it manually.";this.color=this.red; 633 copy.notice(); 634 }); 635 }, 636 fallbackCopyTextToClipboard: function(text) { 637 var textArea = document.createElement("textarea"); 638 textArea.value = text; 639 textArea.style.top = "0"; 640 textArea.style.left = "0"; 641 textArea.style.position = "fixed"; 642 document.body.appendChild(textArea); 643 textArea.focus(); 644 textArea.select(); 645 646 try { 647 var successful = document.execCommand('copy'); 648 var msg = successful ? 'successful' : 'unsuccessful'; 649 copy.notice(); 650 } catch (err) { 651 this.title = "Error!";this.content="<i class='fa-solid fa-bug'></i> Unfortunately we encountered an error copying the information. Please select and copy it manually.";this.color=this.red; 652 copy.notice(); 653 } 654 655 document.body.removeChild(textArea); 656 }, 657 notice: function(){ 658 if (!$("#toast-alert").length){ 659 var d = document.createElement('div'); 660 d.innerHTML = '<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center w-100 py-4 px-5"><div class="toast-container position-fixed top-0 start-50 translate-middle-x" id="toast-placement"><div id="toast-alert" class="toast align-items-center text-white border-0 fade p2 aligncenter shadow-md hide" role="alert" aria-live="assertive" aria-atomic="true" data-bs-animation="true" data-bs-autohide="true" data-bs-delay="5000" style="backrgound-color:' + this.color + '"><div id="toast-alert-title-wrapper" class="toast-body d-none"><strong class="me-auto" id="toast-alert-title">Copied to Clipboard</strong></div><div class="d-flex"><div class="toast-body" id="toast-alert-content"><i class="fa-solid fa-circle-check"></i> Link has been copied to your clipboard.</div><button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button></div></div></div></div>' 661 document.getElementsByTagName('body')[0].appendChild(d); 662 } 663 664 if (this.color){$("#toast-alert").css({"background-color":this.color});} 665 if (this.title!=""){ 666 $("#toast-alert-title-wrapper").removeClass("d-none"); 667 $("#toast-alert-title").html(this.title); 668 }else{ 669 $("#toast-alert-title-wrapper").addClass("d-none"); 670 } 671 $("#toast-alert-content").html(this.content); 672 $("#toast-alert").css({"background-color":this.color}); 673 674 var toast = bootstrap.Toast.getOrCreateInstance($("#toast-alert")) 675 toast.show(); 676 } 677} 678 679/* CHARTS */ 680var char = { 681 loaded: false, 682 loading: false, 683 scriptsLoaded: 0, 684 init: function(text) { 685 //console.log("char.init"); 686 if (typeof FusionCharts === "function") { 687 char.loaded = true; 688 char.load(); 689 } else { 690 char.lazyLoad(); 691 } 692 }, 693 lazyLoad: function(cb){ 694 //console.log("char.lazyLoad"); 695 char.loading = true; 696 /*this.scriptFiles = [ 697 "https://cdn.fusioncharts.com/fusioncharts/4.2.0/fusioncharts.js", 698 "https://cdn.fusioncharts.com/fusioncharts/4.2.0/themes/fusioncharts.theme.fint.js" 699 ];*/ 700 this.scriptFiles = [ 701 "https://cdn.jsdelivr.net/npm/[email protected]/fusioncharts.js", 702 "https://cdn.jsdelivr.net/npm/[email protected]/themes/fusioncharts.theme.fint.min.js" 703 ] 704 if (cb){ 705 this.cb = cb; 706 }else{ 707 this.cb = function() { 708 char.loadAll(); 709 } 710 } 711 712 this.loadScripts(this.scriptFiles, 0, this.cb); 713 char.loaded = true; 714 }, 715 loadScripts: function (urls, u, cb){ 716 //console.log("char.loadScripts: " + u); 717 //console.log(cb) 718 var script = document.createElement('script'); 719 script.setAttribute('src', urls[u]); 720 script.setAttribute('type', 'text/javascript'); 721 script.setAttribute('charset', 'utf-8'); 722 if (urls.length-1 == char.scriptsLoaded){ 723 var loadFunction = cb; 724 }else{ 725 var loadFunction = function () { 726 char.scriptsLoaded++; 727 char.loadScripts(urls, char.scriptsLoaded, cb); 728 }; 729 } 730 731 script.onload = loadFunction; 732 script.onreadystatechange = loadFunction; 733 document.getElementsByTagName("head")[0].appendChild(script); 734 }, 735 loadOne: function(id){ 736 //console.log("char.loadOne: " + id); 737 if (!char.loaded || !typeof FusionCharts === "function"){ 738 //console.log("char.loadOne: Need Lazy Load First!"); 739 char.lazyLoad(function() {char.loadOne(id)}); 740 }else{ 741 for (let i = 0; i < config.charts.length; i++) { 742 if (config.charts[i]._renderAt == id){ 743 try{ 744 config.charts[i].chart.animation = 0; 745 config.charts[i].chart.bgColor = ""; 746 config.charts[i].chart.bgAlpha = "0"; 747 config.charts[i].chart.canvasBgColor = ""; 748 //console.log(config.charts[i]); 749 FusionCharts.ready(function() { 750 var myChart = new FusionCharts({ 751 type: config.charts[i]._type, 752 renderAt: config.charts[i]._renderAt, 753 width: config.charts[i]._width, 754 height: config.charts[i]._height, 755 baseChartMessageFontSize: "18", 756 //dataEmptyMessage: "No data ti display<br><i class='fa-solid fa-battery-empty' style='font-size:40px'></i>", 757 dataFormat: "json", 758 dataSource: config.charts[i],
759 containerBackgroundOpacity:"0" 760 }).render().setTransparent(true); 761 }); 762 }catch(e){ 763 //console.log(e); 764 if (char.loading){ 765 //--> Just wait for Framework to be loaded 766 setTimeout(function(){ 767 char.loadOne(id) 768 }, 750) 769 } 770 } 771 } 772 } 773 } 774 }, 775 loadAll: function(){ 776 for (let i = 0; i < config.charts.length; i++) { 777 config.charts[i].chart.animation = 0; 778 config.charts[i].chart.bgColor = ""; 779 config.charts[i].chart.bgAlpha = "0"; 780 config.charts[i].chart.canvasBgColor = ""; 781 FusionCharts.ready(function() { 782 var myChart = new FusionCharts({ 783 type: config.charts[i]._type, 784 renderAt: config.charts[i]._renderAt, 785 width: config.charts[i]._width, 786 height: config.charts[i]._height, 787 dataFormat: "json", 788 dataSource: config.charts[i], 789 containerBackgroundOpacity:"0" 790 }
790).render().setTransparent(true); 791 }); 792 } 793 } 794} 795 796function swapChart(ID, Tab){ 797 thisEndpointTabs = document.getElementById(ID).getElementsByClassName("tab"); 798 thisEndpointFormats = $('#' + ID + '').attr('format'); 799 800 for (var i = 0, j = thisEndpointTabs.length; i < j; i++) { 801 //console.log(thisEndpointTabs[i]); 802 thisEndpointTabs[i].className = "tab"; 803 } 804 thisEndpointTabs[Tab].className = "tab selected"; 805 806 $('#' + ID + '-0').removeClass("hidden"); 807 $('#' + ID + '-1').removeClass("hidden"); 808 $('#' + ID + '-2').removeClass("hidden"); 809 if (Tab == 2){ 810 $('#' + ID + '-0').addClass("hidden"); 811 $('#' + ID + '-1').addClass("hidden"); 812 }else if (Tab == 1){ 813 $('#' + ID + '-0').addClass("hidden"); 814 $('#' + ID + '-2').addClass("hidden"); 815 }else{ 816 $('#' + ID + '-1').addClass("hidden"); 817 $('#' + ID + '-2').addClass("hidden"); 818 } 819 } 820 821/* Loading Scripts */ 822function ldScript(u, a=true, d=false, c='anonymous', cb=null){ 823 if (u==""){return false} 824 var s = document.createElement('script'); 825 s.src = u; 826 s.type = 'text/javascript'; 827 s.async = a; 828 s.defer = d; 829 s.crossOrigin = c; 830 if (typeof cb === 'function') { s.onload = cb; } 831 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s); 832} 833 834/* Lazy Loader Replacement */ 835var LazyLoader = { 836 loadedResources: null, 837 init: function() { 838 this.loadedResources = { 839 css: new Set(), 840 js: new Set() 841 }; 842 }, 843 844 load: function(config) { 845 var self = this; 846 847 // Initialize 848 if (!this.loadedResources){ 849 this.init(); 850 } 851 852 // Validate config 853 if (!config || !config.resources) { 854 return Promise.reject(new Error('No resources provided')); 855 } 856 857 var resources = config.resources; 858 var cssFiles = resources.css || []; 859 var jsFiles = resources.js || []; 860 var totalResources = cssFiles.length + jsFiles.length; 861 var loadedCount = 0; 862 863 // Execute loading start callback 864 if (typeof config.onLoadStart === 'function') { 865 config.onLoadStart(); 866 } 867 868 // Helper to update progress 869 var updateProgress = function() { 870 loadedCount++; 871 if (typeof config.onProgress === 'function') { 872 config.onProgress(loadedCount, totalResources); 873 } 874 }; 875 876 // Helper to handle completion 877 var handleComplete = function() { 878 if (typeof config.onLoadEnd === 'function') { 879 config.onLoadEnd(); 880 } 881 if (typeof config.onComplete === 'function') { 882 config.onComplete(); 883 } 884 }; 885 886 return new Promise(function(resolve, reject) { 887 // Load CSS first (non-blocking) 888 var cssPromises = cssFiles.map(function(cssConfig) { 889 return self.loadCSS(cssConfig, updateProgress, config.onError); 890 }); 891 892 // Wait for all CSS, then load JS sequentially 893 Promise.all(cssPromises) 894 .then(function() { 895 return self.loadScriptsSequential(jsFiles, updateProgress, config.onError); 896 }) 897 .then(function() { 898 handleComplete(); 899 resolve(); 900 }) 901 .catch(function(error) { 902 if (typeof config.onLoadEnd === 'function') { 903 config.onLoadEnd(); 904 } 905 if (typeof config.onError === 'function') { 906 config.onError(null, error); 907 } 908 reject(error); 909 }); 910 }); 911 }, 912 913 loadCSS: function(cssConfig, progressCallback, errorCallback) { 914 var self = this; 915 var href, media, rel; 916 917 // Parse config (string or object) 918 if (typeof cssConfig === 'string') { 919 href = cssConfig; 920 media = 'all'; 921 rel = 'stylesheet'; 922 } else { 923 href = cssConfig.href; 924 media = cssConfig.media || 'all'; 925 rel = cssConfig.rel || 'stylesheet'; 926 } 927 928 // Check if already loaded 929 if (self.loadedResources.css.has(href)) { 930 if (typeof progressCallback === 'function') { 931 progressCallback(); 932 } 933 return Promise.resolve(); 934 } 935 936 return new Promise(function(resolve, reject) { 937 var link = document.createElement('link'); 938 link.setAttribute('href', href); 939 link.setAttribute('type', 'text/css'); 940 link.setAttribute('rel', rel); 941 link.setAttribute('media', media); 942 943 link.onload = function() { 944 self.loadedResources.css.add(href); 945 if (typeof progressCallback === 'function') { 946 progressCallback(); 947 } 948 resolve(); 949 }; 950 951 link.onerror = function() { 952 var error = new Error('Failed to load CSS: ' + href); 953 if (typeof errorCallback === 'function') { 954 errorCallback(href, error); 955 } 956 reject(error); 957 }; 958 959 document.getElementsByTagName('head')[0].appendChild(link); 960 }); 961 }, 962 963 loadScriptsSequential: function(jsFiles, progressCallback, errorCallback) { 964 var self = this; 965 966 // Create a chain of promises that execute sequentially
967 return jsFiles.reduce(function(chain, jsConfig) { 968 return chain.then(function() { 969 return self.loadScript(jsConfig, progressCallback, errorCallback); 970 }); 971 }, Promise.resolve()); 972 }, 973 974 loadScript: function(jsConfig, progressCallback, errorCallback) { 975 var self = this; 976 var src, async, defer, crossOrigin, type, charset; 977 978 // Parse config (string or object) 979 if (typeof jsConfig === 'string') { 980 src = jsConfig; 981 async = true; 982 defer = false; 983 crossOrigin = 'anonymous'; 984 type = 'text/javascript'; 985 charset = 'utf-8'; 986 } else { 987 src = jsConfig.src; 988 async = jsConfig.async !== undefined ? jsConfig.async : true; 989 defer = jsConfig.defer !== undefined ? jsConfig.defer : false; 990 crossOrigin = jsConfig.crossOrigin || 'anonymous'; 991 type = jsConfig.type || 'text/javascript'; 992 charset = jsConfig.charset || 'utf-8'; 993 } 994 995 // Check if already loaded 996 if (self.loadedResources.js.has(src)) { 997 if (typeof progressCallback === 'function') { 998 progressCallback(); 999 } 1000 return Promise.resolve(); 1001 } 1002 1003 return new Promise(function(resolve, reject) { 1004 var script = document.createElement('script'); 1005 script.setAttribute('src', src); 1006 script.setAttribute('type', type); 1007 script.setAttribute('charset', charset); 1008 script.async = async; 1009 script.defer = defer; 1010 1011 if (crossOrigin) { 1012 script.crossOrigin = crossOrigin; 1013 } 1014 1015 var loadFunction = function() { 1016 self.loadedResources.js.add(src); 1017 if (typeof progressCallback === 'function') { 1018 progressCallback(); 1019 } 1020 resolve(); 1021 }; 1022 1023 script.onload = loadFunction; 1024 script.onreadystatechange = function() { 1025 if (this.readyState === 'complete' || this.readyState === 'loaded') { 1026 loadFunction(); 1027 } 1028 }; 1029 1030 script.onerror = function() { 1031 var error = new Error('Failed to load script: ' + src); 1032 if (typeof errorCallback === 'function') { 1033 errorCallback(src, error); 1034 } 1035 reject(error); 1036 }; 1037 1038 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script); 1039 }); 1040 }, 1041 1042 isLoaded: function(resource) { 1043 return this.loadedResources.css.has(resource) || this.loadedResources.js.has(resource); 1044 }, 1045 1046 reset: function() { 1047 this.init(); 1048 } 1049};
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.