1document.addEventListener("DOMContentLoaded", function () { 2 const firstAccordion = document.querySelector(".accordion-item:first-child"); 3 if (firstAccordion) { 4 const toggleContent = firstAccordion.querySelector(".toggle"); 5 if (toggleContent) { 6 const svgIcon = firstAccordion.querySelector("svg"); 7 const path = svgIcon.querySelector(".icon"); 8 9 // Set styles for the first opened accordion item 10 toggleContent.classList.remove("hidden"); 11 toggleContent.style.maxHeight = toggleContent.scrollHeight + "px"; // Set max-height for the first item 12 svgIcon.classList.add("bg-[#070127]"); // Set background to black 13 svgIcon.setAttribute("stroke", "white"); // Set icon color to white 14 path.setAttribute("d", "M5 12h14"); // Set to minus icon 15 } 16 } 17 const supportedLanguages = [ 18 "ar", 19 "en", 20 "de", 21 "es", 22 "fr", 23 "hi", 24 "it", 25 "ja", 26 "pt", 27 "ru", 28 ]; 29 30 /** 31 * Changes the page URL to include the selected language. 32 * @param {string} lang - The language code (e.g., 'en', 'es'). 33 */ 34 function changeLanguage(lang) { 35 if (!lang) return; 36 37 let hostname = window.location.origin; 38 let pathname = window.location.pathname; 39 40 // Remove existing language code from the path 41 let pathParts = pathname 42 .split("/") 43 .filter((part) => part && !supportedLanguages.includes(part)); 44 45 // Add new language code at the beginning of the path 46 pathParts.unshift(lang); 47 48 // Redirect to the new URL 49 window.location.href = hostname + "/" + pathParts.join("/"); 50 } 51 52 const pathname = window.location.pathname; 53 const pathSegments = pathname.split("/"); 54 55 // Find the language code in the URL 56 const foundLang = pathSegments.find((segment) => 57 supportedLanguages.includes(segment) 58 ); 59 60 if (foundLang) { 61 $("#languageSwitcher").val(foundLang); 62 } else { 63 $("#languageSwitcher").val("en"); 64 } 65 66 // Event listener for when the user selects a different language 67 $("#languageSwitcher").on("change", function () { 68 changeLanguage($(this).val()); 69 }); 70 const dropdownItems = document.querySelectorAll(".group"); 71 dropdownItems.forEach((item) => { 72 const dropdownMenu = item.querySelector(".dropdown"); 73 if (dropdownMenu) { 74 // Show the dropdown on hover 75 item.addEventListener("mouseenter", () => { 76 dropdownMenu.classList.remove("hidden"); 77 }); 78 79 // Hide the dropdown on mouse leave 80 item.addEventListener("mouseleave", () => { 81 dropdownMenu.classList.add("hidden"); 82 }); 83 } 84 }); 85 86 // Mobile functionality for dropdown menus 87 const mobileMenuToggles = document.querySelectorAll(".dropdown-menu-item"); 88 89 mobileMenuToggles.forEach((toggle) => { 90 const dropdownMenu = toggle.querySelector(".dropdown-menu"); 91 toggle = toggle.querySelector("a"); 92 const dropdownIcon = document.getElementById("mobileDropdownIcon"); // Optional: Add a toggle icon 93 if (dropdownMenu) { 94 toggle.addEventListener("click", (e) => { 95 e.preventDefault(); // Prevent navigation on toggle click 96 dropdownMenu.classList.toggle("hidden"); 97 if (dropdownIcon) { 98 dropdownIcon.classList.toggle("rotate-180"); 99 } 100 }); 101 } 102 }); 103 104 const contentArea = document.querySelector(".blog-single-post-content"); // Assuming this is your content container 105 if (contentArea) { 106 const tocSearchInput = document.getElementById("toc-search"); 107 const sidebarLinksContainer = document.getElementById("scrollspy-links"); 108 // Select all headings (h2, h3, h4, h5, h6) 109 const headings = contentArea.querySelectorAll("h2, h3, h4, h5, h6"); 110 111 // Initialize an empty array to store the generated links 112 const links = [];
113 headings.forEach((heading, index) => { 114 const headingText = heading.textContent; 115 const slug = `heading-${index}`; 116 heading.setAttribute("id", slug); // Add dynamic ID for scroll targeting 117 const link = document.createElement("a"); 118 link.href = `#${slug}`; 119 link.textContent = headingText; 120 link.classList.add("text-blue-600", "hover:underline", "block"); 121 const listItem = document.createElement("li"); 122 listItem.appendChild(link); 123 sidebarLinksContainer.appendChild(listItem); 124 links.push({ link, heading }); 125 }); 126 if (tocSearchInput) { 127 tocSearchInput.addEventListener("input", function () { 128 const searchTerm = tocSearchInput.value.toLowerCase(); 129 links.forEach(({ link }) => { 130 const text = link.textContent.toLowerCase(); 131 link.parentElement.style.display = text.includes(searchTerm) 132 ? "" 133 : "none"; 134 }); 135 }); 136 } 137 138 let activeIndex = -1; // Track the active link's index 139 140 // Scrollspy functionality 141 function setActiveLink() { 142 let currentActiveIndex = -1; 143 144 // Loop through all headings and check their position
145 headings.forEach((heading, index) => { 146 const rect = heading.getBoundingClientRect(); 147 // Check if the heading is in the viewport (top is within 150px and bottom is still visible) 148 if (rect.top <= 80 && rect.bottom >= 80) { 149 currentActiveIndex = index; // Set the index of the currently active heading 150 } 151 }); 152 153 // If no active heading is found, reset the active index 154 if (currentActiveIndex === -1) { 155 return; // No heading is currently in view 156 } 157 158 // Only update if the active index has changed 159 if (currentActiveIndex !== activeIndex) { 160 activeIndex = currentActiveIndex; 161 162 // Update the links based on the new active index 163 links.forEach(({ link }, index) => { 164 if (index === activeIndex) { 165 link.classList.add("active"); 166 } else { 167 link.classList.remove("active"); 168 } 169 }); 170 } 171 } 172 173 function progressBar() { 174 const scrollHeight = document.documentElement.scrollHeight; 175 const scrollPosition = 176 document.documentElement.scrollTop || document.body.scrollTop; 177 const windowHeight = window.innerHeight; 178 179 // Calculate scroll progress 180 const scrollProgress = 181 (scrollPosition / (scrollHeight - windowHeight)) * 100; 182 183 // Update the progress bar width 184 const scrollbarProgress = document.getElementById("scrollbar-progress"); 185 scrollbarProgress.style.width = `${scrollProgress}%`; 186 187 // Make the scrollbar container fixed at the top after scrolling 188 const scrollbarContainer = document.getElementById("scrollbar-container"); 189 if (scrollPosition > 150) { 190 scrollbarContainer.style.top = window.innerWidth <= 768 ? "98px" : "104px"; // Set to 0px after scroll starts 191 } else { 192 scrollbarContainer.style.top = "-100%"; // Set to just below the navbar (adjust accordingly) 193 } 194 } 195 196 // Add event listener for scrolling to trigger the active link update 197 window.addEventListener("scroll", function () { 198 setActiveLink(); 199 progressBar(); 200 }); 201 202 // Also set the initial active link on page load 203 setActiveLink(); 204 205 // Smooth scrolling functionality 206 document.querySelectorAll('a[href^="#"]').forEach((anchor) => { 207 anchor.addEventListener("click", function (e) { 208 e.preventDefault(); 209 210 const target = document.querySelector(this.getAttribute("href")); 211 212 // Smooth scroll to the target element 213 window.scrollTo({ 214 top: target.offsetTop - 20, // Adjust if you have a fixed navbar 215 behavior: "smooth", 216 }); 217 }); 218 }); 219 const asideContent = document.querySelector("aside.blog-single-post-aside"); 220 const dropdownContent = document.getElementById("mobile-dropdown-content"); 221 const toggleButton = document.getElementById("mobile-dropdown-toggle"); 222 223 if (window.innerWidth <= 768 && asideContent) { 224 Array.from(asideContent.children).forEach((child) => { 225 const clone = child.cloneNode(true); 226 227 // Check if the cloned element is the search container 228 if (clone.querySelector("#toc-search")) { 229 // Assign a unique ID to the cloned search input 230 clone.querySelector("#toc-search").id = "mobile-toc-search"; 231 } 232 233 dropdownContent.appendChild(clone); 234 }); 235 236 toggleButton.addEventListener("click", () => { 237 dropdownContent.classList.toggle("open"); 238 }); 239 240 dropdownContent.addEventListener("click", (event) => { 241 if (event.target.tagName === "A") { 242 dropdownContent.classList.remove("open"); 243 } 244 }); 245 246 const mobileTocSearch = document.getElementById("mobile-toc-search"); 247 if (mobileTocSearch) { 248 mobileTocSearch.addEventListener("input", (e) => { 249 const query = e.target.value.toLowerCase(); 250 const links = dropdownContent.querySelectorAll("li"); 251 links.forEach((link) => { 252 const anchor = link.querySelector("a"); 253 if (anchor.textContent.toLowerCase().includes(query)) { 254 link.style.display = "block"; 255 } else { 256 link.style.display = "none"; 257 } 258 }); 259 }); 260 } 261 } 262 263 // Optional: Close dropdown when clicking outside 264 document.addEventListener("click", function (event) { 265 if ( 266 !dropdownContent.contains(event.target) && 267 !toggleButton.contains(event.target) 268 ) { 269 dropdownContent.classList.remove("open"); 270 } 271 }); 272 } 273 // Mobile Menu Toggle 274 const mobileMenuButton = document.getElementById("mobileMenuButton"); 275 const mobileMenu = document.getElementById("mobileMenu"); 276 const menuOpenIcon = document.getElementById("menuOpenIcon"); 277 const menuCloseIcon = document.getElementById("menuCloseIcon"); 278 279 mobileMenuButton.addEventListener("click", () => { 280 mobileMenu.classList.toggle("hidden"); 281 menuOpenIcon.classList.toggle("hidden"); 282 menuCloseIcon.classList.toggle("hidden"); 283 }); 284 285 // Optional: Close dropdown when clicking outside 286 document.addEventListener("click", function (event) { 287 if ( 288 !mobileMenu.contains(event.target) && 289 !mobileMenuButton.contains(event.target) 290 ) { 291 mobileMenu.classList.add("hidden"); 292 menuOpenIcon.classList.remove("hidden"); 293 menuCloseIcon.classList.add("hidden"); 294 } 295 }); 296 297 var isRTL = $("html").attr("dir") === "rtl" || $("body").hasClass("rtl"); 298 if ($(".blog-posts-carousel").length > 0) { 299 var $carousel = $(".blog-posts-carousel"); 300 301 $carousel.on("init", function (event, slick) { 302 if (slick.slideCount <= 1) { 303 $(".btn-arrows-container").empty(); 304 } 305 }); 306 307 $carousel.slick({ 308 slidesToShow: 1, 309 slidesToScroll: 1, 310 dots: false, 311 arrows: true, 312 focusOnSelect: true, 313 prevArrow: $(".carousel-section .btn-arrow-prev"), 314 nextArrow: $(".carousel-section .btn-arrow-next"), 315 rtl: isRTL, // ð auto RTL 316 }); 317 } 318 $("#front-page-logos").slick({ 319 slidesToShow: 7, 320 slidesToScroll: 1, 321 autoplay: true, 322 autoplaySpeed: 0, // no delay 323 speed: 3000, // controls the speed of transition 324 cssEase: "linear", // for smooth continuous scrolling 325 infinite: true,
326 arrows: false, 327 dots: false, 328 pauseOnHover: false, 329 pauseOnFocus: false, 330 rtl: isRTL, // ð auto RTL 331 responsive: [ 332 { 333 breakpoint: 1200, // below 1200px 334 settings: { 335 slidesToShow: 6, 336 }, 337 }, 338 { 339 breakpoint: 992, // below 992px 340 settings: { 341 slidesToShow: 4, 342 }, 343 }, 344 { 345 breakpoint: 768, // below 768px 346 settings: { 347 slidesToShow: 3, 348 }, 349 }, 350 ], 351 }); 352 353 $(".popular-posts-slider").slick({ 354 slidesToShow: 3, // Number of slides to show 355 slidesToScroll: 1, // Number of slides to scroll 356 infinite: true, 357 dots: false, 358 arrows: true, 359 focusOnSelect: true, 360 prevArrow: $(".blog-page-most-popular .btn-arrow-prev"), 361 nextArrow: $(".blog-page-most-popular .btn-arrow-next"), 362 rtl: isRTL, // ð auto RTL 363 responsive: [ 364 { 365 breakpoint: 768, 366 settings: { 367 slidesToShow: 1, 368 }, 369 }, 370 ], 371 }); 372 $(".testimonials-slider").slick({ 373 autoplay: true, 374 autoplaySpeed: 0, // set to 0 for continuous movement 375 speed: 4000, // control how fast it moves 376 cssEase: "linear", // make movement smooth 377 infinite: true, 378 arrows: false, 379 dots: false, 380 pauseOnHover: false, // donât stop on hover 381 pauseOnFocus: false, // donât stop on focus 382 slidesToShow: 5, // how many cards visible 383 slidesToScroll: 1, 384 rtl: isRTL, // ð auto RTL 385 responsive: [ 386 { 387 breakpoint: 1800, // below 1200px 388 settings: { 389 slidesToShow: 4, 390 }, 391 }, 392 { 393 breakpoint: 1400, // below 1200px 394 settings: { 395 slidesToShow: 3, 396 }, 397 }, 398 { 399 breakpoint: 992, // below 992px 400 settings: { 401 slidesToShow: 2, 402 }, 403 }, 404 { 405 breakpoint: 768, // below 768px 406 settings: { 407 slidesToShow: 1, 408 }, 409 }, 410 ], 411 }); 412}); 413function toggleAccordion(element) { 414 const items = document.querySelectorAll(".accordion-item"); 415 const toggleContent = element.nextElementSibling; 416 const svgIcon = element.querySelector("svg"); 417 const path = svgIcon.querySelector(".icon"); 418 419 // Close all other accordion items 420 items.forEach((item) => { 421 if (item !== element.parentElement) { 422 const content = item.querySelector(".toggle"); 423 const icon = item.querySelector(".icon"); 424 const svg = item.querySelector("svg"); 425 426 content.style.maxHeight = null; // Reset max-height 427 content.classList.add("hidden"); // Hide content 428 svg.classList.remove("rotate-180"); 429 icon.setAttribute("d", "M12 5v14M5 12h14"); // Reset to plus icon 430 svg.classList.remove("bg-[#070127]"); 431 svg.classList.add("bg-mainBg"); 432 svg.setAttribute("stroke", "currentColor"); // Reset stroke color 433 } 434 }); 435 436 // Toggle the clicked accordion 437 if (toggleContent.classList.contains("hidden")) { 438 // Opening the content 439 toggleContent.classList.remove("hidden"); 440 toggleContent.style.maxHeight = toggleContent.scrollHeight + "px"; // Set max-height to the scroll height 441 svgIcon.classList.add("rotate-180"); 442 443 path.setAttribute("d", "M5 12h14"); // Minus icon 444 svgIcon.classList.remove("bg-mainBg"); // Remove background mainBg 445 svgIcon.classList.add("bg-[#070127]"); // Set background to black 446 svgIcon.setAttribute("stroke", "white"); // Icon color to white 447 } else { 448 // Closing the content 449 toggleContent.style.maxHeight = null; // Reset max-height 450 toggleContent.classList.add("hidden"); // Hide content 451 svgIcon.classList.remove("rotate-180"); 452 453 path.setAttribute("d", "M12 5v14M5 12h14"); // Plus icon 454 svgIcon.classList.remove("bg-[#070127]"); // Remove black background 455 svgIcon.classList.add("bg-mainBg"); // Add background mainBg 456 svgIcon.setAttribute("stroke", "currentColor"); // Reset stroke color to default 457 } 458}
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.