1/* marquee loop */ 2const mq=document.getElementById('marquee'); 3mq.innerHTML+=mq.innerHTML; 4 5/* live terminal feed */ 6const platforms=['BLINKIT','ZEPTO','INSTAMART','AMAZON','SWIGGY','ZOMATO','WALMART','KROGER','TESCO','BIGBASKET','NOON','TALABAT']; 7const skus=['Amul Butter 500g','Maggi Noodles 12-pk','Coca-Cola 1.25L','Tata Salt 1kg','Surf Excel 2kg','Dove Shampoo 650ml','Lays Classic 90g','Paneer Tikka Pizza','Chicken Biryani (Lg)','Organic Bananas 1kg','Red Bull 4-pack','Aashirvaad Atta 5kg','Margherita Pizza Med','Masala Dosa Combo','Nescafe Gold 200g','iPhone 15 Case Clr']; 8const stocks=[['IN-STOCK','st-in'],['IN-STOCK','st-in'],['IN-STOCK','st-in'],['LOW','st-low'],['OUT','st-out']]; 9const feed=document.getElementById('feed'),rc=document.getElementById('rowCount'); 10let count=2841906; 11const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches; 12function addRow(){ 13 const p=platforms[Math.random()*platforms.length|0]; 14 const s=skus[Math.random()*skus.length|0]; 15 const pr='â¹'+(Math.random()*900+20).toFixed(0)+'.00'; 16 const [st,cls]=stocks[Math.random()*stocks.length|0]; 17 const r=document.createElement('div'); 18 r.className='row'; 19 r.innerHTML=`<div class="plat">${p}</div><div class="sku">${s}</div><div class="price">${pr}</div><div class="${cls}">${st}</div>`; 20 feed.prepend(r); 21 while(feed.children.length>12)feed.lastChild.remove(); 22 count+=Math.random()*40+5|0; 23 rc.textContent=count.toLocaleString('en-IN'); 24} 25for(let i=0;i<9;i++)addRow(); 26if(!reduced)setInterval(addRow,1400); 27 28/* scroll reveal */ 29const io=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target)}}),{threshold:.15}); 30document.querySelectorAll('.reveal').forEach(el=>io.observe(el)); 31 32/* counters */ 33const cio = new IntersectionObserver(es => es.forEach(e => { 34 if (!e.isIntersecting) return; 35 36 const el = e.target; 37 const end = parseFloat(el.dataset.count); 38 const hasDecimal = el.dataset.count.includes("."); 39 const dur = 1400; 40 const t0 = performance.now(); 41 42 (function tick(t) { 43 const k = Math.min((t - t0) / dur, 1); 44 const ease = 1 - Math.pow(1 - k, 3); 45 const value = end * ease; 46 47 if (hasDecimal) { 48 el.textContent = value.toLocaleString(undefined, { 49 minimumFractionDigits: 1, 50 maximumFractionDigits: 1 51 }); 52 } else { 53 el.textContent = Math.round(value).toLocaleString(); 54 } 55 56 if (k < 1) requestAnimationFrame(tick); 57 })(t0); 58 59 cio.unobserve(el); 60}), { threshold: .6 }); 61 62document.querySelectorAll("[data-count]").forEach(el => cio.observe(el)); 63 64/* FAQ */ 65document.querySelectorAll('.faq-q').forEach(q=>q.addEventListener('click',()=>{ 66 const item=q.parentElement,open=item.classList.contains('open'); 67 document.querySelectorAll('.faq-item').forEach(i=>i.classList.remove('open')); 68 if(!open)item.classList.add('open'); 69})); 70 71/* testimonial slider */ 72const track=document.getElementById('tstTrack'); 73let tIdx=0; 74const slides=track.children.length; 75function visible(){return innerWidth>1020?2:1} 76function go(n){ 77 const max=slides-visible();
78 tIdx=Math.max(0,Math.min(n,max)); 79 const w=track.children[0].getBoundingClientRect().width+22; 80 track.style.transform=`translateX(${-tIdx*w}px)`; 81} 82document.getElementById('tstPrev').addEventListener('click',()=>go(tIdx-1)); 83document.getElementById('tstNext').addEventListener('click',()=>go(tIdx+1)); 84addEventListener('resize',()=>go(tIdx)); 85if(!reduced)setInterval(()=>go(tIdx+1>slides-visible()?0:tIdx+1),6000); 86 87 88/* ---------- 3D DATA GLOBE (hero background) ---------- */ 89(function(){ 90 if(reduced || innerWidth < 768 || typeof THREE === 'undefined') return; 91 const canvas = document.getElementById('globe3d'); 92 if(!canvas) return; 93 const hero = canvas.parentElement; 94 const renderer = new THREE.WebGLRenderer({canvas, alpha:true, antialias:true}); 95 renderer.setPixelRatio(Math.min(devicePixelRatio, 2)); 96 const scene = new THREE.Scene(); 97 const camera = new THREE.PerspectiveCamera(50, 1, .1, 100); 98 camera.position.z = 7; 99 100 function sizeIt(){ 101 const w = hero.clientWidth, h = hero.clientHeight; 102 renderer.setSize(w, h, false); 103 camera.aspect = w/h; 104 camera.updateProjectionMatrix(); 105 } 106 sizeIt(); 107 108 const group = new THREE.Group(); 109 // globe shifted to the right behind the terminal 110 group.position.x = 3.1; group.position.y = .2; 111 scene.add(group); 112 113 function pointSphere(count, radius, color, size, opacity){ 114 const pos = new Float32Array(count*3); 115 for(let i=0;i<count;i++){ 116 const phi = Math.acos(2*Math.random()-1), th = Math.random()*Math.PI*2; 117 pos[i*3] = radius*Math.sin(phi)*Math.cos(th); 118 pos[i*3+1] = radius*Math.cos(phi); 119 pos[i*3+2] = radius*Math.sin(phi)*Math.sin(th); 120 } 121 const g = new THREE.BufferGeometry(); 122 g.setAttribute('position', new THREE.BufferAttribute(pos,3)); 123 const m = new THREE.PointsMaterial({color, size, transparent:true, opacity, sizeAttenuation:true}); 124 return new THREE.Points(g,m); 125 } 126 group.add(pointSphere(900, 2.6, 0x00A5E8, .035, .85)); // data nodes (brand cyan) 127 group.add(pointSphere(140, 2.62, 0x2DD4A8, .07, .95)); // live capture points (green) 128 group.add(pointSphere(400, 3.4, 0x3A5A8C, .025, .35)); // outer halo 129 130 // latitude rings 131 const ringMat = new THREE.LineBasicMaterial({color:0x00A5E8, transparent:true, opacity:.14}); 132 [-1.6,-.8,0,.8,1.6].forEach(y=>{ 133 const r = Math.sqrt(Math.max(.05, 2.6*2.6 - y*y)); 134 const pts=[]; for(let a=0;a<=64;a++){const t=a/64*Math.PI*2;pts.push(new THREE.Vector3(r*Math.cos(t),y,r*Math.sin(t)))} 135 const ring = new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts), ringMat); 136 group.add(ring); 137 }); 138 139 // gentle mouse parallax 140 let mx=0,my=0; 141 addEventListener('mousemove',e=>{mx=(e.clientX/innerWidth-.5);my=(e.clientY/innerHeight-.5)}); 142 143 let raf; 144 function animate(){ 145 raf = requestAnimationFrame(animate); 146 group.rotation.y += .0016; 147 group.rotation.x += (my*.25 - group.rotation.x)*.04; 148 group.position.x += ((3.1 + mx*.4) - group.position.x)*.05; 149 renderer.render(scene, camera); 150 } 151 // run only while hero is on screen (saves battery, protects CWV) 152 new IntersectionObserver(es=>{ 153 es.forEach(e=>{ if(e.isIntersecting){animate()} else {cancelAnimationFrame(raf)} }); 154 }).observe(hero); 155 addEventListener('resize', sizeIt); 156})(); 157 158/* ---------- 3D DATA PIPELINE: chaos -> structure ---------- */ 159(function(){ 160 if(reduced || innerWidth < 768 || typeof THREE === 'undefined') return; 161 const canvas = document.getElementById('pipe3d'); 162 if(!canvas) return; 163 const renderer = new THREE.WebGLRenderer({canvas, alpha:true, antialias:true}); 164 renderer.setPixelRatio(Math.min(devicePixelRatio,2)); 165 const scene = new THREE.Scene(); 166 const camera = new THREE.PerspectiveCamera(42, 2, .1, 100); 167 camera.position.set(0, .6, 11); 168 169 function sizeIt(){ 170 const w = canvas.clientWidth || canvas.parentElement.clientWidth, h = 340; 171 renderer.setSize(w, h, false); 172 camera.aspect = w/h; camera.updateProjectionMatrix(); 173 } 174 sizeIt(); 175 176 const N = 1400; 177 const pos = new Float32Array(N*3), col = new Float32Array(N*3); 178 const P = []; // particle state 179 const cChaos = new THREE.Color(0x5B6B85), cMid = new THREE.Color(0x00A5E8), cDone = new THREE.Color(0x2DD4A8); 180 const COLS=26, ROWS=10, LAYS=5; 181 function gridTarget(i){ 182 const c=i%COLS, r=(i/COLS|0)%ROWS, l=(i/(COLS*ROWS)|0)%LAYS; 183 return [3.4 + c*.16, (r-(ROWS-1)/2)*.30, (l-(LAYS-1)/2)*.34]; 184 } 185 function spawn(i, randomP){ 186 P[i] = { 187 p: randomP ? Math.random() : 0, 188 sp: .0016 + Math.random()*.0022, 189 sy: (Math.random()-.5)*4.6, sz: (Math.random()-.5)*4.2, 190 ph: Math.random()*Math.PI*2, 191 t: gridTarget(i) 192 }; 193 } 194 for(let i=0;i<N;i++) spawn(i, true); 195 196 const geo = new THREE.BufferGeometry(); 197 geo.setAttribute('position', new THREE.BufferAttribute(pos,3)); 198 geo.setAttribute('color', new THREE.BufferAttribute(col,3)); 199 const pts = new THREE.Points(geo, new THREE.PointsMaterial({size:.055, vertexColors:true, transparent:true, opacity:.95})); 200 scene.add(pts); 201 202 // the "QA gate" â glowing ring at the transformation point 203 const ring = new THREE.Mesh( 204 new THREE.TorusGeometry(2.5, .025, 10, 80), 205 new THREE.MeshBasicMaterial({color:0x00A5E8, transparent:true, opacity:.55}) 206 ); 207 ring.position.x = .4; ring.rotation.y = Math.PI/2; 208 scene.add(ring); 209 const ring2 = ring.clone(); ring2.scale.setScalar(.82); ring2.material = ring.material.clone(); ring2.material.opacity=.25; 210 scene.add(ring2); 211 212 const tmp = new THREE.Color(); 213 const ease = t => t<.5 ? 2*t*t : 1-Math.pow(-2*t+2,2)/2; 214 let raf, time=0; 215 function animate(){ 216 raf = requestAnimationFrame(animate); 217 time += .016; 218 for(let i=0;i<N;i++){ 219 const s=P[i]; s.p += s.sp; 220 if(s.p>=1.06) spawn(i,false); 221 const p = Math.min(s.p,1), e = ease(p), chaos = Math.pow(1-p,1.6); 222 pos[i*3] = -6.4 + e*(s.t[0]+6.4); 223 pos[i*3+1] = s.sy*(1-e) + s.t[1]*e + Math.sin(time*2+s.ph)*.4*chaos; 224 pos[i*3+2] = s.sz*(1-e) + s.t[2]*e + Math.cos(time*1.7+s.ph)*.4*chaos; 225 // color journey: grey -> cyan (at gate) -> green (structured) 226 if(p<.5){ tmp.copy(cChaos).lerp(cMid, p*2); }
226 else { tmp.copy(cMid).lerp(cDone, (p-.5)*2); } 227 col[i*3]=tmp.r; col[i*3+1]=tmp.g; col[i*3+2]=tmp.b; 228 } 229 geo.attributes.position.needsUpdate = true; 230 geo.attributes.color.needsUpdate = true; 231 ring.rotation.x += .004; ring2.rotation.x -= .006; 232 const pulse = 1 + Math.sin(time*2.2)*.03; 233 ring.scale.setScalar(pulse); 234 renderer.render(scene, camera); 235 } 236 new IntersectionObserver(es=>{ 237 es.forEach(e=>{ if(e.isIntersecting){animate()} else {cancelAnimationFrame(raf)} }); 238 },{threshold:.1}).observe(canvas); 239 addEventListener('resize', sizeIt); 240})(); 241 242/* ---------- 3D TILT on AI cards (desktop) ---------- */ 243(function(){ 244 if(reduced || innerWidth < 1020) return; 245 document.querySelectorAll('.ai-card').forEach(card=>{ 246 card.style.transformStyle='preserve-3d'; 247 card.addEventListener('mousemove',e=>{ 248 const r=card.getBoundingClientRect(); 249 const x=(e.clientX-r.left)/r.width-.5, y=(e.clientY-r.top)/r.height-.5; 250 card.style.transform=`translateY(-7px) perspective(800px) rotateY(${x*7}deg) rotateX(${-y*7}deg)`; 251 }); 252 card.addEventListener('mouseleave',()=>{card.style.transform=''}); 253 }); 254})(); 255 256/* back to top */ 257const toTop=document.getElementById('toTop'); 258addEventListener('scroll',()=>toTop.classList.toggle('show',scrollY>700)); 259toTop.addEventListener('click',()=>scrollTo({top:0,behavior:'smooth'}));
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.